ljx

FORK: LuaJIT with native 5.2 and 5.3 support
git clone https://git.neptards.moe/neptards/ljx.git
Log | Files | Refs | README

lj_cparse.c (56983B)


      1 /*
      2 ** C declaration parser.
      3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
      4 */
      5 
      6 #include "lj_obj.h"
      7 
      8 #if LJ_HASFFI
      9 
     10 #include "lj_gc.h"
     11 #include "lj_err.h"
     12 #include "lj_buf.h"
     13 #include "lj_ctype.h"
     14 #include "lj_cparse.h"
     15 #include "lj_frame.h"
     16 #include "lj_vm.h"
     17 #include "lj_char.h"
     18 #include "lj_strscan.h"
     19 #include "lj_strfmt.h"
     20 
     21 /*
     22 ** Important note: this is NOT a validating C parser! This is a minimal
     23 ** C declaration parser, solely for use by the LuaJIT FFI.
     24 **
     25 ** It ought to return correct results for properly formed C declarations,
     26 ** but it may accept some invalid declarations, too (and return nonsense).
     27 ** Also, it shows rather generic error messages to avoid unnecessary bloat.
     28 ** If in doubt, please check the input against your favorite C compiler.
     29 */
     30 
     31 /* -- C lexer ------------------------------------------------------------- */
     32 
     33 /* C lexer token names. */
     34 static const char *const ctoknames[] = {
     35 #define CTOKSTR(name, str)	str,
     36 CTOKDEF(CTOKSTR)
     37 #undef CTOKSTR
     38   NULL
     39 };
     40 
     41 /* Forward declaration. */
     42 LJ_NORET static void cp_err(CPState *cp, ErrMsg em);
     43 
     44 static const char *cp_tok2str(CPState *cp, CPToken tok)
     45 {
     46   lua_assert(tok < CTOK_FIRSTDECL);
     47   if (tok > CTOK_OFS)
     48     return ctoknames[tok-CTOK_OFS-1];
     49   else if (!lj_char_iscntrl(tok))
     50     return lj_strfmt_pushf(cp->L, "%c", tok);
     51   else
     52     return lj_strfmt_pushf(cp->L, "char(%d)", tok);
     53 }
     54 
     55 /* End-of-line? */
     56 static LJ_AINLINE int cp_iseol(CPChar c)
     57 {
     58   return (c == '\n' || c == '\r');
     59 }
     60 
     61 /* Peek next raw character. */
     62 static LJ_AINLINE CPChar cp_rawpeek(CPState *cp)
     63 {
     64   return (CPChar)(uint8_t)(*cp->p);
     65 }
     66 
     67 static LJ_NOINLINE CPChar cp_get_bs(CPState *cp);
     68 
     69 /* Get next character. */
     70 static LJ_AINLINE CPChar cp_get(CPState *cp)
     71 {
     72   cp->c = (CPChar)(uint8_t)(*cp->p++);
     73   if (LJ_LIKELY(cp->c != '\\')) return cp->c;
     74   return cp_get_bs(cp);
     75 }
     76 
     77 /* Transparently skip backslash-escaped line breaks. */
     78 static LJ_NOINLINE CPChar cp_get_bs(CPState *cp)
     79 {
     80   CPChar c2, c = cp_rawpeek(cp);
     81   if (!cp_iseol(c)) return cp->c;
     82   cp->p++;
     83   c2 = cp_rawpeek(cp);
     84   if (cp_iseol(c2) && c2 != c) cp->p++;
     85   cp->linenumber++;
     86   return cp_get(cp);
     87 }
     88 
     89 /* Save character in buffer. */
     90 static LJ_AINLINE void cp_save(CPState *cp, CPChar c)
     91 {
     92   lj_buf_putb(&cp->sb, c);
     93 }
     94 
     95 /* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
     96 static void cp_newline(CPState *cp)
     97 {
     98   CPChar c = cp_rawpeek(cp);
     99   if (cp_iseol(c) && c != cp->c) cp->p++;
    100   cp->linenumber++;
    101 }
    102 
    103 LJ_NORET static void cp_errmsg(CPState *cp, CPToken tok, ErrMsg em, ...)
    104 {
    105   const char *msg, *tokstr;
    106   lua_State *L;
    107   va_list argp;
    108   if (tok == 0) {
    109     tokstr = NULL;
    110   } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING ||
    111 	     tok >= CTOK_FIRSTDECL) {
    112     if (sbufP(&cp->sb) == sbufB(&cp->sb)) cp_save(cp, '$');
    113     cp_save(cp, '\0');
    114     tokstr = sbufB(&cp->sb);
    115   } else {
    116     tokstr = cp_tok2str(cp, tok);
    117   }
    118   L = cp->L;
    119   va_start(argp, em);
    120   msg = lj_strfmt_pushvf(L, err2msg(em), argp);
    121   va_end(argp);
    122   if (tokstr)
    123     msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tokstr);
    124   if (cp->linenumber > 1)
    125     msg = lj_strfmt_pushf(L, "%s at line %d", msg, cp->linenumber);
    126   lj_err_callermsg(L, msg);
    127 }
    128 
    129 LJ_NORET LJ_NOINLINE static void cp_err_token(CPState *cp, CPToken tok)
    130 {
    131   cp_errmsg(cp, cp->tok, LJ_ERR_XTOKEN, cp_tok2str(cp, tok));
    132 }
    133 
    134 LJ_NORET LJ_NOINLINE static void cp_err_badidx(CPState *cp, CType *ct)
    135 {
    136   GCstr *s = lj_ctype_repr(cp->cts->L, ctype_typeid(cp->cts, ct), NULL);
    137   cp_errmsg(cp, 0, LJ_ERR_FFI_BADIDX, strdata(s));
    138 }
    139 
    140 LJ_NORET LJ_NOINLINE static void cp_err(CPState *cp, ErrMsg em)
    141 {
    142   cp_errmsg(cp, 0, em);
    143 }
    144 
    145 /* -- Main lexical scanner ------------------------------------------------ */
    146 
    147 /* Parse number literal. Only handles int32_t/uint32_t right now. */
    148 static CPToken cp_number(CPState *cp)
    149 {
    150   StrScanFmt fmt;
    151   TValue o;
    152   do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
    153   cp_save(cp, '\0');
    154   fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), &o, STRSCAN_OPT_C);
    155   if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32;
    156   else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
    157   else if (!(cp->mode & CPARSE_MODE_SKIP))
    158     cp_errmsg(cp, CTOK_INTEGER, LJ_ERR_XNUMBER);
    159   cp->val.u32 = (uint32_t)o.i;
    160   return CTOK_INTEGER;
    161 }
    162 
    163 /* Parse identifier or keyword. */
    164 static CPToken cp_ident(CPState *cp)
    165 {
    166   do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
    167   cp->str = lj_buf_str(cp->L, &cp->sb);
    168   cp->val.id = lj_ctype_getname(cp->cts, &cp->ct, cp->str, cp->tmask);
    169   if (ctype_type(cp->ct->info) == CT_KW)
    170     return ctype_cid(cp->ct->info);
    171   return CTOK_IDENT;
    172 }
    173 
    174 /* Parse parameter. */
    175 static CPToken cp_param(CPState *cp)
    176 {
    177   CPChar c = cp_get(cp);
    178   TValue *o = cp->param;
    179   if (lj_char_isident(c) || c == '$')  /* Reserve $xyz for future extensions. */
    180     cp_errmsg(cp, c, LJ_ERR_XSYNTAX);
    181   if (!o || o >= cp->L->top)
    182     cp_err(cp, LJ_ERR_FFI_NUMPARAM);
    183   cp->param = o+1;
    184   if (tvisstr(o)) {
    185     cp->str = strV(o);
    186     cp->val.id = 0;
    187     cp->ct = &cp->cts->tab[0];
    188     return CTOK_IDENT;
    189   } else if (tvisnumber(o)) {
    190     cp->val.i32 = numberVint(o);
    191     cp->val.id = CTID_INT32;
    192     return CTOK_INTEGER;
    193   } else {
    194     GCcdata *cd;
    195     if (!tviscdata(o))
    196       lj_err_argtype(cp->L, (int)(o-cp->L->base)+1, "type parameter");
    197     cd = cdataV(o);
    198     if (cd->ctypeid == CTID_CTYPEID)
    199       cp->val.id = *(CTypeID *)cdataptr(cd);
    200     else
    201       cp->val.id = cd->ctypeid;
    202     return '$';
    203   }
    204 }
    205 
    206 /* Parse string or character constant. */
    207 static CPToken cp_string(CPState *cp)
    208 {
    209   CPChar delim = cp->c;
    210   cp_get(cp);
    211   while (cp->c != delim) {
    212     CPChar c = cp->c;
    213     if (c == '\0') cp_errmsg(cp, CTOK_EOF, LJ_ERR_XSTR);
    214     if (c == '\\') {
    215       c = cp_get(cp);
    216       switch (c) {
    217       case '\0': cp_errmsg(cp, CTOK_EOF, LJ_ERR_XSTR); break;
    218       case 'a': c = '\a'; break;
    219       case 'b': c = '\b'; break;
    220       case 'f': c = '\f'; break;
    221       case 'n': c = '\n'; break;
    222       case 'r': c = '\r'; break;
    223       case 't': c = '\t'; break;
    224       case 'v': c = '\v'; break;
    225       case 'e': c = 27; break;
    226       case 'x':
    227 	c = 0;
    228 	while (lj_char_isxdigit(cp_get(cp)))
    229 	  c = (c<<4) + (lj_char_isdigit(cp->c) ? cp->c-'0' : (cp->c&15)+9);
    230 	cp_save(cp, (c & 0xff));
    231 	continue;
    232       default:
    233 	if (lj_char_isdigit(c)) {
    234 	  c -= '0';
    235 	  if (lj_char_isdigit(cp_get(cp))) {
    236 	    c = c*8 + (cp->c - '0');
    237 	    if (lj_char_isdigit(cp_get(cp))) {
    238 	      c = c*8 + (cp->c - '0');
    239 	      cp_get(cp);
    240 	    }
    241 	  }
    242 	  cp_save(cp, (c & 0xff));
    243 	  continue;
    244 	}
    245 	break;
    246       }
    247     }
    248     cp_save(cp, c);
    249     cp_get(cp);
    250   }
    251   cp_get(cp);
    252   if (delim == '"') {
    253     cp->str = lj_buf_str(cp->L, &cp->sb);
    254     return CTOK_STRING;
    255   } else {
    256     if (sbuflen(&cp->sb) != 1) cp_err_token(cp, '\'');
    257     cp->val.i32 = (int32_t)(char)*sbufB(&cp->sb);
    258     cp->val.id = CTID_INT32;
    259     return CTOK_INTEGER;
    260   }
    261 }
    262 
    263 /* Skip C comment. */
    264 static void cp_comment_c(CPState *cp)
    265 {
    266   do {
    267     if (cp_get(cp) == '*') {
    268       do {
    269 	if (cp_get(cp) == '/') { cp_get(cp); return; }
    270       } while (cp->c == '*');
    271     }
    272     if (cp_iseol(cp->c)) cp_newline(cp);
    273   } while (cp->c != '\0');
    274 }
    275 
    276 /* Skip C++ comment. */
    277 static void cp_comment_cpp(CPState *cp)
    278 {
    279   while (!cp_iseol(cp_get(cp)) && cp->c != '\0')
    280     ;
    281 }
    282 
    283 /* Lexical scanner for C. Only a minimal subset is implemented. */
    284 static CPToken cp_next_(CPState *cp)
    285 {
    286   lj_buf_reset(&cp->sb);
    287   for (;;) {
    288     if (lj_char_isident(cp->c))
    289       return lj_char_isdigit(cp->c) ? cp_number(cp) : cp_ident(cp);
    290     switch (cp->c) {
    291     case '\n': case '\r': cp_newline(cp);  /* fallthrough. */
    292     case ' ': case '\t': case '\v': case '\f': cp_get(cp); break;
    293     case '"': case '\'': return cp_string(cp);
    294     case '/':
    295       if (cp_get(cp) == '*') cp_comment_c(cp);
    296       else if (cp->c == '/') cp_comment_cpp(cp);
    297       else return '/';
    298       break;
    299     case '|':
    300       if (cp_get(cp) != '|') return '|';
    301       cp_get(cp); return CTOK_OROR;
    302     case '&':
    303       if (cp_get(cp) != '&') return '&';
    304       cp_get(cp); return CTOK_ANDAND;
    305     case '=':
    306       if (cp_get(cp) != '=') return '=';
    307       cp_get(cp); return CTOK_EQ;
    308     case '!':
    309       if (cp_get(cp) != '=') return '!';
    310       cp_get(cp); return CTOK_NE;
    311     case '<':
    312       if (cp_get(cp) == '=') { cp_get(cp); return CTOK_LE; }
    313       else if (cp->c == '<') { cp_get(cp); return CTOK_SHL; }
    314       return '<';
    315     case '>':
    316       if (cp_get(cp) == '=') { cp_get(cp); return CTOK_GE; }
    317       else if (cp->c == '>') { cp_get(cp); return CTOK_SHR; }
    318       return '>';
    319     case '-':
    320       if (cp_get(cp) != '>') return '-';
    321       cp_get(cp); return CTOK_DEREF;
    322     case '$':
    323       return cp_param(cp);
    324     case '\0': return CTOK_EOF;
    325     default: { CPToken c = cp->c; cp_get(cp); return c; }
    326     }
    327   }
    328 }
    329 
    330 static LJ_NOINLINE CPToken cp_next(CPState *cp)
    331 {
    332   return (cp->tok = cp_next_(cp));
    333 }
    334 
    335 /* -- C parser ------------------------------------------------------------ */
    336 
    337 /* Namespaces for resolving identifiers. */
    338 #define CPNS_DEFAULT \
    339   ((1u<<CT_KW)|(1u<<CT_TYPEDEF)|(1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
    340 #define CPNS_STRUCT	((1u<<CT_KW)|(1u<<CT_STRUCT)|(1u<<CT_ENUM))
    341 
    342 typedef CTypeID CPDeclIdx;	/* Index into declaration stack. */
    343 typedef uint32_t CPscl;		/* Storage class flags. */
    344 
    345 /* Type declaration context. */
    346 typedef struct CPDecl {
    347   CPDeclIdx top;	/* Top of declaration stack. */
    348   CPDeclIdx pos;	/* Insertion position in declaration chain. */
    349   CPDeclIdx specpos;	/* Saved position for declaration specifier. */
    350   uint32_t mode;	/* Declarator mode. */
    351   CPState *cp;		/* C parser state. */
    352   GCstr *name;		/* Name of declared identifier (if direct). */
    353   GCstr *redir;		/* Redirected symbol name. */
    354   CTypeID nameid;	/* Existing typedef for declared identifier. */
    355   CTInfo attr;		/* Attributes. */
    356   CTInfo fattr;		/* Function attributes. */
    357   CTInfo specattr;	/* Saved attributes. */
    358   CTInfo specfattr;	/* Saved function attributes. */
    359   CTSize bits;		/* Field size in bits (if any). */
    360   CType stack[CPARSE_MAX_DECLSTACK];  /* Type declaration stack. */
    361 } CPDecl;
    362 
    363 /* Forward declarations. */
    364 static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl);
    365 static void cp_declarator(CPState *cp, CPDecl *decl);
    366 static CTypeID cp_decl_abstract(CPState *cp);
    367 
    368 /* Initialize C parser state. Caller must set up: L, p, srcname, mode. */
    369 static void cp_init(CPState *cp)
    370 {
    371   cp->linenumber = 1;
    372   cp->depth = 0;
    373   cp->curpack = 0;
    374   cp->packstack[0] = 255;
    375   lj_buf_init(cp->L, &cp->sb);
    376   lua_assert(cp->p != NULL);
    377   cp_get(cp);  /* Read-ahead first char. */
    378   cp->tok = 0;
    379   cp->tmask = CPNS_DEFAULT;
    380   cp_next(cp);  /* Read-ahead first token. */
    381 }
    382 
    383 /* Cleanup C parser state. */
    384 static void cp_cleanup(CPState *cp)
    385 {
    386   global_State *g = G(cp->L);
    387   lj_buf_free(g, &cp->sb);
    388 }
    389 
    390 /* Check and consume optional token. */
    391 static int cp_opt(CPState *cp, CPToken tok)
    392 {
    393   if (cp->tok == tok) { cp_next(cp); return 1; }
    394   return 0;
    395 }
    396 
    397 /* Check and consume token. */
    398 static void cp_check(CPState *cp, CPToken tok)
    399 {
    400   if (cp->tok != tok) cp_err_token(cp, tok);
    401   cp_next(cp);
    402 }
    403 
    404 /* Check if the next token may start a type declaration. */
    405 static int cp_istypedecl(CPState *cp)
    406 {
    407   if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECL) return 1;
    408   if (cp->tok == CTOK_IDENT && ctype_istypedef(cp->ct->info)) return 1;
    409   if (cp->tok == '$') return 1;
    410   return 0;
    411 }
    412 
    413 /* -- Constant expression evaluator --------------------------------------- */
    414 
    415 /* Forward declarations. */
    416 static void cp_expr_unary(CPState *cp, CPValue *k);
    417 static void cp_expr_sub(CPState *cp, CPValue *k, int pri);
    418 
    419 /* Please note that type handling is very weak here. Most ops simply
    420 ** assume integer operands. Accessors are only needed to compute types and
    421 ** return synthetic values. The only purpose of the expression evaluator
    422 ** is to compute the values of constant expressions one would typically
    423 ** find in C header files. And again: this is NOT a validating C parser!
    424 */
    425 
    426 /* Parse comma separated expression and return last result. */
    427 static void cp_expr_comma(CPState *cp, CPValue *k)
    428 {
    429   do { cp_expr_sub(cp, k, 0); } while (cp_opt(cp, ','));
    430 }
    431 
    432 /* Parse sizeof/alignof operator. */
    433 static void cp_expr_sizeof(CPState *cp, CPValue *k, int wantsz)
    434 {
    435   CTSize sz;
    436   CTInfo info;
    437   if (cp_opt(cp, '(')) {
    438     if (cp_istypedecl(cp))
    439       k->id = cp_decl_abstract(cp);
    440     else
    441       cp_expr_comma(cp, k);
    442     cp_check(cp, ')');
    443   } else {
    444     cp_expr_unary(cp, k);
    445   }
    446   info = lj_ctype_info(cp->cts, k->id, &sz);
    447   if (wantsz) {
    448     if (sz != CTSIZE_INVALID)
    449       k->u32 = sz;
    450     else if (k->id != CTID_A_CCHAR)  /* Special case for sizeof("string"). */
    451       cp_err(cp, LJ_ERR_FFI_INVSIZE);
    452   } else {
    453     k->u32 = 1u << ctype_align(info);
    454   }
    455   k->id = CTID_UINT32;  /* Really size_t. */
    456 }
    457 
    458 /* Parse prefix operators. */
    459 static void cp_expr_prefix(CPState *cp, CPValue *k)
    460 {
    461   if (cp->tok == CTOK_INTEGER) {
    462     *k = cp->val; cp_next(cp);
    463   } else if (cp_opt(cp, '+')) {
    464     cp_expr_unary(cp, k);  /* Nothing to do (well, integer promotion). */
    465   } else if (cp_opt(cp, '-')) {
    466     cp_expr_unary(cp, k); k->i32 = -k->i32;
    467   } else if (cp_opt(cp, '~')) {
    468     cp_expr_unary(cp, k); k->i32 = ~k->i32;
    469   } else if (cp_opt(cp, '!')) {
    470     cp_expr_unary(cp, k); k->i32 = !k->i32; k->id = CTID_INT32;
    471   } else if (cp_opt(cp, '(')) {
    472     if (cp_istypedecl(cp)) {  /* Cast operator. */
    473       CTypeID id = cp_decl_abstract(cp);
    474       cp_check(cp, ')');
    475       cp_expr_unary(cp, k);
    476       k->id = id;  /* No conversion performed. */
    477     } else {  /* Sub-expression. */
    478       cp_expr_comma(cp, k);
    479       cp_check(cp, ')');
    480     }
    481   } else if (cp_opt(cp, '*')) {  /* Indirection. */
    482     CType *ct;
    483     cp_expr_unary(cp, k);
    484     ct = lj_ctype_rawref(cp->cts, k->id);
    485     if (!ctype_ispointer(ct->info))
    486       cp_err_badidx(cp, ct);
    487     k->u32 = 0; k->id = ctype_cid(ct->info);
    488   } else if (cp_opt(cp, '&')) {  /* Address operator. */
    489     cp_expr_unary(cp, k);
    490     k->id = lj_ctype_intern(cp->cts, CTINFO(CT_PTR, CTALIGN_PTR+k->id),
    491 			    CTSIZE_PTR);
    492   } else if (cp_opt(cp, CTOK_SIZEOF)) {
    493     cp_expr_sizeof(cp, k, 1);
    494   } else if (cp_opt(cp, CTOK_ALIGNOF)) {
    495     cp_expr_sizeof(cp, k, 0);
    496   } else if (cp->tok == CTOK_IDENT) {
    497     if (ctype_type(cp->ct->info) == CT_CONSTVAL) {
    498       k->u32 = cp->ct->size; k->id = ctype_cid(cp->ct->info);
    499     } else if (ctype_type(cp->ct->info) == CT_EXTERN) {
    500       k->u32 = cp->val.id; k->id = ctype_cid(cp->ct->info);
    501     } else if (ctype_type(cp->ct->info) == CT_FUNC) {
    502       k->u32 = cp->val.id; k->id = cp->val.id;
    503     } else {
    504       goto err_expr;
    505     }
    506     cp_next(cp);
    507   } else if (cp->tok == CTOK_STRING) {
    508     CTSize sz = cp->str->len;
    509     while (cp_next(cp) == CTOK_STRING)
    510       sz += cp->str->len;
    511     k->u32 = sz + 1;
    512     k->id = CTID_A_CCHAR;
    513   } else {
    514   err_expr:
    515     cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
    516   }
    517 }
    518 
    519 /* Parse postfix operators. */
    520 static void cp_expr_postfix(CPState *cp, CPValue *k)
    521 {
    522   for (;;) {
    523     CType *ct;
    524     if (cp_opt(cp, '[')) {  /* Array/pointer index. */
    525       CPValue k2;
    526       cp_expr_comma(cp, &k2);
    527       ct = lj_ctype_rawref(cp->cts, k->id);
    528       if (!ctype_ispointer(ct->info)) {
    529 	ct = lj_ctype_rawref(cp->cts, k2.id);
    530 	if (!ctype_ispointer(ct->info))
    531 	  cp_err_badidx(cp, ct);
    532       }
    533       cp_check(cp, ']');
    534       k->u32 = 0;
    535     } else if (cp->tok == '.' || cp->tok == CTOK_DEREF) {  /* Struct deref. */
    536       CTSize ofs;
    537       CType *fct;
    538       ct = lj_ctype_rawref(cp->cts, k->id);
    539       if (cp->tok == CTOK_DEREF) {
    540 	if (!ctype_ispointer(ct->info))
    541 	  cp_err_badidx(cp, ct);
    542 	ct = lj_ctype_rawref(cp->cts, ctype_cid(ct->info));
    543       }
    544       cp_next(cp);
    545       if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
    546       if (!ctype_isstruct(ct->info) || ct->size == CTSIZE_INVALID ||
    547 	  !(fct = lj_ctype_getfield(cp->cts, ct, cp->str, &ofs)) ||
    548 	  ctype_isbitfield(fct->info)) {
    549 	GCstr *s = lj_ctype_repr(cp->cts->L, ctype_typeid(cp->cts, ct), NULL);
    550 	cp_errmsg(cp, 0, LJ_ERR_FFI_BADMEMBER, strdata(s), strdata(cp->str));
    551       }
    552       ct = fct;
    553       k->u32 = ctype_isconstval(ct->info) ? ct->size : 0;
    554       cp_next(cp);
    555     } else {
    556       return;
    557     }
    558     k->id = ctype_cid(ct->info);
    559   }
    560 }
    561 
    562 /* Parse infix operators. */
    563 static void cp_expr_infix(CPState *cp, CPValue *k, int pri)
    564 {
    565   CPValue k2;
    566   k2.u32 = 0; k2.id = 0;  /* Silence the compiler. */
    567   for (;;) {
    568     switch (pri) {
    569     case 0:
    570       if (cp_opt(cp, '?')) {
    571 	CPValue k3;
    572 	cp_expr_comma(cp, &k2);  /* Right-associative. */
    573 	cp_check(cp, ':');
    574 	cp_expr_sub(cp, &k3, 0);
    575 	k->u32 = k->u32 ? k2.u32 : k3.u32;
    576 	k->id = k2.id > k3.id ? k2.id : k3.id;
    577 	continue;
    578       }
    579     case 1:
    580       if (cp_opt(cp, CTOK_OROR)) {
    581 	cp_expr_sub(cp, &k2, 2); k->i32 = k->u32 || k2.u32; k->id = CTID_INT32;
    582 	continue;
    583       }
    584     case 2:
    585       if (cp_opt(cp, CTOK_ANDAND)) {
    586 	cp_expr_sub(cp, &k2, 3); k->i32 = k->u32 && k2.u32; k->id = CTID_INT32;
    587 	continue;
    588       }
    589     case 3:
    590       if (cp_opt(cp, '|')) {
    591 	cp_expr_sub(cp, &k2, 4); k->u32 = k->u32 | k2.u32; goto arith_result;
    592       }
    593     case 4:
    594       if (cp_opt(cp, '^')) {
    595 	cp_expr_sub(cp, &k2, 5); k->u32 = k->u32 ^ k2.u32; goto arith_result;
    596       }
    597     case 5:
    598       if (cp_opt(cp, '&')) {
    599 	cp_expr_sub(cp, &k2, 6); k->u32 = k->u32 & k2.u32; goto arith_result;
    600       }
    601     case 6:
    602       if (cp_opt(cp, CTOK_EQ)) {
    603 	cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 == k2.u32; k->id = CTID_INT32;
    604 	continue;
    605       } else if (cp_opt(cp, CTOK_NE)) {
    606 	cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 != k2.u32; k->id = CTID_INT32;
    607 	continue;
    608       }
    609     case 7:
    610       if (cp_opt(cp, '<')) {
    611 	cp_expr_sub(cp, &k2, 8);
    612 	if (k->id == CTID_INT32 && k2.id == CTID_INT32)
    613 	  k->i32 = k->i32 < k2.i32;
    614 	else
    615 	  k->i32 = k->u32 < k2.u32;
    616 	k->id = CTID_INT32;
    617 	continue;
    618       } else if (cp_opt(cp, '>')) {
    619 	cp_expr_sub(cp, &k2, 8);
    620 	if (k->id == CTID_INT32 && k2.id == CTID_INT32)
    621 	  k->i32 = k->i32 > k2.i32;
    622 	else
    623 	  k->i32 = k->u32 > k2.u32;
    624 	k->id = CTID_INT32;
    625 	continue;
    626       } else if (cp_opt(cp, CTOK_LE)) {
    627 	cp_expr_sub(cp, &k2, 8);
    628 	if (k->id == CTID_INT32 && k2.id == CTID_INT32)
    629 	  k->i32 = k->i32 <= k2.i32;
    630 	else
    631 	  k->i32 = k->u32 <= k2.u32;
    632 	k->id = CTID_INT32;
    633 	continue;
    634       } else if (cp_opt(cp, CTOK_GE)) {
    635 	cp_expr_sub(cp, &k2, 8);
    636 	if (k->id == CTID_INT32 && k2.id == CTID_INT32)
    637 	  k->i32 = k->i32 >= k2.i32;
    638 	else
    639 	  k->i32 = k->u32 >= k2.u32;
    640 	k->id = CTID_INT32;
    641 	continue;
    642       }
    643     case 8:
    644       if (cp_opt(cp, CTOK_SHL)) {
    645 	cp_expr_sub(cp, &k2, 9); k->u32 = k->u32 << k2.u32;
    646 	continue;
    647       } else if (cp_opt(cp, CTOK_SHR)) {
    648 	cp_expr_sub(cp, &k2, 9);
    649 	if (k->id == CTID_INT32)
    650 	  k->i32 = k->i32 >> k2.i32;
    651 	else
    652 	  k->u32 = k->u32 >> k2.u32;
    653 	continue;
    654       }
    655     case 9:
    656       if (cp_opt(cp, '+')) {
    657 	cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 + k2.u32;
    658       arith_result:
    659 	if (k2.id > k->id) k->id = k2.id;  /* Trivial promotion to unsigned. */
    660 	continue;
    661       } else if (cp_opt(cp, '-')) {
    662 	cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 - k2.u32; goto arith_result;
    663       }
    664     case 10:
    665       if (cp_opt(cp, '*')) {
    666 	cp_expr_unary(cp, &k2); k->u32 = k->u32 * k2.u32; goto arith_result;
    667       } else if (cp_opt(cp, '/')) {
    668 	cp_expr_unary(cp, &k2);
    669 	if (k2.id > k->id) k->id = k2.id;  /* Trivial promotion to unsigned. */
    670 	if (k2.u32 == 0 ||
    671 	    (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
    672 	  cp_err(cp, LJ_ERR_BADVAL);
    673 	if (k->id == CTID_INT32)
    674 	  k->i32 = k->i32 / k2.i32;
    675 	else
    676 	  k->u32 = k->u32 / k2.u32;
    677 	continue;
    678       } else if (cp_opt(cp, '%')) {
    679 	cp_expr_unary(cp, &k2);
    680 	if (k2.id > k->id) k->id = k2.id;  /* Trivial promotion to unsigned. */
    681 	if (k2.u32 == 0 ||
    682 	    (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
    683 	  cp_err(cp, LJ_ERR_BADVAL);
    684 	if (k->id == CTID_INT32)
    685 	  k->i32 = k->i32 % k2.i32;
    686 	else
    687 	  k->u32 = k->u32 % k2.u32;
    688 	continue;
    689       }
    690     default:
    691       return;
    692     }
    693   }
    694 }
    695 
    696 /* Parse and evaluate unary expression. */
    697 static void cp_expr_unary(CPState *cp, CPValue *k)
    698 {
    699   if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS);
    700   cp_expr_prefix(cp, k);
    701   cp_expr_postfix(cp, k);
    702   cp->depth--;
    703 }
    704 
    705 /* Parse and evaluate sub-expression. */
    706 static void cp_expr_sub(CPState *cp, CPValue *k, int pri)
    707 {
    708   cp_expr_unary(cp, k);
    709   cp_expr_infix(cp, k, pri);
    710 }
    711 
    712 /* Parse constant integer expression. */
    713 static void cp_expr_kint(CPState *cp, CPValue *k)
    714 {
    715   CType *ct;
    716   cp_expr_sub(cp, k, 0);
    717   ct = ctype_raw(cp->cts, k->id);
    718   if (!ctype_isinteger(ct->info)) cp_err(cp, LJ_ERR_BADVAL);
    719 }
    720 
    721 /* Parse (non-negative) size expression. */
    722 static CTSize cp_expr_ksize(CPState *cp)
    723 {
    724   CPValue k;
    725   cp_expr_kint(cp, &k);
    726   if (k.u32 >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE);
    727   return k.u32;
    728 }
    729 
    730 /* -- Type declaration stack management ----------------------------------- */
    731 
    732 /* Add declaration element behind the insertion position. */
    733 static CPDeclIdx cp_add(CPDecl *decl, CTInfo info, CTSize size)
    734 {
    735   CPDeclIdx top = decl->top;
    736   if (top >= CPARSE_MAX_DECLSTACK) cp_err(decl->cp, LJ_ERR_XLEVELS);
    737   decl->stack[top].info = info;
    738   decl->stack[top].size = size;
    739   decl->stack[top].sib = 0;
    740   setgcrefnull(decl->stack[top].name);
    741   decl->stack[top].next = decl->stack[decl->pos].next;
    742   decl->stack[decl->pos].next = (CTypeID1)top;
    743   decl->top = top+1;
    744   return top;
    745 }
    746 
    747 /* Push declaration element before the insertion position. */
    748 static CPDeclIdx cp_push(CPDecl *decl, CTInfo info, CTSize size)
    749 {
    750   return (decl->pos = cp_add(decl, info, size));
    751 }
    752 
    753 /* Push or merge attributes. */
    754 static void cp_push_attributes(CPDecl *decl)
    755 {
    756   CType *ct = &decl->stack[decl->pos];
    757   if (ctype_isfunc(ct->info)) {  /* Ok to modify in-place. */
    758 #if LJ_TARGET_X86
    759     if ((decl->fattr & CTFP_CCONV))
    760       ct->info = (ct->info & (CTMASK_NUM|CTF_VARARG|CTMASK_CID)) +
    761 		 (decl->fattr & ~CTMASK_CID);
    762 #endif
    763   } else {
    764     if ((decl->attr & CTFP_ALIGNED) && !(decl->mode & CPARSE_MODE_FIELD))
    765       cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_ALIGN)),
    766 	      ctype_align(decl->attr));
    767   }
    768 }
    769 
    770 /* Push unrolled type to declaration stack and merge qualifiers. */
    771 static void cp_push_type(CPDecl *decl, CTypeID id)
    772 {
    773   CType *ct = ctype_get(decl->cp->cts, id);
    774   CTInfo info = ct->info;
    775   CTSize size = ct->size;
    776   switch (ctype_type(info)) {
    777   case CT_STRUCT: case CT_ENUM:
    778     cp_push(decl, CTINFO(CT_TYPEDEF, id), 0);  /* Don't copy unique types. */
    779     if ((decl->attr & CTF_QUAL)) {  /* Push unmerged qualifiers. */
    780       cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_QUAL)),
    781 	      (decl->attr & CTF_QUAL));
    782       decl->attr &= ~CTF_QUAL;
    783     }
    784     break;
    785   case CT_ATTRIB:
    786     if (ctype_isxattrib(info, CTA_QUAL))
    787       decl->attr &= ~size;  /* Remove redundant qualifiers. */
    788     cp_push_type(decl, ctype_cid(info));  /* Unroll. */
    789     cp_push(decl, info & ~CTMASK_CID, size);  /* Copy type. */
    790     break;
    791   case CT_ARRAY:
    792     if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) {
    793       info |= (decl->attr & CTF_QUAL);
    794       decl->attr &= ~CTF_QUAL;
    795     }
    796     cp_push_type(decl, ctype_cid(info));  /* Unroll. */
    797     cp_push(decl, info & ~CTMASK_CID, size);  /* Copy type. */
    798     decl->stack[decl->pos].sib = 1;  /* Mark as already checked and sized. */
    799     /* Note: this is not copied to the ct->sib in the C type table. */
    800     break;
    801   case CT_FUNC:
    802     /* Copy type, link parameters (shared). */
    803     decl->stack[cp_push(decl, info, size)].sib = ct->sib;
    804     break;
    805   default:
    806     /* Copy type, merge common qualifiers. */
    807     cp_push(decl, info|(decl->attr & CTF_QUAL), size);
    808     decl->attr &= ~CTF_QUAL;
    809     break;
    810   }
    811 }
    812 
    813 /* Consume the declaration element chain and intern the C type. */
    814 static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl)
    815 {
    816   CTypeID id = 0;
    817   CPDeclIdx idx = 0;
    818   CTSize csize = CTSIZE_INVALID;
    819   CTSize cinfo = 0;
    820   do {
    821     CType *ct = &decl->stack[idx];
    822     CTInfo info = ct->info;
    823     CTInfo size = ct->size;
    824     /* The cid is already part of info for copies of pointers/functions. */
    825     idx = ct->next;
    826     if (ctype_istypedef(info)) {
    827       lua_assert(id == 0);
    828       id = ctype_cid(info);
    829       /* Always refetch info/size, since struct/enum may have been completed. */
    830       cinfo = ctype_get(cp->cts, id)->info;
    831       csize = ctype_get(cp->cts, id)->size;
    832       lua_assert(ctype_isstruct(cinfo) || ctype_isenum(cinfo));
    833     } else if (ctype_isfunc(info)) {  /* Intern function. */
    834       CType *fct;
    835       CTypeID fid;
    836       CTypeID sib;
    837       if (id) {
    838 	CType *refct = ctype_raw(cp->cts, id);
    839 	/* Reject function or refarray return types. */
    840 	if (ctype_isfunc(refct->info) || ctype_isrefarray(refct->info))
    841 	  cp_err(cp, LJ_ERR_FFI_INVTYPE);
    842       }
    843       /* No intervening attributes allowed, skip forward. */
    844       while (idx) {
    845 	CType *ctn = &decl->stack[idx];
    846 	if (!ctype_isattrib(ctn->info)) break;
    847 	idx = ctn->next;  /* Skip attribute. */
    848       }
    849       sib = ct->sib;  /* Next line may reallocate the C type table. */
    850       fid = lj_ctype_new(cp->cts, &fct);
    851       csize = CTSIZE_INVALID;
    852       fct->info = cinfo = info + id;
    853       fct->size = size;
    854       fct->sib = sib;
    855       id = fid;
    856     } else if (ctype_isattrib(info)) {
    857       if (ctype_isxattrib(info, CTA_QUAL))
    858 	cinfo |= size;
    859       else if (ctype_isxattrib(info, CTA_ALIGN))
    860 	CTF_INSERT(cinfo, ALIGN, size);
    861       id = lj_ctype_intern(cp->cts, info+id, size);
    862       /* Inherit csize/cinfo from original type. */
    863     } else {
    864       if (ctype_isnum(info)) {  /* Handle mode/vector-size attributes. */
    865 	lua_assert(id == 0);
    866 	if (!(info & CTF_BOOL)) {
    867 	  CTSize msize = ctype_msizeP(decl->attr);
    868 	  CTSize vsize = ctype_vsizeP(decl->attr);
    869 	  if (msize && (!(info & CTF_FP) || (msize == 4 || msize == 8))) {
    870 	    CTSize malign = lj_fls(msize);
    871 	    if (malign > 4) malign = 4;  /* Limit alignment. */
    872 	    CTF_INSERT(info, ALIGN, malign);
    873 	    size = msize;  /* Override size via mode. */
    874 	  }
    875 	  if (vsize) {  /* Vector size set? */
    876 	    CTSize esize = lj_fls(size);
    877 	    if (vsize >= esize) {
    878 	      /* Intern the element type first. */
    879 	      id = lj_ctype_intern(cp->cts, info, size);
    880 	      /* Then create a vector (array) with vsize alignment. */
    881 	      size = (1u << vsize);
    882 	      if (vsize > 4) vsize = 4;  /* Limit alignment. */
    883 	      if (ctype_align(info) > vsize) vsize = ctype_align(info);
    884 	      info = CTINFO(CT_ARRAY, (info & CTF_QUAL) + CTF_VECTOR +
    885 				      CTALIGN(vsize));
    886 	    }
    887 	  }
    888 	}
    889       } else if (ctype_isptr(info)) {
    890 	/* Reject pointer/ref to ref. */
    891 	if (id && ctype_isref(ctype_raw(cp->cts, id)->info))
    892 	  cp_err(cp, LJ_ERR_FFI_INVTYPE);
    893 	if (ctype_isref(info)) {
    894 	  info &= ~CTF_VOLATILE;  /* Refs are always const, never volatile. */
    895 	  /* No intervening attributes allowed, skip forward. */
    896 	  while (idx) {
    897 	    CType *ctn = &decl->stack[idx];
    898 	    if (!ctype_isattrib(ctn->info)) break;
    899 	    idx = ctn->next;  /* Skip attribute. */
    900 	  }
    901 	}
    902       } else if (ctype_isarray(info)) {  /* Check for valid array size etc. */
    903 	if (ct->sib == 0) {  /* Only check/size arrays not copied by unroll. */
    904 	  if (ctype_isref(cinfo))  /* Reject arrays of refs. */
    905 	    cp_err(cp, LJ_ERR_FFI_INVTYPE);
    906 	  /* Reject VLS or unknown-sized types. */
    907 	  if (ctype_isvltype(cinfo) || csize == CTSIZE_INVALID)
    908 	    cp_err(cp, LJ_ERR_FFI_INVSIZE);
    909 	  /* a[] and a[?] keep their invalid size. */
    910 	  if (size != CTSIZE_INVALID) {
    911 	    uint64_t xsz = (uint64_t)size * csize;
    912 	    if (xsz >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE);
    913 	    size = (CTSize)xsz;
    914 	  }
    915 	}
    916 	if ((cinfo & CTF_ALIGN) > (info & CTF_ALIGN))  /* Find max. align. */
    917 	  info = (info & ~CTF_ALIGN) | (cinfo & CTF_ALIGN);
    918 	info |= (cinfo & CTF_QUAL);  /* Inherit qual. */
    919       } else {
    920 	lua_assert(ctype_isvoid(info));
    921       }
    922       csize = size;
    923       cinfo = info+id;
    924       id = lj_ctype_intern(cp->cts, info+id, size);
    925     }
    926   } while (idx);
    927   return id;
    928 }
    929 
    930 /* -- C declaration parser ------------------------------------------------ */
    931 
    932 #define H_(le, be)	LJ_ENDIAN_SELECT(0x##le, 0x##be)
    933 
    934 /* Reset declaration state to declaration specifier. */
    935 static void cp_decl_reset(CPDecl *decl)
    936 {
    937   decl->pos = decl->specpos;
    938   decl->top = decl->specpos+1;
    939   decl->stack[decl->specpos].next = 0;
    940   decl->attr = decl->specattr;
    941   decl->fattr = decl->specfattr;
    942   decl->name = NULL;
    943   decl->redir = NULL;
    944 }
    945 
    946 /* Parse constant initializer. */
    947 /* NYI: FP constants and strings as initializers. */
    948 static CTypeID cp_decl_constinit(CPState *cp, CType **ctp, CTypeID ctypeid)
    949 {
    950   CType *ctt = ctype_get(cp->cts, ctypeid);
    951   CTInfo info;
    952   CTSize size;
    953   CPValue k;
    954   CTypeID constid;
    955   while (ctype_isattrib(ctt->info)) {  /* Skip attributes. */
    956     ctypeid = ctype_cid(ctt->info);  /* Update ID, too. */
    957     ctt = ctype_get(cp->cts, ctypeid);
    958   }
    959   info = ctt->info;
    960   size = ctt->size;
    961   if (!ctype_isinteger(info) || !(info & CTF_CONST) || size > 4)
    962     cp_err(cp, LJ_ERR_FFI_INVTYPE);
    963   cp_check(cp, '=');
    964   cp_expr_sub(cp, &k, 0);
    965   constid = lj_ctype_new(cp->cts, ctp);
    966   (*ctp)->info = CTINFO(CT_CONSTVAL, CTF_CONST|ctypeid);
    967   k.u32 <<= 8*(4-size);
    968   if ((info & CTF_UNSIGNED))
    969     k.u32 >>= 8*(4-size);
    970   else
    971     k.u32 = (uint32_t)((int32_t)k.u32 >> 8*(4-size));
    972   (*ctp)->size = k.u32;
    973   return constid;
    974 }
    975 
    976 /* Parse size in parentheses as part of attribute. */
    977 static CTSize cp_decl_sizeattr(CPState *cp)
    978 {
    979   CTSize sz;
    980   uint32_t oldtmask = cp->tmask;
    981   cp->tmask = CPNS_DEFAULT;  /* Required for expression evaluator. */
    982   cp_check(cp, '(');
    983   sz = cp_expr_ksize(cp);
    984   cp->tmask = oldtmask;
    985   cp_check(cp, ')');
    986   return sz;
    987 }
    988 
    989 /* Parse alignment attribute. */
    990 static void cp_decl_align(CPState *cp, CPDecl *decl)
    991 {
    992   CTSize al = 4;  /* Unspecified alignment is 16 bytes. */
    993   if (cp->tok == '(') {
    994     al = cp_decl_sizeattr(cp);
    995     al = al ? lj_fls(al) : 0;
    996   }
    997   CTF_INSERT(decl->attr, ALIGN, al);
    998   decl->attr |= CTFP_ALIGNED;
    999 }
   1000 
   1001 /* Parse GCC asm("name") redirect. */
   1002 static void cp_decl_asm(CPState *cp, CPDecl *decl)
   1003 {
   1004   UNUSED(decl);
   1005   cp_next(cp);
   1006   cp_check(cp, '(');
   1007   if (cp->tok == CTOK_STRING) {
   1008     GCstr *str = cp->str;
   1009     while (cp_next(cp) == CTOK_STRING) {
   1010       lj_strfmt_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str));
   1011       cp->L->top--;
   1012       str = strV(cp->L->top);
   1013     }
   1014     decl->redir = str;
   1015   }
   1016   cp_check(cp, ')');
   1017 }
   1018 
   1019 /* Parse GCC __attribute__((mode(...))). */
   1020 static void cp_decl_mode(CPState *cp, CPDecl *decl)
   1021 {
   1022   cp_check(cp, '(');
   1023   if (cp->tok == CTOK_IDENT) {
   1024     const char *s = strdata(cp->str);
   1025     CTSize sz = 0, vlen = 0;
   1026     if (s[0] == '_' && s[1] == '_') s += 2;
   1027     if (*s == 'V') {
   1028       s++;
   1029       vlen = *s++ - '0';
   1030       if (*s >= '0' && *s <= '9')
   1031 	vlen = vlen*10 + (*s++ - '0');
   1032     }
   1033     switch (*s++) {
   1034     case 'Q': sz = 1; break;
   1035     case 'H': sz = 2; break;
   1036     case 'S': sz = 4; break;
   1037     case 'D': sz = 8; break;
   1038     case 'T': sz = 16; break;
   1039     case 'O': sz = 32; break;
   1040     default: goto bad_size;
   1041     }
   1042     if (*s == 'I' || *s == 'F') {
   1043       CTF_INSERT(decl->attr, MSIZEP, sz);
   1044       if (vlen) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vlen*sz));
   1045     }
   1046   bad_size:
   1047     cp_next(cp);
   1048   }
   1049   cp_check(cp, ')');
   1050 }
   1051 
   1052 /* Parse GCC __attribute__((...)). */
   1053 static void cp_decl_gccattribute(CPState *cp, CPDecl *decl)
   1054 {
   1055   cp_next(cp);
   1056   cp_check(cp, '(');
   1057   cp_check(cp, '(');
   1058   while (cp->tok != ')') {
   1059     if (cp->tok == CTOK_IDENT) {
   1060       GCstr *attrstr = cp->str;
   1061       cp_next(cp);
   1062       switch (attrstr->hash) {
   1063       case H_(64a9208e,8ce14319): case H_(8e6331b2,95a282af):  /* aligned */
   1064 	cp_decl_align(cp, decl);
   1065 	break;
   1066       case H_(42eb47de,f0ede26c): case H_(29f48a09,cf383e0c):  /* packed */
   1067 	decl->attr |= CTFP_PACKED;
   1068 	break;
   1069       case H_(0a84eef6,8dfab04c): case H_(995cf92c,d5696591):  /* mode */
   1070 	cp_decl_mode(cp, decl);
   1071 	break;
   1072       case H_(0ab31997,2d5213fa): case H_(bf875611,200e9990):  /* vector_size */
   1073 	{
   1074 	  CTSize vsize = cp_decl_sizeattr(cp);
   1075 	  if (vsize) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vsize));
   1076 	}
   1077 	break;
   1078 #if LJ_TARGET_X86
   1079       case H_(5ad22db8,c689b848): case H_(439150fa,65ea78cb):  /* regparm */
   1080 	CTF_INSERT(decl->fattr, REGPARM, cp_decl_sizeattr(cp));
   1081 	decl->fattr |= CTFP_CCONV;
   1082 	break;
   1083       case H_(18fc0b98,7ff4c074): case H_(4e62abed,0a747424):  /* cdecl */
   1084 	CTF_INSERT(decl->fattr, CCONV, CTCC_CDECL);
   1085 	decl->fattr |= CTFP_CCONV;
   1086 	break;
   1087       case H_(72b2e41b,494c5a44): case H_(f2356d59,f25fc9bd):  /* thiscall */
   1088 	CTF_INSERT(decl->fattr, CCONV, CTCC_THISCALL);
   1089 	decl->fattr |= CTFP_CCONV;
   1090 	break;
   1091       case H_(0d0ffc42,ab746f88): case H_(21c54ba1,7f0ca7e3):  /* fastcall */
   1092 	CTF_INSERT(decl->fattr, CCONV, CTCC_FASTCALL);
   1093 	decl->fattr |= CTFP_CCONV;
   1094 	break;
   1095       case H_(ef76b040,9412e06a): case H_(de56697b,c750e6e1):  /* stdcall */
   1096 	CTF_INSERT(decl->fattr, CCONV, CTCC_STDCALL);
   1097 	decl->fattr |= CTFP_CCONV;
   1098 	break;
   1099       case H_(ea78b622,f234bd8e): case H_(252ffb06,8d50f34b):  /* sseregparm */
   1100 	decl->fattr |= CTF_SSEREGPARM;
   1101 	decl->fattr |= CTFP_CCONV;
   1102 	break;
   1103 #endif
   1104       default:  /* Skip all other attributes. */
   1105 	goto skip_attr;
   1106       }
   1107     } else if (cp->tok >= CTOK_FIRSTDECL) {  /* For __attribute((const)) etc. */
   1108       cp_next(cp);
   1109     skip_attr:
   1110       if (cp_opt(cp, '(')) {
   1111 	while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp);
   1112 	cp_check(cp, ')');
   1113       }
   1114     } else {
   1115       break;
   1116     }
   1117     if (!cp_opt(cp, ',')) break;
   1118   }
   1119   cp_check(cp, ')');
   1120   cp_check(cp, ')');
   1121 }
   1122 
   1123 /* Parse MSVC __declspec(...). */
   1124 static void cp_decl_msvcattribute(CPState *cp, CPDecl *decl)
   1125 {
   1126   cp_next(cp);
   1127   cp_check(cp, '(');
   1128   while (cp->tok == CTOK_IDENT) {
   1129     GCstr *attrstr = cp->str;
   1130     cp_next(cp);
   1131     switch (attrstr->hash) {
   1132     case H_(bc2395fa,98f267f8):  /* align */
   1133       cp_decl_align(cp, decl);
   1134       break;
   1135     default:  /* Ignore all other attributes. */
   1136       if (cp_opt(cp, '(')) {
   1137 	while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp);
   1138 	cp_check(cp, ')');
   1139       }
   1140       break;
   1141     }
   1142   }
   1143   cp_check(cp, ')');
   1144 }
   1145 
   1146 /* Parse declaration attributes (and common qualifiers). */
   1147 static void cp_decl_attributes(CPState *cp, CPDecl *decl)
   1148 {
   1149   for (;;) {
   1150     switch (cp->tok) {
   1151     case CTOK_CONST: decl->attr |= CTF_CONST; break;
   1152     case CTOK_VOLATILE: decl->attr |= CTF_VOLATILE; break;
   1153     case CTOK_RESTRICT: break;  /* Ignore. */
   1154     case CTOK_EXTENSION: break;  /* Ignore. */
   1155     case CTOK_ATTRIBUTE: cp_decl_gccattribute(cp, decl); continue;
   1156     case CTOK_ASM: cp_decl_asm(cp, decl); continue;
   1157     case CTOK_DECLSPEC: cp_decl_msvcattribute(cp, decl); continue;
   1158     case CTOK_CCDECL:
   1159 #if LJ_TARGET_X86
   1160       CTF_INSERT(decl->fattr, CCONV, cp->ct->size);
   1161       decl->fattr |= CTFP_CCONV;
   1162 #endif
   1163       break;
   1164     case CTOK_PTRSZ:
   1165 #if LJ_64
   1166       CTF_INSERT(decl->attr, MSIZEP, cp->ct->size);
   1167 #endif
   1168       break;
   1169     default: return;
   1170     }
   1171     cp_next(cp);
   1172   }
   1173 }
   1174 
   1175 /* Parse struct/union/enum name. */
   1176 static CTypeID cp_struct_name(CPState *cp, CPDecl *sdecl, CTInfo info)
   1177 {
   1178   CTypeID sid;
   1179   CType *ct;
   1180   cp->tmask = CPNS_STRUCT;
   1181   cp_next(cp);
   1182   cp_decl_attributes(cp, sdecl);
   1183   cp->tmask = CPNS_DEFAULT;
   1184   if (cp->tok != '{') {
   1185     if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
   1186     if (cp->val.id) {  /* Name of existing struct/union/enum. */
   1187       sid = cp->val.id;
   1188       ct = cp->ct;
   1189       if ((ct->info ^ info) & (CTMASK_NUM|CTF_UNION))  /* Wrong type. */
   1190 	cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name))));
   1191     } else {  /* Create named, incomplete struct/union/enum. */
   1192       if ((cp->mode & CPARSE_MODE_NOIMPLICIT))
   1193 	cp_errmsg(cp, 0, LJ_ERR_FFI_BADTAG, strdata(cp->str));
   1194       sid = lj_ctype_new(cp->cts, &ct);
   1195       ct->info = info;
   1196       ct->size = CTSIZE_INVALID;
   1197       ctype_setname(ct, cp->str);
   1198       lj_ctype_addname(cp->cts, ct, sid);
   1199     }
   1200     cp_next(cp);
   1201   } else {  /* Create anonymous, incomplete struct/union/enum. */
   1202     sid = lj_ctype_new(cp->cts, &ct);
   1203     ct->info = info;
   1204     ct->size = CTSIZE_INVALID;
   1205   }
   1206   if (cp->tok == '{') {
   1207     if (ct->size != CTSIZE_INVALID || ct->sib)
   1208       cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name))));
   1209     ct->sib = 1;  /* Indicate the type is currently being defined. */
   1210   }
   1211   return sid;
   1212 }
   1213 
   1214 /* Determine field alignment. */
   1215 static CTSize cp_field_align(CPState *cp, CType *ct, CTInfo info)
   1216 {
   1217   CTSize align = ctype_align(info);
   1218   UNUSED(cp); UNUSED(ct);
   1219 #if (LJ_TARGET_X86 && (!LJ_ABI_WIN || LJ_TARGET_POSIX)) || (LJ_TARGET_ARM && __APPLE__)
   1220   /* The SYSV i386 and iOS ABIs limit alignment of non-vector fields to 2^2. */
   1221   if (align > 2 && !(info & CTFP_ALIGNED)) {
   1222     if (ctype_isarray(info) && !(info & CTF_VECTOR)) {
   1223       do {
   1224 	ct = ctype_rawchild(cp->cts, ct);
   1225 	info = ct->info;
   1226       } while (ctype_isarray(info) && !(info & CTF_VECTOR));
   1227     }
   1228     if (ctype_isnum(info) || ctype_isenum(info))
   1229       align = 2;
   1230   }
   1231 #endif
   1232   return align;
   1233 }
   1234 
   1235 /* Layout struct/union fields. */
   1236 static void cp_struct_layout(CPState *cp, CTypeID sid, CTInfo sattr)
   1237 {
   1238   CTSize bofs = 0, bmaxofs = 0;  /* Bit offset and max. bit offset. */
   1239   CTSize maxalign = ctype_align(sattr);
   1240   CType *sct = ctype_get(cp->cts, sid);
   1241   CTInfo sinfo = sct->info;
   1242   CTypeID fieldid = sct->sib;
   1243   while (fieldid) {
   1244     CType *ct = ctype_get(cp->cts, fieldid);
   1245     CTInfo attr = ct->size;  /* Field declaration attributes (temp.). */
   1246 
   1247     if (ctype_isfield(ct->info) ||
   1248 	(ctype_isxattrib(ct->info, CTA_SUBTYPE) && attr)) {
   1249       CTSize align, amask;  /* Alignment (pow2) and alignment mask (bits). */
   1250       CTSize sz;
   1251       CTInfo info = lj_ctype_info(cp->cts, ctype_cid(ct->info), &sz);
   1252       CTSize bsz, csz = 8*sz;  /* Field size and container size (in bits). */
   1253       sinfo |= (info & (CTF_QUAL|CTF_VLA));  /* Merge pseudo-qualifiers. */
   1254 
   1255       /* Check for size overflow and determine alignment. */
   1256       if (sz >= 0x20000000u || bofs + csz < bofs || (info & CTF_VLA)) {
   1257 	if (!(sz == CTSIZE_INVALID && ctype_isarray(info) &&
   1258 	      !(sinfo & CTF_UNION)))
   1259 	  cp_err(cp, LJ_ERR_FFI_INVSIZE);
   1260 	csz = sz = 0;  /* Treat a[] and a[?] as zero-sized. */
   1261       }
   1262       align = cp_field_align(cp, ct, info);
   1263       if (((attr|sattr) & CTFP_PACKED) ||
   1264 	  ((attr & CTFP_ALIGNED) && ctype_align(attr) > align))
   1265 	align = ctype_align(attr);
   1266       if (cp->packstack[cp->curpack] < align)
   1267 	align = cp->packstack[cp->curpack];
   1268       if (align > maxalign) maxalign = align;
   1269       amask = (8u << align) - 1;
   1270 
   1271       bsz = ctype_bitcsz(ct->info);  /* Bitfield size (temp.). */
   1272       if (bsz == CTBSZ_FIELD || !ctype_isfield(ct->info)) {
   1273 	bsz = csz;  /* Regular fields or subtypes always fill the container. */
   1274 	bofs = (bofs + amask) & ~amask;  /* Start new aligned field. */
   1275 	ct->size = (bofs >> 3);  /* Store field offset. */
   1276       } else {  /* Bitfield. */
   1277 	if (bsz == 0 || (attr & CTFP_ALIGNED) ||
   1278 	    (!((attr|sattr) & CTFP_PACKED) && (bofs & amask) + bsz > csz))
   1279 	  bofs = (bofs + amask) & ~amask;  /* Start new aligned field. */
   1280 
   1281 	/* Prefer regular field over bitfield. */
   1282 	if (bsz == csz && (bofs & amask) == 0) {
   1283 	  ct->info = CTINFO(CT_FIELD, ctype_cid(ct->info));
   1284 	  ct->size = (bofs >> 3);  /* Store field offset. */
   1285 	} else {
   1286 	  ct->info = CTINFO(CT_BITFIELD,
   1287 	    (info & (CTF_QUAL|CTF_UNSIGNED|CTF_BOOL)) +
   1288 	    (csz << (CTSHIFT_BITCSZ-3)) + (bsz << CTSHIFT_BITBSZ));
   1289 #if LJ_BE
   1290 	  ct->info += ((csz - (bofs & (csz-1)) - bsz) << CTSHIFT_BITPOS);
   1291 #else
   1292 	  ct->info += ((bofs & (csz-1)) << CTSHIFT_BITPOS);
   1293 #endif
   1294 	  ct->size = ((bofs & ~(csz-1)) >> 3);  /* Store container offset. */
   1295 	}
   1296       }
   1297 
   1298       /* Determine next offset or max. offset. */
   1299       if ((sinfo & CTF_UNION)) {
   1300 	if (bsz > bmaxofs) bmaxofs = bsz;
   1301       } else {
   1302 	bofs += bsz;
   1303       }
   1304     }  /* All other fields in the chain are already set up. */
   1305 
   1306     fieldid = ct->sib;
   1307   }
   1308 
   1309   /* Complete struct/union. */
   1310   sct->info = sinfo + CTALIGN(maxalign);
   1311   bofs = (sinfo & CTF_UNION) ? bmaxofs : bofs;
   1312   maxalign = (8u << maxalign) - 1;
   1313   sct->size = (((bofs + maxalign) & ~maxalign) >> 3);
   1314 }
   1315 
   1316 /* Parse struct/union declaration. */
   1317 static CTypeID cp_decl_struct(CPState *cp, CPDecl *sdecl, CTInfo sinfo)
   1318 {
   1319   CTypeID sid = cp_struct_name(cp, sdecl, sinfo);
   1320   if (cp_opt(cp, '{')) {  /* Struct/union definition. */
   1321     CTypeID lastid = sid;
   1322     int lastdecl = 0;
   1323     while (cp->tok != '}') {
   1324       CPDecl decl;
   1325       CPscl scl = cp_decl_spec(cp, &decl, CDF_STATIC);
   1326       decl.mode = scl ? CPARSE_MODE_DIRECT :
   1327 	CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT|CPARSE_MODE_FIELD;
   1328 
   1329       for (;;) {
   1330 	CTypeID ctypeid;
   1331 
   1332 	if (lastdecl) cp_err_token(cp, '}');
   1333 
   1334 	/* Parse field declarator. */
   1335 	decl.bits = CTSIZE_INVALID;
   1336 	cp_declarator(cp, &decl);
   1337 	ctypeid = cp_decl_intern(cp, &decl);
   1338 
   1339 	if ((scl & CDF_STATIC)) {  /* Static constant in struct namespace. */
   1340 	  CType *ct;
   1341 	  CTypeID fieldid = cp_decl_constinit(cp, &ct, ctypeid);
   1342 	  ctype_get(cp->cts, lastid)->sib = fieldid;
   1343 	  lastid = fieldid;
   1344 	  ctype_setname(ct, decl.name);
   1345 	} else {
   1346 	  CTSize bsz = CTBSZ_FIELD;  /* Temp. for layout phase. */
   1347 	  CType *ct;
   1348 	  CTypeID fieldid = lj_ctype_new(cp->cts, &ct);  /* Do this first. */
   1349 	  CType *tct = ctype_raw(cp->cts, ctypeid);
   1350 
   1351 	  if (decl.bits == CTSIZE_INVALID) {  /* Regular field. */
   1352 	    if (ctype_isarray(tct->info) && tct->size == CTSIZE_INVALID)
   1353 	      lastdecl = 1;  /* a[] or a[?] must be the last declared field. */
   1354 
   1355 	    /* Accept transparent struct/union/enum. */
   1356 	    if (!decl.name) {
   1357 	      if (!((ctype_isstruct(tct->info) && !(tct->info & CTF_VLA)) ||
   1358 		    ctype_isenum(tct->info)))
   1359 		cp_err_token(cp, CTOK_IDENT);
   1360 	      ct->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_SUBTYPE) + ctypeid);
   1361 	      ct->size = ctype_isstruct(tct->info) ?
   1362 			 (decl.attr|0x80000000u) : 0;  /* For layout phase. */
   1363 	      goto add_field;
   1364 	    }
   1365 	  } else {  /* Bitfield. */
   1366 	    bsz = decl.bits;
   1367 	    if (!ctype_isinteger_or_bool(tct->info) ||
   1368 		(bsz == 0 && decl.name) || 8*tct->size > CTBSZ_MAX ||
   1369 		bsz > ((tct->info & CTF_BOOL) ? 1 : 8*tct->size))
   1370 	      cp_errmsg(cp, ':', LJ_ERR_BADVAL);
   1371 	  }
   1372 
   1373 	  /* Create temporary field for layout phase. */
   1374 	  ct->info = CTINFO(CT_FIELD, ctypeid + (bsz << CTSHIFT_BITCSZ));
   1375 	  ct->size = decl.attr;
   1376 	  if (decl.name) ctype_setname(ct, decl.name);
   1377 
   1378 	add_field:
   1379 	  ctype_get(cp->cts, lastid)->sib = fieldid;
   1380 	  lastid = fieldid;
   1381 	}
   1382 	if (!cp_opt(cp, ',')) break;
   1383 	cp_decl_reset(&decl);
   1384       }
   1385       cp_check(cp, ';');
   1386     }
   1387     cp_check(cp, '}');
   1388     ctype_get(cp->cts, lastid)->sib = 0;  /* Drop sib = 1 for empty structs. */
   1389     cp_decl_attributes(cp, sdecl);  /* Layout phase needs postfix attributes. */
   1390     cp_struct_layout(cp, sid, sdecl->attr);
   1391   }
   1392   return sid;
   1393 }
   1394 
   1395 /* Parse enum declaration. */
   1396 static CTypeID cp_decl_enum(CPState *cp, CPDecl *sdecl)
   1397 {
   1398   CTypeID eid = cp_struct_name(cp, sdecl, CTINFO(CT_ENUM, CTID_VOID));
   1399   CTInfo einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_UINT32);
   1400   CTSize esize = 4;  /* Only 32 bit enums are supported. */
   1401   if (cp_opt(cp, '{')) {  /* Enum definition. */
   1402     CPValue k;
   1403     CTypeID lastid = eid;
   1404     k.u32 = 0;
   1405     k.id = CTID_INT32;
   1406     do {
   1407       GCstr *name = cp->str;
   1408       if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
   1409       if (cp->val.id) cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(name));
   1410       cp_next(cp);
   1411       if (cp_opt(cp, '=')) {
   1412 	cp_expr_kint(cp, &k);
   1413 	if (k.id == CTID_UINT32) {
   1414 	  /* C99 says that enum constants are always (signed) integers.
   1415 	  ** But since unsigned constants like 0x80000000 are quite common,
   1416 	  ** those are left as uint32_t.
   1417 	  */
   1418 	  if (k.i32 >= 0) k.id = CTID_INT32;
   1419 	} else {
   1420 	  /* OTOH it's common practice and even mandated by some ABIs
   1421 	  ** that the enum type itself is unsigned, unless there are any
   1422 	  ** negative constants.
   1423 	  */
   1424 	  k.id = CTID_INT32;
   1425 	  if (k.i32 < 0) einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_INT32);
   1426 	}
   1427       }
   1428       /* Add named enum constant. */
   1429       {
   1430 	CType *ct;
   1431 	CTypeID constid = lj_ctype_new(cp->cts, &ct);
   1432 	ctype_get(cp->cts, lastid)->sib = constid;
   1433 	lastid = constid;
   1434 	ctype_setname(ct, name);
   1435 	ct->info = CTINFO(CT_CONSTVAL, CTF_CONST|k.id);
   1436 	ct->size = k.u32++;
   1437 	if (k.u32 == 0x80000000u) k.id = CTID_UINT32;
   1438 	lj_ctype_addname(cp->cts, ct, constid);
   1439       }
   1440       if (!cp_opt(cp, ',')) break;
   1441     } while (cp->tok != '}');  /* Trailing ',' is ok. */
   1442     cp_check(cp, '}');
   1443     /* Complete enum. */
   1444     ctype_get(cp->cts, eid)->info = einfo;
   1445     ctype_get(cp->cts, eid)->size = esize;
   1446   }
   1447   return eid;
   1448 }
   1449 
   1450 /* Parse declaration specifiers. */
   1451 static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl)
   1452 {
   1453   uint32_t cds = 0, sz = 0;
   1454   CTypeID tdef = 0;
   1455 
   1456   decl->cp = cp;
   1457   decl->mode = cp->mode;
   1458   decl->name = NULL;
   1459   decl->redir = NULL;
   1460   decl->attr = 0;
   1461   decl->fattr = 0;
   1462   decl->pos = decl->top = 0;
   1463   decl->stack[0].next = 0;
   1464 
   1465   for (;;) {  /* Parse basic types. */
   1466     cp_decl_attributes(cp, decl);
   1467     if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECLFLAG) {
   1468       uint32_t cbit;
   1469       if (cp->ct->size) {
   1470 	if (sz) goto end_decl;
   1471 	sz = cp->ct->size;
   1472       }
   1473       cbit = (1u << (cp->tok - CTOK_FIRSTDECL));
   1474       cds = cds | cbit | ((cbit & cds & CDF_LONG) << 1);
   1475       if (cp->tok >= CTOK_FIRSTSCL) {
   1476 	if (!(scl & cbit)) cp_errmsg(cp, cp->tok, LJ_ERR_FFI_BADSCL);
   1477       } else if (tdef) {
   1478 	goto end_decl;
   1479       }
   1480       cp_next(cp);
   1481       continue;
   1482     }
   1483     if (sz || tdef ||
   1484 	(cds & (CDF_SHORT|CDF_LONG|CDF_SIGNED|CDF_UNSIGNED|CDF_COMPLEX)))
   1485       break;
   1486     switch (cp->tok) {
   1487     case CTOK_STRUCT:
   1488       tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, 0));
   1489       continue;
   1490     case CTOK_UNION:
   1491       tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, CTF_UNION));
   1492       continue;
   1493     case CTOK_ENUM:
   1494       tdef = cp_decl_enum(cp, decl);
   1495       continue;
   1496     case CTOK_IDENT:
   1497       if (ctype_istypedef(cp->ct->info)) {
   1498 	tdef = ctype_cid(cp->ct->info);  /* Get typedef. */
   1499 	cp_next(cp);
   1500 	continue;
   1501       }
   1502       break;
   1503     case '$':
   1504       tdef = cp->val.id;
   1505       cp_next(cp);
   1506       continue;
   1507     default:
   1508       break;
   1509     }
   1510     break;
   1511   }
   1512 end_decl:
   1513 
   1514   if ((cds & CDF_COMPLEX))  /* Use predefined complex types. */
   1515     tdef = sz == 4 ? CTID_COMPLEX_FLOAT : CTID_COMPLEX_DOUBLE;
   1516 
   1517   if (tdef) {
   1518     cp_push_type(decl, tdef);
   1519   } else if ((cds & CDF_VOID)) {
   1520     cp_push(decl, CTINFO(CT_VOID, (decl->attr & CTF_QUAL)), CTSIZE_INVALID);
   1521     decl->attr &= ~CTF_QUAL;
   1522   } else {
   1523     /* Determine type info and size. */
   1524     CTInfo info = CTINFO(CT_NUM, (cds & CDF_UNSIGNED) ? CTF_UNSIGNED : 0);
   1525     if ((cds & CDF_BOOL)) {
   1526       if ((cds & ~(CDF_SCL|CDF_BOOL|CDF_INT|CDF_SIGNED|CDF_UNSIGNED)))
   1527 	cp_errmsg(cp, 0, LJ_ERR_FFI_INVTYPE);
   1528       info |= CTF_BOOL;
   1529       if (!(cds & CDF_SIGNED)) info |= CTF_UNSIGNED;
   1530       if (!sz) {
   1531 	sz = 1;
   1532       }
   1533     } else if ((cds & CDF_FP)) {
   1534       info = CTINFO(CT_NUM, CTF_FP);
   1535       if ((cds & CDF_LONG)) sz = sizeof(long double);
   1536     } else if ((cds & CDF_CHAR)) {
   1537       if ((cds & (CDF_CHAR|CDF_SIGNED|CDF_UNSIGNED)) == CDF_CHAR)
   1538 	info |= CTF_UCHAR;  /* Handle platforms where char is unsigned. */
   1539     } else if ((cds & CDF_SHORT)) {
   1540       sz = sizeof(short);
   1541     } else if ((cds & CDF_LONGLONG)) {
   1542       sz = 8;
   1543     } else if ((cds & CDF_LONG)) {
   1544       info |= CTF_LONG;
   1545       sz = sizeof(long);
   1546     } else if (!sz) {
   1547       if (!(cds & (CDF_SIGNED|CDF_UNSIGNED)))
   1548 	cp_errmsg(cp, cp->tok, LJ_ERR_FFI_DECLSPEC);
   1549       sz = sizeof(int);
   1550     }
   1551     lua_assert(sz != 0);
   1552     info += CTALIGN(lj_fls(sz));  /* Use natural alignment. */
   1553     info += (decl->attr & CTF_QUAL);  /* Merge qualifiers. */
   1554     cp_push(decl, info, sz);
   1555     decl->attr &= ~CTF_QUAL;
   1556   }
   1557   decl->specpos = decl->pos;
   1558   decl->specattr = decl->attr;
   1559   decl->specfattr = decl->fattr;
   1560   return (cds & CDF_SCL);  /* Return storage class. */
   1561 }
   1562 
   1563 /* Parse array declaration. */
   1564 static void cp_decl_array(CPState *cp, CPDecl *decl)
   1565 {
   1566   CTInfo info = CTINFO(CT_ARRAY, 0);
   1567   CTSize nelem = CTSIZE_INVALID;  /* Default size for a[] or a[?]. */
   1568   cp_decl_attributes(cp, decl);
   1569   if (cp_opt(cp, '?'))
   1570     info |= CTF_VLA;  /* Create variable-length array a[?]. */
   1571   else if (cp->tok != ']')
   1572     nelem = cp_expr_ksize(cp);
   1573   cp_check(cp, ']');
   1574   cp_add(decl, info, nelem);
   1575 }
   1576 
   1577 /* Parse function declaration. */
   1578 static void cp_decl_func(CPState *cp, CPDecl *fdecl)
   1579 {
   1580   CTSize nargs = 0;
   1581   CTInfo info = CTINFO(CT_FUNC, 0);
   1582   CTypeID lastid = 0, anchor = 0;
   1583   if (cp->tok != ')') {
   1584     do {
   1585       CPDecl decl;
   1586       CTypeID ctypeid, fieldid;
   1587       CType *ct;
   1588       if (cp_opt(cp, '.')) {  /* Vararg function. */
   1589 	cp_check(cp, '.');  /* Workaround for the minimalistic lexer. */
   1590 	cp_check(cp, '.');
   1591 	info |= CTF_VARARG;
   1592 	break;
   1593       }
   1594       cp_decl_spec(cp, &decl, CDF_REGISTER);
   1595       decl.mode = CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT;
   1596       cp_declarator(cp, &decl);
   1597       ctypeid = cp_decl_intern(cp, &decl);
   1598       ct = ctype_raw(cp->cts, ctypeid);
   1599       if (ctype_isvoid(ct->info))
   1600 	break;
   1601       else if (ctype_isrefarray(ct->info))
   1602 	ctypeid = lj_ctype_intern(cp->cts,
   1603 	  CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ct->info)), CTSIZE_PTR);
   1604       else if (ctype_isfunc(ct->info))
   1605 	ctypeid = lj_ctype_intern(cp->cts,
   1606 	  CTINFO(CT_PTR, CTALIGN_PTR|ctypeid), CTSIZE_PTR);
   1607       /* Add new parameter. */
   1608       fieldid = lj_ctype_new(cp->cts, &ct);
   1609       if (anchor)
   1610 	ctype_get(cp->cts, lastid)->sib = fieldid;
   1611       else
   1612 	anchor = fieldid;
   1613       lastid = fieldid;
   1614       if (decl.name) ctype_setname(ct, decl.name);
   1615       ct->info = CTINFO(CT_FIELD, ctypeid);
   1616       ct->size = nargs++;
   1617     } while (cp_opt(cp, ','));
   1618   }
   1619   cp_check(cp, ')');
   1620   if (cp_opt(cp, '{')) {  /* Skip function definition. */
   1621     int level = 1;
   1622     cp->mode |= CPARSE_MODE_SKIP;
   1623     for (;;) {
   1624       if (cp->tok == '{') level++;
   1625       else if (cp->tok == '}' && --level == 0) break;
   1626       else if (cp->tok == CTOK_EOF) cp_err_token(cp, '}');
   1627       cp_next(cp);
   1628     }
   1629     cp->mode &= ~CPARSE_MODE_SKIP;
   1630     cp->tok = ';';  /* Ok for cp_decl_multi(), error in cp_decl_single(). */
   1631   }
   1632   info |= (fdecl->fattr & ~CTMASK_CID);
   1633   fdecl->fattr = 0;
   1634   fdecl->stack[cp_add(fdecl, info, nargs)].sib = anchor;
   1635 }
   1636 
   1637 /* Parse declarator. */
   1638 static void cp_declarator(CPState *cp, CPDecl *decl)
   1639 {
   1640   if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS);
   1641 
   1642   for (;;) {  /* Head of declarator. */
   1643     if (cp_opt(cp, '*')) {  /* Pointer. */
   1644       CTSize sz;
   1645       CTInfo info;
   1646       cp_decl_attributes(cp, decl);
   1647       sz = CTSIZE_PTR;
   1648       info = CTINFO(CT_PTR, CTALIGN_PTR);
   1649 #if LJ_64
   1650       if (ctype_msizeP(decl->attr) == 4) {
   1651 	sz = 4;
   1652 	info = CTINFO(CT_PTR, CTALIGN(2));
   1653       }
   1654 #endif
   1655       info += (decl->attr & (CTF_QUAL|CTF_REF));
   1656       decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP));
   1657       cp_push(decl, info, sz);
   1658     } else if (cp_opt(cp, '&') || cp_opt(cp, CTOK_ANDAND)) {  /* Reference. */
   1659       decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP));
   1660       cp_push(decl, CTINFO_REF(0), CTSIZE_PTR);
   1661     } else {
   1662       break;
   1663     }
   1664   }
   1665 
   1666   if (cp_opt(cp, '(')) {  /* Inner declarator. */
   1667     CPDeclIdx pos;
   1668     cp_decl_attributes(cp, decl);
   1669     /* Resolve ambiguity between inner declarator and 1st function parameter. */
   1670     if ((decl->mode & CPARSE_MODE_ABSTRACT) &&
   1671 	(cp->tok == ')' || cp_istypedecl(cp))) goto func_decl;
   1672     pos = decl->pos;
   1673     cp_declarator(cp, decl);
   1674     cp_check(cp, ')');
   1675     decl->pos = pos;
   1676   } else if (cp->tok == CTOK_IDENT) {  /* Direct declarator. */
   1677     if (!(decl->mode & CPARSE_MODE_DIRECT)) cp_err_token(cp, CTOK_EOF);
   1678     decl->name = cp->str;
   1679     decl->nameid = cp->val.id;
   1680     cp_next(cp);
   1681   } else {  /* Abstract declarator. */
   1682     if (!(decl->mode & CPARSE_MODE_ABSTRACT)) cp_err_token(cp, CTOK_IDENT);
   1683   }
   1684 
   1685   for (;;) {  /* Tail of declarator. */
   1686     if (cp_opt(cp, '[')) {  /* Array. */
   1687       cp_decl_array(cp, decl);
   1688     } else if (cp_opt(cp, '(')) {  /* Function. */
   1689     func_decl:
   1690       cp_decl_func(cp, decl);
   1691     } else {
   1692       break;
   1693     }
   1694   }
   1695 
   1696   if ((decl->mode & CPARSE_MODE_FIELD) && cp_opt(cp, ':'))  /* Field width. */
   1697     decl->bits = cp_expr_ksize(cp);
   1698 
   1699   /* Process postfix attributes. */
   1700   cp_decl_attributes(cp, decl);
   1701   cp_push_attributes(decl);
   1702 
   1703   cp->depth--;
   1704 }
   1705 
   1706 /* Parse an abstract type declaration and return it's C type ID. */
   1707 static CTypeID cp_decl_abstract(CPState *cp)
   1708 {
   1709   CPDecl decl;
   1710   cp_decl_spec(cp, &decl, 0);
   1711   decl.mode = CPARSE_MODE_ABSTRACT;
   1712   cp_declarator(cp, &decl);
   1713   return cp_decl_intern(cp, &decl);
   1714 }
   1715 
   1716 /* Handle pragmas. */
   1717 static void cp_pragma(CPState *cp, BCLine pragmaline)
   1718 {
   1719   cp_next(cp);
   1720   if (cp->tok == CTOK_IDENT &&
   1721       cp->str->hash == H_(e79b999f,42ca3e85))  {  /* pack */
   1722     cp_next(cp);
   1723     cp_check(cp, '(');
   1724     if (cp->tok == CTOK_IDENT) {
   1725       if (cp->str->hash == H_(738e923c,a1b65954)) {  /* push */
   1726 	if (cp->curpack < CPARSE_MAX_PACKSTACK) {
   1727 	  cp->packstack[cp->curpack+1] = cp->packstack[cp->curpack];
   1728 	  cp->curpack++;
   1729 	}
   1730       } else if (cp->str->hash == H_(6c71cf27,6c71cf27)) {  /* pop */
   1731 	if (cp->curpack > 0) cp->curpack--;
   1732       } else {
   1733 	cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
   1734       }
   1735       cp_next(cp);
   1736       if (!cp_opt(cp, ',')) goto end_pack;
   1737     }
   1738     if (cp->tok == CTOK_INTEGER) {
   1739       cp->packstack[cp->curpack] = cp->val.u32 ? lj_fls(cp->val.u32) : 0;
   1740       cp_next(cp);
   1741     } else {
   1742       cp->packstack[cp->curpack] = 255;
   1743     }
   1744   end_pack:
   1745     cp_check(cp, ')');
   1746   } else {  /* Ignore all other pragmas. */
   1747     while (cp->tok != CTOK_EOF && cp->linenumber == pragmaline)
   1748       cp_next(cp);
   1749   }
   1750 }
   1751 
   1752 /* Handle line number. */
   1753 static void cp_line(CPState *cp, BCLine hashline)
   1754 {
   1755   BCLine newline = cp->val.u32;
   1756   /* TODO: Handle file name and include it in error messages. */
   1757   while (cp->tok != CTOK_EOF && cp->linenumber == hashline)
   1758     cp_next(cp);
   1759   cp->linenumber = newline;
   1760 }
   1761 
   1762 /* Parse multiple C declarations of types or extern identifiers. */
   1763 static void cp_decl_multi(CPState *cp)
   1764 {
   1765   int first = 1;
   1766   while (cp->tok != CTOK_EOF) {
   1767     CPDecl decl;
   1768     CPscl scl;
   1769     if (cp_opt(cp, ';')) {  /* Skip empty statements. */
   1770       first = 0;
   1771       continue;
   1772     }
   1773     if (cp->tok == '#') {  /* Workaround, since we have no preprocessor, yet. */
   1774       BCLine hashline = cp->linenumber;
   1775       CPToken tok = cp_next(cp);
   1776       if (tok == CTOK_INTEGER) {
   1777 	cp_line(cp, hashline);
   1778 	continue;
   1779       } else if (tok == CTOK_IDENT &&
   1780 		 cp->str->hash == H_(187aab88,fcb60b42)) { /* line */
   1781 	if (cp_next(cp) != CTOK_INTEGER) cp_err_token(cp, tok);
   1782 	cp_line(cp, hashline);
   1783 	continue;
   1784       } else if (tok == CTOK_IDENT &&
   1785 	  cp->str->hash == H_(f5e6b4f8,1d509107)) { /* pragma */
   1786 	cp_pragma(cp, hashline);
   1787 	continue;
   1788       } else {
   1789 	cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
   1790       }
   1791     }
   1792     scl = cp_decl_spec(cp, &decl, CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC);
   1793     if ((cp->tok == ';' || cp->tok == CTOK_EOF) &&
   1794 	ctype_istypedef(decl.stack[0].info)) {
   1795       CTInfo info = ctype_rawchild(cp->cts, &decl.stack[0])->info;
   1796       if (ctype_isstruct(info) || ctype_isenum(info))
   1797 	goto decl_end;  /* Accept empty declaration of struct/union/enum. */
   1798     }
   1799     for (;;) {
   1800       CTypeID ctypeid;
   1801       cp_declarator(cp, &decl);
   1802       ctypeid = cp_decl_intern(cp, &decl);
   1803       if (decl.name && !decl.nameid) {  /* NYI: redeclarations are ignored. */
   1804 	CType *ct;
   1805 	CTypeID id;
   1806 	if ((scl & CDF_TYPEDEF)) {  /* Create new typedef. */
   1807 	  id = lj_ctype_new(cp->cts, &ct);
   1808 	  ct->info = CTINFO(CT_TYPEDEF, ctypeid);
   1809 	  goto noredir;
   1810 	} else if (ctype_isfunc(ctype_get(cp->cts, ctypeid)->info)) {
   1811 	  /* Treat both static and extern function declarations as extern. */
   1812 	  ct = ctype_get(cp->cts, ctypeid);
   1813 	  /* We always get new anonymous functions (typedefs are copied). */
   1814 	  lua_assert(gcref(ct->name) == NULL);
   1815 	  id = ctypeid;  /* Just name it. */
   1816 	} else if ((scl & CDF_STATIC)) {  /* Accept static constants. */
   1817 	  id = cp_decl_constinit(cp, &ct, ctypeid);
   1818 	  goto noredir;
   1819 	} else {  /* External references have extern or no storage class. */
   1820 	  id = lj_ctype_new(cp->cts, &ct);
   1821 	  ct->info = CTINFO(CT_EXTERN, ctypeid);
   1822 	}
   1823 	if (decl.redir) {  /* Add attribute for redirected symbol name. */
   1824 	  CType *cta;
   1825 	  CTypeID aid = lj_ctype_new(cp->cts, &cta);
   1826 	  ct = ctype_get(cp->cts, id);  /* Table may have been reallocated. */
   1827 	  cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR));
   1828 	  cta->sib = ct->sib;
   1829 	  ct->sib = aid;
   1830 	  ctype_setname(cta, decl.redir);
   1831 	}
   1832       noredir:
   1833 	ctype_setname(ct, decl.name);
   1834 	lj_ctype_addname(cp->cts, ct, id);
   1835       }
   1836       if (!cp_opt(cp, ',')) break;
   1837       cp_decl_reset(&decl);
   1838     }
   1839   decl_end:
   1840     if (cp->tok == CTOK_EOF && first) break;  /* May omit ';' for 1 decl. */
   1841     first = 0;
   1842     cp_check(cp, ';');
   1843   }
   1844 }
   1845 
   1846 /* Parse a single C type declaration. */
   1847 static void cp_decl_single(CPState *cp)
   1848 {
   1849   CPDecl decl;
   1850   cp_decl_spec(cp, &decl, 0);
   1851   cp_declarator(cp, &decl);
   1852   cp->val.id = cp_decl_intern(cp, &decl);
   1853   if (cp->tok != CTOK_EOF) cp_err_token(cp, CTOK_EOF);
   1854 }
   1855 
   1856 #undef H_
   1857 
   1858 /* ------------------------------------------------------------------------ */
   1859 
   1860 /* Protected callback for C parser. */
   1861 static TValue *cpcparser(lua_State *L, lua_CFunction dummy, void *ud)
   1862 {
   1863   CPState *cp = (CPState *)ud;
   1864   UNUSED(dummy);
   1865   cframe_errfunc(L->cframe) = -1;  /* Inherit error function. */
   1866   cp_init(cp);
   1867   if ((cp->mode & CPARSE_MODE_MULTI))
   1868     cp_decl_multi(cp);
   1869   else
   1870     cp_decl_single(cp);
   1871   if (cp->param && cp->param != cp->L->top)
   1872     cp_err(cp, LJ_ERR_FFI_NUMPARAM);
   1873   lua_assert(cp->depth == 0);
   1874   return NULL;
   1875 }
   1876 
   1877 /* C parser. */
   1878 int lj_cparse(CPState *cp)
   1879 {
   1880   LJ_CTYPE_SAVE(cp->cts);
   1881   int errcode = lj_vm_cpcall(cp->L, NULL, cp, cpcparser);
   1882   if (errcode)
   1883     LJ_CTYPE_RESTORE(cp->cts);
   1884   cp_cleanup(cp);
   1885   return errcode;
   1886 }
   1887 
   1888 #endif