2 ** C declaration parser.
3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
14 #include "lj_cparse.h"
18 #include "lj_strscan.h"
19 #include "lj_strfmt.h"
22 ** Important note: this is NOT a validating C parser! This is a minimal
23 ** C declaration parser, solely for use by the LuaJIT FFI.
25 ** It ought to return correct results for properly formed C declarations,
26 ** but it may accept some invalid declarations, too (and return nonsense).
27 ** Also, it shows rather generic error messages to avoid unnecessary bloat.
28 ** If in doubt, please check the input against your favorite C compiler.
32 #define lj_assertCP(c, ...) (lj_assertG_(G(cp->L), (c), __VA_ARGS__))
34 #define lj_assertCP(c, ...) ((void)cp)
37 /* -- Miscellaneous ------------------------------------------------------- */
39 /* Match string against a C literal. */
40 #define cp_str_is(str, k) \
41 ((str)->len == sizeof(k)-1 && !memcmp(strdata(str), k, sizeof(k)-1))
43 /* Check string against a linear list of matches. */
44 int lj_cparse_case(GCstr
*str
, const char *match
)
48 for (n
= 0; (len
= (MSize
)*match
++); n
++, match
+= len
) {
49 if (str
->len
== len
&& !memcmp(match
, strdata(str
), len
))
55 /* -- C lexer ------------------------------------------------------------- */
57 /* C lexer token names. */
58 static const char *const ctoknames
[] = {
59 #define CTOKSTR(name, str) str,
65 /* Forward declaration. */
66 LJ_NORET
static void cp_err(CPState
*cp
, ErrMsg em
);
68 static const char *cp_tok2str(CPState
*cp
, CPToken tok
)
70 lj_assertCP(tok
< CTOK_FIRSTDECL
, "bad CPToken %d", tok
);
72 return ctoknames
[tok
-CTOK_OFS
-1];
73 else if (!lj_char_iscntrl(tok
))
74 return lj_strfmt_pushf(cp
->L
, "%c", tok
);
76 return lj_strfmt_pushf(cp
->L
, "char(%d)", tok
);
80 static LJ_AINLINE
int cp_iseol(CPChar c
)
82 return (c
== '\n' || c
== '\r');
85 /* Peek next raw character. */
86 static LJ_AINLINE CPChar
cp_rawpeek(CPState
*cp
)
88 return (CPChar
)(uint8_t)(*cp
->p
);
91 static LJ_NOINLINE CPChar
cp_get_bs(CPState
*cp
);
93 /* Get next character. */
94 static LJ_AINLINE CPChar
cp_get(CPState
*cp
)
96 cp
->c
= (CPChar
)(uint8_t)(*cp
->p
++);
97 if (LJ_LIKELY(cp
->c
!= '\\')) return cp
->c
;
101 /* Transparently skip backslash-escaped line breaks. */
102 static LJ_NOINLINE CPChar
cp_get_bs(CPState
*cp
)
104 CPChar c2
, c
= cp_rawpeek(cp
);
105 if (!cp_iseol(c
)) return cp
->c
;
108 if (cp_iseol(c2
) && c2
!= c
) cp
->p
++;
113 /* Save character in buffer. */
114 static LJ_AINLINE
void cp_save(CPState
*cp
, CPChar c
)
116 lj_buf_putb(&cp
->sb
, c
);
119 /* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
120 static void cp_newline(CPState
*cp
)
122 CPChar c
= cp_rawpeek(cp
);
123 if (cp_iseol(c
) && c
!= cp
->c
) cp
->p
++;
127 LJ_NORET
static void cp_errmsg(CPState
*cp
, CPToken tok
, ErrMsg em
, ...)
129 const char *msg
, *tokstr
;
134 } else if (tok
== CTOK_IDENT
|| tok
== CTOK_INTEGER
|| tok
== CTOK_STRING
||
135 tok
>= CTOK_FIRSTDECL
) {
136 if (cp
->sb
.w
== cp
->sb
.b
) cp_save(cp
, '$');
140 tokstr
= cp_tok2str(cp
, tok
);
144 msg
= lj_strfmt_pushvf(L
, err2msg(em
), argp
);
147 msg
= lj_strfmt_pushf(L
, err2msg(LJ_ERR_XNEAR
), msg
, tokstr
);
148 if (cp
->linenumber
> 1)
149 msg
= lj_strfmt_pushf(L
, "%s at line %d", msg
, cp
->linenumber
);
150 lj_err_callermsg(L
, msg
);
153 LJ_NORET LJ_NOINLINE
static void cp_err_token(CPState
*cp
, CPToken tok
)
155 cp_errmsg(cp
, cp
->tok
, LJ_ERR_XTOKEN
, cp_tok2str(cp
, tok
));
158 LJ_NORET LJ_NOINLINE
static void cp_err_badidx(CPState
*cp
, CType
*ct
)
160 GCstr
*s
= lj_ctype_repr(cp
->cts
->L
, ctype_typeid(cp
->cts
, ct
), NULL
);
161 cp_errmsg(cp
, 0, LJ_ERR_FFI_BADIDX
, strdata(s
));
164 LJ_NORET LJ_NOINLINE
static void cp_err(CPState
*cp
, ErrMsg em
)
166 cp_errmsg(cp
, 0, em
);
169 /* -- Main lexical scanner ------------------------------------------------ */
171 /* Parse number literal. Only handles int32_t/uint32_t right now. */
172 static CPToken
cp_number(CPState
*cp
)
176 do { cp_save(cp
, cp
->c
); } while (lj_char_isident(cp_get(cp
)));
178 fmt
= lj_strscan_scan((const uint8_t *)(cp
->sb
.b
), sbuflen(&cp
->sb
)-1,
180 if (fmt
== STRSCAN_INT
) cp
->val
.id
= CTID_INT32
;
181 else if (fmt
== STRSCAN_U32
) cp
->val
.id
= CTID_UINT32
;
182 else if (!(cp
->mode
& CPARSE_MODE_SKIP
))
183 cp_errmsg(cp
, CTOK_INTEGER
, LJ_ERR_XNUMBER
);
184 cp
->val
.u32
= (uint32_t)o
.i
;
188 /* Parse identifier or keyword. */
189 static CPToken
cp_ident(CPState
*cp
)
191 do { cp_save(cp
, cp
->c
); } while (lj_char_isident(cp_get(cp
)));
192 cp
->str
= lj_buf_str(cp
->L
, &cp
->sb
);
193 cp
->val
.id
= lj_ctype_getname(cp
->cts
, &cp
->ct
, cp
->str
, cp
->tmask
);
194 if (ctype_type(cp
->ct
->info
) == CT_KW
)
195 return ctype_cid(cp
->ct
->info
);
199 /* Parse parameter. */
200 static CPToken
cp_param(CPState
*cp
)
202 CPChar c
= cp_get(cp
);
203 TValue
*o
= cp
->param
;
204 if (lj_char_isident(c
) || c
== '$') /* Reserve $xyz for future extensions. */
205 cp_errmsg(cp
, c
, LJ_ERR_XSYNTAX
);
206 if (!o
|| o
>= cp
->L
->top
)
207 cp_err(cp
, LJ_ERR_FFI_NUMPARAM
);
212 cp
->ct
= &cp
->cts
->tab
[0];
214 } else if (tvisnumber(o
)) {
215 cp
->val
.i32
= numberVint(o
);
216 cp
->val
.id
= CTID_INT32
;
221 lj_err_argtype(cp
->L
, (int)(o
-cp
->L
->base
)+1, "type parameter");
223 if (cd
->ctypeid
== CTID_CTYPEID
)
224 cp
->val
.id
= *(CTypeID
*)cdataptr(cd
);
226 cp
->val
.id
= cd
->ctypeid
;
231 /* Parse string or character constant. */
232 static CPToken
cp_string(CPState
*cp
)
234 CPChar delim
= cp
->c
;
236 while (cp
->c
!= delim
) {
238 if (c
== '\0') cp_errmsg(cp
, CTOK_EOF
, LJ_ERR_XSTR
);
242 case '\0': cp_errmsg(cp
, CTOK_EOF
, LJ_ERR_XSTR
); break;
243 case 'a': c
= '\a'; break;
244 case 'b': c
= '\b'; break;
245 case 'f': c
= '\f'; break;
246 case 'n': c
= '\n'; break;
247 case 'r': c
= '\r'; break;
248 case 't': c
= '\t'; break;
249 case 'v': c
= '\v'; break;
250 case 'e': c
= 27; break;
253 while (lj_char_isxdigit(cp_get(cp
)))
254 c
= (c
<<4) + (lj_char_isdigit(cp
->c
) ? cp
->c
-'0' : (cp
->c
&15)+9);
255 cp_save(cp
, (c
& 0xff));
258 if (lj_char_isdigit(c
)) {
260 if (lj_char_isdigit(cp_get(cp
))) {
261 c
= c
*8 + (cp
->c
- '0');
262 if (lj_char_isdigit(cp_get(cp
))) {
263 c
= c
*8 + (cp
->c
- '0');
267 cp_save(cp
, (c
& 0xff));
278 cp
->str
= lj_buf_str(cp
->L
, &cp
->sb
);
281 if (sbuflen(&cp
->sb
) != 1) cp_err_token(cp
, '\'');
282 cp
->val
.i32
= (int32_t)(char)*cp
->sb
.b
;
283 cp
->val
.id
= CTID_INT32
;
288 /* Skip C comment. */
289 static void cp_comment_c(CPState
*cp
)
292 if (cp_get(cp
) == '*') {
294 if (cp_get(cp
) == '/') { cp_get(cp
); return; }
295 } while (cp
->c
== '*');
297 if (cp_iseol(cp
->c
)) cp_newline(cp
);
298 } while (cp
->c
!= '\0');
301 /* Skip C++ comment. */
302 static void cp_comment_cpp(CPState
*cp
)
304 while (!cp_iseol(cp_get(cp
)) && cp
->c
!= '\0')
308 /* Lexical scanner for C. Only a minimal subset is implemented. */
309 static CPToken
cp_next_(CPState
*cp
)
311 lj_buf_reset(&cp
->sb
);
313 if (lj_char_isident(cp
->c
))
314 return lj_char_isdigit(cp
->c
) ? cp_number(cp
) : cp_ident(cp
);
316 case '\n': case '\r': cp_newline(cp
); /* fallthrough. */
317 case ' ': case '\t': case '\v': case '\f': cp_get(cp
); break;
318 case '"': case '\'': return cp_string(cp
);
320 if (cp_get(cp
) == '*') cp_comment_c(cp
);
321 else if (cp
->c
== '/') cp_comment_cpp(cp
);
325 if (cp_get(cp
) != '|') return '|';
326 cp_get(cp
); return CTOK_OROR
;
328 if (cp_get(cp
) != '&') return '&';
329 cp_get(cp
); return CTOK_ANDAND
;
331 if (cp_get(cp
) != '=') return '=';
332 cp_get(cp
); return CTOK_EQ
;
334 if (cp_get(cp
) != '=') return '!';
335 cp_get(cp
); return CTOK_NE
;
337 if (cp_get(cp
) == '=') { cp_get(cp
); return CTOK_LE
; }
338 else if (cp
->c
== '<') { cp_get(cp
); return CTOK_SHL
; }
341 if (cp_get(cp
) == '=') { cp_get(cp
); return CTOK_GE
; }
342 else if (cp
->c
== '>') { cp_get(cp
); return CTOK_SHR
; }
345 if (cp_get(cp
) != '>') return '-';
346 cp_get(cp
); return CTOK_DEREF
;
349 case '\0': return CTOK_EOF
;
350 default: { CPToken c
= cp
->c
; cp_get(cp
); return c
; }
355 static LJ_NOINLINE CPToken
cp_next(CPState
*cp
)
357 return (cp
->tok
= cp_next_(cp
));
360 /* -- C parser ------------------------------------------------------------ */
362 /* Namespaces for resolving identifiers. */
363 #define CPNS_DEFAULT \
364 ((1u<<CT_KW)|(1u<<CT_TYPEDEF)|(1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
365 #define CPNS_STRUCT ((1u<<CT_KW)|(1u<<CT_STRUCT)|(1u<<CT_ENUM))
367 typedef CTypeID CPDeclIdx
; /* Index into declaration stack. */
368 typedef uint32_t CPscl
; /* Storage class flags. */
370 /* Type declaration context. */
371 typedef struct CPDecl
{
372 CPDeclIdx top
; /* Top of declaration stack. */
373 CPDeclIdx pos
; /* Insertion position in declaration chain. */
374 CPDeclIdx specpos
; /* Saved position for declaration specifier. */
375 uint32_t mode
; /* Declarator mode. */
376 CPState
*cp
; /* C parser state. */
377 GCstr
*name
; /* Name of declared identifier (if direct). */
378 GCstr
*redir
; /* Redirected symbol name. */
379 CTypeID nameid
; /* Existing typedef for declared identifier. */
380 CTInfo attr
; /* Attributes. */
381 CTInfo fattr
; /* Function attributes. */
382 CTInfo specattr
; /* Saved attributes. */
383 CTInfo specfattr
; /* Saved function attributes. */
384 CTSize bits
; /* Field size in bits (if any). */
385 CType stack
[CPARSE_MAX_DECLSTACK
]; /* Type declaration stack. */
388 /* Forward declarations. */
389 static CPscl
cp_decl_spec(CPState
*cp
, CPDecl
*decl
, CPscl scl
);
390 static void cp_declarator(CPState
*cp
, CPDecl
*decl
);
391 static CTypeID
cp_decl_abstract(CPState
*cp
);
393 /* Initialize C parser state. Caller must set up: L, p, srcname, mode. */
394 static void cp_init(CPState
*cp
)
399 cp
->packstack
[0] = 255;
400 lj_buf_init(cp
->L
, &cp
->sb
);
401 lj_assertCP(cp
->p
!= NULL
, "uninitialized cp->p");
402 cp_get(cp
); /* Read-ahead first char. */
404 cp
->tmask
= CPNS_DEFAULT
;
405 cp_next(cp
); /* Read-ahead first token. */
408 /* Cleanup C parser state. */
409 static void cp_cleanup(CPState
*cp
)
411 global_State
*g
= G(cp
->L
);
412 lj_buf_free(g
, &cp
->sb
);
415 /* Check and consume optional token. */
416 static int cp_opt(CPState
*cp
, CPToken tok
)
418 if (cp
->tok
== tok
) { cp_next(cp
); return 1; }
422 /* Check and consume token. */
423 static void cp_check(CPState
*cp
, CPToken tok
)
425 if (cp
->tok
!= tok
) cp_err_token(cp
, tok
);
429 /* Check if the next token may start a type declaration. */
430 static int cp_istypedecl(CPState
*cp
)
432 if (cp
->tok
>= CTOK_FIRSTDECL
&& cp
->tok
<= CTOK_LASTDECL
) return 1;
433 if (cp
->tok
== CTOK_IDENT
&& ctype_istypedef(cp
->ct
->info
)) return 1;
434 if (cp
->tok
== '$') return 1;
438 /* -- Constant expression evaluator --------------------------------------- */
440 /* Forward declarations. */
441 static void cp_expr_unary(CPState
*cp
, CPValue
*k
);
442 static void cp_expr_sub(CPState
*cp
, CPValue
*k
, int pri
);
444 /* Please note that type handling is very weak here. Most ops simply
445 ** assume integer operands. Accessors are only needed to compute types and
446 ** return synthetic values. The only purpose of the expression evaluator
447 ** is to compute the values of constant expressions one would typically
448 ** find in C header files. And again: this is NOT a validating C parser!
451 /* Parse comma separated expression and return last result. */
452 static void cp_expr_comma(CPState
*cp
, CPValue
*k
)
454 do { cp_expr_sub(cp
, k
, 0); } while (cp_opt(cp
, ','));
457 /* Parse sizeof/alignof operator. */
458 static void cp_expr_sizeof(CPState
*cp
, CPValue
*k
, int wantsz
)
462 if (cp_opt(cp
, '(')) {
463 if (cp_istypedecl(cp
))
464 k
->id
= cp_decl_abstract(cp
);
466 cp_expr_comma(cp
, k
);
469 cp_expr_unary(cp
, k
);
471 info
= lj_ctype_info_raw(cp
->cts
, k
->id
, &sz
);
473 if (sz
!= CTSIZE_INVALID
)
475 else if (k
->id
!= CTID_A_CCHAR
) /* Special case for sizeof("string"). */
476 cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
478 k
->u32
= 1u << ctype_align(info
);
480 k
->id
= CTID_UINT32
; /* Really size_t. */
483 /* Parse prefix operators. */
484 static void cp_expr_prefix(CPState
*cp
, CPValue
*k
)
486 if (cp
->tok
== CTOK_INTEGER
) {
487 *k
= cp
->val
; cp_next(cp
);
488 } else if (cp_opt(cp
, '+')) {
489 cp_expr_unary(cp
, k
); /* Nothing to do (well, integer promotion). */
490 } else if (cp_opt(cp
, '-')) {
491 cp_expr_unary(cp
, k
); k
->i32
= (int32_t)(~(uint32_t)k
->i32
+1);
492 } else if (cp_opt(cp
, '~')) {
493 cp_expr_unary(cp
, k
); k
->i32
= ~k
->i32
;
494 } else if (cp_opt(cp
, '!')) {
495 cp_expr_unary(cp
, k
); k
->i32
= !k
->i32
; k
->id
= CTID_INT32
;
496 } else if (cp_opt(cp
, '(')) {
497 if (cp_istypedecl(cp
)) { /* Cast operator. */
498 CTypeID id
= cp_decl_abstract(cp
);
500 cp_expr_unary(cp
, k
);
501 k
->id
= id
; /* No conversion performed. */
502 } else { /* Sub-expression. */
503 cp_expr_comma(cp
, k
);
506 } else if (cp_opt(cp
, '*')) { /* Indirection. */
508 cp_expr_unary(cp
, k
);
509 ct
= lj_ctype_rawref(cp
->cts
, k
->id
);
510 if (!ctype_ispointer(ct
->info
))
511 cp_err_badidx(cp
, ct
);
512 k
->u32
= 0; k
->id
= ctype_cid(ct
->info
);
513 } else if (cp_opt(cp
, '&')) { /* Address operator. */
514 cp_expr_unary(cp
, k
);
515 k
->id
= lj_ctype_intern(cp
->cts
, CTINFO(CT_PTR
, CTALIGN_PTR
+k
->id
),
517 } else if (cp_opt(cp
, CTOK_SIZEOF
)) {
518 cp_expr_sizeof(cp
, k
, 1);
519 } else if (cp_opt(cp
, CTOK_ALIGNOF
)) {
520 cp_expr_sizeof(cp
, k
, 0);
521 } else if (cp
->tok
== CTOK_IDENT
) {
522 if (ctype_type(cp
->ct
->info
) == CT_CONSTVAL
) {
523 k
->u32
= cp
->ct
->size
; k
->id
= ctype_cid(cp
->ct
->info
);
524 } else if (ctype_type(cp
->ct
->info
) == CT_EXTERN
) {
525 k
->u32
= cp
->val
.id
; k
->id
= ctype_cid(cp
->ct
->info
);
526 } else if (ctype_type(cp
->ct
->info
) == CT_FUNC
) {
527 k
->u32
= cp
->val
.id
; k
->id
= cp
->val
.id
;
532 } else if (cp
->tok
== CTOK_STRING
) {
533 CTSize sz
= cp
->str
->len
;
534 while (cp_next(cp
) == CTOK_STRING
)
537 k
->id
= CTID_A_CCHAR
;
540 cp_errmsg(cp
, cp
->tok
, LJ_ERR_XSYMBOL
);
544 /* Parse postfix operators. */
545 static void cp_expr_postfix(CPState
*cp
, CPValue
*k
)
549 if (cp_opt(cp
, '[')) { /* Array/pointer index. */
551 cp_expr_comma(cp
, &k2
);
552 ct
= lj_ctype_rawref(cp
->cts
, k
->id
);
553 if (!ctype_ispointer(ct
->info
)) {
554 ct
= lj_ctype_rawref(cp
->cts
, k2
.id
);
555 if (!ctype_ispointer(ct
->info
))
556 cp_err_badidx(cp
, ct
);
560 } else if (cp
->tok
== '.' || cp
->tok
== CTOK_DEREF
) { /* Struct deref. */
563 ct
= lj_ctype_rawref(cp
->cts
, k
->id
);
564 if (cp
->tok
== CTOK_DEREF
) {
565 if (!ctype_ispointer(ct
->info
))
566 cp_err_badidx(cp
, ct
);
567 ct
= lj_ctype_rawref(cp
->cts
, ctype_cid(ct
->info
));
570 if (cp
->tok
!= CTOK_IDENT
) cp_err_token(cp
, CTOK_IDENT
);
571 if (!ctype_isstruct(ct
->info
) || ct
->size
== CTSIZE_INVALID
||
572 !(fct
= lj_ctype_getfield(cp
->cts
, ct
, cp
->str
, &ofs
)) ||
573 ctype_isbitfield(fct
->info
)) {
574 GCstr
*s
= lj_ctype_repr(cp
->cts
->L
, ctype_typeid(cp
->cts
, ct
), NULL
);
575 cp_errmsg(cp
, 0, LJ_ERR_FFI_BADMEMBER
, strdata(s
), strdata(cp
->str
));
578 k
->u32
= ctype_isconstval(ct
->info
) ? ct
->size
: 0;
583 k
->id
= ctype_cid(ct
->info
);
587 /* Parse infix operators. */
588 static void cp_expr_infix(CPState
*cp
, CPValue
*k
, int pri
)
591 k2
.u32
= 0; k2
.id
= 0; /* Silence the compiler. */
595 if (cp_opt(cp
, '?')) {
597 cp_expr_comma(cp
, &k2
); /* Right-associative. */
599 cp_expr_sub(cp
, &k3
, 0);
600 k
->u32
= k
->u32
? k2
.u32
: k3
.u32
;
601 k
->id
= k2
.id
> k3
.id
? k2
.id
: k3
.id
;
606 if (cp_opt(cp
, CTOK_OROR
)) {
607 cp_expr_sub(cp
, &k2
, 2); k
->i32
= k
->u32
|| k2
.u32
; k
->id
= CTID_INT32
;
612 if (cp_opt(cp
, CTOK_ANDAND
)) {
613 cp_expr_sub(cp
, &k2
, 3); k
->i32
= k
->u32
&& k2
.u32
; k
->id
= CTID_INT32
;
618 if (cp_opt(cp
, '|')) {
619 cp_expr_sub(cp
, &k2
, 4); k
->u32
= k
->u32
| k2
.u32
; goto arith_result
;
623 if (cp_opt(cp
, '^')) {
624 cp_expr_sub(cp
, &k2
, 5); k
->u32
= k
->u32
^ k2
.u32
; goto arith_result
;
628 if (cp_opt(cp
, '&')) {
629 cp_expr_sub(cp
, &k2
, 6); k
->u32
= k
->u32
& k2
.u32
; goto arith_result
;
633 if (cp_opt(cp
, CTOK_EQ
)) {
634 cp_expr_sub(cp
, &k2
, 7); k
->i32
= k
->u32
== k2
.u32
; k
->id
= CTID_INT32
;
636 } else if (cp_opt(cp
, CTOK_NE
)) {
637 cp_expr_sub(cp
, &k2
, 7); k
->i32
= k
->u32
!= k2
.u32
; k
->id
= CTID_INT32
;
642 if (cp_opt(cp
, '<')) {
643 cp_expr_sub(cp
, &k2
, 8);
644 if (k
->id
== CTID_INT32
&& k2
.id
== CTID_INT32
)
645 k
->i32
= k
->i32
< k2
.i32
;
647 k
->i32
= k
->u32
< k2
.u32
;
650 } else if (cp_opt(cp
, '>')) {
651 cp_expr_sub(cp
, &k2
, 8);
652 if (k
->id
== CTID_INT32
&& k2
.id
== CTID_INT32
)
653 k
->i32
= k
->i32
> k2
.i32
;
655 k
->i32
= k
->u32
> k2
.u32
;
658 } else if (cp_opt(cp
, CTOK_LE
)) {
659 cp_expr_sub(cp
, &k2
, 8);
660 if (k
->id
== CTID_INT32
&& k2
.id
== CTID_INT32
)
661 k
->i32
= k
->i32
<= k2
.i32
;
663 k
->i32
= k
->u32
<= k2
.u32
;
666 } else if (cp_opt(cp
, CTOK_GE
)) {
667 cp_expr_sub(cp
, &k2
, 8);
668 if (k
->id
== CTID_INT32
&& k2
.id
== CTID_INT32
)
669 k
->i32
= k
->i32
>= k2
.i32
;
671 k
->i32
= k
->u32
>= k2
.u32
;
677 if (cp_opt(cp
, CTOK_SHL
)) {
678 cp_expr_sub(cp
, &k2
, 9); k
->u32
= k
->u32
<< k2
.u32
;
680 } else if (cp_opt(cp
, CTOK_SHR
)) {
681 cp_expr_sub(cp
, &k2
, 9);
682 if (k
->id
== CTID_INT32
)
683 k
->i32
= k
->i32
>> k2
.i32
;
685 k
->u32
= k
->u32
>> k2
.u32
;
690 if (cp_opt(cp
, '+')) {
691 cp_expr_sub(cp
, &k2
, 10); k
->u32
= k
->u32
+ k2
.u32
;
693 if (k2
.id
> k
->id
) k
->id
= k2
.id
; /* Trivial promotion to unsigned. */
695 } else if (cp_opt(cp
, '-')) {
696 cp_expr_sub(cp
, &k2
, 10); k
->u32
= k
->u32
- k2
.u32
; goto arith_result
;
700 if (cp_opt(cp
, '*')) {
701 cp_expr_unary(cp
, &k2
); k
->u32
= k
->u32
* k2
.u32
; goto arith_result
;
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. */
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
;
711 k
->u32
= k
->u32
/ k2
.u32
;
713 } else if (cp_opt(cp
, '%')) {
714 cp_expr_unary(cp
, &k2
);
715 if (k2
.id
> k
->id
) k
->id
= k2
.id
; /* Trivial promotion to unsigned. */
717 (k
->id
== CTID_INT32
&& k
->u32
== 0x80000000u
&& k2
.i32
== -1))
718 cp_err(cp
, LJ_ERR_BADVAL
);
719 if (k
->id
== CTID_INT32
)
720 k
->i32
= k
->i32
% k2
.i32
;
722 k
->u32
= k
->u32
% k2
.u32
;
731 /* Parse and evaluate unary expression. */
732 static void cp_expr_unary(CPState
*cp
, CPValue
*k
)
734 if (++cp
->depth
> CPARSE_MAX_DECLDEPTH
) cp_err(cp
, LJ_ERR_XLEVELS
);
735 cp_expr_prefix(cp
, k
);
736 cp_expr_postfix(cp
, k
);
740 /* Parse and evaluate sub-expression. */
741 static void cp_expr_sub(CPState
*cp
, CPValue
*k
, int pri
)
743 cp_expr_unary(cp
, k
);
744 cp_expr_infix(cp
, k
, pri
);
747 /* Parse constant integer expression. */
748 static void cp_expr_kint(CPState
*cp
, CPValue
*k
)
751 cp_expr_sub(cp
, k
, 0);
752 ct
= ctype_raw(cp
->cts
, k
->id
);
753 if (!ctype_isinteger(ct
->info
)) cp_err(cp
, LJ_ERR_BADVAL
);
756 /* Parse (non-negative) size expression. */
757 static CTSize
cp_expr_ksize(CPState
*cp
)
760 cp_expr_kint(cp
, &k
);
761 if (k
.u32
>= 0x80000000u
) cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
765 /* -- Type declaration stack management ----------------------------------- */
767 /* Add declaration element behind the insertion position. */
768 static CPDeclIdx
cp_add(CPDecl
*decl
, CTInfo info
, CTSize size
)
770 CPDeclIdx top
= decl
->top
;
771 if (top
>= CPARSE_MAX_DECLSTACK
) cp_err(decl
->cp
, LJ_ERR_XLEVELS
);
772 decl
->stack
[top
].info
= info
;
773 decl
->stack
[top
].size
= size
;
774 decl
->stack
[top
].sib
= 0;
775 setgcrefnull(decl
->stack
[top
].name
);
776 decl
->stack
[top
].next
= decl
->stack
[decl
->pos
].next
;
777 decl
->stack
[decl
->pos
].next
= (CTypeID1
)top
;
782 /* Push declaration element before the insertion position. */
783 static CPDeclIdx
cp_push(CPDecl
*decl
, CTInfo info
, CTSize size
)
785 return (decl
->pos
= cp_add(decl
, info
, size
));
788 /* Push or merge attributes. */
789 static void cp_push_attributes(CPDecl
*decl
)
791 CType
*ct
= &decl
->stack
[decl
->pos
];
792 if (ctype_isfunc(ct
->info
)) { /* Ok to modify in-place. */
794 if ((decl
->fattr
& CTFP_CCONV
))
795 ct
->info
= (ct
->info
& (CTMASK_NUM
|CTF_VARARG
|CTMASK_CID
)) +
796 (decl
->fattr
& ~CTMASK_CID
);
799 if ((decl
->attr
& CTFP_ALIGNED
) && !(decl
->mode
& CPARSE_MODE_FIELD
))
800 cp_push(decl
, CTINFO(CT_ATTRIB
, CTATTRIB(CTA_ALIGN
)),
801 ctype_align(decl
->attr
));
805 /* Push unrolled type to declaration stack and merge qualifiers. */
806 static void cp_push_type(CPDecl
*decl
, CTypeID id
)
808 CType
*ct
= ctype_get(decl
->cp
->cts
, id
);
809 CTInfo info
= ct
->info
;
810 CTSize size
= ct
->size
;
811 switch (ctype_type(info
)) {
812 case CT_STRUCT
: case CT_ENUM
:
813 cp_push(decl
, CTINFO(CT_TYPEDEF
, id
), 0); /* Don't copy unique types. */
814 if ((decl
->attr
& CTF_QUAL
)) { /* Push unmerged qualifiers. */
815 cp_push(decl
, CTINFO(CT_ATTRIB
, CTATTRIB(CTA_QUAL
)),
816 (decl
->attr
& CTF_QUAL
));
817 decl
->attr
&= ~CTF_QUAL
;
821 if (ctype_isxattrib(info
, CTA_QUAL
))
822 decl
->attr
&= ~size
; /* Remove redundant qualifiers. */
823 cp_push_type(decl
, ctype_cid(info
)); /* Unroll. */
824 cp_push(decl
, info
& ~CTMASK_CID
, size
); /* Copy type. */
827 if ((ct
->info
& (CTF_VECTOR
|CTF_COMPLEX
))) {
828 info
|= (decl
->attr
& CTF_QUAL
);
829 decl
->attr
&= ~CTF_QUAL
;
831 cp_push_type(decl
, ctype_cid(info
)); /* Unroll. */
832 cp_push(decl
, info
& ~CTMASK_CID
, size
); /* Copy type. */
833 decl
->stack
[decl
->pos
].sib
= 1; /* Mark as already checked and sized. */
834 /* Note: this is not copied to the ct->sib in the C type table. */
837 /* Copy type, link parameters (shared). */
838 decl
->stack
[cp_push(decl
, info
, size
)].sib
= ct
->sib
;
841 /* Copy type, merge common qualifiers. */
842 cp_push(decl
, info
|(decl
->attr
& CTF_QUAL
), size
);
843 decl
->attr
&= ~CTF_QUAL
;
848 /* Consume the declaration element chain and intern the C type. */
849 static CTypeID
cp_decl_intern(CPState
*cp
, CPDecl
*decl
)
853 CTSize csize
= CTSIZE_INVALID
;
856 CType
*ct
= &decl
->stack
[idx
];
857 CTInfo info
= ct
->info
;
858 CTInfo size
= ct
->size
;
859 /* The cid is already part of info for copies of pointers/functions. */
861 if (ctype_istypedef(info
)) {
862 lj_assertCP(id
== 0, "typedef not at toplevel");
863 id
= ctype_cid(info
);
864 /* Always refetch info/size, since struct/enum may have been completed. */
865 cinfo
= ctype_get(cp
->cts
, id
)->info
;
866 csize
= ctype_get(cp
->cts
, id
)->size
;
867 lj_assertCP(ctype_isstruct(cinfo
) || ctype_isenum(cinfo
),
868 "typedef of bad type");
869 } else if (ctype_isfunc(info
)) { /* Intern function. */
874 CType
*refct
= ctype_raw(cp
->cts
, id
);
875 /* Reject function or refarray return types. */
876 if (ctype_isfunc(refct
->info
) || ctype_isrefarray(refct
->info
))
877 cp_err(cp
, LJ_ERR_FFI_INVTYPE
);
879 /* No intervening attributes allowed, skip forward. */
881 CType
*ctn
= &decl
->stack
[idx
];
882 if (!ctype_isattrib(ctn
->info
)) break;
883 idx
= ctn
->next
; /* Skip attribute. */
885 sib
= ct
->sib
; /* Next line may reallocate the C type table. */
886 fid
= lj_ctype_new(cp
->cts
, &fct
);
887 csize
= CTSIZE_INVALID
;
888 fct
->info
= cinfo
= info
+ id
;
892 } else if (ctype_isattrib(info
)) {
893 if (ctype_isxattrib(info
, CTA_QUAL
))
895 else if (ctype_isxattrib(info
, CTA_ALIGN
))
896 CTF_INSERT(cinfo
, ALIGN
, size
);
897 id
= lj_ctype_intern(cp
->cts
, info
+id
, size
);
898 /* Inherit csize/cinfo from original type. */
900 if (ctype_isnum(info
)) { /* Handle mode/vector-size attributes. */
901 lj_assertCP(id
== 0, "number not at toplevel");
902 if (!(info
& CTF_BOOL
)) {
903 CTSize msize
= ctype_msizeP(decl
->attr
);
904 CTSize vsize
= ctype_vsizeP(decl
->attr
);
905 if (msize
&& (!(info
& CTF_FP
) || (msize
== 4 || msize
== 8))) {
906 CTSize malign
= lj_fls(msize
);
907 if (malign
> 4) malign
= 4; /* Limit alignment. */
908 CTF_INSERT(info
, ALIGN
, malign
);
909 size
= msize
; /* Override size via mode. */
911 if (vsize
) { /* Vector size set? */
912 CTSize esize
= lj_fls(size
);
913 if (vsize
>= esize
) {
914 /* Intern the element type first. */
915 id
= lj_ctype_intern(cp
->cts
, info
, size
);
916 /* Then create a vector (array) with vsize alignment. */
917 size
= (1u << vsize
);
918 if (vsize
> 4) vsize
= 4; /* Limit alignment. */
919 if (ctype_align(info
) > vsize
) vsize
= ctype_align(info
);
920 info
= CTINFO(CT_ARRAY
, (info
& CTF_QUAL
) + CTF_VECTOR
+
925 } else if (ctype_isptr(info
)) {
926 /* Reject pointer/ref to ref. */
927 if (id
&& ctype_isref(ctype_raw(cp
->cts
, id
)->info
))
928 cp_err(cp
, LJ_ERR_FFI_INVTYPE
);
929 if (ctype_isref(info
)) {
930 info
&= ~CTF_VOLATILE
; /* Refs are always const, never volatile. */
931 /* No intervening attributes allowed, skip forward. */
933 CType
*ctn
= &decl
->stack
[idx
];
934 if (!ctype_isattrib(ctn
->info
)) break;
935 idx
= ctn
->next
; /* Skip attribute. */
938 } else if (ctype_isarray(info
)) { /* Check for valid array size etc. */
939 if (ct
->sib
== 0) { /* Only check/size arrays not copied by unroll. */
940 if (ctype_isref(cinfo
)) /* Reject arrays of refs. */
941 cp_err(cp
, LJ_ERR_FFI_INVTYPE
);
942 /* Reject VLS or unknown-sized types. */
943 if (ctype_isvltype(cinfo
) || csize
== CTSIZE_INVALID
)
944 cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
945 /* a[] and a[?] keep their invalid size. */
946 if (size
!= CTSIZE_INVALID
) {
947 uint64_t xsz
= (uint64_t)size
* csize
;
948 if (xsz
>= 0x80000000u
) cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
952 if ((cinfo
& CTF_ALIGN
) > (info
& CTF_ALIGN
)) /* Find max. align. */
953 info
= (info
& ~CTF_ALIGN
) | (cinfo
& CTF_ALIGN
);
954 info
|= (cinfo
& CTF_QUAL
); /* Inherit qual. */
956 lj_assertCP(ctype_isvoid(info
), "bad ctype %08x", info
);
960 id
= lj_ctype_intern(cp
->cts
, info
+id
, size
);
966 /* -- C declaration parser ------------------------------------------------ */
968 /* Reset declaration state to declaration specifier. */
969 static void cp_decl_reset(CPDecl
*decl
)
971 decl
->pos
= decl
->specpos
;
972 decl
->top
= decl
->specpos
+1;
973 decl
->stack
[decl
->specpos
].next
= 0;
974 decl
->attr
= decl
->specattr
;
975 decl
->fattr
= decl
->specfattr
;
980 /* Parse constant initializer. */
981 /* NYI: FP constants and strings as initializers. */
982 static CTypeID
cp_decl_constinit(CPState
*cp
, CType
**ctp
, CTypeID ctypeid
)
984 CType
*ctt
= ctype_get(cp
->cts
, ctypeid
);
989 while (ctype_isattrib(ctt
->info
)) { /* Skip attributes. */
990 ctypeid
= ctype_cid(ctt
->info
); /* Update ID, too. */
991 ctt
= ctype_get(cp
->cts
, ctypeid
);
995 if (!ctype_isinteger(info
) || !(info
& CTF_CONST
) || size
> 4)
996 cp_err(cp
, LJ_ERR_FFI_INVTYPE
);
998 cp_expr_sub(cp
, &k
, 0);
999 constid
= lj_ctype_new(cp
->cts
, ctp
);
1000 (*ctp
)->info
= CTINFO(CT_CONSTVAL
, CTF_CONST
|ctypeid
);
1001 k
.u32
<<= 8*(4-size
);
1002 if ((info
& CTF_UNSIGNED
))
1003 k
.u32
>>= 8*(4-size
);
1005 k
.u32
= (uint32_t)((int32_t)k
.u32
>> 8*(4-size
));
1006 (*ctp
)->size
= k
.u32
;
1010 /* Parse size in parentheses as part of attribute. */
1011 static CTSize
cp_decl_sizeattr(CPState
*cp
)
1014 uint32_t oldtmask
= cp
->tmask
;
1015 cp
->tmask
= CPNS_DEFAULT
; /* Required for expression evaluator. */
1017 sz
= cp_expr_ksize(cp
);
1018 cp
->tmask
= oldtmask
;
1023 /* Parse alignment attribute. */
1024 static void cp_decl_align(CPState
*cp
, CPDecl
*decl
)
1026 CTSize al
= 4; /* Unspecified alignment is 16 bytes. */
1027 if (cp
->tok
== '(') {
1028 al
= cp_decl_sizeattr(cp
);
1029 al
= al
? lj_fls(al
) : 0;
1031 CTF_INSERT(decl
->attr
, ALIGN
, al
);
1032 decl
->attr
|= CTFP_ALIGNED
;
1035 /* Parse GCC asm("name") redirect. */
1036 static void cp_decl_asm(CPState
*cp
, CPDecl
*decl
)
1041 if (cp
->tok
== CTOK_STRING
) {
1042 GCstr
*str
= cp
->str
;
1043 while (cp_next(cp
) == CTOK_STRING
) {
1044 lj_strfmt_pushf(cp
->L
, "%s%s", strdata(str
), strdata(cp
->str
));
1046 str
= strV(cp
->L
->top
);
1053 /* Parse GCC __attribute__((mode(...))). */
1054 static void cp_decl_mode(CPState
*cp
, CPDecl
*decl
)
1057 if (cp
->tok
== CTOK_IDENT
) {
1058 const char *s
= strdata(cp
->str
);
1059 CTSize sz
= 0, vlen
= 0;
1060 if (s
[0] == '_' && s
[1] == '_') s
+= 2;
1064 if (*s
>= '0' && *s
<= '9')
1065 vlen
= vlen
*10 + (*s
++ - '0');
1068 case 'Q': sz
= 1; break;
1069 case 'H': sz
= 2; break;
1070 case 'S': sz
= 4; break;
1071 case 'D': sz
= 8; break;
1072 case 'T': sz
= 16; break;
1073 case 'O': sz
= 32; break;
1074 default: goto bad_size
;
1076 if (*s
== 'I' || *s
== 'F') {
1077 CTF_INSERT(decl
->attr
, MSIZEP
, sz
);
1078 if (vlen
) CTF_INSERT(decl
->attr
, VSIZEP
, lj_fls(vlen
*sz
));
1086 /* Parse GCC __attribute__((...)). */
1087 static void cp_decl_gccattribute(CPState
*cp
, CPDecl
*decl
)
1092 while (cp
->tok
!= ')') {
1093 if (cp
->tok
== CTOK_IDENT
) {
1094 GCstr
*attrstr
= cp
->str
;
1096 switch (lj_cparse_case(attrstr
,
1097 "\007aligned" "\013__aligned__"
1098 "\006packed" "\012__packed__"
1099 "\004mode" "\010__mode__"
1100 "\013vector_size" "\017__vector_size__"
1102 "\007regparm" "\013__regparm__"
1103 "\005cdecl" "\011__cdecl__"
1104 "\010thiscall" "\014__thiscall__"
1105 "\010fastcall" "\014__fastcall__"
1106 "\007stdcall" "\013__stdcall__"
1107 "\012sseregparm" "\016__sseregparm__"
1110 case 0: case 1: /* aligned */
1111 cp_decl_align(cp
, decl
);
1113 case 2: case 3: /* packed */
1114 decl
->attr
|= CTFP_PACKED
;
1116 case 4: case 5: /* mode */
1117 cp_decl_mode(cp
, decl
);
1119 case 6: case 7: /* vector_size */
1121 CTSize vsize
= cp_decl_sizeattr(cp
);
1122 if (vsize
) CTF_INSERT(decl
->attr
, VSIZEP
, lj_fls(vsize
));
1126 case 8: case 9: /* regparm */
1127 CTF_INSERT(decl
->fattr
, REGPARM
, cp_decl_sizeattr(cp
));
1128 decl
->fattr
|= CTFP_CCONV
;
1130 case 10: case 11: /* cdecl */
1131 CTF_INSERT(decl
->fattr
, CCONV
, CTCC_CDECL
);
1132 decl
->fattr
|= CTFP_CCONV
;
1134 case 12: case 13: /* thiscall */
1135 CTF_INSERT(decl
->fattr
, CCONV
, CTCC_THISCALL
);
1136 decl
->fattr
|= CTFP_CCONV
;
1138 case 14: case 15: /* fastcall */
1139 CTF_INSERT(decl
->fattr
, CCONV
, CTCC_FASTCALL
);
1140 decl
->fattr
|= CTFP_CCONV
;
1142 case 16: case 17: /* stdcall */
1143 CTF_INSERT(decl
->fattr
, CCONV
, CTCC_STDCALL
);
1144 decl
->fattr
|= CTFP_CCONV
;
1146 case 18: case 19: /* sseregparm */
1147 decl
->fattr
|= CTF_SSEREGPARM
;
1148 decl
->fattr
|= CTFP_CCONV
;
1151 default: /* Skip all other attributes. */
1154 } else if (cp
->tok
>= CTOK_FIRSTDECL
) { /* For __attribute((const)) etc. */
1157 if (cp_opt(cp
, '(')) {
1158 while (cp
->tok
!= ')' && cp
->tok
!= CTOK_EOF
) cp_next(cp
);
1164 if (!cp_opt(cp
, ',')) break;
1170 /* Parse MSVC __declspec(...). */
1171 static void cp_decl_msvcattribute(CPState
*cp
, CPDecl
*decl
)
1175 while (cp
->tok
== CTOK_IDENT
) {
1176 GCstr
*attrstr
= cp
->str
;
1178 if (cp_str_is(attrstr
, "align")) {
1179 cp_decl_align(cp
, decl
);
1180 } else { /* Ignore all other attributes. */
1181 if (cp_opt(cp
, '(')) {
1182 while (cp
->tok
!= ')' && cp
->tok
!= CTOK_EOF
) cp_next(cp
);
1190 /* Parse declaration attributes (and common qualifiers). */
1191 static void cp_decl_attributes(CPState
*cp
, CPDecl
*decl
)
1195 case CTOK_CONST
: decl
->attr
|= CTF_CONST
; break;
1196 case CTOK_VOLATILE
: decl
->attr
|= CTF_VOLATILE
; break;
1197 case CTOK_RESTRICT
: break; /* Ignore. */
1198 case CTOK_EXTENSION
: break; /* Ignore. */
1199 case CTOK_ATTRIBUTE
: cp_decl_gccattribute(cp
, decl
); continue;
1200 case CTOK_ASM
: cp_decl_asm(cp
, decl
); continue;
1201 case CTOK_DECLSPEC
: cp_decl_msvcattribute(cp
, decl
); continue;
1204 CTF_INSERT(decl
->fattr
, CCONV
, cp
->ct
->size
);
1205 decl
->fattr
|= CTFP_CCONV
;
1210 CTF_INSERT(decl
->attr
, MSIZEP
, cp
->ct
->size
);
1219 /* Parse struct/union/enum name. */
1220 static CTypeID
cp_struct_name(CPState
*cp
, CPDecl
*sdecl
, CTInfo info
)
1224 cp
->tmask
= CPNS_STRUCT
;
1226 cp_decl_attributes(cp
, sdecl
);
1227 cp
->tmask
= CPNS_DEFAULT
;
1228 if (cp
->tok
!= '{') {
1229 if (cp
->tok
!= CTOK_IDENT
) cp_err_token(cp
, CTOK_IDENT
);
1230 if (cp
->val
.id
) { /* Name of existing struct/union/enum. */
1233 if ((ct
->info
^ info
) & (CTMASK_NUM
|CTF_UNION
)) /* Wrong type. */
1234 cp_errmsg(cp
, 0, LJ_ERR_FFI_REDEF
, strdata(gco2str(gcref(ct
->name
))));
1235 } else { /* Create named, incomplete struct/union/enum. */
1236 if ((cp
->mode
& CPARSE_MODE_NOIMPLICIT
))
1237 cp_errmsg(cp
, 0, LJ_ERR_FFI_BADTAG
, strdata(cp
->str
));
1238 sid
= lj_ctype_new(cp
->cts
, &ct
);
1240 ct
->size
= CTSIZE_INVALID
;
1241 ctype_setname(ct
, cp
->str
);
1242 lj_ctype_addname(cp
->cts
, ct
, sid
);
1245 } else { /* Create anonymous, incomplete struct/union/enum. */
1246 sid
= lj_ctype_new(cp
->cts
, &ct
);
1248 ct
->size
= CTSIZE_INVALID
;
1250 if (cp
->tok
== '{') {
1251 if (ct
->size
!= CTSIZE_INVALID
|| ct
->sib
)
1252 cp_errmsg(cp
, 0, LJ_ERR_FFI_REDEF
, strdata(gco2str(gcref(ct
->name
))));
1253 ct
->sib
= 1; /* Indicate the type is currently being defined. */
1258 /* Determine field alignment. */
1259 static CTSize
cp_field_align(CPState
*cp
, CType
*ct
, CTInfo info
)
1261 CTSize align
= ctype_align(info
);
1262 UNUSED(cp
); UNUSED(ct
);
1263 #if (LJ_TARGET_X86 && !LJ_ABI_WIN) || (LJ_TARGET_ARM && __APPLE__)
1264 /* The SYSV i386 and iOS ABIs limit alignment of non-vector fields to 2^2. */
1265 if (align
> 2 && !(info
& CTFP_ALIGNED
)) {
1266 if (ctype_isarray(info
) && !(info
& CTF_VECTOR
)) {
1268 ct
= ctype_rawchild(cp
->cts
, ct
);
1270 } while (ctype_isarray(info
) && !(info
& CTF_VECTOR
));
1272 if (ctype_isnum(info
) || ctype_isenum(info
))
1279 /* Layout struct/union fields. */
1280 static void cp_struct_layout(CPState
*cp
, CTypeID sid
, CTInfo sattr
)
1282 CTSize bofs
= 0, bmaxofs
= 0; /* Bit offset and max. bit offset. */
1283 CTSize maxalign
= ctype_align(sattr
);
1284 CType
*sct
= ctype_get(cp
->cts
, sid
);
1285 CTInfo sinfo
= sct
->info
;
1286 CTypeID fieldid
= sct
->sib
;
1288 CType
*ct
= ctype_get(cp
->cts
, fieldid
);
1289 CTInfo attr
= ct
->size
; /* Field declaration attributes (temp.). */
1291 if (ctype_isfield(ct
->info
) ||
1292 (ctype_isxattrib(ct
->info
, CTA_SUBTYPE
) && attr
)) {
1293 CTSize align
, amask
; /* Alignment (pow2) and alignment mask (bits). */
1295 CTInfo info
= lj_ctype_info(cp
->cts
, ctype_cid(ct
->info
), &sz
);
1296 CTSize bsz
, csz
= 8*sz
; /* Field size and container size (in bits). */
1297 sinfo
|= (info
& (CTF_QUAL
|CTF_VLA
)); /* Merge pseudo-qualifiers. */
1299 /* Check for size overflow and determine alignment. */
1300 if (sz
>= 0x20000000u
|| bofs
+ csz
< bofs
|| (info
& CTF_VLA
)) {
1301 if (!(sz
== CTSIZE_INVALID
&& ctype_isarray(info
) &&
1302 !(sinfo
& CTF_UNION
)))
1303 cp_err(cp
, LJ_ERR_FFI_INVSIZE
);
1304 csz
= sz
= 0; /* Treat a[] and a[?] as zero-sized. */
1306 align
= cp_field_align(cp
, ct
, info
);
1307 if (((attr
|sattr
) & CTFP_PACKED
) ||
1308 ((attr
& CTFP_ALIGNED
) && ctype_align(attr
) > align
))
1309 align
= ctype_align(attr
);
1310 if (cp
->packstack
[cp
->curpack
] < align
)
1311 align
= cp
->packstack
[cp
->curpack
];
1312 if (align
> maxalign
) maxalign
= align
;
1313 amask
= (8u << align
) - 1;
1315 bsz
= ctype_bitcsz(ct
->info
); /* Bitfield size (temp.). */
1316 if (bsz
== CTBSZ_FIELD
|| !ctype_isfield(ct
->info
)) {
1317 bsz
= csz
; /* Regular fields or subtypes always fill the container. */
1318 bofs
= (bofs
+ amask
) & ~amask
; /* Start new aligned field. */
1319 ct
->size
= (bofs
>> 3); /* Store field offset. */
1320 } else { /* Bitfield. */
1321 if (bsz
== 0 || (attr
& CTFP_ALIGNED
) ||
1322 (!((attr
|sattr
) & CTFP_PACKED
) && (bofs
& amask
) + bsz
> csz
))
1323 bofs
= (bofs
+ amask
) & ~amask
; /* Start new aligned field. */
1325 /* Prefer regular field over bitfield. */
1326 if (bsz
== csz
&& (bofs
& amask
) == 0) {
1327 ct
->info
= CTINFO(CT_FIELD
, ctype_cid(ct
->info
));
1328 ct
->size
= (bofs
>> 3); /* Store field offset. */
1330 ct
->info
= CTINFO(CT_BITFIELD
,
1331 (info
& (CTF_QUAL
|CTF_UNSIGNED
|CTF_BOOL
)) +
1332 (csz
<< (CTSHIFT_BITCSZ
-3)) + (bsz
<< CTSHIFT_BITBSZ
));
1334 ct
->info
+= ((csz
- (bofs
& (csz
-1)) - bsz
) << CTSHIFT_BITPOS
);
1336 ct
->info
+= ((bofs
& (csz
-1)) << CTSHIFT_BITPOS
);
1338 ct
->size
= ((bofs
& ~(csz
-1)) >> 3); /* Store container offset. */
1342 /* Determine next offset or max. offset. */
1343 if ((sinfo
& CTF_UNION
)) {
1344 if (bsz
> bmaxofs
) bmaxofs
= bsz
;
1348 } /* All other fields in the chain are already set up. */
1353 /* Complete struct/union. */
1354 sct
->info
= sinfo
+ CTALIGN(maxalign
);
1355 bofs
= (sinfo
& CTF_UNION
) ? bmaxofs
: bofs
;
1356 maxalign
= (8u << maxalign
) - 1;
1357 sct
->size
= (((bofs
+ maxalign
) & ~maxalign
) >> 3);
1360 /* Parse struct/union declaration. */
1361 static CTypeID
cp_decl_struct(CPState
*cp
, CPDecl
*sdecl
, CTInfo sinfo
)
1363 CTypeID sid
= cp_struct_name(cp
, sdecl
, sinfo
);
1364 if (cp_opt(cp
, '{')) { /* Struct/union definition. */
1365 CTypeID lastid
= sid
;
1367 while (cp
->tok
!= '}') {
1369 CPscl scl
= cp_decl_spec(cp
, &decl
, CDF_STATIC
);
1370 decl
.mode
= scl
? CPARSE_MODE_DIRECT
:
1371 CPARSE_MODE_DIRECT
|CPARSE_MODE_ABSTRACT
|CPARSE_MODE_FIELD
;
1376 if (lastdecl
) cp_err_token(cp
, '}');
1378 /* Parse field declarator. */
1379 decl
.bits
= CTSIZE_INVALID
;
1380 cp_declarator(cp
, &decl
);
1381 ctypeid
= cp_decl_intern(cp
, &decl
);
1383 if ((scl
& CDF_STATIC
)) { /* Static constant in struct namespace. */
1385 CTypeID fieldid
= cp_decl_constinit(cp
, &ct
, ctypeid
);
1386 ctype_get(cp
->cts
, lastid
)->sib
= fieldid
;
1388 ctype_setname(ct
, decl
.name
);
1390 CTSize bsz
= CTBSZ_FIELD
; /* Temp. for layout phase. */
1392 CTypeID fieldid
= lj_ctype_new(cp
->cts
, &ct
); /* Do this first. */
1393 CType
*tct
= ctype_raw(cp
->cts
, ctypeid
);
1395 if (decl
.bits
== CTSIZE_INVALID
) { /* Regular field. */
1396 if (ctype_isarray(tct
->info
) && tct
->size
== CTSIZE_INVALID
)
1397 lastdecl
= 1; /* a[] or a[?] must be the last declared field. */
1399 /* Accept transparent struct/union/enum. */
1401 if (!((ctype_isstruct(tct
->info
) && !(tct
->info
& CTF_VLA
)) ||
1402 ctype_isenum(tct
->info
)))
1403 cp_err_token(cp
, CTOK_IDENT
);
1404 ct
->info
= CTINFO(CT_ATTRIB
, CTATTRIB(CTA_SUBTYPE
) + ctypeid
);
1405 ct
->size
= ctype_isstruct(tct
->info
) ?
1406 (decl
.attr
|0x80000000u
) : 0; /* For layout phase. */
1409 } else { /* Bitfield. */
1411 if (!ctype_isinteger_or_bool(tct
->info
) ||
1412 (bsz
== 0 && decl
.name
) || 8*tct
->size
> CTBSZ_MAX
||
1413 bsz
> ((tct
->info
& CTF_BOOL
) ? 1 : 8*tct
->size
))
1414 cp_errmsg(cp
, ':', LJ_ERR_BADVAL
);
1417 /* Create temporary field for layout phase. */
1418 ct
->info
= CTINFO(CT_FIELD
, ctypeid
+ (bsz
<< CTSHIFT_BITCSZ
));
1419 ct
->size
= decl
.attr
;
1420 if (decl
.name
) ctype_setname(ct
, decl
.name
);
1423 ctype_get(cp
->cts
, lastid
)->sib
= fieldid
;
1426 if (!cp_opt(cp
, ',')) break;
1427 cp_decl_reset(&decl
);
1432 ctype_get(cp
->cts
, lastid
)->sib
= 0; /* Drop sib = 1 for empty structs. */
1433 cp_decl_attributes(cp
, sdecl
); /* Layout phase needs postfix attributes. */
1434 cp_struct_layout(cp
, sid
, sdecl
->attr
);
1439 /* Parse enum declaration. */
1440 static CTypeID
cp_decl_enum(CPState
*cp
, CPDecl
*sdecl
)
1442 CTypeID eid
= cp_struct_name(cp
, sdecl
, CTINFO(CT_ENUM
, CTID_VOID
));
1443 CTInfo einfo
= CTINFO(CT_ENUM
, CTALIGN(2) + CTID_UINT32
);
1444 CTSize esize
= 4; /* Only 32 bit enums are supported. */
1445 if (cp_opt(cp
, '{')) { /* Enum definition. */
1447 CTypeID lastid
= eid
;
1451 GCstr
*name
= cp
->str
;
1452 if (cp
->tok
!= CTOK_IDENT
) cp_err_token(cp
, CTOK_IDENT
);
1453 if (cp
->val
.id
) cp_errmsg(cp
, 0, LJ_ERR_FFI_REDEF
, strdata(name
));
1455 if (cp_opt(cp
, '=')) {
1456 cp_expr_kint(cp
, &k
);
1457 if (k
.id
== CTID_UINT32
) {
1458 /* C99 says that enum constants are always (signed) integers.
1459 ** But since unsigned constants like 0x80000000 are quite common,
1460 ** those are left as uint32_t.
1462 if (k
.i32
>= 0) k
.id
= CTID_INT32
;
1464 /* OTOH it's common practice and even mandated by some ABIs
1465 ** that the enum type itself is unsigned, unless there are any
1466 ** negative constants.
1469 if (k
.i32
< 0) einfo
= CTINFO(CT_ENUM
, CTALIGN(2) + CTID_INT32
);
1472 /* Add named enum constant. */
1475 CTypeID constid
= lj_ctype_new(cp
->cts
, &ct
);
1476 ctype_get(cp
->cts
, lastid
)->sib
= constid
;
1478 ctype_setname(ct
, name
);
1479 ct
->info
= CTINFO(CT_CONSTVAL
, CTF_CONST
|k
.id
);
1481 if (k
.u32
== 0x80000000u
) k
.id
= CTID_UINT32
;
1482 lj_ctype_addname(cp
->cts
, ct
, constid
);
1484 if (!cp_opt(cp
, ',')) break;
1485 } while (cp
->tok
!= '}'); /* Trailing ',' is ok. */
1487 /* Complete enum. */
1488 ctype_get(cp
->cts
, eid
)->info
= einfo
;
1489 ctype_get(cp
->cts
, eid
)->size
= esize
;
1494 /* Parse declaration specifiers. */
1495 static CPscl
cp_decl_spec(CPState
*cp
, CPDecl
*decl
, CPscl scl
)
1497 uint32_t cds
= 0, sz
= 0;
1501 decl
->mode
= cp
->mode
;
1506 decl
->pos
= decl
->top
= 0;
1507 decl
->stack
[0].next
= 0;
1509 for (;;) { /* Parse basic types. */
1510 cp_decl_attributes(cp
, decl
);
1511 if (cp
->tok
>= CTOK_FIRSTDECL
&& cp
->tok
<= CTOK_LASTDECLFLAG
) {
1514 if (sz
) goto end_decl
;
1517 cbit
= (1u << (cp
->tok
- CTOK_FIRSTDECL
));
1518 cds
= cds
| cbit
| ((cbit
& cds
& CDF_LONG
) << 1);
1519 if (cp
->tok
>= CTOK_FIRSTSCL
) {
1520 if (!(scl
& cbit
)) cp_errmsg(cp
, cp
->tok
, LJ_ERR_FFI_BADSCL
);
1528 (cds
& (CDF_SHORT
|CDF_LONG
|CDF_SIGNED
|CDF_UNSIGNED
|CDF_COMPLEX
)))
1532 tdef
= cp_decl_struct(cp
, decl
, CTINFO(CT_STRUCT
, 0));
1535 tdef
= cp_decl_struct(cp
, decl
, CTINFO(CT_STRUCT
, CTF_UNION
));
1538 tdef
= cp_decl_enum(cp
, decl
);
1541 if (ctype_istypedef(cp
->ct
->info
)) {
1542 tdef
= ctype_cid(cp
->ct
->info
); /* Get typedef. */
1558 if ((cds
& CDF_COMPLEX
)) /* Use predefined complex types. */
1559 tdef
= sz
== 4 ? CTID_COMPLEX_FLOAT
: CTID_COMPLEX_DOUBLE
;
1562 cp_push_type(decl
, tdef
);
1563 } else if ((cds
& CDF_VOID
)) {
1564 cp_push(decl
, CTINFO(CT_VOID
, (decl
->attr
& CTF_QUAL
)), CTSIZE_INVALID
);
1565 decl
->attr
&= ~CTF_QUAL
;
1567 /* Determine type info and size. */
1568 CTInfo info
= CTINFO(CT_NUM
, (cds
& CDF_UNSIGNED
) ? CTF_UNSIGNED
: 0);
1569 if ((cds
& CDF_BOOL
)) {
1570 if ((cds
& ~(CDF_SCL
|CDF_BOOL
|CDF_INT
|CDF_SIGNED
|CDF_UNSIGNED
)))
1571 cp_errmsg(cp
, 0, LJ_ERR_FFI_INVTYPE
);
1573 if (!(cds
& CDF_SIGNED
)) info
|= CTF_UNSIGNED
;
1577 } else if ((cds
& CDF_FP
)) {
1578 info
= CTINFO(CT_NUM
, CTF_FP
);
1579 if ((cds
& CDF_LONG
)) sz
= sizeof(long double);
1580 } else if ((cds
& CDF_CHAR
)) {
1581 if ((cds
& (CDF_CHAR
|CDF_SIGNED
|CDF_UNSIGNED
)) == CDF_CHAR
)
1582 info
|= CTF_UCHAR
; /* Handle platforms where char is unsigned. */
1583 } else if ((cds
& CDF_SHORT
)) {
1585 } else if ((cds
& CDF_LONGLONG
)) {
1587 } else if ((cds
& CDF_LONG
)) {
1591 if (!(cds
& (CDF_SIGNED
|CDF_UNSIGNED
)))
1592 cp_errmsg(cp
, cp
->tok
, LJ_ERR_FFI_DECLSPEC
);
1595 lj_assertCP(sz
!= 0, "basic ctype with zero size");
1596 info
+= CTALIGN(lj_fls(sz
)); /* Use natural alignment. */
1597 info
+= (decl
->attr
& CTF_QUAL
); /* Merge qualifiers. */
1598 cp_push(decl
, info
, sz
);
1599 decl
->attr
&= ~CTF_QUAL
;
1601 decl
->specpos
= decl
->pos
;
1602 decl
->specattr
= decl
->attr
;
1603 decl
->specfattr
= decl
->fattr
;
1604 return (cds
& CDF_SCL
); /* Return storage class. */
1607 /* Parse array declaration. */
1608 static void cp_decl_array(CPState
*cp
, CPDecl
*decl
)
1610 CTInfo info
= CTINFO(CT_ARRAY
, 0);
1611 CTSize nelem
= CTSIZE_INVALID
; /* Default size for a[] or a[?]. */
1612 cp_decl_attributes(cp
, decl
);
1613 if (cp_opt(cp
, '?'))
1614 info
|= CTF_VLA
; /* Create variable-length array a[?]. */
1615 else if (cp
->tok
!= ']')
1616 nelem
= cp_expr_ksize(cp
);
1618 cp_add(decl
, info
, nelem
);
1621 /* Parse function declaration. */
1622 static void cp_decl_func(CPState
*cp
, CPDecl
*fdecl
)
1625 CTInfo info
= CTINFO(CT_FUNC
, 0);
1626 CTypeID lastid
= 0, anchor
= 0;
1627 if (cp
->tok
!= ')') {
1630 CTypeID ctypeid
, fieldid
;
1632 if (cp_opt(cp
, '.')) { /* Vararg function. */
1633 cp_check(cp
, '.'); /* Workaround for the minimalistic lexer. */
1638 cp_decl_spec(cp
, &decl
, CDF_REGISTER
);
1639 decl
.mode
= CPARSE_MODE_DIRECT
|CPARSE_MODE_ABSTRACT
;
1640 cp_declarator(cp
, &decl
);
1641 ctypeid
= cp_decl_intern(cp
, &decl
);
1642 ct
= ctype_raw(cp
->cts
, ctypeid
);
1643 if (ctype_isvoid(ct
->info
))
1645 else if (ctype_isrefarray(ct
->info
))
1646 ctypeid
= lj_ctype_intern(cp
->cts
,
1647 CTINFO(CT_PTR
, CTALIGN_PTR
|ctype_cid(ct
->info
)), CTSIZE_PTR
);
1648 else if (ctype_isfunc(ct
->info
))
1649 ctypeid
= lj_ctype_intern(cp
->cts
,
1650 CTINFO(CT_PTR
, CTALIGN_PTR
|ctypeid
), CTSIZE_PTR
);
1651 /* Add new parameter. */
1652 fieldid
= lj_ctype_new(cp
->cts
, &ct
);
1654 ctype_get(cp
->cts
, lastid
)->sib
= fieldid
;
1658 if (decl
.name
) ctype_setname(ct
, decl
.name
);
1659 ct
->info
= CTINFO(CT_FIELD
, ctypeid
);
1661 } while (cp_opt(cp
, ','));
1664 if (cp_opt(cp
, '{')) { /* Skip function definition. */
1666 cp
->mode
|= CPARSE_MODE_SKIP
;
1668 if (cp
->tok
== '{') level
++;
1669 else if (cp
->tok
== '}' && --level
== 0) break;
1670 else if (cp
->tok
== CTOK_EOF
) cp_err_token(cp
, '}');
1673 cp
->mode
&= ~CPARSE_MODE_SKIP
;
1674 cp
->tok
= ';'; /* Ok for cp_decl_multi(), error in cp_decl_single(). */
1676 info
|= (fdecl
->fattr
& ~CTMASK_CID
);
1678 fdecl
->stack
[cp_add(fdecl
, info
, nargs
)].sib
= anchor
;
1681 /* Parse declarator. */
1682 static void cp_declarator(CPState
*cp
, CPDecl
*decl
)
1684 if (++cp
->depth
> CPARSE_MAX_DECLDEPTH
) cp_err(cp
, LJ_ERR_XLEVELS
);
1686 for (;;) { /* Head of declarator. */
1687 if (cp_opt(cp
, '*')) { /* Pointer. */
1690 cp_decl_attributes(cp
, decl
);
1692 info
= CTINFO(CT_PTR
, CTALIGN_PTR
);
1694 if (ctype_msizeP(decl
->attr
) == 4) {
1696 info
= CTINFO(CT_PTR
, CTALIGN(2));
1699 info
+= (decl
->attr
& (CTF_QUAL
|CTF_REF
));
1700 decl
->attr
&= ~(CTF_QUAL
|(CTMASK_MSIZEP
<<CTSHIFT_MSIZEP
));
1701 cp_push(decl
, info
, sz
);
1702 } else if (cp_opt(cp
, '&') || cp_opt(cp
, CTOK_ANDAND
)) { /* Reference. */
1703 decl
->attr
&= ~(CTF_QUAL
|(CTMASK_MSIZEP
<<CTSHIFT_MSIZEP
));
1704 cp_push(decl
, CTINFO_REF(0), CTSIZE_PTR
);
1710 if (cp_opt(cp
, '(')) { /* Inner declarator. */
1712 cp_decl_attributes(cp
, decl
);
1713 /* Resolve ambiguity between inner declarator and 1st function parameter. */
1714 if ((decl
->mode
& CPARSE_MODE_ABSTRACT
) &&
1715 (cp
->tok
== ')' || cp_istypedecl(cp
))) goto func_decl
;
1717 cp_declarator(cp
, decl
);
1720 } else if (cp
->tok
== CTOK_IDENT
) { /* Direct declarator. */
1721 if (!(decl
->mode
& CPARSE_MODE_DIRECT
)) cp_err_token(cp
, CTOK_EOF
);
1722 decl
->name
= cp
->str
;
1723 decl
->nameid
= cp
->val
.id
;
1725 } else { /* Abstract declarator. */
1726 if (!(decl
->mode
& CPARSE_MODE_ABSTRACT
)) cp_err_token(cp
, CTOK_IDENT
);
1729 for (;;) { /* Tail of declarator. */
1730 if (cp_opt(cp
, '[')) { /* Array. */
1731 cp_decl_array(cp
, decl
);
1732 } else if (cp_opt(cp
, '(')) { /* Function. */
1734 cp_decl_func(cp
, decl
);
1740 if ((decl
->mode
& CPARSE_MODE_FIELD
) && cp_opt(cp
, ':')) /* Field width. */
1741 decl
->bits
= cp_expr_ksize(cp
);
1743 /* Process postfix attributes. */
1744 cp_decl_attributes(cp
, decl
);
1745 cp_push_attributes(decl
);
1750 /* Parse an abstract type declaration and return it's C type ID. */
1751 static CTypeID
cp_decl_abstract(CPState
*cp
)
1754 cp_decl_spec(cp
, &decl
, 0);
1755 decl
.mode
= CPARSE_MODE_ABSTRACT
;
1756 cp_declarator(cp
, &decl
);
1757 return cp_decl_intern(cp
, &decl
);
1760 /* Handle pragmas. */
1761 static void cp_pragma(CPState
*cp
, BCLine pragmaline
)
1764 if (cp
->tok
== CTOK_IDENT
&& cp_str_is(cp
->str
, "pack")) {
1767 if (cp
->tok
== CTOK_IDENT
) {
1768 if (cp_str_is(cp
->str
, "push")) {
1769 if (cp
->curpack
< CPARSE_MAX_PACKSTACK
-1) {
1770 cp
->packstack
[cp
->curpack
+1] = cp
->packstack
[cp
->curpack
];
1773 cp_errmsg(cp
, cp
->tok
, LJ_ERR_XLEVELS
);
1775 } else if (cp_str_is(cp
->str
, "pop")) {
1776 if (cp
->curpack
> 0) cp
->curpack
--;
1778 cp_errmsg(cp
, cp
->tok
, LJ_ERR_XSYMBOL
);
1781 if (!cp_opt(cp
, ',')) goto end_pack
;
1783 if (cp
->tok
== CTOK_INTEGER
) {
1784 cp
->packstack
[cp
->curpack
] = cp
->val
.u32
? lj_fls(cp
->val
.u32
) : 0;
1787 cp
->packstack
[cp
->curpack
] = 255;
1791 } else { /* Ignore all other pragmas. */
1792 while (cp
->tok
!= CTOK_EOF
&& cp
->linenumber
== pragmaline
)
1797 /* Handle line number. */
1798 static void cp_line(CPState
*cp
, BCLine hashline
)
1800 BCLine newline
= cp
->val
.u32
;
1801 /* TODO: Handle file name and include it in error messages. */
1802 while (cp
->tok
!= CTOK_EOF
&& cp
->linenumber
== hashline
)
1804 cp
->linenumber
= newline
;
1807 /* Parse multiple C declarations of types or extern identifiers. */
1808 static void cp_decl_multi(CPState
*cp
)
1811 while (cp
->tok
!= CTOK_EOF
) {
1814 if (cp_opt(cp
, ';')) { /* Skip empty statements. */
1818 if (cp
->tok
== '#') { /* Workaround, since we have no preprocessor, yet. */
1819 BCLine hashline
= cp
->linenumber
;
1820 CPToken tok
= cp_next(cp
);
1821 if (tok
== CTOK_INTEGER
) {
1822 cp_line(cp
, hashline
);
1824 } else if (tok
== CTOK_IDENT
&& cp_str_is(cp
->str
, "line")) {
1825 if (cp_next(cp
) != CTOK_INTEGER
) cp_err_token(cp
, tok
);
1826 cp_line(cp
, hashline
);
1828 } else if (tok
== CTOK_IDENT
&& cp_str_is(cp
->str
, "pragma")) {
1829 cp_pragma(cp
, hashline
);
1832 cp_errmsg(cp
, cp
->tok
, LJ_ERR_XSYMBOL
);
1835 scl
= cp_decl_spec(cp
, &decl
, CDF_TYPEDEF
|CDF_EXTERN
|CDF_STATIC
);
1836 if ((cp
->tok
== ';' || cp
->tok
== CTOK_EOF
) &&
1837 ctype_istypedef(decl
.stack
[0].info
)) {
1838 CTInfo info
= ctype_rawchild(cp
->cts
, &decl
.stack
[0])->info
;
1839 if (ctype_isstruct(info
) || ctype_isenum(info
))
1840 goto decl_end
; /* Accept empty declaration of struct/union/enum. */
1844 cp_declarator(cp
, &decl
);
1845 ctypeid
= cp_decl_intern(cp
, &decl
);
1846 if (decl
.name
&& !decl
.nameid
) { /* NYI: redeclarations are ignored. */
1849 if ((scl
& CDF_TYPEDEF
)) { /* Create new typedef. */
1850 id
= lj_ctype_new(cp
->cts
, &ct
);
1851 ct
->info
= CTINFO(CT_TYPEDEF
, ctypeid
);
1853 } else if (ctype_isfunc(ctype_get(cp
->cts
, ctypeid
)->info
)) {
1854 /* Treat both static and extern function declarations as extern. */
1855 ct
= ctype_get(cp
->cts
, ctypeid
);
1856 /* We always get new anonymous functions (typedefs are copied). */
1857 lj_assertCP(gcref(ct
->name
) == NULL
, "unexpected named function");
1858 id
= ctypeid
; /* Just name it. */
1859 } else if ((scl
& CDF_STATIC
)) { /* Accept static constants. */
1860 id
= cp_decl_constinit(cp
, &ct
, ctypeid
);
1862 } else { /* External references have extern or no storage class. */
1863 id
= lj_ctype_new(cp
->cts
, &ct
);
1864 ct
->info
= CTINFO(CT_EXTERN
, ctypeid
);
1866 if (decl
.redir
) { /* Add attribute for redirected symbol name. */
1868 CTypeID aid
= lj_ctype_new(cp
->cts
, &cta
);
1869 ct
= ctype_get(cp
->cts
, id
); /* Table may have been reallocated. */
1870 cta
->info
= CTINFO(CT_ATTRIB
, CTATTRIB(CTA_REDIR
));
1873 ctype_setname(cta
, decl
.redir
);
1876 ctype_setname(ct
, decl
.name
);
1877 lj_ctype_addname(cp
->cts
, ct
, id
);
1879 if (!cp_opt(cp
, ',')) break;
1880 cp_decl_reset(&decl
);
1883 if (cp
->tok
== CTOK_EOF
&& first
) break; /* May omit ';' for 1 decl. */
1889 /* Parse a single C type declaration. */
1890 static void cp_decl_single(CPState
*cp
)
1893 cp_decl_spec(cp
, &decl
, 0);
1894 cp_declarator(cp
, &decl
);
1895 cp
->val
.id
= cp_decl_intern(cp
, &decl
);
1896 if (cp
->tok
!= CTOK_EOF
) cp_err_token(cp
, CTOK_EOF
);
1899 /* ------------------------------------------------------------------------ */
1901 /* Protected callback for C parser. */
1902 static TValue
*cpcparser(lua_State
*L
, lua_CFunction dummy
, void *ud
)
1904 CPState
*cp
= (CPState
*)ud
;
1906 cframe_errfunc(L
->cframe
) = -1; /* Inherit error function. */
1908 if ((cp
->mode
& CPARSE_MODE_MULTI
))
1912 if (cp
->param
&& cp
->param
!= cp
->L
->top
)
1913 cp_err(cp
, LJ_ERR_FFI_NUMPARAM
);
1914 lj_assertCP(cp
->depth
== 0, "unbalanced cparser declaration depth");
1919 int lj_cparse(CPState
*cp
)
1921 LJ_CTYPE_SAVE(cp
->cts
);
1922 int errcode
= lj_vm_cpcall(cp
->L
, NULL
, cp
, cpcparser
);
1924 LJ_CTYPE_RESTORE(cp
->cts
);