root/lj_cparse.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cp_tok2str
  2. cp_iseol
  3. cp_rawpeek
  4. cp_get
  5. cp_get_bs
  6. cp_save
  7. cp_newline
  8. cp_errmsg
  9. cp_err_token
  10. cp_err_badidx
  11. cp_err
  12. cp_number
  13. cp_ident
  14. cp_param
  15. cp_string
  16. cp_comment_c
  17. cp_comment_cpp
  18. cp_next_
  19. cp_next
  20. cp_init
  21. cp_cleanup
  22. cp_opt
  23. cp_check
  24. cp_istypedecl
  25. cp_expr_comma
  26. cp_expr_sizeof
  27. cp_expr_prefix
  28. cp_expr_postfix
  29. cp_expr_infix
  30. cp_expr_unary
  31. cp_expr_sub
  32. cp_expr_kint
  33. cp_expr_ksize
  34. cp_add
  35. cp_push
  36. cp_push_attributes
  37. cp_push_type
  38. cp_decl_intern
  39. cp_decl_reset
  40. cp_decl_constinit
  41. cp_decl_sizeattr
  42. cp_decl_align
  43. cp_decl_asm
  44. cp_decl_mode
  45. cp_decl_gccattribute
  46. cp_decl_msvcattribute
  47. cp_decl_attributes
  48. cp_struct_name
  49. cp_field_align
  50. cp_struct_layout
  51. cp_decl_struct
  52. cp_decl_enum
  53. cp_decl_spec
  54. cp_decl_array
  55. cp_decl_func
  56. cp_declarator
  57. cp_decl_abstract
  58. cp_pragma
  59. cp_line
  60. cp_decl_multi
  61. cp_decl_single
  62. cpcparser
  63. lj_cparse

   1 /*
   2 ** C declaration parser.
   3 ** Copyright (C) 2005-2017 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       /* fallthrough */
 580     case 1:
 581       if (cp_opt(cp, CTOK_OROR)) {
 582         cp_expr_sub(cp, &k2, 2); k->i32 = k->u32 || k2.u32; k->id = CTID_INT32;
 583         continue;
 584       }
 585       /* fallthrough */
 586     case 2:
 587       if (cp_opt(cp, CTOK_ANDAND)) {
 588         cp_expr_sub(cp, &k2, 3); k->i32 = k->u32 && k2.u32; k->id = CTID_INT32;
 589         continue;
 590       }
 591       /* fallthrough */
 592     case 3:
 593       if (cp_opt(cp, '|')) {
 594         cp_expr_sub(cp, &k2, 4); k->u32 = k->u32 | k2.u32; goto arith_result;
 595       }
 596       /* fallthrough */
 597     case 4:
 598       if (cp_opt(cp, '^')) {
 599         cp_expr_sub(cp, &k2, 5); k->u32 = k->u32 ^ k2.u32; goto arith_result;
 600       }
 601       /* fallthrough */
 602     case 5:
 603       if (cp_opt(cp, '&')) {
 604         cp_expr_sub(cp, &k2, 6); k->u32 = k->u32 & k2.u32; goto arith_result;
 605       }
 606       /* fallthrough */
 607     case 6:
 608       if (cp_opt(cp, CTOK_EQ)) {
 609         cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 == k2.u32; k->id = CTID_INT32;
 610         continue;
 611       } else if (cp_opt(cp, CTOK_NE)) {
 612         cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 != k2.u32; k->id = CTID_INT32;
 613         continue;
 614       }
 615       /* fallthrough */
 616     case 7:
 617       if (cp_opt(cp, '<')) {
 618         cp_expr_sub(cp, &k2, 8);
 619         if (k->id == CTID_INT32 && k2.id == CTID_INT32)
 620           k->i32 = k->i32 < k2.i32;
 621         else
 622           k->i32 = k->u32 < k2.u32;
 623         k->id = CTID_INT32;
 624         continue;
 625       } else if (cp_opt(cp, '>')) {
 626         cp_expr_sub(cp, &k2, 8);
 627         if (k->id == CTID_INT32 && k2.id == CTID_INT32)
 628           k->i32 = k->i32 > k2.i32;
 629         else
 630           k->i32 = k->u32 > k2.u32;
 631         k->id = CTID_INT32;
 632         continue;
 633       } else if (cp_opt(cp, CTOK_LE)) {
 634         cp_expr_sub(cp, &k2, 8);
 635         if (k->id == CTID_INT32 && k2.id == CTID_INT32)
 636           k->i32 = k->i32 <= k2.i32;
 637         else
 638           k->i32 = k->u32 <= k2.u32;
 639         k->id = CTID_INT32;
 640         continue;
 641       } else if (cp_opt(cp, CTOK_GE)) {
 642         cp_expr_sub(cp, &k2, 8);
 643         if (k->id == CTID_INT32 && k2.id == CTID_INT32)
 644           k->i32 = k->i32 >= k2.i32;
 645         else
 646           k->i32 = k->u32 >= k2.u32;
 647         k->id = CTID_INT32;
 648         continue;
 649       }
 650       /* fallthrough */
 651     case 8:
 652       if (cp_opt(cp, CTOK_SHL)) {
 653         cp_expr_sub(cp, &k2, 9); k->u32 = k->u32 << k2.u32;
 654         continue;
 655       } else if (cp_opt(cp, CTOK_SHR)) {
 656         cp_expr_sub(cp, &k2, 9);
 657         if (k->id == CTID_INT32)
 658           k->i32 = k->i32 >> k2.i32;
 659         else
 660           k->u32 = k->u32 >> k2.u32;
 661         continue;
 662       }
 663       /* fallthrough */
 664     case 9:
 665       if (cp_opt(cp, '+')) {
 666         cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 + k2.u32;
 667       arith_result:
 668         if (k2.id > k->id) k->id = k2.id;  /* Trivial promotion to unsigned. */
 669         continue;
 670       } else if (cp_opt(cp, '-')) {
 671         cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 - k2.u32; goto arith_result;
 672       }
 673       /* fallthrough */
 674     case 10:
 675       if (cp_opt(cp, '*')) {
 676         cp_expr_unary(cp, &k2); k->u32 = k->u32 * k2.u32; goto arith_result;
 677       } else if (cp_opt(cp, '/')) {
 678         cp_expr_unary(cp, &k2);
 679         if (k2.id > k->id) k->id = k2.id;  /* Trivial promotion to unsigned. */
 680         if (k2.u32 == 0 ||
 681             (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
 682           cp_err(cp, LJ_ERR_BADVAL);
 683         if (k->id == CTID_INT32)
 684           k->i32 = k->i32 / k2.i32;
 685         else
 686           k->u32 = k->u32 / k2.u32;
 687         continue;
 688       } else if (cp_opt(cp, '%')) {
 689         cp_expr_unary(cp, &k2);
 690         if (k2.id > k->id) k->id = k2.id;  /* Trivial promotion to unsigned. */
 691         if (k2.u32 == 0 ||
 692             (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1))
 693           cp_err(cp, LJ_ERR_BADVAL);
 694         if (k->id == CTID_INT32)
 695           k->i32 = k->i32 % k2.i32;
 696         else
 697           k->u32 = k->u32 % k2.u32;
 698         continue;
 699       }
 700     default:
 701       return;
 702     }
 703   }
 704 }
 705 
 706 /* Parse and evaluate unary expression. */
 707 static void cp_expr_unary(CPState *cp, CPValue *k)
 708 {
 709   if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS);
 710   cp_expr_prefix(cp, k);
 711   cp_expr_postfix(cp, k);
 712   cp->depth--;
 713 }
 714 
 715 /* Parse and evaluate sub-expression. */
 716 static void cp_expr_sub(CPState *cp, CPValue *k, int pri)
 717 {
 718   cp_expr_unary(cp, k);
 719   cp_expr_infix(cp, k, pri);
 720 }
 721 
 722 /* Parse constant integer expression. */
 723 static void cp_expr_kint(CPState *cp, CPValue *k)
 724 {
 725   CType *ct;
 726   cp_expr_sub(cp, k, 0);
 727   ct = ctype_raw(cp->cts, k->id);
 728   if (!ctype_isinteger(ct->info)) cp_err(cp, LJ_ERR_BADVAL);
 729 }
 730 
 731 /* Parse (non-negative) size expression. */
 732 static CTSize cp_expr_ksize(CPState *cp)
 733 {
 734   CPValue k;
 735   cp_expr_kint(cp, &k);
 736   if (k.u32 >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE);
 737   return k.u32;
 738 }
 739 
 740 /* -- Type declaration stack management ----------------------------------- */
 741 
 742 /* Add declaration element behind the insertion position. */
 743 static CPDeclIdx cp_add(CPDecl *decl, CTInfo info, CTSize size)
 744 {
 745   CPDeclIdx top = decl->top;
 746   if (top >= CPARSE_MAX_DECLSTACK) cp_err(decl->cp, LJ_ERR_XLEVELS);
 747   decl->stack[top].info = info;
 748   decl->stack[top].size = size;
 749   decl->stack[top].sib = 0;
 750   setgcrefnull(decl->stack[top].name);
 751   decl->stack[top].next = decl->stack[decl->pos].next;
 752   decl->stack[decl->pos].next = (CTypeID1)top;
 753   decl->top = top+1;
 754   return top;
 755 }
 756 
 757 /* Push declaration element before the insertion position. */
 758 static CPDeclIdx cp_push(CPDecl *decl, CTInfo info, CTSize size)
 759 {
 760   return (decl->pos = cp_add(decl, info, size));
 761 }
 762 
 763 /* Push or merge attributes. */
 764 static void cp_push_attributes(CPDecl *decl)
 765 {
 766   CType *ct = &decl->stack[decl->pos];
 767   if (ctype_isfunc(ct->info)) {  /* Ok to modify in-place. */
 768 #if LJ_TARGET_X86
 769     if ((decl->fattr & CTFP_CCONV))
 770       ct->info = (ct->info & (CTMASK_NUM|CTF_VARARG|CTMASK_CID)) +
 771                  (decl->fattr & ~CTMASK_CID);
 772 #endif
 773   } else {
 774     if ((decl->attr & CTFP_ALIGNED) && !(decl->mode & CPARSE_MODE_FIELD))
 775       cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_ALIGN)),
 776               ctype_align(decl->attr));
 777   }
 778 }
 779 
 780 /* Push unrolled type to declaration stack and merge qualifiers. */
 781 static void cp_push_type(CPDecl *decl, CTypeID id)
 782 {
 783   CType *ct = ctype_get(decl->cp->cts, id);
 784   CTInfo info = ct->info;
 785   CTSize size = ct->size;
 786   switch (ctype_type(info)) {
 787   case CT_STRUCT: case CT_ENUM:
 788     cp_push(decl, CTINFO(CT_TYPEDEF, id), 0);  /* Don't copy unique types. */
 789     if ((decl->attr & CTF_QUAL)) {  /* Push unmerged qualifiers. */
 790       cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_QUAL)),
 791               (decl->attr & CTF_QUAL));
 792       decl->attr &= ~CTF_QUAL;
 793     }
 794     break;
 795   case CT_ATTRIB:
 796     if (ctype_isxattrib(info, CTA_QUAL))
 797       decl->attr &= ~size;  /* Remove redundant qualifiers. */
 798     cp_push_type(decl, ctype_cid(info));  /* Unroll. */
 799     cp_push(decl, info & ~CTMASK_CID, size);  /* Copy type. */
 800     break;
 801   case CT_ARRAY:
 802     if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) {
 803       info |= (decl->attr & CTF_QUAL);
 804       decl->attr &= ~CTF_QUAL;
 805     }
 806     cp_push_type(decl, ctype_cid(info));  /* Unroll. */
 807     cp_push(decl, info & ~CTMASK_CID, size);  /* Copy type. */
 808     decl->stack[decl->pos].sib = 1;  /* Mark as already checked and sized. */
 809     /* Note: this is not copied to the ct->sib in the C type table. */
 810     break;
 811   case CT_FUNC:
 812     /* Copy type, link parameters (shared). */
 813     decl->stack[cp_push(decl, info, size)].sib = ct->sib;
 814     break;
 815   default:
 816     /* Copy type, merge common qualifiers. */
 817     cp_push(decl, info|(decl->attr & CTF_QUAL), size);
 818     decl->attr &= ~CTF_QUAL;
 819     break;
 820   }
 821 }
 822 
 823 /* Consume the declaration element chain and intern the C type. */
 824 static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl)
 825 {
 826   CTypeID id = 0;
 827   CPDeclIdx idx = 0;
 828   CTSize csize = CTSIZE_INVALID;
 829   CTSize cinfo = 0;
 830   do {
 831     CType *ct = &decl->stack[idx];
 832     CTInfo info = ct->info;
 833     CTInfo size = ct->size;
 834     /* The cid is already part of info for copies of pointers/functions. */
 835     idx = ct->next;
 836     if (ctype_istypedef(info)) {
 837       lua_assert(id == 0);
 838       id = ctype_cid(info);
 839       /* Always refetch info/size, since struct/enum may have been completed. */
 840       cinfo = ctype_get(cp->cts, id)->info;
 841       csize = ctype_get(cp->cts, id)->size;
 842       lua_assert(ctype_isstruct(cinfo) || ctype_isenum(cinfo));
 843     } else if (ctype_isfunc(info)) {  /* Intern function. */
 844       CType *fct;
 845       CTypeID fid;
 846       CTypeID sib;
 847       if (id) {
 848         CType *refct = ctype_raw(cp->cts, id);
 849         /* Reject function or refarray return types. */
 850         if (ctype_isfunc(refct->info) || ctype_isrefarray(refct->info))
 851           cp_err(cp, LJ_ERR_FFI_INVTYPE);
 852       }
 853       /* No intervening attributes allowed, skip forward. */
 854       while (idx) {
 855         CType *ctn = &decl->stack[idx];
 856         if (!ctype_isattrib(ctn->info)) break;
 857         idx = ctn->next;  /* Skip attribute. */
 858       }
 859       sib = ct->sib;  /* Next line may reallocate the C type table. */
 860       fid = lj_ctype_new(cp->cts, &fct);
 861       csize = CTSIZE_INVALID;
 862       fct->info = cinfo = info + id;
 863       fct->size = size;
 864       fct->sib = sib;
 865       id = fid;
 866     } else if (ctype_isattrib(info)) {
 867       if (ctype_isxattrib(info, CTA_QUAL))
 868         cinfo |= size;
 869       else if (ctype_isxattrib(info, CTA_ALIGN))
 870         CTF_INSERT(cinfo, ALIGN, size);
 871       id = lj_ctype_intern(cp->cts, info+id, size);
 872       /* Inherit csize/cinfo from original type. */
 873     } else {
 874       if (ctype_isnum(info)) {  /* Handle mode/vector-size attributes. */
 875         lua_assert(id == 0);
 876         if (!(info & CTF_BOOL)) {
 877           CTSize msize = ctype_msizeP(decl->attr);
 878           CTSize vsize = ctype_vsizeP(decl->attr);
 879           if (msize && (!(info & CTF_FP) || (msize == 4 || msize == 8))) {
 880             CTSize malign = lj_fls(msize);
 881             if (malign > 4) malign = 4;  /* Limit alignment. */
 882             CTF_INSERT(info, ALIGN, malign);
 883             size = msize;  /* Override size via mode. */
 884           }
 885           if (vsize) {  /* Vector size set? */
 886             CTSize esize = lj_fls(size);
 887             if (vsize >= esize) {
 888               /* Intern the element type first. */
 889               id = lj_ctype_intern(cp->cts, info, size);
 890               /* Then create a vector (array) with vsize alignment. */
 891               size = (1u << vsize);
 892               if (vsize > 4) vsize = 4;  /* Limit alignment. */
 893               if (ctype_align(info) > vsize) vsize = ctype_align(info);
 894               info = CTINFO(CT_ARRAY, (info & CTF_QUAL) + CTF_VECTOR +
 895                                       CTALIGN(vsize));
 896             }
 897           }
 898         }
 899       } else if (ctype_isptr(info)) {
 900         /* Reject pointer/ref to ref. */
 901         if (id && ctype_isref(ctype_raw(cp->cts, id)->info))
 902           cp_err(cp, LJ_ERR_FFI_INVTYPE);
 903         if (ctype_isref(info)) {
 904           info &= ~CTF_VOLATILE;  /* Refs are always const, never volatile. */
 905           /* No intervening attributes allowed, skip forward. */
 906           while (idx) {
 907             CType *ctn = &decl->stack[idx];
 908             if (!ctype_isattrib(ctn->info)) break;
 909             idx = ctn->next;  /* Skip attribute. */
 910           }
 911         }
 912       } else if (ctype_isarray(info)) {  /* Check for valid array size etc. */
 913         if (ct->sib == 0) {  /* Only check/size arrays not copied by unroll. */
 914           if (ctype_isref(cinfo))  /* Reject arrays of refs. */
 915             cp_err(cp, LJ_ERR_FFI_INVTYPE);
 916           /* Reject VLS or unknown-sized types. */
 917           if (ctype_isvltype(cinfo) || csize == CTSIZE_INVALID)
 918             cp_err(cp, LJ_ERR_FFI_INVSIZE);
 919           /* a[] and a[?] keep their invalid size. */
 920           if (size != CTSIZE_INVALID) {
 921             uint64_t xsz = (uint64_t)size * csize;
 922             if (xsz >= 0x80000000u) cp_err(cp, LJ_ERR_FFI_INVSIZE);
 923             size = (CTSize)xsz;
 924           }
 925         }
 926         if ((cinfo & CTF_ALIGN) > (info & CTF_ALIGN))  /* Find max. align. */
 927           info = (info & ~CTF_ALIGN) | (cinfo & CTF_ALIGN);
 928         info |= (cinfo & CTF_QUAL);  /* Inherit qual. */
 929       } else {
 930         lua_assert(ctype_isvoid(info));
 931       }
 932       csize = size;
 933       cinfo = info+id;
 934       id = lj_ctype_intern(cp->cts, info+id, size);
 935     }
 936   } while (idx);
 937   return id;
 938 }
 939 
 940 /* -- C declaration parser ------------------------------------------------ */
 941 
 942 #define H_(le, be)      LJ_ENDIAN_SELECT(0x##le, 0x##be)
 943 
 944 /* Reset declaration state to declaration specifier. */
 945 static void cp_decl_reset(CPDecl *decl)
 946 {
 947   decl->pos = decl->specpos;
 948   decl->top = decl->specpos+1;
 949   decl->stack[decl->specpos].next = 0;
 950   decl->attr = decl->specattr;
 951   decl->fattr = decl->specfattr;
 952   decl->name = NULL;
 953   decl->redir = NULL;
 954 }
 955 
 956 /* Parse constant initializer. */
 957 /* NYI: FP constants and strings as initializers. */
 958 static CTypeID cp_decl_constinit(CPState *cp, CType **ctp, CTypeID ctypeid)
 959 {
 960   CType *ctt = ctype_get(cp->cts, ctypeid);
 961   CTInfo info;
 962   CTSize size;
 963   CPValue k;
 964   CTypeID constid;
 965   while (ctype_isattrib(ctt->info)) {  /* Skip attributes. */
 966     ctypeid = ctype_cid(ctt->info);  /* Update ID, too. */
 967     ctt = ctype_get(cp->cts, ctypeid);
 968   }
 969   info = ctt->info;
 970   size = ctt->size;
 971   if (!ctype_isinteger(info) || !(info & CTF_CONST) || size > 4)
 972     cp_err(cp, LJ_ERR_FFI_INVTYPE);
 973   cp_check(cp, '=');
 974   cp_expr_sub(cp, &k, 0);
 975   constid = lj_ctype_new(cp->cts, ctp);
 976   (*ctp)->info = CTINFO(CT_CONSTVAL, CTF_CONST|ctypeid);
 977   k.u32 <<= 8*(4-size);
 978   if ((info & CTF_UNSIGNED))
 979     k.u32 >>= 8*(4-size);
 980   else
 981     k.u32 = (uint32_t)((int32_t)k.u32 >> 8*(4-size));
 982   (*ctp)->size = k.u32;
 983   return constid;
 984 }
 985 
 986 /* Parse size in parentheses as part of attribute. */
 987 static CTSize cp_decl_sizeattr(CPState *cp)
 988 {
 989   CTSize sz;
 990   uint32_t oldtmask = cp->tmask;
 991   cp->tmask = CPNS_DEFAULT;  /* Required for expression evaluator. */
 992   cp_check(cp, '(');
 993   sz = cp_expr_ksize(cp);
 994   cp->tmask = oldtmask;
 995   cp_check(cp, ')');
 996   return sz;
 997 }
 998 
 999 /* Parse alignment attribute. */
