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