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

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