1000 static void cp_decl_align(CPState *cp, CPDecl *decl)
1001 {
1002   CTSize al = 4;  /* Unspecified alignment is 16 bytes. */
1003   if (cp->tok == '(') {
1004     al = cp_decl_sizeattr(cp);
1005     al = al ? lj_fls(al) : 0;
1006   }
1007   CTF_INSERT(decl->attr, ALIGN, al);
1008   decl->attr |= CTFP_ALIGNED;
1009 }
1010 
1011 /* Parse GCC asm("name") redirect. */
1012 static void cp_decl_asm(CPState *cp, CPDecl *decl)
1013 {
1014   UNUSED(decl);
1015   cp_next(cp);
1016   cp_check(cp, '(');
1017   if (cp->tok == CTOK_STRING) {
1018     GCstr *str = cp->str;
1019     while (cp_next(cp) == CTOK_STRING) {
1020       lj_strfmt_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str));
1021       cp->L->top--;
1022       str = strV(cp->L->top);
1023     }
1024     decl->redir = str;
1025   }
1026   cp_check(cp, ')');
1027 }
1028 
1029 /* Parse GCC __attribute__((mode(...))). */
1030 static void cp_decl_mode(CPState *cp, CPDecl *decl)
1031 {
1032   cp_check(cp, '(');
1033   if (cp->tok == CTOK_IDENT) {
1034     const char *s = strdata(cp->str);
1035     CTSize sz = 0, vlen = 0;
1036     if (s[0] == '_' && s[1] == '_') s += 2;
1037     if (*s == 'V') {
1038       s++;
1039       vlen = *s++ - '0';
1040       if (*s >= '0' && *s <= '9')
1041         vlen = vlen*10 + (*s++ - '0');
1042     }
1043     switch (*s++) {
1044     case 'Q': sz = 1; break;
1045     case 'H': sz = 2; break;
1046     case 'S': sz = 4; break;
1047     case 'D': sz = 8; break;
1048     case 'T': sz = 16; break;
1049     case 'O': sz = 32; break;
1050     default: goto bad_size;
1051     }
1052     if (*s == 'I' || *s == 'F') {
1053       CTF_INSERT(decl->attr, MSIZEP, sz);
1054       if (vlen) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vlen*sz));
1055     }
1056   bad_size:
1057     cp_next(cp);
1058   }
1059   cp_check(cp, ')');
1060 }
1061 
1062 /* Parse GCC __attribute__((...)). */
1063 static void cp_decl_gccattribute(CPState *cp, CPDecl *decl)
1064 {
1065   cp_next(cp);
1066   cp_check(cp, '(');
1067   cp_check(cp, '(');
1068   while (cp->tok != ')') {
1069     if (cp->tok == CTOK_IDENT) {
1070       GCstr *attrstr = cp->str;
1071       cp_next(cp);
1072       switch (attrstr->hash) {
1073       case H_(64a9208e,8ce14319): case H_(8e6331b2,95a282af):  /* aligned */
1074         cp_decl_align(cp, decl);
1075         break;
1076       case H_(42eb47de,f0ede26c): case H_(29f48a09,cf383e0c):  /* packed */
1077         decl->attr |= CTFP_PACKED;
1078         break;
1079       case H_(0a84eef6,8dfab04c): case H_(995cf92c,d5696591):  /* mode */
1080         cp_decl_mode(cp, decl);
1081         break;
1082       case H_(0ab31997,2d5213fa): case H_(bf875611,200e9990):  /* vector_size */
1083         {
1084           CTSize vsize = cp_decl_sizeattr(cp);
1085           if (vsize) CTF_INSERT(decl->attr, VSIZEP, lj_fls(vsize));
1086         }
1087         break;
1088 #if LJ_TARGET_X86
1089       case H_(5ad22db8,c689b848): case H_(439150fa,65ea78cb):  /* regparm */
1090         CTF_INSERT(decl->fattr, REGPARM, cp_decl_sizeattr(cp));
1091         decl->fattr |= CTFP_CCONV;
1092         break;
1093       case H_(18fc0b98,7ff4c074): case H_(4e62abed,0a747424):  /* cdecl */
1094         CTF_INSERT(decl->fattr, CCONV, CTCC_CDECL);
1095         decl->fattr |= CTFP_CCONV;
1096         break;
1097       case H_(72b2e41b,494c5a44): case H_(f2356d59,f25fc9bd):  /* thiscall */
1098         CTF_INSERT(decl->fattr, CCONV, CTCC_THISCALL);
1099         decl->fattr |= CTFP_CCONV;
1100         break;
1101       case H_(0d0ffc42,ab746f88): case H_(21c54ba1,7f0ca7e3):  /* fastcall */
1102         CTF_INSERT(decl->fattr, CCONV, CTCC_FASTCALL);
1103         decl->fattr |= CTFP_CCONV;
1104         break;
1105       case H_(ef76b040,9412e06a): case H_(de56697b,c750e6e1):  /* stdcall */
1106         CTF_INSERT(decl->fattr, CCONV, CTCC_STDCALL);
1107         decl->fattr |= CTFP_CCONV;
1108         break;
1109       case H_(ea78b622,f234bd8e): case H_(252ffb06,8d50f34b):  /* sseregparm */
1110         decl->fattr |= CTF_SSEREGPARM;
1111         decl->fattr |= CTFP_CCONV;
1112         break;
1113 #endif
1114       default:  /* Skip all other attributes. */
1115         goto skip_attr;
1116       }
1117     } else if (cp->tok >= CTOK_FIRSTDECL) {  /* For __attribute((const)) etc. */
1118       cp_next(cp);
1119     skip_attr:
1120       if (cp_opt(cp, '(')) {
1121         while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp);
1122         cp_check(cp, ')');
1123       }
1124     } else {
1125       break;
1126     }
1127     if (!cp_opt(cp, ',')) break;
1128   }
1129   cp_check(cp, ')');
1130   cp_check(cp, ')');
1131 }
1132 
1133 /* Parse MSVC __declspec(...). */
1134 static void cp_decl_msvcattribute(CPState *cp, CPDecl *decl)
1135 {
1136   cp_next(cp);
1137   cp_check(cp, '(');
1138   while (cp->tok == CTOK_IDENT) {
1139     GCstr *attrstr = cp->str;
1140     cp_next(cp);
1141     switch (attrstr->hash) {
1142     case H_(bc2395fa,98f267f8):  /* align */
1143       cp_decl_align(cp, decl);
1144       break;
1145     default:  /* Ignore all other attributes. */
1146       if (cp_opt(cp, '(')) {
1147         while (cp->tok != ')' && cp->tok != CTOK_EOF) cp_next(cp);
1148         cp_check(cp, ')');
1149       }
1150       break;
1151     }
1152   }
1153   cp_check(cp, ')');
1154 }
1155 
1156 /* Parse declaration attributes (and common qualifiers). */
1157 static void cp_decl_attributes(CPState *cp, CPDecl *decl)
1158 {
1159   for (;;) {
1160     switch (cp->tok) {
1161     case CTOK_CONST: decl->attr |= CTF_CONST; break;
1162     case CTOK_VOLATILE: decl->attr |= CTF_VOLATILE; break;
1163     case CTOK_RESTRICT: break;  /* Ignore. */
1164     case CTOK_EXTENSION: break;  /* Ignore. */
1165     case CTOK_ATTRIBUTE: cp_decl_gccattribute(cp, decl); continue;
1166     case CTOK_ASM: cp_decl_asm(cp, decl); continue;
1167     case CTOK_DECLSPEC: cp_decl_msvcattribute(cp, decl); continue;
1168     case CTOK_CCDECL:
1169 #if LJ_TARGET_X86
1170       CTF_INSERT(decl->fattr, CCONV, cp->ct->size);
1171       decl->fattr |= CTFP_CCONV;
1172 #endif
1173       break;
1174     case CTOK_PTRSZ:
1175 #if LJ_64
1176       CTF_INSERT(decl->attr, MSIZEP, cp->ct->size);
1177 #endif
1178       break;
1179     default: return;
1180     }
1181     cp_next(cp);
1182   }
1183 }
1184 
1185 /* Parse struct/union/enum name. */
1186 static CTypeID cp_struct_name(CPState *cp, CPDecl *sdecl, CTInfo info)
1187 {
1188   CTypeID sid;
1189   CType *ct;
1190   cp->tmask = CPNS_STRUCT;
1191   cp_next(cp);
1192   cp_decl_attributes(cp, sdecl);
1193   cp->tmask = CPNS_DEFAULT;
1194   if (cp->tok != '{') {
1195     if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
1196     if (cp->val.id) {  /* Name of existing struct/union/enum. */
1197       sid = cp->val.id;
1198       ct = cp->ct;
1199       if ((ct->info ^ info) & (CTMASK_NUM|CTF_UNION))  /* Wrong type. */
1200         cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name))));
1201     } else {  /* Create named, incomplete struct/union/enum. */
1202       if ((cp->mode & CPARSE_MODE_NOIMPLICIT))
1203         cp_errmsg(cp, 0, LJ_ERR_FFI_BADTAG, strdata(cp->str));
1204       sid = lj_ctype_new(cp->cts, &ct);
1205       ct->info = info;
1206       ct->size = CTSIZE_INVALID;
1207       ctype_setname(ct, cp->str);
1208       lj_ctype_addname(cp->cts, ct, sid);
1209     }
1210     cp_next(cp);
1211   } else {  /* Create anonymous, incomplete struct/union/enum. */
1212     sid = lj_ctype_new(cp->cts, &ct);
1213     ct->info = info;
1214     ct->size = CTSIZE_INVALID;
1215   }
1216   if (cp->tok == '{') {
1217     if (ct->size != CTSIZE_INVALID || ct->sib)
1218       cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(gco2str(gcref(ct->name))));
1219     ct->sib = 1;  /* Indicate the type is currently being defined. */
1220   }
1221   return sid;
1222 }
1223 
1224 /* Determine field alignment. */
1225 static CTSize cp_field_align(CPState *cp, CType *ct, CTInfo info)
1226 {
1227   CTSize align = ctype_align(info);
1228   UNUSED(cp); UNUSED(ct);
1229 #if (LJ_TARGET_X86 && !LJ_ABI_WIN) || (LJ_TARGET_ARM && __APPLE__)
1230   /* The SYSV i386 and iOS ABIs limit alignment of non-vector fields to 2^2. */
1231   if (align > 2 && !(info & CTFP_ALIGNED)) {
1232     if (ctype_isarray(info) && !(info & CTF_VECTOR)) {
1233       do {
1234         ct = ctype_rawchild(cp->cts, ct);
1235         info = ct->info;
1236       } while (ctype_isarray(info) && !(info & CTF_VECTOR));
1237     }
1238     if (ctype_isnum(info) || ctype_isenum(info))
1239       align = 2;
1240   }
1241 #endif
1242   return align;
1243 }
1244 
1245 /* Layout struct/union fields. */
1246 static void cp_struct_layout(CPState *cp, CTypeID sid, CTInfo sattr)
1247 {
1248   CTSize bofs = 0, bmaxofs = 0;  /* Bit offset and max. bit offset. */
1249   CTSize maxalign = ctype_align(sattr);
1250   CType *sct = ctype_get(cp->cts, sid);
1251   CTInfo sinfo = sct->info;
1252   CTypeID fieldid = sct->sib;
1253   while (fieldid) {
1254     CType *ct = ctype_get(cp->cts, fieldid);
1255     CTInfo attr = ct->size;  /* Field declaration attributes (temp.). */
1256 
1257     if (ctype_isfield(ct->info) ||
1258         (ctype_isxattrib(ct->info, CTA_SUBTYPE) && attr)) {
1259       CTSize align, amask;  /* Alignment (pow2) and alignment mask (bits). */
1260       CTSize sz;
1261       CTInfo info = lj_ctype_info(cp->cts, ctype_cid(ct->info), &sz);
1262       CTSize bsz, csz = 8*sz;  /* Field size and container size (in bits). */
1263       sinfo |= (info & (CTF_QUAL|CTF_VLA));  /* Merge pseudo-qualifiers. */
1264 
1265       /* Check for size overflow and determine alignment. */
1266       if (sz >= 0x20000000u || bofs + csz < bofs || (info & CTF_VLA)) {
1267         if (!(sz == CTSIZE_INVALID && ctype_isarray(info) &&
1268               !(sinfo & CTF_UNION)))
1269           cp_err(cp, LJ_ERR_FFI_INVSIZE);
1270         csz = sz = 0;  /* Treat a[] and a[?] as zero-sized. */
1271       }
1272       align = cp_field_align(cp, ct, info);
1273       if (((attr|sattr) & CTFP_PACKED) ||
1274           ((attr & CTFP_ALIGNED) && ctype_align(attr) > align))
1275         align = ctype_align(attr);
1276       if (cp->packstack[cp->curpack] < align)
1277         align = cp->packstack[cp->curpack];
1278       if (align > maxalign) maxalign = align;
1279       amask = (8u << align) - 1;
1280 
1281       bsz = ctype_bitcsz(ct->info);  /* Bitfield size (temp.). */
1282       if (bsz == CTBSZ_FIELD || !ctype_isfield(ct->info)) {
1283         bsz = csz;  /* Regular fields or subtypes always fill the container. */
1284         bofs = (bofs + amask) & ~amask;  /* Start new aligned field. */
1285         ct->size = (bofs >> 3);  /* Store field offset. */
1286       } else {  /* Bitfield. */
1287         if (bsz == 0 || (attr & CTFP_ALIGNED) ||
1288             (!((attr|sattr) & CTFP_PACKED) && (bofs & amask) + bsz > csz))
1289           bofs = (bofs + amask) & ~amask;  /* Start new aligned field. */
1290 
1291         /* Prefer regular field over bitfield. */
1292         if (bsz == csz && (bofs & amask) == 0) {
1293           ct->info = CTINFO(CT_FIELD, ctype_cid(ct->info));
1294           ct->size = (bofs >> 3);  /* Store field offset. */
1295         } else {
1296           ct->info = CTINFO(CT_BITFIELD,
1297             (info & (CTF_QUAL|CTF_UNSIGNED|CTF_BOOL)) +
1298             (csz << (CTSHIFT_BITCSZ-3)) + (bsz << CTSHIFT_BITBSZ));
1299 #if LJ_BE
1300           ct->info += ((csz - (bofs & (csz-1)) - bsz) << CTSHIFT_BITPOS);
1301 #else
1302           ct->info += ((bofs & (csz-1)) << CTSHIFT_BITPOS);
1303 #endif
1304           ct->size = ((bofs & ~(csz-1)) >> 3);  /* Store container offset. */
1305         }
1306       }
1307 
1308       /* Determine next offset or max. offset. */
1309       if ((sinfo & CTF_UNION)) {
1310         if (bsz > bmaxofs) bmaxofs = bsz;
1311       } else {
1312         bofs += bsz;
1313       }
1314     }  /* All other fields in the chain are already set up. */
1315 
1316     fieldid = ct->sib;
1317   }
1318 
1319   /* Complete struct/union. */
1320   sct->info = sinfo + CTALIGN(maxalign);
1321   bofs = (sinfo & CTF_UNION) ? bmaxofs : bofs;
1322   maxalign = (8u << maxalign) - 1;
1323   sct->size = (((bofs + maxalign) & ~maxalign) >> 3);
1324 }
1325 
1326 /* Parse struct/union declaration. */
1327 static CTypeID cp_decl_struct(CPState *cp, CPDecl *sdecl, CTInfo sinfo)
1328 {
1329   CTypeID sid = cp_struct_name(cp, sdecl, sinfo);
1330   if (cp_opt(cp, '{')) {  /* Struct/union definition. */
1331     CTypeID lastid = sid;
1332     int lastdecl = 0;
1333     while (cp->tok != '}') {
1334       CPDecl decl;
1335       CPscl scl = cp_decl_spec(cp, &decl, CDF_STATIC);
1336       decl.mode = scl ? CPARSE_MODE_DIRECT :
1337         CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT|CPARSE_MODE_FIELD;
1338 
1339       for (;;) {
1340         CTypeID ctypeid;
1341 
1342         if (lastdecl) cp_err_token(cp, '}');
1343 
1344         /* Parse field declarator. */
1345         decl.bits = CTSIZE_INVALID;
1346         cp_declarator(cp, &decl);
1347         ctypeid = cp_decl_intern(cp, &decl);
1348 
1349         if ((scl & CDF_STATIC)) {  /* Static constant in struct namespace. */
1350           CType *ct;
1351           CTypeID fieldid = cp_decl_constinit(cp, &ct, ctypeid);
1352           ctype_get(cp->cts, lastid)->sib = fieldid;
1353           lastid = fieldid;
1354           ctype_setname(ct, decl.name);
1355         } else {
1356           CTSize bsz = CTBSZ_FIELD;  /* Temp. for layout phase. */
1357           CType *ct;
1358           CTypeID fieldid = lj_ctype_new(cp->cts, &ct);  /* Do this first. */
1359           CType *tct = ctype_raw(cp->cts, ctypeid);
1360 
1361           if (decl.bits == CTSIZE_INVALID) {  /* Regular field. */
1362             if (ctype_isarray(tct->info) && tct->size == CTSIZE_INVALID)
1363               lastdecl = 1;  /* a[] or a[?] must be the last declared field. */
1364 
1365             /* Accept transparent struct/union/enum. */
1366             if (!decl.name) {
1367               if (!((ctype_isstruct(tct->info) && !(tct->info & CTF_VLA)) ||
1368                     ctype_isenum(tct->info)))
1369                 cp_err_token(cp, CTOK_IDENT);
1370               ct->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_SUBTYPE) + ctypeid);
1371               ct->size = ctype_isstruct(tct->info) ?
1372                          (decl.attr|0x80000000u) : 0;  /* For layout phase. */
1373               goto add_field;
1374             }
1375           } else {  /* Bitfield. */
1376             bsz = decl.bits;
1377             if (!ctype_isinteger_or_bool(tct->info) ||
1378                 (bsz == 0 && decl.name) || 8*tct->size > CTBSZ_MAX ||
1379                 bsz > ((tct->info & CTF_BOOL) ? 1 : 8*tct->size))
1380               cp_errmsg(cp, ':', LJ_ERR_BADVAL);
1381           }
1382 
1383           /* Create temporary field for layout phase. */
1384           ct->info = CTINFO(CT_FIELD, ctypeid + (bsz << CTSHIFT_BITCSZ));
1385           ct->size = decl.attr;
1386           if (decl.name) ctype_setname(ct, decl.name);
1387 
1388         add_field:
1389           ctype_get(cp->cts, lastid)->sib = fieldid;
1390           lastid = fieldid;
1391         }
1392         if (!cp_opt(cp, ',')) break;
1393         cp_decl_reset(&decl);
1394       }
1395       cp_check(cp, ';');
1396     }
1397     cp_check(cp, '}');
1398     ctype_get(cp->cts, lastid)->sib = 0;  /* Drop sib = 1 for empty structs. */
1399     cp_decl_attributes(cp, sdecl);  /* Layout phase needs postfix attributes. */
1400     cp_struct_layout(cp, sid, sdecl->attr);
1401   }
1402   return sid;
1403 }
1404 
1405 /* Parse enum declaration. */
1406 static CTypeID cp_decl_enum(CPState *cp, CPDecl *sdecl)
1407 {
1408   CTypeID eid = cp_struct_name(cp, sdecl, CTINFO(CT_ENUM, CTID_VOID));
1409   CTInfo einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_UINT32);
1410   CTSize esize = 4;  /* Only 32 bit enums are supported. */
1411   if (cp_opt(cp, '{')) {  /* Enum definition. */
1412     CPValue k;
1413     CTypeID lastid = eid;
1414     k.u32 = 0;
1415     k.id = CTID_INT32;
1416     do {
1417       GCstr *name = cp->str;
1418       if (cp->tok != CTOK_IDENT) cp_err_token(cp, CTOK_IDENT);
1419       if (cp->val.id) cp_errmsg(cp, 0, LJ_ERR_FFI_REDEF, strdata(name));
1420       cp_next(cp);
1421       if (cp_opt(cp, '=')) {
1422         cp_expr_kint(cp, &k);
1423         if (k.id == CTID_UINT32) {
1424           /* C99 says that enum constants are always (signed) integers.
1425           ** But since unsigned constants like 0x80000000 are quite common,
1426           ** those are left as uint32_t.
1427           */
1428           if (k.i32 >= 0) k.id = CTID_INT32;
1429         } else {
1430           /* OTOH it's common practice and even mandated by some ABIs
1431           ** that the enum type itself is unsigned, unless there are any
1432           ** negative constants.
1433           */
1434           k.id = CTID_INT32;
1435           if (k.i32 < 0) einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_INT32);
1436         }
1437       }
1438       /* Add named enum constant. */
1439       {
1440         CType *ct;
1441         CTypeID constid = lj_ctype_new(cp->cts, &ct);
1442         ctype_get(cp->cts, lastid)->sib = constid;
1443         lastid = constid;
1444         ctype_setname(ct, name);
1445         ct->info = CTINFO(CT_CONSTVAL, CTF_CONST|k.id);
1446         ct->size = k.u32++;
1447         if (k.u32 == 0x80000000u) k.id = CTID_UINT32;
1448         lj_ctype_addname(cp->cts, ct, constid);
1449       }
1450       if (!cp_opt(cp, ',')) break;
1451     } while (cp->tok != '}');  /* Trailing ',' is ok. */
1452     cp_check(cp, '}');
1453     /* Complete enum. */
1454     ctype_get(cp->cts, eid)->info = einfo;
1455     ctype_get(cp->cts, eid)->size = esize;
1456   }
1457   return eid;
1458 }
1459 
1460 /* Parse declaration specifiers. */
1461 static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl)
1462 {
1463   uint32_t cds = 0, sz = 0;
1464   CTypeID tdef = 0;
1465 
1466   decl->cp = cp;
1467   decl->mode = cp->mode;
1468   decl->name = NULL;
1469   decl->redir = NULL;
1470   decl->attr = 0;
1471   decl->fattr = 0;
1472   decl->pos = decl->top = 0;
1473   decl->stack[0].next = 0;
1474 
1475   for (;;) {  /* Parse basic types. */
1476     cp_decl_attributes(cp, decl);
1477     if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECLFLAG) {
1478       uint32_t cbit;
1479       if (cp->ct->size) {
1480         if (sz) goto end_decl;
1481         sz = cp->ct->size;
1482       }
1483       cbit = (1u << (cp->tok - CTOK_FIRSTDECL));
1484       cds = cds | cbit | ((cbit & cds & CDF_LONG) << 1);
1485       if (cp->tok >= CTOK_FIRSTSCL) {
1486         if (!(scl & cbit)) cp_errmsg(cp, cp->tok, LJ_ERR_FFI_BADSCL);
1487       } else if (tdef) {
1488         goto end_decl;
1489       }
1490       cp_next(cp);
1491       continue;
1492     }
1493     if (sz || tdef ||
1494         (cds & (CDF_SHORT|CDF_LONG|CDF_SIGNED|CDF_UNSIGNED|CDF_COMPLEX)))
1495       break;
1496     switch (cp->tok) {
1497     case CTOK_STRUCT:
1498       tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, 0));
1499       continue;
1500     case CTOK_UNION:
1501       tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, CTF_UNION));
1502       continue;
1503     case CTOK_ENUM:
1504       tdef = cp_decl_enum(cp, decl);
1505       continue;
1506     case CTOK_IDENT:
1507       if (ctype_istypedef(cp->ct->info)) {
1508         tdef = ctype_cid(cp->ct->info);  /* Get typedef. */
1509         cp_next(cp);
1510         continue;
1511       }
1512       break;
1513     case '$':
1514       tdef = cp->val.id;
1515       cp_next(cp);
1516       continue;
1517     default:
1518       break;
1519     }
1520     break;
1521   }
1522 end_decl:
1523 
1524   if ((cds & CDF_COMPLEX))  /* Use predefined complex types. */
1525     tdef = sz == 4 ? CTID_COMPLEX_FLOAT : CTID_COMPLEX_DOUBLE;
1526 
1527   if (tdef) {
1528     cp_push_type(decl, tdef);
1529   } else if ((cds & CDF_VOID)) {
1530     cp_push(decl, CTINFO(CT_VOID, (decl->attr & CTF_QUAL)), CTSIZE_INVALID);
1531     decl->attr &= ~CTF_QUAL;
1532   } else {
1533     /* Determine type info and size. */
1534     CTInfo info = CTINFO(CT_NUM, (cds & CDF_UNSIGNED) ? CTF_UNSIGNED : 0);
1535     if ((cds & CDF_BOOL)) {
1536       if ((cds & ~(CDF_SCL|CDF_BOOL|CDF_INT|CDF_SIGNED|CDF_UNSIGNED)))
1537         cp_errmsg(cp, 0, LJ_ERR_FFI_INVTYPE);
1538       info |= CTF_BOOL;
1539       if (!(cds & CDF_SIGNED)) info |= CTF_UNSIGNED;
1540       if (!sz) {
1541         sz = 1;
1542       }
1543     } else if ((cds & CDF_FP)) {
1544       info = CTINFO(CT_NUM, CTF_FP);
1545       if ((cds & CDF_LONG)) sz = sizeof(long double);
1546     } else if ((cds & CDF_CHAR)) {
1547       if ((cds & (CDF_CHAR|CDF_SIGNED|CDF_UNSIGNED)) == CDF_CHAR)
1548         info |= CTF_UCHAR;  /* Handle platforms where char is unsigned. */
1549     } else if ((cds & CDF_SHORT)) {
1550       sz = sizeof(short);
1551     } else if ((cds & CDF_LONGLONG)) {
1552       sz = 8;
1553     } else if ((cds & CDF_LONG)) {
1554       info |= CTF_LONG;
1555       sz = sizeof(long);
1556     } else if (!sz) {
1557       if (!(cds & (CDF_SIGNED|CDF_UNSIGNED)))
1558         cp_errmsg(cp, cp->tok, LJ_ERR_FFI_DECLSPEC);
1559       sz = sizeof(int);
1560     }
1561     lua_assert(sz != 0);
1562     info += CTALIGN(lj_fls(sz));  /* Use natural alignment. */
1563     info += (decl->attr & CTF_QUAL);  /* Merge qualifiers. */
1564     cp_push(decl, info, sz);
1565     decl->attr &= ~CTF_QUAL;
1566   }
1567   decl->specpos = decl->pos;
1568   decl->specattr = decl->attr;
1569   decl->specfattr = decl->fattr;
1570   return (cds & CDF_SCL);  /* Return storage class. */
1571 }
1572 
1573 /* Parse array declaration. */
1574 static void cp_decl_array(CPState *cp, CPDecl *decl)
1575 {
1576   CTInfo info = CTINFO(CT_ARRAY, 0);
1577   CTSize nelem = CTSIZE_INVALID;  /* Default size for a[] or a[?]. */
1578   cp_decl_attributes(cp, decl);
1579   if (cp_opt(cp, '?'))
1580     info |= CTF_VLA;  /* Create variable-length array a[?]. */
1581   else if (cp->tok != ']')
1582     nelem = cp_expr_ksize(cp);
1583   cp_check(cp, ']');
1584   cp_add(decl, info, nelem);
1585 }
1586 
1587 /* Parse function declaration. */
1588 static void cp_decl_func(CPState *cp, CPDecl *fdecl)
1589 {
1590   CTSize nargs = 0;
1591   CTInfo info = CTINFO(CT_FUNC, 0);
1592   CTypeID lastid = 0, anchor = 0;
1593   if (cp->tok != ')') {
1594     do {
1595       CPDecl decl;
1596       CTypeID ctypeid, fieldid;
1597       CType *ct;
1598       if (cp_opt(cp, '.')) {  /* Vararg function. */
1599         cp_check(cp, '.');  /* Workaround for the minimalistic lexer. */
1600         cp_check(cp, '.');
1601         info |= CTF_VARARG;
1602         break;
1603       }
1604       cp_decl_spec(cp, &decl, CDF_REGISTER);
1605       decl.mode = CPARSE_MODE_DIRECT|CPARSE_MODE_ABSTRACT;
1606       cp_declarator(cp, &decl);
1607       ctypeid = cp_decl_intern(cp, &decl);
1608       ct = ctype_raw(cp->cts, ctypeid);
1609       if (ctype_isvoid(ct->info))
1610         break;
1611       else if (ctype_isrefarray(ct->info))
1612         ctypeid = lj_ctype_intern(cp->cts,
1613           CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ct->info)), CTSIZE_PTR);
1614       else if (ctype_isfunc(ct->info))
1615         ctypeid = lj_ctype_intern(cp->cts,
1616           CTINFO(CT_PTR, CTALIGN_PTR|ctypeid), CTSIZE_PTR);
1617       /* Add new parameter. */
1618       fieldid = lj_ctype_new(cp->cts, &ct);
1619       if (anchor)
1620         ctype_get(cp->cts, lastid)->sib = fieldid;
1621       else
1622         anchor = fieldid;
1623       lastid = fieldid;
1624       if (decl.name) ctype_setname(ct, decl.name);
1625       ct->info = CTINFO(CT_FIELD, ctypeid);
1626       ct->size = nargs++;
1627     } while (cp_opt(cp, ','));
1628   }
1629   cp_check(cp, ')');
1630   if (cp_opt(cp, '{')) {  /* Skip function definition. */
1631     int level = 1;
1632     cp->mode |= CPARSE_MODE_SKIP;
1633     for (;;) {
1634       if (cp->tok == '{') level++;
1635       else if (cp->tok == '}' && --level == 0) break;
1636       else if (cp->tok == CTOK_EOF) cp_err_token(cp, '}');
1637       cp_next(cp);
1638     }
1639     cp->mode &= ~CPARSE_MODE_SKIP;
1640     cp->tok = ';';  /* Ok for cp_decl_multi(), error in cp_decl_single(). */
1641   }
1642   info |= (fdecl->fattr & ~CTMASK_CID);
1643   fdecl->fattr = 0;
1644   fdecl->stack[cp_add(fdecl, info, nargs)].sib = anchor;
1645 }
1646 
1647 /* Parse declarator. */
1648 static void cp_declarator(CPState *cp, CPDecl *decl)
1649 {
1650   if (++cp->depth > CPARSE_MAX_DECLDEPTH) cp_err(cp, LJ_ERR_XLEVELS);
1651 
1652   for (;;) {  /* Head of declarator. */
1653     if (cp_opt(cp, '*')) {  /* Pointer. */
1654       CTSize sz;
1655       CTInfo info;
1656       cp_decl_attributes(cp, decl);
1657       sz = CTSIZE_PTR;
1658       info = CTINFO(CT_PTR, CTALIGN_PTR);
1659 #if LJ_64
1660       if (ctype_msizeP(decl->attr) == 4) {
1661         sz = 4;
1662         info = CTINFO(CT_PTR, CTALIGN(2));
1663       }
1664 #endif
1665       info += (decl->attr & (CTF_QUAL|CTF_REF));
1666       decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP));
1667       cp_push(decl, info, sz);
1668     } else if (cp_opt(cp, '&') || cp_opt(cp, CTOK_ANDAND)) {  /* Reference. */
1669       decl->attr &= ~(CTF_QUAL|(CTMASK_MSIZEP<<CTSHIFT_MSIZEP));
1670       cp_push(decl, CTINFO_REF(0), CTSIZE_PTR);
1671     } else {
1672       break;
1673     }
1674   }
1675 
1676   if (cp_opt(cp, '(')) {  /* Inner declarator. */
1677     CPDeclIdx pos;
1678     cp_decl_attributes(cp, decl);
1679     /* Resolve ambiguity between inner declarator and 1st function parameter. */
1680     if ((decl->mode & CPARSE_MODE_ABSTRACT) &&
1681         (cp->tok == ')' || cp_istypedecl(cp))) goto func_decl;
1682     pos = decl->pos;
1683     cp_declarator(cp, decl);
1684     cp_check(cp, ')');
1685     decl->pos = pos;
1686   } else if (cp->tok == CTOK_IDENT) {  /* Direct declarator. */
1687     if (!(decl->mode & CPARSE_MODE_DIRECT)) cp_err_token(cp, CTOK_EOF);
1688     decl->name = cp->str;
1689     decl->nameid = cp->val.id;
1690     cp_next(cp);
1691   } else {  /* Abstract declarator. */
1692     if (!(decl->mode & CPARSE_MODE_ABSTRACT)) cp_err_token(cp, CTOK_IDENT);
1693   }
1694 
1695   for (;;) {  /* Tail of declarator. */
1696     if (cp_opt(cp, '[')) {  /* Array. */
1697       cp_decl_array(cp, decl);
1698     } else if (cp_opt(cp, '(')) {  /* Function. */
1699     func_decl:
1700       cp_decl_func(cp, decl);
1701     } else {
1702       break;
1703     }
1704   }
1705 
1706   if ((decl->mode & CPARSE_MODE_FIELD) && cp_opt(cp, ':'))  /* Field width. */
1707     decl->bits = cp_expr_ksize(cp);
1708 
1709   /* Process postfix attributes. */
1710   cp_decl_attributes(cp, decl);
1711   cp_push_attributes(decl);
1712 
1713   cp->depth--;
1714 }
1715 
1716 /* Parse an abstract type declaration and return it's C type ID. */
1717 static CTypeID cp_decl_abstract(CPState *cp)
1718 {
1719   CPDecl decl;
1720   cp_decl_spec(cp, &decl, 0);
1721   decl.mode = CPARSE_MODE_ABSTRACT;
1722   cp_declarator(cp, &decl);
1723   return cp_decl_intern(cp, &decl);
1724 }
1725 
1726 /* Handle pragmas. */
1727 static void cp_pragma(CPState *cp, BCLine pragmaline)
1728 {
1729   cp_next(cp);
1730   if (cp->tok == CTOK_IDENT &&
1731       cp->str->hash == H_(e79b999f,42ca3e85))  {  /* pack */
1732     cp_next(cp);
1733     cp_check(cp, '(');
1734     if (cp->tok == CTOK_IDENT) {
1735       if (cp->str->hash == H_(738e923c,a1b65954)) {  /* push */
1736         if (cp->curpack < CPARSE_MAX_PACKSTACK) {
1737           cp->packstack[cp->curpack+1] = cp->packstack[cp->curpack];
1738           cp->curpack++;
1739         }
1740       } else if (cp->str->hash == H_(6c71cf27,6c71cf27)) {  /* pop */
1741         if (cp->curpack > 0) cp->curpack--;
1742       } else {
1743         cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
1744       }
1745       cp_next(cp);
1746       if (!cp_opt(cp, ',')) goto end_pack;
1747     }
1748     if (cp->tok == CTOK_INTEGER) {
1749       cp->packstack[cp->curpack] = cp->val.u32 ? lj_fls(cp->val.u32) : 0;
1750       cp_next(cp);
1751     } else {
1752       cp->packstack[cp->curpack] = 255;
1753     }
1754   end_pack:
1755     cp_check(cp, ')');
1756   } else {  /* Ignore all other pragmas. */
1757     while (cp->tok != CTOK_EOF && cp->linenumber == pragmaline)
1758       cp_next(cp);
1759   }
1760 }
1761 
1762 /* Handle line number. */
1763 static void cp_line(CPState *cp, BCLine hashline)
1764 {
1765   BCLine newline = cp->val.u32;
1766   /* TODO: Handle file name and include it in error messages. */
1767   while (cp->tok != CTOK_EOF && cp->linenumber == hashline)
1768     cp_next(cp);
1769   cp->linenumber = newline;
1770 }
1771 
1772 /* Parse multiple C declarations of types or extern identifiers. */
1773 static void cp_decl_multi(CPState *cp)
1774 {
1775   int first = 1;
1776   while (cp->tok != CTOK_EOF) {
1777     CPDecl decl;
1778     CPscl scl;
1779     if (cp_opt(cp, ';')) {  /* Skip empty statements. */
1780       first = 0;
1781       continue;
1782     }
1783     if (cp->tok == '#') {  /* Workaround, since we have no preprocessor, yet. */
1784       BCLine hashline = cp->linenumber;
1785       CPToken tok = cp_next(cp);
1786       if (tok == CTOK_INTEGER) {
1787         cp_line(cp, hashline);
1788         continue;
1789       } else if (tok == CTOK_IDENT &&
1790                  cp->str->hash == H_(187aab88,fcb60b42)) { /* line */
1791         if (cp_next(cp) != CTOK_INTEGER) cp_err_token(cp, tok);
1792         cp_line(cp, hashline);
1793         continue;
1794       } else if (tok == CTOK_IDENT &&
1795           cp->str->hash == H_(f5e6b4f8,1d509107)) { /* pragma */
1796         cp_pragma(cp, hashline);
1797         continue;
1798       } else {
1799         cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL);
1800       }
1801     }
1802     scl = cp_decl_spec(cp, &decl, CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC);
1803     if ((cp->tok == ';' || cp->tok == CTOK_EOF) &&
1804         ctype_istypedef(decl.stack[0].info)) {
1805       CTInfo info = ctype_rawchild(cp->cts, &decl.stack[0])->info;
1806       if (ctype_isstruct(info) || ctype_isenum(info))
1807         goto decl_end;  /* Accept empty declaration of struct/union/enum. */
1808     }
1809     for (;;) {
1810       CTypeID ctypeid;
1811       cp_declarator(cp, &decl);
1812       ctypeid = cp_decl_intern(cp, &decl);
1813       if (decl.name && !decl.nameid) {  /* NYI: redeclarations are ignored. */
1814         CType *ct;
1815         CTypeID id;
1816         if ((scl & CDF_TYPEDEF)) {  /* Create new typedef. */
1817           id = lj_ctype_new(cp->cts, &ct);
1818           ct->info = CTINFO(CT_TYPEDEF, ctypeid);
1819           goto noredir;
1820         } else if (ctype_isfunc(ctype_get(cp->cts, ctypeid)->info)) {
1821           /* Treat both static and extern function declarations as extern. */
1822           ct = ctype_get(cp->cts, ctypeid);
1823           /* We always get new anonymous functions (typedefs are copied). */
1824           lua_assert(gcref(ct->name) == NULL);
1825           id = ctypeid;  /* Just name it. */
1826         } else if ((scl & CDF_STATIC)) {  /* Accept static constants. */
1827           id = cp_decl_constinit(cp, &ct, ctypeid);
1828           goto noredir;
1829         } else {  /* External references have extern or no storage class. */
1830           id = lj_ctype_new(cp->cts, &ct);
1831           ct->info = CTINFO(CT_EXTERN, ctypeid);
1832         }
1833         if (decl.redir) {  /* Add attribute for redirected symbol name. */
1834           CType *cta;
1835           CTypeID aid = lj_ctype_new(cp->cts, &cta);
1836           ct = ctype_get(cp->cts, id);  /* Table may have been reallocated. */
1837           cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR));
1838           cta->sib = ct->sib;
1839           ct->sib = aid;
1840           ctype_setname(cta, decl.redir);
1841         }
1842       noredir:
1843         ctype_setname(ct, decl.name);
1844         lj_ctype_addname(cp->cts, ct, id);
1845       }
1846       if (!cp_opt(cp, ',')) break;
1847       cp_decl_reset(&decl);
1848     }
1849   decl_end:
1850     if (cp->tok == CTOK_EOF && first) break;  /* May omit ';' for 1 decl. */
1851     first = 0;
1852     cp_check(cp, ';');
1853   }
1854 }
1855 
1856 /* Parse a single C type declaration. */
1857 static void cp_decl_single(CPState *cp)
1858 {
1859   CPDecl decl;
1860   cp_decl_spec(cp, &decl, 0);
1861   cp_declarator(cp, &decl);
1862   cp->val.id = cp_decl_intern(cp, &decl);
1863   if (cp->tok != CTOK_EOF) cp_err_token(cp, CTOK_EOF);
1864 }
1865 
1866 #undef H_
1867 
1868 /* ------------------------------------------------------------------------ */
1869 
1870 /* Protected callback for C parser. */
1871 static TValue *cpcparser(lua_State *L, lua_CFunction dummy, void *ud)
1872 {
1873   CPState *cp = (CPState *)ud;
1874   UNUSED(dummy);
1875   cframe_errfunc(L->cframe) = -1;  /* Inherit error function. */
1876   cp_init(cp);
1877   if ((cp->mode & CPARSE_MODE_MULTI))
1878     cp_decl_multi(cp);
1879   else
1880     cp_decl_single(cp);
1881   if (cp->param && cp->param != cp->L->top)
1882     cp_err(cp, LJ_ERR_FFI_NUMPARAM);
1883   lua_assert(cp->depth == 0);
1884   return NULL;
1885 }
1886 
1887 /* C parser. */
1888 int lj_cparse(CPState *cp)
1889 {
1890   LJ_CTYPE_SAVE(cp->cts);
1891   int errcode = lj_vm_cpcall(cp->L, NULL, cp, cpcparser);
1892   if (errcode)
1893     LJ_CTYPE_RESTORE(cp->cts);
1894   cp_cleanup(cp);
1895   return errcode;
1896 }
1897 
1898 #endif

/* [<][>][^][v][top][bottom][index][help] */