switch: fix label sorting
[tinycc.git] / tccgen.c
blob6f7cf1f4ff0587998b4f0ce0204428b047fa7619
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 *define_stack;
54 ST_DATA Sym *global_label_stack;
55 ST_DATA Sym *local_label_stack;
56 static int local_scope;
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 ST_DATA struct switch_t {
76 struct case_t {
77 int v1, v2, sym;
78 } **p; int n; /* list of case ranges */
79 int def_sym; /* default symbol */
80 } *cur_switch; /* current switch */
82 /* ------------------------------------------------------------------------- */
83 static void gen_cast(CType *type);
84 static inline CType *pointed_type(CType *type);
85 static int is_compatible_types(CType *type1, CType *type2);
86 static int parse_btype(CType *type, AttributeDef *ad);
87 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
88 static void parse_expr_type(CType *type);
89 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
90 static void block(int *bsym, int *csym, int is_expr);
91 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
92 static int decl0(int l, int is_for_loop_init);
93 static void expr_eq(void);
94 static void expr_lor_const(void);
95 static void unary_type(CType *type);
96 static void vla_runtime_type_size(CType *type, int *a);
97 static void vla_sp_restore(void);
98 static void vla_sp_restore_root(void);
99 static int is_compatible_parameter_types(CType *type1, CType *type2);
100 static void expr_type(CType *type);
101 ST_FUNC void vpush64(int ty, unsigned long long v);
102 ST_FUNC void vpush(CType *type);
103 ST_FUNC int gvtst(int inv, int t);
104 ST_FUNC int is_btype_size(int bt);
106 ST_INLN int is_float(int t)
108 int bt;
109 bt = t & VT_BTYPE;
110 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
113 /* we use our own 'finite' function to avoid potential problems with
114 non standard math libs */
115 /* XXX: endianness dependent */
116 ST_FUNC int ieee_finite(double d)
118 int p[4];
119 memcpy(p, &d, sizeof(double));
120 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
123 ST_FUNC void test_lvalue(void)
125 if (!(vtop->r & VT_LVAL))
126 expect("lvalue");
129 ST_FUNC void check_vstack(void)
131 if (pvtop != vtop)
132 tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
135 /* ------------------------------------------------------------------------- */
136 /* symbol allocator */
137 static Sym *__sym_malloc(void)
139 Sym *sym_pool, *sym, *last_sym;
140 int i;
142 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
143 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
145 last_sym = sym_free_first;
146 sym = sym_pool;
147 for(i = 0; i < SYM_POOL_NB; i++) {
148 sym->next = last_sym;
149 last_sym = sym;
150 sym++;
152 sym_free_first = last_sym;
153 return last_sym;
156 static inline Sym *sym_malloc(void)
158 Sym *sym;
159 sym = sym_free_first;
160 if (!sym)
161 sym = __sym_malloc();
162 sym_free_first = sym->next;
163 return sym;
166 ST_INLN void sym_free(Sym *sym)
168 sym->next = sym_free_first;
169 sym_free_first = sym;
172 /* push, without hashing */
173 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
175 Sym *s;
177 s = sym_malloc();
178 s->asm_label = 0;
179 s->v = v;
180 s->type.t = t;
181 s->type.ref = NULL;
182 #ifdef _WIN64
183 s->d = NULL;
184 #endif
185 s->c = c;
186 s->next = NULL;
187 /* add in stack */
188 s->prev = *ps;
189 *ps = s;
190 return s;
193 /* find a symbol and return its associated structure. 's' is the top
194 of the symbol stack */
195 ST_FUNC Sym *sym_find2(Sym *s, int v)
197 while (s) {
198 if (s->v == v)
199 return s;
200 else if (s->v == -1)
201 return NULL;
202 s = s->prev;
204 return NULL;
207 /* structure lookup */
208 ST_INLN Sym *struct_find(int v)
210 v -= TOK_IDENT;
211 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
212 return NULL;
213 return table_ident[v]->sym_struct;
216 /* find an identifier */
217 ST_INLN Sym *sym_find(int v)
219 v -= TOK_IDENT;
220 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
221 return NULL;
222 return table_ident[v]->sym_identifier;
225 /* push a given symbol on the symbol stack */
226 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
228 Sym *s, **ps;
229 TokenSym *ts;
231 if (local_stack)
232 ps = &local_stack;
233 else
234 ps = &global_stack;
235 s = sym_push2(ps, v, type->t, c);
236 s->type.ref = type->ref;
237 s->r = r;
238 /* don't record fields or anonymous symbols */
239 /* XXX: simplify */
240 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
241 /* record symbol in token array */
242 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
243 if (v & SYM_STRUCT)
244 ps = &ts->sym_struct;
245 else
246 ps = &ts->sym_identifier;
247 s->prev_tok = *ps;
248 *ps = s;
249 s->scope = local_scope;
250 if (s->prev_tok && s->prev_tok->scope == s->scope)
251 tcc_error("redeclaration of '%s'",
252 get_tok_str(v & ~SYM_STRUCT, NULL));
254 return s;
257 /* push a global identifier */
258 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
260 Sym *s, **ps;
261 s = sym_push2(&global_stack, v, t, c);
262 /* don't record anonymous symbol */
263 if (v < SYM_FIRST_ANOM) {
264 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
265 /* modify the top most local identifier, so that
266 sym_identifier will point to 's' when popped */
267 while (*ps != NULL)
268 ps = &(*ps)->prev_tok;
269 s->prev_tok = NULL;
270 *ps = s;
272 return s;
275 /* pop symbols until top reaches 'b' */
276 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
278 Sym *s, *ss, **ps;
279 TokenSym *ts;
280 int v;
282 s = *ptop;
283 while(s != b) {
284 ss = s->prev;
285 v = s->v;
286 /* remove symbol in token array */
287 /* XXX: simplify */
288 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
289 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
290 if (v & SYM_STRUCT)
291 ps = &ts->sym_struct;
292 else
293 ps = &ts->sym_identifier;
294 *ps = s->prev_tok;
296 sym_free(s);
297 s = ss;
299 *ptop = b;
302 static void weaken_symbol(Sym *sym)
304 sym->type.t |= VT_WEAK;
305 if (sym->c > 0) {
306 int esym_type;
307 ElfW(Sym) *esym;
309 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
310 esym_type = ELFW(ST_TYPE)(esym->st_info);
311 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
315 static void apply_visibility(Sym *sym, CType *type)
317 int vis = sym->type.t & VT_VIS_MASK;
318 int vis2 = type->t & VT_VIS_MASK;
319 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
320 vis = vis2;
321 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
323 else
324 vis = (vis < vis2) ? vis : vis2;
325 sym->type.t &= ~VT_VIS_MASK;
326 sym->type.t |= vis;
328 if (sym->c > 0) {
329 ElfW(Sym) *esym;
331 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
332 vis >>= VT_VIS_SHIFT;
333 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
337 /* ------------------------------------------------------------------------- */
339 ST_FUNC void swap(int *p, int *q)
341 int t;
342 t = *p;
343 *p = *q;
344 *q = t;
347 static void vsetc(CType *type, int r, CValue *vc)
349 int v;
351 if (vtop >= vstack + (VSTACK_SIZE - 1))
352 tcc_error("memory full (vstack)");
353 /* cannot let cpu flags if other instruction are generated. Also
354 avoid leaving VT_JMP anywhere except on the top of the stack
355 because it would complicate the code generator. */
356 if (vtop >= vstack) {
357 v = vtop->r & VT_VALMASK;
358 if (v == VT_CMP || (v & ~1) == VT_JMP)
359 gv(RC_INT);
361 vtop++;
362 vtop->type = *type;
363 vtop->r = r;
364 vtop->r2 = VT_CONST;
365 vtop->c = *vc;
368 /* push constant of type "type" with useless value */
369 ST_FUNC void vpush(CType *type)
371 CValue cval;
372 vsetc(type, VT_CONST, &cval);
375 /* push integer constant */
376 ST_FUNC void vpushi(int v)
378 CValue cval;
379 cval.i = v;
380 vsetc(&int_type, VT_CONST, &cval);
383 /* push a pointer sized constant */
384 static void vpushs(addr_t v)
386 CValue cval;
387 cval.i = v;
388 vsetc(&size_type, VT_CONST, &cval);
391 /* push arbitrary 64bit constant */
392 ST_FUNC void vpush64(int ty, unsigned long long v)
394 CValue cval;
395 CType ctype;
396 ctype.t = ty;
397 ctype.ref = NULL;
398 cval.i = v;
399 vsetc(&ctype, VT_CONST, &cval);
402 /* push long long constant */
403 static inline void vpushll(long long v)
405 vpush64(VT_LLONG, v);
408 /* push a symbol value of TYPE */
409 static inline void vpushsym(CType *type, Sym *sym)
411 CValue cval;
412 cval.i = 0;
413 vsetc(type, VT_CONST | VT_SYM, &cval);
414 vtop->sym = sym;
417 /* Return a static symbol pointing to a section */
418 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
420 int v;
421 Sym *sym;
423 v = anon_sym++;
424 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
425 sym->type.ref = type->ref;
426 sym->r = VT_CONST | VT_SYM;
427 put_extern_sym(sym, sec, offset, size);
428 return sym;
431 /* push a reference to a section offset by adding a dummy symbol */
432 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
434 vpushsym(type, get_sym_ref(type, sec, offset, size));
437 /* define a new external reference to a symbol 'v' of type 'u' */
438 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
440 Sym *s;
442 s = sym_find(v);
443 if (!s) {
444 /* push forward reference */
445 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
446 s->type.ref = type->ref;
447 s->r = r | VT_CONST | VT_SYM;
449 return s;
452 /* define a new external reference to a symbol 'v' */
453 static Sym *external_sym(int v, CType *type, int r)
455 Sym *s;
457 s = sym_find(v);
458 if (!s) {
459 /* push forward reference */
460 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
461 s->type.t |= VT_EXTERN;
462 } else if (s->type.ref == func_old_type.ref) {
463 s->type.ref = type->ref;
464 s->r = r | VT_CONST | VT_SYM;
465 s->type.t |= VT_EXTERN;
466 } else if (!is_compatible_types(&s->type, type)) {
467 tcc_error("incompatible types for redefinition of '%s'",
468 get_tok_str(v, NULL));
470 /* Merge some storage attributes. */
471 if (type->t & VT_WEAK)
472 weaken_symbol(s);
474 if (type->t & VT_VIS_MASK)
475 apply_visibility(s, type);
477 return s;
480 /* push a reference to global symbol v */
481 ST_FUNC void vpush_global_sym(CType *type, int v)
483 vpushsym(type, external_global_sym(v, type, 0));
486 ST_FUNC void vset(CType *type, int r, int v)
488 CValue cval;
490 cval.i = v;
491 vsetc(type, r, &cval);
494 static void vseti(int r, int v)
496 CType type;
497 type.t = VT_INT;
498 type.ref = 0;
499 vset(&type, r, v);
502 ST_FUNC void vswap(void)
504 SValue tmp;
505 /* cannot let cpu flags if other instruction are generated. Also
506 avoid leaving VT_JMP anywhere except on the top of the stack
507 because it would complicate the code generator. */
508 if (vtop >= vstack) {
509 int v = vtop->r & VT_VALMASK;
510 if (v == VT_CMP || (v & ~1) == VT_JMP)
511 gv(RC_INT);
513 tmp = vtop[0];
514 vtop[0] = vtop[-1];
515 vtop[-1] = tmp;
517 /* XXX: +2% overall speed possible with optimized memswap
519 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
523 ST_FUNC void vpushv(SValue *v)
525 if (vtop >= vstack + (VSTACK_SIZE - 1))
526 tcc_error("memory full (vstack)");
527 vtop++;
528 *vtop = *v;
531 static void vdup(void)
533 vpushv(vtop);
536 /* save r to the memory stack, and mark it as being free */
537 ST_FUNC void save_reg(int r)
539 int l, saved, size, align;
540 SValue *p, sv;
541 CType *type;
543 /* modify all stack values */
544 saved = 0;
545 l = 0;
546 for(p=vstack;p<=vtop;p++) {
547 if ((p->r & VT_VALMASK) == r ||
548 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
549 /* must save value on stack if not already done */
550 if (!saved) {
551 /* NOTE: must reload 'r' because r might be equal to r2 */
552 r = p->r & VT_VALMASK;
553 /* store register in the stack */
554 type = &p->type;
555 if ((p->r & VT_LVAL) ||
556 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
557 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
558 type = &char_pointer_type;
559 #else
560 type = &int_type;
561 #endif
562 size = type_size(type, &align);
563 loc = (loc - size) & -align;
564 sv.type.t = type->t;
565 sv.r = VT_LOCAL | VT_LVAL;
566 sv.c.i = loc;
567 store(r, &sv);
568 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
569 /* x86 specific: need to pop fp register ST0 if saved */
570 if (r == TREG_ST0) {
571 o(0xd8dd); /* fstp %st(0) */
573 #endif
574 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
575 /* special long long case */
576 if ((type->t & VT_BTYPE) == VT_LLONG) {
577 sv.c.i += 4;
578 store(p->r2, &sv);
580 #endif
581 l = loc;
582 saved = 1;
584 /* mark that stack entry as being saved on the stack */
585 if (p->r & VT_LVAL) {
586 /* also clear the bounded flag because the
587 relocation address of the function was stored in
588 p->c.i */
589 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
590 } else {
591 p->r = lvalue_type(p->type.t) | VT_LOCAL;
593 p->r2 = VT_CONST;
594 p->c.i = l;
599 #ifdef TCC_TARGET_ARM
600 /* find a register of class 'rc2' with at most one reference on stack.
601 * If none, call get_reg(rc) */
602 ST_FUNC int get_reg_ex(int rc, int rc2)
604 int r;
605 SValue *p;
607 for(r=0;r<NB_REGS;r++) {
608 if (reg_classes[r] & rc2) {
609 int n;
610 n=0;
611 for(p = vstack; p <= vtop; p++) {
612 if ((p->r & VT_VALMASK) == r ||
613 (p->r2 & VT_VALMASK) == r)
614 n++;
616 if (n <= 1)
617 return r;
620 return get_reg(rc);
622 #endif
624 /* find a free register of class 'rc'. If none, save one register */
625 ST_FUNC int get_reg(int rc)
627 int r;
628 SValue *p;
630 /* find a free register */
631 for(r=0;r<NB_REGS;r++) {
632 if (reg_classes[r] & rc) {
633 for(p=vstack;p<=vtop;p++) {
634 if ((p->r & VT_VALMASK) == r ||
635 (p->r2 & VT_VALMASK) == r)
636 goto notfound;
638 return r;
640 notfound: ;
643 /* no register left : free the first one on the stack (VERY
644 IMPORTANT to start from the bottom to ensure that we don't
645 spill registers used in gen_opi()) */
646 for(p=vstack;p<=vtop;p++) {
647 /* look at second register (if long long) */
648 r = p->r2 & VT_VALMASK;
649 if (r < VT_CONST && (reg_classes[r] & rc))
650 goto save_found;
651 r = p->r & VT_VALMASK;
652 if (r < VT_CONST && (reg_classes[r] & rc)) {
653 save_found:
654 save_reg(r);
655 return r;
658 /* Should never comes here */
659 return -1;
662 /* save registers up to (vtop - n) stack entry */
663 ST_FUNC void save_regs(int n)
665 int r;
666 SValue *p, *p1;
667 p1 = vtop - n;
668 for(p = vstack;p <= p1; p++) {
669 r = p->r & VT_VALMASK;
670 if (r < VT_CONST) {
671 save_reg(r);
676 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
677 if needed */
678 static void move_reg(int r, int s, int t)
680 SValue sv;
682 if (r != s) {
683 save_reg(r);
684 sv.type.t = t;
685 sv.type.ref = NULL;
686 sv.r = s;
687 sv.c.i = 0;
688 load(r, &sv);
692 /* get address of vtop (vtop MUST BE an lvalue) */
693 ST_FUNC void gaddrof(void)
695 if (vtop->r & VT_REF && !nocode_wanted)
696 gv(RC_INT);
697 vtop->r &= ~VT_LVAL;
698 /* tricky: if saved lvalue, then we can go back to lvalue */
699 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
700 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
705 #ifdef CONFIG_TCC_BCHECK
706 /* generate lvalue bound code */
707 static void gbound(void)
709 int lval_type;
710 CType type1;
712 vtop->r &= ~VT_MUSTBOUND;
713 /* if lvalue, then use checking code before dereferencing */
714 if (vtop->r & VT_LVAL) {
715 /* if not VT_BOUNDED value, then make one */
716 if (!(vtop->r & VT_BOUNDED)) {
717 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
718 /* must save type because we must set it to int to get pointer */
719 type1 = vtop->type;
720 vtop->type.t = VT_PTR;
721 gaddrof();
722 vpushi(0);
723 gen_bounded_ptr_add();
724 vtop->r |= lval_type;
725 vtop->type = type1;
727 /* then check for dereferencing */
728 gen_bounded_ptr_deref();
731 #endif
733 /* store vtop a register belonging to class 'rc'. lvalues are
734 converted to values. Cannot be used if cannot be converted to
735 register value (such as structures). */
736 ST_FUNC int gv(int rc)
738 int r, bit_pos, bit_size, size, align, i;
739 int rc2;
741 /* NOTE: get_reg can modify vstack[] */
742 if (vtop->type.t & VT_BITFIELD) {
743 CType type;
744 int bits = 32;
745 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
746 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
747 /* remove bit field info to avoid loops */
748 vtop->type.t &= ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
749 /* cast to int to propagate signedness in following ops */
750 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
751 type.t = VT_LLONG;
752 bits = 64;
753 } else
754 type.t = VT_INT;
755 if((vtop->type.t & VT_UNSIGNED) ||
756 (vtop->type.t & VT_BTYPE) == VT_BOOL)
757 type.t |= VT_UNSIGNED;
758 gen_cast(&type);
759 /* generate shifts */
760 vpushi(bits - (bit_pos + bit_size));
761 gen_op(TOK_SHL);
762 vpushi(bits - bit_size);
763 /* NOTE: transformed to SHR if unsigned */
764 gen_op(TOK_SAR);
765 r = gv(rc);
766 } else {
767 if (is_float(vtop->type.t) &&
768 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
769 Sym *sym;
770 int *ptr;
771 unsigned long offset;
772 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
773 CValue check;
774 #endif
776 /* XXX: unify with initializers handling ? */
777 /* CPUs usually cannot use float constants, so we store them
778 generically in data segment */
779 size = type_size(&vtop->type, &align);
780 offset = (data_section->data_offset + align - 1) & -align;
781 data_section->data_offset = offset;
782 /* XXX: not portable yet */
783 #if defined(__i386__) || defined(__x86_64__)
784 /* Zero pad x87 tenbyte long doubles */
785 if (size == LDOUBLE_SIZE) {
786 vtop->c.tab[2] &= 0xffff;
787 #if LDOUBLE_SIZE == 16
788 vtop->c.tab[3] = 0;
789 #endif
791 #endif
792 ptr = section_ptr_add(data_section, size);
793 size = size >> 2;
794 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
795 check.d = 1;
796 if(check.tab[0])
797 for(i=0;i<size;i++)
798 ptr[i] = vtop->c.tab[size-1-i];
799 else
800 #endif
801 for(i=0;i<size;i++)
802 ptr[i] = vtop->c.tab[i];
803 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
804 vtop->r |= VT_LVAL | VT_SYM;
805 vtop->sym = sym;
806 vtop->c.i = 0;
808 #ifdef CONFIG_TCC_BCHECK
809 if (vtop->r & VT_MUSTBOUND)
810 gbound();
811 #endif
813 r = vtop->r & VT_VALMASK;
814 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
815 #ifndef TCC_TARGET_ARM64
816 if (rc == RC_IRET)
817 rc2 = RC_LRET;
818 #ifdef TCC_TARGET_X86_64
819 else if (rc == RC_FRET)
820 rc2 = RC_QRET;
821 #endif
822 #endif
824 /* need to reload if:
825 - constant
826 - lvalue (need to dereference pointer)
827 - already a register, but not in the right class */
828 if (r >= VT_CONST
829 || (vtop->r & VT_LVAL)
830 || !(reg_classes[r] & rc)
831 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
832 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
833 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
834 #else
835 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
836 #endif
839 r = get_reg(rc);
840 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
841 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
842 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
843 #else
844 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
845 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
846 unsigned long long ll;
847 #endif
848 int r2, original_type;
849 original_type = vtop->type.t;
850 /* two register type load : expand to two words
851 temporarily */
852 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
853 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
854 /* load constant */
855 ll = vtop->c.i;
856 vtop->c.i = ll; /* first word */
857 load(r, vtop);
858 vtop->r = r; /* save register value */
859 vpushi(ll >> 32); /* second word */
860 } else
861 #endif
862 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
863 (vtop->r & VT_LVAL)) {
864 /* load from memory */
865 vtop->type.t = load_type;
866 load(r, vtop);
867 vdup();
868 vtop[-1].r = r; /* save register value */
869 /* increment pointer to get second word */
870 vtop->type.t = addr_type;
871 gaddrof();
872 vpushi(load_size);
873 gen_op('+');
874 vtop->r |= VT_LVAL;
875 vtop->type.t = load_type;
876 } else {
877 /* move registers */
878 load(r, vtop);
879 vdup();
880 vtop[-1].r = r; /* save register value */
881 vtop->r = vtop[-1].r2;
883 /* Allocate second register. Here we rely on the fact that
884 get_reg() tries first to free r2 of an SValue. */
885 r2 = get_reg(rc2);
886 load(r2, vtop);
887 vpop();
888 /* write second register */
889 vtop->r2 = r2;
890 vtop->type.t = original_type;
891 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
892 int t1, t;
893 /* lvalue of scalar type : need to use lvalue type
894 because of possible cast */
895 t = vtop->type.t;
896 t1 = t;
897 /* compute memory access type */
898 if (vtop->r & VT_REF)
899 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
900 t = VT_PTR;
901 #else
902 t = VT_INT;
903 #endif
904 else if (vtop->r & VT_LVAL_BYTE)
905 t = VT_BYTE;
906 else if (vtop->r & VT_LVAL_SHORT)
907 t = VT_SHORT;
908 if (vtop->r & VT_LVAL_UNSIGNED)
909 t |= VT_UNSIGNED;
910 vtop->type.t = t;
911 load(r, vtop);
912 /* restore wanted type */
913 vtop->type.t = t1;
914 } else {
915 /* one register type load */
916 load(r, vtop);
919 vtop->r = r;
920 #ifdef TCC_TARGET_C67
921 /* uses register pairs for doubles */
922 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
923 vtop->r2 = r+1;
924 #endif
926 return r;
929 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
930 ST_FUNC void gv2(int rc1, int rc2)
932 int v;
934 /* generate more generic register first. But VT_JMP or VT_CMP
935 values must be generated first in all cases to avoid possible
936 reload errors */
937 v = vtop[0].r & VT_VALMASK;
938 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
939 vswap();
940 gv(rc1);
941 vswap();
942 gv(rc2);
943 /* test if reload is needed for first register */
944 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
945 vswap();
946 gv(rc1);
947 vswap();
949 } else {
950 gv(rc2);
951 vswap();
952 gv(rc1);
953 vswap();
954 /* test if reload is needed for first register */
955 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
956 gv(rc2);
961 #ifndef TCC_TARGET_ARM64
962 /* wrapper around RC_FRET to return a register by type */
963 static int rc_fret(int t)
965 #ifdef TCC_TARGET_X86_64
966 if (t == VT_LDOUBLE) {
967 return RC_ST0;
969 #endif
970 return RC_FRET;
972 #endif
974 /* wrapper around REG_FRET to return a register by type */
975 static int reg_fret(int t)
977 #ifdef TCC_TARGET_X86_64
978 if (t == VT_LDOUBLE) {
979 return TREG_ST0;
981 #endif
982 return REG_FRET;
985 /* expand long long on stack in two int registers */
986 static void lexpand(void)
988 int u;
990 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
991 gv(RC_INT);
992 vdup();
993 vtop[0].r = vtop[-1].r2;
994 vtop[0].r2 = VT_CONST;
995 vtop[-1].r2 = VT_CONST;
996 vtop[0].type.t = VT_INT | u;
997 vtop[-1].type.t = VT_INT | u;
1000 #ifdef TCC_TARGET_ARM
1001 /* expand long long on stack */
1002 ST_FUNC void lexpand_nr(void)
1004 int u,v;
1006 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1007 vdup();
1008 vtop->r2 = VT_CONST;
1009 vtop->type.t = VT_INT | u;
1010 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1011 if (v == VT_CONST) {
1012 vtop[-1].c.i = vtop->c.i;
1013 vtop->c.i = vtop->c.i >> 32;
1014 vtop->r = VT_CONST;
1015 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1016 vtop->c.i += 4;
1017 vtop->r = vtop[-1].r;
1018 } else if (v > VT_CONST) {
1019 vtop--;
1020 lexpand();
1021 } else
1022 vtop->r = vtop[-1].r2;
1023 vtop[-1].r2 = VT_CONST;
1024 vtop[-1].type.t = VT_INT | u;
1026 #endif
1028 /* build a long long from two ints */
1029 static void lbuild(int t)
1031 gv2(RC_INT, RC_INT);
1032 vtop[-1].r2 = vtop[0].r;
1033 vtop[-1].type.t = t;
1034 vpop();
1037 /* rotate n first stack elements to the bottom
1038 I1 ... In -> I2 ... In I1 [top is right]
1040 ST_FUNC void vrotb(int n)
1042 int i;
1043 SValue tmp;
1045 tmp = vtop[-n + 1];
1046 for(i=-n+1;i!=0;i++)
1047 vtop[i] = vtop[i+1];
1048 vtop[0] = tmp;
1051 /* rotate the n elements before entry e towards the top
1052 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1054 ST_FUNC void vrote(SValue *e, int n)
1056 int i;
1057 SValue tmp;
1059 tmp = *e;
1060 for(i = 0;i < n - 1; i++)
1061 e[-i] = e[-i - 1];
1062 e[-n + 1] = tmp;
1065 /* rotate n first stack elements to the top
1066 I1 ... In -> In I1 ... I(n-1) [top is right]
1068 ST_FUNC void vrott(int n)
1070 vrote(vtop, n);
1073 /* pop stack value */
1074 ST_FUNC void vpop(void)
1076 int v;
1077 v = vtop->r & VT_VALMASK;
1078 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1079 /* for x86, we need to pop the FP stack */
1080 if (v == TREG_ST0 && !nocode_wanted) {
1081 o(0xd8dd); /* fstp %st(0) */
1082 } else
1083 #endif
1084 if (v == VT_JMP || v == VT_JMPI) {
1085 /* need to put correct jump if && or || without test */
1086 gsym(vtop->c.i);
1088 vtop--;
1091 /* convert stack entry to register and duplicate its value in another
1092 register */
1093 static void gv_dup(void)
1095 int rc, t, r, r1;
1096 SValue sv;
1098 t = vtop->type.t;
1099 if ((t & VT_BTYPE) == VT_LLONG) {
1100 lexpand();
1101 gv_dup();
1102 vswap();
1103 vrotb(3);
1104 gv_dup();
1105 vrotb(4);
1106 /* stack: H L L1 H1 */
1107 lbuild(t);
1108 vrotb(3);
1109 vrotb(3);
1110 vswap();
1111 lbuild(t);
1112 vswap();
1113 } else {
1114 /* duplicate value */
1115 rc = RC_INT;
1116 sv.type.t = VT_INT;
1117 if (is_float(t)) {
1118 rc = RC_FLOAT;
1119 #ifdef TCC_TARGET_X86_64
1120 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1121 rc = RC_ST0;
1123 #endif
1124 sv.type.t = t;
1126 r = gv(rc);
1127 r1 = get_reg(rc);
1128 sv.r = r;
1129 sv.c.i = 0;
1130 load(r1, &sv); /* move r to r1 */
1131 vdup();
1132 /* duplicates value */
1133 if (r != r1)
1134 vtop->r = r1;
1138 /* Generate value test
1140 * Generate a test for any value (jump, comparison and integers) */
1141 ST_FUNC int gvtst(int inv, int t)
1143 int v = vtop->r & VT_VALMASK;
1144 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1145 vpushi(0);
1146 gen_op(TOK_NE);
1148 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1149 /* constant jmp optimization */
1150 if ((vtop->c.i != 0) != inv)
1151 t = gjmp(t);
1152 vtop--;
1153 return t;
1155 return gtst(inv, t);
1158 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1159 /* generate CPU independent (unsigned) long long operations */
1160 static void gen_opl(int op)
1162 int t, a, b, op1, c, i;
1163 int func;
1164 unsigned short reg_iret = REG_IRET;
1165 unsigned short reg_lret = REG_LRET;
1166 SValue tmp;
1168 switch(op) {
1169 case '/':
1170 case TOK_PDIV:
1171 func = TOK___divdi3;
1172 goto gen_func;
1173 case TOK_UDIV:
1174 func = TOK___udivdi3;
1175 goto gen_func;
1176 case '%':
1177 func = TOK___moddi3;
1178 goto gen_mod_func;
1179 case TOK_UMOD:
1180 func = TOK___umoddi3;
1181 gen_mod_func:
1182 #ifdef TCC_ARM_EABI
1183 reg_iret = TREG_R2;
1184 reg_lret = TREG_R3;
1185 #endif
1186 gen_func:
1187 /* call generic long long function */
1188 vpush_global_sym(&func_old_type, func);
1189 vrott(3);
1190 gfunc_call(2);
1191 vpushi(0);
1192 vtop->r = reg_iret;
1193 vtop->r2 = reg_lret;
1194 break;
1195 case '^':
1196 case '&':
1197 case '|':
1198 case '*':
1199 case '+':
1200 case '-':
1201 t = vtop->type.t;
1202 vswap();
1203 lexpand();
1204 vrotb(3);
1205 lexpand();
1206 /* stack: L1 H1 L2 H2 */
1207 tmp = vtop[0];
1208 vtop[0] = vtop[-3];
1209 vtop[-3] = tmp;
1210 tmp = vtop[-2];
1211 vtop[-2] = vtop[-3];
1212 vtop[-3] = tmp;
1213 vswap();
1214 /* stack: H1 H2 L1 L2 */
1215 if (op == '*') {
1216 vpushv(vtop - 1);
1217 vpushv(vtop - 1);
1218 gen_op(TOK_UMULL);
1219 lexpand();
1220 /* stack: H1 H2 L1 L2 ML MH */
1221 for(i=0;i<4;i++)
1222 vrotb(6);
1223 /* stack: ML MH H1 H2 L1 L2 */
1224 tmp = vtop[0];
1225 vtop[0] = vtop[-2];
1226 vtop[-2] = tmp;
1227 /* stack: ML MH H1 L2 H2 L1 */
1228 gen_op('*');
1229 vrotb(3);
1230 vrotb(3);
1231 gen_op('*');
1232 /* stack: ML MH M1 M2 */
1233 gen_op('+');
1234 gen_op('+');
1235 } else if (op == '+' || op == '-') {
1236 /* XXX: add non carry method too (for MIPS or alpha) */
1237 if (op == '+')
1238 op1 = TOK_ADDC1;
1239 else
1240 op1 = TOK_SUBC1;
1241 gen_op(op1);
1242 /* stack: H1 H2 (L1 op L2) */
1243 vrotb(3);
1244 vrotb(3);
1245 gen_op(op1 + 1); /* TOK_xxxC2 */
1246 } else {
1247 gen_op(op);
1248 /* stack: H1 H2 (L1 op L2) */
1249 vrotb(3);
1250 vrotb(3);
1251 /* stack: (L1 op L2) H1 H2 */
1252 gen_op(op);
1253 /* stack: (L1 op L2) (H1 op H2) */
1255 /* stack: L H */
1256 lbuild(t);
1257 break;
1258 case TOK_SAR:
1259 case TOK_SHR:
1260 case TOK_SHL:
1261 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1262 t = vtop[-1].type.t;
1263 vswap();
1264 lexpand();
1265 vrotb(3);
1266 /* stack: L H shift */
1267 c = (int)vtop->c.i;
1268 /* constant: simpler */
1269 /* NOTE: all comments are for SHL. the other cases are
1270 done by swaping words */
1271 vpop();
1272 if (op != TOK_SHL)
1273 vswap();
1274 if (c >= 32) {
1275 /* stack: L H */
1276 vpop();
1277 if (c > 32) {
1278 vpushi(c - 32);
1279 gen_op(op);
1281 if (op != TOK_SAR) {
1282 vpushi(0);
1283 } else {
1284 gv_dup();
1285 vpushi(31);
1286 gen_op(TOK_SAR);
1288 vswap();
1289 } else {
1290 vswap();
1291 gv_dup();
1292 /* stack: H L L */
1293 vpushi(c);
1294 gen_op(op);
1295 vswap();
1296 vpushi(32 - c);
1297 if (op == TOK_SHL)
1298 gen_op(TOK_SHR);
1299 else
1300 gen_op(TOK_SHL);
1301 vrotb(3);
1302 /* stack: L L H */
1303 vpushi(c);
1304 if (op == TOK_SHL)
1305 gen_op(TOK_SHL);
1306 else
1307 gen_op(TOK_SHR);
1308 gen_op('|');
1310 if (op != TOK_SHL)
1311 vswap();
1312 lbuild(t);
1313 } else {
1314 /* XXX: should provide a faster fallback on x86 ? */
1315 switch(op) {
1316 case TOK_SAR:
1317 func = TOK___ashrdi3;
1318 goto gen_func;
1319 case TOK_SHR:
1320 func = TOK___lshrdi3;
1321 goto gen_func;
1322 case TOK_SHL:
1323 func = TOK___ashldi3;
1324 goto gen_func;
1327 break;
1328 default:
1329 /* compare operations */
1330 t = vtop->type.t;
1331 vswap();
1332 lexpand();
1333 vrotb(3);
1334 lexpand();
1335 /* stack: L1 H1 L2 H2 */
1336 tmp = vtop[-1];
1337 vtop[-1] = vtop[-2];
1338 vtop[-2] = tmp;
1339 /* stack: L1 L2 H1 H2 */
1340 /* compare high */
1341 op1 = op;
1342 /* when values are equal, we need to compare low words. since
1343 the jump is inverted, we invert the test too. */
1344 if (op1 == TOK_LT)
1345 op1 = TOK_LE;
1346 else if (op1 == TOK_GT)
1347 op1 = TOK_GE;
1348 else if (op1 == TOK_ULT)
1349 op1 = TOK_ULE;
1350 else if (op1 == TOK_UGT)
1351 op1 = TOK_UGE;
1352 a = 0;
1353 b = 0;
1354 gen_op(op1);
1355 if (op1 != TOK_NE) {
1356 a = gvtst(1, 0);
1358 if (op != TOK_EQ) {
1359 /* generate non equal test */
1360 /* XXX: NOT PORTABLE yet */
1361 if (a == 0) {
1362 b = gvtst(0, 0);
1363 } else {
1364 #if defined(TCC_TARGET_I386)
1365 b = psym(0x850f, 0);
1366 #elif defined(TCC_TARGET_ARM)
1367 b = ind;
1368 o(0x1A000000 | encbranch(ind, 0, 1));
1369 #elif defined(TCC_TARGET_C67) || defined(TCC_TARGET_ARM64)
1370 tcc_error("not implemented");
1371 #else
1372 #error not supported
1373 #endif
1376 /* compare low. Always unsigned */
1377 op1 = op;
1378 if (op1 == TOK_LT)
1379 op1 = TOK_ULT;
1380 else if (op1 == TOK_LE)
1381 op1 = TOK_ULE;
1382 else if (op1 == TOK_GT)
1383 op1 = TOK_UGT;
1384 else if (op1 == TOK_GE)
1385 op1 = TOK_UGE;
1386 gen_op(op1);
1387 a = gvtst(1, a);
1388 gsym(b);
1389 vseti(VT_JMPI, a);
1390 break;
1393 #endif
1395 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
1397 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
1398 return (a ^ b) >> 63 ? -x : x;
1401 static int gen_opic_lt(uint64_t a, uint64_t b)
1403 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
1406 /* handle integer constant optimizations and various machine
1407 independent opt */
1408 static void gen_opic(int op)
1410 SValue *v1 = vtop - 1;
1411 SValue *v2 = vtop;
1412 int t1 = v1->type.t & VT_BTYPE;
1413 int t2 = v2->type.t & VT_BTYPE;
1414 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1415 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1416 uint64_t l1 = c1 ? v1->c.i : 0;
1417 uint64_t l2 = c2 ? v2->c.i : 0;
1418 int shm = (t1 == VT_LLONG) ? 63 : 31;
1420 if (t1 != VT_LLONG)
1421 l1 = ((uint32_t)l1 |
1422 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
1423 if (t2 != VT_LLONG)
1424 l2 = ((uint32_t)l2 |
1425 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
1427 if (c1 && c2) {
1428 switch(op) {
1429 case '+': l1 += l2; break;
1430 case '-': l1 -= l2; break;
1431 case '&': l1 &= l2; break;
1432 case '^': l1 ^= l2; break;
1433 case '|': l1 |= l2; break;
1434 case '*': l1 *= l2; break;
1436 case TOK_PDIV:
1437 case '/':
1438 case '%':
1439 case TOK_UDIV:
1440 case TOK_UMOD:
1441 /* if division by zero, generate explicit division */
1442 if (l2 == 0) {
1443 if (const_wanted)
1444 tcc_error("division by zero in constant");
1445 goto general_case;
1447 switch(op) {
1448 default: l1 = gen_opic_sdiv(l1, l2); break;
1449 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
1450 case TOK_UDIV: l1 = l1 / l2; break;
1451 case TOK_UMOD: l1 = l1 % l2; break;
1453 break;
1454 case TOK_SHL: l1 <<= (l2 & shm); break;
1455 case TOK_SHR: l1 >>= (l2 & shm); break;
1456 case TOK_SAR:
1457 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
1458 break;
1459 /* tests */
1460 case TOK_ULT: l1 = l1 < l2; break;
1461 case TOK_UGE: l1 = l1 >= l2; break;
1462 case TOK_EQ: l1 = l1 == l2; break;
1463 case TOK_NE: l1 = l1 != l2; break;
1464 case TOK_ULE: l1 = l1 <= l2; break;
1465 case TOK_UGT: l1 = l1 > l2; break;
1466 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
1467 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
1468 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
1469 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
1470 /* logical */
1471 case TOK_LAND: l1 = l1 && l2; break;
1472 case TOK_LOR: l1 = l1 || l2; break;
1473 default:
1474 goto general_case;
1476 v1->c.i = l1;
1477 vtop--;
1478 } else {
1479 /* if commutative ops, put c2 as constant */
1480 if (c1 && (op == '+' || op == '&' || op == '^' ||
1481 op == '|' || op == '*')) {
1482 vswap();
1483 c2 = c1; //c = c1, c1 = c2, c2 = c;
1484 l2 = l1; //l = l1, l1 = l2, l2 = l;
1486 if (!const_wanted &&
1487 c1 && ((l1 == 0 &&
1488 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
1489 (l1 == -1 && op == TOK_SAR))) {
1490 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
1491 vtop--;
1492 } else if (!const_wanted &&
1493 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
1494 (l2 == -1 && op == '|') ||
1495 (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
1496 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
1497 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
1498 if (l2 == 1)
1499 vtop->c.i = 0;
1500 vswap();
1501 vtop--;
1502 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1503 op == TOK_PDIV) &&
1504 l2 == 1) ||
1505 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1506 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1507 l2 == 0) ||
1508 (op == '&' &&
1509 l2 == -1))) {
1510 /* filter out NOP operations like x*1, x-0, x&-1... */
1511 vtop--;
1512 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1513 /* try to use shifts instead of muls or divs */
1514 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1515 int n = -1;
1516 while (l2) {
1517 l2 >>= 1;
1518 n++;
1520 vtop->c.i = n;
1521 if (op == '*')
1522 op = TOK_SHL;
1523 else if (op == TOK_PDIV)
1524 op = TOK_SAR;
1525 else
1526 op = TOK_SHR;
1528 goto general_case;
1529 } else if (c2 && (op == '+' || op == '-') &&
1530 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1531 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1532 /* symbol + constant case */
1533 if (op == '-')
1534 l2 = -l2;
1535 vtop--;
1536 vtop->c.i += l2;
1537 } else {
1538 general_case:
1539 if (!nocode_wanted) {
1540 /* call low level op generator */
1541 if (t1 == VT_LLONG || t2 == VT_LLONG ||
1542 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
1543 gen_opl(op);
1544 else
1545 gen_opi(op);
1546 } else {
1547 vtop--;
1553 /* generate a floating point operation with constant propagation */
1554 static void gen_opif(int op)
1556 int c1, c2;
1557 SValue *v1, *v2;
1558 long double f1, f2;
1560 v1 = vtop - 1;
1561 v2 = vtop;
1562 /* currently, we cannot do computations with forward symbols */
1563 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1564 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1565 if (c1 && c2) {
1566 if (v1->type.t == VT_FLOAT) {
1567 f1 = v1->c.f;
1568 f2 = v2->c.f;
1569 } else if (v1->type.t == VT_DOUBLE) {
1570 f1 = v1->c.d;
1571 f2 = v2->c.d;
1572 } else {
1573 f1 = v1->c.ld;
1574 f2 = v2->c.ld;
1577 /* NOTE: we only do constant propagation if finite number (not
1578 NaN or infinity) (ANSI spec) */
1579 if (!ieee_finite(f1) || !ieee_finite(f2))
1580 goto general_case;
1582 switch(op) {
1583 case '+': f1 += f2; break;
1584 case '-': f1 -= f2; break;
1585 case '*': f1 *= f2; break;
1586 case '/':
1587 if (f2 == 0.0) {
1588 if (const_wanted)
1589 tcc_error("division by zero in constant");
1590 goto general_case;
1592 f1 /= f2;
1593 break;
1594 /* XXX: also handles tests ? */
1595 default:
1596 goto general_case;
1598 /* XXX: overflow test ? */
1599 if (v1->type.t == VT_FLOAT) {
1600 v1->c.f = f1;
1601 } else if (v1->type.t == VT_DOUBLE) {
1602 v1->c.d = f1;
1603 } else {
1604 v1->c.ld = f1;
1606 vtop--;
1607 } else {
1608 general_case:
1609 if (!nocode_wanted) {
1610 gen_opf(op);
1611 } else {
1612 vtop--;
1617 static int pointed_size(CType *type)
1619 int align;
1620 return type_size(pointed_type(type), &align);
1623 static void vla_runtime_pointed_size(CType *type)
1625 int align;
1626 vla_runtime_type_size(pointed_type(type), &align);
1629 static inline int is_null_pointer(SValue *p)
1631 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1632 return 0;
1633 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
1634 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
1635 ((p->type.t & VT_BTYPE) == VT_PTR &&
1636 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
1639 static inline int is_integer_btype(int bt)
1641 return (bt == VT_BYTE || bt == VT_SHORT ||
1642 bt == VT_INT || bt == VT_LLONG);
1645 /* check types for comparison or subtraction of pointers */
1646 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1648 CType *type1, *type2, tmp_type1, tmp_type2;
1649 int bt1, bt2;
1651 /* null pointers are accepted for all comparisons as gcc */
1652 if (is_null_pointer(p1) || is_null_pointer(p2))
1653 return;
1654 type1 = &p1->type;
1655 type2 = &p2->type;
1656 bt1 = type1->t & VT_BTYPE;
1657 bt2 = type2->t & VT_BTYPE;
1658 /* accept comparison between pointer and integer with a warning */
1659 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1660 if (op != TOK_LOR && op != TOK_LAND )
1661 tcc_warning("comparison between pointer and integer");
1662 return;
1665 /* both must be pointers or implicit function pointers */
1666 if (bt1 == VT_PTR) {
1667 type1 = pointed_type(type1);
1668 } else if (bt1 != VT_FUNC)
1669 goto invalid_operands;
1671 if (bt2 == VT_PTR) {
1672 type2 = pointed_type(type2);
1673 } else if (bt2 != VT_FUNC) {
1674 invalid_operands:
1675 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1677 if ((type1->t & VT_BTYPE) == VT_VOID ||
1678 (type2->t & VT_BTYPE) == VT_VOID)
1679 return;
1680 tmp_type1 = *type1;
1681 tmp_type2 = *type2;
1682 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1683 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1684 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1685 /* gcc-like error if '-' is used */
1686 if (op == '-')
1687 goto invalid_operands;
1688 else
1689 tcc_warning("comparison of distinct pointer types lacks a cast");
1693 /* generic gen_op: handles types problems */
1694 ST_FUNC void gen_op(int op)
1696 int u, t1, t2, bt1, bt2, t;
1697 CType type1;
1699 t1 = vtop[-1].type.t;
1700 t2 = vtop[0].type.t;
1701 bt1 = t1 & VT_BTYPE;
1702 bt2 = t2 & VT_BTYPE;
1704 if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1705 tcc_error("operation on a struct");
1706 } else 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 {
1828 /* integer operations */
1829 t = VT_INT;
1830 /* convert to unsigned if it does not fit in an integer */
1831 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1832 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1833 t |= VT_UNSIGNED;
1834 std_op:
1835 /* XXX: currently, some unsigned operations are explicit, so
1836 we modify them here */
1837 if (t & VT_UNSIGNED) {
1838 if (op == TOK_SAR)
1839 op = TOK_SHR;
1840 else if (op == '/')
1841 op = TOK_UDIV;
1842 else if (op == '%')
1843 op = TOK_UMOD;
1844 else if (op == TOK_LT)
1845 op = TOK_ULT;
1846 else if (op == TOK_GT)
1847 op = TOK_UGT;
1848 else if (op == TOK_LE)
1849 op = TOK_ULE;
1850 else if (op == TOK_GE)
1851 op = TOK_UGE;
1853 vswap();
1854 type1.t = t;
1855 gen_cast(&type1);
1856 vswap();
1857 /* special case for shifts and long long: we keep the shift as
1858 an integer */
1859 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1860 type1.t = VT_INT;
1861 gen_cast(&type1);
1862 if (is_float(t))
1863 gen_opif(op);
1864 else
1865 gen_opic(op);
1866 if (op >= TOK_ULT && op <= TOK_GT) {
1867 /* relationnal op: the result is an int */
1868 vtop->type.t = VT_INT;
1869 } else {
1870 vtop->type.t = t;
1873 // Make sure that we have converted to an rvalue:
1874 if (vtop->r & VT_LVAL && !nocode_wanted)
1875 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
1878 #ifndef TCC_TARGET_ARM
1879 /* generic itof for unsigned long long case */
1880 static void gen_cvt_itof1(int t)
1882 #ifdef TCC_TARGET_ARM64
1883 gen_cvt_itof(t);
1884 #else
1885 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1886 (VT_LLONG | VT_UNSIGNED)) {
1888 if (t == VT_FLOAT)
1889 vpush_global_sym(&func_old_type, TOK___floatundisf);
1890 #if LDOUBLE_SIZE != 8
1891 else if (t == VT_LDOUBLE)
1892 vpush_global_sym(&func_old_type, TOK___floatundixf);
1893 #endif
1894 else
1895 vpush_global_sym(&func_old_type, TOK___floatundidf);
1896 vrott(2);
1897 gfunc_call(1);
1898 vpushi(0);
1899 vtop->r = reg_fret(t);
1900 } else {
1901 gen_cvt_itof(t);
1903 #endif
1905 #endif
1907 /* generic ftoi for unsigned long long case */
1908 static void gen_cvt_ftoi1(int t)
1910 #ifdef TCC_TARGET_ARM64
1911 gen_cvt_ftoi(t);
1912 #else
1913 int st;
1915 if (t == (VT_LLONG | VT_UNSIGNED)) {
1916 /* not handled natively */
1917 st = vtop->type.t & VT_BTYPE;
1918 if (st == VT_FLOAT)
1919 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1920 #if LDOUBLE_SIZE != 8
1921 else if (st == VT_LDOUBLE)
1922 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1923 #endif
1924 else
1925 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1926 vrott(2);
1927 gfunc_call(1);
1928 vpushi(0);
1929 vtop->r = REG_IRET;
1930 vtop->r2 = REG_LRET;
1931 } else {
1932 gen_cvt_ftoi(t);
1934 #endif
1937 /* force char or short cast */
1938 static void force_charshort_cast(int t)
1940 int bits, dbt;
1941 dbt = t & VT_BTYPE;
1942 /* XXX: add optimization if lvalue : just change type and offset */
1943 if (dbt == VT_BYTE)
1944 bits = 8;
1945 else
1946 bits = 16;
1947 if (t & VT_UNSIGNED) {
1948 vpushi((1 << bits) - 1);
1949 gen_op('&');
1950 } else {
1951 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
1952 bits = 64 - bits;
1953 else
1954 bits = 32 - bits;
1955 vpushi(bits);
1956 gen_op(TOK_SHL);
1957 /* result must be signed or the SAR is converted to an SHL
1958 This was not the case when "t" was a signed short
1959 and the last value on the stack was an unsigned int */
1960 vtop->type.t &= ~VT_UNSIGNED;
1961 vpushi(bits);
1962 gen_op(TOK_SAR);
1966 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1967 static void gen_cast(CType *type)
1969 int sbt, dbt, sf, df, c, p;
1971 /* special delayed cast for char/short */
1972 /* XXX: in some cases (multiple cascaded casts), it may still
1973 be incorrect */
1974 if (vtop->r & VT_MUSTCAST) {
1975 vtop->r &= ~VT_MUSTCAST;
1976 force_charshort_cast(vtop->type.t);
1979 /* bitfields first get cast to ints */
1980 if (vtop->type.t & VT_BITFIELD && !nocode_wanted) {
1981 gv(RC_INT);
1984 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1985 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1987 if (sbt != dbt) {
1988 sf = is_float(sbt);
1989 df = is_float(dbt);
1990 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1991 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1992 if (c) {
1993 /* constant case: we can do it now */
1994 /* XXX: in ISOC, cannot do it if error in convert */
1995 if (sbt == VT_FLOAT)
1996 vtop->c.ld = vtop->c.f;
1997 else if (sbt == VT_DOUBLE)
1998 vtop->c.ld = vtop->c.d;
2000 if (df) {
2001 if ((sbt & VT_BTYPE) == VT_LLONG) {
2002 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
2003 vtop->c.ld = vtop->c.i;
2004 else
2005 vtop->c.ld = -(long double)-vtop->c.i;
2006 } else if(!sf) {
2007 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
2008 vtop->c.ld = (uint32_t)vtop->c.i;
2009 else
2010 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
2013 if (dbt == VT_FLOAT)
2014 vtop->c.f = (float)vtop->c.ld;
2015 else if (dbt == VT_DOUBLE)
2016 vtop->c.d = (double)vtop->c.ld;
2017 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
2018 vtop->c.i = vtop->c.ld;
2019 } else if (sf && dbt == VT_BOOL) {
2020 vtop->c.i = (vtop->c.ld != 0);
2021 } else {
2022 if(sf)
2023 vtop->c.i = vtop->c.ld;
2024 else if (sbt == (VT_LLONG|VT_UNSIGNED))
2026 else if (sbt & VT_UNSIGNED)
2027 vtop->c.i = (uint32_t)vtop->c.i;
2028 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2029 else if (sbt == VT_PTR)
2031 #endif
2032 else if (sbt != VT_LLONG)
2033 vtop->c.i = ((uint32_t)vtop->c.i |
2034 -(vtop->c.i & 0x80000000));
2036 if (dbt == (VT_LLONG|VT_UNSIGNED))
2038 else if (dbt == VT_BOOL)
2039 vtop->c.i = (vtop->c.i != 0);
2040 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2041 else if (dbt == VT_PTR)
2043 #endif
2044 else if (dbt != VT_LLONG) {
2045 uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
2046 (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
2047 0xffffffff);
2048 vtop->c.i &= m;
2049 if (!(dbt & VT_UNSIGNED))
2050 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
2053 } else if (p && dbt == VT_BOOL) {
2054 vtop->r = VT_CONST;
2055 vtop->c.i = 1;
2056 } else if (!nocode_wanted) {
2057 /* non constant case: generate code */
2058 if (sf && df) {
2059 /* convert from fp to fp */
2060 gen_cvt_ftof(dbt);
2061 } else if (df) {
2062 /* convert int to fp */
2063 gen_cvt_itof1(dbt);
2064 } else if (sf) {
2065 /* convert fp to int */
2066 if (dbt == VT_BOOL) {
2067 vpushi(0);
2068 gen_op(TOK_NE);
2069 } else {
2070 /* we handle char/short/etc... with generic code */
2071 if (dbt != (VT_INT | VT_UNSIGNED) &&
2072 dbt != (VT_LLONG | VT_UNSIGNED) &&
2073 dbt != VT_LLONG)
2074 dbt = VT_INT;
2075 gen_cvt_ftoi1(dbt);
2076 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2077 /* additional cast for char/short... */
2078 vtop->type.t = dbt;
2079 gen_cast(type);
2082 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
2083 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2084 if ((sbt & VT_BTYPE) != VT_LLONG && !nocode_wanted) {
2085 /* scalar to long long */
2086 /* machine independent conversion */
2087 gv(RC_INT);
2088 /* generate high word */
2089 if (sbt == (VT_INT | VT_UNSIGNED)) {
2090 vpushi(0);
2091 gv(RC_INT);
2092 } else {
2093 if (sbt == VT_PTR) {
2094 /* cast from pointer to int before we apply
2095 shift operation, which pointers don't support*/
2096 gen_cast(&int_type);
2098 gv_dup();
2099 vpushi(31);
2100 gen_op(TOK_SAR);
2102 /* patch second register */
2103 vtop[-1].r2 = vtop->r;
2104 vpop();
2106 #else
2107 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2108 (dbt & VT_BTYPE) == VT_PTR ||
2109 (dbt & VT_BTYPE) == VT_FUNC) {
2110 if ((sbt & VT_BTYPE) != VT_LLONG &&
2111 (sbt & VT_BTYPE) != VT_PTR &&
2112 (sbt & VT_BTYPE) != VT_FUNC && !nocode_wanted) {
2113 /* need to convert from 32bit to 64bit */
2114 gv(RC_INT);
2115 if (sbt != (VT_INT | VT_UNSIGNED)) {
2116 #if defined(TCC_TARGET_ARM64)
2117 gen_cvt_sxtw();
2118 #elif defined(TCC_TARGET_X86_64)
2119 int r = gv(RC_INT);
2120 /* x86_64 specific: movslq */
2121 o(0x6348);
2122 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2123 #else
2124 #error
2125 #endif
2128 #endif
2129 } else if (dbt == VT_BOOL) {
2130 /* scalar to bool */
2131 vpushi(0);
2132 gen_op(TOK_NE);
2133 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2134 (dbt & VT_BTYPE) == VT_SHORT) {
2135 if (sbt == VT_PTR) {
2136 vtop->type.t = VT_INT;
2137 tcc_warning("nonportable conversion from pointer to char/short");
2139 force_charshort_cast(dbt);
2140 } else if ((dbt & VT_BTYPE) == VT_INT) {
2141 /* scalar to int */
2142 if (sbt == VT_LLONG && !nocode_wanted) {
2143 /* from long long: just take low order word */
2144 lexpand();
2145 vpop();
2147 /* if lvalue and single word type, nothing to do because
2148 the lvalue already contains the real type size (see
2149 VT_LVAL_xxx constants) */
2152 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2153 /* if we are casting between pointer types,
2154 we must update the VT_LVAL_xxx size */
2155 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2156 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2158 vtop->type = *type;
2161 /* return type size as known at compile time. Put alignment at 'a' */
2162 ST_FUNC int type_size(CType *type, int *a)
2164 Sym *s;
2165 int bt;
2167 bt = type->t & VT_BTYPE;
2168 if (bt == VT_STRUCT) {
2169 /* struct/union */
2170 s = type->ref;
2171 *a = s->r;
2172 return s->c;
2173 } else if (bt == VT_PTR) {
2174 if (type->t & VT_ARRAY) {
2175 int ts;
2177 s = type->ref;
2178 ts = type_size(&s->type, a);
2180 if (ts < 0 && s->c < 0)
2181 ts = -ts;
2183 return ts * s->c;
2184 } else {
2185 *a = PTR_SIZE;
2186 return PTR_SIZE;
2188 } else if (bt == VT_LDOUBLE) {
2189 *a = LDOUBLE_ALIGN;
2190 return LDOUBLE_SIZE;
2191 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2192 #ifdef TCC_TARGET_I386
2193 #ifdef TCC_TARGET_PE
2194 *a = 8;
2195 #else
2196 *a = 4;
2197 #endif
2198 #elif defined(TCC_TARGET_ARM)
2199 #ifdef TCC_ARM_EABI
2200 *a = 8;
2201 #else
2202 *a = 4;
2203 #endif
2204 #else
2205 *a = 8;
2206 #endif
2207 return 8;
2208 } else if (bt == VT_INT || bt == VT_FLOAT) {
2209 *a = 4;
2210 return 4;
2211 } else if (bt == VT_SHORT) {
2212 *a = 2;
2213 return 2;
2214 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2215 *a = 8;
2216 return 16;
2217 } else if (bt == VT_ENUM) {
2218 *a = 4;
2219 /* Enums might be incomplete, so don't just return '4' here. */
2220 return type->ref->c;
2221 } else {
2222 /* char, void, function, _Bool */
2223 *a = 1;
2224 return 1;
2228 /* push type size as known at runtime time on top of value stack. Put
2229 alignment at 'a' */
2230 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2232 if (type->t & VT_VLA) {
2233 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2234 } else {
2235 vpushi(type_size(type, a));
2239 static void vla_sp_restore(void) {
2240 if (vlas_in_scope) {
2241 gen_vla_sp_restore(vla_sp_loc);
2245 static void vla_sp_restore_root(void) {
2246 if (vlas_in_scope) {
2247 gen_vla_sp_restore(vla_sp_root_loc);
2251 /* return the pointed type of t */
2252 static inline CType *pointed_type(CType *type)
2254 return &type->ref->type;
2257 /* modify type so that its it is a pointer to type. */
2258 ST_FUNC void mk_pointer(CType *type)
2260 Sym *s;
2261 s = sym_push(SYM_FIELD, type, 0, -1);
2262 type->t = VT_PTR | (type->t & ~VT_TYPE);
2263 type->ref = s;
2266 /* compare function types. OLD functions match any new functions */
2267 static int is_compatible_func(CType *type1, CType *type2)
2269 Sym *s1, *s2;
2271 s1 = type1->ref;
2272 s2 = type2->ref;
2273 if (!is_compatible_types(&s1->type, &s2->type))
2274 return 0;
2275 /* check func_call */
2276 if (s1->a.func_call != s2->a.func_call)
2277 return 0;
2278 /* XXX: not complete */
2279 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2280 return 1;
2281 if (s1->c != s2->c)
2282 return 0;
2283 while (s1 != NULL) {
2284 if (s2 == NULL)
2285 return 0;
2286 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2287 return 0;
2288 s1 = s1->next;
2289 s2 = s2->next;
2291 if (s2)
2292 return 0;
2293 return 1;
2296 /* return true if type1 and type2 are the same. If unqualified is
2297 true, qualifiers on the types are ignored.
2299 - enums are not checked as gcc __builtin_types_compatible_p ()
2301 static int compare_types(CType *type1, CType *type2, int unqualified)
2303 int bt1, t1, t2;
2305 t1 = type1->t & VT_TYPE;
2306 t2 = type2->t & VT_TYPE;
2307 if (unqualified) {
2308 /* strip qualifiers before comparing */
2309 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2310 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2312 /* Default Vs explicit signedness only matters for char */
2313 if ((t1 & VT_BTYPE) != VT_BYTE) {
2314 t1 &= ~VT_DEFSIGN;
2315 t2 &= ~VT_DEFSIGN;
2317 /* XXX: bitfields ? */
2318 if (t1 != t2)
2319 return 0;
2320 /* test more complicated cases */
2321 bt1 = t1 & VT_BTYPE;
2322 if (bt1 == VT_PTR) {
2323 type1 = pointed_type(type1);
2324 type2 = pointed_type(type2);
2325 return is_compatible_types(type1, type2);
2326 } else if (bt1 == VT_STRUCT) {
2327 return (type1->ref == type2->ref);
2328 } else if (bt1 == VT_FUNC) {
2329 return is_compatible_func(type1, type2);
2330 } else {
2331 return 1;
2335 /* return true if type1 and type2 are exactly the same (including
2336 qualifiers).
2338 static int is_compatible_types(CType *type1, CType *type2)
2340 return compare_types(type1,type2,0);
2343 /* return true if type1 and type2 are the same (ignoring qualifiers).
2345 static int is_compatible_parameter_types(CType *type1, CType *type2)
2347 return compare_types(type1,type2,1);
2350 /* print a type. If 'varstr' is not NULL, then the variable is also
2351 printed in the type */
2352 /* XXX: union */
2353 /* XXX: add array and function pointers */
2354 static void type_to_str(char *buf, int buf_size,
2355 CType *type, const char *varstr)
2357 int bt, v, t;
2358 Sym *s, *sa;
2359 char buf1[256];
2360 const char *tstr;
2362 t = type->t & VT_TYPE;
2363 bt = t & VT_BTYPE;
2364 buf[0] = '\0';
2365 if (t & VT_CONSTANT)
2366 pstrcat(buf, buf_size, "const ");
2367 if (t & VT_VOLATILE)
2368 pstrcat(buf, buf_size, "volatile ");
2369 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2370 pstrcat(buf, buf_size, "unsigned ");
2371 else if (t & VT_DEFSIGN)
2372 pstrcat(buf, buf_size, "signed ");
2373 switch(bt) {
2374 case VT_VOID:
2375 tstr = "void";
2376 goto add_tstr;
2377 case VT_BOOL:
2378 tstr = "_Bool";
2379 goto add_tstr;
2380 case VT_BYTE:
2381 tstr = "char";
2382 goto add_tstr;
2383 case VT_SHORT:
2384 tstr = "short";
2385 goto add_tstr;
2386 case VT_INT:
2387 tstr = "int";
2388 goto add_tstr;
2389 case VT_LONG:
2390 tstr = "long";
2391 goto add_tstr;
2392 case VT_LLONG:
2393 tstr = "long long";
2394 goto add_tstr;
2395 case VT_FLOAT:
2396 tstr = "float";
2397 goto add_tstr;
2398 case VT_DOUBLE:
2399 tstr = "double";
2400 goto add_tstr;
2401 case VT_LDOUBLE:
2402 tstr = "long double";
2403 add_tstr:
2404 pstrcat(buf, buf_size, tstr);
2405 break;
2406 case VT_ENUM:
2407 case VT_STRUCT:
2408 if (bt == VT_STRUCT)
2409 tstr = "struct ";
2410 else
2411 tstr = "enum ";
2412 pstrcat(buf, buf_size, tstr);
2413 v = type->ref->v & ~SYM_STRUCT;
2414 if (v >= SYM_FIRST_ANOM)
2415 pstrcat(buf, buf_size, "<anonymous>");
2416 else
2417 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2418 break;
2419 case VT_FUNC:
2420 s = type->ref;
2421 type_to_str(buf, buf_size, &s->type, varstr);
2422 pstrcat(buf, buf_size, "(");
2423 sa = s->next;
2424 while (sa != NULL) {
2425 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2426 pstrcat(buf, buf_size, buf1);
2427 sa = sa->next;
2428 if (sa)
2429 pstrcat(buf, buf_size, ", ");
2431 pstrcat(buf, buf_size, ")");
2432 goto no_var;
2433 case VT_PTR:
2434 s = type->ref;
2435 if (t & VT_ARRAY) {
2436 snprintf(buf1, sizeof(buf1), "%s[%ld]", varstr ? varstr : "", s->c);
2437 type_to_str(buf, buf_size, &s->type, buf1);
2438 goto no_var;
2440 pstrcpy(buf1, sizeof(buf1), "*");
2441 if (t & VT_CONSTANT)
2442 pstrcat(buf1, buf_size, "const ");
2443 if (t & VT_VOLATILE)
2444 pstrcat(buf1, buf_size, "volatile ");
2445 if (varstr)
2446 pstrcat(buf1, sizeof(buf1), varstr);
2447 type_to_str(buf, buf_size, &s->type, buf1);
2448 goto no_var;
2450 if (varstr) {
2451 pstrcat(buf, buf_size, " ");
2452 pstrcat(buf, buf_size, varstr);
2454 no_var: ;
2457 /* verify type compatibility to store vtop in 'dt' type, and generate
2458 casts if needed. */
2459 static void gen_assign_cast(CType *dt)
2461 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2462 char buf1[256], buf2[256];
2463 int dbt, sbt;
2465 st = &vtop->type; /* source type */
2466 dbt = dt->t & VT_BTYPE;
2467 sbt = st->t & VT_BTYPE;
2468 if (sbt == VT_VOID || dbt == VT_VOID) {
2469 if (sbt == VT_VOID && dbt == VT_VOID)
2470 ; /*
2471 It is Ok if both are void
2472 A test program:
2473 void func1() {}
2474 void func2() {
2475 return func1();
2477 gcc accepts this program
2479 else
2480 tcc_error("cannot cast from/to void");
2482 if (dt->t & VT_CONSTANT)
2483 tcc_warning("assignment of read-only location");
2484 switch(dbt) {
2485 case VT_PTR:
2486 /* special cases for pointers */
2487 /* '0' can also be a pointer */
2488 if (is_null_pointer(vtop))
2489 goto type_ok;
2490 /* accept implicit pointer to integer cast with warning */
2491 if (is_integer_btype(sbt)) {
2492 tcc_warning("assignment makes pointer from integer without a cast");
2493 goto type_ok;
2495 type1 = pointed_type(dt);
2496 /* a function is implicitely a function pointer */
2497 if (sbt == VT_FUNC) {
2498 if ((type1->t & VT_BTYPE) != VT_VOID &&
2499 !is_compatible_types(pointed_type(dt), st))
2500 tcc_warning("assignment from incompatible pointer type");
2501 goto type_ok;
2503 if (sbt != VT_PTR)
2504 goto error;
2505 type2 = pointed_type(st);
2506 if ((type1->t & VT_BTYPE) == VT_VOID ||
2507 (type2->t & VT_BTYPE) == VT_VOID) {
2508 /* void * can match anything */
2509 } else {
2510 /* exact type match, except for unsigned */
2511 tmp_type1 = *type1;
2512 tmp_type2 = *type2;
2513 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2514 VT_VOLATILE);
2515 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2516 VT_VOLATILE);
2517 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2518 tcc_warning("assignment from incompatible pointer type");
2520 /* check const and volatile */
2521 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2522 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2523 tcc_warning("assignment discards qualifiers from pointer target type");
2524 break;
2525 case VT_BYTE:
2526 case VT_SHORT:
2527 case VT_INT:
2528 case VT_LLONG:
2529 if (sbt == VT_PTR || sbt == VT_FUNC) {
2530 tcc_warning("assignment makes integer from pointer without a cast");
2531 } else if (sbt == VT_STRUCT) {
2532 goto case_VT_STRUCT;
2534 /* XXX: more tests */
2535 break;
2536 case VT_STRUCT:
2537 case_VT_STRUCT:
2538 tmp_type1 = *dt;
2539 tmp_type2 = *st;
2540 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2541 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2542 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2543 error:
2544 type_to_str(buf1, sizeof(buf1), st, NULL);
2545 type_to_str(buf2, sizeof(buf2), dt, NULL);
2546 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2548 break;
2550 type_ok:
2551 gen_cast(dt);
2554 /* store vtop in lvalue pushed on stack */
2555 ST_FUNC void vstore(void)
2557 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2559 ft = vtop[-1].type.t;
2560 sbt = vtop->type.t & VT_BTYPE;
2561 dbt = ft & VT_BTYPE;
2562 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2563 (sbt == VT_INT && dbt == VT_SHORT))
2564 && !(vtop->type.t & VT_BITFIELD)) {
2565 /* optimize char/short casts */
2566 delayed_cast = VT_MUSTCAST;
2567 vtop->type.t = (ft & VT_TYPE & ~VT_BITFIELD &
2568 ((1 << VT_STRUCT_SHIFT) - 1));
2569 /* XXX: factorize */
2570 if (ft & VT_CONSTANT)
2571 tcc_warning("assignment of read-only location");
2572 } else {
2573 delayed_cast = 0;
2574 if (!(ft & VT_BITFIELD))
2575 gen_assign_cast(&vtop[-1].type);
2578 if (sbt == VT_STRUCT) {
2579 /* if structure, only generate pointer */
2580 /* structure assignment : generate memcpy */
2581 /* XXX: optimize if small size */
2582 if (!nocode_wanted) {
2583 size = type_size(&vtop->type, &align);
2585 /* destination */
2586 vswap();
2587 vtop->type.t = VT_PTR;
2588 gaddrof();
2590 /* address of memcpy() */
2591 #ifdef TCC_ARM_EABI
2592 if(!(align & 7))
2593 vpush_global_sym(&func_old_type, TOK_memcpy8);
2594 else if(!(align & 3))
2595 vpush_global_sym(&func_old_type, TOK_memcpy4);
2596 else
2597 #endif
2598 /* Use memmove, rather than memcpy, as dest and src may be same: */
2599 vpush_global_sym(&func_old_type, TOK_memmove);
2601 vswap();
2602 /* source */
2603 vpushv(vtop - 2);
2604 vtop->type.t = VT_PTR;
2605 gaddrof();
2606 /* type size */
2607 vpushi(size);
2608 gfunc_call(3);
2609 } else {
2610 vswap();
2611 vpop();
2613 /* leave source on stack */
2614 } else if (ft & VT_BITFIELD) {
2615 /* bitfield store handling */
2617 /* save lvalue as expression result (example: s.b = s.a = n;) */
2618 vdup(), vtop[-1] = vtop[-2];
2620 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2621 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2622 /* remove bit field info to avoid loops */
2623 vtop[-1].type.t = ft & ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
2625 if((ft & VT_BTYPE) == VT_BOOL) {
2626 gen_cast(&vtop[-1].type);
2627 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2630 /* duplicate destination */
2631 vdup();
2632 vtop[-1] = vtop[-2];
2634 /* mask and shift source */
2635 if((ft & VT_BTYPE) != VT_BOOL) {
2636 if((ft & VT_BTYPE) == VT_LLONG) {
2637 vpushll((1ULL << bit_size) - 1ULL);
2638 } else {
2639 vpushi((1 << bit_size) - 1);
2641 gen_op('&');
2643 vpushi(bit_pos);
2644 gen_op(TOK_SHL);
2645 /* load destination, mask and or with source */
2646 vswap();
2647 if((ft & VT_BTYPE) == VT_LLONG) {
2648 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2649 } else {
2650 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2652 gen_op('&');
2653 gen_op('|');
2654 /* store result */
2655 vstore();
2656 /* ... and discard */
2657 vpop();
2659 } else {
2660 if (!nocode_wanted) {
2661 #ifdef CONFIG_TCC_BCHECK
2662 /* bound check case */
2663 if (vtop[-1].r & VT_MUSTBOUND) {
2664 vswap();
2665 gbound();
2666 vswap();
2668 #endif
2669 rc = RC_INT;
2670 if (is_float(ft)) {
2671 rc = RC_FLOAT;
2672 #ifdef TCC_TARGET_X86_64
2673 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2674 rc = RC_ST0;
2675 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2676 rc = RC_FRET;
2678 #endif
2680 r = gv(rc); /* generate value */
2681 /* if lvalue was saved on stack, must read it */
2682 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2683 SValue sv;
2684 t = get_reg(RC_INT);
2685 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2686 sv.type.t = VT_PTR;
2687 #else
2688 sv.type.t = VT_INT;
2689 #endif
2690 sv.r = VT_LOCAL | VT_LVAL;
2691 sv.c.i = vtop[-1].c.i;
2692 load(t, &sv);
2693 vtop[-1].r = t | VT_LVAL;
2695 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2696 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2697 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2698 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2699 #else
2700 if ((ft & VT_BTYPE) == VT_LLONG) {
2701 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2702 #endif
2703 vtop[-1].type.t = load_type;
2704 store(r, vtop - 1);
2705 vswap();
2706 /* convert to int to increment easily */
2707 vtop->type.t = addr_type;
2708 gaddrof();
2709 vpushi(load_size);
2710 gen_op('+');
2711 vtop->r |= VT_LVAL;
2712 vswap();
2713 vtop[-1].type.t = load_type;
2714 /* XXX: it works because r2 is spilled last ! */
2715 store(vtop->r2, vtop - 1);
2716 } else {
2717 store(r, vtop - 1);
2720 vswap();
2721 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2722 vtop->r |= delayed_cast;
2726 /* post defines POST/PRE add. c is the token ++ or -- */
2727 ST_FUNC void inc(int post, int c)
2729 test_lvalue();
2730 vdup(); /* save lvalue */
2731 if (post) {
2732 if (!nocode_wanted)
2733 gv_dup(); /* duplicate value */
2734 else
2735 vdup(); /* duplicate value */
2736 vrotb(3);
2737 vrotb(3);
2739 /* add constant */
2740 vpushi(c - TOK_MID);
2741 gen_op('+');
2742 vstore(); /* store value */
2743 if (post)
2744 vpop(); /* if post op, return saved value */
2747 /* Parse GNUC __attribute__ extension. Currently, the following
2748 extensions are recognized:
2749 - aligned(n) : set data/function alignment.
2750 - packed : force data alignment to 1
2751 - section(x) : generate data/code in this section.
2752 - unused : currently ignored, but may be used someday.
2753 - regparm(n) : pass function parameters in registers (i386 only)
2755 static void parse_attribute(AttributeDef *ad)
2757 int t, n;
2759 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2760 next();
2761 skip('(');
2762 skip('(');
2763 while (tok != ')') {
2764 if (tok < TOK_IDENT)
2765 expect("attribute name");
2766 t = tok;
2767 next();
2768 switch(t) {
2769 case TOK_SECTION1:
2770 case TOK_SECTION2:
2771 skip('(');
2772 if (tok != TOK_STR)
2773 expect("section name");
2774 ad->section = find_section(tcc_state, (char *)tokc.str.data);
2775 next();
2776 skip(')');
2777 break;
2778 case TOK_ALIAS1:
2779 case TOK_ALIAS2:
2780 skip('(');
2781 if (tok != TOK_STR)
2782 expect("alias(\"target\")");
2783 ad->alias_target = /* save string as token, for later */
2784 tok_alloc((char*)tokc.str.data, tokc.str.size-1)->tok;
2785 next();
2786 skip(')');
2787 break;
2788 case TOK_VISIBILITY1:
2789 case TOK_VISIBILITY2:
2790 skip('(');
2791 if (tok != TOK_STR)
2792 expect("visibility(\"default|hidden|internal|protected\")");
2793 if (!strcmp (tokc.str.data, "default"))
2794 ad->a.visibility = STV_DEFAULT;
2795 else if (!strcmp (tokc.str.data, "hidden"))
2796 ad->a.visibility = STV_HIDDEN;
2797 else if (!strcmp (tokc.str.data, "internal"))
2798 ad->a.visibility = STV_INTERNAL;
2799 else if (!strcmp (tokc.str.data, "protected"))
2800 ad->a.visibility = STV_PROTECTED;
2801 else
2802 expect("visibility(\"default|hidden|internal|protected\")");
2803 next();
2804 skip(')');
2805 break;
2806 case TOK_ALIGNED1:
2807 case TOK_ALIGNED2:
2808 if (tok == '(') {
2809 next();
2810 n = expr_const();
2811 if (n <= 0 || (n & (n - 1)) != 0)
2812 tcc_error("alignment must be a positive power of two");
2813 skip(')');
2814 } else {
2815 n = MAX_ALIGN;
2817 ad->a.aligned = n;
2818 break;
2819 case TOK_PACKED1:
2820 case TOK_PACKED2:
2821 ad->a.packed = 1;
2822 break;
2823 case TOK_WEAK1:
2824 case TOK_WEAK2:
2825 ad->a.weak = 1;
2826 break;
2827 case TOK_UNUSED1:
2828 case TOK_UNUSED2:
2829 /* currently, no need to handle it because tcc does not
2830 track unused objects */
2831 break;
2832 case TOK_NORETURN1:
2833 case TOK_NORETURN2:
2834 /* currently, no need to handle it because tcc does not
2835 track unused objects */
2836 break;
2837 case TOK_CDECL1:
2838 case TOK_CDECL2:
2839 case TOK_CDECL3:
2840 ad->a.func_call = FUNC_CDECL;
2841 break;
2842 case TOK_STDCALL1:
2843 case TOK_STDCALL2:
2844 case TOK_STDCALL3:
2845 ad->a.func_call = FUNC_STDCALL;
2846 break;
2847 #ifdef TCC_TARGET_I386
2848 case TOK_REGPARM1:
2849 case TOK_REGPARM2:
2850 skip('(');
2851 n = expr_const();
2852 if (n > 3)
2853 n = 3;
2854 else if (n < 0)
2855 n = 0;
2856 if (n > 0)
2857 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
2858 skip(')');
2859 break;
2860 case TOK_FASTCALL1:
2861 case TOK_FASTCALL2:
2862 case TOK_FASTCALL3:
2863 ad->a.func_call = FUNC_FASTCALLW;
2864 break;
2865 #endif
2866 case TOK_MODE:
2867 skip('(');
2868 switch(tok) {
2869 case TOK_MODE_DI:
2870 ad->a.mode = VT_LLONG + 1;
2871 break;
2872 case TOK_MODE_HI:
2873 ad->a.mode = VT_SHORT + 1;
2874 break;
2875 case TOK_MODE_SI:
2876 ad->a.mode = VT_INT + 1;
2877 break;
2878 default:
2879 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2880 break;
2882 next();
2883 skip(')');
2884 break;
2885 case TOK_DLLEXPORT:
2886 ad->a.func_export = 1;
2887 break;
2888 case TOK_DLLIMPORT:
2889 ad->a.func_import = 1;
2890 break;
2891 default:
2892 if (tcc_state->warn_unsupported)
2893 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2894 /* skip parameters */
2895 if (tok == '(') {
2896 int parenthesis = 0;
2897 do {
2898 if (tok == '(')
2899 parenthesis++;
2900 else if (tok == ')')
2901 parenthesis--;
2902 next();
2903 } while (parenthesis && tok != -1);
2905 break;
2907 if (tok != ',')
2908 break;
2909 next();
2911 skip(')');
2912 skip(')');
2916 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2917 static void struct_decl(CType *type, AttributeDef *ad, int u)
2919 int a, v, size, align, maxalign, c, offset, flexible;
2920 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2921 Sym *s, *ss, *ass, **ps;
2922 AttributeDef ad1;
2923 CType type1, btype;
2925 a = tok; /* save decl type */
2926 next();
2927 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2928 parse_attribute(ad);
2929 next();
2931 if (tok != '{') {
2932 v = tok;
2933 next();
2934 /* struct already defined ? return it */
2935 if (v < TOK_IDENT)
2936 expect("struct/union/enum name");
2937 s = struct_find(v);
2938 if (s && (s->scope == local_scope || (tok != '{' && tok != ';'))) {
2939 if (s->type.t != a)
2940 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
2941 goto do_decl;
2943 } else {
2944 v = anon_sym++;
2946 type1.t = a;
2947 type1.ref = NULL;
2948 /* we put an undefined size for struct/union */
2949 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2950 s->r = 0; /* default alignment is zero as gcc */
2951 /* put struct/union/enum name in type */
2952 do_decl:
2953 type->t = u;
2954 type->ref = s;
2956 if (tok == '{') {
2957 next();
2958 if (s->c != -1)
2959 tcc_error("struct/union/enum already defined");
2960 /* cannot be empty */
2961 c = 0;
2962 /* non empty enums are not allowed */
2963 if (a == TOK_ENUM) {
2964 for(;;) {
2965 v = tok;
2966 if (v < TOK_UIDENT)
2967 expect("identifier");
2968 ss = sym_find(v);
2969 if (ss && !local_stack)
2970 tcc_error("redefinition of enumerator '%s'",
2971 get_tok_str(v, NULL));
2972 next();
2973 if (tok == '=') {
2974 next();
2975 c = expr_const();
2977 /* enum symbols have static storage */
2978 ss = sym_push(v, &int_type, VT_CONST, c);
2979 ss->type.t |= VT_STATIC;
2980 if (tok != ',')
2981 break;
2982 next();
2983 c++;
2984 /* NOTE: we accept a trailing comma */
2985 if (tok == '}')
2986 break;
2988 s->c = type_size(&int_type, &align);
2989 skip('}');
2990 } else {
2991 maxalign = 1;
2992 ps = &s->next;
2993 prevbt = VT_INT;
2994 bit_pos = 0;
2995 offset = 0;
2996 flexible = 0;
2997 while (tok != '}') {
2998 parse_btype(&btype, &ad1);
2999 while (1) {
3000 if (flexible)
3001 tcc_error("flexible array member '%s' not at the end of struct",
3002 get_tok_str(v, NULL));
3003 bit_size = -1;
3004 v = 0;
3005 type1 = btype;
3006 if (tok != ':') {
3007 type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT);
3008 if (v == 0) {
3009 if ((type1.t & VT_BTYPE) != VT_STRUCT)
3010 expect("identifier");
3011 else {
3012 int v = btype.ref->v;
3013 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
3014 if (tcc_state->ms_extensions == 0)
3015 expect("identifier");
3019 if (type_size(&type1, &align) < 0) {
3020 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
3021 flexible = 1;
3022 else
3023 tcc_error("field '%s' has incomplete type",
3024 get_tok_str(v, NULL));
3026 if ((type1.t & VT_BTYPE) == VT_FUNC ||
3027 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
3028 tcc_error("invalid type for '%s'",
3029 get_tok_str(v, NULL));
3031 if (tok == ':') {
3032 next();
3033 bit_size = expr_const();
3034 /* XXX: handle v = 0 case for messages */
3035 if (bit_size < 0)
3036 tcc_error("negative width in bit-field '%s'",
3037 get_tok_str(v, NULL));
3038 if (v && bit_size == 0)
3039 tcc_error("zero width for bit-field '%s'",
3040 get_tok_str(v, NULL));
3042 size = type_size(&type1, &align);
3043 if (ad1.a.aligned) {
3044 if (align < ad1.a.aligned)
3045 align = ad1.a.aligned;
3046 } else if (ad1.a.packed) {
3047 align = 1;
3048 } else if (*tcc_state->pack_stack_ptr) {
3049 if (align > *tcc_state->pack_stack_ptr)
3050 align = *tcc_state->pack_stack_ptr;
3052 lbit_pos = 0;
3053 if (bit_size >= 0) {
3054 bt = type1.t & VT_BTYPE;
3055 if (bt != VT_INT &&
3056 bt != VT_BYTE &&
3057 bt != VT_SHORT &&
3058 bt != VT_BOOL &&
3059 bt != VT_ENUM &&
3060 bt != VT_LLONG)
3061 tcc_error("bitfields must have scalar type");
3062 bsize = size * 8;
3063 if (bit_size > bsize) {
3064 tcc_error("width of '%s' exceeds its type",
3065 get_tok_str(v, NULL));
3066 } else if (bit_size == bsize) {
3067 /* no need for bit fields */
3068 bit_pos = 0;
3069 } else if (bit_size == 0) {
3070 /* XXX: what to do if only padding in a
3071 structure ? */
3072 /* zero size: means to pad */
3073 bit_pos = 0;
3074 } else {
3075 /* we do not have enough room ?
3076 did the type change?
3077 is it a union? */
3078 if ((bit_pos + bit_size) > bsize ||
3079 bt != prevbt || a == TOK_UNION)
3080 bit_pos = 0;
3081 lbit_pos = bit_pos;
3082 /* XXX: handle LSB first */
3083 type1.t |= VT_BITFIELD |
3084 (bit_pos << VT_STRUCT_SHIFT) |
3085 (bit_size << (VT_STRUCT_SHIFT + 6));
3086 bit_pos += bit_size;
3088 prevbt = bt;
3089 } else {
3090 bit_pos = 0;
3092 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3093 /* add new memory data only if starting
3094 bit field */
3095 if (lbit_pos == 0) {
3096 if (a == TOK_STRUCT) {
3097 c = (c + align - 1) & -align;
3098 offset = c;
3099 if (size > 0)
3100 c += size;
3101 } else {
3102 offset = 0;
3103 if (size > c)
3104 c = size;
3106 if (align > maxalign)
3107 maxalign = align;
3109 #if 0
3110 printf("add field %s offset=%d",
3111 get_tok_str(v, NULL), offset);
3112 if (type1.t & VT_BITFIELD) {
3113 printf(" pos=%d size=%d",
3114 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3115 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3117 printf("\n");
3118 #endif
3120 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3121 ass = type1.ref;
3122 while ((ass = ass->next) != NULL) {
3123 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3124 *ps = ss;
3125 ps = &ss->next;
3127 } else if (v) {
3128 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3129 *ps = ss;
3130 ps = &ss->next;
3132 if (tok == ';' || tok == TOK_EOF)
3133 break;
3134 skip(',');
3136 skip(';');
3138 skip('}');
3139 /* store size and alignment */
3140 s->c = (c + maxalign - 1) & -maxalign;
3141 s->r = maxalign;
3146 /* return 1 if basic type is a type size (short, long, long long) */
3147 ST_FUNC int is_btype_size(int bt)
3149 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3152 /* Add type qualifiers to a type. If the type is an array then the qualifiers
3153 are added to the element type, copied because it could be a typedef. */
3154 static void parse_btype_qualify(CType *type, int qualifiers)
3156 while (type->t & VT_ARRAY) {
3157 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
3158 type = &type->ref->type;
3160 type->t |= qualifiers;
3163 /* return 0 if no type declaration. otherwise, return the basic type
3164 and skip it.
3166 static int parse_btype(CType *type, AttributeDef *ad)
3168 int t, u, bt_size, complete, type_found, typespec_found;
3169 Sym *s;
3170 CType type1;
3172 memset(ad, 0, sizeof(AttributeDef));
3173 complete = 0;
3174 type_found = 0;
3175 typespec_found = 0;
3176 t = 0;
3177 while(1) {
3178 switch(tok) {
3179 case TOK_EXTENSION:
3180 /* currently, we really ignore extension */
3181 next();
3182 continue;
3184 /* basic types */
3185 case TOK_CHAR:
3186 u = VT_BYTE;
3187 basic_type:
3188 next();
3189 basic_type1:
3190 if (complete)
3191 tcc_error("too many basic types");
3192 t |= u;
3193 bt_size = is_btype_size (u & VT_BTYPE);
3194 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3195 complete = 1;
3196 typespec_found = 1;
3197 break;
3198 case TOK_VOID:
3199 u = VT_VOID;
3200 goto basic_type;
3201 case TOK_SHORT:
3202 u = VT_SHORT;
3203 goto basic_type;
3204 case TOK_INT:
3205 u = VT_INT;
3206 goto basic_type;
3207 case TOK_LONG:
3208 next();
3209 if ((t & VT_BTYPE) == VT_DOUBLE) {
3210 #ifndef TCC_TARGET_PE
3211 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3212 #endif
3213 } else if ((t & VT_BTYPE) == VT_LONG) {
3214 t = (t & ~VT_BTYPE) | VT_LLONG;
3215 } else {
3216 u = VT_LONG;
3217 goto basic_type1;
3219 break;
3220 #ifdef TCC_TARGET_ARM64
3221 case TOK_UINT128:
3222 /* GCC's __uint128_t appears in some Linux header files. Make it a
3223 synonym for long double to get the size and alignment right. */
3224 u = VT_LDOUBLE;
3225 goto basic_type;
3226 #endif
3227 case TOK_BOOL:
3228 u = VT_BOOL;
3229 goto basic_type;
3230 case TOK_FLOAT:
3231 u = VT_FLOAT;
3232 goto basic_type;
3233 case TOK_DOUBLE:
3234 next();
3235 if ((t & VT_BTYPE) == VT_LONG) {
3236 #ifdef TCC_TARGET_PE
3237 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3238 #else
3239 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3240 #endif
3241 } else {
3242 u = VT_DOUBLE;
3243 goto basic_type1;
3245 break;
3246 case TOK_ENUM:
3247 struct_decl(&type1, ad, VT_ENUM);
3248 basic_type2:
3249 u = type1.t;
3250 type->ref = type1.ref;
3251 goto basic_type1;
3252 case TOK_STRUCT:
3253 case TOK_UNION:
3254 struct_decl(&type1, ad, VT_STRUCT);
3255 goto basic_type2;
3257 /* type modifiers */
3258 case TOK_CONST1:
3259 case TOK_CONST2:
3260 case TOK_CONST3:
3261 type->t = t;
3262 parse_btype_qualify(type, VT_CONSTANT);
3263 t = type->t;
3264 next();
3265 break;
3266 case TOK_VOLATILE1:
3267 case TOK_VOLATILE2:
3268 case TOK_VOLATILE3:
3269 type->t = t;
3270 parse_btype_qualify(type, VT_VOLATILE);
3271 t = type->t;
3272 next();
3273 break;
3274 case TOK_SIGNED1:
3275 case TOK_SIGNED2:
3276 case TOK_SIGNED3:
3277 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3278 tcc_error("signed and unsigned modifier");
3279 typespec_found = 1;
3280 t |= VT_DEFSIGN;
3281 next();
3282 break;
3283 case TOK_REGISTER:
3284 case TOK_AUTO:
3285 case TOK_RESTRICT1:
3286 case TOK_RESTRICT2:
3287 case TOK_RESTRICT3:
3288 next();
3289 break;
3290 case TOK_UNSIGNED:
3291 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3292 tcc_error("signed and unsigned modifier");
3293 t |= VT_DEFSIGN | VT_UNSIGNED;
3294 next();
3295 typespec_found = 1;
3296 break;
3298 /* storage */
3299 case TOK_EXTERN:
3300 t |= VT_EXTERN;
3301 next();
3302 break;
3303 case TOK_STATIC:
3304 t |= VT_STATIC;
3305 next();
3306 break;
3307 case TOK_TYPEDEF:
3308 t |= VT_TYPEDEF;
3309 next();
3310 break;
3311 case TOK_INLINE1:
3312 case TOK_INLINE2:
3313 case TOK_INLINE3:
3314 t |= VT_INLINE;
3315 next();
3316 break;
3318 /* GNUC attribute */
3319 case TOK_ATTRIBUTE1:
3320 case TOK_ATTRIBUTE2:
3321 parse_attribute(ad);
3322 if (ad->a.mode) {
3323 u = ad->a.mode -1;
3324 t = (t & ~VT_BTYPE) | u;
3326 break;
3327 /* GNUC typeof */
3328 case TOK_TYPEOF1:
3329 case TOK_TYPEOF2:
3330 case TOK_TYPEOF3:
3331 next();
3332 parse_expr_type(&type1);
3333 /* remove all storage modifiers except typedef */
3334 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3335 goto basic_type2;
3336 default:
3337 if (typespec_found)
3338 goto the_end;
3339 s = sym_find(tok);
3340 if (!s || !(s->type.t & VT_TYPEDEF))
3341 goto the_end;
3343 type->t = ((s->type.t & ~VT_TYPEDEF) |
3344 (t & ~(VT_CONSTANT | VT_VOLATILE)));
3345 type->ref = s->type.ref;
3346 if (t & (VT_CONSTANT | VT_VOLATILE))
3347 parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE));
3348 t = type->t;
3350 if (s->r) {
3351 /* get attributes from typedef */
3352 if (0 == ad->a.aligned)
3353 ad->a.aligned = s->a.aligned;
3354 if (0 == ad->a.func_call)
3355 ad->a.func_call = s->a.func_call;
3356 ad->a.packed |= s->a.packed;
3358 next();
3359 typespec_found = 1;
3360 break;
3362 type_found = 1;
3364 the_end:
3365 if (tcc_state->char_is_unsigned) {
3366 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3367 t |= VT_UNSIGNED;
3370 /* long is never used as type */
3371 if ((t & VT_BTYPE) == VT_LONG)
3372 #if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \
3373 defined TCC_TARGET_PE
3374 t = (t & ~VT_BTYPE) | VT_INT;
3375 #else
3376 t = (t & ~VT_BTYPE) | VT_LLONG;
3377 #endif
3378 type->t = t;
3379 return type_found;
3382 /* convert a function parameter type (array to pointer and function to
3383 function pointer) */
3384 static inline void convert_parameter_type(CType *pt)
3386 /* remove const and volatile qualifiers (XXX: const could be used
3387 to indicate a const function parameter */
3388 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3389 /* array must be transformed to pointer according to ANSI C */
3390 pt->t &= ~VT_ARRAY;
3391 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3392 mk_pointer(pt);
3396 ST_FUNC void parse_asm_str(CString *astr)
3398 skip('(');
3399 /* read the string */
3400 if (tok != TOK_STR)
3401 expect("string constant");
3402 cstr_new(astr);
3403 while (tok == TOK_STR) {
3404 /* XXX: add \0 handling too ? */
3405 cstr_cat(astr, tokc.str.data, -1);
3406 next();
3408 cstr_ccat(astr, '\0');
3411 /* Parse an asm label and return the token */
3412 static int asm_label_instr(void)
3414 int v;
3415 CString astr;
3417 next();
3418 parse_asm_str(&astr);
3419 skip(')');
3420 #ifdef ASM_DEBUG
3421 printf("asm_alias: \"%s\"\n", (char *)astr.data);
3422 #endif
3423 v = tok_alloc(astr.data, astr.size - 1)->tok;
3424 cstr_free(&astr);
3425 return v;
3428 static void post_type(CType *type, AttributeDef *ad)
3430 int n, l, t1, arg_size, align;
3431 Sym **plast, *s, *first;
3432 AttributeDef ad1;
3433 CType pt;
3435 if (tok == '(') {
3436 /* function declaration */
3437 next();
3438 l = 0;
3439 first = NULL;
3440 plast = &first;
3441 arg_size = 0;
3442 if (tok != ')') {
3443 for(;;) {
3444 /* read param name and compute offset */
3445 if (l != FUNC_OLD) {
3446 if (!parse_btype(&pt, &ad1)) {
3447 if (l) {
3448 tcc_error("invalid type");
3449 } else {
3450 l = FUNC_OLD;
3451 goto old_proto;
3454 l = FUNC_NEW;
3455 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3456 break;
3457 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3458 if ((pt.t & VT_BTYPE) == VT_VOID)
3459 tcc_error("parameter declared as void");
3460 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3461 } else {
3462 old_proto:
3463 n = tok;
3464 if (n < TOK_UIDENT)
3465 expect("identifier");
3466 pt.t = VT_INT;
3467 next();
3469 convert_parameter_type(&pt);
3470 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3471 *plast = s;
3472 plast = &s->next;
3473 if (tok == ')')
3474 break;
3475 skip(',');
3476 if (l == FUNC_NEW && tok == TOK_DOTS) {
3477 l = FUNC_ELLIPSIS;
3478 next();
3479 break;
3483 /* if no parameters, then old type prototype */
3484 if (l == 0)
3485 l = FUNC_OLD;
3486 skip(')');
3487 /* NOTE: const is ignored in returned type as it has a special
3488 meaning in gcc / C++ */
3489 type->t &= ~VT_CONSTANT;
3490 /* some ancient pre-K&R C allows a function to return an array
3491 and the array brackets to be put after the arguments, such
3492 that "int c()[]" means something like "int[] c()" */
3493 if (tok == '[') {
3494 next();
3495 skip(']'); /* only handle simple "[]" */
3496 type->t |= VT_PTR;
3498 /* we push a anonymous symbol which will contain the function prototype */
3499 ad->a.func_args = arg_size;
3500 s = sym_push(SYM_FIELD, type, 0, l);
3501 s->a = ad->a;
3502 s->next = first;
3503 type->t = VT_FUNC;
3504 type->ref = s;
3505 } else if (tok == '[') {
3506 /* array definition */
3507 next();
3508 if (tok == TOK_RESTRICT1)
3509 next();
3510 n = -1;
3511 t1 = 0;
3512 if (tok != ']') {
3513 if (!local_stack || nocode_wanted)
3514 vpushi(expr_const());
3515 else gexpr();
3516 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3517 n = vtop->c.i;
3518 if (n < 0)
3519 tcc_error("invalid array size");
3520 } else {
3521 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3522 tcc_error("size of variable length array should be an integer");
3523 t1 = VT_VLA;
3526 skip(']');
3527 /* parse next post type */
3528 post_type(type, ad);
3529 if (type->t == VT_FUNC)
3530 tcc_error("declaration of an array of functions");
3531 t1 |= type->t & VT_VLA;
3533 if (t1 & VT_VLA) {
3534 loc -= type_size(&int_type, &align);
3535 loc &= -align;
3536 n = loc;
3538 vla_runtime_type_size(type, &align);
3539 gen_op('*');
3540 vset(&int_type, VT_LOCAL|VT_LVAL, n);
3541 vswap();
3542 vstore();
3544 if (n != -1)
3545 vpop();
3547 /* we push an anonymous symbol which will contain the array
3548 element type */
3549 s = sym_push(SYM_FIELD, type, 0, n);
3550 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3551 type->ref = s;
3555 /* Parse a type declaration (except basic type), and return the type
3556 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3557 expected. 'type' should contain the basic type. 'ad' is the
3558 attribute definition of the basic type. It can be modified by
3559 type_decl().
3561 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3563 Sym *s;
3564 CType type1, *type2;
3565 int qualifiers, storage;
3567 while (tok == '*') {
3568 qualifiers = 0;
3569 redo:
3570 next();
3571 switch(tok) {
3572 case TOK_CONST1:
3573 case TOK_CONST2:
3574 case TOK_CONST3:
3575 qualifiers |= VT_CONSTANT;
3576 goto redo;
3577 case TOK_VOLATILE1:
3578 case TOK_VOLATILE2:
3579 case TOK_VOLATILE3:
3580 qualifiers |= VT_VOLATILE;
3581 goto redo;
3582 case TOK_RESTRICT1:
3583 case TOK_RESTRICT2:
3584 case TOK_RESTRICT3:
3585 goto redo;
3587 mk_pointer(type);
3588 type->t |= qualifiers;
3591 /* XXX: clarify attribute handling */
3592 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3593 parse_attribute(ad);
3595 /* recursive type */
3596 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3597 type1.t = 0; /* XXX: same as int */
3598 if (tok == '(') {
3599 next();
3600 /* XXX: this is not correct to modify 'ad' at this point, but
3601 the syntax is not clear */
3602 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3603 parse_attribute(ad);
3604 type_decl(&type1, ad, v, td);
3605 skip(')');
3606 } else {
3607 /* type identifier */
3608 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3609 *v = tok;
3610 next();
3611 } else {
3612 if (!(td & TYPE_ABSTRACT))
3613 expect("identifier");
3614 *v = 0;
3617 storage = type->t & VT_STORAGE;
3618 type->t &= ~VT_STORAGE;
3619 if (storage & VT_STATIC) {
3620 int saved_nocode_wanted = nocode_wanted;
3621 nocode_wanted = 1;
3622 post_type(type, ad);
3623 nocode_wanted = saved_nocode_wanted;
3624 } else
3625 post_type(type, ad);
3626 type->t |= storage;
3627 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3628 parse_attribute(ad);
3630 if (!type1.t)
3631 return;
3632 /* append type at the end of type1 */
3633 type2 = &type1;
3634 for(;;) {
3635 s = type2->ref;
3636 type2 = &s->type;
3637 if (!type2->t) {
3638 *type2 = *type;
3639 break;
3642 *type = type1;
3645 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3646 ST_FUNC int lvalue_type(int t)
3648 int bt, r;
3649 r = VT_LVAL;
3650 bt = t & VT_BTYPE;
3651 if (bt == VT_BYTE || bt == VT_BOOL)
3652 r |= VT_LVAL_BYTE;
3653 else if (bt == VT_SHORT)
3654 r |= VT_LVAL_SHORT;
3655 else
3656 return r;
3657 if (t & VT_UNSIGNED)
3658 r |= VT_LVAL_UNSIGNED;
3659 return r;
3662 /* indirection with full error checking and bound check */
3663 ST_FUNC void indir(void)
3665 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3666 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3667 return;
3668 expect("pointer");
3670 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3671 gv(RC_INT);
3672 vtop->type = *pointed_type(&vtop->type);
3673 /* Arrays and functions are never lvalues */
3674 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3675 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3676 vtop->r |= lvalue_type(vtop->type.t);
3677 /* if bound checking, the referenced pointer must be checked */
3678 #ifdef CONFIG_TCC_BCHECK
3679 if (tcc_state->do_bounds_check)
3680 vtop->r |= VT_MUSTBOUND;
3681 #endif
3685 /* pass a parameter to a function and do type checking and casting */
3686 static void gfunc_param_typed(Sym *func, Sym *arg)
3688 int func_type;
3689 CType type;
3691 func_type = func->c;
3692 if (func_type == FUNC_OLD ||
3693 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3694 /* default casting : only need to convert float to double */
3695 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3696 type.t = VT_DOUBLE;
3697 gen_cast(&type);
3698 } else if (vtop->type.t & VT_BITFIELD) {
3699 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3700 gen_cast(&type);
3702 } else if (arg == NULL) {
3703 tcc_error("too many arguments to function");
3704 } else {
3705 type = arg->type;
3706 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3707 gen_assign_cast(&type);
3711 /* parse an expression of the form '(type)' or '(expr)' and return its
3712 type */
3713 static void parse_expr_type(CType *type)
3715 int n;
3716 AttributeDef ad;
3718 skip('(');
3719 if (parse_btype(type, &ad)) {
3720 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3721 } else {
3722 expr_type(type);
3724 skip(')');
3727 static void parse_type(CType *type)
3729 AttributeDef ad;
3730 int n;
3732 if (!parse_btype(type, &ad)) {
3733 expect("type");
3735 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3738 static void vpush_tokc(int t)
3740 CType type;
3741 type.t = t;
3742 type.ref = 0;
3743 vsetc(&type, VT_CONST, &tokc);
3746 ST_FUNC void unary(void)
3748 int n, t, align, size, r, sizeof_caller;
3749 CType type;
3750 Sym *s;
3751 AttributeDef ad;
3752 static int in_sizeof = 0;
3754 sizeof_caller = in_sizeof;
3755 in_sizeof = 0;
3756 /* XXX: GCC 2.95.3 does not generate a table although it should be
3757 better here */
3758 tok_next:
3759 switch(tok) {
3760 case TOK_EXTENSION:
3761 next();
3762 goto tok_next;
3763 case TOK_CINT:
3764 case TOK_CCHAR:
3765 case TOK_LCHAR:
3766 vpushi(tokc.i);
3767 next();
3768 break;
3769 case TOK_CUINT:
3770 vpush_tokc(VT_INT | VT_UNSIGNED);
3771 next();
3772 break;
3773 case TOK_CLLONG:
3774 vpush_tokc(VT_LLONG);
3775 next();
3776 break;
3777 case TOK_CULLONG:
3778 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3779 next();
3780 break;
3781 case TOK_CFLOAT:
3782 vpush_tokc(VT_FLOAT);
3783 next();
3784 break;
3785 case TOK_CDOUBLE:
3786 vpush_tokc(VT_DOUBLE);
3787 next();
3788 break;
3789 case TOK_CLDOUBLE:
3790 vpush_tokc(VT_LDOUBLE);
3791 next();
3792 break;
3793 case TOK___FUNCTION__:
3794 if (!gnu_ext)
3795 goto tok_identifier;
3796 /* fall thru */
3797 case TOK___FUNC__:
3799 void *ptr;
3800 int len;
3801 /* special function name identifier */
3802 len = strlen(funcname) + 1;
3803 /* generate char[len] type */
3804 type.t = VT_BYTE;
3805 mk_pointer(&type);
3806 type.t |= VT_ARRAY;
3807 type.ref->c = len;
3808 vpush_ref(&type, data_section, data_section->data_offset, len);
3809 ptr = section_ptr_add(data_section, len);
3810 memcpy(ptr, funcname, len);
3811 next();
3813 break;
3814 case TOK_LSTR:
3815 #ifdef TCC_TARGET_PE
3816 t = VT_SHORT | VT_UNSIGNED;
3817 #else
3818 t = VT_INT;
3819 #endif
3820 goto str_init;
3821 case TOK_STR:
3822 /* string parsing */
3823 t = VT_BYTE;
3824 str_init:
3825 if (tcc_state->warn_write_strings)
3826 t |= VT_CONSTANT;
3827 type.t = t;
3828 mk_pointer(&type);
3829 type.t |= VT_ARRAY;
3830 memset(&ad, 0, sizeof(AttributeDef));
3831 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3832 break;
3833 case '(':
3834 next();
3835 /* cast ? */
3836 if (parse_btype(&type, &ad)) {
3837 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3838 skip(')');
3839 /* check ISOC99 compound literal */
3840 if (tok == '{') {
3841 /* data is allocated locally by default */
3842 if (global_expr)
3843 r = VT_CONST;
3844 else
3845 r = VT_LOCAL;
3846 /* all except arrays are lvalues */
3847 if (!(type.t & VT_ARRAY))
3848 r |= lvalue_type(type.t);
3849 memset(&ad, 0, sizeof(AttributeDef));
3850 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3851 } else {
3852 if (sizeof_caller) {
3853 vpush(&type);
3854 return;
3856 unary();
3857 gen_cast(&type);
3859 } else if (tok == '{') {
3860 if (const_wanted)
3861 tcc_error("expected constant");
3862 /* save all registers */
3863 if (!nocode_wanted)
3864 save_regs(0);
3865 /* statement expression : we do not accept break/continue
3866 inside as GCC does */
3867 block(NULL, NULL, 1);
3868 skip(')');
3869 } else {
3870 gexpr();
3871 skip(')');
3873 break;
3874 case '*':
3875 next();
3876 unary();
3877 indir();
3878 break;
3879 case '&':
3880 next();
3881 unary();
3882 /* functions names must be treated as function pointers,
3883 except for unary '&' and sizeof. Since we consider that
3884 functions are not lvalues, we only have to handle it
3885 there and in function calls. */
3886 /* arrays can also be used although they are not lvalues */
3887 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3888 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3889 test_lvalue();
3890 mk_pointer(&vtop->type);
3891 gaddrof();
3892 break;
3893 case '!':
3894 next();
3895 unary();
3896 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3897 CType boolean;
3898 boolean.t = VT_BOOL;
3899 gen_cast(&boolean);
3900 vtop->c.i = !vtop->c.i;
3901 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3902 vtop->c.i ^= 1;
3903 else {
3904 save_regs(1);
3905 vseti(VT_JMP, gvtst(1, 0));
3907 break;
3908 case '~':
3909 next();
3910 unary();
3911 vpushi(-1);
3912 gen_op('^');
3913 break;
3914 case '+':
3915 next();
3916 unary();
3917 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3918 tcc_error("pointer not accepted for unary plus");
3919 /* In order to force cast, we add zero, except for floating point
3920 where we really need an noop (otherwise -0.0 will be transformed
3921 into +0.0). */
3922 if (!is_float(vtop->type.t)) {
3923 vpushi(0);
3924 gen_op('+');
3926 break;
3927 case TOK_SIZEOF:
3928 case TOK_ALIGNOF1:
3929 case TOK_ALIGNOF2:
3930 t = tok;
3931 next();
3932 in_sizeof++;
3933 unary_type(&type); // Perform a in_sizeof = 0;
3934 size = type_size(&type, &align);
3935 if (t == TOK_SIZEOF) {
3936 if (!(type.t & VT_VLA)) {
3937 if (size < 0)
3938 tcc_error("sizeof applied to an incomplete type");
3939 vpushs(size);
3940 } else {
3941 vla_runtime_type_size(&type, &align);
3943 } else {
3944 vpushs(align);
3946 vtop->type.t |= VT_UNSIGNED;
3947 break;
3949 case TOK_builtin_expect:
3951 /* __builtin_expect is a no-op for now */
3952 int saved_nocode_wanted;
3953 next();
3954 skip('(');
3955 expr_eq();
3956 skip(',');
3957 saved_nocode_wanted = nocode_wanted;
3958 nocode_wanted = 1;
3959 expr_lor_const();
3960 vpop();
3961 nocode_wanted = saved_nocode_wanted;
3962 skip(')');
3964 break;
3965 case TOK_builtin_types_compatible_p:
3967 CType type1, type2;
3968 next();
3969 skip('(');
3970 parse_type(&type1);
3971 skip(',');
3972 parse_type(&type2);
3973 skip(')');
3974 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3975 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3976 vpushi(is_compatible_types(&type1, &type2));
3978 break;
3979 case TOK_builtin_constant_p:
3981 int saved_nocode_wanted, res;
3982 next();
3983 skip('(');
3984 saved_nocode_wanted = nocode_wanted;
3985 nocode_wanted = 1;
3986 gexpr();
3987 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3988 vpop();
3989 nocode_wanted = saved_nocode_wanted;
3990 skip(')');
3991 vpushi(res);
3993 break;
3994 case TOK_builtin_frame_address:
3995 case TOK_builtin_return_address:
3997 int tok1 = tok;
3998 int level;
3999 CType type;
4000 next();
4001 skip('(');
4002 if (tok != TOK_CINT) {
4003 tcc_error("%s only takes positive integers",
4004 tok1 == TOK_builtin_return_address ?
4005 "__builtin_return_address" :
4006 "__builtin_frame_address");
4008 level = (uint32_t)tokc.i;
4009 next();
4010 skip(')');
4011 type.t = VT_VOID;
4012 mk_pointer(&type);
4013 vset(&type, VT_LOCAL, 0); /* local frame */
4014 while (level--) {
4015 mk_pointer(&vtop->type);
4016 indir(); /* -> parent frame */
4018 if (tok1 == TOK_builtin_return_address) {
4019 // assume return address is just above frame pointer on stack
4020 vpushi(PTR_SIZE);
4021 gen_op('+');
4022 mk_pointer(&vtop->type);
4023 indir();
4026 break;
4027 #ifdef TCC_TARGET_X86_64
4028 #ifdef TCC_TARGET_PE
4029 case TOK_builtin_va_start:
4031 next();
4032 skip('(');
4033 expr_eq();
4034 skip(',');
4035 expr_eq();
4036 skip(')');
4037 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
4038 tcc_error("__builtin_va_start expects a local variable");
4039 vtop->r &= ~(VT_LVAL | VT_REF);
4040 vtop->type = char_pointer_type;
4041 vtop->c.i += 8;
4042 vstore();
4044 break;
4045 #else
4046 case TOK_builtin_va_arg_types:
4048 CType type;
4049 next();
4050 skip('(');
4051 parse_type(&type);
4052 skip(')');
4053 vpushi(classify_x86_64_va_arg(&type));
4055 break;
4056 #endif
4057 #endif
4059 #ifdef TCC_TARGET_ARM64
4060 case TOK___va_start: {
4061 if (nocode_wanted)
4062 tcc_error("statement in global scope");
4063 next();
4064 skip('(');
4065 expr_eq();
4066 skip(',');
4067 expr_eq();
4068 skip(')');
4069 //xx check types
4070 gen_va_start();
4071 vpushi(0);
4072 vtop->type.t = VT_VOID;
4073 break;
4075 case TOK___va_arg: {
4076 CType type;
4077 if (nocode_wanted)
4078 tcc_error("statement in global scope");
4079 next();
4080 skip('(');
4081 expr_eq();
4082 skip(',');
4083 parse_type(&type);
4084 skip(')');
4085 //xx check types
4086 gen_va_arg(&type);
4087 vtop->type = type;
4088 break;
4090 case TOK___arm64_clear_cache: {
4091 next();
4092 skip('(');
4093 expr_eq();
4094 skip(',');
4095 expr_eq();
4096 skip(')');
4097 gen_clear_cache();
4098 vpushi(0);
4099 vtop->type.t = VT_VOID;
4100 break;
4102 #endif
4103 /* pre operations */
4104 case TOK_INC:
4105 case TOK_DEC:
4106 t = tok;
4107 next();
4108 unary();
4109 inc(0, t);
4110 break;
4111 case '-':
4112 next();
4113 unary();
4114 t = vtop->type.t & VT_BTYPE;
4115 if (is_float(t)) {
4116 /* In IEEE negate(x) isn't subtract(0,x), but rather
4117 subtract(-0, x). */
4118 vpush(&vtop->type);
4119 if (t == VT_FLOAT)
4120 vtop->c.f = -0.0f;
4121 else if (t == VT_DOUBLE)
4122 vtop->c.d = -0.0;
4123 else
4124 vtop->c.ld = -0.0;
4125 } else
4126 vpushi(0);
4127 vswap();
4128 gen_op('-');
4129 break;
4130 case TOK_LAND:
4131 if (!gnu_ext)
4132 goto tok_identifier;
4133 next();
4134 /* allow to take the address of a label */
4135 if (tok < TOK_UIDENT)
4136 expect("label identifier");
4137 s = label_find(tok);
4138 if (!s) {
4139 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4140 } else {
4141 if (s->r == LABEL_DECLARED)
4142 s->r = LABEL_FORWARD;
4144 if (!s->type.t) {
4145 s->type.t = VT_VOID;
4146 mk_pointer(&s->type);
4147 s->type.t |= VT_STATIC;
4149 vpushsym(&s->type, s);
4150 next();
4151 break;
4153 // special qnan , snan and infinity values
4154 case TOK___NAN__:
4155 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
4156 next();
4157 break;
4158 case TOK___SNAN__:
4159 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
4160 next();
4161 break;
4162 case TOK___INF__:
4163 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
4164 next();
4165 break;
4167 default:
4168 tok_identifier:
4169 t = tok;
4170 next();
4171 if (t < TOK_UIDENT)
4172 expect("identifier");
4173 s = sym_find(t);
4174 if (!s) {
4175 const char *name = get_tok_str(t, NULL);
4176 if (tok != '(')
4177 tcc_error("'%s' undeclared", name);
4178 /* for simple function calls, we tolerate undeclared
4179 external reference to int() function */
4180 if (tcc_state->warn_implicit_function_declaration
4181 #ifdef TCC_TARGET_PE
4182 /* people must be warned about using undeclared WINAPI functions
4183 (which usually start with uppercase letter) */
4184 || (name[0] >= 'A' && name[0] <= 'Z')
4185 #endif
4187 tcc_warning("implicit declaration of function '%s'", name);
4188 s = external_global_sym(t, &func_old_type, 0);
4190 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
4191 (VT_STATIC | VT_INLINE | VT_FUNC)) {
4192 /* if referencing an inline function, then we generate a
4193 symbol to it if not already done. It will have the
4194 effect to generate code for it at the end of the
4195 compilation unit. Inline function as always
4196 generated in the text section. */
4197 if (!s->c)
4198 put_extern_sym(s, text_section, 0, 0);
4199 r = VT_SYM | VT_CONST;
4200 } else {
4201 r = s->r;
4203 vset(&s->type, r, s->c);
4204 /* if forward reference, we must point to s */
4205 if (vtop->r & VT_SYM) {
4206 vtop->sym = s;
4207 vtop->c.i = 0;
4209 break;
4212 /* post operations */
4213 while (1) {
4214 if (tok == TOK_INC || tok == TOK_DEC) {
4215 inc(1, tok);
4216 next();
4217 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
4218 int qualifiers;
4219 /* field */
4220 if (tok == TOK_ARROW)
4221 indir();
4222 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4223 test_lvalue();
4224 gaddrof();
4225 /* expect pointer on structure */
4226 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4227 expect("struct or union");
4228 if (tok == TOK_CDOUBLE)
4229 expect("field name");
4230 next();
4231 if (tok == TOK_CINT || tok == TOK_CUINT)
4232 expect("field name");
4233 s = vtop->type.ref;
4234 /* find field */
4235 tok |= SYM_FIELD;
4236 while ((s = s->next) != NULL) {
4237 if (s->v == tok)
4238 break;
4240 if (!s)
4241 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
4242 /* add field offset to pointer */
4243 vtop->type = char_pointer_type; /* change type to 'char *' */
4244 vpushi(s->c);
4245 gen_op('+');
4246 /* change type to field type, and set to lvalue */
4247 vtop->type = s->type;
4248 vtop->type.t |= qualifiers;
4249 /* an array is never an lvalue */
4250 if (!(vtop->type.t & VT_ARRAY)) {
4251 vtop->r |= lvalue_type(vtop->type.t);
4252 #ifdef CONFIG_TCC_BCHECK
4253 /* if bound checking, the referenced pointer must be checked */
4254 if (tcc_state->do_bounds_check)
4255 vtop->r |= VT_MUSTBOUND;
4256 #endif
4258 next();
4259 } else if (tok == '[') {
4260 next();
4261 gexpr();
4262 gen_op('+');
4263 indir();
4264 skip(']');
4265 } else if (tok == '(') {
4266 SValue ret;
4267 Sym *sa;
4268 int nb_args, ret_nregs, ret_align, regsize, variadic;
4270 /* function call */
4271 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4272 /* pointer test (no array accepted) */
4273 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4274 vtop->type = *pointed_type(&vtop->type);
4275 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4276 goto error_func;
4277 } else {
4278 error_func:
4279 expect("function pointer");
4281 } else {
4282 vtop->r &= ~VT_LVAL; /* no lvalue */
4284 /* get return type */
4285 s = vtop->type.ref;
4286 next();
4287 sa = s->next; /* first parameter */
4288 nb_args = 0;
4289 ret.r2 = VT_CONST;
4290 /* compute first implicit argument if a structure is returned */
4291 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4292 variadic = (s->c == FUNC_ELLIPSIS);
4293 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4294 &ret_align, &regsize);
4295 if (!ret_nregs) {
4296 /* get some space for the returned structure */
4297 size = type_size(&s->type, &align);
4298 #ifdef TCC_TARGET_ARM64
4299 /* On arm64, a small struct is return in registers.
4300 It is much easier to write it to memory if we know
4301 that we are allowed to write some extra bytes, so
4302 round the allocated space up to a power of 2: */
4303 if (size < 16)
4304 while (size & (size - 1))
4305 size = (size | (size - 1)) + 1;
4306 #endif
4307 loc = (loc - size) & -align;
4308 ret.type = s->type;
4309 ret.r = VT_LOCAL | VT_LVAL;
4310 /* pass it as 'int' to avoid structure arg passing
4311 problems */
4312 vseti(VT_LOCAL, loc);
4313 ret.c = vtop->c;
4314 nb_args++;
4316 } else {
4317 ret_nregs = 1;
4318 ret.type = s->type;
4321 if (ret_nregs) {
4322 /* return in register */
4323 if (is_float(ret.type.t)) {
4324 ret.r = reg_fret(ret.type.t);
4325 #ifdef TCC_TARGET_X86_64
4326 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4327 ret.r2 = REG_QRET;
4328 #endif
4329 } else {
4330 #ifndef TCC_TARGET_ARM64
4331 #ifdef TCC_TARGET_X86_64
4332 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4333 #else
4334 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4335 #endif
4336 ret.r2 = REG_LRET;
4337 #endif
4338 ret.r = REG_IRET;
4340 ret.c.i = 0;
4342 if (tok != ')') {
4343 for(;;) {
4344 expr_eq();
4345 gfunc_param_typed(s, sa);
4346 nb_args++;
4347 if (sa)
4348 sa = sa->next;
4349 if (tok == ')')
4350 break;
4351 skip(',');
4354 if (sa)
4355 tcc_error("too few arguments to function");
4356 skip(')');
4357 if (!nocode_wanted) {
4358 gfunc_call(nb_args);
4359 } else {
4360 vtop -= (nb_args + 1);
4363 /* return value */
4364 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4365 vsetc(&ret.type, r, &ret.c);
4366 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4369 /* handle packed struct return */
4370 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4371 int addr, offset;
4373 size = type_size(&s->type, &align);
4374 /* We're writing whole regs often, make sure there's enough
4375 space. Assume register size is power of 2. */
4376 if (regsize > align)
4377 align = regsize;
4378 loc = (loc - size) & -align;
4379 addr = loc;
4380 offset = 0;
4381 for (;;) {
4382 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4383 vswap();
4384 vstore();
4385 vtop--;
4386 if (--ret_nregs == 0)
4387 break;
4388 offset += regsize;
4390 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4392 } else {
4393 break;
4398 ST_FUNC void expr_prod(void)
4400 int t;
4402 unary();
4403 while (tok == '*' || tok == '/' || tok == '%') {
4404 t = tok;
4405 next();
4406 unary();
4407 gen_op(t);
4411 ST_FUNC void expr_sum(void)
4413 int t;
4415 expr_prod();
4416 while (tok == '+' || tok == '-') {
4417 t = tok;
4418 next();
4419 expr_prod();
4420 gen_op(t);
4424 static void expr_shift(void)
4426 int t;
4428 expr_sum();
4429 while (tok == TOK_SHL || tok == TOK_SAR) {
4430 t = tok;
4431 next();
4432 expr_sum();
4433 gen_op(t);
4437 static void expr_cmp(void)
4439 int t;
4441 expr_shift();
4442 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4443 tok == TOK_ULT || tok == TOK_UGE) {
4444 t = tok;
4445 next();
4446 expr_shift();
4447 gen_op(t);
4451 static void expr_cmpeq(void)
4453 int t;
4455 expr_cmp();
4456 while (tok == TOK_EQ || tok == TOK_NE) {
4457 t = tok;
4458 next();
4459 expr_cmp();
4460 gen_op(t);
4464 static void expr_and(void)
4466 expr_cmpeq();
4467 while (tok == '&') {
4468 next();
4469 expr_cmpeq();
4470 gen_op('&');
4474 static void expr_xor(void)
4476 expr_and();
4477 while (tok == '^') {
4478 next();
4479 expr_and();
4480 gen_op('^');
4484 static void expr_or(void)
4486 expr_xor();
4487 while (tok == '|') {
4488 next();
4489 expr_xor();
4490 gen_op('|');
4494 /* XXX: fix this mess */
4495 static void expr_land_const(void)
4497 expr_or();
4498 while (tok == TOK_LAND) {
4499 next();
4500 expr_or();
4501 gen_op(TOK_LAND);
4504 static void expr_lor_const(void)
4506 expr_land_const();
4507 while (tok == TOK_LOR) {
4508 next();
4509 expr_land_const();
4510 gen_op(TOK_LOR);
4514 static void expr_land(void)
4516 expr_or();
4517 if (tok == TOK_LAND) {
4518 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4519 CType ctb, cti;
4520 ctb.t = VT_BOOL;
4521 cti.t = VT_INT;
4522 next();
4523 gen_cast(&ctb);
4524 if (vtop->c.i) {
4525 vpop();
4526 expr_land();
4527 gen_cast(&ctb);
4528 } else {
4529 int saved_nocode_wanted = nocode_wanted;
4530 nocode_wanted = 1;
4531 expr_land();
4532 vpop();
4533 nocode_wanted = saved_nocode_wanted;
4535 gen_cast(&cti);
4536 } else {
4537 int t = 0;
4538 save_regs(1);
4539 for(;;) {
4540 t = gvtst(1, t);
4541 if (tok != TOK_LAND) {
4542 vseti(VT_JMPI, t);
4543 break;
4545 next();
4546 expr_or();
4552 static void expr_lor(void)
4554 expr_land();
4555 if (tok == TOK_LOR) {
4556 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4557 CType ctb, cti;
4558 ctb.t = VT_BOOL;
4559 cti.t = VT_INT;
4560 next();
4561 gen_cast(&ctb);
4562 if (vtop->c.i) {
4563 int saved_nocode_wanted = nocode_wanted;
4564 nocode_wanted = 1;
4565 expr_lor();
4566 vpop();
4567 nocode_wanted = saved_nocode_wanted;
4568 } else {
4569 vpop();
4570 expr_lor();
4571 gen_cast(&ctb);
4573 gen_cast(&cti);
4574 } else {
4575 int t = 0;
4576 save_regs(1);
4577 for(;;) {
4578 t = gvtst(0, t);
4579 if (tok != TOK_LOR) {
4580 vseti(VT_JMP, t);
4581 break;
4583 next();
4584 expr_land();
4590 static void expr_cond(void)
4592 int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv;
4593 SValue sv;
4594 CType type, type1, type2;
4596 expr_lor();
4597 if (tok == '?') {
4598 next();
4599 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4600 int saved_nocode_wanted = nocode_wanted;
4601 CType boolean;
4602 int c;
4603 boolean.t = VT_BOOL;
4604 vdup();
4605 gen_cast(&boolean);
4606 c = vtop->c.i;
4607 vpop();
4608 if (c) {
4609 if (tok != ':' || !gnu_ext) {
4610 vpop();
4611 gexpr();
4613 skip(':');
4614 nocode_wanted = 1;
4615 expr_cond();
4616 vpop();
4617 nocode_wanted = saved_nocode_wanted;
4618 } else {
4619 vpop();
4620 if (tok != ':' || !gnu_ext) {
4621 nocode_wanted = 1;
4622 gexpr();
4623 vpop();
4624 nocode_wanted = saved_nocode_wanted;
4626 skip(':');
4627 expr_cond();
4630 else {
4631 if (vtop != vstack) {
4632 /* needed to avoid having different registers saved in
4633 each branch */
4634 if (is_float(vtop->type.t)) {
4635 rc = RC_FLOAT;
4636 #ifdef TCC_TARGET_X86_64
4637 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4638 rc = RC_ST0;
4640 #endif
4642 else
4643 rc = RC_INT;
4644 gv(rc);
4645 save_regs(1);
4647 if (tok == ':' && gnu_ext) {
4648 gv_dup();
4649 tt = gvtst(1, 0);
4650 } else {
4651 tt = gvtst(1, 0);
4652 gexpr();
4654 type1 = vtop->type;
4655 sv = *vtop; /* save value to handle it later */
4656 vtop--; /* no vpop so that FP stack is not flushed */
4657 skip(':');
4658 u = gjmp(0);
4659 gsym(tt);
4660 expr_cond();
4661 type2 = vtop->type;
4663 t1 = type1.t;
4664 bt1 = t1 & VT_BTYPE;
4665 t2 = type2.t;
4666 bt2 = t2 & VT_BTYPE;
4667 /* cast operands to correct type according to ISOC rules */
4668 if (is_float(bt1) || is_float(bt2)) {
4669 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4670 type.t = VT_LDOUBLE;
4671 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4672 type.t = VT_DOUBLE;
4673 } else {
4674 type.t = VT_FLOAT;
4676 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4677 /* cast to biggest op */
4678 type.t = VT_LLONG;
4679 /* convert to unsigned if it does not fit in a long long */
4680 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4681 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4682 type.t |= VT_UNSIGNED;
4683 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4684 /* If one is a null ptr constant the result type
4685 is the other. */
4686 if (is_null_pointer (vtop))
4687 type = type1;
4688 else if (is_null_pointer (&sv))
4689 type = type2;
4690 /* XXX: test pointer compatibility, C99 has more elaborate
4691 rules here. */
4692 else
4693 type = type1;
4694 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4695 /* XXX: test function pointer compatibility */
4696 type = bt1 == VT_FUNC ? type1 : type2;
4697 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4698 /* XXX: test structure compatibility */
4699 type = bt1 == VT_STRUCT ? type1 : type2;
4700 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4701 /* NOTE: as an extension, we accept void on only one side */
4702 type.t = VT_VOID;
4703 } else {
4704 /* integer operations */
4705 type.t = VT_INT;
4706 /* convert to unsigned if it does not fit in an integer */
4707 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4708 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4709 type.t |= VT_UNSIGNED;
4711 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
4712 that `(expr ? a : b).mem` does not error with "lvalue expected" */
4713 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
4715 /* now we convert second operand */
4716 gen_cast(&type);
4717 if (islv) {
4718 mk_pointer(&vtop->type);
4719 gaddrof();
4721 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4722 gaddrof();
4723 rc = RC_INT;
4724 if (is_float(type.t)) {
4725 rc = RC_FLOAT;
4726 #ifdef TCC_TARGET_X86_64
4727 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4728 rc = RC_ST0;
4730 #endif
4731 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4732 /* for long longs, we use fixed registers to avoid having
4733 to handle a complicated move */
4734 rc = RC_IRET;
4737 r2 = gv(rc);
4738 /* this is horrible, but we must also convert first
4739 operand */
4740 tt = gjmp(0);
4741 gsym(u);
4742 /* put again first value and cast it */
4743 *vtop = sv;
4744 gen_cast(&type);
4745 if (islv) {
4746 mk_pointer(&vtop->type);
4747 gaddrof();
4749 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4750 gaddrof();
4751 r1 = gv(rc);
4752 move_reg(r2, r1, type.t);
4753 vtop->r = r2;
4754 gsym(tt);
4755 if (islv)
4756 indir();
4761 static void expr_eq(void)
4763 int t;
4765 expr_cond();
4766 if (tok == '=' ||
4767 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4768 tok == TOK_A_XOR || tok == TOK_A_OR ||
4769 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4770 test_lvalue();
4771 t = tok;
4772 next();
4773 if (t == '=') {
4774 expr_eq();
4775 } else {
4776 vdup();
4777 expr_eq();
4778 gen_op(t & 0x7f);
4780 vstore();
4784 ST_FUNC void gexpr(void)
4786 while (1) {
4787 expr_eq();
4788 if (tok != ',')
4789 break;
4790 vpop();
4791 next();
4795 /* parse an expression and return its type without any side effect. */
4796 static void expr_type(CType *type)
4798 int saved_nocode_wanted;
4800 saved_nocode_wanted = nocode_wanted;
4801 nocode_wanted = 1;
4802 gexpr();
4803 *type = vtop->type;
4804 vpop();
4805 nocode_wanted = saved_nocode_wanted;
4808 /* parse a unary expression and return its type without any side
4809 effect. */
4810 static void unary_type(CType *type)
4812 int a;
4814 a = nocode_wanted;
4815 nocode_wanted = 1;
4816 unary();
4817 *type = vtop->type;
4818 vpop();
4819 nocode_wanted = a;
4822 /* parse a constant expression and return value in vtop. */
4823 static void expr_const1(void)
4825 int a;
4826 a = const_wanted;
4827 const_wanted = 1;
4828 expr_cond();
4829 const_wanted = a;
4832 /* parse an integer constant and return its value. */
4833 ST_FUNC int expr_const(void)
4835 int c;
4836 expr_const1();
4837 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4838 expect("constant expression");
4839 c = vtop->c.i;
4840 vpop();
4841 return c;
4844 /* return the label token if current token is a label, otherwise
4845 return zero */
4846 static int is_label(void)
4848 int last_tok;
4850 /* fast test first */
4851 if (tok < TOK_UIDENT)
4852 return 0;
4853 /* no need to save tokc because tok is an identifier */
4854 last_tok = tok;
4855 next();
4856 if (tok == ':') {
4857 next();
4858 return last_tok;
4859 } else {
4860 unget_tok(last_tok);
4861 return 0;
4865 static void label_or_decl(int l)
4867 int last_tok;
4869 /* fast test first */
4870 if (tok >= TOK_UIDENT)
4872 /* no need to save tokc because tok is an identifier */
4873 last_tok = tok;
4874 next();
4875 if (tok == ':') {
4876 unget_tok(last_tok);
4877 return;
4879 unget_tok(last_tok);
4881 decl(l);
4884 static int case_cmp(const void *pa, const void *pb)
4886 int a = (*(struct case_t**) pa)->v1;
4887 int b = (*(struct case_t**) pb)->v1;
4888 return a < b ? -1 : a > b;
4891 static void block(int *bsym, int *csym, int is_expr)
4893 int a, b, c, d;
4894 Sym *s;
4896 /* generate line number info */
4897 if (tcc_state->do_debug &&
4898 (last_line_num != file->line_num || last_ind != ind)) {
4899 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4900 last_ind = ind;
4901 last_line_num = file->line_num;
4904 if (is_expr) {
4905 /* default return value is (void) */
4906 vpushi(0);
4907 vtop->type.t = VT_VOID;
4910 if (tok == TOK_IF) {
4911 /* if test */
4912 next();
4913 skip('(');
4914 gexpr();
4915 skip(')');
4916 a = gvtst(1, 0);
4917 block(bsym, csym, 0);
4918 c = tok;
4919 if (c == TOK_ELSE) {
4920 next();
4921 d = gjmp(0);
4922 gsym(a);
4923 block(bsym, csym, 0);
4924 gsym(d); /* patch else jmp */
4925 } else
4926 gsym(a);
4927 } else if (tok == TOK_WHILE) {
4928 next();
4929 d = ind;
4930 vla_sp_restore();
4931 skip('(');
4932 gexpr();
4933 skip(')');
4934 a = gvtst(1, 0);
4935 b = 0;
4936 ++local_scope;
4937 block(&a, &b, 0);
4938 --local_scope;
4939 if(!nocode_wanted)
4940 gjmp_addr(d);
4941 gsym(a);
4942 gsym_addr(b, d);
4943 } else if (tok == '{') {
4944 Sym *llabel;
4945 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
4947 next();
4948 /* record local declaration stack position */
4949 s = local_stack;
4950 llabel = local_label_stack;
4951 ++local_scope;
4953 /* handle local labels declarations */
4954 if (tok == TOK_LABEL) {
4955 next();
4956 for(;;) {
4957 if (tok < TOK_UIDENT)
4958 expect("label identifier");
4959 label_push(&local_label_stack, tok, LABEL_DECLARED);
4960 next();
4961 if (tok == ',') {
4962 next();
4963 } else {
4964 skip(';');
4965 break;
4969 while (tok != '}') {
4970 label_or_decl(VT_LOCAL);
4971 if (tok != '}') {
4972 if (is_expr)
4973 vpop();
4974 block(bsym, csym, is_expr);
4977 /* pop locally defined labels */
4978 label_pop(&local_label_stack, llabel);
4979 if(is_expr) {
4980 /* XXX: this solution makes only valgrind happy...
4981 triggered by gcc.c-torture/execute/20000917-1.c */
4982 Sym *p;
4983 switch(vtop->type.t & VT_BTYPE) {
4984 /* case VT_PTR: */
4985 /* this breaks a compilation of the linux kernel v2.4.26 */
4986 /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
4987 /* Look a commit a80acab: Display error on statement expressions with complex return type */
4988 /* A pointer is not a complex return type */
4989 case VT_STRUCT:
4990 case VT_ENUM:
4991 case VT_FUNC:
4992 for(p=vtop->type.ref;p;p=p->prev)
4993 if(p->prev==s)
4994 tcc_error("unsupported expression type");
4997 /* pop locally defined symbols */
4998 --local_scope;
4999 sym_pop(&local_stack, s);
5001 /* Pop VLA frames and restore stack pointer if required */
5002 if (vlas_in_scope > saved_vlas_in_scope) {
5003 vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
5004 vla_sp_restore();
5006 vlas_in_scope = saved_vlas_in_scope;
5008 next();
5009 } else if (tok == TOK_RETURN) {
5010 next();
5011 if (tok != ';') {
5012 gexpr();
5013 gen_assign_cast(&func_vt);
5014 #ifdef TCC_TARGET_ARM64
5015 // Perhaps it would be better to use this for all backends:
5016 greturn();
5017 #else
5018 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
5019 CType type, ret_type;
5020 int ret_align, ret_nregs, regsize;
5021 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
5022 &ret_align, &regsize);
5023 if (0 == ret_nregs) {
5024 /* if returning structure, must copy it to implicit
5025 first pointer arg location */
5026 type = func_vt;
5027 mk_pointer(&type);
5028 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
5029 indir();
5030 vswap();
5031 /* copy structure value to pointer */
5032 vstore();
5033 } else {
5034 /* returning structure packed into registers */
5035 int r, size, addr, align;
5036 size = type_size(&func_vt,&align);
5037 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
5038 (vtop->c.i & (ret_align-1)))
5039 && (align & (ret_align-1))) {
5040 loc = (loc - size) & -ret_align;
5041 addr = loc;
5042 type = func_vt;
5043 vset(&type, VT_LOCAL | VT_LVAL, addr);
5044 vswap();
5045 vstore();
5046 vpop();
5047 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
5049 vtop->type = ret_type;
5050 if (is_float(ret_type.t))
5051 r = rc_fret(ret_type.t);
5052 else
5053 r = RC_IRET;
5055 for (;;) {
5056 gv(r);
5057 if (--ret_nregs == 0)
5058 break;
5059 /* We assume that when a structure is returned in multiple
5060 registers, their classes are consecutive values of the
5061 suite s(n) = 2^n */
5062 r <<= 1;
5063 vtop->c.i += regsize;
5064 vtop->r = VT_LOCAL | VT_LVAL;
5067 } else if (is_float(func_vt.t)) {
5068 gv(rc_fret(func_vt.t));
5069 } else {
5070 gv(RC_IRET);
5072 #endif
5073 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5075 skip(';');
5076 /* jump unless last stmt in top-level block */
5077 if (tok != '}' || local_scope != 1)
5078 rsym = gjmp(rsym);
5079 } else if (tok == TOK_BREAK) {
5080 /* compute jump */
5081 if (!bsym)
5082 tcc_error("cannot break");
5083 *bsym = gjmp(*bsym);
5084 next();
5085 skip(';');
5086 } else if (tok == TOK_CONTINUE) {
5087 /* compute jump */
5088 if (!csym)
5089 tcc_error("cannot continue");
5090 vla_sp_restore_root();
5091 *csym = gjmp(*csym);
5092 next();
5093 skip(';');
5094 } else if (tok == TOK_FOR) {
5095 int e;
5096 next();
5097 skip('(');
5098 s = local_stack;
5099 ++local_scope;
5100 if (tok != ';') {
5101 /* c99 for-loop init decl? */
5102 if (!decl0(VT_LOCAL, 1)) {
5103 /* no, regular for-loop init expr */
5104 gexpr();
5105 vpop();
5108 skip(';');
5109 d = ind;
5110 c = ind;
5111 vla_sp_restore();
5112 a = 0;
5113 b = 0;
5114 if (tok != ';') {
5115 gexpr();
5116 a = gvtst(1, 0);
5118 skip(';');
5119 if (tok != ')') {
5120 e = gjmp(0);
5121 c = ind;
5122 vla_sp_restore();
5123 gexpr();
5124 vpop();
5125 gjmp_addr(d);
5126 gsym(e);
5128 skip(')');
5129 block(&a, &b, 0);
5130 if(!nocode_wanted)
5131 gjmp_addr(c);
5132 gsym(a);
5133 gsym_addr(b, c);
5134 --local_scope;
5135 sym_pop(&local_stack, s);
5137 } else
5138 if (tok == TOK_DO) {
5139 next();
5140 a = 0;
5141 b = 0;
5142 d = ind;
5143 vla_sp_restore();
5144 block(&a, &b, 0);
5145 skip(TOK_WHILE);
5146 skip('(');
5147 gsym(b);
5148 gexpr();
5149 c = gvtst(0, 0);
5150 gsym_addr(c, d);
5151 skip(')');
5152 gsym(a);
5153 skip(';');
5154 } else
5155 if (tok == TOK_SWITCH) {
5156 struct switch_t *saved, sw;
5157 next();
5158 skip('(');
5159 gexpr();
5160 /* XXX: other types than integer */
5161 c = gv(RC_INT);
5162 vpop();
5163 skip(')');
5164 a = 0;
5165 b = gjmp(0); /* jump to first case */
5166 sw.p = NULL; sw.n = 0; sw.def_sym = 0;
5167 saved = cur_switch;
5168 cur_switch = &sw; block(&a, csym, 0);
5169 cur_switch = saved;
5170 a = gjmp(a); /* add implicit break */
5171 gsym(b);
5173 qsort(sw.p, sw.n, sizeof(void*), case_cmp);
5174 for (b = 0; b < sw.n; b++) {
5175 int v = sw.p[b]->v1;
5176 if (b && v <= d)
5177 tcc_error("duplicate case value");
5178 d = sw.p[b]->v2;
5180 vseti(c, 0);
5181 vpushi(v);
5182 if (v == d) {
5183 gen_op(TOK_EQ);
5184 gtst_addr(0, sw.p[b]->sym);
5185 } else {
5186 int e;
5187 gen_op(TOK_GE);
5188 e = gtst(1, 0);
5189 vseti(c, 0);
5190 vpushi(d);
5191 gen_op(TOK_LE);
5192 gtst_addr(0, sw.p[b]->sym);
5193 gsym(e);
5196 if (sw.def_sym)
5197 gjmp_addr(sw.def_sym);
5198 /* break label */
5199 gsym(a);
5200 } else
5201 if (tok == TOK_CASE) {
5202 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
5203 if (!cur_switch)
5204 expect("switch");
5205 next();
5206 cr->v1 = cr->v2 = expr_const();
5207 if (gnu_ext && tok == TOK_DOTS) {
5208 next();
5209 cr->v2 = expr_const();
5210 if (cr->v2 < cr->v1)
5211 tcc_warning("empty case range");
5213 cr->sym = ind;
5214 dynarray_add((void***) &cur_switch->p, &cur_switch->n, cr);
5215 skip(':');
5216 is_expr = 0;
5217 goto block_after_label;
5218 } else
5219 if (tok == TOK_DEFAULT) {
5220 next();
5221 skip(':');
5222 if (!cur_switch)
5223 expect("switch");
5224 if (cur_switch->def_sym)
5225 tcc_error("too many 'default'");
5226 cur_switch->def_sym = ind;
5227 is_expr = 0;
5228 goto block_after_label;
5229 } else
5230 if (tok == TOK_GOTO) {
5231 next();
5232 if (tok == '*' && gnu_ext) {
5233 /* computed goto */
5234 next();
5235 gexpr();
5236 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5237 expect("pointer");
5238 ggoto();
5239 } else if (tok >= TOK_UIDENT) {
5240 s = label_find(tok);
5241 /* put forward definition if needed */
5242 if (!s) {
5243 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5244 } else {
5245 if (s->r == LABEL_DECLARED)
5246 s->r = LABEL_FORWARD;
5248 vla_sp_restore_root();
5249 if (s->r & LABEL_FORWARD)
5250 s->jnext = gjmp(s->jnext);
5251 else
5252 gjmp_addr(s->jnext);
5253 next();
5254 } else {
5255 expect("label identifier");
5257 skip(';');
5258 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
5259 asm_instr();
5260 } else {
5261 b = is_label();
5262 if (b) {
5263 /* label case */
5264 s = label_find(b);
5265 if (s) {
5266 if (s->r == LABEL_DEFINED)
5267 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
5268 gsym(s->jnext);
5269 s->r = LABEL_DEFINED;
5270 } else {
5271 s = label_push(&global_label_stack, b, LABEL_DEFINED);
5273 s->jnext = ind;
5274 vla_sp_restore();
5275 /* we accept this, but it is a mistake */
5276 block_after_label:
5277 if (tok == '}') {
5278 tcc_warning("deprecated use of label at end of compound statement");
5279 } else {
5280 if (is_expr)
5281 vpop();
5282 block(bsym, csym, is_expr);
5284 } else {
5285 /* expression case */
5286 if (tok != ';') {
5287 if (is_expr) {
5288 vpop();
5289 gexpr();
5290 } else {
5291 gexpr();
5292 vpop();
5295 skip(';');
5300 /* t is the array or struct type. c is the array or struct
5301 address. cur_index/cur_field is the pointer to the current
5302 value. 'size_only' is true if only size info is needed (only used
5303 in arrays) */
5304 static void decl_designator(CType *type, Section *sec, unsigned long c,
5305 int *cur_index, Sym **cur_field,
5306 int size_only)
5308 Sym *s, *f;
5309 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5310 CType type1;
5312 notfirst = 0;
5313 elem_size = 0;
5314 nb_elems = 1;
5315 if (gnu_ext && (l = is_label()) != 0)
5316 goto struct_field;
5317 while (tok == '[' || tok == '.') {
5318 if (tok == '[') {
5319 if (!(type->t & VT_ARRAY))
5320 expect("array type");
5321 s = type->ref;
5322 next();
5323 index = expr_const();
5324 if (index < 0 || (s->c >= 0 && index >= s->c))
5325 expect("invalid index");
5326 if (tok == TOK_DOTS && gnu_ext) {
5327 next();
5328 index_last = expr_const();
5329 if (index_last < 0 ||
5330 (s->c >= 0 && index_last >= s->c) ||
5331 index_last < index)
5332 expect("invalid index");
5333 } else {
5334 index_last = index;
5336 skip(']');
5337 if (!notfirst)
5338 *cur_index = index_last;
5339 type = pointed_type(type);
5340 elem_size = type_size(type, &align);
5341 c += index * elem_size;
5342 /* NOTE: we only support ranges for last designator */
5343 nb_elems = index_last - index + 1;
5344 if (nb_elems != 1) {
5345 notfirst = 1;
5346 break;
5348 } else {
5349 next();
5350 l = tok;
5351 next();
5352 struct_field:
5353 if ((type->t & VT_BTYPE) != VT_STRUCT)
5354 expect("struct/union type");
5355 s = type->ref;
5356 l |= SYM_FIELD;
5357 f = s->next;
5358 while (f) {
5359 if (f->v == l)
5360 break;
5361 f = f->next;
5363 if (!f)
5364 expect("field");
5365 if (!notfirst)
5366 *cur_field = f;
5367 /* XXX: fix this mess by using explicit storage field */
5368 type1 = f->type;
5369 type1.t |= (type->t & ~VT_TYPE);
5370 type = &type1;
5371 c += f->c;
5373 notfirst = 1;
5375 if (notfirst) {
5376 if (tok == '=') {
5377 next();
5378 } else {
5379 if (!gnu_ext)
5380 expect("=");
5382 } else {
5383 if (type->t & VT_ARRAY) {
5384 index = *cur_index;
5385 type = pointed_type(type);
5386 c += index * type_size(type, &align);
5387 } else {
5388 f = *cur_field;
5389 if (!f)
5390 tcc_error("too many field init");
5391 /* XXX: fix this mess by using explicit storage field */
5392 type1 = f->type;
5393 type1.t |= (type->t & ~VT_TYPE);
5394 type = &type1;
5395 c += f->c;
5398 decl_initializer(type, sec, c, 0, size_only);
5400 /* XXX: make it more general */
5401 if (!size_only && nb_elems > 1) {
5402 unsigned long c_end;
5403 uint8_t *src, *dst;
5404 int i;
5406 if (!sec)
5407 tcc_error("range init not supported yet for dynamic storage");
5408 c_end = c + nb_elems * elem_size;
5409 if (c_end > sec->data_allocated)
5410 section_realloc(sec, c_end);
5411 src = sec->data + c;
5412 dst = src;
5413 for(i = 1; i < nb_elems; i++) {
5414 dst += elem_size;
5415 memcpy(dst, src, elem_size);
5420 #define EXPR_VAL 0
5421 #define EXPR_CONST 1
5422 #define EXPR_ANY 2
5424 /* store a value or an expression directly in global data or in local array */
5425 static void init_putv(CType *type, Section *sec, unsigned long c,
5426 int v, int expr_type)
5428 int saved_global_expr, bt, bit_pos, bit_size;
5429 void *ptr;
5430 unsigned long long bit_mask;
5431 CType dtype;
5433 switch(expr_type) {
5434 case EXPR_VAL:
5435 vpushi(v);
5436 break;
5437 case EXPR_CONST:
5438 /* compound literals must be allocated globally in this case */
5439 saved_global_expr = global_expr;
5440 global_expr = 1;
5441 expr_const1();
5442 global_expr = saved_global_expr;
5443 /* NOTE: symbols are accepted */
5444 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5445 tcc_error("initializer element is not constant");
5446 break;
5447 case EXPR_ANY:
5448 expr_eq();
5449 break;
5452 dtype = *type;
5453 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5455 if (sec) {
5456 /* XXX: not portable */
5457 /* XXX: generate error if incorrect relocation */
5458 gen_assign_cast(&dtype);
5459 bt = type->t & VT_BTYPE;
5460 /* we'll write at most 16 bytes */
5461 if (c + 16 > sec->data_allocated) {
5462 section_realloc(sec, c + 16);
5464 ptr = sec->data + c;
5465 /* XXX: make code faster ? */
5466 if (!(type->t & VT_BITFIELD)) {
5467 bit_pos = 0;
5468 bit_size = 32;
5469 bit_mask = -1LL;
5470 } else {
5471 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5472 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5473 bit_mask = (1LL << bit_size) - 1;
5475 if ((vtop->r & VT_SYM) &&
5476 (bt == VT_BYTE ||
5477 bt == VT_SHORT ||
5478 bt == VT_DOUBLE ||
5479 bt == VT_LDOUBLE ||
5480 bt == VT_LLONG ||
5481 (bt == VT_INT && bit_size != 32)))
5482 tcc_error("initializer element is not computable at load time");
5483 switch(bt) {
5484 /* XXX: when cross-compiling we assume that each type has the
5485 same representation on host and target, which is likely to
5486 be wrong in the case of long double */
5487 case VT_BOOL:
5488 vtop->c.i = (vtop->c.i != 0);
5489 case VT_BYTE:
5490 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5491 break;
5492 case VT_SHORT:
5493 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5494 break;
5495 case VT_DOUBLE:
5496 *(double *)ptr = vtop->c.d;
5497 break;
5498 case VT_LDOUBLE:
5499 *(long double *)ptr = vtop->c.ld;
5500 break;
5501 case VT_LLONG:
5502 *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5503 break;
5504 case VT_PTR: {
5505 addr_t val = (vtop->c.i & bit_mask) << bit_pos;
5506 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5507 if (vtop->r & VT_SYM)
5508 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5509 else
5510 *(addr_t *)ptr |= val;
5511 #else
5512 if (vtop->r & VT_SYM)
5513 greloc(sec, vtop->sym, c, R_DATA_PTR);
5514 *(addr_t *)ptr |= val;
5515 #endif
5516 break;
5518 default: {
5519 int val = (vtop->c.i & bit_mask) << bit_pos;
5520 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5521 if (vtop->r & VT_SYM)
5522 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5523 else
5524 *(int *)ptr |= val;
5525 #else
5526 if (vtop->r & VT_SYM)
5527 greloc(sec, vtop->sym, c, R_DATA_PTR);
5528 *(int *)ptr |= val;
5529 #endif
5530 break;
5533 vtop--;
5534 } else {
5535 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5536 vswap();
5537 vstore();
5538 vpop();
5542 /* put zeros for variable based init */
5543 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5545 if (sec) {
5546 /* nothing to do because globals are already set to zero */
5547 } else {
5548 vpush_global_sym(&func_old_type, TOK_memset);
5549 vseti(VT_LOCAL, c);
5550 #ifdef TCC_TARGET_ARM
5551 vpushs(size);
5552 vpushi(0);
5553 #else
5554 vpushi(0);
5555 vpushs(size);
5556 #endif
5557 gfunc_call(3);
5561 /* 't' contains the type and storage info. 'c' is the offset of the
5562 object in section 'sec'. If 'sec' is NULL, it means stack based
5563 allocation. 'first' is true if array '{' must be read (multi
5564 dimension implicit array init handling). 'size_only' is true if
5565 size only evaluation is wanted (only for arrays). */
5566 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5567 int first, int size_only)
5569 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5570 int size1, align1, expr_type;
5571 Sym *s, *f;
5572 CType *t1;
5574 if (type->t & VT_VLA) {
5575 int a;
5577 /* save current stack pointer */
5578 if (vlas_in_scope == 0) {
5579 if (vla_sp_root_loc == -1)
5580 vla_sp_root_loc = (loc -= PTR_SIZE);
5581 gen_vla_sp_save(vla_sp_root_loc);
5584 vla_runtime_type_size(type, &a);
5585 gen_vla_alloc(type, a);
5586 gen_vla_sp_save(c);
5587 vla_sp_loc = c;
5588 vlas_in_scope++;
5589 } else if (type->t & VT_ARRAY) {
5590 s = type->ref;
5591 n = s->c;
5592 array_length = 0;
5593 t1 = pointed_type(type);
5594 size1 = type_size(t1, &align1);
5596 no_oblock = 1;
5597 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5598 tok == '{') {
5599 if (tok != '{')
5600 tcc_error("character array initializer must be a literal,"
5601 " optionally enclosed in braces");
5602 skip('{');
5603 no_oblock = 0;
5606 /* only parse strings here if correct type (otherwise: handle
5607 them as ((w)char *) expressions */
5608 if ((tok == TOK_LSTR &&
5609 #ifdef TCC_TARGET_PE
5610 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5611 #else
5612 (t1->t & VT_BTYPE) == VT_INT
5613 #endif
5614 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5615 while (tok == TOK_STR || tok == TOK_LSTR) {
5616 int cstr_len, ch;
5618 /* compute maximum number of chars wanted */
5619 if (tok == TOK_STR)
5620 cstr_len = tokc.str.size;
5621 else
5622 cstr_len = tokc.str.size / sizeof(nwchar_t);
5623 cstr_len--;
5624 nb = cstr_len;
5625 if (n >= 0 && nb > (n - array_length))
5626 nb = n - array_length;
5627 if (!size_only) {
5628 if (cstr_len > nb)
5629 tcc_warning("initializer-string for array is too long");
5630 /* in order to go faster for common case (char
5631 string in global variable, we handle it
5632 specifically */
5633 if (sec && tok == TOK_STR && size1 == 1) {
5634 memcpy(sec->data + c + array_length, tokc.str.data, nb);
5635 } else {
5636 for(i=0;i<nb;i++) {
5637 if (tok == TOK_STR)
5638 ch = ((unsigned char *)tokc.str.data)[i];
5639 else
5640 ch = ((nwchar_t *)tokc.str.data)[i];
5641 init_putv(t1, sec, c + (array_length + i) * size1,
5642 ch, EXPR_VAL);
5646 array_length += nb;
5647 next();
5649 /* only add trailing zero if enough storage (no
5650 warning in this case since it is standard) */
5651 if (n < 0 || array_length < n) {
5652 if (!size_only) {
5653 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5655 array_length++;
5657 } else {
5658 index = 0;
5659 while (tok != '}') {
5660 decl_designator(type, sec, c, &index, NULL, size_only);
5661 if (n >= 0 && index >= n)
5662 tcc_error("index too large");
5663 /* must put zero in holes (note that doing it that way
5664 ensures that it even works with designators) */
5665 if (!size_only && array_length < index) {
5666 init_putz(t1, sec, c + array_length * size1,
5667 (index - array_length) * size1);
5669 index++;
5670 if (index > array_length)
5671 array_length = index;
5672 /* special test for multi dimensional arrays (may not
5673 be strictly correct if designators are used at the
5674 same time) */
5675 if (index >= n && no_oblock)
5676 break;
5677 if (tok == '}')
5678 break;
5679 skip(',');
5682 if (!no_oblock)
5683 skip('}');
5684 /* put zeros at the end */
5685 if (!size_only && n >= 0 && array_length < n) {
5686 init_putz(t1, sec, c + array_length * size1,
5687 (n - array_length) * size1);
5689 /* patch type size if needed */
5690 if (n < 0)
5691 s->c = array_length;
5692 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5693 (sec || !first || tok == '{')) {
5695 /* NOTE: the previous test is a specific case for automatic
5696 struct/union init */
5697 /* XXX: union needs only one init */
5699 int par_count = 0;
5700 if (tok == '(') {
5701 AttributeDef ad1;
5702 CType type1;
5703 next();
5704 if (tcc_state->old_struct_init_code) {
5705 /* an old version of struct initialization.
5706 It have a problems. But with a new version
5707 linux 2.4.26 can't load ramdisk.
5709 while (tok == '(') {
5710 par_count++;
5711 next();
5713 if (!parse_btype(&type1, &ad1))
5714 expect("cast");
5715 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5716 #if 0
5717 if (!is_assignable_types(type, &type1))
5718 tcc_error("invalid type for cast");
5719 #endif
5720 skip(')');
5722 else
5724 if (tok != '(') {
5725 if (!parse_btype(&type1, &ad1))
5726 expect("cast");
5727 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5728 #if 0
5729 if (!is_assignable_types(type, &type1))
5730 tcc_error("invalid type for cast");
5731 #endif
5732 skip(')');
5733 } else
5734 unget_tok(tok);
5738 no_oblock = 1;
5739 if (first || tok == '{') {
5740 skip('{');
5741 no_oblock = 0;
5743 s = type->ref;
5744 f = s->next;
5745 array_length = 0;
5746 index = 0;
5747 n = s->c;
5748 while (tok != '}') {
5749 decl_designator(type, sec, c, NULL, &f, size_only);
5750 index = f->c;
5751 if (!size_only && array_length < index) {
5752 init_putz(type, sec, c + array_length,
5753 index - array_length);
5755 index = index + type_size(&f->type, &align1);
5756 if (index > array_length)
5757 array_length = index;
5759 /* gr: skip fields from same union - ugly. */
5760 while (f->next) {
5761 int align = 0;
5762 int f_size = type_size(&f->type, &align);
5763 int f_type = (f->type.t & VT_BTYPE);
5765 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5766 /* test for same offset */
5767 if (f->next->c != f->c)
5768 break;
5769 if ((f_type == VT_STRUCT) && (f_size == 0)) {
5771 Lets assume a structure of size 0 can't be a member of the union.
5772 This allow to compile the following code from a linux kernel v2.4.26
5773 typedef struct { } rwlock_t;
5774 struct fs_struct {
5775 int count;
5776 rwlock_t lock;
5777 int umask;
5779 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
5780 tcc-0.9.23 can succesfully compile this version of the kernel.
5781 gcc don't have problems with this code too.
5783 break;
5785 /* if yes, test for bitfield shift */
5786 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5787 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5788 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5789 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5790 if (bit_pos_1 != bit_pos_2)
5791 break;
5793 f = f->next;
5796 f = f->next;
5797 if (no_oblock && f == NULL)
5798 break;
5799 if (tok == '}')
5800 break;
5801 skip(',');
5803 /* put zeros at the end */
5804 if (!size_only && array_length < n) {
5805 init_putz(type, sec, c + array_length,
5806 n - array_length);
5808 if (!no_oblock)
5809 skip('}');
5810 while (par_count) {
5811 skip(')');
5812 par_count--;
5814 } else if (tok == '{') {
5815 next();
5816 decl_initializer(type, sec, c, first, size_only);
5817 skip('}');
5818 } else if (size_only) {
5819 /* just skip expression */
5820 parlevel = parlevel1 = 0;
5821 while ((parlevel > 0 || parlevel1 > 0 ||
5822 (tok != '}' && tok != ',')) && tok != -1) {
5823 if (tok == '(')
5824 parlevel++;
5825 else if (tok == ')') {
5826 if (parlevel == 0 && parlevel1 == 0)
5827 break;
5828 parlevel--;
5830 else if (tok == '{')
5831 parlevel1++;
5832 else if (tok == '}') {
5833 if (parlevel == 0 && parlevel1 == 0)
5834 break;
5835 parlevel1--;
5837 next();
5839 } else {
5840 /* currently, we always use constant expression for globals
5841 (may change for scripting case) */
5842 expr_type = EXPR_CONST;
5843 if (!sec)
5844 expr_type = EXPR_ANY;
5845 init_putv(type, sec, c, 0, expr_type);
5849 /* parse an initializer for type 't' if 'has_init' is non zero, and
5850 allocate space in local or global data space ('r' is either
5851 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5852 variable 'v' of scope 'scope' is declared before initializers
5853 are parsed. If 'v' is zero, then a reference to the new object
5854 is put in the value stack. If 'has_init' is 2, a special parsing
5855 is done to handle string constants. */
5856 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5857 int has_init, int v, int scope)
5859 int size, align, addr, data_offset;
5860 int level;
5861 ParseState saved_parse_state = {0};
5862 TokenString *init_str = NULL;
5863 Section *sec;
5864 Sym *flexible_array;
5866 flexible_array = NULL;
5867 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5868 Sym *field = type->ref->next;
5869 if (field) {
5870 while (field->next)
5871 field = field->next;
5872 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5873 flexible_array = field;
5877 size = type_size(type, &align);
5878 /* If unknown size, we must evaluate it before
5879 evaluating initializers because
5880 initializers can generate global data too
5881 (e.g. string pointers or ISOC99 compound
5882 literals). It also simplifies local
5883 initializers handling */
5884 if (size < 0 || (flexible_array && has_init)) {
5885 if (!has_init)
5886 tcc_error("unknown type size");
5887 /* get all init string */
5888 init_str = tok_str_alloc();
5889 if (has_init == 2) {
5890 /* only get strings */
5891 while (tok == TOK_STR || tok == TOK_LSTR) {
5892 tok_str_add_tok(init_str);
5893 next();
5895 } else {
5896 level = 0;
5897 while (level > 0 || (tok != ',' && tok != ';')) {
5898 if (tok < 0)
5899 tcc_error("unexpected end of file in initializer");
5900 tok_str_add_tok(init_str);
5901 if (tok == '{')
5902 level++;
5903 else if (tok == '}') {
5904 level--;
5905 if (level <= 0) {
5906 next();
5907 break;
5910 next();
5913 tok_str_add(init_str, -1);
5914 tok_str_add(init_str, 0);
5916 /* compute size */
5917 save_parse_state(&saved_parse_state);
5919 begin_macro(init_str, 1);
5920 next();
5921 decl_initializer(type, NULL, 0, 1, 1);
5922 /* prepare second initializer parsing */
5923 macro_ptr = init_str->str;
5924 next();
5926 /* if still unknown size, error */
5927 size = type_size(type, &align);
5928 if (size < 0)
5929 tcc_error("unknown type size");
5931 /* If there's a flex member and it was used in the initializer
5932 adjust size. */
5933 if (flexible_array &&
5934 flexible_array->type.ref->c > 0)
5935 size += flexible_array->type.ref->c
5936 * pointed_size(&flexible_array->type);
5937 /* take into account specified alignment if bigger */
5938 if (ad->a.aligned) {
5939 if (ad->a.aligned > align)
5940 align = ad->a.aligned;
5941 } else if (ad->a.packed) {
5942 align = 1;
5944 if ((r & VT_VALMASK) == VT_LOCAL) {
5945 sec = NULL;
5946 #ifdef CONFIG_TCC_BCHECK
5947 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5948 loc--;
5950 #endif
5951 loc = (loc - size) & -align;
5952 addr = loc;
5953 #ifdef CONFIG_TCC_BCHECK
5954 /* handles bounds */
5955 /* XXX: currently, since we do only one pass, we cannot track
5956 '&' operators, so we add only arrays */
5957 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5958 addr_t *bounds_ptr;
5959 /* add padding between regions */
5960 loc--;
5961 /* then add local bound info */
5962 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
5963 bounds_ptr[0] = addr;
5964 bounds_ptr[1] = size;
5966 #endif
5967 if (v) {
5968 /* local variable */
5969 sym_push(v, type, r, addr);
5970 } else {
5971 /* push local reference */
5972 vset(type, r, addr);
5974 } else {
5975 Sym *sym;
5977 sym = NULL;
5978 if (v && scope == VT_CONST) {
5979 /* see if the symbol was already defined */
5980 sym = sym_find(v);
5981 if (sym) {
5982 if (!is_compatible_types(&sym->type, type))
5983 tcc_error("incompatible types for redefinition of '%s'",
5984 get_tok_str(v, NULL));
5985 if (sym->type.t & VT_EXTERN) {
5986 /* if the variable is extern, it was not allocated */
5987 sym->type.t &= ~VT_EXTERN;
5988 /* set array size if it was omitted in extern
5989 declaration */
5990 if ((sym->type.t & VT_ARRAY) &&
5991 sym->type.ref->c < 0 &&
5992 type->ref->c >= 0)
5993 sym->type.ref->c = type->ref->c;
5994 } else {
5995 /* we accept several definitions of the same
5996 global variable. this is tricky, because we
5997 must play with the SHN_COMMON type of the symbol */
5998 /* XXX: should check if the variable was already
5999 initialized. It is incorrect to initialized it
6000 twice */
6001 /* no init data, we won't add more to the symbol */
6002 if (!has_init)
6003 goto no_alloc;
6008 /* allocate symbol in corresponding section */
6009 sec = ad->section;
6010 if (!sec) {
6011 if (has_init)
6012 sec = data_section;
6013 else if (tcc_state->nocommon)
6014 sec = bss_section;
6016 if (sec) {
6017 data_offset = sec->data_offset;
6018 data_offset = (data_offset + align - 1) & -align;
6019 addr = data_offset;
6020 /* very important to increment global pointer at this time
6021 because initializers themselves can create new initializers */
6022 data_offset += size;
6023 #ifdef CONFIG_TCC_BCHECK
6024 /* add padding if bound check */
6025 if (tcc_state->do_bounds_check)
6026 data_offset++;
6027 #endif
6028 sec->data_offset = data_offset;
6029 /* allocate section space to put the data */
6030 if (sec->sh_type != SHT_NOBITS &&
6031 data_offset > sec->data_allocated)
6032 section_realloc(sec, data_offset);
6033 /* align section if needed */
6034 if (align > sec->sh_addralign)
6035 sec->sh_addralign = align;
6036 } else {
6037 addr = 0; /* avoid warning */
6040 if (v) {
6041 if (scope != VT_CONST || !sym) {
6042 sym = sym_push(v, type, r | VT_SYM, 0);
6043 sym->asm_label = ad->asm_label;
6045 /* update symbol definition */
6046 if (sec) {
6047 put_extern_sym(sym, sec, addr, size);
6048 } else {
6049 ElfW(Sym) *esym;
6050 /* put a common area */
6051 put_extern_sym(sym, NULL, align, size);
6052 /* XXX: find a nicer way */
6053 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
6054 esym->st_shndx = SHN_COMMON;
6056 } else {
6057 /* push global reference */
6058 sym = get_sym_ref(type, sec, addr, size);
6059 vpushsym(type, sym);
6061 /* patch symbol weakness */
6062 if (type->t & VT_WEAK)
6063 weaken_symbol(sym);
6064 apply_visibility(sym, type);
6065 #ifdef CONFIG_TCC_BCHECK
6066 /* handles bounds now because the symbol must be defined
6067 before for the relocation */
6068 if (tcc_state->do_bounds_check) {
6069 addr_t *bounds_ptr;
6071 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
6072 /* then add global bound info */
6073 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
6074 bounds_ptr[0] = 0; /* relocated */
6075 bounds_ptr[1] = size;
6077 #endif
6079 if (has_init || (type->t & VT_VLA)) {
6080 decl_initializer(type, sec, addr, 1, 0);
6081 /* patch flexible array member size back to -1, */
6082 /* for possible subsequent similar declarations */
6083 if (flexible_array)
6084 flexible_array->type.ref->c = -1;
6086 no_alloc: ;
6087 /* restore parse state if needed */
6088 if (init_str) {
6089 end_macro();
6090 restore_parse_state(&saved_parse_state);
6094 static void put_func_debug(Sym *sym)
6096 char buf[512];
6098 /* stabs info */
6099 /* XXX: we put here a dummy type */
6100 snprintf(buf, sizeof(buf), "%s:%c1",
6101 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
6102 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6103 cur_text_section, sym->c);
6104 /* //gr gdb wants a line at the function */
6105 put_stabn(N_SLINE, 0, file->line_num, 0);
6106 last_ind = 0;
6107 last_line_num = 0;
6110 /* parse an old style function declaration list */
6111 /* XXX: check multiple parameter */
6112 static void func_decl_list(Sym *func_sym)
6114 AttributeDef ad;
6115 int v;
6116 Sym *s;
6117 CType btype, type;
6119 /* parse each declaration */
6120 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
6121 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
6122 if (!parse_btype(&btype, &ad))
6123 expect("declaration list");
6124 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6125 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6126 tok == ';') {
6127 /* we accept no variable after */
6128 } else {
6129 for(;;) {
6130 type = btype;
6131 type_decl(&type, &ad, &v, TYPE_DIRECT);
6132 /* find parameter in function parameter list */
6133 s = func_sym->next;
6134 while (s != NULL) {
6135 if ((s->v & ~SYM_FIELD) == v)
6136 goto found;
6137 s = s->next;
6139 tcc_error("declaration for parameter '%s' but no such parameter",
6140 get_tok_str(v, NULL));
6141 found:
6142 /* check that no storage specifier except 'register' was given */
6143 if (type.t & VT_STORAGE)
6144 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
6145 convert_parameter_type(&type);
6146 /* we can add the type (NOTE: it could be local to the function) */
6147 s->type = type;
6148 /* accept other parameters */
6149 if (tok == ',')
6150 next();
6151 else
6152 break;
6155 skip(';');
6159 /* parse a function defined by symbol 'sym' and generate its code in
6160 'cur_text_section' */
6161 static void gen_function(Sym *sym)
6163 int saved_nocode_wanted = nocode_wanted;
6165 nocode_wanted = 0;
6166 ind = cur_text_section->data_offset;
6167 /* NOTE: we patch the symbol size later */
6168 put_extern_sym(sym, cur_text_section, ind, 0);
6169 funcname = get_tok_str(sym->v, NULL);
6170 func_ind = ind;
6171 /* Initialize VLA state */
6172 vla_sp_loc = -1;
6173 vla_sp_root_loc = -1;
6174 /* put debug symbol */
6175 if (tcc_state->do_debug)
6176 put_func_debug(sym);
6178 /* push a dummy symbol to enable local sym storage */
6179 sym_push2(&local_stack, SYM_FIELD, 0, 0);
6180 local_scope = 1; /* for function parameters */
6181 gfunc_prolog(&sym->type);
6182 local_scope = 0;
6184 rsym = 0;
6185 block(NULL, NULL, 0);
6186 gsym(rsym);
6187 gfunc_epilog();
6188 cur_text_section->data_offset = ind;
6189 label_pop(&global_label_stack, NULL);
6190 /* reset local stack */
6191 local_scope = 0;
6192 sym_pop(&local_stack, NULL);
6193 /* end of function */
6194 /* patch symbol size */
6195 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
6196 ind - func_ind;
6197 /* patch symbol weakness (this definition overrules any prototype) */
6198 if (sym->type.t & VT_WEAK)
6199 weaken_symbol(sym);
6200 apply_visibility(sym, &sym->type);
6201 if (tcc_state->do_debug) {
6202 put_stabn(N_FUN, 0, 0, ind - func_ind);
6204 /* It's better to crash than to generate wrong code */
6205 cur_text_section = NULL;
6206 funcname = ""; /* for safety */
6207 func_vt.t = VT_VOID; /* for safety */
6208 func_var = 0; /* for safety */
6209 ind = 0; /* for safety */
6210 nocode_wanted = saved_nocode_wanted;
6211 check_vstack();
6214 ST_FUNC void gen_inline_functions(void)
6216 Sym *sym;
6217 int inline_generated, i, ln;
6218 struct InlineFunc *fn;
6220 ln = file->line_num;
6221 /* iterate while inline function are referenced */
6222 for(;;) {
6223 inline_generated = 0;
6224 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6225 fn = tcc_state->inline_fns[i];
6226 sym = fn->sym;
6227 if (sym && sym->c) {
6228 /* the function was used: generate its code and
6229 convert it to a normal function */
6230 fn->sym = NULL;
6231 if (file)
6232 pstrcpy(file->filename, sizeof file->filename, fn->filename);
6233 sym->r = VT_SYM | VT_CONST;
6234 sym->type.t &= ~VT_INLINE;
6236 begin_macro(&fn->func_str, 0);
6237 next();
6238 cur_text_section = text_section;
6239 gen_function(sym);
6240 end_macro();
6242 inline_generated = 1;
6245 if (!inline_generated)
6246 break;
6248 file->line_num = ln;
6249 /* free tokens of unused inline functions */
6250 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6251 fn = tcc_state->inline_fns[i];
6252 if (fn->sym)
6253 tok_str_free(fn->func_str.str);
6255 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
6258 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6259 static int decl0(int l, int is_for_loop_init)
6261 int v, has_init, r;
6262 CType type, btype;
6263 Sym *sym;
6264 AttributeDef ad;
6266 while (1) {
6267 if (!parse_btype(&btype, &ad)) {
6268 if (is_for_loop_init)
6269 return 0;
6270 /* skip redundant ';' */
6271 /* XXX: find more elegant solution */
6272 if (tok == ';') {
6273 next();
6274 continue;
6276 if (l == VT_CONST &&
6277 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6278 /* global asm block */
6279 asm_global_instr();
6280 continue;
6282 /* special test for old K&R protos without explicit int
6283 type. Only accepted when defining global data */
6284 if (l == VT_LOCAL || tok < TOK_DEFINE)
6285 break;
6286 btype.t = VT_INT;
6288 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6289 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6290 tok == ';') {
6291 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
6292 int v = btype.ref->v;
6293 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
6294 tcc_warning("unnamed struct/union that defines no instances");
6296 next();
6297 continue;
6299 while (1) { /* iterate thru each declaration */
6300 type = btype;
6301 type_decl(&type, &ad, &v, TYPE_DIRECT);
6302 #if 0
6304 char buf[500];
6305 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6306 printf("type = '%s'\n", buf);
6308 #endif
6309 if ((type.t & VT_BTYPE) == VT_FUNC) {
6310 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
6311 tcc_error("function without file scope cannot be static");
6313 /* if old style function prototype, we accept a
6314 declaration list */
6315 sym = type.ref;
6316 if (sym->c == FUNC_OLD)
6317 func_decl_list(sym);
6320 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6321 ad.asm_label = asm_label_instr();
6322 /* parse one last attribute list, after asm label */
6323 parse_attribute(&ad);
6324 if (tok == '{')
6325 expect(";");
6328 if (ad.a.weak)
6329 type.t |= VT_WEAK;
6330 #ifdef TCC_TARGET_PE
6331 if (ad.a.func_import)
6332 type.t |= VT_IMPORT;
6333 if (ad.a.func_export)
6334 type.t |= VT_EXPORT;
6335 #endif
6336 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6338 if (tok == '{') {
6339 if (l == VT_LOCAL)
6340 tcc_error("cannot use local functions");
6341 if ((type.t & VT_BTYPE) != VT_FUNC)
6342 expect("function definition");
6344 /* reject abstract declarators in function definition */
6345 sym = type.ref;
6346 while ((sym = sym->next) != NULL)
6347 if (!(sym->v & ~SYM_FIELD))
6348 expect("identifier");
6350 /* XXX: cannot do better now: convert extern line to static inline */
6351 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6352 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6354 sym = sym_find(v);
6355 if (sym) {
6356 Sym *ref;
6357 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6358 goto func_error1;
6360 ref = sym->type.ref;
6361 if (0 == ref->a.func_proto)
6362 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6364 /* use func_call from prototype if not defined */
6365 if (ref->a.func_call != FUNC_CDECL
6366 && type.ref->a.func_call == FUNC_CDECL)
6367 type.ref->a.func_call = ref->a.func_call;
6369 /* use export from prototype */
6370 if (ref->a.func_export)
6371 type.ref->a.func_export = 1;
6373 /* use static from prototype */
6374 if (sym->type.t & VT_STATIC)
6375 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6377 /* If the definition has no visibility use the
6378 one from prototype. */
6379 if (! (type.t & VT_VIS_MASK))
6380 type.t |= sym->type.t & VT_VIS_MASK;
6382 if (!is_compatible_types(&sym->type, &type)) {
6383 func_error1:
6384 tcc_error("incompatible types for redefinition of '%s'",
6385 get_tok_str(v, NULL));
6387 type.ref->a.func_proto = 0;
6388 /* if symbol is already defined, then put complete type */
6389 sym->type = type;
6390 } else {
6391 /* put function symbol */
6392 sym = global_identifier_push(v, type.t, 0);
6393 sym->type.ref = type.ref;
6396 /* static inline functions are just recorded as a kind
6397 of macro. Their code will be emitted at the end of
6398 the compilation unit only if they are used */
6399 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6400 (VT_INLINE | VT_STATIC)) {
6401 int block_level;
6402 struct InlineFunc *fn;
6403 const char *filename;
6405 filename = file ? file->filename : "";
6406 fn = tcc_malloc(sizeof *fn + strlen(filename));
6407 strcpy(fn->filename, filename);
6408 fn->sym = sym;
6409 tok_str_new(&fn->func_str);
6411 block_level = 0;
6412 for(;;) {
6413 int t;
6414 if (tok == TOK_EOF)
6415 tcc_error("unexpected end of file");
6416 tok_str_add_tok(&fn->func_str);
6417 t = tok;
6418 next();
6419 if (t == '{') {
6420 block_level++;
6421 } else if (t == '}') {
6422 block_level--;
6423 if (block_level == 0)
6424 break;
6427 tok_str_add(&fn->func_str, -1);
6428 tok_str_add(&fn->func_str, 0);
6429 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6431 } else {
6432 /* compute text section */
6433 cur_text_section = ad.section;
6434 if (!cur_text_section)
6435 cur_text_section = text_section;
6436 sym->r = VT_SYM | VT_CONST;
6437 gen_function(sym);
6439 break;
6440 } else {
6441 if (btype.t & VT_TYPEDEF) {
6442 /* save typedefed type */
6443 /* XXX: test storage specifiers ? */
6444 sym = sym_find(v);
6445 if (sym && sym->scope == local_scope) {
6446 if (!is_compatible_types(&sym->type, &type)
6447 || !(sym->type.t & VT_TYPEDEF))
6448 tcc_error("incompatible redefinition of '%s'",
6449 get_tok_str(v, NULL));
6450 sym->type = type;
6451 } else {
6452 sym = sym_push(v, &type, 0, 0);
6454 sym->a = ad.a;
6455 sym->type.t |= VT_TYPEDEF;
6456 } else {
6457 r = 0;
6458 if ((type.t & VT_BTYPE) == VT_FUNC) {
6459 /* external function definition */
6460 /* specific case for func_call attribute */
6461 ad.a.func_proto = 1;
6462 type.ref->a = ad.a;
6463 } else if (!(type.t & VT_ARRAY)) {
6464 /* not lvalue if array */
6465 r |= lvalue_type(type.t);
6467 has_init = (tok == '=');
6468 if (has_init && (type.t & VT_VLA))
6469 tcc_error("Variable length array cannot be initialized");
6470 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6471 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6472 !has_init && l == VT_CONST && type.ref->c < 0)) {
6473 /* external variable or function */
6474 /* NOTE: as GCC, uninitialized global static
6475 arrays of null size are considered as
6476 extern */
6477 sym = external_sym(v, &type, r);
6478 sym->asm_label = ad.asm_label;
6480 if (ad.alias_target) {
6481 Section tsec;
6482 Elf32_Sym *esym;
6483 Sym *alias_target;
6485 alias_target = sym_find(ad.alias_target);
6486 if (!alias_target || !alias_target->c)
6487 tcc_error("unsupported forward __alias__ attribute");
6488 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6489 tsec.sh_num = esym->st_shndx;
6490 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6492 } else {
6493 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6494 if (type.t & VT_STATIC)
6495 r |= VT_CONST;
6496 else
6497 r |= l;
6498 if (has_init)
6499 next();
6500 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
6503 if (tok != ',') {
6504 if (is_for_loop_init)
6505 return 1;
6506 skip(';');
6507 break;
6509 next();
6511 ad.a.aligned = 0;
6514 return 0;
6517 ST_FUNC void decl(int l)
6519 decl0(l, 0);