tccgen.c: Recognise constant expressions with conditional operator.
[tinycc.git] / tccgen.c
blob5e52f29c95f3918b6ae1d44d806b74a88c4809da
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /********************************************************/
24 /* global variables */
26 /* loc : local variable index
27 ind : output code index
28 rsym: return symbol
29 anon_sym: anonymous symbol index
31 ST_DATA int rsym, anon_sym, ind, loc;
33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
34 ST_DATA Section *cur_text_section; /* current section where function code is generated */
35 #ifdef CONFIG_TCC_ASM
36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
37 #endif
38 #ifdef CONFIG_TCC_BCHECK
39 /* bound check related sections */
40 ST_DATA Section *bounds_section; /* contains global data bound description */
41 ST_DATA Section *lbounds_section; /* contains local data bound description */
42 #endif
43 /* symbol sections */
44 ST_DATA Section *symtab_section, *strtab_section;
45 /* debug sections */
46 ST_DATA Section *stab_section, *stabstr_section;
47 ST_DATA Sym *sym_free_first;
48 ST_DATA void **sym_pools;
49 ST_DATA int nb_sym_pools;
51 ST_DATA Sym *global_stack;
52 ST_DATA Sym *local_stack;
53 ST_DATA Sym *scope_stack_bottom;
54 ST_DATA Sym *define_stack;
55 ST_DATA Sym *global_label_stack;
56 ST_DATA Sym *local_label_stack;
58 ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
59 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
60 ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
62 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
64 ST_DATA int const_wanted; /* true if constant wanted */
65 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
66 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
67 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
68 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
69 ST_DATA int func_vc;
70 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
71 ST_DATA const char *funcname;
73 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
75 /* ------------------------------------------------------------------------- */
76 static void gen_cast(CType *type);
77 static inline CType *pointed_type(CType *type);
78 static int is_compatible_types(CType *type1, CType *type2);
79 static int parse_btype(CType *type, AttributeDef *ad);
80 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
81 static void parse_expr_type(CType *type);
82 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
83 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
84 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
85 static int decl0(int l, int is_for_loop_init);
86 static void expr_eq(void);
87 static void unary_type(CType *type);
88 static void vla_runtime_type_size(CType *type, int *a);
89 static void vla_sp_restore(void);
90 static void vla_sp_restore_root(void);
91 static int is_compatible_parameter_types(CType *type1, CType *type2);
92 static void expr_type(CType *type);
93 ST_FUNC void vpush64(int ty, unsigned long long v);
94 ST_FUNC void vpush(CType *type);
95 ST_FUNC int gvtst(int inv, int t);
96 ST_FUNC int is_btype_size(int bt);
98 ST_INLN int is_float(int t)
100 int bt;
101 bt = t & VT_BTYPE;
102 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
105 /* we use our own 'finite' function to avoid potential problems with
106 non standard math libs */
107 /* XXX: endianness dependent */
108 ST_FUNC int ieee_finite(double d)
110 int p[4];
111 memcpy(p, &d, sizeof(double));
112 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
115 ST_FUNC void test_lvalue(void)
117 if (!(vtop->r & VT_LVAL))
118 expect("lvalue");
121 ST_FUNC void check_vstack(void)
123 if (pvtop != vtop)
124 tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
127 /* ------------------------------------------------------------------------- */
128 /* symbol allocator */
129 static Sym *__sym_malloc(void)
131 Sym *sym_pool, *sym, *last_sym;
132 int i;
134 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
135 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
137 last_sym = sym_free_first;
138 sym = sym_pool;
139 for(i = 0; i < SYM_POOL_NB; i++) {
140 sym->next = last_sym;
141 last_sym = sym;
142 sym++;
144 sym_free_first = last_sym;
145 return last_sym;
148 static inline Sym *sym_malloc(void)
150 Sym *sym;
151 sym = sym_free_first;
152 if (!sym)
153 sym = __sym_malloc();
154 sym_free_first = sym->next;
155 return sym;
158 ST_INLN void sym_free(Sym *sym)
160 sym->next = sym_free_first;
161 tcc_free(sym->asm_label);
162 sym_free_first = sym;
165 /* push, without hashing */
166 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
168 Sym *s;
169 if (ps == &local_stack) {
170 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
171 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
172 tcc_error("incompatible types for redefinition of '%s'",
173 get_tok_str(v, NULL));
175 s = sym_malloc();
176 s->asm_label = NULL;
177 s->v = v;
178 s->type.t = t;
179 s->type.ref = NULL;
180 #ifdef _WIN64
181 s->d = NULL;
182 #endif
183 s->c = c;
184 s->next = NULL;
185 /* add in stack */
186 s->prev = *ps;
187 *ps = s;
188 return s;
191 /* find a symbol and return its associated structure. 's' is the top
192 of the symbol stack */
193 ST_FUNC Sym *sym_find2(Sym *s, int v)
195 while (s) {
196 if (s->v == v)
197 return s;
198 else if (s->v == -1)
199 return NULL;
200 s = s->prev;
202 return NULL;
205 /* structure lookup */
206 ST_INLN Sym *struct_find(int v)
208 v -= TOK_IDENT;
209 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
210 return NULL;
211 return table_ident[v]->sym_struct;
214 /* find an identifier */
215 ST_INLN Sym *sym_find(int v)
217 v -= TOK_IDENT;
218 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
219 return NULL;
220 return table_ident[v]->sym_identifier;
223 /* push a given symbol on the symbol stack */
224 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
226 Sym *s, **ps;
227 TokenSym *ts;
229 if (local_stack)
230 ps = &local_stack;
231 else
232 ps = &global_stack;
233 s = sym_push2(ps, v, type->t, c);
234 s->type.ref = type->ref;
235 s->r = r;
236 /* don't record fields or anonymous symbols */
237 /* XXX: simplify */
238 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
239 /* record symbol in token array */
240 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
241 if (v & SYM_STRUCT)
242 ps = &ts->sym_struct;
243 else
244 ps = &ts->sym_identifier;
245 s->prev_tok = *ps;
246 *ps = s;
248 return s;
251 /* push a global identifier */
252 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
254 Sym *s, **ps;
255 s = sym_push2(&global_stack, v, t, c);
256 /* don't record anonymous symbol */
257 if (v < SYM_FIRST_ANOM) {
258 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
259 /* modify the top most local identifier, so that
260 sym_identifier will point to 's' when popped */
261 while (*ps != NULL)
262 ps = &(*ps)->prev_tok;
263 s->prev_tok = NULL;
264 *ps = s;
266 return s;
269 /* pop symbols until top reaches 'b' */
270 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
272 Sym *s, *ss, **ps;
273 TokenSym *ts;
274 int v;
276 s = *ptop;
277 while(s != b) {
278 ss = s->prev;
279 v = s->v;
280 /* remove symbol in token array */
281 /* XXX: simplify */
282 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
283 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
284 if (v & SYM_STRUCT)
285 ps = &ts->sym_struct;
286 else
287 ps = &ts->sym_identifier;
288 *ps = s->prev_tok;
290 sym_free(s);
291 s = ss;
293 *ptop = b;
296 static void weaken_symbol(Sym *sym)
298 sym->type.t |= VT_WEAK;
299 if (sym->c > 0) {
300 int esym_type;
301 ElfW(Sym) *esym;
303 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
304 esym_type = ELFW(ST_TYPE)(esym->st_info);
305 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
309 static void apply_visibility(Sym *sym, CType *type)
311 int vis = sym->type.t & VT_VIS_MASK;
312 int vis2 = type->t & VT_VIS_MASK;
313 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
314 vis = vis2;
315 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
317 else
318 vis = (vis < vis2) ? vis : vis2;
319 sym->type.t &= ~VT_VIS_MASK;
320 sym->type.t |= vis;
322 if (sym->c > 0) {
323 ElfW(Sym) *esym;
325 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
326 vis >>= VT_VIS_SHIFT;
327 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
331 /* ------------------------------------------------------------------------- */
333 ST_FUNC void swap(int *p, int *q)
335 int t;
336 t = *p;
337 *p = *q;
338 *q = t;
341 static void vsetc(CType *type, int r, CValue *vc)
343 int v;
345 if (vtop >= vstack + (VSTACK_SIZE - 1))
346 tcc_error("memory full (vstack)");
347 /* cannot let cpu flags if other instruction are generated. Also
348 avoid leaving VT_JMP anywhere except on the top of the stack
349 because it would complicate the code generator. */
350 if (vtop >= vstack) {
351 v = vtop->r & VT_VALMASK;
352 if (v == VT_CMP || (v & ~1) == VT_JMP)
353 gv(RC_INT);
355 vtop++;
356 vtop->type = *type;
357 vtop->r = r;
358 vtop->r2 = VT_CONST;
359 vtop->c = *vc;
362 /* push constant of type "type" with useless value */
363 ST_FUNC void vpush(CType *type)
365 CValue cval;
366 vsetc(type, VT_CONST, &cval);
369 /* push integer constant */
370 ST_FUNC void vpushi(int v)
372 CValue cval;
373 cval.i = v;
374 vsetc(&int_type, VT_CONST, &cval);
377 /* push a pointer sized constant */
378 static void vpushs(addr_t v)
380 CValue cval;
381 cval.i = v;
382 vsetc(&size_type, VT_CONST, &cval);
385 /* push arbitrary 64bit constant */
386 ST_FUNC void vpush64(int ty, unsigned long long v)
388 CValue cval;
389 CType ctype;
390 ctype.t = ty;
391 ctype.ref = NULL;
392 cval.i = v;
393 vsetc(&ctype, VT_CONST, &cval);
396 /* push long long constant */
397 static inline void vpushll(long long v)
399 vpush64(VT_LLONG, v);
402 /* push a symbol value of TYPE */
403 static inline void vpushsym(CType *type, Sym *sym)
405 CValue cval;
406 cval.i = 0;
407 vsetc(type, VT_CONST | VT_SYM, &cval);
408 vtop->sym = sym;
411 /* Return a static symbol pointing to a section */
412 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
414 int v;
415 Sym *sym;
417 v = anon_sym++;
418 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
419 sym->type.ref = type->ref;
420 sym->r = VT_CONST | VT_SYM;
421 put_extern_sym(sym, sec, offset, size);
422 return sym;
425 /* push a reference to a section offset by adding a dummy symbol */
426 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
428 vpushsym(type, get_sym_ref(type, sec, offset, size));
431 /* define a new external reference to a symbol 'v' of type 'u' */
432 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
434 Sym *s;
436 s = sym_find(v);
437 if (!s) {
438 /* push forward reference */
439 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
440 s->type.ref = type->ref;
441 s->r = r | VT_CONST | VT_SYM;
443 return s;
446 /* define a new external reference to a symbol 'v' with alternate asm
447 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
448 is no alternate name (most cases) */
449 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
451 Sym *s;
453 s = sym_find(v);
454 if (!s) {
455 /* push forward reference */
456 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
457 s->asm_label = asm_label ? tcc_strdup(asm_label) : 0;
458 s->type.t |= VT_EXTERN;
459 } else if (s->type.ref == func_old_type.ref) {
460 s->type.ref = type->ref;
461 s->r = r | VT_CONST | VT_SYM;
462 s->type.t |= VT_EXTERN;
463 } else if (!is_compatible_types(&s->type, type)) {
464 tcc_error("incompatible types for redefinition of '%s'",
465 get_tok_str(v, NULL));
467 /* Merge some storage attributes. */
468 if (type->t & VT_WEAK)
469 weaken_symbol(s);
471 if (type->t & VT_VIS_MASK)
472 apply_visibility(s, type);
474 return s;
477 /* push a reference to global symbol v */
478 ST_FUNC void vpush_global_sym(CType *type, int v)
480 vpushsym(type, external_global_sym(v, type, 0));
483 ST_FUNC void vset(CType *type, int r, int v)
485 CValue cval;
487 cval.i = v;
488 vsetc(type, r, &cval);
491 static void vseti(int r, int v)
493 CType type;
494 type.t = VT_INT;
495 type.ref = 0;
496 vset(&type, r, v);
499 ST_FUNC void vswap(void)
501 SValue tmp;
502 /* cannot let cpu flags if other instruction are generated. Also
503 avoid leaving VT_JMP anywhere except on the top of the stack
504 because it would complicate the code generator. */
505 if (vtop >= vstack) {
506 int v = vtop->r & VT_VALMASK;
507 if (v == VT_CMP || (v & ~1) == VT_JMP)
508 gv(RC_INT);
510 tmp = vtop[0];
511 vtop[0] = vtop[-1];
512 vtop[-1] = tmp;
514 /* XXX: +2% overall speed possible with optimized memswap
516 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
520 ST_FUNC void vpushv(SValue *v)
522 if (vtop >= vstack + (VSTACK_SIZE - 1))
523 tcc_error("memory full (vstack)");
524 vtop++;
525 *vtop = *v;
528 static void vdup(void)
530 vpushv(vtop);
533 /* save r to the memory stack, and mark it as being free */
534 ST_FUNC void save_reg(int r)
536 int l, saved, size, align;
537 SValue *p, sv;
538 CType *type;
540 /* modify all stack values */
541 saved = 0;
542 l = 0;
543 for(p=vstack;p<=vtop;p++) {
544 if ((p->r & VT_VALMASK) == r ||
545 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
546 /* must save value on stack if not already done */
547 if (!saved) {
548 /* NOTE: must reload 'r' because r might be equal to r2 */
549 r = p->r & VT_VALMASK;
550 /* store register in the stack */
551 type = &p->type;
552 if ((p->r & VT_LVAL) ||
553 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
554 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
555 type = &char_pointer_type;
556 #else
557 type = &int_type;
558 #endif
559 size = type_size(type, &align);
560 loc = (loc - size) & -align;
561 sv.type.t = type->t;
562 sv.r = VT_LOCAL | VT_LVAL;
563 sv.c.i = loc;
564 store(r, &sv);
565 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
566 /* x86 specific: need to pop fp register ST0 if saved */
567 if (r == TREG_ST0) {
568 o(0xd8dd); /* fstp %st(0) */
570 #endif
571 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
572 /* special long long case */
573 if ((type->t & VT_BTYPE) == VT_LLONG) {
574 sv.c.i += 4;
575 store(p->r2, &sv);
577 #endif
578 l = loc;
579 saved = 1;
581 /* mark that stack entry as being saved on the stack */
582 if (p->r & VT_LVAL) {
583 /* also clear the bounded flag because the
584 relocation address of the function was stored in
585 p->c.i */
586 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
587 } else {
588 p->r = lvalue_type(p->type.t) | VT_LOCAL;
590 p->r2 = VT_CONST;
591 p->c.i = l;
596 #ifdef TCC_TARGET_ARM
597 /* find a register of class 'rc2' with at most one reference on stack.
598 * If none, call get_reg(rc) */
599 ST_FUNC int get_reg_ex(int rc, int rc2)
601 int r;
602 SValue *p;
604 for(r=0;r<NB_REGS;r++) {
605 if (reg_classes[r] & rc2) {
606 int n;
607 n=0;
608 for(p = vstack; p <= vtop; p++) {
609 if ((p->r & VT_VALMASK) == r ||
610 (p->r2 & VT_VALMASK) == r)
611 n++;
613 if (n <= 1)
614 return r;
617 return get_reg(rc);
619 #endif
621 /* find a free register of class 'rc'. If none, save one register */
622 ST_FUNC int get_reg(int rc)
624 int r;
625 SValue *p;
627 /* find a free register */
628 for(r=0;r<NB_REGS;r++) {
629 if (reg_classes[r] & rc) {
630 for(p=vstack;p<=vtop;p++) {
631 if ((p->r & VT_VALMASK) == r ||
632 (p->r2 & VT_VALMASK) == r)
633 goto notfound;
635 return r;
637 notfound: ;
640 /* no register left : free the first one on the stack (VERY
641 IMPORTANT to start from the bottom to ensure that we don't
642 spill registers used in gen_opi()) */
643 for(p=vstack;p<=vtop;p++) {
644 /* look at second register (if long long) */
645 r = p->r2 & VT_VALMASK;
646 if (r < VT_CONST && (reg_classes[r] & rc))
647 goto save_found;
648 r = p->r & VT_VALMASK;
649 if (r < VT_CONST && (reg_classes[r] & rc)) {
650 save_found:
651 save_reg(r);
652 return r;
655 /* Should never comes here */
656 return -1;
659 /* save registers up to (vtop - n) stack entry */
660 ST_FUNC void save_regs(int n)
662 int r;
663 SValue *p, *p1;
664 p1 = vtop - n;
665 for(p = vstack;p <= p1; p++) {
666 r = p->r & VT_VALMASK;
667 if (r < VT_CONST) {
668 save_reg(r);
673 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
674 if needed */
675 static void move_reg(int r, int s, int t)
677 SValue sv;
679 if (r != s) {
680 save_reg(r);
681 sv.type.t = t;
682 sv.type.ref = NULL;
683 sv.r = s;
684 sv.c.i = 0;
685 load(r, &sv);
689 /* get address of vtop (vtop MUST BE an lvalue) */
690 ST_FUNC void gaddrof(void)
692 if (vtop->r & VT_REF && !nocode_wanted)
693 gv(RC_INT);
694 vtop->r &= ~VT_LVAL;
695 /* tricky: if saved lvalue, then we can go back to lvalue */
696 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
697 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
702 #ifdef CONFIG_TCC_BCHECK
703 /* generate lvalue bound code */
704 static void gbound(void)
706 int lval_type;
707 CType type1;
709 vtop->r &= ~VT_MUSTBOUND;
710 /* if lvalue, then use checking code before dereferencing */
711 if (vtop->r & VT_LVAL) {
712 /* if not VT_BOUNDED value, then make one */
713 if (!(vtop->r & VT_BOUNDED)) {
714 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
715 /* must save type because we must set it to int to get pointer */
716 type1 = vtop->type;
717 vtop->type.t = VT_PTR;
718 gaddrof();
719 vpushi(0);
720 gen_bounded_ptr_add();
721 vtop->r |= lval_type;
722 vtop->type = type1;
724 /* then check for dereferencing */
725 gen_bounded_ptr_deref();
728 #endif
730 /* store vtop a register belonging to class 'rc'. lvalues are
731 converted to values. Cannot be used if cannot be converted to
732 register value (such as structures). */
733 ST_FUNC int gv(int rc)
735 int r, bit_pos, bit_size, size, align, i;
736 int rc2;
738 /* NOTE: get_reg can modify vstack[] */
739 if (vtop->type.t & VT_BITFIELD) {
740 CType type;
741 int bits = 32;
742 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
743 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
744 /* remove bit field info to avoid loops */
745 vtop->type.t &= ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
746 /* cast to int to propagate signedness in following ops */
747 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
748 type.t = VT_LLONG;
749 bits = 64;
750 } else
751 type.t = VT_INT;
752 if((vtop->type.t & VT_UNSIGNED) ||
753 (vtop->type.t & VT_BTYPE) == VT_BOOL)
754 type.t |= VT_UNSIGNED;
755 gen_cast(&type);
756 /* generate shifts */
757 vpushi(bits - (bit_pos + bit_size));
758 gen_op(TOK_SHL);
759 vpushi(bits - bit_size);
760 /* NOTE: transformed to SHR if unsigned */
761 gen_op(TOK_SAR);
762 r = gv(rc);
763 } else {
764 if (is_float(vtop->type.t) &&
765 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
766 Sym *sym;
767 int *ptr;
768 unsigned long offset;
769 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
770 CValue check;
771 #endif
773 /* XXX: unify with initializers handling ? */
774 /* CPUs usually cannot use float constants, so we store them
775 generically in data segment */
776 size = type_size(&vtop->type, &align);
777 offset = (data_section->data_offset + align - 1) & -align;
778 data_section->data_offset = offset;
779 /* XXX: not portable yet */
780 #if defined(__i386__) || defined(__x86_64__)
781 /* Zero pad x87 tenbyte long doubles */
782 if (size == LDOUBLE_SIZE) {
783 vtop->c.tab[2] &= 0xffff;
784 #if LDOUBLE_SIZE == 16
785 vtop->c.tab[3] = 0;
786 #endif
788 #endif
789 ptr = section_ptr_add(data_section, size);
790 size = size >> 2;
791 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
792 check.d = 1;
793 if(check.tab[0])
794 for(i=0;i<size;i++)
795 ptr[i] = vtop->c.tab[size-1-i];
796 else
797 #endif
798 for(i=0;i<size;i++)
799 ptr[i] = vtop->c.tab[i];
800 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
801 vtop->r |= VT_LVAL | VT_SYM;
802 vtop->sym = sym;
803 vtop->c.i = 0;
805 #ifdef CONFIG_TCC_BCHECK
806 if (vtop->r & VT_MUSTBOUND)
807 gbound();
808 #endif
810 r = vtop->r & VT_VALMASK;
811 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
812 #ifndef TCC_TARGET_ARM64
813 if (rc == RC_IRET)
814 rc2 = RC_LRET;
815 #ifdef TCC_TARGET_X86_64
816 else if (rc == RC_FRET)
817 rc2 = RC_QRET;
818 #endif
819 #endif
821 /* need to reload if:
822 - constant
823 - lvalue (need to dereference pointer)
824 - already a register, but not in the right class */
825 if (r >= VT_CONST
826 || (vtop->r & VT_LVAL)
827 || !(reg_classes[r] & rc)
828 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
829 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
830 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
831 #else
832 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
833 #endif
836 r = get_reg(rc);
837 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
838 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
839 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
840 #else
841 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
842 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
843 unsigned long long ll;
844 #endif
845 int r2, original_type;
846 original_type = vtop->type.t;
847 /* two register type load : expand to two words
848 temporarily */
849 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
850 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
851 /* load constant */
852 ll = vtop->c.i;
853 vtop->c.i = ll; /* first word */
854 load(r, vtop);
855 vtop->r = r; /* save register value */
856 vpushi(ll >> 32); /* second word */
857 } else
858 #endif
859 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
860 (vtop->r & VT_LVAL)) {
861 /* We do not want to modifier the long long
862 pointer here, so the safest (and less
863 efficient) is to save all the other registers
864 in the stack. XXX: totally inefficient. */
865 save_regs(1);
866 /* load from memory */
867 vtop->type.t = load_type;
868 load(r, vtop);
869 vdup();
870 vtop[-1].r = r; /* save register value */
871 /* increment pointer to get second word */
872 vtop->type.t = addr_type;
873 gaddrof();
874 vpushi(load_size);
875 gen_op('+');
876 vtop->r |= VT_LVAL;
877 vtop->type.t = load_type;
878 } else {
879 /* move registers */
880 load(r, vtop);
881 vdup();
882 vtop[-1].r = r; /* save register value */
883 vtop->r = vtop[-1].r2;
885 /* Allocate second register. Here we rely on the fact that
886 get_reg() tries first to free r2 of an SValue. */
887 r2 = get_reg(rc2);
888 load(r2, vtop);
889 vpop();
890 /* write second register */
891 vtop->r2 = r2;
892 vtop->type.t = original_type;
893 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
894 int t1, t;
895 /* lvalue of scalar type : need to use lvalue type
896 because of possible cast */
897 t = vtop->type.t;
898 t1 = t;
899 /* compute memory access type */
900 if (vtop->r & VT_REF)
901 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
902 t = VT_PTR;
903 #else
904 t = VT_INT;
905 #endif
906 else if (vtop->r & VT_LVAL_BYTE)
907 t = VT_BYTE;
908 else if (vtop->r & VT_LVAL_SHORT)
909 t = VT_SHORT;
910 if (vtop->r & VT_LVAL_UNSIGNED)
911 t |= VT_UNSIGNED;
912 vtop->type.t = t;
913 load(r, vtop);
914 /* restore wanted type */
915 vtop->type.t = t1;
916 } else {
917 /* one register type load */
918 load(r, vtop);
921 vtop->r = r;
922 #ifdef TCC_TARGET_C67
923 /* uses register pairs for doubles */
924 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
925 vtop->r2 = r+1;
926 #endif
928 return r;
931 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
932 ST_FUNC void gv2(int rc1, int rc2)
934 int v;
936 /* generate more generic register first. But VT_JMP or VT_CMP
937 values must be generated first in all cases to avoid possible
938 reload errors */
939 v = vtop[0].r & VT_VALMASK;
940 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
941 vswap();
942 gv(rc1);
943 vswap();
944 gv(rc2);
945 /* test if reload is needed for first register */
946 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
947 vswap();
948 gv(rc1);
949 vswap();
951 } else {
952 gv(rc2);
953 vswap();
954 gv(rc1);
955 vswap();
956 /* test if reload is needed for first register */
957 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
958 gv(rc2);
963 #ifndef TCC_TARGET_ARM64
964 /* wrapper around RC_FRET to return a register by type */
965 static int rc_fret(int t)
967 #ifdef TCC_TARGET_X86_64
968 if (t == VT_LDOUBLE) {
969 return RC_ST0;
971 #endif
972 return RC_FRET;
974 #endif
976 /* wrapper around REG_FRET to return a register by type */
977 static int reg_fret(int t)
979 #ifdef TCC_TARGET_X86_64
980 if (t == VT_LDOUBLE) {
981 return TREG_ST0;
983 #endif
984 return REG_FRET;
987 /* expand long long on stack in two int registers */
988 static void lexpand(void)
990 int u;
992 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
993 gv(RC_INT);
994 vdup();
995 vtop[0].r = vtop[-1].r2;
996 vtop[0].r2 = VT_CONST;
997 vtop[-1].r2 = VT_CONST;
998 vtop[0].type.t = VT_INT | u;
999 vtop[-1].type.t = VT_INT | u;
1002 #ifdef TCC_TARGET_ARM
1003 /* expand long long on stack */
1004 ST_FUNC void lexpand_nr(void)
1006 int u,v;
1008 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1009 vdup();
1010 vtop->r2 = VT_CONST;
1011 vtop->type.t = VT_INT | u;
1012 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1013 if (v == VT_CONST) {
1014 vtop[-1].c.i = vtop->c.i;
1015 vtop->c.i = vtop->c.i >> 32;
1016 vtop->r = VT_CONST;
1017 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1018 vtop->c.i += 4;
1019 vtop->r = vtop[-1].r;
1020 } else if (v > VT_CONST) {
1021 vtop--;
1022 lexpand();
1023 } else
1024 vtop->r = vtop[-1].r2;
1025 vtop[-1].r2 = VT_CONST;
1026 vtop[-1].type.t = VT_INT | u;
1028 #endif
1030 /* build a long long from two ints */
1031 static void lbuild(int t)
1033 gv2(RC_INT, RC_INT);
1034 vtop[-1].r2 = vtop[0].r;
1035 vtop[-1].type.t = t;
1036 vpop();
1039 /* rotate n first stack elements to the bottom
1040 I1 ... In -> I2 ... In I1 [top is right]
1042 ST_FUNC void vrotb(int n)
1044 int i;
1045 SValue tmp;
1047 tmp = vtop[-n + 1];
1048 for(i=-n+1;i!=0;i++)
1049 vtop[i] = vtop[i+1];
1050 vtop[0] = tmp;
1053 /* rotate the n elements before entry e towards the top
1054 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1056 ST_FUNC void vrote(SValue *e, int n)
1058 int i;
1059 SValue tmp;
1061 tmp = *e;
1062 for(i = 0;i < n - 1; i++)
1063 e[-i] = e[-i - 1];
1064 e[-n + 1] = tmp;
1067 /* rotate n first stack elements to the top
1068 I1 ... In -> In I1 ... I(n-1) [top is right]
1070 ST_FUNC void vrott(int n)
1072 vrote(vtop, n);
1075 /* pop stack value */
1076 ST_FUNC void vpop(void)
1078 int v;
1079 v = vtop->r & VT_VALMASK;
1080 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1081 /* for x86, we need to pop the FP stack */
1082 if (v == TREG_ST0 && !nocode_wanted) {
1083 o(0xd8dd); /* fstp %st(0) */
1084 } else
1085 #endif
1086 if (v == VT_JMP || v == VT_JMPI) {
1087 /* need to put correct jump if && or || without test */
1088 gsym(vtop->c.i);
1090 vtop--;
1093 /* convert stack entry to register and duplicate its value in another
1094 register */
1095 static void gv_dup(void)
1097 int rc, t, r, r1;
1098 SValue sv;
1100 t = vtop->type.t;
1101 if ((t & VT_BTYPE) == VT_LLONG) {
1102 lexpand();
1103 gv_dup();
1104 vswap();
1105 vrotb(3);
1106 gv_dup();
1107 vrotb(4);
1108 /* stack: H L L1 H1 */
1109 lbuild(t);
1110 vrotb(3);
1111 vrotb(3);
1112 vswap();
1113 lbuild(t);
1114 vswap();
1115 } else {
1116 /* duplicate value */
1117 rc = RC_INT;
1118 sv.type.t = VT_INT;
1119 if (is_float(t)) {
1120 rc = RC_FLOAT;
1121 #ifdef TCC_TARGET_X86_64
1122 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1123 rc = RC_ST0;
1125 #endif
1126 sv.type.t = t;
1128 r = gv(rc);
1129 r1 = get_reg(rc);
1130 sv.r = r;
1131 sv.c.i = 0;
1132 load(r1, &sv); /* move r to r1 */
1133 vdup();
1134 /* duplicates value */
1135 if (r != r1)
1136 vtop->r = r1;
1140 /* Generate value test
1142 * Generate a test for any value (jump, comparison and integers) */
1143 ST_FUNC int gvtst(int inv, int t)
1145 int v = vtop->r & VT_VALMASK;
1146 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1147 vpushi(0);
1148 gen_op(TOK_NE);
1150 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1151 /* constant jmp optimization */
1152 if ((vtop->c.i != 0) != inv)
1153 t = gjmp(t);
1154 vtop--;
1155 return t;
1157 return gtst(inv, t);
1160 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1161 /* generate CPU independent (unsigned) long long operations */
1162 static void gen_opl(int op)
1164 int t, a, b, op1, c, i;
1165 int func;
1166 unsigned short reg_iret = REG_IRET;
1167 unsigned short reg_lret = REG_LRET;
1168 SValue tmp;
1170 switch(op) {
1171 case '/':
1172 case TOK_PDIV:
1173 func = TOK___divdi3;
1174 goto gen_func;
1175 case TOK_UDIV:
1176 func = TOK___udivdi3;
1177 goto gen_func;
1178 case '%':
1179 func = TOK___moddi3;
1180 goto gen_mod_func;
1181 case TOK_UMOD:
1182 func = TOK___umoddi3;
1183 gen_mod_func:
1184 #ifdef TCC_ARM_EABI
1185 reg_iret = TREG_R2;
1186 reg_lret = TREG_R3;
1187 #endif
1188 gen_func:
1189 /* call generic long long function */
1190 vpush_global_sym(&func_old_type, func);
1191 vrott(3);
1192 gfunc_call(2);
1193 vpushi(0);
1194 vtop->r = reg_iret;
1195 vtop->r2 = reg_lret;
1196 break;
1197 case '^':
1198 case '&':
1199 case '|':
1200 case '*':
1201 case '+':
1202 case '-':
1203 t = vtop->type.t;
1204 vswap();
1205 lexpand();
1206 vrotb(3);
1207 lexpand();
1208 /* stack: L1 H1 L2 H2 */
1209 tmp = vtop[0];
1210 vtop[0] = vtop[-3];
1211 vtop[-3] = tmp;
1212 tmp = vtop[-2];
1213 vtop[-2] = vtop[-3];
1214 vtop[-3] = tmp;
1215 vswap();
1216 /* stack: H1 H2 L1 L2 */
1217 if (op == '*') {
1218 vpushv(vtop - 1);
1219 vpushv(vtop - 1);
1220 gen_op(TOK_UMULL);
1221 lexpand();
1222 /* stack: H1 H2 L1 L2 ML MH */
1223 for(i=0;i<4;i++)
1224 vrotb(6);
1225 /* stack: ML MH H1 H2 L1 L2 */
1226 tmp = vtop[0];
1227 vtop[0] = vtop[-2];
1228 vtop[-2] = tmp;
1229 /* stack: ML MH H1 L2 H2 L1 */
1230 gen_op('*');
1231 vrotb(3);
1232 vrotb(3);
1233 gen_op('*');
1234 /* stack: ML MH M1 M2 */
1235 gen_op('+');
1236 gen_op('+');
1237 } else if (op == '+' || op == '-') {
1238 /* XXX: add non carry method too (for MIPS or alpha) */
1239 if (op == '+')
1240 op1 = TOK_ADDC1;
1241 else
1242 op1 = TOK_SUBC1;
1243 gen_op(op1);
1244 /* stack: H1 H2 (L1 op L2) */
1245 vrotb(3);
1246 vrotb(3);
1247 gen_op(op1 + 1); /* TOK_xxxC2 */
1248 } else {
1249 gen_op(op);
1250 /* stack: H1 H2 (L1 op L2) */
1251 vrotb(3);
1252 vrotb(3);
1253 /* stack: (L1 op L2) H1 H2 */
1254 gen_op(op);
1255 /* stack: (L1 op L2) (H1 op H2) */
1257 /* stack: L H */
1258 lbuild(t);
1259 break;
1260 case TOK_SAR:
1261 case TOK_SHR:
1262 case TOK_SHL:
1263 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1264 t = vtop[-1].type.t;
1265 vswap();
1266 lexpand();
1267 vrotb(3);
1268 /* stack: L H shift */
1269 c = (int)vtop->c.i;
1270 /* constant: simpler */
1271 /* NOTE: all comments are for SHL. the other cases are
1272 done by swaping words */
1273 vpop();
1274 if (op != TOK_SHL)
1275 vswap();
1276 if (c >= 32) {
1277 /* stack: L H */
1278 vpop();
1279 if (c > 32) {
1280 vpushi(c - 32);
1281 gen_op(op);
1283 if (op != TOK_SAR) {
1284 vpushi(0);
1285 } else {
1286 gv_dup();
1287 vpushi(31);
1288 gen_op(TOK_SAR);
1290 vswap();
1291 } else {
1292 vswap();
1293 gv_dup();
1294 /* stack: H L L */
1295 vpushi(c);
1296 gen_op(op);
1297 vswap();
1298 vpushi(32 - c);
1299 if (op == TOK_SHL)
1300 gen_op(TOK_SHR);
1301 else
1302 gen_op(TOK_SHL);
1303 vrotb(3);
1304 /* stack: L L H */
1305 vpushi(c);
1306 if (op == TOK_SHL)
1307 gen_op(TOK_SHL);
1308 else
1309 gen_op(TOK_SHR);
1310 gen_op('|');
1312 if (op != TOK_SHL)
1313 vswap();
1314 lbuild(t);
1315 } else {
1316 /* XXX: should provide a faster fallback on x86 ? */
1317 switch(op) {
1318 case TOK_SAR:
1319 func = TOK___ashrdi3;
1320 goto gen_func;
1321 case TOK_SHR:
1322 func = TOK___lshrdi3;
1323 goto gen_func;
1324 case TOK_SHL:
1325 func = TOK___ashldi3;
1326 goto gen_func;
1329 break;
1330 default:
1331 /* compare operations */
1332 t = vtop->type.t;
1333 vswap();
1334 lexpand();
1335 vrotb(3);
1336 lexpand();
1337 /* stack: L1 H1 L2 H2 */
1338 tmp = vtop[-1];
1339 vtop[-1] = vtop[-2];
1340 vtop[-2] = tmp;
1341 /* stack: L1 L2 H1 H2 */
1342 /* compare high */
1343 op1 = op;
1344 /* when values are equal, we need to compare low words. since
1345 the jump is inverted, we invert the test too. */
1346 if (op1 == TOK_LT)
1347 op1 = TOK_LE;
1348 else if (op1 == TOK_GT)
1349 op1 = TOK_GE;
1350 else if (op1 == TOK_ULT)
1351 op1 = TOK_ULE;
1352 else if (op1 == TOK_UGT)
1353 op1 = TOK_UGE;
1354 a = 0;
1355 b = 0;
1356 gen_op(op1);
1357 if (op1 != TOK_NE) {
1358 a = gvtst(1, 0);
1360 if (op != TOK_EQ) {
1361 /* generate non equal test */
1362 /* XXX: NOT PORTABLE yet */
1363 if (a == 0) {
1364 b = gvtst(0, 0);
1365 } else {
1366 #if defined(TCC_TARGET_I386)
1367 b = psym(0x850f, 0);
1368 #elif defined(TCC_TARGET_ARM)
1369 b = ind;
1370 o(0x1A000000 | encbranch(ind, 0, 1));
1371 #elif defined(TCC_TARGET_C67) || defined(TCC_TARGET_ARM64)
1372 tcc_error("not implemented");
1373 #else
1374 #error not supported
1375 #endif
1378 /* compare low. Always unsigned */
1379 op1 = op;
1380 if (op1 == TOK_LT)
1381 op1 = TOK_ULT;
1382 else if (op1 == TOK_LE)
1383 op1 = TOK_ULE;
1384 else if (op1 == TOK_GT)
1385 op1 = TOK_UGT;
1386 else if (op1 == TOK_GE)
1387 op1 = TOK_UGE;
1388 gen_op(op1);
1389 a = gvtst(1, a);
1390 gsym(b);
1391 vseti(VT_JMPI, a);
1392 break;
1395 #endif
1397 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
1399 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
1400 return (a ^ b) >> 63 ? -x : x;
1403 static int gen_opic_lt(uint64_t a, uint64_t b)
1405 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
1408 /* handle integer constant optimizations and various machine
1409 independent opt */
1410 static void gen_opic(int op)
1412 SValue *v1 = vtop - 1;
1413 SValue *v2 = vtop;
1414 int t1 = v1->type.t & VT_BTYPE;
1415 int t2 = v2->type.t & VT_BTYPE;
1416 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1417 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1418 uint64_t l1 = c1 ? v1->c.i : 0;
1419 uint64_t l2 = c2 ? v2->c.i : 0;
1420 int shm = (t1 == VT_LLONG) ? 63 : 31;
1422 if (t1 != VT_LLONG)
1423 l1 = ((uint32_t)l1 |
1424 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
1425 if (t2 != VT_LLONG)
1426 l2 = ((uint32_t)l2 |
1427 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
1429 if (c1 && c2) {
1430 switch(op) {
1431 case '+': l1 += l2; break;
1432 case '-': l1 -= l2; break;
1433 case '&': l1 &= l2; break;
1434 case '^': l1 ^= l2; break;
1435 case '|': l1 |= l2; break;
1436 case '*': l1 *= l2; break;
1438 case TOK_PDIV:
1439 case '/':
1440 case '%':
1441 case TOK_UDIV:
1442 case TOK_UMOD:
1443 /* if division by zero, generate explicit division */
1444 if (l2 == 0) {
1445 if (const_wanted)
1446 tcc_error("division by zero in constant");
1447 goto general_case;
1449 switch(op) {
1450 default: l1 = gen_opic_sdiv(l1, l2); break;
1451 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
1452 case TOK_UDIV: l1 = l1 / l2; break;
1453 case TOK_UMOD: l1 = l1 % l2; break;
1455 break;
1456 case TOK_SHL: l1 <<= (l2 & shm); break;
1457 case TOK_SHR: l1 >>= (l2 & shm); break;
1458 case TOK_SAR:
1459 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
1460 break;
1461 /* tests */
1462 case TOK_ULT: l1 = l1 < l2; break;
1463 case TOK_UGE: l1 = l1 >= l2; break;
1464 case TOK_EQ: l1 = l1 == l2; break;
1465 case TOK_NE: l1 = l1 != l2; break;
1466 case TOK_ULE: l1 = l1 <= l2; break;
1467 case TOK_UGT: l1 = l1 > l2; break;
1468 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
1469 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
1470 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
1471 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
1472 /* logical */
1473 case TOK_LAND: l1 = l1 && l2; break;
1474 case TOK_LOR: l1 = l1 || l2; break;
1475 default:
1476 goto general_case;
1478 v1->c.i = l1;
1479 vtop--;
1480 } else {
1481 /* if commutative ops, put c2 as constant */
1482 if (c1 && (op == '+' || op == '&' || op == '^' ||
1483 op == '|' || op == '*')) {
1484 vswap();
1485 c2 = c1; //c = c1, c1 = c2, c2 = c;
1486 l2 = l1; //l = l1, l1 = l2, l2 = l;
1488 if (!const_wanted &&
1489 c1 && ((l1 == 0 &&
1490 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
1491 (l1 == -1 && op == TOK_SAR))) {
1492 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
1493 vtop--;
1494 } else if (!const_wanted &&
1495 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
1496 (l2 == -1 && op == '|') ||
1497 (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
1498 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
1499 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
1500 if (l2 == 1)
1501 vtop->c.i = 0;
1502 vswap();
1503 vtop--;
1504 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1505 op == TOK_PDIV) &&
1506 l2 == 1) ||
1507 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1508 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1509 l2 == 0) ||
1510 (op == '&' &&
1511 l2 == -1))) {
1512 /* filter out NOP operations like x*1, x-0, x&-1... */
1513 vtop--;
1514 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1515 /* try to use shifts instead of muls or divs */
1516 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1517 int n = -1;
1518 while (l2) {
1519 l2 >>= 1;
1520 n++;
1522 vtop->c.i = n;
1523 if (op == '*')
1524 op = TOK_SHL;
1525 else if (op == TOK_PDIV)
1526 op = TOK_SAR;
1527 else
1528 op = TOK_SHR;
1530 goto general_case;
1531 } else if (c2 && (op == '+' || op == '-') &&
1532 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1533 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1534 /* symbol + constant case */
1535 if (op == '-')
1536 l2 = -l2;
1537 vtop--;
1538 vtop->c.i += l2;
1539 } else {
1540 general_case:
1541 if (!nocode_wanted) {
1542 /* call low level op generator */
1543 if (t1 == VT_LLONG || t2 == VT_LLONG ||
1544 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
1545 gen_opl(op);
1546 else
1547 gen_opi(op);
1548 } else {
1549 vtop--;
1555 /* generate a floating point operation with constant propagation */
1556 static void gen_opif(int op)
1558 int c1, c2;
1559 SValue *v1, *v2;
1560 long double f1, f2;
1562 v1 = vtop - 1;
1563 v2 = vtop;
1564 /* currently, we cannot do computations with forward symbols */
1565 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1566 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1567 if (c1 && c2) {
1568 if (v1->type.t == VT_FLOAT) {
1569 f1 = v1->c.f;
1570 f2 = v2->c.f;
1571 } else if (v1->type.t == VT_DOUBLE) {
1572 f1 = v1->c.d;
1573 f2 = v2->c.d;
1574 } else {
1575 f1 = v1->c.ld;
1576 f2 = v2->c.ld;
1579 /* NOTE: we only do constant propagation if finite number (not
1580 NaN or infinity) (ANSI spec) */
1581 if (!ieee_finite(f1) || !ieee_finite(f2))
1582 goto general_case;
1584 switch(op) {
1585 case '+': f1 += f2; break;
1586 case '-': f1 -= f2; break;
1587 case '*': f1 *= f2; break;
1588 case '/':
1589 if (f2 == 0.0) {
1590 if (const_wanted)
1591 tcc_error("division by zero in constant");
1592 goto general_case;
1594 f1 /= f2;
1595 break;
1596 /* XXX: also handles tests ? */
1597 default:
1598 goto general_case;
1600 /* XXX: overflow test ? */
1601 if (v1->type.t == VT_FLOAT) {
1602 v1->c.f = f1;
1603 } else if (v1->type.t == VT_DOUBLE) {
1604 v1->c.d = f1;
1605 } else {
1606 v1->c.ld = f1;
1608 vtop--;
1609 } else {
1610 general_case:
1611 if (!nocode_wanted) {
1612 gen_opf(op);
1613 } else {
1614 vtop--;
1619 static int pointed_size(CType *type)
1621 int align;
1622 return type_size(pointed_type(type), &align);
1625 static void vla_runtime_pointed_size(CType *type)
1627 int align;
1628 vla_runtime_type_size(pointed_type(type), &align);
1631 static inline int is_null_pointer(SValue *p)
1633 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1634 return 0;
1635 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
1636 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
1637 ((p->type.t & VT_BTYPE) == VT_PTR &&
1638 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
1641 static inline int is_integer_btype(int bt)
1643 return (bt == VT_BYTE || bt == VT_SHORT ||
1644 bt == VT_INT || bt == VT_LLONG);
1647 /* check types for comparison or subtraction of pointers */
1648 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1650 CType *type1, *type2, tmp_type1, tmp_type2;
1651 int bt1, bt2;
1653 /* null pointers are accepted for all comparisons as gcc */
1654 if (is_null_pointer(p1) || is_null_pointer(p2))
1655 return;
1656 type1 = &p1->type;
1657 type2 = &p2->type;
1658 bt1 = type1->t & VT_BTYPE;
1659 bt2 = type2->t & VT_BTYPE;
1660 /* accept comparison between pointer and integer with a warning */
1661 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1662 if (op != TOK_LOR && op != TOK_LAND )
1663 tcc_warning("comparison between pointer and integer");
1664 return;
1667 /* both must be pointers or implicit function pointers */
1668 if (bt1 == VT_PTR) {
1669 type1 = pointed_type(type1);
1670 } else if (bt1 != VT_FUNC)
1671 goto invalid_operands;
1673 if (bt2 == VT_PTR) {
1674 type2 = pointed_type(type2);
1675 } else if (bt2 != VT_FUNC) {
1676 invalid_operands:
1677 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1679 if ((type1->t & VT_BTYPE) == VT_VOID ||
1680 (type2->t & VT_BTYPE) == VT_VOID)
1681 return;
1682 tmp_type1 = *type1;
1683 tmp_type2 = *type2;
1684 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1685 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1686 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1687 /* gcc-like error if '-' is used */
1688 if (op == '-')
1689 goto invalid_operands;
1690 else
1691 tcc_warning("comparison of distinct pointer types lacks a cast");
1695 /* generic gen_op: handles types problems */
1696 ST_FUNC void gen_op(int op)
1698 int u, t1, t2, bt1, bt2, t;
1699 CType type1;
1701 t1 = vtop[-1].type.t;
1702 t2 = vtop[0].type.t;
1703 bt1 = t1 & VT_BTYPE;
1704 bt2 = t2 & VT_BTYPE;
1706 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1707 /* at least one operand is a pointer */
1708 /* relationnal op: must be both pointers */
1709 if (op >= TOK_ULT && op <= TOK_LOR) {
1710 check_comparison_pointer_types(vtop - 1, vtop, op);
1711 /* pointers are handled are unsigned */
1712 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1713 t = VT_LLONG | VT_UNSIGNED;
1714 #else
1715 t = VT_INT | VT_UNSIGNED;
1716 #endif
1717 goto std_op;
1719 /* if both pointers, then it must be the '-' op */
1720 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1721 if (op != '-')
1722 tcc_error("cannot use pointers here");
1723 check_comparison_pointer_types(vtop - 1, vtop, op);
1724 /* XXX: check that types are compatible */
1725 if (vtop[-1].type.t & VT_VLA) {
1726 vla_runtime_pointed_size(&vtop[-1].type);
1727 } else {
1728 vpushi(pointed_size(&vtop[-1].type));
1730 vrott(3);
1731 gen_opic(op);
1732 /* set to integer type */
1733 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1734 vtop->type.t = VT_LLONG;
1735 #else
1736 vtop->type.t = VT_INT;
1737 #endif
1738 vswap();
1739 gen_op(TOK_PDIV);
1740 } else {
1741 /* exactly one pointer : must be '+' or '-'. */
1742 if (op != '-' && op != '+')
1743 tcc_error("cannot use pointers here");
1744 /* Put pointer as first operand */
1745 if (bt2 == VT_PTR) {
1746 vswap();
1747 swap(&t1, &t2);
1749 type1 = vtop[-1].type;
1750 type1.t &= ~VT_ARRAY;
1751 if (vtop[-1].type.t & VT_VLA)
1752 vla_runtime_pointed_size(&vtop[-1].type);
1753 else {
1754 u = pointed_size(&vtop[-1].type);
1755 if (u < 0)
1756 tcc_error("unknown array element size");
1757 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1758 vpushll(u);
1759 #else
1760 /* XXX: cast to int ? (long long case) */
1761 vpushi(u);
1762 #endif
1764 gen_op('*');
1765 #if 0
1766 /* #ifdef CONFIG_TCC_BCHECK
1767 The main reason to removing this code:
1768 #include <stdio.h>
1769 int main ()
1771 int v[10];
1772 int i = 10;
1773 int j = 9;
1774 fprintf(stderr, "v+i-j = %p\n", v+i-j);
1775 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
1777 When this code is on. then the output looks like
1778 v+i-j = 0xfffffffe
1779 v+(i-j) = 0xbff84000
1781 /* if evaluating constant expression, no code should be
1782 generated, so no bound check */
1783 if (tcc_state->do_bounds_check && !const_wanted) {
1784 /* if bounded pointers, we generate a special code to
1785 test bounds */
1786 if (op == '-') {
1787 vpushi(0);
1788 vswap();
1789 gen_op('-');
1791 gen_bounded_ptr_add();
1792 } else
1793 #endif
1795 gen_opic(op);
1797 /* put again type if gen_opic() swaped operands */
1798 vtop->type = type1;
1800 } else if (is_float(bt1) || is_float(bt2)) {
1801 /* compute bigger type and do implicit casts */
1802 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1803 t = VT_LDOUBLE;
1804 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1805 t = VT_DOUBLE;
1806 } else {
1807 t = VT_FLOAT;
1809 /* floats can only be used for a few operations */
1810 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1811 (op < TOK_ULT || op > TOK_GT))
1812 tcc_error("invalid operands for binary operation");
1813 goto std_op;
1814 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1815 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1816 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1817 t |= VT_UNSIGNED;
1818 goto std_op;
1819 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1820 /* cast to biggest op */
1821 t = VT_LLONG;
1822 /* convert to unsigned if it does not fit in a long long */
1823 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1824 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1825 t |= VT_UNSIGNED;
1826 goto std_op;
1827 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1828 tcc_error("comparison of struct");
1829 } else {
1830 /* integer operations */
1831 t = VT_INT;
1832 /* convert to unsigned if it does not fit in an integer */
1833 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1834 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1835 t |= VT_UNSIGNED;
1836 std_op:
1837 /* XXX: currently, some unsigned operations are explicit, so
1838 we modify them here */
1839 if (t & VT_UNSIGNED) {
1840 if (op == TOK_SAR)
1841 op = TOK_SHR;
1842 else if (op == '/')
1843 op = TOK_UDIV;
1844 else if (op == '%')
1845 op = TOK_UMOD;
1846 else if (op == TOK_LT)
1847 op = TOK_ULT;
1848 else if (op == TOK_GT)
1849 op = TOK_UGT;
1850 else if (op == TOK_LE)
1851 op = TOK_ULE;
1852 else if (op == TOK_GE)
1853 op = TOK_UGE;
1855 vswap();
1856 type1.t = t;
1857 gen_cast(&type1);
1858 vswap();
1859 /* special case for shifts and long long: we keep the shift as
1860 an integer */
1861 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1862 type1.t = VT_INT;
1863 gen_cast(&type1);
1864 if (is_float(t))
1865 gen_opif(op);
1866 else
1867 gen_opic(op);
1868 if (op >= TOK_ULT && op <= TOK_GT) {
1869 /* relationnal op: the result is an int */
1870 vtop->type.t = VT_INT;
1871 } else {
1872 vtop->type.t = t;
1875 // Make sure that we have converted to an rvalue:
1876 if (vtop->r & VT_LVAL && !nocode_wanted)
1877 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
1880 #ifndef TCC_TARGET_ARM
1881 /* generic itof for unsigned long long case */
1882 static void gen_cvt_itof1(int t)
1884 #ifdef TCC_TARGET_ARM64
1885 gen_cvt_itof(t);
1886 #else
1887 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1888 (VT_LLONG | VT_UNSIGNED)) {
1890 if (t == VT_FLOAT)
1891 vpush_global_sym(&func_old_type, TOK___floatundisf);
1892 #if LDOUBLE_SIZE != 8
1893 else if (t == VT_LDOUBLE)
1894 vpush_global_sym(&func_old_type, TOK___floatundixf);
1895 #endif
1896 else
1897 vpush_global_sym(&func_old_type, TOK___floatundidf);
1898 vrott(2);
1899 gfunc_call(1);
1900 vpushi(0);
1901 vtop->r = reg_fret(t);
1902 } else {
1903 gen_cvt_itof(t);
1905 #endif
1907 #endif
1909 /* generic ftoi for unsigned long long case */
1910 static void gen_cvt_ftoi1(int t)
1912 #ifdef TCC_TARGET_ARM64
1913 gen_cvt_ftoi(t);
1914 #else
1915 int st;
1917 if (t == (VT_LLONG | VT_UNSIGNED)) {
1918 /* not handled natively */
1919 st = vtop->type.t & VT_BTYPE;
1920 if (st == VT_FLOAT)
1921 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1922 #if LDOUBLE_SIZE != 8
1923 else if (st == VT_LDOUBLE)
1924 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1925 #endif
1926 else
1927 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1928 vrott(2);
1929 gfunc_call(1);
1930 vpushi(0);
1931 vtop->r = REG_IRET;
1932 vtop->r2 = REG_LRET;
1933 } else {
1934 gen_cvt_ftoi(t);
1936 #endif
1939 /* force char or short cast */
1940 static void force_charshort_cast(int t)
1942 int bits, dbt;
1943 dbt = t & VT_BTYPE;
1944 /* XXX: add optimization if lvalue : just change type and offset */
1945 if (dbt == VT_BYTE)
1946 bits = 8;
1947 else
1948 bits = 16;
1949 if (t & VT_UNSIGNED) {
1950 vpushi((1 << bits) - 1);
1951 gen_op('&');
1952 } else {
1953 bits = 32 - bits;
1954 vpushi(bits);
1955 gen_op(TOK_SHL);
1956 /* result must be signed or the SAR is converted to an SHL
1957 This was not the case when "t" was a signed short
1958 and the last value on the stack was an unsigned int */
1959 vtop->type.t &= ~VT_UNSIGNED;
1960 vpushi(bits);
1961 gen_op(TOK_SAR);
1965 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1966 static void gen_cast(CType *type)
1968 int sbt, dbt, sf, df, c, p;
1970 /* special delayed cast for char/short */
1971 /* XXX: in some cases (multiple cascaded casts), it may still
1972 be incorrect */
1973 if (vtop->r & VT_MUSTCAST) {
1974 vtop->r &= ~VT_MUSTCAST;
1975 force_charshort_cast(vtop->type.t);
1978 /* bitfields first get cast to ints */
1979 if (vtop->type.t & VT_BITFIELD && !nocode_wanted) {
1980 gv(RC_INT);
1983 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1984 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1986 if (sbt != dbt) {
1987 sf = is_float(sbt);
1988 df = is_float(dbt);
1989 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1990 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1991 if (c) {
1992 /* constant case: we can do it now */
1993 /* XXX: in ISOC, cannot do it if error in convert */
1994 if (sbt == VT_FLOAT)
1995 vtop->c.ld = vtop->c.f;
1996 else if (sbt == VT_DOUBLE)
1997 vtop->c.ld = vtop->c.d;
1999 if (df) {
2000 if ((sbt & VT_BTYPE) == VT_LLONG) {
2001 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
2002 vtop->c.ld = vtop->c.i;
2003 else
2004 vtop->c.ld = -(long double)-vtop->c.i;
2005 } else if(!sf) {
2006 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
2007 vtop->c.ld = (uint32_t)vtop->c.i;
2008 else
2009 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
2012 if (dbt == VT_FLOAT)
2013 vtop->c.f = (float)vtop->c.ld;
2014 else if (dbt == VT_DOUBLE)
2015 vtop->c.d = (double)vtop->c.ld;
2016 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
2017 vtop->c.i = vtop->c.ld;
2018 } else if (sf && dbt == VT_BOOL) {
2019 vtop->c.i = (vtop->c.ld != 0);
2020 } else {
2021 if(sf)
2022 vtop->c.i = vtop->c.ld;
2023 else if (sbt == (VT_LLONG|VT_UNSIGNED))
2025 else if (sbt & VT_UNSIGNED)
2026 vtop->c.i = (uint32_t)vtop->c.i;
2027 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2028 else if (sbt == VT_PTR)
2030 #endif
2031 else if (sbt != VT_LLONG)
2032 vtop->c.i = ((uint32_t)vtop->c.i |
2033 -(vtop->c.i & 0x80000000));
2035 if (dbt == (VT_LLONG|VT_UNSIGNED))
2037 else if (dbt == VT_BOOL)
2038 vtop->c.i = (vtop->c.i != 0);
2039 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2040 else if (dbt == VT_PTR)
2042 #endif
2043 else if (dbt != VT_LLONG) {
2044 uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
2045 (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
2046 0xffffffff);
2047 vtop->c.i &= m;
2048 if (!(dbt & VT_UNSIGNED))
2049 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
2052 } else if (p && dbt == VT_BOOL) {
2053 vtop->r = VT_CONST;
2054 vtop->c.i = 1;
2055 } else if (!nocode_wanted) {
2056 /* non constant case: generate code */
2057 if (sf && df) {
2058 /* convert from fp to fp */
2059 gen_cvt_ftof(dbt);
2060 } else if (df) {
2061 /* convert int to fp */
2062 gen_cvt_itof1(dbt);
2063 } else if (sf) {
2064 /* convert fp to int */
2065 if (dbt == VT_BOOL) {
2066 vpushi(0);
2067 gen_op(TOK_NE);
2068 } else {
2069 /* we handle char/short/etc... with generic code */
2070 if (dbt != (VT_INT | VT_UNSIGNED) &&
2071 dbt != (VT_LLONG | VT_UNSIGNED) &&
2072 dbt != VT_LLONG)
2073 dbt = VT_INT;
2074 gen_cvt_ftoi1(dbt);
2075 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2076 /* additional cast for char/short... */
2077 vtop->type.t = dbt;
2078 gen_cast(type);
2081 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
2082 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2083 if ((sbt & VT_BTYPE) != VT_LLONG && !nocode_wanted) {
2084 /* scalar to long long */
2085 /* machine independent conversion */
2086 gv(RC_INT);
2087 /* generate high word */
2088 if (sbt == (VT_INT | VT_UNSIGNED)) {
2089 vpushi(0);
2090 gv(RC_INT);
2091 } else {
2092 if (sbt == VT_PTR) {
2093 /* cast from pointer to int before we apply
2094 shift operation, which pointers don't support*/
2095 gen_cast(&int_type);
2097 gv_dup();
2098 vpushi(31);
2099 gen_op(TOK_SAR);
2101 /* patch second register */
2102 vtop[-1].r2 = vtop->r;
2103 vpop();
2105 #else
2106 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2107 (dbt & VT_BTYPE) == VT_PTR ||
2108 (dbt & VT_BTYPE) == VT_FUNC) {
2109 if ((sbt & VT_BTYPE) != VT_LLONG &&
2110 (sbt & VT_BTYPE) != VT_PTR &&
2111 (sbt & VT_BTYPE) != VT_FUNC && !nocode_wanted) {
2112 /* need to convert from 32bit to 64bit */
2113 gv(RC_INT);
2114 if (sbt != (VT_INT | VT_UNSIGNED)) {
2115 #if defined(TCC_TARGET_ARM64)
2116 gen_cvt_sxtw();
2117 #elif defined(TCC_TARGET_X86_64)
2118 int r = gv(RC_INT);
2119 /* x86_64 specific: movslq */
2120 o(0x6348);
2121 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2122 #else
2123 #error
2124 #endif
2127 #endif
2128 } else if (dbt == VT_BOOL) {
2129 /* scalar to bool */
2130 vpushi(0);
2131 gen_op(TOK_NE);
2132 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2133 (dbt & VT_BTYPE) == VT_SHORT) {
2134 if (sbt == VT_PTR) {
2135 vtop->type.t = VT_INT;
2136 tcc_warning("nonportable conversion from pointer to char/short");
2138 force_charshort_cast(dbt);
2139 } else if ((dbt & VT_BTYPE) == VT_INT) {
2140 /* scalar to int */
2141 if (sbt == VT_LLONG && !nocode_wanted) {
2142 /* from long long: just take low order word */
2143 lexpand();
2144 vpop();
2146 /* if lvalue and single word type, nothing to do because
2147 the lvalue already contains the real type size (see
2148 VT_LVAL_xxx constants) */
2151 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2152 /* if we are casting between pointer types,
2153 we must update the VT_LVAL_xxx size */
2154 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2155 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2157 vtop->type = *type;
2160 /* return type size as known at compile time. Put alignment at 'a' */
2161 ST_FUNC int type_size(CType *type, int *a)
2163 Sym *s;
2164 int bt;
2166 bt = type->t & VT_BTYPE;
2167 if (bt == VT_STRUCT) {
2168 /* struct/union */
2169 s = type->ref;
2170 *a = s->r;
2171 return s->c;
2172 } else if (bt == VT_PTR) {
2173 if (type->t & VT_ARRAY) {
2174 int ts;
2176 s = type->ref;
2177 ts = type_size(&s->type, a);
2179 if (ts < 0 && s->c < 0)
2180 ts = -ts;
2182 return ts * s->c;
2183 } else {
2184 *a = PTR_SIZE;
2185 return PTR_SIZE;
2187 } else if (bt == VT_LDOUBLE) {
2188 *a = LDOUBLE_ALIGN;
2189 return LDOUBLE_SIZE;
2190 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2191 #ifdef TCC_TARGET_I386
2192 #ifdef TCC_TARGET_PE
2193 *a = 8;
2194 #else
2195 *a = 4;
2196 #endif
2197 #elif defined(TCC_TARGET_ARM)
2198 #ifdef TCC_ARM_EABI
2199 *a = 8;
2200 #else
2201 *a = 4;
2202 #endif
2203 #else
2204 *a = 8;
2205 #endif
2206 return 8;
2207 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2208 *a = 4;
2209 return 4;
2210 } else if (bt == VT_SHORT) {
2211 *a = 2;
2212 return 2;
2213 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2214 *a = 8;
2215 return 16;
2216 } else {
2217 /* char, void, function, _Bool */
2218 *a = 1;
2219 return 1;
2223 /* push type size as known at runtime time on top of value stack. Put
2224 alignment at 'a' */
2225 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2227 if (type->t & VT_VLA) {
2228 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2229 } else {
2230 vpushi(type_size(type, a));
2234 static void vla_sp_restore(void) {
2235 if (vlas_in_scope) {
2236 gen_vla_sp_restore(vla_sp_loc);
2240 static void vla_sp_restore_root(void) {
2241 if (vlas_in_scope) {
2242 gen_vla_sp_restore(vla_sp_root_loc);
2246 /* return the pointed type of t */
2247 static inline CType *pointed_type(CType *type)
2249 return &type->ref->type;
2252 /* modify type so that its it is a pointer to type. */
2253 ST_FUNC void mk_pointer(CType *type)
2255 Sym *s;
2256 s = sym_push(SYM_FIELD, type, 0, -1);
2257 type->t = VT_PTR | (type->t & ~VT_TYPE);
2258 type->ref = s;
2261 /* compare function types. OLD functions match any new functions */
2262 static int is_compatible_func(CType *type1, CType *type2)
2264 Sym *s1, *s2;
2266 s1 = type1->ref;
2267 s2 = type2->ref;
2268 if (!is_compatible_types(&s1->type, &s2->type))
2269 return 0;
2270 /* check func_call */
2271 if (s1->a.func_call != s2->a.func_call)
2272 return 0;
2273 /* XXX: not complete */
2274 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2275 return 1;
2276 if (s1->c != s2->c)
2277 return 0;
2278 while (s1 != NULL) {
2279 if (s2 == NULL)
2280 return 0;
2281 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2282 return 0;
2283 s1 = s1->next;
2284 s2 = s2->next;
2286 if (s2)
2287 return 0;
2288 return 1;
2291 /* return true if type1 and type2 are the same. If unqualified is
2292 true, qualifiers on the types are ignored.
2294 - enums are not checked as gcc __builtin_types_compatible_p ()
2296 static int compare_types(CType *type1, CType *type2, int unqualified)
2298 int bt1, t1, t2;
2300 t1 = type1->t & VT_TYPE;
2301 t2 = type2->t & VT_TYPE;
2302 if (unqualified) {
2303 /* strip qualifiers before comparing */
2304 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2305 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2307 /* Default Vs explicit signedness only matters for char */
2308 if ((t1 & VT_BTYPE) != VT_BYTE) {
2309 t1 &= ~VT_DEFSIGN;
2310 t2 &= ~VT_DEFSIGN;
2312 /* XXX: bitfields ? */
2313 if (t1 != t2)
2314 return 0;
2315 /* test more complicated cases */
2316 bt1 = t1 & VT_BTYPE;
2317 if (bt1 == VT_PTR) {
2318 type1 = pointed_type(type1);
2319 type2 = pointed_type(type2);
2320 return is_compatible_types(type1, type2);
2321 } else if (bt1 == VT_STRUCT) {
2322 return (type1->ref == type2->ref);
2323 } else if (bt1 == VT_FUNC) {
2324 return is_compatible_func(type1, type2);
2325 } else {
2326 return 1;
2330 /* return true if type1 and type2 are exactly the same (including
2331 qualifiers).
2333 static int is_compatible_types(CType *type1, CType *type2)
2335 return compare_types(type1,type2,0);
2338 /* return true if type1 and type2 are the same (ignoring qualifiers).
2340 static int is_compatible_parameter_types(CType *type1, CType *type2)
2342 return compare_types(type1,type2,1);
2345 /* print a type. If 'varstr' is not NULL, then the variable is also
2346 printed in the type */
2347 /* XXX: union */
2348 /* XXX: add array and function pointers */
2349 static void type_to_str(char *buf, int buf_size,
2350 CType *type, const char *varstr)
2352 int bt, v, t;
2353 Sym *s, *sa;
2354 char buf1[256];
2355 const char *tstr;
2357 t = type->t & VT_TYPE;
2358 bt = t & VT_BTYPE;
2359 buf[0] = '\0';
2360 if (t & VT_CONSTANT)
2361 pstrcat(buf, buf_size, "const ");
2362 if (t & VT_VOLATILE)
2363 pstrcat(buf, buf_size, "volatile ");
2364 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2365 pstrcat(buf, buf_size, "unsigned ");
2366 else if (t & VT_DEFSIGN)
2367 pstrcat(buf, buf_size, "signed ");
2368 switch(bt) {
2369 case VT_VOID:
2370 tstr = "void";
2371 goto add_tstr;
2372 case VT_BOOL:
2373 tstr = "_Bool";
2374 goto add_tstr;
2375 case VT_BYTE:
2376 tstr = "char";
2377 goto add_tstr;
2378 case VT_SHORT:
2379 tstr = "short";
2380 goto add_tstr;
2381 case VT_INT:
2382 tstr = "int";
2383 goto add_tstr;
2384 case VT_LONG:
2385 tstr = "long";
2386 goto add_tstr;
2387 case VT_LLONG:
2388 tstr = "long long";
2389 goto add_tstr;
2390 case VT_FLOAT:
2391 tstr = "float";
2392 goto add_tstr;
2393 case VT_DOUBLE:
2394 tstr = "double";
2395 goto add_tstr;
2396 case VT_LDOUBLE:
2397 tstr = "long double";
2398 add_tstr:
2399 pstrcat(buf, buf_size, tstr);
2400 break;
2401 case VT_ENUM:
2402 case VT_STRUCT:
2403 if (bt == VT_STRUCT)
2404 tstr = "struct ";
2405 else
2406 tstr = "enum ";
2407 pstrcat(buf, buf_size, tstr);
2408 v = type->ref->v & ~SYM_STRUCT;
2409 if (v >= SYM_FIRST_ANOM)
2410 pstrcat(buf, buf_size, "<anonymous>");
2411 else
2412 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2413 break;
2414 case VT_FUNC:
2415 s = type->ref;
2416 type_to_str(buf, buf_size, &s->type, varstr);
2417 pstrcat(buf, buf_size, "(");
2418 sa = s->next;
2419 while (sa != NULL) {
2420 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2421 pstrcat(buf, buf_size, buf1);
2422 sa = sa->next;
2423 if (sa)
2424 pstrcat(buf, buf_size, ", ");
2426 pstrcat(buf, buf_size, ")");
2427 goto no_var;
2428 case VT_PTR:
2429 s = type->ref;
2430 if (t & VT_ARRAY) {
2431 snprintf(buf1, sizeof(buf1), "%s[%ld]", varstr ? varstr : "", s->c);
2432 type_to_str(buf, buf_size, &s->type, buf1);
2433 goto no_var;
2435 pstrcpy(buf1, sizeof(buf1), "*");
2436 if (t & VT_CONSTANT)
2437 pstrcat(buf1, buf_size, "const ");
2438 if (t & VT_VOLATILE)
2439 pstrcat(buf1, buf_size, "volatile ");
2440 if (varstr)
2441 pstrcat(buf1, sizeof(buf1), varstr);
2442 type_to_str(buf, buf_size, &s->type, buf1);
2443 goto no_var;
2445 if (varstr) {
2446 pstrcat(buf, buf_size, " ");
2447 pstrcat(buf, buf_size, varstr);
2449 no_var: ;
2452 /* verify type compatibility to store vtop in 'dt' type, and generate
2453 casts if needed. */
2454 static void gen_assign_cast(CType *dt)
2456 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2457 char buf1[256], buf2[256];
2458 int dbt, sbt;
2460 st = &vtop->type; /* source type */
2461 dbt = dt->t & VT_BTYPE;
2462 sbt = st->t & VT_BTYPE;
2463 if (sbt == VT_VOID || dbt == VT_VOID) {
2464 if (sbt == VT_VOID && dbt == VT_VOID)
2465 ; /*
2466 It is Ok if both are void
2467 A test program:
2468 void func1() {}
2469 void func2() {
2470 return func1();
2472 gcc accepts this program
2474 else
2475 tcc_error("cannot cast from/to void");
2477 if (dt->t & VT_CONSTANT)
2478 tcc_warning("assignment of read-only location");
2479 switch(dbt) {
2480 case VT_PTR:
2481 /* special cases for pointers */
2482 /* '0' can also be a pointer */
2483 if (is_null_pointer(vtop))
2484 goto type_ok;
2485 /* accept implicit pointer to integer cast with warning */
2486 if (is_integer_btype(sbt)) {
2487 tcc_warning("assignment makes pointer from integer without a cast");
2488 goto type_ok;
2490 type1 = pointed_type(dt);
2491 /* a function is implicitely a function pointer */
2492 if (sbt == VT_FUNC) {
2493 if ((type1->t & VT_BTYPE) != VT_VOID &&
2494 !is_compatible_types(pointed_type(dt), st))
2495 tcc_warning("assignment from incompatible pointer type");
2496 goto type_ok;
2498 if (sbt != VT_PTR)
2499 goto error;
2500 type2 = pointed_type(st);
2501 if ((type1->t & VT_BTYPE) == VT_VOID ||
2502 (type2->t & VT_BTYPE) == VT_VOID) {
2503 /* void * can match anything */
2504 } else {
2505 /* exact type match, except for unsigned */
2506 tmp_type1 = *type1;
2507 tmp_type2 = *type2;
2508 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2509 VT_VOLATILE);
2510 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2511 VT_VOLATILE);
2512 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2513 tcc_warning("assignment from incompatible pointer type");
2515 /* check const and volatile */
2516 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2517 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2518 tcc_warning("assignment discards qualifiers from pointer target type");
2519 break;
2520 case VT_BYTE:
2521 case VT_SHORT:
2522 case VT_INT:
2523 case VT_LLONG:
2524 if (sbt == VT_PTR || sbt == VT_FUNC) {
2525 tcc_warning("assignment makes integer from pointer without a cast");
2527 /* XXX: more tests */
2528 break;
2529 case VT_STRUCT:
2530 tmp_type1 = *dt;
2531 tmp_type2 = *st;
2532 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2533 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2534 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2535 error:
2536 type_to_str(buf1, sizeof(buf1), st, NULL);
2537 type_to_str(buf2, sizeof(buf2), dt, NULL);
2538 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2540 break;
2542 type_ok:
2543 gen_cast(dt);
2546 /* store vtop in lvalue pushed on stack */
2547 ST_FUNC void vstore(void)
2549 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2551 ft = vtop[-1].type.t;
2552 sbt = vtop->type.t & VT_BTYPE;
2553 dbt = ft & VT_BTYPE;
2554 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2555 (sbt == VT_INT && dbt == VT_SHORT))
2556 && !(vtop->type.t & VT_BITFIELD)) {
2557 /* optimize char/short casts */
2558 delayed_cast = VT_MUSTCAST;
2559 vtop->type.t = (ft & VT_TYPE & ~VT_BITFIELD &
2560 ((1 << VT_STRUCT_SHIFT) - 1));
2561 /* XXX: factorize */
2562 if (ft & VT_CONSTANT)
2563 tcc_warning("assignment of read-only location");
2564 } else {
2565 delayed_cast = 0;
2566 if (!(ft & VT_BITFIELD))
2567 gen_assign_cast(&vtop[-1].type);
2570 if (sbt == VT_STRUCT) {
2571 /* if structure, only generate pointer */
2572 /* structure assignment : generate memcpy */
2573 /* XXX: optimize if small size */
2574 if (!nocode_wanted) {
2575 size = type_size(&vtop->type, &align);
2577 /* destination */
2578 vswap();
2579 vtop->type.t = VT_PTR;
2580 gaddrof();
2582 /* address of memcpy() */
2583 #ifdef TCC_ARM_EABI
2584 if(!(align & 7))
2585 vpush_global_sym(&func_old_type, TOK_memcpy8);
2586 else if(!(align & 3))
2587 vpush_global_sym(&func_old_type, TOK_memcpy4);
2588 else
2589 #endif
2590 /* Use memmove, rather than memcpy, as dest and src may be same: */
2591 vpush_global_sym(&func_old_type, TOK_memmove);
2593 vswap();
2594 /* source */
2595 vpushv(vtop - 2);
2596 vtop->type.t = VT_PTR;
2597 gaddrof();
2598 /* type size */
2599 vpushi(size);
2600 gfunc_call(3);
2601 } else {
2602 vswap();
2603 vpop();
2605 /* leave source on stack */
2606 } else if (ft & VT_BITFIELD) {
2607 /* bitfield store handling */
2609 /* save lvalue as expression result (example: s.b = s.a = n;) */
2610 vdup(), vtop[-1] = vtop[-2];
2612 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2613 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2614 /* remove bit field info to avoid loops */
2615 vtop[-1].type.t = ft & ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
2617 if((ft & VT_BTYPE) == VT_BOOL) {
2618 gen_cast(&vtop[-1].type);
2619 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2622 /* duplicate destination */
2623 vdup();
2624 vtop[-1] = vtop[-2];
2626 /* mask and shift source */
2627 if((ft & VT_BTYPE) != VT_BOOL) {
2628 if((ft & VT_BTYPE) == VT_LLONG) {
2629 vpushll((1ULL << bit_size) - 1ULL);
2630 } else {
2631 vpushi((1 << bit_size) - 1);
2633 gen_op('&');
2635 vpushi(bit_pos);
2636 gen_op(TOK_SHL);
2637 /* load destination, mask and or with source */
2638 vswap();
2639 if((ft & VT_BTYPE) == VT_LLONG) {
2640 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2641 } else {
2642 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2644 gen_op('&');
2645 gen_op('|');
2646 /* store result */
2647 vstore();
2648 /* ... and discard */
2649 vpop();
2651 } else {
2652 if (!nocode_wanted) {
2653 #ifdef CONFIG_TCC_BCHECK
2654 /* bound check case */
2655 if (vtop[-1].r & VT_MUSTBOUND) {
2656 vswap();
2657 gbound();
2658 vswap();
2660 #endif
2661 rc = RC_INT;
2662 if (is_float(ft)) {
2663 rc = RC_FLOAT;
2664 #ifdef TCC_TARGET_X86_64
2665 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2666 rc = RC_ST0;
2667 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2668 rc = RC_FRET;
2670 #endif
2672 r = gv(rc); /* generate value */
2673 /* if lvalue was saved on stack, must read it */
2674 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2675 SValue sv;
2676 t = get_reg(RC_INT);
2677 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2678 sv.type.t = VT_PTR;
2679 #else
2680 sv.type.t = VT_INT;
2681 #endif
2682 sv.r = VT_LOCAL | VT_LVAL;
2683 sv.c.i = vtop[-1].c.i;
2684 load(t, &sv);
2685 vtop[-1].r = t | VT_LVAL;
2687 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2688 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2689 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2690 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2691 #else
2692 if ((ft & VT_BTYPE) == VT_LLONG) {
2693 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2694 #endif
2695 vtop[-1].type.t = load_type;
2696 store(r, vtop - 1);
2697 vswap();
2698 /* convert to int to increment easily */
2699 vtop->type.t = addr_type;
2700 gaddrof();
2701 vpushi(load_size);
2702 gen_op('+');
2703 vtop->r |= VT_LVAL;
2704 vswap();
2705 vtop[-1].type.t = load_type;
2706 /* XXX: it works because r2 is spilled last ! */
2707 store(vtop->r2, vtop - 1);
2708 } else {
2709 store(r, vtop - 1);
2712 vswap();
2713 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2714 vtop->r |= delayed_cast;
2718 /* post defines POST/PRE add. c is the token ++ or -- */
2719 ST_FUNC void inc(int post, int c)
2721 test_lvalue();
2722 vdup(); /* save lvalue */
2723 if (post) {
2724 if (!nocode_wanted)
2725 gv_dup(); /* duplicate value */
2726 else
2727 vdup(); /* duplicate value */
2728 vrotb(3);
2729 vrotb(3);
2731 /* add constant */
2732 vpushi(c - TOK_MID);
2733 gen_op('+');
2734 vstore(); /* store value */
2735 if (post)
2736 vpop(); /* if post op, return saved value */
2739 /* Parse GNUC __attribute__ extension. Currently, the following
2740 extensions are recognized:
2741 - aligned(n) : set data/function alignment.
2742 - packed : force data alignment to 1
2743 - section(x) : generate data/code in this section.
2744 - unused : currently ignored, but may be used someday.
2745 - regparm(n) : pass function parameters in registers (i386 only)
2747 static void parse_attribute(AttributeDef *ad)
2749 int t, n;
2751 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2752 next();
2753 skip('(');
2754 skip('(');
2755 while (tok != ')') {
2756 if (tok < TOK_IDENT)
2757 expect("attribute name");
2758 t = tok;
2759 next();
2760 switch(t) {
2761 case TOK_SECTION1:
2762 case TOK_SECTION2:
2763 skip('(');
2764 if (tok != TOK_STR)
2765 expect("section name");
2766 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2767 next();
2768 skip(')');
2769 break;
2770 case TOK_ALIAS1:
2771 case TOK_ALIAS2:
2772 skip('(');
2773 if (tok != TOK_STR)
2774 expect("alias(\"target\")");
2775 ad->alias_target = /* save string as token, for later */
2776 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2777 next();
2778 skip(')');
2779 break;
2780 case TOK_VISIBILITY1:
2781 case TOK_VISIBILITY2:
2782 skip('(');
2783 if (tok != TOK_STR)
2784 expect("visibility(\"default|hidden|internal|protected\")");
2785 if (!strcmp (tokc.cstr->data, "default"))
2786 ad->a.visibility = STV_DEFAULT;
2787 else if (!strcmp (tokc.cstr->data, "hidden"))
2788 ad->a.visibility = STV_HIDDEN;
2789 else if (!strcmp (tokc.cstr->data, "internal"))
2790 ad->a.visibility = STV_INTERNAL;
2791 else if (!strcmp (tokc.cstr->data, "protected"))
2792 ad->a.visibility = STV_PROTECTED;
2793 else
2794 expect("visibility(\"default|hidden|internal|protected\")");
2795 next();
2796 skip(')');
2797 break;
2798 case TOK_ALIGNED1:
2799 case TOK_ALIGNED2:
2800 if (tok == '(') {
2801 next();
2802 n = expr_const();
2803 if (n <= 0 || (n & (n - 1)) != 0)
2804 tcc_error("alignment must be a positive power of two");
2805 skip(')');
2806 } else {
2807 n = MAX_ALIGN;
2809 ad->a.aligned = n;
2810 break;
2811 case TOK_PACKED1:
2812 case TOK_PACKED2:
2813 ad->a.packed = 1;
2814 break;
2815 case TOK_WEAK1:
2816 case TOK_WEAK2:
2817 ad->a.weak = 1;
2818 break;
2819 case TOK_UNUSED1:
2820 case TOK_UNUSED2:
2821 /* currently, no need to handle it because tcc does not
2822 track unused objects */
2823 break;
2824 case TOK_NORETURN1:
2825 case TOK_NORETURN2:
2826 /* currently, no need to handle it because tcc does not
2827 track unused objects */
2828 break;
2829 case TOK_CDECL1:
2830 case TOK_CDECL2:
2831 case TOK_CDECL3:
2832 ad->a.func_call = FUNC_CDECL;
2833 break;
2834 case TOK_STDCALL1:
2835 case TOK_STDCALL2:
2836 case TOK_STDCALL3:
2837 ad->a.func_call = FUNC_STDCALL;
2838 break;
2839 #ifdef TCC_TARGET_I386
2840 case TOK_REGPARM1:
2841 case TOK_REGPARM2:
2842 skip('(');
2843 n = expr_const();
2844 if (n > 3)
2845 n = 3;
2846 else if (n < 0)
2847 n = 0;
2848 if (n > 0)
2849 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
2850 skip(')');
2851 break;
2852 case TOK_FASTCALL1:
2853 case TOK_FASTCALL2:
2854 case TOK_FASTCALL3:
2855 ad->a.func_call = FUNC_FASTCALLW;
2856 break;
2857 #endif
2858 case TOK_MODE:
2859 skip('(');
2860 switch(tok) {
2861 case TOK_MODE_DI:
2862 ad->a.mode = VT_LLONG + 1;
2863 break;
2864 case TOK_MODE_HI:
2865 ad->a.mode = VT_SHORT + 1;
2866 break;
2867 case TOK_MODE_SI:
2868 ad->a.mode = VT_INT + 1;
2869 break;
2870 default:
2871 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2872 break;
2874 next();
2875 skip(')');
2876 break;
2877 case TOK_DLLEXPORT:
2878 ad->a.func_export = 1;
2879 break;
2880 case TOK_DLLIMPORT:
2881 ad->a.func_import = 1;
2882 break;
2883 default:
2884 if (tcc_state->warn_unsupported)
2885 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2886 /* skip parameters */
2887 if (tok == '(') {
2888 int parenthesis = 0;
2889 do {
2890 if (tok == '(')
2891 parenthesis++;
2892 else if (tok == ')')
2893 parenthesis--;
2894 next();
2895 } while (parenthesis && tok != -1);
2897 break;
2899 if (tok != ',')
2900 break;
2901 next();
2903 skip(')');
2904 skip(')');
2908 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2909 static void struct_decl(CType *type, int u, int tdef)
2911 int a, v, size, align, maxalign, c, offset, flexible;
2912 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2913 Sym *s, *ss, *ass, **ps;
2914 AttributeDef ad;
2915 CType type1, btype;
2917 a = tok; /* save decl type */
2918 next();
2919 if (tok != '{') {
2920 v = tok;
2921 next();
2922 /* struct already defined ? return it */
2923 if (v < TOK_IDENT)
2924 expect("struct/union/enum name");
2925 s = struct_find(v);
2926 if (s) {
2927 if (s->type.t != a)
2928 tcc_error("invalid type");
2929 goto do_decl;
2930 } else if (tok >= TOK_IDENT && !tdef)
2931 tcc_error("unknown struct/union/enum");
2932 } else {
2933 v = anon_sym++;
2935 type1.t = a;
2936 type1.ref = NULL;
2937 /* we put an undefined size for struct/union */
2938 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2939 s->r = 0; /* default alignment is zero as gcc */
2940 /* put struct/union/enum name in type */
2941 do_decl:
2942 type->t = u;
2943 type->ref = s;
2945 if (tok == '{') {
2946 next();
2947 if (s->c != -1)
2948 tcc_error("struct/union/enum already defined");
2949 /* cannot be empty */
2950 c = 0;
2951 /* non empty enums are not allowed */
2952 if (a == TOK_ENUM) {
2953 for(;;) {
2954 v = tok;
2955 if (v < TOK_UIDENT)
2956 expect("identifier");
2957 ss = sym_find(v);
2958 if (ss && !local_stack)
2959 tcc_error("redefinition of enumerator '%s'",
2960 get_tok_str(v, NULL));
2961 next();
2962 if (tok == '=') {
2963 next();
2964 c = expr_const();
2966 /* enum symbols have static storage */
2967 ss = sym_push(v, &int_type, VT_CONST, c);
2968 ss->type.t |= VT_STATIC;
2969 if (tok != ',')
2970 break;
2971 next();
2972 c++;
2973 /* NOTE: we accept a trailing comma */
2974 if (tok == '}')
2975 break;
2977 s->c = type_size(&int_type, &align);
2978 skip('}');
2979 } else {
2980 maxalign = 1;
2981 ps = &s->next;
2982 prevbt = VT_INT;
2983 bit_pos = 0;
2984 offset = 0;
2985 flexible = 0;
2986 while (tok != '}') {
2987 parse_btype(&btype, &ad);
2988 while (1) {
2989 if (flexible)
2990 tcc_error("flexible array member '%s' not at the end of struct",
2991 get_tok_str(v, NULL));
2992 bit_size = -1;
2993 v = 0;
2994 type1 = btype;
2995 if (tok != ':') {
2996 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2997 if (v == 0) {
2998 if ((type1.t & VT_BTYPE) != VT_STRUCT)
2999 expect("identifier");
3000 else {
3001 int v = btype.ref->v;
3002 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
3003 if (tcc_state->ms_extensions == 0)
3004 expect("identifier");
3008 if (type_size(&type1, &align) < 0) {
3009 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
3010 flexible = 1;
3011 else
3012 tcc_error("field '%s' has incomplete type",
3013 get_tok_str(v, NULL));
3015 if ((type1.t & VT_BTYPE) == VT_FUNC ||
3016 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
3017 tcc_error("invalid type for '%s'",
3018 get_tok_str(v, NULL));
3020 if (tok == ':') {
3021 next();
3022 bit_size = expr_const();
3023 /* XXX: handle v = 0 case for messages */
3024 if (bit_size < 0)
3025 tcc_error("negative width in bit-field '%s'",
3026 get_tok_str(v, NULL));
3027 if (v && bit_size == 0)
3028 tcc_error("zero width for bit-field '%s'",
3029 get_tok_str(v, NULL));
3031 size = type_size(&type1, &align);
3032 if (ad.a.aligned) {
3033 if (align < ad.a.aligned)
3034 align = ad.a.aligned;
3035 } else if (ad.a.packed) {
3036 align = 1;
3037 } else if (*tcc_state->pack_stack_ptr) {
3038 if (align > *tcc_state->pack_stack_ptr)
3039 align = *tcc_state->pack_stack_ptr;
3041 lbit_pos = 0;
3042 if (bit_size >= 0) {
3043 bt = type1.t & VT_BTYPE;
3044 if (bt != VT_INT &&
3045 bt != VT_BYTE &&
3046 bt != VT_SHORT &&
3047 bt != VT_BOOL &&
3048 bt != VT_ENUM &&
3049 bt != VT_LLONG)
3050 tcc_error("bitfields must have scalar type");
3051 bsize = size * 8;
3052 if (bit_size > bsize) {
3053 tcc_error("width of '%s' exceeds its type",
3054 get_tok_str(v, NULL));
3055 } else if (bit_size == bsize) {
3056 /* no need for bit fields */
3057 bit_pos = 0;
3058 } else if (bit_size == 0) {
3059 /* XXX: what to do if only padding in a
3060 structure ? */
3061 /* zero size: means to pad */
3062 bit_pos = 0;
3063 } else {
3064 /* we do not have enough room ?
3065 did the type change?
3066 is it a union? */
3067 if ((bit_pos + bit_size) > bsize ||
3068 bt != prevbt || a == TOK_UNION)
3069 bit_pos = 0;
3070 lbit_pos = bit_pos;
3071 /* XXX: handle LSB first */
3072 type1.t |= VT_BITFIELD |
3073 (bit_pos << VT_STRUCT_SHIFT) |
3074 (bit_size << (VT_STRUCT_SHIFT + 6));
3075 bit_pos += bit_size;
3077 prevbt = bt;
3078 } else {
3079 bit_pos = 0;
3081 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3082 /* add new memory data only if starting
3083 bit field */
3084 if (lbit_pos == 0) {
3085 if (a == TOK_STRUCT) {
3086 c = (c + align - 1) & -align;
3087 offset = c;
3088 if (size > 0)
3089 c += size;
3090 } else {
3091 offset = 0;
3092 if (size > c)
3093 c = size;
3095 if (align > maxalign)
3096 maxalign = align;
3098 #if 0
3099 printf("add field %s offset=%d",
3100 get_tok_str(v, NULL), offset);
3101 if (type1.t & VT_BITFIELD) {
3102 printf(" pos=%d size=%d",
3103 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3104 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3106 printf("\n");
3107 #endif
3109 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3110 ass = type1.ref;
3111 while ((ass = ass->next) != NULL) {
3112 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3113 *ps = ss;
3114 ps = &ss->next;
3116 } else if (v) {
3117 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3118 *ps = ss;
3119 ps = &ss->next;
3121 if (tok == ';' || tok == TOK_EOF)
3122 break;
3123 skip(',');
3125 skip(';');
3127 skip('}');
3128 /* store size and alignment */
3129 s->c = (c + maxalign - 1) & -maxalign;
3130 s->r = maxalign;
3135 /* return 1 if basic type is a type size (short, long, long long) */
3136 ST_FUNC int is_btype_size(int bt)
3138 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3141 /* return 0 if no type declaration. otherwise, return the basic type
3142 and skip it.
3144 static int parse_btype(CType *type, AttributeDef *ad)
3146 int t, u, bt_size, complete, type_found, typespec_found;
3147 Sym *s;
3148 CType type1;
3150 memset(ad, 0, sizeof(AttributeDef));
3151 complete = 0;
3152 type_found = 0;
3153 typespec_found = 0;
3154 t = 0;
3155 while(1) {
3156 switch(tok) {
3157 case TOK_EXTENSION:
3158 /* currently, we really ignore extension */
3159 next();
3160 continue;
3162 /* basic types */
3163 case TOK_CHAR:
3164 u = VT_BYTE;
3165 basic_type:
3166 next();
3167 basic_type1:
3168 if (complete)
3169 tcc_error("too many basic types");
3170 t |= u;
3171 bt_size = is_btype_size (u & VT_BTYPE);
3172 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3173 complete = 1;
3174 typespec_found = 1;
3175 break;
3176 case TOK_VOID:
3177 u = VT_VOID;
3178 goto basic_type;
3179 case TOK_SHORT:
3180 u = VT_SHORT;
3181 goto basic_type;
3182 case TOK_INT:
3183 u = VT_INT;
3184 goto basic_type;
3185 case TOK_LONG:
3186 next();
3187 if ((t & VT_BTYPE) == VT_DOUBLE) {
3188 #ifndef TCC_TARGET_PE
3189 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3190 #endif
3191 } else if ((t & VT_BTYPE) == VT_LONG) {
3192 t = (t & ~VT_BTYPE) | VT_LLONG;
3193 } else {
3194 u = VT_LONG;
3195 goto basic_type1;
3197 break;
3198 #ifdef TCC_TARGET_ARM64
3199 case TOK_UINT128:
3200 /* GCC's __uint128_t appears in some Linux header files. Make it a
3201 synonym for long double to get the size and alignment right. */
3202 u = VT_LDOUBLE;
3203 goto basic_type;
3204 #endif
3205 case TOK_BOOL:
3206 u = VT_BOOL;
3207 goto basic_type;
3208 case TOK_FLOAT:
3209 u = VT_FLOAT;
3210 goto basic_type;
3211 case TOK_DOUBLE:
3212 next();
3213 if ((t & VT_BTYPE) == VT_LONG) {
3214 #ifdef TCC_TARGET_PE
3215 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3216 #else
3217 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3218 #endif
3219 } else {
3220 u = VT_DOUBLE;
3221 goto basic_type1;
3223 break;
3224 case TOK_ENUM:
3225 struct_decl(&type1, VT_ENUM, t & (VT_TYPEDEF | VT_EXTERN));
3226 basic_type2:
3227 u = type1.t;
3228 type->ref = type1.ref;
3229 goto basic_type1;
3230 case TOK_STRUCT:
3231 case TOK_UNION:
3232 struct_decl(&type1, VT_STRUCT, t & (VT_TYPEDEF | VT_EXTERN));
3233 goto basic_type2;
3235 /* type modifiers */
3236 case TOK_CONST1:
3237 case TOK_CONST2:
3238 case TOK_CONST3:
3239 t |= VT_CONSTANT;
3240 next();
3241 break;
3242 case TOK_VOLATILE1:
3243 case TOK_VOLATILE2:
3244 case TOK_VOLATILE3:
3245 t |= VT_VOLATILE;
3246 next();
3247 break;
3248 case TOK_SIGNED1:
3249 case TOK_SIGNED2:
3250 case TOK_SIGNED3:
3251 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3252 tcc_error("signed and unsigned modifier");
3253 typespec_found = 1;
3254 t |= VT_DEFSIGN;
3255 next();
3256 break;
3257 case TOK_REGISTER:
3258 case TOK_AUTO:
3259 case TOK_RESTRICT1:
3260 case TOK_RESTRICT2:
3261 case TOK_RESTRICT3:
3262 next();
3263 break;
3264 case TOK_UNSIGNED:
3265 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3266 tcc_error("signed and unsigned modifier");
3267 t |= VT_DEFSIGN | VT_UNSIGNED;
3268 next();
3269 typespec_found = 1;
3270 break;
3272 /* storage */
3273 case TOK_EXTERN:
3274 t |= VT_EXTERN;
3275 next();
3276 break;
3277 case TOK_STATIC:
3278 t |= VT_STATIC;
3279 next();
3280 break;
3281 case TOK_TYPEDEF:
3282 t |= VT_TYPEDEF;
3283 next();
3284 break;
3285 case TOK_INLINE1:
3286 case TOK_INLINE2:
3287 case TOK_INLINE3:
3288 t |= VT_INLINE;
3289 next();
3290 break;
3292 /* GNUC attribute */
3293 case TOK_ATTRIBUTE1:
3294 case TOK_ATTRIBUTE2:
3295 parse_attribute(ad);
3296 if (ad->a.mode) {
3297 u = ad->a.mode -1;
3298 t = (t & ~VT_BTYPE) | u;
3300 break;
3301 /* GNUC typeof */
3302 case TOK_TYPEOF1:
3303 case TOK_TYPEOF2:
3304 case TOK_TYPEOF3:
3305 next();
3306 parse_expr_type(&type1);
3307 /* remove all storage modifiers except typedef */
3308 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3309 goto basic_type2;
3310 default:
3311 if (typespec_found)
3312 goto the_end;
3313 s = sym_find(tok);
3314 if (!s || !(s->type.t & VT_TYPEDEF))
3315 goto the_end;
3316 t |= (s->type.t & ~VT_TYPEDEF);
3317 if ((t & VT_ARRAY) &&
3318 t & (VT_CONSTANT | VT_VOLATILE) & ~s->type.ref->type.t) {
3319 /* This is a case like "typedef int T[1]; const T x;"
3320 in which which we must make a copy of the typedef
3321 type so that we can add the type qualifiers to it. */
3322 type->ref = sym_push(SYM_FIELD, &s->type.ref->type,
3323 0, s->type.ref->c);
3324 type->ref->type.t |= t & (VT_CONSTANT | VT_VOLATILE);
3326 else
3327 type->ref = s->type.ref;
3328 if (s->r) {
3329 /* get attributes from typedef */
3330 if (0 == ad->a.aligned)
3331 ad->a.aligned = s->a.aligned;
3332 if (0 == ad->a.func_call)
3333 ad->a.func_call = s->a.func_call;
3334 ad->a.packed |= s->a.packed;
3336 next();
3337 typespec_found = 1;
3338 break;
3340 type_found = 1;
3342 the_end:
3343 if (tcc_state->char_is_unsigned) {
3344 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3345 t |= VT_UNSIGNED;
3348 /* long is never used as type */
3349 if ((t & VT_BTYPE) == VT_LONG)
3350 #if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \
3351 defined TCC_TARGET_PE
3352 t = (t & ~VT_BTYPE) | VT_INT;
3353 #else
3354 t = (t & ~VT_BTYPE) | VT_LLONG;
3355 #endif
3356 type->t = t;
3357 return type_found;
3360 /* convert a function parameter type (array to pointer and function to
3361 function pointer) */
3362 static inline void convert_parameter_type(CType *pt)
3364 /* remove const and volatile qualifiers (XXX: const could be used
3365 to indicate a const function parameter */
3366 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3367 /* array must be transformed to pointer according to ANSI C */
3368 pt->t &= ~VT_ARRAY;
3369 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3370 mk_pointer(pt);
3374 ST_FUNC void parse_asm_str(CString *astr)
3376 skip('(');
3377 /* read the string */
3378 if (tok != TOK_STR)
3379 expect("string constant");
3380 cstr_new(astr);
3381 while (tok == TOK_STR) {
3382 /* XXX: add \0 handling too ? */
3383 cstr_cat(astr, tokc.cstr->data);
3384 next();
3386 cstr_ccat(astr, '\0');
3389 /* Parse an asm label and return the label
3390 * Don't forget to free the CString in the caller! */
3391 static void asm_label_instr(CString *astr)
3393 next();
3394 parse_asm_str(astr);
3395 skip(')');
3396 #ifdef ASM_DEBUG
3397 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3398 #endif
3401 static void post_type(CType *type, AttributeDef *ad)
3403 int n, l, t1, arg_size, align;
3404 Sym **plast, *s, *first;
3405 AttributeDef ad1;
3406 CType pt;
3408 if (tok == '(') {
3409 /* function declaration */
3410 next();
3411 l = 0;
3412 first = NULL;
3413 plast = &first;
3414 arg_size = 0;
3415 if (tok != ')') {
3416 for(;;) {
3417 /* read param name and compute offset */
3418 if (l != FUNC_OLD) {
3419 if (!parse_btype(&pt, &ad1)) {
3420 if (l) {
3421 tcc_error("invalid type");
3422 } else {
3423 l = FUNC_OLD;
3424 goto old_proto;
3427 l = FUNC_NEW;
3428 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3429 break;
3430 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3431 if ((pt.t & VT_BTYPE) == VT_VOID)
3432 tcc_error("parameter declared as void");
3433 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3434 } else {
3435 old_proto:
3436 n = tok;
3437 if (n < TOK_UIDENT)
3438 expect("identifier");
3439 pt.t = VT_INT;
3440 next();
3442 convert_parameter_type(&pt);
3443 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3444 *plast = s;
3445 plast = &s->next;
3446 if (tok == ')')
3447 break;
3448 skip(',');
3449 if (l == FUNC_NEW && tok == TOK_DOTS) {
3450 l = FUNC_ELLIPSIS;
3451 next();
3452 break;
3456 /* if no parameters, then old type prototype */
3457 if (l == 0)
3458 l = FUNC_OLD;
3459 skip(')');
3460 /* NOTE: const is ignored in returned type as it has a special
3461 meaning in gcc / C++ */
3462 type->t &= ~VT_CONSTANT;
3463 /* some ancient pre-K&R C allows a function to return an array
3464 and the array brackets to be put after the arguments, such
3465 that "int c()[]" means something like "int[] c()" */
3466 if (tok == '[') {
3467 next();
3468 skip(']'); /* only handle simple "[]" */
3469 type->t |= VT_PTR;
3471 /* we push a anonymous symbol which will contain the function prototype */
3472 ad->a.func_args = arg_size;
3473 s = sym_push(SYM_FIELD, type, 0, l);
3474 s->a = ad->a;
3475 s->next = first;
3476 type->t = VT_FUNC;
3477 type->ref = s;
3478 } else if (tok == '[') {
3479 /* array definition */
3480 next();
3481 if (tok == TOK_RESTRICT1)
3482 next();
3483 n = -1;
3484 t1 = 0;
3485 if (tok != ']') {
3486 if (!local_stack || nocode_wanted)
3487 vpushi(expr_const());
3488 else gexpr();
3489 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3490 n = vtop->c.i;
3491 if (n < 0)
3492 tcc_error("invalid array size");
3493 } else {
3494 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3495 tcc_error("size of variable length array should be an integer");
3496 t1 = VT_VLA;
3499 skip(']');
3500 /* parse next post type */
3501 post_type(type, ad);
3502 if (type->t == VT_FUNC)
3503 tcc_error("declaration of an array of functions");
3504 t1 |= type->t & VT_VLA;
3506 if (t1 & VT_VLA) {
3507 loc -= type_size(&int_type, &align);
3508 loc &= -align;
3509 n = loc;
3511 vla_runtime_type_size(type, &align);
3512 gen_op('*');
3513 vset(&int_type, VT_LOCAL|VT_LVAL, n);
3514 vswap();
3515 vstore();
3517 if (n != -1)
3518 vpop();
3520 /* we push an anonymous symbol which will contain the array
3521 element type */
3522 s = sym_push(SYM_FIELD, type, 0, n);
3523 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3524 type->ref = s;
3528 /* Parse a type declaration (except basic type), and return the type
3529 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3530 expected. 'type' should contain the basic type. 'ad' is the
3531 attribute definition of the basic type. It can be modified by
3532 type_decl().
3534 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3536 Sym *s;
3537 CType type1, *type2;
3538 int qualifiers, storage;
3540 while (tok == '*') {
3541 qualifiers = 0;
3542 redo:
3543 next();
3544 switch(tok) {
3545 case TOK_CONST1:
3546 case TOK_CONST2:
3547 case TOK_CONST3:
3548 qualifiers |= VT_CONSTANT;
3549 goto redo;
3550 case TOK_VOLATILE1:
3551 case TOK_VOLATILE2:
3552 case TOK_VOLATILE3:
3553 qualifiers |= VT_VOLATILE;
3554 goto redo;
3555 case TOK_RESTRICT1:
3556 case TOK_RESTRICT2:
3557 case TOK_RESTRICT3:
3558 goto redo;
3560 mk_pointer(type);
3561 type->t |= qualifiers;
3564 /* XXX: clarify attribute handling */
3565 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3566 parse_attribute(ad);
3568 /* recursive type */
3569 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3570 type1.t = 0; /* XXX: same as int */
3571 if (tok == '(') {
3572 next();
3573 /* XXX: this is not correct to modify 'ad' at this point, but
3574 the syntax is not clear */
3575 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3576 parse_attribute(ad);
3577 type_decl(&type1, ad, v, td);
3578 skip(')');
3579 } else {
3580 /* type identifier */
3581 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3582 *v = tok;
3583 next();
3584 } else {
3585 if (!(td & TYPE_ABSTRACT))
3586 expect("identifier");
3587 *v = 0;
3590 storage = type->t & VT_STORAGE;
3591 type->t &= ~VT_STORAGE;
3592 if (storage & VT_STATIC) {
3593 int saved_nocode_wanted = nocode_wanted;
3594 nocode_wanted = 1;
3595 post_type(type, ad);
3596 nocode_wanted = saved_nocode_wanted;
3597 } else
3598 post_type(type, ad);
3599 type->t |= storage;
3600 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3601 parse_attribute(ad);
3603 if (!type1.t)
3604 return;
3605 /* append type at the end of type1 */
3606 type2 = &type1;
3607 for(;;) {
3608 s = type2->ref;
3609 type2 = &s->type;
3610 if (!type2->t) {
3611 *type2 = *type;
3612 break;
3615 *type = type1;
3618 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3619 ST_FUNC int lvalue_type(int t)
3621 int bt, r;
3622 r = VT_LVAL;
3623 bt = t & VT_BTYPE;
3624 if (bt == VT_BYTE || bt == VT_BOOL)
3625 r |= VT_LVAL_BYTE;
3626 else if (bt == VT_SHORT)
3627 r |= VT_LVAL_SHORT;
3628 else
3629 return r;
3630 if (t & VT_UNSIGNED)
3631 r |= VT_LVAL_UNSIGNED;
3632 return r;
3635 /* indirection with full error checking and bound check */
3636 ST_FUNC void indir(void)
3638 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3639 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3640 return;
3641 expect("pointer");
3643 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3644 gv(RC_INT);
3645 vtop->type = *pointed_type(&vtop->type);
3646 /* Arrays and functions are never lvalues */
3647 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3648 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3649 vtop->r |= lvalue_type(vtop->type.t);
3650 /* if bound checking, the referenced pointer must be checked */
3651 #ifdef CONFIG_TCC_BCHECK
3652 if (tcc_state->do_bounds_check)
3653 vtop->r |= VT_MUSTBOUND;
3654 #endif
3658 /* pass a parameter to a function and do type checking and casting */
3659 static void gfunc_param_typed(Sym *func, Sym *arg)
3661 int func_type;
3662 CType type;
3664 func_type = func->c;
3665 if (func_type == FUNC_OLD ||
3666 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3667 /* default casting : only need to convert float to double */
3668 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3669 type.t = VT_DOUBLE;
3670 gen_cast(&type);
3671 } else if (vtop->type.t & VT_BITFIELD) {
3672 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3673 gen_cast(&type);
3675 } else if (arg == NULL) {
3676 tcc_error("too many arguments to function");
3677 } else {
3678 type = arg->type;
3679 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3680 gen_assign_cast(&type);
3684 /* parse an expression of the form '(type)' or '(expr)' and return its
3685 type */
3686 static void parse_expr_type(CType *type)
3688 int n;
3689 AttributeDef ad;
3691 skip('(');
3692 if (parse_btype(type, &ad)) {
3693 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3694 } else {
3695 expr_type(type);
3697 skip(')');
3700 static void parse_type(CType *type)
3702 AttributeDef ad;
3703 int n;
3705 if (!parse_btype(type, &ad)) {
3706 expect("type");
3708 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3711 static void vpush_tokc(int t)
3713 CType type;
3714 type.t = t;
3715 type.ref = 0;
3716 vsetc(&type, VT_CONST, &tokc);
3719 ST_FUNC void unary(void)
3721 int n, t, align, size, r, sizeof_caller;
3722 CType type;
3723 Sym *s;
3724 AttributeDef ad;
3725 static int in_sizeof = 0;
3727 sizeof_caller = in_sizeof;
3728 in_sizeof = 0;
3729 /* XXX: GCC 2.95.3 does not generate a table although it should be
3730 better here */
3731 tok_next:
3732 switch(tok) {
3733 case TOK_EXTENSION:
3734 next();
3735 goto tok_next;
3736 case TOK_CINT:
3737 case TOK_CCHAR:
3738 case TOK_LCHAR:
3739 vpushi(tokc.i);
3740 next();
3741 break;
3742 case TOK_CUINT:
3743 vpush_tokc(VT_INT | VT_UNSIGNED);
3744 next();
3745 break;
3746 case TOK_CLLONG:
3747 vpush_tokc(VT_LLONG);
3748 next();
3749 break;
3750 case TOK_CULLONG:
3751 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3752 next();
3753 break;
3754 case TOK_CFLOAT:
3755 vpush_tokc(VT_FLOAT);
3756 next();
3757 break;
3758 case TOK_CDOUBLE:
3759 vpush_tokc(VT_DOUBLE);
3760 next();
3761 break;
3762 case TOK_CLDOUBLE:
3763 vpush_tokc(VT_LDOUBLE);
3764 next();
3765 break;
3766 case TOK___FUNCTION__:
3767 if (!gnu_ext)
3768 goto tok_identifier;
3769 /* fall thru */
3770 case TOK___FUNC__:
3772 void *ptr;
3773 int len;
3774 /* special function name identifier */
3775 len = strlen(funcname) + 1;
3776 /* generate char[len] type */
3777 type.t = VT_BYTE;
3778 mk_pointer(&type);
3779 type.t |= VT_ARRAY;
3780 type.ref->c = len;
3781 vpush_ref(&type, data_section, data_section->data_offset, len);
3782 ptr = section_ptr_add(data_section, len);
3783 memcpy(ptr, funcname, len);
3784 next();
3786 break;
3787 case TOK_LSTR:
3788 #ifdef TCC_TARGET_PE
3789 t = VT_SHORT | VT_UNSIGNED;
3790 #else
3791 t = VT_INT;
3792 #endif
3793 goto str_init;
3794 case TOK_STR:
3795 /* string parsing */
3796 t = VT_BYTE;
3797 str_init:
3798 if (tcc_state->warn_write_strings)
3799 t |= VT_CONSTANT;
3800 type.t = t;
3801 mk_pointer(&type);
3802 type.t |= VT_ARRAY;
3803 memset(&ad, 0, sizeof(AttributeDef));
3804 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3805 break;
3806 case '(':
3807 next();
3808 /* cast ? */
3809 if (parse_btype(&type, &ad)) {
3810 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3811 skip(')');
3812 /* check ISOC99 compound literal */
3813 if (tok == '{') {
3814 /* data is allocated locally by default */
3815 if (global_expr)
3816 r = VT_CONST;
3817 else
3818 r = VT_LOCAL;
3819 /* all except arrays are lvalues */
3820 if (!(type.t & VT_ARRAY))
3821 r |= lvalue_type(type.t);
3822 memset(&ad, 0, sizeof(AttributeDef));
3823 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3824 } else {
3825 if (sizeof_caller) {
3826 vpush(&type);
3827 return;
3829 unary();
3830 gen_cast(&type);
3832 } else if (tok == '{') {
3834 if (nocode_wanted)
3835 tcc_error("statement expression in global scope"); */
3836 /* this check breaks compilation of the linux 2.4.26 with the meesage:
3837 linux/include/net/tcp.h:945: error: statement expression in global scope */
3839 /* save all registers */
3840 save_regs(0);
3841 /* statement expression : we do not accept break/continue
3842 inside as GCC does */
3843 block(NULL, NULL, NULL, NULL, 0, 1);
3844 skip(')');
3845 } else {
3846 gexpr();
3847 skip(')');
3849 break;
3850 case '*':
3851 next();
3852 unary();
3853 indir();
3854 break;
3855 case '&':
3856 next();
3857 unary();
3858 /* functions names must be treated as function pointers,
3859 except for unary '&' and sizeof. Since we consider that
3860 functions are not lvalues, we only have to handle it
3861 there and in function calls. */
3862 /* arrays can also be used although they are not lvalues */
3863 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3864 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3865 test_lvalue();
3866 mk_pointer(&vtop->type);
3867 gaddrof();
3868 break;
3869 case '!':
3870 next();
3871 unary();
3872 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3873 CType boolean;
3874 boolean.t = VT_BOOL;
3875 gen_cast(&boolean);
3876 vtop->c.i = !vtop->c.i;
3877 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3878 vtop->c.i ^= 1;
3879 else if (!nocode_wanted) {
3880 save_regs(1);
3881 vseti(VT_JMP, gvtst(1, 0));
3883 else
3884 vtop--;
3885 break;
3886 case '~':
3887 next();
3888 unary();
3889 vpushi(-1);
3890 gen_op('^');
3891 break;
3892 case '+':
3893 next();
3894 unary();
3895 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3896 tcc_error("pointer not accepted for unary plus");
3897 /* In order to force cast, we add zero, except for floating point
3898 where we really need an noop (otherwise -0.0 will be transformed
3899 into +0.0). */
3900 if (!is_float(vtop->type.t)) {
3901 vpushi(0);
3902 gen_op('+');
3904 break;
3905 case TOK_SIZEOF:
3906 case TOK_ALIGNOF1:
3907 case TOK_ALIGNOF2:
3908 t = tok;
3909 next();
3910 in_sizeof++;
3911 unary_type(&type); // Perform a in_sizeof = 0;
3912 size = type_size(&type, &align);
3913 if (t == TOK_SIZEOF) {
3914 if (!(type.t & VT_VLA)) {
3915 if (size < 0)
3916 tcc_error("sizeof applied to an incomplete type");
3917 vpushs(size);
3918 } else {
3919 vla_runtime_type_size(&type, &align);
3921 } else {
3922 vpushs(align);
3924 vtop->type.t |= VT_UNSIGNED;
3925 break;
3927 case TOK_builtin_types_compatible_p:
3929 CType type1, type2;
3930 next();
3931 skip('(');
3932 parse_type(&type1);
3933 skip(',');
3934 parse_type(&type2);
3935 skip(')');
3936 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3937 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3938 vpushi(is_compatible_types(&type1, &type2));
3940 break;
3941 case TOK_builtin_constant_p:
3943 int saved_nocode_wanted, res;
3944 next();
3945 skip('(');
3946 saved_nocode_wanted = nocode_wanted;
3947 nocode_wanted = 1;
3948 gexpr();
3949 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3950 vpop();
3951 nocode_wanted = saved_nocode_wanted;
3952 skip(')');
3953 vpushi(res);
3955 break;
3956 case TOK_builtin_frame_address:
3957 case TOK_builtin_return_address:
3959 int tok1 = tok;
3960 int level;
3961 CType type;
3962 next();
3963 skip('(');
3964 if (tok != TOK_CINT) {
3965 tcc_error("%s only takes positive integers",
3966 tok1 == TOK_builtin_return_address ?
3967 "__builtin_return_address" :
3968 "__builtin_frame_address");
3970 level = (uint32_t)tokc.i;
3971 next();
3972 skip(')');
3973 type.t = VT_VOID;
3974 mk_pointer(&type);
3975 vset(&type, VT_LOCAL, 0); /* local frame */
3976 while (level--) {
3977 mk_pointer(&vtop->type);
3978 indir(); /* -> parent frame */
3980 if (tok1 == TOK_builtin_return_address) {
3981 // assume return address is just above frame pointer on stack
3982 vpushi(PTR_SIZE);
3983 gen_op('+');
3984 mk_pointer(&vtop->type);
3985 indir();
3988 break;
3989 #ifdef TCC_TARGET_X86_64
3990 #ifdef TCC_TARGET_PE
3991 case TOK_builtin_va_start:
3993 next();
3994 skip('(');
3995 expr_eq();
3996 skip(',');
3997 expr_eq();
3998 skip(')');
3999 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
4000 tcc_error("__builtin_va_start expects a local variable");
4001 vtop->r &= ~(VT_LVAL | VT_REF);
4002 vtop->type = char_pointer_type;
4003 vstore();
4005 break;
4006 #else
4007 case TOK_builtin_va_arg_types:
4009 CType type;
4010 next();
4011 skip('(');
4012 parse_type(&type);
4013 skip(')');
4014 vpushi(classify_x86_64_va_arg(&type));
4016 break;
4017 #endif
4018 #endif
4020 #ifdef TCC_TARGET_ARM64
4021 case TOK___va_start: {
4022 if (nocode_wanted)
4023 tcc_error("statement in global scope");
4024 next();
4025 skip('(');
4026 expr_eq();
4027 skip(',');
4028 expr_eq();
4029 skip(')');
4030 //xx check types
4031 gen_va_start();
4032 vpushi(0);
4033 vtop->type.t = VT_VOID;
4034 break;
4036 case TOK___va_arg: {
4037 CType type;
4038 if (nocode_wanted)
4039 tcc_error("statement in global scope");
4040 next();
4041 skip('(');
4042 expr_eq();
4043 skip(',');
4044 parse_type(&type);
4045 skip(')');
4046 //xx check types
4047 gen_va_arg(&type);
4048 vtop->type = type;
4049 break;
4051 case TOK___arm64_clear_cache: {
4052 next();
4053 skip('(');
4054 expr_eq();
4055 skip(',');
4056 expr_eq();
4057 skip(')');
4058 gen_clear_cache();
4059 vpushi(0);
4060 vtop->type.t = VT_VOID;
4061 break;
4063 #endif
4064 /* pre operations */
4065 case TOK_INC:
4066 case TOK_DEC:
4067 t = tok;
4068 next();
4069 unary();
4070 inc(0, t);
4071 break;
4072 case '-':
4073 next();
4074 unary();
4075 t = vtop->type.t & VT_BTYPE;
4076 if (is_float(t)) {
4077 /* In IEEE negate(x) isn't subtract(0,x), but rather
4078 subtract(-0, x). */
4079 vpush(&vtop->type);
4080 if (t == VT_FLOAT)
4081 vtop->c.f = -0.0f;
4082 else if (t == VT_DOUBLE)
4083 vtop->c.d = -0.0;
4084 else
4085 vtop->c.ld = -0.0;
4086 } else
4087 vpushi(0);
4088 vswap();
4089 gen_op('-');
4090 break;
4091 case TOK_LAND:
4092 if (!gnu_ext)
4093 goto tok_identifier;
4094 next();
4095 /* allow to take the address of a label */
4096 if (tok < TOK_UIDENT)
4097 expect("label identifier");
4098 s = label_find(tok);
4099 if (!s) {
4100 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4101 } else {
4102 if (s->r == LABEL_DECLARED)
4103 s->r = LABEL_FORWARD;
4105 if (!s->type.t) {
4106 s->type.t = VT_VOID;
4107 mk_pointer(&s->type);
4108 s->type.t |= VT_STATIC;
4110 vpushsym(&s->type, s);
4111 next();
4112 break;
4114 // special qnan , snan and infinity values
4115 case TOK___NAN__:
4116 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
4117 next();
4118 break;
4119 case TOK___SNAN__:
4120 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
4121 next();
4122 break;
4123 case TOK___INF__:
4124 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
4125 next();
4126 break;
4128 default:
4129 tok_identifier:
4130 t = tok;
4131 next();
4132 if (t < TOK_UIDENT)
4133 expect("identifier");
4134 s = sym_find(t);
4135 if (!s) {
4136 const char *name = get_tok_str(t, NULL);
4137 if (tok != '(')
4138 tcc_error("'%s' undeclared", name);
4139 /* for simple function calls, we tolerate undeclared
4140 external reference to int() function */
4141 if (tcc_state->warn_implicit_function_declaration
4142 #ifdef TCC_TARGET_PE
4143 /* people must be warned about using undeclared WINAPI functions
4144 (which usually start with uppercase letter) */
4145 || (name[0] >= 'A' && name[0] <= 'Z')
4146 #endif
4148 tcc_warning("implicit declaration of function '%s'", name);
4149 s = external_global_sym(t, &func_old_type, 0);
4151 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
4152 (VT_STATIC | VT_INLINE | VT_FUNC)) {
4153 /* if referencing an inline function, then we generate a
4154 symbol to it if not already done. It will have the
4155 effect to generate code for it at the end of the
4156 compilation unit. Inline function as always
4157 generated in the text section. */
4158 if (!s->c)
4159 put_extern_sym(s, text_section, 0, 0);
4160 r = VT_SYM | VT_CONST;
4161 } else {
4162 r = s->r;
4164 vset(&s->type, r, s->c);
4165 /* if forward reference, we must point to s */
4166 if (vtop->r & VT_SYM) {
4167 vtop->sym = s;
4168 vtop->c.i = 0;
4170 break;
4173 /* post operations */
4174 while (1) {
4175 if (tok == TOK_INC || tok == TOK_DEC) {
4176 inc(1, tok);
4177 next();
4178 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
4179 int qualifiers;
4180 /* field */
4181 if (tok == TOK_ARROW)
4182 indir();
4183 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4184 test_lvalue();
4185 gaddrof();
4186 /* expect pointer on structure */
4187 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4188 expect("struct or union");
4189 if (tok == TOK_CDOUBLE)
4190 expect("field name");
4191 next();
4192 if (tok == TOK_CINT || tok == TOK_CUINT)
4193 expect("field name");
4194 s = vtop->type.ref;
4195 /* find field */
4196 tok |= SYM_FIELD;
4197 while ((s = s->next) != NULL) {
4198 if (s->v == tok)
4199 break;
4201 if (!s)
4202 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
4203 /* add field offset to pointer */
4204 vtop->type = char_pointer_type; /* change type to 'char *' */
4205 vpushi(s->c);
4206 gen_op('+');
4207 /* change type to field type, and set to lvalue */
4208 vtop->type = s->type;
4209 vtop->type.t |= qualifiers;
4210 /* an array is never an lvalue */
4211 if (!(vtop->type.t & VT_ARRAY)) {
4212 vtop->r |= lvalue_type(vtop->type.t);
4213 #ifdef CONFIG_TCC_BCHECK
4214 /* if bound checking, the referenced pointer must be checked */
4215 if (tcc_state->do_bounds_check)
4216 vtop->r |= VT_MUSTBOUND;
4217 #endif
4219 next();
4220 } else if (tok == '[') {
4221 next();
4222 gexpr();
4223 gen_op('+');
4224 indir();
4225 skip(']');
4226 } else if (tok == '(') {
4227 SValue ret;
4228 Sym *sa;
4229 int nb_args, ret_nregs, ret_align, regsize, variadic;
4231 /* function call */
4232 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4233 /* pointer test (no array accepted) */
4234 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4235 vtop->type = *pointed_type(&vtop->type);
4236 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4237 goto error_func;
4238 } else {
4239 error_func:
4240 expect("function pointer");
4242 } else {
4243 vtop->r &= ~VT_LVAL; /* no lvalue */
4245 /* get return type */
4246 s = vtop->type.ref;
4247 next();
4248 sa = s->next; /* first parameter */
4249 nb_args = 0;
4250 ret.r2 = VT_CONST;
4251 /* compute first implicit argument if a structure is returned */
4252 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4253 variadic = (s->c == FUNC_ELLIPSIS);
4254 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4255 &ret_align, &regsize);
4256 if (!ret_nregs) {
4257 /* get some space for the returned structure */
4258 size = type_size(&s->type, &align);
4259 #ifdef TCC_TARGET_ARM64
4260 /* On arm64, a small struct is return in registers.
4261 It is much easier to write it to memory if we know
4262 that we are allowed to write some extra bytes, so
4263 round the allocated space up to a power of 2: */
4264 if (size < 16)
4265 while (size & (size - 1))
4266 size = (size | (size - 1)) + 1;
4267 #endif
4268 loc = (loc - size) & -align;
4269 ret.type = s->type;
4270 ret.r = VT_LOCAL | VT_LVAL;
4271 /* pass it as 'int' to avoid structure arg passing
4272 problems */
4273 vseti(VT_LOCAL, loc);
4274 ret.c = vtop->c;
4275 nb_args++;
4277 } else {
4278 ret_nregs = 1;
4279 ret.type = s->type;
4282 if (ret_nregs) {
4283 /* return in register */
4284 if (is_float(ret.type.t)) {
4285 ret.r = reg_fret(ret.type.t);
4286 #ifdef TCC_TARGET_X86_64
4287 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4288 ret.r2 = REG_QRET;
4289 #endif
4290 } else {
4291 #ifndef TCC_TARGET_ARM64
4292 #ifdef TCC_TARGET_X86_64
4293 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4294 #else
4295 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4296 #endif
4297 ret.r2 = REG_LRET;
4298 #endif
4299 ret.r = REG_IRET;
4301 ret.c.i = 0;
4303 if (tok != ')') {
4304 for(;;) {
4305 expr_eq();
4306 gfunc_param_typed(s, sa);
4307 nb_args++;
4308 if (sa)
4309 sa = sa->next;
4310 if (tok == ')')
4311 break;
4312 skip(',');
4315 if (sa)
4316 tcc_error("too few arguments to function");
4317 skip(')');
4318 if (!nocode_wanted) {
4319 gfunc_call(nb_args);
4320 } else {
4321 vtop -= (nb_args + 1);
4324 /* return value */
4325 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4326 vsetc(&ret.type, r, &ret.c);
4327 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4330 /* handle packed struct return */
4331 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4332 int addr, offset;
4334 size = type_size(&s->type, &align);
4335 /* We're writing whole regs often, make sure there's enough
4336 space. Assume register size is power of 2. */
4337 if (regsize > align)
4338 align = regsize;
4339 loc = (loc - size) & -align;
4340 addr = loc;
4341 offset = 0;
4342 for (;;) {
4343 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4344 vswap();
4345 vstore();
4346 vtop--;
4347 if (--ret_nregs == 0)
4348 break;
4349 offset += regsize;
4351 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4353 } else {
4354 break;
4359 ST_FUNC void expr_prod(void)
4361 int t;
4363 unary();
4364 while (tok == '*' || tok == '/' || tok == '%') {
4365 t = tok;
4366 next();
4367 unary();
4368 gen_op(t);
4372 ST_FUNC void expr_sum(void)
4374 int t;
4376 expr_prod();
4377 while (tok == '+' || tok == '-') {
4378 t = tok;
4379 next();
4380 expr_prod();
4381 gen_op(t);
4385 static void expr_shift(void)
4387 int t;
4389 expr_sum();
4390 while (tok == TOK_SHL || tok == TOK_SAR) {
4391 t = tok;
4392 next();
4393 expr_sum();
4394 gen_op(t);
4398 static void expr_cmp(void)
4400 int t;
4402 expr_shift();
4403 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4404 tok == TOK_ULT || tok == TOK_UGE) {
4405 t = tok;
4406 next();
4407 expr_shift();
4408 gen_op(t);
4412 static void expr_cmpeq(void)
4414 int t;
4416 expr_cmp();
4417 while (tok == TOK_EQ || tok == TOK_NE) {
4418 t = tok;
4419 next();
4420 expr_cmp();
4421 gen_op(t);
4425 static void expr_and(void)
4427 expr_cmpeq();
4428 while (tok == '&') {
4429 next();
4430 expr_cmpeq();
4431 gen_op('&');
4435 static void expr_xor(void)
4437 expr_and();
4438 while (tok == '^') {
4439 next();
4440 expr_and();
4441 gen_op('^');
4445 static void expr_or(void)
4447 expr_xor();
4448 while (tok == '|') {
4449 next();
4450 expr_xor();
4451 gen_op('|');
4455 /* XXX: fix this mess */
4456 static void expr_land_const(void)
4458 expr_or();
4459 while (tok == TOK_LAND) {
4460 next();
4461 expr_or();
4462 gen_op(TOK_LAND);
4466 /* XXX: fix this mess */
4467 static void expr_lor_const(void)
4469 expr_land_const();
4470 while (tok == TOK_LOR) {
4471 next();
4472 expr_land_const();
4473 gen_op(TOK_LOR);
4477 /* only used if non constant */
4478 static void expr_land(void)
4480 int t;
4482 expr_or();
4483 if (tok == TOK_LAND) {
4484 t = 0;
4485 save_regs(1);
4486 for(;;) {
4487 t = gvtst(1, t);
4488 if (tok != TOK_LAND) {
4489 vseti(VT_JMPI, t);
4490 break;
4492 next();
4493 expr_or();
4498 static void expr_lor(void)
4500 int t;
4502 expr_land();
4503 if (tok == TOK_LOR) {
4504 t = 0;
4505 save_regs(1);
4506 for(;;) {
4507 t = gvtst(0, t);
4508 if (tok != TOK_LOR) {
4509 vseti(VT_JMP, t);
4510 break;
4512 next();
4513 expr_land();
4518 /* XXX: better constant handling */
4519 static void expr_cond(void)
4521 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4522 SValue sv;
4523 CType type, type1, type2;
4525 if (const_wanted)
4526 expr_lor_const();
4527 else
4528 expr_lor();
4529 if (tok == '?') {
4530 next();
4531 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4532 CType boolean;
4533 int c;
4534 boolean.t = VT_BOOL;
4535 vdup();
4536 gen_cast(&boolean);
4537 c = vtop->c.i;
4538 vpop();
4539 if (tok != ':' || !gnu_ext) {
4540 vpop();
4541 gexpr();
4543 if (!c)
4544 vpop();
4545 skip(':');
4546 expr_cond();
4547 if (c)
4548 vpop();
4550 else {
4551 if (vtop != vstack) {
4552 /* needed to avoid having different registers saved in
4553 each branch */
4554 if (is_float(vtop->type.t)) {
4555 rc = RC_FLOAT;
4556 #ifdef TCC_TARGET_X86_64
4557 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4558 rc = RC_ST0;
4560 #endif
4562 else
4563 rc = RC_INT;
4564 gv(rc);
4565 save_regs(1);
4567 if (tok == ':' && gnu_ext) {
4568 gv_dup();
4569 tt = gvtst(1, 0);
4570 } else {
4571 tt = gvtst(1, 0);
4572 gexpr();
4574 type1 = vtop->type;
4575 sv = *vtop; /* save value to handle it later */
4576 vtop--; /* no vpop so that FP stack is not flushed */
4577 skip(':');
4578 u = gjmp(0);
4579 gsym(tt);
4580 expr_cond();
4581 type2 = vtop->type;
4583 t1 = type1.t;
4584 bt1 = t1 & VT_BTYPE;
4585 t2 = type2.t;
4586 bt2 = t2 & VT_BTYPE;
4587 /* cast operands to correct type according to ISOC rules */
4588 if (is_float(bt1) || is_float(bt2)) {
4589 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4590 type.t = VT_LDOUBLE;
4591 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4592 type.t = VT_DOUBLE;
4593 } else {
4594 type.t = VT_FLOAT;
4596 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4597 /* cast to biggest op */
4598 type.t = VT_LLONG;
4599 /* convert to unsigned if it does not fit in a long long */
4600 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4601 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4602 type.t |= VT_UNSIGNED;
4603 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4604 /* If one is a null ptr constant the result type
4605 is the other. */
4606 if (is_null_pointer (vtop))
4607 type = type1;
4608 else if (is_null_pointer (&sv))
4609 type = type2;
4610 /* XXX: test pointer compatibility, C99 has more elaborate
4611 rules here. */
4612 else
4613 type = type1;
4614 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4615 /* XXX: test function pointer compatibility */
4616 type = bt1 == VT_FUNC ? type1 : type2;
4617 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4618 /* XXX: test structure compatibility */
4619 type = bt1 == VT_STRUCT ? type1 : type2;
4620 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4621 /* NOTE: as an extension, we accept void on only one side */
4622 type.t = VT_VOID;
4623 } else {
4624 /* integer operations */
4625 type.t = VT_INT;
4626 /* convert to unsigned if it does not fit in an integer */
4627 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4628 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4629 type.t |= VT_UNSIGNED;
4632 /* now we convert second operand */
4633 gen_cast(&type);
4634 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4635 gaddrof();
4636 rc = RC_INT;
4637 if (is_float(type.t)) {
4638 rc = RC_FLOAT;
4639 #ifdef TCC_TARGET_X86_64
4640 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4641 rc = RC_ST0;
4643 #endif
4644 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4645 /* for long longs, we use fixed registers to avoid having
4646 to handle a complicated move */
4647 rc = RC_IRET;
4650 r2 = gv(rc);
4651 /* this is horrible, but we must also convert first
4652 operand */
4653 tt = gjmp(0);
4654 gsym(u);
4655 /* put again first value and cast it */
4656 *vtop = sv;
4657 gen_cast(&type);
4658 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4659 gaddrof();
4660 r1 = gv(rc);
4661 move_reg(r2, r1, type.t);
4662 vtop->r = r2;
4663 gsym(tt);
4668 static void expr_eq(void)
4670 int t;
4672 expr_cond();
4673 if (tok == '=' ||
4674 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4675 tok == TOK_A_XOR || tok == TOK_A_OR ||
4676 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4677 test_lvalue();
4678 t = tok;
4679 next();
4680 if (t == '=') {
4681 expr_eq();
4682 } else {
4683 vdup();
4684 expr_eq();
4685 gen_op(t & 0x7f);
4687 vstore();
4691 ST_FUNC void gexpr(void)
4693 while (1) {
4694 expr_eq();
4695 if (tok != ',')
4696 break;
4697 vpop();
4698 next();
4702 /* parse an expression and return its type without any side effect. */
4703 static void expr_type(CType *type)
4705 int saved_nocode_wanted;
4707 saved_nocode_wanted = nocode_wanted;
4708 nocode_wanted = 1;
4709 gexpr();
4710 *type = vtop->type;
4711 vpop();
4712 nocode_wanted = saved_nocode_wanted;
4715 /* parse a unary expression and return its type without any side
4716 effect. */
4717 static void unary_type(CType *type)
4719 int a;
4721 a = nocode_wanted;
4722 nocode_wanted = 1;
4723 unary();
4724 *type = vtop->type;
4725 vpop();
4726 nocode_wanted = a;
4729 /* parse a constant expression and return value in vtop. */
4730 static void expr_const1(void)
4732 int a;
4733 a = const_wanted;
4734 const_wanted = 1;
4735 expr_cond();
4736 const_wanted = a;
4739 /* parse an integer constant and return its value. */
4740 ST_FUNC int expr_const(void)
4742 int c;
4743 expr_const1();
4744 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4745 expect("constant expression");
4746 c = vtop->c.i;
4747 vpop();
4748 return c;
4751 /* return the label token if current token is a label, otherwise
4752 return zero */
4753 static int is_label(void)
4755 int last_tok;
4757 /* fast test first */
4758 if (tok < TOK_UIDENT)
4759 return 0;
4760 /* no need to save tokc because tok is an identifier */
4761 last_tok = tok;
4762 next();
4763 if (tok == ':') {
4764 next();
4765 return last_tok;
4766 } else {
4767 unget_tok(last_tok);
4768 return 0;
4772 static void label_or_decl(int l)
4774 int last_tok;
4776 /* fast test first */
4777 if (tok >= TOK_UIDENT)
4779 /* no need to save tokc because tok is an identifier */
4780 last_tok = tok;
4781 next();
4782 if (tok == ':') {
4783 unget_tok(last_tok);
4784 return;
4786 unget_tok(last_tok);
4788 decl(l);
4791 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4792 int case_reg, int is_expr)
4794 int a, b, c, d;
4795 Sym *s, *frame_bottom;
4797 /* generate line number info */
4798 if (tcc_state->do_debug &&
4799 (last_line_num != file->line_num || last_ind != ind)) {
4800 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4801 last_ind = ind;
4802 last_line_num = file->line_num;
4805 if (is_expr) {
4806 /* default return value is (void) */
4807 vpushi(0);
4808 vtop->type.t = VT_VOID;
4811 if (tok == TOK_IF) {
4812 /* if test */
4813 next();
4814 skip('(');
4815 gexpr();
4816 skip(')');
4817 a = gvtst(1, 0);
4818 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4819 c = tok;
4820 if (c == TOK_ELSE) {
4821 next();
4822 d = gjmp(0);
4823 gsym(a);
4824 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4825 gsym(d); /* patch else jmp */
4826 } else
4827 gsym(a);
4828 } else if (tok == TOK_WHILE) {
4829 next();
4830 d = ind;
4831 vla_sp_restore();
4832 skip('(');
4833 gexpr();
4834 skip(')');
4835 a = gvtst(1, 0);
4836 b = 0;
4837 block(&a, &b, case_sym, def_sym, case_reg, 0);
4838 gjmp_addr(d);
4839 gsym(a);
4840 gsym_addr(b, d);
4841 } else if (tok == '{') {
4842 Sym *llabel;
4843 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
4845 next();
4846 /* record local declaration stack position */
4847 s = local_stack;
4848 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4849 frame_bottom->next = scope_stack_bottom;
4850 scope_stack_bottom = frame_bottom;
4851 llabel = local_label_stack;
4853 /* handle local labels declarations */
4854 if (tok == TOK_LABEL) {
4855 next();
4856 for(;;) {
4857 if (tok < TOK_UIDENT)
4858 expect("label identifier");
4859 label_push(&local_label_stack, tok, LABEL_DECLARED);
4860 next();
4861 if (tok == ',') {
4862 next();
4863 } else {
4864 skip(';');
4865 break;
4869 while (tok != '}') {
4870 label_or_decl(VT_LOCAL);
4871 if (tok != '}') {
4872 if (is_expr)
4873 vpop();
4874 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4877 /* pop locally defined labels */
4878 label_pop(&local_label_stack, llabel);
4879 if(is_expr) {
4880 /* XXX: this solution makes only valgrind happy...
4881 triggered by gcc.c-torture/execute/20000917-1.c */
4882 Sym *p;
4883 switch(vtop->type.t & VT_BTYPE) {
4884 /* case VT_PTR: */
4885 /* this breaks a compilation of the linux kernel v2.4.26 */
4886 /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
4887 /* Look a commit a80acab: Display error on statement expressions with complex return type */
4888 /* A pointer is not a complex return type */
4889 case VT_STRUCT:
4890 case VT_ENUM:
4891 case VT_FUNC:
4892 for(p=vtop->type.ref;p;p=p->prev)
4893 if(p->prev==s)
4894 tcc_error("unsupported expression type");
4897 /* pop locally defined symbols */
4898 scope_stack_bottom = scope_stack_bottom->next;
4899 sym_pop(&local_stack, s);
4901 /* Pop VLA frames and restore stack pointer if required */
4902 if (vlas_in_scope > saved_vlas_in_scope) {
4903 vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
4904 vla_sp_restore();
4906 vlas_in_scope = saved_vlas_in_scope;
4908 next();
4909 } else if (tok == TOK_RETURN) {
4910 next();
4911 if (tok != ';') {
4912 gexpr();
4913 gen_assign_cast(&func_vt);
4914 #ifdef TCC_TARGET_ARM64
4915 // Perhaps it would be better to use this for all backends:
4916 greturn();
4917 #else
4918 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4919 CType type, ret_type;
4920 int ret_align, ret_nregs, regsize;
4921 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
4922 &ret_align, &regsize);
4923 if (0 == ret_nregs) {
4924 /* if returning structure, must copy it to implicit
4925 first pointer arg location */
4926 type = func_vt;
4927 mk_pointer(&type);
4928 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4929 indir();
4930 vswap();
4931 /* copy structure value to pointer */
4932 vstore();
4933 } else {
4934 /* returning structure packed into registers */
4935 int r, size, addr, align;
4936 size = type_size(&func_vt,&align);
4937 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
4938 (vtop->c.i & (ret_align-1)))
4939 && (align & (ret_align-1))) {
4940 loc = (loc - size) & -ret_align;
4941 addr = loc;
4942 type = func_vt;
4943 vset(&type, VT_LOCAL | VT_LVAL, addr);
4944 vswap();
4945 vstore();
4946 vpop();
4947 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
4949 vtop->type = ret_type;
4950 if (is_float(ret_type.t))
4951 r = rc_fret(ret_type.t);
4952 else
4953 r = RC_IRET;
4955 for (;;) {
4956 gv(r);
4957 if (--ret_nregs == 0)
4958 break;
4959 /* We assume that when a structure is returned in multiple
4960 registers, their classes are consecutive values of the
4961 suite s(n) = 2^n */
4962 r <<= 1;
4963 vtop->c.i += regsize;
4964 vtop->r = VT_LOCAL | VT_LVAL;
4967 } else if (is_float(func_vt.t)) {
4968 gv(rc_fret(func_vt.t));
4969 } else {
4970 gv(RC_IRET);
4972 #endif
4973 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4975 skip(';');
4976 rsym = gjmp(rsym); /* jmp */
4977 } else if (tok == TOK_BREAK) {
4978 /* compute jump */
4979 if (!bsym)
4980 tcc_error("cannot break");
4981 *bsym = gjmp(*bsym);
4982 next();
4983 skip(';');
4984 } else if (tok == TOK_CONTINUE) {
4985 /* compute jump */
4986 if (!csym)
4987 tcc_error("cannot continue");
4988 vla_sp_restore_root();
4989 *csym = gjmp(*csym);
4990 next();
4991 skip(';');
4992 } else if (tok == TOK_FOR) {
4993 int e;
4994 next();
4995 skip('(');
4996 s = local_stack;
4997 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4998 frame_bottom->next = scope_stack_bottom;
4999 scope_stack_bottom = frame_bottom;
5000 if (tok != ';') {
5001 /* c99 for-loop init decl? */
5002 if (!decl0(VT_LOCAL, 1)) {
5003 /* no, regular for-loop init expr */
5004 gexpr();
5005 vpop();
5008 skip(';');
5009 d = ind;
5010 c = ind;
5011 vla_sp_restore();
5012 a = 0;
5013 b = 0;
5014 if (tok != ';') {
5015 gexpr();
5016 a = gvtst(1, 0);
5018 skip(';');
5019 if (tok != ')') {
5020 e = gjmp(0);
5021 c = ind;
5022 vla_sp_restore();
5023 gexpr();
5024 vpop();
5025 gjmp_addr(d);
5026 gsym(e);
5028 skip(')');
5029 block(&a, &b, case_sym, def_sym, case_reg, 0);
5030 gjmp_addr(c);
5031 gsym(a);
5032 gsym_addr(b, c);
5033 scope_stack_bottom = scope_stack_bottom->next;
5034 sym_pop(&local_stack, s);
5035 } else
5036 if (tok == TOK_DO) {
5037 next();
5038 a = 0;
5039 b = 0;
5040 d = ind;
5041 vla_sp_restore();
5042 block(&a, &b, case_sym, def_sym, case_reg, 0);
5043 skip(TOK_WHILE);
5044 skip('(');
5045 gsym(b);
5046 gexpr();
5047 c = gvtst(0, 0);
5048 gsym_addr(c, d);
5049 skip(')');
5050 gsym(a);
5051 skip(';');
5052 } else
5053 if (tok == TOK_SWITCH) {
5054 next();
5055 skip('(');
5056 gexpr();
5057 /* XXX: other types than integer */
5058 case_reg = gv(RC_INT);
5059 vpop();
5060 skip(')');
5061 a = 0;
5062 b = gjmp(0); /* jump to first case */
5063 c = 0;
5064 block(&a, csym, &b, &c, case_reg, 0);
5065 /* if no default, jmp after switch */
5066 if (c == 0)
5067 c = ind;
5068 /* default label */
5069 gsym_addr(b, c);
5070 /* break label */
5071 gsym(a);
5072 } else
5073 if (tok == TOK_CASE) {
5074 int v1, v2;
5075 if (!case_sym)
5076 expect("switch");
5077 next();
5078 v1 = expr_const();
5079 v2 = v1;
5080 if (gnu_ext && tok == TOK_DOTS) {
5081 next();
5082 v2 = expr_const();
5083 if (v2 < v1)
5084 tcc_warning("empty case range");
5086 /* since a case is like a label, we must skip it with a jmp */
5087 b = gjmp(0);
5088 gsym(*case_sym);
5089 vseti(case_reg, 0);
5090 vdup();
5091 vpushi(v1);
5092 if (v1 == v2) {
5093 gen_op(TOK_EQ);
5094 *case_sym = gtst(1, 0);
5095 } else {
5096 gen_op(TOK_GE);
5097 *case_sym = gtst(1, 0);
5098 vseti(case_reg, 0);
5099 vpushi(v2);
5100 gen_op(TOK_LE);
5101 *case_sym = gtst(1, *case_sym);
5103 case_reg = gv(RC_INT);
5104 vpop();
5105 gsym(b);
5106 skip(':');
5107 is_expr = 0;
5108 goto block_after_label;
5109 } else
5110 if (tok == TOK_DEFAULT) {
5111 next();
5112 skip(':');
5113 if (!def_sym)
5114 expect("switch");
5115 if (*def_sym)
5116 tcc_error("too many 'default'");
5117 *def_sym = ind;
5118 is_expr = 0;
5119 goto block_after_label;
5120 } else
5121 if (tok == TOK_GOTO) {
5122 next();
5123 if (tok == '*' && gnu_ext) {
5124 /* computed goto */
5125 next();
5126 gexpr();
5127 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5128 expect("pointer");
5129 ggoto();
5130 } else if (tok >= TOK_UIDENT) {
5131 s = label_find(tok);
5132 /* put forward definition if needed */
5133 if (!s) {
5134 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5135 } else {
5136 if (s->r == LABEL_DECLARED)
5137 s->r = LABEL_FORWARD;
5139 vla_sp_restore_root();
5140 if (s->r & LABEL_FORWARD)
5141 s->jnext = gjmp(s->jnext);
5142 else
5143 gjmp_addr(s->jnext);
5144 next();
5145 } else {
5146 expect("label identifier");
5148 skip(';');
5149 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
5150 asm_instr();
5151 } else {
5152 b = is_label();
5153 if (b) {
5154 /* label case */
5155 s = label_find(b);
5156 if (s) {
5157 if (s->r == LABEL_DEFINED)
5158 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
5159 gsym(s->jnext);
5160 s->r = LABEL_DEFINED;
5161 } else {
5162 s = label_push(&global_label_stack, b, LABEL_DEFINED);
5164 s->jnext = ind;
5165 vla_sp_restore();
5166 /* we accept this, but it is a mistake */
5167 block_after_label:
5168 if (tok == '}') {
5169 tcc_warning("deprecated use of label at end of compound statement");
5170 } else {
5171 if (is_expr)
5172 vpop();
5173 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
5175 } else {
5176 /* expression case */
5177 if (tok != ';') {
5178 if (is_expr) {
5179 vpop();
5180 gexpr();
5181 } else {
5182 gexpr();
5183 vpop();
5186 skip(';');
5191 /* t is the array or struct type. c is the array or struct
5192 address. cur_index/cur_field is the pointer to the current
5193 value. 'size_only' is true if only size info is needed (only used
5194 in arrays) */
5195 static void decl_designator(CType *type, Section *sec, unsigned long c,
5196 int *cur_index, Sym **cur_field,
5197 int size_only)
5199 Sym *s, *f;
5200 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5201 CType type1;
5203 notfirst = 0;
5204 elem_size = 0;
5205 nb_elems = 1;
5206 if (gnu_ext && (l = is_label()) != 0)
5207 goto struct_field;
5208 while (tok == '[' || tok == '.') {
5209 if (tok == '[') {
5210 if (!(type->t & VT_ARRAY))
5211 expect("array type");
5212 s = type->ref;
5213 next();
5214 index = expr_const();
5215 if (index < 0 || (s->c >= 0 && index >= s->c))
5216 expect("invalid index");
5217 if (tok == TOK_DOTS && gnu_ext) {
5218 next();
5219 index_last = expr_const();
5220 if (index_last < 0 ||
5221 (s->c >= 0 && index_last >= s->c) ||
5222 index_last < index)
5223 expect("invalid index");
5224 } else {
5225 index_last = index;
5227 skip(']');
5228 if (!notfirst)
5229 *cur_index = index_last;
5230 type = pointed_type(type);
5231 elem_size = type_size(type, &align);
5232 c += index * elem_size;
5233 /* NOTE: we only support ranges for last designator */
5234 nb_elems = index_last - index + 1;
5235 if (nb_elems != 1) {
5236 notfirst = 1;
5237 break;
5239 } else {
5240 next();
5241 l = tok;
5242 next();
5243 struct_field:
5244 if ((type->t & VT_BTYPE) != VT_STRUCT)
5245 expect("struct/union type");
5246 s = type->ref;
5247 l |= SYM_FIELD;
5248 f = s->next;
5249 while (f) {
5250 if (f->v == l)
5251 break;
5252 f = f->next;
5254 if (!f)
5255 expect("field");
5256 if (!notfirst)
5257 *cur_field = f;
5258 /* XXX: fix this mess by using explicit storage field */
5259 type1 = f->type;
5260 type1.t |= (type->t & ~VT_TYPE);
5261 type = &type1;
5262 c += f->c;
5264 notfirst = 1;
5266 if (notfirst) {
5267 if (tok == '=') {
5268 next();
5269 } else {
5270 if (!gnu_ext)
5271 expect("=");
5273 } else {
5274 if (type->t & VT_ARRAY) {
5275 index = *cur_index;
5276 type = pointed_type(type);
5277 c += index * type_size(type, &align);
5278 } else {
5279 f = *cur_field;
5280 if (!f)
5281 tcc_error("too many field init");
5282 /* XXX: fix this mess by using explicit storage field */
5283 type1 = f->type;
5284 type1.t |= (type->t & ~VT_TYPE);
5285 type = &type1;
5286 c += f->c;
5289 decl_initializer(type, sec, c, 0, size_only);
5291 /* XXX: make it more general */
5292 if (!size_only && nb_elems > 1) {
5293 unsigned long c_end;
5294 uint8_t *src, *dst;
5295 int i;
5297 if (!sec)
5298 tcc_error("range init not supported yet for dynamic storage");
5299 c_end = c + nb_elems * elem_size;
5300 if (c_end > sec->data_allocated)
5301 section_realloc(sec, c_end);
5302 src = sec->data + c;
5303 dst = src;
5304 for(i = 1; i < nb_elems; i++) {
5305 dst += elem_size;
5306 memcpy(dst, src, elem_size);
5311 #define EXPR_VAL 0
5312 #define EXPR_CONST 1
5313 #define EXPR_ANY 2
5315 /* store a value or an expression directly in global data or in local array */
5316 static void init_putv(CType *type, Section *sec, unsigned long c,
5317 int v, int expr_type)
5319 int saved_global_expr, bt, bit_pos, bit_size;
5320 void *ptr;
5321 unsigned long long bit_mask;
5322 CType dtype;
5324 switch(expr_type) {
5325 case EXPR_VAL:
5326 vpushi(v);
5327 break;
5328 case EXPR_CONST:
5329 /* compound literals must be allocated globally in this case */
5330 saved_global_expr = global_expr;
5331 global_expr = 1;
5332 expr_const1();
5333 global_expr = saved_global_expr;
5334 /* NOTE: symbols are accepted */
5335 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5336 tcc_error("initializer element is not constant");
5337 break;
5338 case EXPR_ANY:
5339 expr_eq();
5340 break;
5343 dtype = *type;
5344 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5346 if (sec) {
5347 /* XXX: not portable */
5348 /* XXX: generate error if incorrect relocation */
5349 gen_assign_cast(&dtype);
5350 bt = type->t & VT_BTYPE;
5351 /* we'll write at most 16 bytes */
5352 if (c + 16 > sec->data_allocated) {
5353 section_realloc(sec, c + 16);
5355 ptr = sec->data + c;
5356 /* XXX: make code faster ? */
5357 if (!(type->t & VT_BITFIELD)) {
5358 bit_pos = 0;
5359 bit_size = 32;
5360 bit_mask = -1LL;
5361 } else {
5362 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5363 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5364 bit_mask = (1LL << bit_size) - 1;
5366 if ((vtop->r & VT_SYM) &&
5367 (bt == VT_BYTE ||
5368 bt == VT_SHORT ||
5369 bt == VT_DOUBLE ||
5370 bt == VT_LDOUBLE ||
5371 bt == VT_LLONG ||
5372 (bt == VT_INT && bit_size != 32)))
5373 tcc_error("initializer element is not computable at load time");
5374 switch(bt) {
5375 /* XXX: when cross-compiling we assume that each type has the
5376 same representation on host and target, which is likely to
5377 be wrong in the case of long double */
5378 case VT_BOOL:
5379 vtop->c.i = (vtop->c.i != 0);
5380 case VT_BYTE:
5381 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5382 break;
5383 case VT_SHORT:
5384 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5385 break;
5386 case VT_DOUBLE:
5387 *(double *)ptr = vtop->c.d;
5388 break;
5389 case VT_LDOUBLE:
5390 *(long double *)ptr = vtop->c.ld;
5391 break;
5392 case VT_LLONG:
5393 *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5394 break;
5395 case VT_PTR: {
5396 addr_t val = (vtop->c.i & bit_mask) << bit_pos;
5397 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5398 if (vtop->r & VT_SYM)
5399 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5400 else
5401 *(addr_t *)ptr |= val;
5402 #else
5403 if (vtop->r & VT_SYM)
5404 greloc(sec, vtop->sym, c, R_DATA_PTR);
5405 *(addr_t *)ptr |= val;
5406 #endif
5407 break;
5409 default: {
5410 int val = (vtop->c.i & bit_mask) << bit_pos;
5411 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5412 if (vtop->r & VT_SYM)
5413 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5414 else
5415 *(int *)ptr |= val;
5416 #else
5417 if (vtop->r & VT_SYM)
5418 greloc(sec, vtop->sym, c, R_DATA_PTR);
5419 *(int *)ptr |= val;
5420 #endif
5421 break;
5424 vtop--;
5425 } else {
5426 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5427 vswap();
5428 vstore();
5429 vpop();
5433 /* put zeros for variable based init */
5434 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5436 if (sec) {
5437 /* nothing to do because globals are already set to zero */
5438 } else {
5439 vpush_global_sym(&func_old_type, TOK_memset);
5440 vseti(VT_LOCAL, c);
5441 #ifdef TCC_TARGET_ARM
5442 vpushs(size);
5443 vpushi(0);
5444 #else
5445 vpushi(0);
5446 vpushs(size);
5447 #endif
5448 gfunc_call(3);
5452 /* 't' contains the type and storage info. 'c' is the offset of the
5453 object in section 'sec'. If 'sec' is NULL, it means stack based
5454 allocation. 'first' is true if array '{' must be read (multi
5455 dimension implicit array init handling). 'size_only' is true if
5456 size only evaluation is wanted (only for arrays). */
5457 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5458 int first, int size_only)
5460 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5461 int size1, align1, expr_type;
5462 Sym *s, *f;
5463 CType *t1;
5465 if (type->t & VT_VLA) {
5466 int a;
5468 /* save current stack pointer */
5469 if (vlas_in_scope == 0) {
5470 if (vla_sp_root_loc == -1)
5471 vla_sp_root_loc = (loc -= PTR_SIZE);
5472 gen_vla_sp_save(vla_sp_root_loc);
5475 vla_runtime_type_size(type, &a);
5476 gen_vla_alloc(type, a);
5477 gen_vla_sp_save(c);
5478 vla_sp_loc = c;
5479 vlas_in_scope++;
5480 } else if (type->t & VT_ARRAY) {
5481 s = type->ref;
5482 n = s->c;
5483 array_length = 0;
5484 t1 = pointed_type(type);
5485 size1 = type_size(t1, &align1);
5487 no_oblock = 1;
5488 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5489 tok == '{') {
5490 if (tok != '{')
5491 tcc_error("character array initializer must be a literal,"
5492 " optionally enclosed in braces");
5493 skip('{');
5494 no_oblock = 0;
5497 /* only parse strings here if correct type (otherwise: handle
5498 them as ((w)char *) expressions */
5499 if ((tok == TOK_LSTR &&
5500 #ifdef TCC_TARGET_PE
5501 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5502 #else
5503 (t1->t & VT_BTYPE) == VT_INT
5504 #endif
5505 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5506 while (tok == TOK_STR || tok == TOK_LSTR) {
5507 int cstr_len, ch;
5508 CString *cstr;
5510 cstr = tokc.cstr;
5511 /* compute maximum number of chars wanted */
5512 if (tok == TOK_STR)
5513 cstr_len = cstr->size;
5514 else
5515 cstr_len = cstr->size / sizeof(nwchar_t);
5516 cstr_len--;
5517 nb = cstr_len;
5518 if (n >= 0 && nb > (n - array_length))
5519 nb = n - array_length;
5520 if (!size_only) {
5521 if (cstr_len > nb)
5522 tcc_warning("initializer-string for array is too long");
5523 /* in order to go faster for common case (char
5524 string in global variable, we handle it
5525 specifically */
5526 if (sec && tok == TOK_STR && size1 == 1) {
5527 memcpy(sec->data + c + array_length, cstr->data, nb);
5528 } else {
5529 for(i=0;i<nb;i++) {
5530 if (tok == TOK_STR)
5531 ch = ((unsigned char *)cstr->data)[i];
5532 else
5533 ch = ((nwchar_t *)cstr->data)[i];
5534 init_putv(t1, sec, c + (array_length + i) * size1,
5535 ch, EXPR_VAL);
5539 array_length += nb;
5540 next();
5542 /* only add trailing zero if enough storage (no
5543 warning in this case since it is standard) */
5544 if (n < 0 || array_length < n) {
5545 if (!size_only) {
5546 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5548 array_length++;
5550 } else {
5551 index = 0;
5552 while (tok != '}') {
5553 decl_designator(type, sec, c, &index, NULL, size_only);
5554 if (n >= 0 && index >= n)
5555 tcc_error("index too large");
5556 /* must put zero in holes (note that doing it that way
5557 ensures that it even works with designators) */
5558 if (!size_only && array_length < index) {
5559 init_putz(t1, sec, c + array_length * size1,
5560 (index - array_length) * size1);
5562 index++;
5563 if (index > array_length)
5564 array_length = index;
5565 /* special test for multi dimensional arrays (may not
5566 be strictly correct if designators are used at the
5567 same time) */
5568 if (index >= n && no_oblock)
5569 break;
5570 if (tok == '}')
5571 break;
5572 skip(',');
5575 if (!no_oblock)
5576 skip('}');
5577 /* put zeros at the end */
5578 if (!size_only && n >= 0 && array_length < n) {
5579 init_putz(t1, sec, c + array_length * size1,
5580 (n - array_length) * size1);
5582 /* patch type size if needed */
5583 if (n < 0)
5584 s->c = array_length;
5585 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5586 (sec || !first || tok == '{')) {
5588 /* NOTE: the previous test is a specific case for automatic
5589 struct/union init */
5590 /* XXX: union needs only one init */
5592 int par_count = 0;
5593 if (tok == '(') {
5594 AttributeDef ad1;
5595 CType type1;
5596 next();
5597 if (tcc_state->old_struct_init_code) {
5598 /* an old version of struct initialization.
5599 It have a problems. But with a new version
5600 linux 2.4.26 can't load ramdisk.
5602 while (tok == '(') {
5603 par_count++;
5604 next();
5606 if (!parse_btype(&type1, &ad1))
5607 expect("cast");
5608 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5609 #if 0
5610 if (!is_assignable_types(type, &type1))
5611 tcc_error("invalid type for cast");
5612 #endif
5613 skip(')');
5615 else
5617 if (tok != '(') {
5618 if (!parse_btype(&type1, &ad1))
5619 expect("cast");
5620 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5621 #if 0
5622 if (!is_assignable_types(type, &type1))
5623 tcc_error("invalid type for cast");
5624 #endif
5625 skip(')');
5626 } else
5627 unget_tok(tok);
5631 no_oblock = 1;
5632 if (first || tok == '{') {
5633 skip('{');
5634 no_oblock = 0;
5636 s = type->ref;
5637 f = s->next;
5638 array_length = 0;
5639 index = 0;
5640 n = s->c;
5641 while (tok != '}') {
5642 decl_designator(type, sec, c, NULL, &f, size_only);
5643 index = f->c;
5644 if (!size_only && array_length < index) {
5645 init_putz(type, sec, c + array_length,
5646 index - array_length);
5648 index = index + type_size(&f->type, &align1);
5649 if (index > array_length)
5650 array_length = index;
5652 /* gr: skip fields from same union - ugly. */
5653 while (f->next) {
5654 int align = 0;
5655 int f_size = type_size(&f->type, &align);
5656 int f_type = (f->type.t & VT_BTYPE);
5658 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5659 /* test for same offset */
5660 if (f->next->c != f->c)
5661 break;
5662 if ((f_type == VT_STRUCT) && (f_size == 0)) {
5664 Lets assume a structure of size 0 can't be a member of the union.
5665 This allow to compile the following code from a linux kernel v2.4.26
5666 typedef struct { } rwlock_t;
5667 struct fs_struct {
5668 int count;
5669 rwlock_t lock;
5670 int umask;
5672 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
5673 tcc-0.9.23 can succesfully compile this version of the kernel.
5674 gcc don't have problems with this code too.
5676 break;
5678 /* if yes, test for bitfield shift */
5679 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5680 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5681 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5682 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5683 if (bit_pos_1 != bit_pos_2)
5684 break;
5686 f = f->next;
5689 f = f->next;
5690 if (no_oblock && f == NULL)
5691 break;
5692 if (tok == '}')
5693 break;
5694 skip(',');
5696 /* put zeros at the end */
5697 if (!size_only && array_length < n) {
5698 init_putz(type, sec, c + array_length,
5699 n - array_length);
5701 if (!no_oblock)
5702 skip('}');
5703 while (par_count) {
5704 skip(')');
5705 par_count--;
5707 } else if (tok == '{') {
5708 next();
5709 decl_initializer(type, sec, c, first, size_only);
5710 skip('}');
5711 } else if (size_only) {
5712 /* just skip expression */
5713 parlevel = parlevel1 = 0;
5714 while ((parlevel > 0 || parlevel1 > 0 ||
5715 (tok != '}' && tok != ',')) && tok != -1) {
5716 if (tok == '(')
5717 parlevel++;
5718 else if (tok == ')') {
5719 if (parlevel == 0 && parlevel1 == 0)
5720 break;
5721 parlevel--;
5723 else if (tok == '{')
5724 parlevel1++;
5725 else if (tok == '}') {
5726 if (parlevel == 0 && parlevel1 == 0)
5727 break;
5728 parlevel1--;
5730 next();
5732 } else {
5733 /* currently, we always use constant expression for globals
5734 (may change for scripting case) */
5735 expr_type = EXPR_CONST;
5736 if (!sec)
5737 expr_type = EXPR_ANY;
5738 init_putv(type, sec, c, 0, expr_type);
5742 /* parse an initializer for type 't' if 'has_init' is non zero, and
5743 allocate space in local or global data space ('r' is either
5744 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5745 variable 'v' with an associated name represented by 'asm_label' of
5746 scope 'scope' is declared before initializers are parsed. If 'v' is
5747 zero, then a reference to the new object is put in the value stack.
5748 If 'has_init' is 2, a special parsing is done to handle string
5749 constants. */
5750 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5751 int has_init, int v, char *asm_label,
5752 int scope)
5754 int size, align, addr, data_offset;
5755 int level;
5756 ParseState saved_parse_state = {0};
5757 TokenString init_str;
5758 Section *sec;
5759 Sym *flexible_array;
5761 flexible_array = NULL;
5762 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5763 Sym *field = type->ref->next;
5764 if (field) {
5765 while (field->next)
5766 field = field->next;
5767 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5768 flexible_array = field;
5772 size = type_size(type, &align);
5773 /* If unknown size, we must evaluate it before
5774 evaluating initializers because
5775 initializers can generate global data too
5776 (e.g. string pointers or ISOC99 compound
5777 literals). It also simplifies local
5778 initializers handling */
5779 tok_str_new(&init_str);
5780 if (size < 0 || (flexible_array && has_init)) {
5781 if (!has_init)
5782 tcc_error("unknown type size");
5783 /* get all init string */
5784 if (has_init == 2) {
5785 /* only get strings */
5786 while (tok == TOK_STR || tok == TOK_LSTR) {
5787 tok_str_add_tok(&init_str);
5788 next();
5790 } else {
5791 level = 0;
5792 while (level > 0 || (tok != ',' && tok != ';')) {
5793 if (tok < 0)
5794 tcc_error("unexpected end of file in initializer");
5795 tok_str_add_tok(&init_str);
5796 if (tok == '{')
5797 level++;
5798 else if (tok == '}') {
5799 level--;
5800 if (level <= 0) {
5801 next();
5802 break;
5805 next();
5808 tok_str_add(&init_str, -1);
5809 tok_str_add(&init_str, 0);
5811 /* compute size */
5812 save_parse_state(&saved_parse_state);
5814 begin_macro(&init_str, 0);
5815 next();
5816 decl_initializer(type, NULL, 0, 1, 1);
5817 /* prepare second initializer parsing */
5818 macro_ptr = init_str.str;
5819 next();
5821 /* if still unknown size, error */
5822 size = type_size(type, &align);
5823 if (size < 0)
5824 tcc_error("unknown type size");
5826 if (flexible_array)
5827 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5828 /* take into account specified alignment if bigger */
5829 if (ad->a.aligned) {
5830 if (ad->a.aligned > align)
5831 align = ad->a.aligned;
5832 } else if (ad->a.packed) {
5833 align = 1;
5835 if ((r & VT_VALMASK) == VT_LOCAL) {
5836 sec = NULL;
5837 #ifdef CONFIG_TCC_BCHECK
5838 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5839 loc--;
5841 #endif
5842 loc = (loc - size) & -align;
5843 addr = loc;
5844 #ifdef CONFIG_TCC_BCHECK
5845 /* handles bounds */
5846 /* XXX: currently, since we do only one pass, we cannot track
5847 '&' operators, so we add only arrays */
5848 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5849 addr_t *bounds_ptr;
5850 /* add padding between regions */
5851 loc--;
5852 /* then add local bound info */
5853 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
5854 bounds_ptr[0] = addr;
5855 bounds_ptr[1] = size;
5857 #endif
5858 if (v) {
5859 /* local variable */
5860 sym_push(v, type, r, addr);
5861 } else {
5862 /* push local reference */
5863 vset(type, r, addr);
5865 } else {
5866 Sym *sym;
5868 sym = NULL;
5869 if (v && scope == VT_CONST) {
5870 /* see if the symbol was already defined */
5871 sym = sym_find(v);
5872 if (sym) {
5873 if (!is_compatible_types(&sym->type, type))
5874 tcc_error("incompatible types for redefinition of '%s'",
5875 get_tok_str(v, NULL));
5876 if (sym->type.t & VT_EXTERN) {
5877 /* if the variable is extern, it was not allocated */
5878 sym->type.t &= ~VT_EXTERN;
5879 /* set array size if it was omitted in extern
5880 declaration */
5881 if ((sym->type.t & VT_ARRAY) &&
5882 sym->type.ref->c < 0 &&
5883 type->ref->c >= 0)
5884 sym->type.ref->c = type->ref->c;
5885 } else {
5886 /* we accept several definitions of the same
5887 global variable. this is tricky, because we
5888 must play with the SHN_COMMON type of the symbol */
5889 /* XXX: should check if the variable was already
5890 initialized. It is incorrect to initialized it
5891 twice */
5892 /* no init data, we won't add more to the symbol */
5893 if (!has_init)
5894 goto no_alloc;
5899 /* allocate symbol in corresponding section */
5900 sec = ad->section;
5901 if (!sec) {
5902 if (has_init)
5903 sec = data_section;
5904 else if (tcc_state->nocommon)
5905 sec = bss_section;
5907 if (sec) {
5908 data_offset = sec->data_offset;
5909 data_offset = (data_offset + align - 1) & -align;
5910 addr = data_offset;
5911 /* very important to increment global pointer at this time
5912 because initializers themselves can create new initializers */
5913 data_offset += size;
5914 #ifdef CONFIG_TCC_BCHECK
5915 /* add padding if bound check */
5916 if (tcc_state->do_bounds_check)
5917 data_offset++;
5918 #endif
5919 sec->data_offset = data_offset;
5920 /* allocate section space to put the data */
5921 if (sec->sh_type != SHT_NOBITS &&
5922 data_offset > sec->data_allocated)
5923 section_realloc(sec, data_offset);
5924 /* align section if needed */
5925 if (align > sec->sh_addralign)
5926 sec->sh_addralign = align;
5927 } else {
5928 addr = 0; /* avoid warning */
5931 if (v) {
5932 if (scope != VT_CONST || !sym) {
5933 sym = sym_push(v, type, r | VT_SYM, 0);
5934 sym->asm_label = asm_label ? tcc_strdup(asm_label) : 0;
5936 /* update symbol definition */
5937 if (sec) {
5938 put_extern_sym(sym, sec, addr, size);
5939 } else {
5940 ElfW(Sym) *esym;
5941 /* put a common area */
5942 put_extern_sym(sym, NULL, align, size);
5943 /* XXX: find a nicer way */
5944 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5945 esym->st_shndx = SHN_COMMON;
5947 } else {
5948 /* push global reference */
5949 sym = get_sym_ref(type, sec, addr, size);
5950 vpushsym(type, sym);
5952 /* patch symbol weakness */
5953 if (type->t & VT_WEAK)
5954 weaken_symbol(sym);
5955 apply_visibility(sym, type);
5956 #ifdef CONFIG_TCC_BCHECK
5957 /* handles bounds now because the symbol must be defined
5958 before for the relocation */
5959 if (tcc_state->do_bounds_check) {
5960 addr_t *bounds_ptr;
5962 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5963 /* then add global bound info */
5964 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
5965 bounds_ptr[0] = 0; /* relocated */
5966 bounds_ptr[1] = size;
5968 #endif
5970 if (has_init || (type->t & VT_VLA)) {
5971 decl_initializer(type, sec, addr, 1, 0);
5972 /* restore parse state if needed */
5973 if (init_str.str) {
5974 end_macro();
5975 restore_parse_state(&saved_parse_state);
5977 /* patch flexible array member size back to -1, */
5978 /* for possible subsequent similar declarations */
5979 if (flexible_array)
5980 flexible_array->type.ref->c = -1;
5982 no_alloc: ;
5985 static void put_func_debug(Sym *sym)
5987 char buf[512];
5989 /* stabs info */
5990 /* XXX: we put here a dummy type */
5991 snprintf(buf, sizeof(buf), "%s:%c1",
5992 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5993 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5994 cur_text_section, sym->c);
5995 /* //gr gdb wants a line at the function */
5996 put_stabn(N_SLINE, 0, file->line_num, 0);
5997 last_ind = 0;
5998 last_line_num = 0;
6001 /* parse an old style function declaration list */
6002 /* XXX: check multiple parameter */
6003 static void func_decl_list(Sym *func_sym)
6005 AttributeDef ad;
6006 int v;
6007 Sym *s;
6008 CType btype, type;
6010 /* parse each declaration */
6011 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
6012 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
6013 if (!parse_btype(&btype, &ad))
6014 expect("declaration list");
6015 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6016 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6017 tok == ';') {
6018 /* we accept no variable after */
6019 } else {
6020 for(;;) {
6021 type = btype;
6022 type_decl(&type, &ad, &v, TYPE_DIRECT);
6023 /* find parameter in function parameter list */
6024 s = func_sym->next;
6025 while (s != NULL) {
6026 if ((s->v & ~SYM_FIELD) == v)
6027 goto found;
6028 s = s->next;
6030 tcc_error("declaration for parameter '%s' but no such parameter",
6031 get_tok_str(v, NULL));
6032 found:
6033 /* check that no storage specifier except 'register' was given */
6034 if (type.t & VT_STORAGE)
6035 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
6036 convert_parameter_type(&type);
6037 /* we can add the type (NOTE: it could be local to the function) */
6038 s->type = type;
6039 /* accept other parameters */
6040 if (tok == ',')
6041 next();
6042 else
6043 break;
6046 skip(';');
6050 /* parse a function defined by symbol 'sym' and generate its code in
6051 'cur_text_section' */
6052 static void gen_function(Sym *sym)
6054 int saved_nocode_wanted = nocode_wanted;
6056 nocode_wanted = 0;
6057 ind = cur_text_section->data_offset;
6058 /* NOTE: we patch the symbol size later */
6059 put_extern_sym(sym, cur_text_section, ind, 0);
6060 funcname = get_tok_str(sym->v, NULL);
6061 func_ind = ind;
6062 /* Initialize VLA state */
6063 vla_sp_loc = -1;
6064 vla_sp_root_loc = -1;
6065 /* put debug symbol */
6066 if (tcc_state->do_debug)
6067 put_func_debug(sym);
6068 /* push a dummy symbol to enable local sym storage */
6069 sym_push2(&local_stack, SYM_FIELD, 0, 0);
6070 gfunc_prolog(&sym->type);
6071 #ifdef CONFIG_TCC_BCHECK
6072 if (tcc_state->do_bounds_check && !strcmp(funcname, "main")) {
6073 int i;
6074 Sym *sym;
6075 for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) {
6076 if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD)
6077 break;
6078 vpush_global_sym(&func_old_type, TOK___bound_main_arg);
6079 vset(&sym->type, sym->r, sym->c);
6080 gfunc_call(1);
6083 #endif
6084 rsym = 0;
6085 block(NULL, NULL, NULL, NULL, 0, 0);
6086 gsym(rsym);
6087 gfunc_epilog();
6088 cur_text_section->data_offset = ind;
6089 label_pop(&global_label_stack, NULL);
6090 /* reset local stack */
6091 scope_stack_bottom = NULL;
6092 sym_pop(&local_stack, NULL);
6093 /* end of function */
6094 /* patch symbol size */
6095 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
6096 ind - func_ind;
6097 /* patch symbol weakness (this definition overrules any prototype) */
6098 if (sym->type.t & VT_WEAK)
6099 weaken_symbol(sym);
6100 apply_visibility(sym, &sym->type);
6101 if (tcc_state->do_debug) {
6102 put_stabn(N_FUN, 0, 0, ind - func_ind);
6104 /* It's better to crash than to generate wrong code */
6105 cur_text_section = NULL;
6106 funcname = ""; /* for safety */
6107 func_vt.t = VT_VOID; /* for safety */
6108 func_var = 0; /* for safety */
6109 ind = 0; /* for safety */
6110 nocode_wanted = saved_nocode_wanted;
6111 check_vstack();
6114 ST_FUNC void gen_inline_functions(void)
6116 Sym *sym;
6117 int inline_generated, i, ln;
6118 struct InlineFunc *fn;
6120 ln = file->line_num;
6121 /* iterate while inline function are referenced */
6122 for(;;) {
6123 inline_generated = 0;
6124 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6125 fn = tcc_state->inline_fns[i];
6126 sym = fn->sym;
6127 if (sym && sym->c) {
6128 /* the function was used: generate its code and
6129 convert it to a normal function */
6130 fn->sym = NULL;
6131 if (file)
6132 pstrcpy(file->filename, sizeof file->filename, fn->filename);
6133 sym->r = VT_SYM | VT_CONST;
6134 sym->type.t &= ~VT_INLINE;
6136 begin_macro(&fn->func_str, 0);
6137 next();
6138 cur_text_section = text_section;
6139 gen_function(sym);
6140 end_macro();
6142 inline_generated = 1;
6145 if (!inline_generated)
6146 break;
6148 file->line_num = ln;
6149 /* free tokens of unused inline functions */
6150 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6151 fn = tcc_state->inline_fns[i];
6152 if (fn->sym)
6153 tok_str_free(fn->func_str.str);
6155 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
6158 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6159 static int decl0(int l, int is_for_loop_init)
6161 int v, has_init, r;
6162 CType type, btype;
6163 Sym *sym;
6164 AttributeDef ad;
6165 char *asm_label = 0; // associated asm label
6167 while (1) {
6168 if (!parse_btype(&btype, &ad)) {
6169 if (is_for_loop_init)
6170 return 0;
6171 /* skip redundant ';' */
6172 /* XXX: find more elegant solution */
6173 if (tok == ';') {
6174 next();
6175 continue;
6177 if (l == VT_CONST &&
6178 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6179 /* global asm block */
6180 asm_global_instr();
6181 continue;
6183 /* special test for old K&R protos without explicit int
6184 type. Only accepted when defining global data */
6185 if (l == VT_LOCAL || tok < TOK_DEFINE)
6186 break;
6187 btype.t = VT_INT;
6189 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6190 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6191 tok == ';') {
6192 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
6193 int v = btype.ref->v;
6194 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
6195 tcc_warning("unnamed struct/union that defines no instances");
6197 next();
6198 continue;
6200 while (1) { /* iterate thru each declaration */
6201 type = btype;
6202 type_decl(&type, &ad, &v, TYPE_DIRECT);
6203 #if 0
6205 char buf[500];
6206 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6207 printf("type = '%s'\n", buf);
6209 #endif
6210 if ((type.t & VT_BTYPE) == VT_FUNC) {
6211 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
6212 tcc_error("function without file scope cannot be static");
6214 /* if old style function prototype, we accept a
6215 declaration list */
6216 sym = type.ref;
6217 if (sym->c == FUNC_OLD)
6218 func_decl_list(sym);
6221 tcc_free(asm_label);
6222 asm_label = 0;
6223 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6224 CString astr;
6226 asm_label_instr(&astr);
6227 asm_label = tcc_strdup(astr.data);
6228 cstr_free(&astr);
6230 /* parse one last attribute list, after asm label */
6231 parse_attribute(&ad);
6234 if (ad.a.weak)
6235 type.t |= VT_WEAK;
6236 #ifdef TCC_TARGET_PE
6237 if (ad.a.func_import)
6238 type.t |= VT_IMPORT;
6239 if (ad.a.func_export)
6240 type.t |= VT_EXPORT;
6241 #endif
6242 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6244 if (tok == '{') {
6245 if (l == VT_LOCAL)
6246 tcc_error("cannot use local functions");
6247 if ((type.t & VT_BTYPE) != VT_FUNC)
6248 expect("function definition");
6250 /* reject abstract declarators in function definition */
6251 sym = type.ref;
6252 while ((sym = sym->next) != NULL)
6253 if (!(sym->v & ~SYM_FIELD))
6254 expect("identifier");
6256 /* XXX: cannot do better now: convert extern line to static inline */
6257 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6258 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6260 sym = sym_find(v);
6261 if (sym) {
6262 Sym *ref;
6263 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6264 goto func_error1;
6266 ref = sym->type.ref;
6267 if (0 == ref->a.func_proto)
6268 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6270 /* use func_call from prototype if not defined */
6271 if (ref->a.func_call != FUNC_CDECL
6272 && type.ref->a.func_call == FUNC_CDECL)
6273 type.ref->a.func_call = ref->a.func_call;
6275 /* use export from prototype */
6276 if (ref->a.func_export)
6277 type.ref->a.func_export = 1;
6279 /* use static from prototype */
6280 if (sym->type.t & VT_STATIC)
6281 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6283 /* If the definition has no visibility use the
6284 one from prototype. */
6285 if (! (type.t & VT_VIS_MASK))
6286 type.t |= sym->type.t & VT_VIS_MASK;
6288 if (!is_compatible_types(&sym->type, &type)) {
6289 func_error1:
6290 tcc_error("incompatible types for redefinition of '%s'",
6291 get_tok_str(v, NULL));
6293 type.ref->a.func_proto = 0;
6294 /* if symbol is already defined, then put complete type */
6295 sym->type = type;
6296 } else {
6297 /* put function symbol */
6298 sym = global_identifier_push(v, type.t, 0);
6299 sym->type.ref = type.ref;
6302 /* static inline functions are just recorded as a kind
6303 of macro. Their code will be emitted at the end of
6304 the compilation unit only if they are used */
6305 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6306 (VT_INLINE | VT_STATIC)) {
6307 int block_level;
6308 struct InlineFunc *fn;
6309 const char *filename;
6311 filename = file ? file->filename : "";
6312 fn = tcc_malloc(sizeof *fn + strlen(filename));
6313 strcpy(fn->filename, filename);
6314 fn->sym = sym;
6315 tok_str_new(&fn->func_str);
6317 block_level = 0;
6318 for(;;) {
6319 int t;
6320 if (tok == TOK_EOF)
6321 tcc_error("unexpected end of file");
6322 tok_str_add_tok(&fn->func_str);
6323 t = tok;
6324 next();
6325 if (t == '{') {
6326 block_level++;
6327 } else if (t == '}') {
6328 block_level--;
6329 if (block_level == 0)
6330 break;
6333 tok_str_add(&fn->func_str, -1);
6334 tok_str_add(&fn->func_str, 0);
6335 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6337 } else {
6338 /* compute text section */
6339 cur_text_section = ad.section;
6340 if (!cur_text_section)
6341 cur_text_section = text_section;
6342 sym->r = VT_SYM | VT_CONST;
6343 gen_function(sym);
6345 break;
6346 } else {
6347 if (btype.t & VT_TYPEDEF) {
6348 /* save typedefed type */
6349 /* XXX: test storage specifiers ? */
6350 sym = sym_push(v, &type, 0, 0);
6351 sym->a = ad.a;
6352 sym->type.t |= VT_TYPEDEF;
6353 } else {
6354 r = 0;
6355 if ((type.t & VT_BTYPE) == VT_FUNC) {
6356 /* external function definition */
6357 /* specific case for func_call attribute */
6358 ad.a.func_proto = 1;
6359 type.ref->a = ad.a;
6360 } else if (!(type.t & VT_ARRAY)) {
6361 /* not lvalue if array */
6362 r |= lvalue_type(type.t);
6364 has_init = (tok == '=');
6365 if (has_init && (type.t & VT_VLA))
6366 tcc_error("Variable length array cannot be initialized");
6367 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6368 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6369 !has_init && l == VT_CONST && type.ref->c < 0)) {
6370 /* external variable or function */
6371 /* NOTE: as GCC, uninitialized global static
6372 arrays of null size are considered as
6373 extern */
6374 sym = external_sym(v, &type, r, asm_label);
6376 if (ad.alias_target) {
6377 Section tsec;
6378 Elf32_Sym *esym;
6379 Sym *alias_target;
6381 alias_target = sym_find(ad.alias_target);
6382 if (!alias_target || !alias_target->c)
6383 tcc_error("unsupported forward __alias__ attribute");
6384 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6385 tsec.sh_num = esym->st_shndx;
6386 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6388 } else {
6389 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6390 if (type.t & VT_STATIC)
6391 r |= VT_CONST;
6392 else
6393 r |= l;
6394 if (has_init)
6395 next();
6396 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
6399 if (tok != ',') {
6400 if (is_for_loop_init) {
6401 tcc_free(asm_label);
6402 return 1;
6404 skip(';');
6405 break;
6407 next();
6409 ad.a.aligned = 0;
6412 tcc_free(asm_label);
6413 return 0;
6416 ST_FUNC void decl(int l)
6418 decl0(l, 0);