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

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