* and #pragma pop_macro("macro_name")
[tinycc.git] / tccgen.c
blob103c955fbde5da62d025c842508f8267f5c8ec4b
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /********************************************************/
24 /* global variables */
26 /* loc : local variable index
27 ind : output code index
28 rsym: return symbol
29 anon_sym: anonymous symbol index
31 ST_DATA int rsym, anon_sym, ind, loc;
33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
34 ST_DATA Section *cur_text_section; /* current section where function code is generated */
35 #ifdef CONFIG_TCC_ASM
36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
37 #endif
38 #ifdef CONFIG_TCC_BCHECK
39 /* bound check related sections */
40 ST_DATA Section *bounds_section; /* contains global data bound description */
41 ST_DATA Section *lbounds_section; /* contains local data bound description */
42 #endif
43 /* symbol sections */
44 ST_DATA Section *symtab_section, *strtab_section;
45 /* debug sections */
46 ST_DATA Section *stab_section, *stabstr_section;
47 ST_DATA Sym *sym_free_first;
48 ST_DATA void **sym_pools;
49 ST_DATA int nb_sym_pools;
51 ST_DATA Sym *global_stack;
52 ST_DATA Sym *local_stack;
53 ST_DATA Sym *scope_stack_bottom;
54 ST_DATA Sym *define_stack;
55 ST_DATA Sym *global_label_stack;
56 ST_DATA Sym *local_label_stack;
58 ST_DATA int vla_sp_loc_tmp; /* vla_sp_loc is set to this when the value won't be needed later */
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 */
61 ST_DATA int vla_flags; /* VLA_* flags */
63 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
65 ST_DATA int const_wanted; /* true if constant wanted */
66 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
67 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
68 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
69 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
70 ST_DATA int func_vc;
71 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
72 ST_DATA char *funcname;
74 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
76 /* ------------------------------------------------------------------------- */
77 static void gen_cast(CType *type);
78 static inline CType *pointed_type(CType *type);
79 static int is_compatible_types(CType *type1, CType *type2);
80 static int parse_btype(CType *type, AttributeDef *ad);
81 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
82 static void parse_expr_type(CType *type);
83 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
84 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
85 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
86 static int decl0(int l, int is_for_loop_init);
87 static void expr_eq(void);
88 static void unary_type(CType *type);
89 static void vla_runtime_type_size(CType *type, int *a);
90 static void vla_sp_save(void);
91 static int is_compatible_parameter_types(CType *type1, CType *type2);
92 static void expr_type(CType *type);
93 ST_FUNC void vpush64(int ty, unsigned long long v);
94 ST_FUNC void vpush(CType *type);
95 ST_FUNC int gvtst(int inv, int t);
96 ST_FUNC int is_btype_size(int bt);
98 ST_INLN int is_float(int t)
100 int bt;
101 bt = t & VT_BTYPE;
102 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
105 /* we use our own 'finite' function to avoid potential problems with
106 non standard math libs */
107 /* XXX: endianness dependent */
108 ST_FUNC int ieee_finite(double d)
110 int p[4];
111 memcpy(p, &d, sizeof(double));
112 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
115 ST_FUNC void test_lvalue(void)
117 if (!(vtop->r & VT_LVAL))
118 expect("lvalue");
121 /* ------------------------------------------------------------------------- */
122 /* symbol allocator */
123 static Sym *__sym_malloc(void)
125 Sym *sym_pool, *sym, *last_sym;
126 int i;
128 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
129 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
131 last_sym = sym_free_first;
132 sym = sym_pool;
133 for(i = 0; i < SYM_POOL_NB; i++) {
134 sym->next = last_sym;
135 last_sym = sym;
136 sym++;
138 sym_free_first = last_sym;
139 return last_sym;
142 static inline Sym *sym_malloc(void)
144 Sym *sym;
145 sym = sym_free_first;
146 if (!sym)
147 sym = __sym_malloc();
148 sym_free_first = sym->next;
149 return sym;
152 ST_INLN void sym_free(Sym *sym)
154 sym->next = sym_free_first;
155 sym_free_first = sym;
158 /* push, without hashing */
159 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
161 Sym *s;
162 if (ps == &local_stack) {
163 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
164 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
165 tcc_error("incompatible types for redefinition of '%s'",
166 get_tok_str(v, NULL));
168 s = sym_malloc();
169 s->asm_label = NULL;
170 s->v = v;
171 s->type.t = t;
172 s->type.ref = NULL;
173 #ifdef _WIN64
174 s->d = NULL;
175 #endif
176 s->c = c;
177 s->next = NULL;
178 /* add in stack */
179 s->prev = *ps;
180 *ps = s;
181 return s;
184 /* find a symbol and return its associated structure. 's' is the top
185 of the symbol stack */
186 ST_FUNC Sym *sym_find2(Sym *s, int v)
188 while (s) {
189 if (s->v == v)
190 return s;
191 else if (s->v == -1)
192 return NULL;
193 s = s->prev;
195 return NULL;
198 /* structure lookup */
199 ST_INLN Sym *struct_find(int v)
201 v -= TOK_IDENT;
202 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
203 return NULL;
204 return table_ident[v]->sym_struct;
207 /* find an identifier */
208 ST_INLN Sym *sym_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_identifier;
216 /* push a given symbol on the symbol stack */
217 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
219 Sym *s, **ps;
220 TokenSym *ts;
222 if (local_stack)
223 ps = &local_stack;
224 else
225 ps = &global_stack;
226 s = sym_push2(ps, v, type->t, c);
227 s->type.ref = type->ref;
228 s->r = r;
229 /* don't record fields or anonymous symbols */
230 /* XXX: simplify */
231 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
232 /* record symbol in token array */
233 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
234 if (v & SYM_STRUCT)
235 ps = &ts->sym_struct;
236 else
237 ps = &ts->sym_identifier;
238 s->prev_tok = *ps;
239 *ps = s;
241 return s;
244 /* push a global identifier */
245 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
247 Sym *s, **ps;
248 s = sym_push2(&global_stack, v, t, c);
249 /* don't record anonymous symbol */
250 if (v < SYM_FIRST_ANOM) {
251 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
252 /* modify the top most local identifier, so that
253 sym_identifier will point to 's' when popped */
254 while (*ps != NULL)
255 ps = &(*ps)->prev_tok;
256 s->prev_tok = NULL;
257 *ps = s;
259 return s;
262 /* pop symbols until top reaches 'b' */
263 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
265 Sym *s, *ss, **ps;
266 TokenSym *ts;
267 int v;
269 s = *ptop;
270 while(s != b) {
271 ss = s->prev;
272 v = s->v;
273 /* remove symbol in token array */
274 /* XXX: simplify */
275 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
276 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
277 if (v & SYM_STRUCT)
278 ps = &ts->sym_struct;
279 else
280 ps = &ts->sym_identifier;
281 *ps = s->prev_tok;
283 sym_free(s);
284 s = ss;
286 *ptop = b;
289 static void weaken_symbol(Sym *sym)
291 sym->type.t |= VT_WEAK;
292 if (sym->c > 0) {
293 int esym_type;
294 ElfW(Sym) *esym;
296 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
297 esym_type = ELFW(ST_TYPE)(esym->st_info);
298 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
302 static void apply_visibility(Sym *sym, CType *type)
304 int vis = sym->type.t & VT_VIS_MASK;
305 int vis2 = type->t & VT_VIS_MASK;
306 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
307 vis = vis2;
308 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
310 else
311 vis = (vis < vis2) ? vis : vis2;
312 sym->type.t &= ~VT_VIS_MASK;
313 sym->type.t |= vis;
315 if (sym->c > 0) {
316 ElfW(Sym) *esym;
318 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
319 vis >>= VT_VIS_SHIFT;
320 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
324 /* ------------------------------------------------------------------------- */
326 ST_FUNC void swap(int *p, int *q)
328 int t;
329 t = *p;
330 *p = *q;
331 *q = t;
334 static void vsetc(CType *type, int r, CValue *vc)
336 int v;
338 if (vtop >= vstack + (VSTACK_SIZE - 1))
339 tcc_error("memory full (vstack)");
340 /* cannot let cpu flags if other instruction are generated. Also
341 avoid leaving VT_JMP anywhere except on the top of the stack
342 because it would complicate the code generator. */
343 if (vtop >= vstack) {
344 v = vtop->r & VT_VALMASK;
345 if (v == VT_CMP || (v & ~1) == VT_JMP)
346 gv(RC_INT);
348 vtop++;
349 vtop->type = *type;
350 vtop->r = r;
351 vtop->r2 = VT_CONST;
352 vtop->c = *vc;
355 /* push constant of type "type" with useless value */
356 ST_FUNC void vpush(CType *type)
358 CValue cval;
359 vsetc(type, VT_CONST, &cval);
362 /* push integer constant */
363 ST_FUNC void vpushi(int v)
365 CValue cval;
366 cval.i = v;
367 vsetc(&int_type, VT_CONST, &cval);
370 /* push a pointer sized constant */
371 static void vpushs(addr_t v)
373 CValue cval;
374 cval.ptr_offset = v;
375 vsetc(&size_type, VT_CONST, &cval);
378 /* push arbitrary 64bit constant */
379 ST_FUNC void vpush64(int ty, unsigned long long v)
381 CValue cval;
382 CType ctype;
383 ctype.t = ty;
384 ctype.ref = NULL;
385 cval.ull = v;
386 vsetc(&ctype, VT_CONST, &cval);
389 /* push long long constant */
390 static inline void vpushll(long long v)
392 vpush64(VT_LLONG, v);
395 /* push a symbol value of TYPE */
396 static inline void vpushsym(CType *type, Sym *sym)
398 CValue cval;
399 cval.ptr_offset = 0;
400 vsetc(type, VT_CONST | VT_SYM, &cval);
401 vtop->sym = sym;
404 /* Return a static symbol pointing to a section */
405 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
407 int v;
408 Sym *sym;
410 v = anon_sym++;
411 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
412 sym->type.ref = type->ref;
413 sym->r = VT_CONST | VT_SYM;
414 put_extern_sym(sym, sec, offset, size);
415 return sym;
418 /* push a reference to a section offset by adding a dummy symbol */
419 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
421 vpushsym(type, get_sym_ref(type, sec, offset, size));
424 /* define a new external reference to a symbol 'v' of type 'u' */
425 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
427 Sym *s;
429 s = sym_find(v);
430 if (!s) {
431 /* push forward reference */
432 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
433 s->type.ref = type->ref;
434 s->r = r | VT_CONST | VT_SYM;
436 return s;
439 /* define a new external reference to a symbol 'v' with alternate asm
440 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
441 is no alternate name (most cases) */
442 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
444 Sym *s;
446 s = sym_find(v);
447 if (!s) {
448 /* push forward reference */
449 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
450 s->asm_label = asm_label;
451 s->type.t |= VT_EXTERN;
452 } else if (s->type.ref == func_old_type.ref) {
453 s->type.ref = type->ref;
454 s->r = r | VT_CONST | VT_SYM;
455 s->type.t |= VT_EXTERN;
456 } else if (!is_compatible_types(&s->type, type)) {
457 tcc_error("incompatible types for redefinition of '%s'",
458 get_tok_str(v, NULL));
460 /* Merge some storage attributes. */
461 if (type->t & VT_WEAK)
462 weaken_symbol(s);
464 if (type->t & VT_VIS_MASK)
465 apply_visibility(s, type);
467 return s;
470 /* push a reference to global symbol v */
471 ST_FUNC void vpush_global_sym(CType *type, int v)
473 vpushsym(type, external_global_sym(v, type, 0));
476 ST_FUNC void vset(CType *type, int r, int v)
478 CValue cval;
480 cval.i = v;
481 vsetc(type, r, &cval);
484 static void vseti(int r, int v)
486 CType type;
487 type.t = VT_INT;
488 type.ref = 0;
489 vset(&type, r, v);
492 ST_FUNC void vswap(void)
494 SValue tmp;
495 /* cannot let cpu flags if other instruction are generated. Also
496 avoid leaving VT_JMP anywhere except on the top of the stack
497 because it would complicate the code generator. */
498 if (vtop >= vstack) {
499 int v = vtop->r & VT_VALMASK;
500 if (v == VT_CMP || (v & ~1) == VT_JMP)
501 gv(RC_INT);
503 tmp = vtop[0];
504 vtop[0] = vtop[-1];
505 vtop[-1] = tmp;
507 /* XXX: +2% overall speed possible with optimized memswap
509 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
513 ST_FUNC void vpushv(SValue *v)
515 if (vtop >= vstack + (VSTACK_SIZE - 1))
516 tcc_error("memory full (vstack)");
517 vtop++;
518 *vtop = *v;
521 static void vdup(void)
523 vpushv(vtop);
526 /* save r to the memory stack, and mark it as being free */
527 ST_FUNC void save_reg(int r)
529 int l, saved, size, align;
530 SValue *p, sv;
531 CType *type;
533 /* modify all stack values */
534 saved = 0;
535 l = 0;
536 for(p=vstack;p<=vtop;p++) {
537 if ((p->r & VT_VALMASK) == r ||
538 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
539 /* must save value on stack if not already done */
540 if (!saved) {
541 /* NOTE: must reload 'r' because r might be equal to r2 */
542 r = p->r & VT_VALMASK;
543 /* store register in the stack */
544 type = &p->type;
545 if ((p->r & VT_LVAL) ||
546 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
547 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
548 type = &char_pointer_type;
549 #else
550 type = &int_type;
551 #endif
552 size = type_size(type, &align);
553 loc = (loc - size) & -align;
554 sv.type.t = type->t;
555 sv.r = VT_LOCAL | VT_LVAL;
556 sv.c.ul = loc;
557 store(r, &sv);
558 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
559 /* x86 specific: need to pop fp register ST0 if saved */
560 if (r == TREG_ST0) {
561 o(0xd8dd); /* fstp %st(0) */
563 #endif
564 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
565 /* special long long case */
566 if ((type->t & VT_BTYPE) == VT_LLONG) {
567 sv.c.ul += 4;
568 store(p->r2, &sv);
570 #endif
571 l = loc;
572 saved = 1;
574 /* mark that stack entry as being saved on the stack */
575 if (p->r & VT_LVAL) {
576 /* also clear the bounded flag because the
577 relocation address of the function was stored in
578 p->c.ul */
579 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
580 } else {
581 p->r = lvalue_type(p->type.t) | VT_LOCAL;
583 p->r2 = VT_CONST;
584 p->c.ul = l;
589 #ifdef TCC_TARGET_ARM
590 /* find a register of class 'rc2' with at most one reference on stack.
591 * If none, call get_reg(rc) */
592 ST_FUNC int get_reg_ex(int rc, int rc2)
594 int r;
595 SValue *p;
597 for(r=0;r<NB_REGS;r++) {
598 if (reg_classes[r] & rc2) {
599 int n;
600 n=0;
601 for(p = vstack; p <= vtop; p++) {
602 if ((p->r & VT_VALMASK) == r ||
603 (p->r2 & VT_VALMASK) == r)
604 n++;
606 if (n <= 1)
607 return r;
610 return get_reg(rc);
612 #endif
614 /* find a free register of class 'rc'. If none, save one register */
615 ST_FUNC int get_reg(int rc)
617 int r;
618 SValue *p;
620 /* find a free register */
621 for(r=0;r<NB_REGS;r++) {
622 if (reg_classes[r] & rc) {
623 for(p=vstack;p<=vtop;p++) {
624 if ((p->r & VT_VALMASK) == r ||
625 (p->r2 & VT_VALMASK) == r)
626 goto notfound;
628 return r;
630 notfound: ;
633 /* no register left : free the first one on the stack (VERY
634 IMPORTANT to start from the bottom to ensure that we don't
635 spill registers used in gen_opi()) */
636 for(p=vstack;p<=vtop;p++) {
637 /* look at second register (if long long) */
638 r = p->r2 & VT_VALMASK;
639 if (r < VT_CONST && (reg_classes[r] & rc))
640 goto save_found;
641 r = p->r & VT_VALMASK;
642 if (r < VT_CONST && (reg_classes[r] & rc)) {
643 save_found:
644 save_reg(r);
645 return r;
648 /* Should never comes here */
649 return -1;
652 /* save registers up to (vtop - n) stack entry */
653 ST_FUNC void save_regs(int n)
655 int r;
656 SValue *p, *p1;
657 p1 = vtop - n;
658 for(p = vstack;p <= p1; p++) {
659 r = p->r & VT_VALMASK;
660 if (r < VT_CONST) {
661 save_reg(r);
666 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
667 if needed */
668 static void move_reg(int r, int s, int t)
670 SValue sv;
672 if (r != s) {
673 save_reg(r);
674 sv.type.t = t;
675 sv.type.ref = NULL;
676 sv.r = s;
677 sv.c.ul = 0;
678 load(r, &sv);
682 /* get address of vtop (vtop MUST BE an lvalue) */
683 ST_FUNC void gaddrof(void)
685 if (vtop->r & VT_REF && !nocode_wanted)
686 gv(RC_INT);
687 vtop->r &= ~VT_LVAL;
688 /* tricky: if saved lvalue, then we can go back to lvalue */
689 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
690 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
695 #ifdef CONFIG_TCC_BCHECK
696 /* generate lvalue bound code */
697 static void gbound(void)
699 int lval_type;
700 CType type1;
702 vtop->r &= ~VT_MUSTBOUND;
703 /* if lvalue, then use checking code before dereferencing */
704 if (vtop->r & VT_LVAL) {
705 /* if not VT_BOUNDED value, then make one */
706 if (!(vtop->r & VT_BOUNDED)) {
707 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
708 /* must save type because we must set it to int to get pointer */
709 type1 = vtop->type;
710 vtop->type.t = VT_PTR;
711 gaddrof();
712 vpushi(0);
713 gen_bounded_ptr_add();
714 vtop->r |= lval_type;
715 vtop->type = type1;
717 /* then check for dereferencing */
718 gen_bounded_ptr_deref();
721 #endif
723 /* store vtop a register belonging to class 'rc'. lvalues are
724 converted to values. Cannot be used if cannot be converted to
725 register value (such as structures). */
726 ST_FUNC int gv(int rc)
728 int r, bit_pos, bit_size, size, align, i;
729 int rc2;
731 /* NOTE: get_reg can modify vstack[] */
732 if (vtop->type.t & VT_BITFIELD) {
733 CType type;
734 int bits = 32;
735 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
736 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
737 /* remove bit field info to avoid loops */
738 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
739 /* cast to int to propagate signedness in following ops */
740 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
741 type.t = VT_LLONG;
742 bits = 64;
743 } else
744 type.t = VT_INT;
745 if((vtop->type.t & VT_UNSIGNED) ||
746 (vtop->type.t & VT_BTYPE) == VT_BOOL)
747 type.t |= VT_UNSIGNED;
748 gen_cast(&type);
749 /* generate shifts */
750 vpushi(bits - (bit_pos + bit_size));
751 gen_op(TOK_SHL);
752 vpushi(bits - bit_size);
753 /* NOTE: transformed to SHR if unsigned */
754 gen_op(TOK_SAR);
755 r = gv(rc);
756 } else {
757 if (is_float(vtop->type.t) &&
758 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
759 Sym *sym;
760 int *ptr;
761 unsigned long offset;
762 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
763 CValue check;
764 #endif
766 /* XXX: unify with initializers handling ? */
767 /* CPUs usually cannot use float constants, so we store them
768 generically in data segment */
769 size = type_size(&vtop->type, &align);
770 offset = (data_section->data_offset + align - 1) & -align;
771 data_section->data_offset = offset;
772 /* XXX: not portable yet */
773 #if defined(__i386__) || defined(__x86_64__)
774 /* Zero pad x87 tenbyte long doubles */
775 if (size == LDOUBLE_SIZE) {
776 vtop->c.tab[2] &= 0xffff;
777 #if LDOUBLE_SIZE == 16
778 vtop->c.tab[3] = 0;
779 #endif
781 #endif
782 ptr = section_ptr_add(data_section, size);
783 size = size >> 2;
784 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
785 check.d = 1;
786 if(check.tab[0])
787 for(i=0;i<size;i++)
788 ptr[i] = vtop->c.tab[size-1-i];
789 else
790 #endif
791 for(i=0;i<size;i++)
792 ptr[i] = vtop->c.tab[i];
793 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
794 vtop->r |= VT_LVAL | VT_SYM;
795 vtop->sym = sym;
796 vtop->c.ptr_offset = 0;
798 #ifdef CONFIG_TCC_BCHECK
799 if (vtop->r & VT_MUSTBOUND)
800 gbound();
801 #endif
803 r = vtop->r & VT_VALMASK;
804 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
805 #ifndef TCC_TARGET_ARM64
806 if (rc == RC_IRET)
807 rc2 = RC_LRET;
808 #ifdef TCC_TARGET_X86_64
809 else if (rc == RC_FRET)
810 rc2 = RC_QRET;
811 #endif
812 #endif
814 /* need to reload if:
815 - constant
816 - lvalue (need to dereference pointer)
817 - already a register, but not in the right class */
818 if (r >= VT_CONST
819 || (vtop->r & VT_LVAL)
820 || !(reg_classes[r] & rc)
821 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
822 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
823 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
824 #else
825 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
826 #endif
829 r = get_reg(rc);
830 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
831 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
832 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
833 #else
834 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
835 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
836 unsigned long long ll;
837 #endif
838 int r2, original_type;
839 original_type = vtop->type.t;
840 /* two register type load : expand to two words
841 temporarily */
842 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
843 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
844 /* load constant */
845 ll = vtop->c.ull;
846 vtop->c.ui = ll; /* first word */
847 load(r, vtop);
848 vtop->r = r; /* save register value */
849 vpushi(ll >> 32); /* second word */
850 } else
851 #endif
852 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
853 (vtop->r & VT_LVAL)) {
854 /* We do not want to modifier the long long
855 pointer here, so the safest (and less
856 efficient) is to save all the other registers
857 in the stack. XXX: totally inefficient. */
858 save_regs(1);
859 /* load from memory */
860 vtop->type.t = load_type;
861 load(r, vtop);
862 vdup();
863 vtop[-1].r = r; /* save register value */
864 /* increment pointer to get second word */
865 vtop->type.t = addr_type;
866 gaddrof();
867 vpushi(load_size);
868 gen_op('+');
869 vtop->r |= VT_LVAL;
870 vtop->type.t = load_type;
871 } else {
872 /* move registers */
873 load(r, vtop);
874 vdup();
875 vtop[-1].r = r; /* save register value */
876 vtop->r = vtop[-1].r2;
878 /* Allocate second register. Here we rely on the fact that
879 get_reg() tries first to free r2 of an SValue. */
880 r2 = get_reg(rc2);
881 load(r2, vtop);
882 vpop();
883 /* write second register */
884 vtop->r2 = r2;
885 vtop->type.t = original_type;
886 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
887 int t1, t;
888 /* lvalue of scalar type : need to use lvalue type
889 because of possible cast */
890 t = vtop->type.t;
891 t1 = t;
892 /* compute memory access type */
893 if (vtop->r & VT_REF)
894 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
895 t = VT_PTR;
896 #else
897 t = VT_INT;
898 #endif
899 else if (vtop->r & VT_LVAL_BYTE)
900 t = VT_BYTE;
901 else if (vtop->r & VT_LVAL_SHORT)
902 t = VT_SHORT;
903 if (vtop->r & VT_LVAL_UNSIGNED)
904 t |= VT_UNSIGNED;
905 vtop->type.t = t;
906 load(r, vtop);
907 /* restore wanted type */
908 vtop->type.t = t1;
909 } else {
910 /* one register type load */
911 load(r, vtop);
914 vtop->r = r;
915 #ifdef TCC_TARGET_C67
916 /* uses register pairs for doubles */
917 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
918 vtop->r2 = r+1;
919 #endif
921 return r;
924 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
925 ST_FUNC void gv2(int rc1, int rc2)
927 int v;
929 /* generate more generic register first. But VT_JMP or VT_CMP
930 values must be generated first in all cases to avoid possible
931 reload errors */
932 v = vtop[0].r & VT_VALMASK;
933 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
934 vswap();
935 gv(rc1);
936 vswap();
937 gv(rc2);
938 /* test if reload is needed for first register */
939 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
940 vswap();
941 gv(rc1);
942 vswap();
944 } else {
945 gv(rc2);
946 vswap();
947 gv(rc1);
948 vswap();
949 /* test if reload is needed for first register */
950 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
951 gv(rc2);
956 #ifndef TCC_TARGET_ARM64
957 /* wrapper around RC_FRET to return a register by type */
958 static int rc_fret(int t)
960 #ifdef TCC_TARGET_X86_64
961 if (t == VT_LDOUBLE) {
962 return RC_ST0;
964 #endif
965 return RC_FRET;
967 #endif
969 /* wrapper around REG_FRET to return a register by type */
970 static int reg_fret(int t)
972 #ifdef TCC_TARGET_X86_64
973 if (t == VT_LDOUBLE) {
974 return TREG_ST0;
976 #endif
977 return REG_FRET;
980 /* expand long long on stack in two int registers */
981 static void lexpand(void)
983 int u;
985 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
986 gv(RC_INT);
987 vdup();
988 vtop[0].r = vtop[-1].r2;
989 vtop[0].r2 = VT_CONST;
990 vtop[-1].r2 = VT_CONST;
991 vtop[0].type.t = VT_INT | u;
992 vtop[-1].type.t = VT_INT | u;
995 #ifdef TCC_TARGET_ARM
996 /* expand long long on stack */
997 ST_FUNC void lexpand_nr(void)
999 int u,v;
1001 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1002 vdup();
1003 vtop->r2 = VT_CONST;
1004 vtop->type.t = VT_INT | u;
1005 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1006 if (v == VT_CONST) {
1007 vtop[-1].c.ui = vtop->c.ull;
1008 vtop->c.ui = vtop->c.ull >> 32;
1009 vtop->r = VT_CONST;
1010 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1011 vtop->c.ui += 4;
1012 vtop->r = vtop[-1].r;
1013 } else if (v > VT_CONST) {
1014 vtop--;
1015 lexpand();
1016 } else
1017 vtop->r = vtop[-1].r2;
1018 vtop[-1].r2 = VT_CONST;
1019 vtop[-1].type.t = VT_INT | u;
1021 #endif
1023 /* build a long long from two ints */
1024 static void lbuild(int t)
1026 gv2(RC_INT, RC_INT);
1027 vtop[-1].r2 = vtop[0].r;
1028 vtop[-1].type.t = t;
1029 vpop();
1032 /* rotate n first stack elements to the bottom
1033 I1 ... In -> I2 ... In I1 [top is right]
1035 ST_FUNC void vrotb(int n)
1037 int i;
1038 SValue tmp;
1040 tmp = vtop[-n + 1];
1041 for(i=-n+1;i!=0;i++)
1042 vtop[i] = vtop[i+1];
1043 vtop[0] = tmp;
1046 /* rotate the n elements before entry e towards the top
1047 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1049 ST_FUNC void vrote(SValue *e, int n)
1051 int i;
1052 SValue tmp;
1054 tmp = *e;
1055 for(i = 0;i < n - 1; i++)
1056 e[-i] = e[-i - 1];
1057 e[-n + 1] = tmp;
1060 /* rotate n first stack elements to the top
1061 I1 ... In -> In I1 ... I(n-1) [top is right]
1063 ST_FUNC void vrott(int n)
1065 vrote(vtop, n);
1068 /* pop stack value */
1069 ST_FUNC void vpop(void)
1071 int v;
1072 v = vtop->r & VT_VALMASK;
1073 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1074 /* for x86, we need to pop the FP stack */
1075 if (v == TREG_ST0 && !nocode_wanted) {
1076 o(0xd8dd); /* fstp %st(0) */
1077 } else
1078 #endif
1079 if (v == VT_JMP || v == VT_JMPI) {
1080 /* need to put correct jump if && or || without test */
1081 gsym(vtop->c.ul);
1083 vtop--;
1086 /* convert stack entry to register and duplicate its value in another
1087 register */
1088 static void gv_dup(void)
1090 int rc, t, r, r1;
1091 SValue sv;
1093 t = vtop->type.t;
1094 if ((t & VT_BTYPE) == VT_LLONG) {
1095 lexpand();
1096 gv_dup();
1097 vswap();
1098 vrotb(3);
1099 gv_dup();
1100 vrotb(4);
1101 /* stack: H L L1 H1 */
1102 lbuild(t);
1103 vrotb(3);
1104 vrotb(3);
1105 vswap();
1106 lbuild(t);
1107 vswap();
1108 } else {
1109 /* duplicate value */
1110 rc = RC_INT;
1111 sv.type.t = VT_INT;
1112 if (is_float(t)) {
1113 rc = RC_FLOAT;
1114 #ifdef TCC_TARGET_X86_64
1115 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1116 rc = RC_ST0;
1118 #endif
1119 sv.type.t = t;
1121 r = gv(rc);
1122 r1 = get_reg(rc);
1123 sv.r = r;
1124 sv.c.ul = 0;
1125 load(r1, &sv); /* move r to r1 */
1126 vdup();
1127 /* duplicates value */
1128 if (r != r1)
1129 vtop->r = r1;
1133 /* Generate value test
1135 * Generate a test for any value (jump, comparison and integers) */
1136 ST_FUNC int gvtst(int inv, int t)
1138 int v = vtop->r & VT_VALMASK;
1139 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1140 vpushi(0);
1141 gen_op(TOK_NE);
1143 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1144 /* constant jmp optimization */
1145 if ((vtop->c.i != 0) != inv)
1146 t = gjmp(t);
1147 vtop--;
1148 return t;
1150 return gtst(inv, t);
1153 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1154 /* generate CPU independent (unsigned) long long operations */
1155 static void gen_opl(int op)
1157 int t, a, b, op1, c, i;
1158 int func;
1159 unsigned short reg_iret = REG_IRET;
1160 unsigned short reg_lret = REG_LRET;
1161 SValue tmp;
1163 switch(op) {
1164 case '/':
1165 case TOK_PDIV:
1166 func = TOK___divdi3;
1167 goto gen_func;
1168 case TOK_UDIV:
1169 func = TOK___udivdi3;
1170 goto gen_func;
1171 case '%':
1172 func = TOK___moddi3;
1173 goto gen_mod_func;
1174 case TOK_UMOD:
1175 func = TOK___umoddi3;
1176 gen_mod_func:
1177 #ifdef TCC_ARM_EABI
1178 reg_iret = TREG_R2;
1179 reg_lret = TREG_R3;
1180 #endif
1181 gen_func:
1182 /* call generic long long function */
1183 vpush_global_sym(&func_old_type, func);
1184 vrott(3);
1185 gfunc_call(2);
1186 vpushi(0);
1187 vtop->r = reg_iret;
1188 vtop->r2 = reg_lret;
1189 break;
1190 case '^':
1191 case '&':
1192 case '|':
1193 case '*':
1194 case '+':
1195 case '-':
1196 t = vtop->type.t;
1197 vswap();
1198 lexpand();
1199 vrotb(3);
1200 lexpand();
1201 /* stack: L1 H1 L2 H2 */
1202 tmp = vtop[0];
1203 vtop[0] = vtop[-3];
1204 vtop[-3] = tmp;
1205 tmp = vtop[-2];
1206 vtop[-2] = vtop[-3];
1207 vtop[-3] = tmp;
1208 vswap();
1209 /* stack: H1 H2 L1 L2 */
1210 if (op == '*') {
1211 vpushv(vtop - 1);
1212 vpushv(vtop - 1);
1213 gen_op(TOK_UMULL);
1214 lexpand();
1215 /* stack: H1 H2 L1 L2 ML MH */
1216 for(i=0;i<4;i++)
1217 vrotb(6);
1218 /* stack: ML MH H1 H2 L1 L2 */
1219 tmp = vtop[0];
1220 vtop[0] = vtop[-2];
1221 vtop[-2] = tmp;
1222 /* stack: ML MH H1 L2 H2 L1 */
1223 gen_op('*');
1224 vrotb(3);
1225 vrotb(3);
1226 gen_op('*');
1227 /* stack: ML MH M1 M2 */
1228 gen_op('+');
1229 gen_op('+');
1230 } else if (op == '+' || op == '-') {
1231 /* XXX: add non carry method too (for MIPS or alpha) */
1232 if (op == '+')
1233 op1 = TOK_ADDC1;
1234 else
1235 op1 = TOK_SUBC1;
1236 gen_op(op1);
1237 /* stack: H1 H2 (L1 op L2) */
1238 vrotb(3);
1239 vrotb(3);
1240 gen_op(op1 + 1); /* TOK_xxxC2 */
1241 } else {
1242 gen_op(op);
1243 /* stack: H1 H2 (L1 op L2) */
1244 vrotb(3);
1245 vrotb(3);
1246 /* stack: (L1 op L2) H1 H2 */
1247 gen_op(op);
1248 /* stack: (L1 op L2) (H1 op H2) */
1250 /* stack: L H */
1251 lbuild(t);
1252 break;
1253 case TOK_SAR:
1254 case TOK_SHR:
1255 case TOK_SHL:
1256 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1257 t = vtop[-1].type.t;
1258 vswap();
1259 lexpand();
1260 vrotb(3);
1261 /* stack: L H shift */
1262 c = (int)vtop->c.i;
1263 /* constant: simpler */
1264 /* NOTE: all comments are for SHL. the other cases are
1265 done by swaping words */
1266 vpop();
1267 if (op != TOK_SHL)
1268 vswap();
1269 if (c >= 32) {
1270 /* stack: L H */
1271 vpop();
1272 if (c > 32) {
1273 vpushi(c - 32);
1274 gen_op(op);
1276 if (op != TOK_SAR) {
1277 vpushi(0);
1278 } else {
1279 gv_dup();
1280 vpushi(31);
1281 gen_op(TOK_SAR);
1283 vswap();
1284 } else {
1285 vswap();
1286 gv_dup();
1287 /* stack: H L L */
1288 vpushi(c);
1289 gen_op(op);
1290 vswap();
1291 vpushi(32 - c);
1292 if (op == TOK_SHL)
1293 gen_op(TOK_SHR);
1294 else
1295 gen_op(TOK_SHL);
1296 vrotb(3);
1297 /* stack: L L H */
1298 vpushi(c);
1299 if (op == TOK_SHL)
1300 gen_op(TOK_SHL);
1301 else
1302 gen_op(TOK_SHR);
1303 gen_op('|');
1305 if (op != TOK_SHL)
1306 vswap();
1307 lbuild(t);
1308 } else {
1309 /* XXX: should provide a faster fallback on x86 ? */
1310 switch(op) {
1311 case TOK_SAR:
1312 func = TOK___ashrdi3;
1313 goto gen_func;
1314 case TOK_SHR:
1315 func = TOK___lshrdi3;
1316 goto gen_func;
1317 case TOK_SHL:
1318 func = TOK___ashldi3;
1319 goto gen_func;
1322 break;
1323 default:
1324 /* compare operations */
1325 t = vtop->type.t;
1326 vswap();
1327 lexpand();
1328 vrotb(3);
1329 lexpand();
1330 /* stack: L1 H1 L2 H2 */
1331 tmp = vtop[-1];
1332 vtop[-1] = vtop[-2];
1333 vtop[-2] = tmp;
1334 /* stack: L1 L2 H1 H2 */
1335 /* compare high */
1336 op1 = op;
1337 /* when values are equal, we need to compare low words. since
1338 the jump is inverted, we invert the test too. */
1339 if (op1 == TOK_LT)
1340 op1 = TOK_LE;
1341 else if (op1 == TOK_GT)
1342 op1 = TOK_GE;
1343 else if (op1 == TOK_ULT)
1344 op1 = TOK_ULE;
1345 else if (op1 == TOK_UGT)
1346 op1 = TOK_UGE;
1347 a = 0;
1348 b = 0;
1349 gen_op(op1);
1350 if (op1 != TOK_NE) {
1351 a = gvtst(1, 0);
1353 if (op != TOK_EQ) {
1354 /* generate non equal test */
1355 /* XXX: NOT PORTABLE yet */
1356 if (a == 0) {
1357 b = gvtst(0, 0);
1358 } else {
1359 #if defined(TCC_TARGET_I386)
1360 b = psym(0x850f, 0);
1361 #elif defined(TCC_TARGET_ARM)
1362 b = ind;
1363 o(0x1A000000 | encbranch(ind, 0, 1));
1364 #elif defined(TCC_TARGET_C67) || defined(TCC_TARGET_ARM64)
1365 tcc_error("not implemented");
1366 #else
1367 #error not supported
1368 #endif
1371 /* compare low. Always unsigned */
1372 op1 = op;
1373 if (op1 == TOK_LT)
1374 op1 = TOK_ULT;
1375 else if (op1 == TOK_LE)
1376 op1 = TOK_ULE;
1377 else if (op1 == TOK_GT)
1378 op1 = TOK_UGT;
1379 else if (op1 == TOK_GE)
1380 op1 = TOK_UGE;
1381 gen_op(op1);
1382 a = gvtst(1, a);
1383 gsym(b);
1384 vseti(VT_JMPI, a);
1385 break;
1388 #endif
1390 /* handle integer constant optimizations and various machine
1391 independent opt */
1392 static void gen_opic(int op)
1394 int c1, c2, t1, t2, n;
1395 SValue *v1, *v2;
1396 long long l1, l2;
1397 typedef unsigned long long U;
1399 v1 = vtop - 1;
1400 v2 = vtop;
1401 t1 = v1->type.t & VT_BTYPE;
1402 t2 = v2->type.t & VT_BTYPE;
1404 if (t1 == VT_LLONG)
1405 l1 = v1->c.ll;
1406 else if (v1->type.t & VT_UNSIGNED)
1407 l1 = v1->c.ui;
1408 else
1409 l1 = v1->c.i;
1411 if (t2 == VT_LLONG)
1412 l2 = v2->c.ll;
1413 else if (v2->type.t & VT_UNSIGNED)
1414 l2 = v2->c.ui;
1415 else
1416 l2 = v2->c.i;
1418 /* currently, we cannot do computations with forward symbols */
1419 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1420 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1421 if (c1 && c2) {
1422 switch(op) {
1423 case '+': l1 += l2; break;
1424 case '-': l1 -= l2; break;
1425 case '&': l1 &= l2; break;
1426 case '^': l1 ^= l2; break;
1427 case '|': l1 |= l2; break;
1428 case '*': l1 *= l2; break;
1430 case TOK_PDIV:
1431 case '/':
1432 case '%':
1433 case TOK_UDIV:
1434 case TOK_UMOD:
1435 /* if division by zero, generate explicit division */
1436 if (l2 == 0) {
1437 if (const_wanted)
1438 tcc_error("division by zero in constant");
1439 goto general_case;
1441 switch(op) {
1442 default: l1 /= l2; break;
1443 case '%': l1 %= l2; break;
1444 case TOK_UDIV: l1 = (U)l1 / l2; break;
1445 case TOK_UMOD: l1 = (U)l1 % l2; break;
1447 break;
1448 case TOK_SHL: l1 <<= l2; break;
1449 case TOK_SHR: l1 = (U)l1 >> l2; break;
1450 case TOK_SAR: l1 >>= l2; break;
1451 /* tests */
1452 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1453 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1454 case TOK_EQ: l1 = l1 == l2; break;
1455 case TOK_NE: l1 = l1 != l2; break;
1456 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1457 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1458 case TOK_LT: l1 = l1 < l2; break;
1459 case TOK_GE: l1 = l1 >= l2; break;
1460 case TOK_LE: l1 = l1 <= l2; break;
1461 case TOK_GT: l1 = l1 > l2; break;
1462 /* logical */
1463 case TOK_LAND: l1 = l1 && l2; break;
1464 case TOK_LOR: l1 = l1 || l2; break;
1465 default:
1466 goto general_case;
1468 v1->c.ll = l1;
1469 vtop--;
1470 } else {
1471 /* if commutative ops, put c2 as constant */
1472 if (c1 && (op == '+' || op == '&' || op == '^' ||
1473 op == '|' || op == '*')) {
1474 vswap();
1475 c2 = c1; //c = c1, c1 = c2, c2 = c;
1476 l2 = l1; //l = l1, l1 = l2, l2 = l;
1478 if (!const_wanted &&
1479 c1 && ((l1 == 0 &&
1480 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
1481 (l1 == -1 && op == TOK_SAR))) {
1482 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
1483 vtop--;
1484 } else if (!const_wanted &&
1485 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
1486 (l2 == -1 && op == '|') ||
1487 (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
1488 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
1489 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
1490 if (l2 == 1)
1491 vtop->c.ll = 0;
1492 vswap();
1493 vtop--;
1494 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1495 op == TOK_PDIV) &&
1496 l2 == 1) ||
1497 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1498 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1499 l2 == 0) ||
1500 (op == '&' &&
1501 l2 == -1))) {
1502 /* filter out NOP operations like x*1, x-0, x&-1... */
1503 vtop--;
1504 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1505 /* try to use shifts instead of muls or divs */
1506 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1507 n = -1;
1508 while (l2) {
1509 l2 >>= 1;
1510 n++;
1512 vtop->c.ll = n;
1513 if (op == '*')
1514 op = TOK_SHL;
1515 else if (op == TOK_PDIV)
1516 op = TOK_SAR;
1517 else
1518 op = TOK_SHR;
1520 goto general_case;
1521 } else if (c2 && (op == '+' || op == '-') &&
1522 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1523 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1524 /* symbol + constant case */
1525 if (op == '-')
1526 l2 = -l2;
1527 vtop--;
1528 vtop->c.ll += l2;
1529 } else {
1530 general_case:
1531 if (!nocode_wanted) {
1532 /* call low level op generator */
1533 if (t1 == VT_LLONG || t2 == VT_LLONG ||
1534 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
1535 gen_opl(op);
1536 else
1537 gen_opi(op);
1538 } else {
1539 vtop--;
1545 /* generate a floating point operation with constant propagation */
1546 static void gen_opif(int op)
1548 int c1, c2;
1549 SValue *v1, *v2;
1550 long double f1, f2;
1552 v1 = vtop - 1;
1553 v2 = vtop;
1554 /* currently, we cannot do computations with forward symbols */
1555 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1556 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1557 if (c1 && c2) {
1558 if (v1->type.t == VT_FLOAT) {
1559 f1 = v1->c.f;
1560 f2 = v2->c.f;
1561 } else if (v1->type.t == VT_DOUBLE) {
1562 f1 = v1->c.d;
1563 f2 = v2->c.d;
1564 } else {
1565 f1 = v1->c.ld;
1566 f2 = v2->c.ld;
1569 /* NOTE: we only do constant propagation if finite number (not
1570 NaN or infinity) (ANSI spec) */
1571 if (!ieee_finite(f1) || !ieee_finite(f2))
1572 goto general_case;
1574 switch(op) {
1575 case '+': f1 += f2; break;
1576 case '-': f1 -= f2; break;
1577 case '*': f1 *= f2; break;
1578 case '/':
1579 if (f2 == 0.0) {
1580 if (const_wanted)
1581 tcc_error("division by zero in constant");
1582 goto general_case;
1584 f1 /= f2;
1585 break;
1586 /* XXX: also handles tests ? */
1587 default:
1588 goto general_case;
1590 /* XXX: overflow test ? */
1591 if (v1->type.t == VT_FLOAT) {
1592 v1->c.f = f1;
1593 } else if (v1->type.t == VT_DOUBLE) {
1594 v1->c.d = f1;
1595 } else {
1596 v1->c.ld = f1;
1598 vtop--;
1599 } else {
1600 general_case:
1601 if (!nocode_wanted) {
1602 gen_opf(op);
1603 } else {
1604 vtop--;
1609 static int pointed_size(CType *type)
1611 int align;
1612 return type_size(pointed_type(type), &align);
1615 static void vla_runtime_pointed_size(CType *type)
1617 int align;
1618 vla_runtime_type_size(pointed_type(type), &align);
1621 static inline int is_null_pointer(SValue *p)
1623 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1624 return 0;
1625 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1626 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1627 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0);
1630 static inline int is_integer_btype(int bt)
1632 return (bt == VT_BYTE || bt == VT_SHORT ||
1633 bt == VT_INT || bt == VT_LLONG);
1636 /* check types for comparison or subtraction of pointers */
1637 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1639 CType *type1, *type2, tmp_type1, tmp_type2;
1640 int bt1, bt2;
1642 /* null pointers are accepted for all comparisons as gcc */
1643 if (is_null_pointer(p1) || is_null_pointer(p2))
1644 return;
1645 type1 = &p1->type;
1646 type2 = &p2->type;
1647 bt1 = type1->t & VT_BTYPE;
1648 bt2 = type2->t & VT_BTYPE;
1649 /* accept comparison between pointer and integer with a warning */
1650 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1651 if (op != TOK_LOR && op != TOK_LAND )
1652 tcc_warning("comparison between pointer and integer");
1653 return;
1656 /* both must be pointers or implicit function pointers */
1657 if (bt1 == VT_PTR) {
1658 type1 = pointed_type(type1);
1659 } else if (bt1 != VT_FUNC)
1660 goto invalid_operands;
1662 if (bt2 == VT_PTR) {
1663 type2 = pointed_type(type2);
1664 } else if (bt2 != VT_FUNC) {
1665 invalid_operands:
1666 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1668 if ((type1->t & VT_BTYPE) == VT_VOID ||
1669 (type2->t & VT_BTYPE) == VT_VOID)
1670 return;
1671 tmp_type1 = *type1;
1672 tmp_type2 = *type2;
1673 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1674 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1675 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1676 /* gcc-like error if '-' is used */
1677 if (op == '-')
1678 goto invalid_operands;
1679 else
1680 tcc_warning("comparison of distinct pointer types lacks a cast");
1684 /* generic gen_op: handles types problems */
1685 ST_FUNC void gen_op(int op)
1687 int u, t1, t2, bt1, bt2, t;
1688 CType type1;
1690 t1 = vtop[-1].type.t;
1691 t2 = vtop[0].type.t;
1692 bt1 = t1 & VT_BTYPE;
1693 bt2 = t2 & VT_BTYPE;
1695 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1696 /* at least one operand is a pointer */
1697 /* relationnal op: must be both pointers */
1698 if (op >= TOK_ULT && op <= TOK_LOR) {
1699 check_comparison_pointer_types(vtop - 1, vtop, op);
1700 /* pointers are handled are unsigned */
1701 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1702 t = VT_LLONG | VT_UNSIGNED;
1703 #else
1704 t = VT_INT | VT_UNSIGNED;
1705 #endif
1706 goto std_op;
1708 /* if both pointers, then it must be the '-' op */
1709 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1710 if (op != '-')
1711 tcc_error("cannot use pointers here");
1712 check_comparison_pointer_types(vtop - 1, vtop, op);
1713 /* XXX: check that types are compatible */
1714 if (vtop[-1].type.t & VT_VLA) {
1715 vla_runtime_pointed_size(&vtop[-1].type);
1716 } else {
1717 vpushi(pointed_size(&vtop[-1].type));
1719 vrott(3);
1720 gen_opic(op);
1721 /* set to integer type */
1722 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1723 vtop->type.t = VT_LLONG;
1724 #else
1725 vtop->type.t = VT_INT;
1726 #endif
1727 vswap();
1728 gen_op(TOK_PDIV);
1729 } else {
1730 /* exactly one pointer : must be '+' or '-'. */
1731 if (op != '-' && op != '+')
1732 tcc_error("cannot use pointers here");
1733 /* Put pointer as first operand */
1734 if (bt2 == VT_PTR) {
1735 vswap();
1736 swap(&t1, &t2);
1738 type1 = vtop[-1].type;
1739 type1.t &= ~VT_ARRAY;
1740 if (vtop[-1].type.t & VT_VLA)
1741 vla_runtime_pointed_size(&vtop[-1].type);
1742 else {
1743 u = pointed_size(&vtop[-1].type);
1744 if (u < 0)
1745 tcc_error("unknown array element size");
1746 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1747 vpushll(u);
1748 #else
1749 /* XXX: cast to int ? (long long case) */
1750 vpushi(u);
1751 #endif
1753 gen_op('*');
1754 #if 0
1755 /* #ifdef CONFIG_TCC_BCHECK
1756 The main reason to removing this code:
1757 #include <stdio.h>
1758 int main ()
1760 int v[10];
1761 int i = 10;
1762 int j = 9;
1763 fprintf(stderr, "v+i-j = %p\n", v+i-j);
1764 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
1766 When this code is on. then the output looks like
1767 v+i-j = 0xfffffffe
1768 v+(i-j) = 0xbff84000
1770 /* if evaluating constant expression, no code should be
1771 generated, so no bound check */
1772 if (tcc_state->do_bounds_check && !const_wanted) {
1773 /* if bounded pointers, we generate a special code to
1774 test bounds */
1775 if (op == '-') {
1776 vpushi(0);
1777 vswap();
1778 gen_op('-');
1780 gen_bounded_ptr_add();
1781 } else
1782 #endif
1784 gen_opic(op);
1786 /* put again type if gen_opic() swaped operands */
1787 vtop->type = type1;
1789 } else if (is_float(bt1) || is_float(bt2)) {
1790 /* compute bigger type and do implicit casts */
1791 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1792 t = VT_LDOUBLE;
1793 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1794 t = VT_DOUBLE;
1795 } else {
1796 t = VT_FLOAT;
1798 /* floats can only be used for a few operations */
1799 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1800 (op < TOK_ULT || op > TOK_GT))
1801 tcc_error("invalid operands for binary operation");
1802 goto std_op;
1803 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1804 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1805 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1806 t |= VT_UNSIGNED;
1807 goto std_op;
1808 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1809 /* cast to biggest op */
1810 t = VT_LLONG;
1811 /* convert to unsigned if it does not fit in a long long */
1812 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1813 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1814 t |= VT_UNSIGNED;
1815 goto std_op;
1816 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1817 tcc_error("comparison of struct");
1818 } else {
1819 /* integer operations */
1820 t = VT_INT;
1821 /* convert to unsigned if it does not fit in an integer */
1822 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1823 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1824 t |= VT_UNSIGNED;
1825 std_op:
1826 /* XXX: currently, some unsigned operations are explicit, so
1827 we modify them here */
1828 if (t & VT_UNSIGNED) {
1829 if (op == TOK_SAR)
1830 op = TOK_SHR;
1831 else if (op == '/')
1832 op = TOK_UDIV;
1833 else if (op == '%')
1834 op = TOK_UMOD;
1835 else if (op == TOK_LT)
1836 op = TOK_ULT;
1837 else if (op == TOK_GT)
1838 op = TOK_UGT;
1839 else if (op == TOK_LE)
1840 op = TOK_ULE;
1841 else if (op == TOK_GE)
1842 op = TOK_UGE;
1844 vswap();
1845 type1.t = t;
1846 gen_cast(&type1);
1847 vswap();
1848 /* special case for shifts and long long: we keep the shift as
1849 an integer */
1850 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1851 type1.t = VT_INT;
1852 gen_cast(&type1);
1853 if (is_float(t))
1854 gen_opif(op);
1855 else
1856 gen_opic(op);
1857 if (op >= TOK_ULT && op <= TOK_GT) {
1858 /* relationnal op: the result is an int */
1859 vtop->type.t = VT_INT;
1860 } else {
1861 vtop->type.t = t;
1864 // Make sure that we have converted to an rvalue:
1865 if (vtop->r & VT_LVAL && !nocode_wanted)
1866 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
1869 #ifndef TCC_TARGET_ARM
1870 /* generic itof for unsigned long long case */
1871 static void gen_cvt_itof1(int t)
1873 #ifdef TCC_TARGET_ARM64
1874 gen_cvt_itof(t);
1875 #else
1876 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1877 (VT_LLONG | VT_UNSIGNED)) {
1879 if (t == VT_FLOAT)
1880 vpush_global_sym(&func_old_type, TOK___floatundisf);
1881 #if LDOUBLE_SIZE != 8
1882 else if (t == VT_LDOUBLE)
1883 vpush_global_sym(&func_old_type, TOK___floatundixf);
1884 #endif
1885 else
1886 vpush_global_sym(&func_old_type, TOK___floatundidf);
1887 vrott(2);
1888 gfunc_call(1);
1889 vpushi(0);
1890 vtop->r = reg_fret(t);
1891 } else {
1892 gen_cvt_itof(t);
1894 #endif
1896 #endif
1898 /* generic ftoi for unsigned long long case */
1899 static void gen_cvt_ftoi1(int t)
1901 #ifdef TCC_TARGET_ARM64
1902 gen_cvt_ftoi(t);
1903 #else
1904 int st;
1906 if (t == (VT_LLONG | VT_UNSIGNED)) {
1907 /* not handled natively */
1908 st = vtop->type.t & VT_BTYPE;
1909 if (st == VT_FLOAT)
1910 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1911 #if LDOUBLE_SIZE != 8
1912 else if (st == VT_LDOUBLE)
1913 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1914 #endif
1915 else
1916 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1917 vrott(2);
1918 gfunc_call(1);
1919 vpushi(0);
1920 vtop->r = REG_IRET;
1921 vtop->r2 = REG_LRET;
1922 } else {
1923 gen_cvt_ftoi(t);
1925 #endif
1928 /* force char or short cast */
1929 static void force_charshort_cast(int t)
1931 int bits, dbt;
1932 dbt = t & VT_BTYPE;
1933 /* XXX: add optimization if lvalue : just change type and offset */
1934 if (dbt == VT_BYTE)
1935 bits = 8;
1936 else
1937 bits = 16;
1938 if (t & VT_UNSIGNED) {
1939 vpushi((1 << bits) - 1);
1940 gen_op('&');
1941 } else {
1942 bits = 32 - bits;
1943 vpushi(bits);
1944 gen_op(TOK_SHL);
1945 /* result must be signed or the SAR is converted to an SHL
1946 This was not the case when "t" was a signed short
1947 and the last value on the stack was an unsigned int */
1948 vtop->type.t &= ~VT_UNSIGNED;
1949 vpushi(bits);
1950 gen_op(TOK_SAR);
1954 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1955 static void gen_cast(CType *type)
1957 int sbt, dbt, sf, df, c, p;
1959 /* special delayed cast for char/short */
1960 /* XXX: in some cases (multiple cascaded casts), it may still
1961 be incorrect */
1962 if (vtop->r & VT_MUSTCAST) {
1963 vtop->r &= ~VT_MUSTCAST;
1964 force_charshort_cast(vtop->type.t);
1967 /* bitfields first get cast to ints */
1968 if (vtop->type.t & VT_BITFIELD && !nocode_wanted) {
1969 gv(RC_INT);
1972 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1973 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1975 if (sbt != dbt) {
1976 sf = is_float(sbt);
1977 df = is_float(dbt);
1978 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1979 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1980 if (c) {
1981 /* constant case: we can do it now */
1982 /* XXX: in ISOC, cannot do it if error in convert */
1983 if (sbt == VT_FLOAT)
1984 vtop->c.ld = vtop->c.f;
1985 else if (sbt == VT_DOUBLE)
1986 vtop->c.ld = vtop->c.d;
1988 if (df) {
1989 if ((sbt & VT_BTYPE) == VT_LLONG) {
1990 if (sbt & VT_UNSIGNED)
1991 vtop->c.ld = vtop->c.ull;
1992 else
1993 vtop->c.ld = vtop->c.ll;
1994 } else if(!sf) {
1995 if (sbt & VT_UNSIGNED)
1996 vtop->c.ld = vtop->c.ui;
1997 else
1998 vtop->c.ld = vtop->c.i;
2001 if (dbt == VT_FLOAT)
2002 vtop->c.f = (float)vtop->c.ld;
2003 else if (dbt == VT_DOUBLE)
2004 vtop->c.d = (double)vtop->c.ld;
2005 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
2006 vtop->c.ull = (unsigned long long)vtop->c.ld;
2007 } else if (sf && dbt == VT_BOOL) {
2008 vtop->c.i = (vtop->c.ld != 0);
2009 } else {
2010 if(sf)
2011 vtop->c.ll = (long long)vtop->c.ld;
2012 else if (sbt == (VT_LLONG|VT_UNSIGNED))
2013 vtop->c.ll = vtop->c.ull;
2014 else if (sbt & VT_UNSIGNED)
2015 vtop->c.ll = vtop->c.ui;
2016 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2017 else if (sbt == VT_PTR)
2019 #endif
2020 else if (sbt != VT_LLONG)
2021 vtop->c.ll = vtop->c.i;
2023 if (dbt == (VT_LLONG|VT_UNSIGNED))
2024 vtop->c.ull = vtop->c.ll;
2025 else if (dbt == VT_BOOL)
2026 vtop->c.i = (vtop->c.ll != 0);
2027 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2028 else if (dbt == VT_PTR)
2030 #endif
2031 else if (dbt != VT_LLONG) {
2032 int s = 0;
2033 if ((dbt & VT_BTYPE) == VT_BYTE)
2034 s = 24;
2035 else if ((dbt & VT_BTYPE) == VT_SHORT)
2036 s = 16;
2037 if(dbt & VT_UNSIGNED)
2038 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
2039 else
2040 vtop->c.i = ((int)vtop->c.ll << s) >> s;
2043 } else if (p && dbt == VT_BOOL) {
2044 vtop->r = VT_CONST;
2045 vtop->c.i = 1;
2046 } else if (!nocode_wanted) {
2047 /* non constant case: generate code */
2048 if (sf && df) {
2049 /* convert from fp to fp */
2050 gen_cvt_ftof(dbt);
2051 } else if (df) {
2052 /* convert int to fp */
2053 gen_cvt_itof1(dbt);
2054 } else if (sf) {
2055 /* convert fp to int */
2056 if (dbt == VT_BOOL) {
2057 vpushi(0);
2058 gen_op(TOK_NE);
2059 } else {
2060 /* we handle char/short/etc... with generic code */
2061 if (dbt != (VT_INT | VT_UNSIGNED) &&
2062 dbt != (VT_LLONG | VT_UNSIGNED) &&
2063 dbt != VT_LLONG)
2064 dbt = VT_INT;
2065 gen_cvt_ftoi1(dbt);
2066 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2067 /* additional cast for char/short... */
2068 vtop->type.t = dbt;
2069 gen_cast(type);
2072 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
2073 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2074 if ((sbt & VT_BTYPE) != VT_LLONG && !nocode_wanted) {
2075 /* scalar to long long */
2076 /* machine independent conversion */
2077 gv(RC_INT);
2078 /* generate high word */
2079 if (sbt == (VT_INT | VT_UNSIGNED)) {
2080 vpushi(0);
2081 gv(RC_INT);
2082 } else {
2083 if (sbt == VT_PTR) {
2084 /* cast from pointer to int before we apply
2085 shift operation, which pointers don't support*/
2086 gen_cast(&int_type);
2088 gv_dup();
2089 vpushi(31);
2090 gen_op(TOK_SAR);
2092 /* patch second register */
2093 vtop[-1].r2 = vtop->r;
2094 vpop();
2096 #else
2097 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2098 (dbt & VT_BTYPE) == VT_PTR ||
2099 (dbt & VT_BTYPE) == VT_FUNC) {
2100 if ((sbt & VT_BTYPE) != VT_LLONG &&
2101 (sbt & VT_BTYPE) != VT_PTR &&
2102 (sbt & VT_BTYPE) != VT_FUNC && !nocode_wanted) {
2103 /* need to convert from 32bit to 64bit */
2104 gv(RC_INT);
2105 if (sbt != (VT_INT | VT_UNSIGNED)) {
2106 #if defined(TCC_TARGET_ARM64)
2107 gen_cvt_sxtw();
2108 #elif defined(TCC_TARGET_X86_64)
2109 int r = gv(RC_INT);
2110 /* x86_64 specific: movslq */
2111 o(0x6348);
2112 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2113 #else
2114 #error
2115 #endif
2118 #endif
2119 } else if (dbt == VT_BOOL) {
2120 /* scalar to bool */
2121 vpushi(0);
2122 gen_op(TOK_NE);
2123 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2124 (dbt & VT_BTYPE) == VT_SHORT) {
2125 if (sbt == VT_PTR) {
2126 vtop->type.t = VT_INT;
2127 tcc_warning("nonportable conversion from pointer to char/short");
2129 force_charshort_cast(dbt);
2130 } else if ((dbt & VT_BTYPE) == VT_INT) {
2131 /* scalar to int */
2132 if (sbt == VT_LLONG && !nocode_wanted) {
2133 /* from long long: just take low order word */
2134 lexpand();
2135 vpop();
2137 /* if lvalue and single word type, nothing to do because
2138 the lvalue already contains the real type size (see
2139 VT_LVAL_xxx constants) */
2142 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2143 /* if we are casting between pointer types,
2144 we must update the VT_LVAL_xxx size */
2145 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2146 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2148 vtop->type = *type;
2151 /* return type size as known at compile time. Put alignment at 'a' */
2152 ST_FUNC int type_size(CType *type, int *a)
2154 Sym *s;
2155 int bt;
2157 bt = type->t & VT_BTYPE;
2158 if (bt == VT_STRUCT) {
2159 /* struct/union */
2160 s = type->ref;
2161 *a = s->r;
2162 return s->c;
2163 } else if (bt == VT_PTR) {
2164 if (type->t & VT_ARRAY) {
2165 int ts;
2167 s = type->ref;
2168 ts = type_size(&s->type, a);
2170 if (ts < 0 && s->c < 0)
2171 ts = -ts;
2173 return ts * s->c;
2174 } else {
2175 *a = PTR_SIZE;
2176 return PTR_SIZE;
2178 } else if (bt == VT_LDOUBLE) {
2179 *a = LDOUBLE_ALIGN;
2180 return LDOUBLE_SIZE;
2181 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2182 #ifdef TCC_TARGET_I386
2183 #ifdef TCC_TARGET_PE
2184 *a = 8;
2185 #else
2186 *a = 4;
2187 #endif
2188 #elif defined(TCC_TARGET_ARM)
2189 #ifdef TCC_ARM_EABI
2190 *a = 8;
2191 #else
2192 *a = 4;
2193 #endif
2194 #else
2195 *a = 8;
2196 #endif
2197 return 8;
2198 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2199 *a = 4;
2200 return 4;
2201 } else if (bt == VT_SHORT) {
2202 *a = 2;
2203 return 2;
2204 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2205 *a = 8;
2206 return 16;
2207 } else {
2208 /* char, void, function, _Bool */
2209 *a = 1;
2210 return 1;
2214 /* push type size as known at runtime time on top of value stack. Put
2215 alignment at 'a' */
2216 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2218 if (type->t & VT_VLA) {
2219 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2220 } else {
2221 vpushi(type_size(type, a));
2225 static void vla_sp_save(void) {
2226 if (!(vla_flags & VLA_SP_LOC_SET)) {
2227 *vla_sp_loc = (loc -= PTR_SIZE);
2228 vla_flags |= VLA_SP_LOC_SET;
2230 if (!(vla_flags & VLA_SP_SAVED)) {
2231 gen_vla_sp_save(*vla_sp_loc);
2232 vla_flags |= VLA_SP_SAVED;
2236 /* return the pointed type of t */
2237 static inline CType *pointed_type(CType *type)
2239 return &type->ref->type;
2242 /* modify type so that its it is a pointer to type. */
2243 ST_FUNC void mk_pointer(CType *type)
2245 Sym *s;
2246 s = sym_push(SYM_FIELD, type, 0, -1);
2247 type->t = VT_PTR | (type->t & ~VT_TYPE);
2248 type->ref = s;
2251 /* compare function types. OLD functions match any new functions */
2252 static int is_compatible_func(CType *type1, CType *type2)
2254 Sym *s1, *s2;
2256 s1 = type1->ref;
2257 s2 = type2->ref;
2258 if (!is_compatible_types(&s1->type, &s2->type))
2259 return 0;
2260 /* check func_call */
2261 if (s1->a.func_call != s2->a.func_call)
2262 return 0;
2263 /* XXX: not complete */
2264 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2265 return 1;
2266 if (s1->c != s2->c)
2267 return 0;
2268 while (s1 != NULL) {
2269 if (s2 == NULL)
2270 return 0;
2271 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2272 return 0;
2273 s1 = s1->next;
2274 s2 = s2->next;
2276 if (s2)
2277 return 0;
2278 return 1;
2281 /* return true if type1 and type2 are the same. If unqualified is
2282 true, qualifiers on the types are ignored.
2284 - enums are not checked as gcc __builtin_types_compatible_p ()
2286 static int compare_types(CType *type1, CType *type2, int unqualified)
2288 int bt1, t1, t2;
2290 t1 = type1->t & VT_TYPE;
2291 t2 = type2->t & VT_TYPE;
2292 if (unqualified) {
2293 /* strip qualifiers before comparing */
2294 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2295 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2297 /* Default Vs explicit signedness only matters for char */
2298 if ((t1 & VT_BTYPE) != VT_BYTE) {
2299 t1 &= ~VT_DEFSIGN;
2300 t2 &= ~VT_DEFSIGN;
2302 /* XXX: bitfields ? */
2303 if (t1 != t2)
2304 return 0;
2305 /* test more complicated cases */
2306 bt1 = t1 & VT_BTYPE;
2307 if (bt1 == VT_PTR) {
2308 type1 = pointed_type(type1);
2309 type2 = pointed_type(type2);
2310 return is_compatible_types(type1, type2);
2311 } else if (bt1 == VT_STRUCT) {
2312 return (type1->ref == type2->ref);
2313 } else if (bt1 == VT_FUNC) {
2314 return is_compatible_func(type1, type2);
2315 } else {
2316 return 1;
2320 /* return true if type1 and type2 are exactly the same (including
2321 qualifiers).
2323 static int is_compatible_types(CType *type1, CType *type2)
2325 return compare_types(type1,type2,0);
2328 /* return true if type1 and type2 are the same (ignoring qualifiers).
2330 static int is_compatible_parameter_types(CType *type1, CType *type2)
2332 return compare_types(type1,type2,1);
2335 /* print a type. If 'varstr' is not NULL, then the variable is also
2336 printed in the type */
2337 /* XXX: union */
2338 /* XXX: add array and function pointers */
2339 static void type_to_str(char *buf, int buf_size,
2340 CType *type, const char *varstr)
2342 int bt, v, t;
2343 Sym *s, *sa;
2344 char buf1[256];
2345 const char *tstr;
2347 t = type->t & VT_TYPE;
2348 bt = t & VT_BTYPE;
2349 buf[0] = '\0';
2350 if (t & VT_CONSTANT)
2351 pstrcat(buf, buf_size, "const ");
2352 if (t & VT_VOLATILE)
2353 pstrcat(buf, buf_size, "volatile ");
2354 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2355 pstrcat(buf, buf_size, "unsigned ");
2356 else if (t & VT_DEFSIGN)
2357 pstrcat(buf, buf_size, "signed ");
2358 switch(bt) {
2359 case VT_VOID:
2360 tstr = "void";
2361 goto add_tstr;
2362 case VT_BOOL:
2363 tstr = "_Bool";
2364 goto add_tstr;
2365 case VT_BYTE:
2366 tstr = "char";
2367 goto add_tstr;
2368 case VT_SHORT:
2369 tstr = "short";
2370 goto add_tstr;
2371 case VT_INT:
2372 tstr = "int";
2373 goto add_tstr;
2374 case VT_LONG:
2375 tstr = "long";
2376 goto add_tstr;
2377 case VT_LLONG:
2378 tstr = "long long";
2379 goto add_tstr;
2380 case VT_FLOAT:
2381 tstr = "float";
2382 goto add_tstr;
2383 case VT_DOUBLE:
2384 tstr = "double";
2385 goto add_tstr;
2386 case VT_LDOUBLE:
2387 tstr = "long double";
2388 add_tstr:
2389 pstrcat(buf, buf_size, tstr);
2390 break;
2391 case VT_ENUM:
2392 case VT_STRUCT:
2393 if (bt == VT_STRUCT)
2394 tstr = "struct ";
2395 else
2396 tstr = "enum ";
2397 pstrcat(buf, buf_size, tstr);
2398 v = type->ref->v & ~SYM_STRUCT;
2399 if (v >= SYM_FIRST_ANOM)
2400 pstrcat(buf, buf_size, "<anonymous>");
2401 else
2402 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2403 break;
2404 case VT_FUNC:
2405 s = type->ref;
2406 type_to_str(buf, buf_size, &s->type, varstr);
2407 pstrcat(buf, buf_size, "(");
2408 sa = s->next;
2409 while (sa != NULL) {
2410 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2411 pstrcat(buf, buf_size, buf1);
2412 sa = sa->next;
2413 if (sa)
2414 pstrcat(buf, buf_size, ", ");
2416 pstrcat(buf, buf_size, ")");
2417 goto no_var;
2418 case VT_PTR:
2419 s = type->ref;
2420 pstrcpy(buf1, sizeof(buf1), "*");
2421 if (varstr)
2422 pstrcat(buf1, sizeof(buf1), varstr);
2423 type_to_str(buf, buf_size, &s->type, buf1);
2424 goto no_var;
2426 if (varstr) {
2427 pstrcat(buf, buf_size, " ");
2428 pstrcat(buf, buf_size, varstr);
2430 no_var: ;
2433 /* verify type compatibility to store vtop in 'dt' type, and generate
2434 casts if needed. */
2435 static void gen_assign_cast(CType *dt)
2437 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2438 char buf1[256], buf2[256];
2439 int dbt, sbt;
2441 st = &vtop->type; /* source type */
2442 dbt = dt->t & VT_BTYPE;
2443 sbt = st->t & VT_BTYPE;
2444 if (sbt == VT_VOID || dbt == VT_VOID) {
2445 if (sbt == VT_VOID && dbt == VT_VOID)
2446 ; /*
2447 It is Ok if both are void
2448 A test program:
2449 void func1() {}
2450 void func2() {
2451 return func1();
2453 gcc accepts this program
2455 else
2456 tcc_error("cannot cast from/to void");
2458 if (dt->t & VT_CONSTANT)
2459 tcc_warning("assignment of read-only location");
2460 switch(dbt) {
2461 case VT_PTR:
2462 /* special cases for pointers */
2463 /* '0' can also be a pointer */
2464 if (is_null_pointer(vtop))
2465 goto type_ok;
2466 /* accept implicit pointer to integer cast with warning */
2467 if (is_integer_btype(sbt)) {
2468 tcc_warning("assignment makes pointer from integer without a cast");
2469 goto type_ok;
2471 type1 = pointed_type(dt);
2472 /* a function is implicitely a function pointer */
2473 if (sbt == VT_FUNC) {
2474 if ((type1->t & VT_BTYPE) != VT_VOID &&
2475 !is_compatible_types(pointed_type(dt), st))
2476 tcc_warning("assignment from incompatible pointer type");
2477 goto type_ok;
2479 if (sbt != VT_PTR)
2480 goto error;
2481 type2 = pointed_type(st);
2482 if ((type1->t & VT_BTYPE) == VT_VOID ||
2483 (type2->t & VT_BTYPE) == VT_VOID) {
2484 /* void * can match anything */
2485 } else {
2486 /* exact type match, except for unsigned */
2487 tmp_type1 = *type1;
2488 tmp_type2 = *type2;
2489 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2490 VT_VOLATILE);
2491 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2492 VT_VOLATILE);
2493 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2494 tcc_warning("assignment from incompatible pointer type");
2496 /* check const and volatile */
2497 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2498 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2499 tcc_warning("assignment discards qualifiers from pointer target type");
2500 break;
2501 case VT_BYTE:
2502 case VT_SHORT:
2503 case VT_INT:
2504 case VT_LLONG:
2505 if (sbt == VT_PTR || sbt == VT_FUNC) {
2506 tcc_warning("assignment makes integer from pointer without a cast");
2508 /* XXX: more tests */
2509 break;
2510 case VT_STRUCT:
2511 tmp_type1 = *dt;
2512 tmp_type2 = *st;
2513 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2514 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2515 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2516 error:
2517 type_to_str(buf1, sizeof(buf1), st, NULL);
2518 type_to_str(buf2, sizeof(buf2), dt, NULL);
2519 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2521 break;
2523 type_ok:
2524 gen_cast(dt);
2527 /* store vtop in lvalue pushed on stack */
2528 ST_FUNC void vstore(void)
2530 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2532 ft = vtop[-1].type.t;
2533 sbt = vtop->type.t & VT_BTYPE;
2534 dbt = ft & VT_BTYPE;
2535 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2536 (sbt == VT_INT && dbt == VT_SHORT))
2537 && !(vtop->type.t & VT_BITFIELD)) {
2538 /* optimize char/short casts */
2539 delayed_cast = VT_MUSTCAST;
2540 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2541 /* XXX: factorize */
2542 if (ft & VT_CONSTANT)
2543 tcc_warning("assignment of read-only location");
2544 } else {
2545 delayed_cast = 0;
2546 if (!(ft & VT_BITFIELD))
2547 gen_assign_cast(&vtop[-1].type);
2550 if (sbt == VT_STRUCT) {
2551 /* if structure, only generate pointer */
2552 /* structure assignment : generate memcpy */
2553 /* XXX: optimize if small size */
2554 if (!nocode_wanted) {
2555 size = type_size(&vtop->type, &align);
2557 /* destination */
2558 vswap();
2559 vtop->type.t = VT_PTR;
2560 gaddrof();
2562 /* address of memcpy() */
2563 #ifdef TCC_ARM_EABI
2564 if(!(align & 7))
2565 vpush_global_sym(&func_old_type, TOK_memcpy8);
2566 else if(!(align & 3))
2567 vpush_global_sym(&func_old_type, TOK_memcpy4);
2568 else
2569 #endif
2570 vpush_global_sym(&func_old_type, TOK_memcpy);
2572 vswap();
2573 /* source */
2574 vpushv(vtop - 2);
2575 vtop->type.t = VT_PTR;
2576 gaddrof();
2577 /* type size */
2578 vpushi(size);
2579 gfunc_call(3);
2580 } else {
2581 vswap();
2582 vpop();
2584 /* leave source on stack */
2585 } else if (ft & VT_BITFIELD) {
2586 /* bitfield store handling */
2588 /* save lvalue as expression result (example: s.b = s.a = n;) */
2589 vdup(), vtop[-1] = vtop[-2];
2591 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2592 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2593 /* remove bit field info to avoid loops */
2594 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2596 if((ft & VT_BTYPE) == VT_BOOL) {
2597 gen_cast(&vtop[-1].type);
2598 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2601 /* duplicate destination */
2602 vdup();
2603 vtop[-1] = vtop[-2];
2605 /* mask and shift source */
2606 if((ft & VT_BTYPE) != VT_BOOL) {
2607 if((ft & VT_BTYPE) == VT_LLONG) {
2608 vpushll((1ULL << bit_size) - 1ULL);
2609 } else {
2610 vpushi((1 << bit_size) - 1);
2612 gen_op('&');
2614 vpushi(bit_pos);
2615 gen_op(TOK_SHL);
2616 /* load destination, mask and or with source */
2617 vswap();
2618 if((ft & VT_BTYPE) == VT_LLONG) {
2619 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2620 } else {
2621 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2623 gen_op('&');
2624 gen_op('|');
2625 /* store result */
2626 vstore();
2627 /* ... and discard */
2628 vpop();
2630 } else {
2631 if (!nocode_wanted) {
2632 #ifdef CONFIG_TCC_BCHECK
2633 /* bound check case */
2634 if (vtop[-1].r & VT_MUSTBOUND) {
2635 vswap();
2636 gbound();
2637 vswap();
2639 #endif
2640 rc = RC_INT;
2641 if (is_float(ft)) {
2642 rc = RC_FLOAT;
2643 #ifdef TCC_TARGET_X86_64
2644 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2645 rc = RC_ST0;
2646 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2647 rc = RC_FRET;
2649 #endif
2651 r = gv(rc); /* generate value */
2652 /* if lvalue was saved on stack, must read it */
2653 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2654 SValue sv;
2655 t = get_reg(RC_INT);
2656 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2657 sv.type.t = VT_PTR;
2658 #else
2659 sv.type.t = VT_INT;
2660 #endif
2661 sv.r = VT_LOCAL | VT_LVAL;
2662 sv.c.ul = vtop[-1].c.ul;
2663 load(t, &sv);
2664 vtop[-1].r = t | VT_LVAL;
2666 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2667 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2668 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2669 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2670 #else
2671 if ((ft & VT_BTYPE) == VT_LLONG) {
2672 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2673 #endif
2674 vtop[-1].type.t = load_type;
2675 store(r, vtop - 1);
2676 vswap();
2677 /* convert to int to increment easily */
2678 vtop->type.t = addr_type;
2679 gaddrof();
2680 vpushi(load_size);
2681 gen_op('+');
2682 vtop->r |= VT_LVAL;
2683 vswap();
2684 vtop[-1].type.t = load_type;
2685 /* XXX: it works because r2 is spilled last ! */
2686 store(vtop->r2, vtop - 1);
2687 } else {
2688 store(r, vtop - 1);
2691 vswap();
2692 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2693 vtop->r |= delayed_cast;
2697 /* post defines POST/PRE add. c is the token ++ or -- */
2698 ST_FUNC void inc(int post, int c)
2700 test_lvalue();
2701 vdup(); /* save lvalue */
2702 if (post) {
2703 if (!nocode_wanted)
2704 gv_dup(); /* duplicate value */
2705 else
2706 vdup(); /* duplicate value */
2707 vrotb(3);
2708 vrotb(3);
2710 /* add constant */
2711 vpushi(c - TOK_MID);
2712 gen_op('+');
2713 vstore(); /* store value */
2714 if (post)
2715 vpop(); /* if post op, return saved value */
2718 /* Parse GNUC __attribute__ extension. Currently, the following
2719 extensions are recognized:
2720 - aligned(n) : set data/function alignment.
2721 - packed : force data alignment to 1
2722 - section(x) : generate data/code in this section.
2723 - unused : currently ignored, but may be used someday.
2724 - regparm(n) : pass function parameters in registers (i386 only)
2726 static void parse_attribute(AttributeDef *ad)
2728 int t, n;
2730 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2731 next();
2732 skip('(');
2733 skip('(');
2734 while (tok != ')') {
2735 if (tok < TOK_IDENT)
2736 expect("attribute name");
2737 t = tok;
2738 next();
2739 switch(t) {
2740 case TOK_SECTION1:
2741 case TOK_SECTION2:
2742 skip('(');
2743 if (tok != TOK_STR)
2744 expect("section name");
2745 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2746 next();
2747 skip(')');
2748 break;
2749 case TOK_ALIAS1:
2750 case TOK_ALIAS2:
2751 skip('(');
2752 if (tok != TOK_STR)
2753 expect("alias(\"target\")");
2754 ad->alias_target = /* save string as token, for later */
2755 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2756 next();
2757 skip(')');
2758 break;
2759 case TOK_VISIBILITY1:
2760 case TOK_VISIBILITY2:
2761 skip('(');
2762 if (tok != TOK_STR)
2763 expect("visibility(\"default|hidden|internal|protected\")");
2764 if (!strcmp (tokc.cstr->data, "default"))
2765 ad->a.visibility = STV_DEFAULT;
2766 else if (!strcmp (tokc.cstr->data, "hidden"))
2767 ad->a.visibility = STV_HIDDEN;
2768 else if (!strcmp (tokc.cstr->data, "internal"))
2769 ad->a.visibility = STV_INTERNAL;
2770 else if (!strcmp (tokc.cstr->data, "protected"))
2771 ad->a.visibility = STV_PROTECTED;
2772 else
2773 expect("visibility(\"default|hidden|internal|protected\")");
2774 next();
2775 skip(')');
2776 break;
2777 case TOK_ALIGNED1:
2778 case TOK_ALIGNED2:
2779 if (tok == '(') {
2780 next();
2781 n = expr_const();
2782 if (n <= 0 || (n & (n - 1)) != 0)
2783 tcc_error("alignment must be a positive power of two");
2784 skip(')');
2785 } else {
2786 n = MAX_ALIGN;
2788 ad->a.aligned = n;
2789 break;
2790 case TOK_PACKED1:
2791 case TOK_PACKED2:
2792 ad->a.packed = 1;
2793 break;
2794 case TOK_WEAK1:
2795 case TOK_WEAK2:
2796 ad->a.weak = 1;
2797 break;
2798 case TOK_UNUSED1:
2799 case TOK_UNUSED2:
2800 /* currently, no need to handle it because tcc does not
2801 track unused objects */
2802 break;
2803 case TOK_NORETURN1:
2804 case TOK_NORETURN2:
2805 /* currently, no need to handle it because tcc does not
2806 track unused objects */
2807 break;
2808 case TOK_CDECL1:
2809 case TOK_CDECL2:
2810 case TOK_CDECL3:
2811 ad->a.func_call = FUNC_CDECL;
2812 break;
2813 case TOK_STDCALL1:
2814 case TOK_STDCALL2:
2815 case TOK_STDCALL3:
2816 ad->a.func_call = FUNC_STDCALL;
2817 break;
2818 #ifdef TCC_TARGET_I386
2819 case TOK_REGPARM1:
2820 case TOK_REGPARM2:
2821 skip('(');
2822 n = expr_const();
2823 if (n > 3)
2824 n = 3;
2825 else if (n < 0)
2826 n = 0;
2827 if (n > 0)
2828 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
2829 skip(')');
2830 break;
2831 case TOK_FASTCALL1:
2832 case TOK_FASTCALL2:
2833 case TOK_FASTCALL3:
2834 ad->a.func_call = FUNC_FASTCALLW;
2835 break;
2836 #endif
2837 case TOK_MODE:
2838 skip('(');
2839 switch(tok) {
2840 case TOK_MODE_DI:
2841 ad->a.mode = VT_LLONG + 1;
2842 break;
2843 case TOK_MODE_HI:
2844 ad->a.mode = VT_SHORT + 1;
2845 break;
2846 case TOK_MODE_SI:
2847 ad->a.mode = VT_INT + 1;
2848 break;
2849 default:
2850 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2851 break;
2853 next();
2854 skip(')');
2855 break;
2856 case TOK_DLLEXPORT:
2857 ad->a.func_export = 1;
2858 break;
2859 case TOK_DLLIMPORT:
2860 ad->a.func_import = 1;
2861 break;
2862 default:
2863 if (tcc_state->warn_unsupported)
2864 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2865 /* skip parameters */
2866 if (tok == '(') {
2867 int parenthesis = 0;
2868 do {
2869 if (tok == '(')
2870 parenthesis++;
2871 else if (tok == ')')
2872 parenthesis--;
2873 next();
2874 } while (parenthesis && tok != -1);
2876 break;
2878 if (tok != ',')
2879 break;
2880 next();
2882 skip(')');
2883 skip(')');
2887 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2888 static void struct_decl(CType *type, int u, int tdef)
2890 int a, v, size, align, maxalign, c, offset, flexible;
2891 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2892 Sym *s, *ss, *ass, **ps;
2893 AttributeDef ad;
2894 CType type1, btype;
2896 a = tok; /* save decl type */
2897 next();
2898 if (tok != '{') {
2899 v = tok;
2900 next();
2901 /* struct already defined ? return it */
2902 if (v < TOK_IDENT)
2903 expect("struct/union/enum name");
2904 s = struct_find(v);
2905 if (s) {
2906 if (s->type.t != a)
2907 tcc_error("invalid type");
2908 goto do_decl;
2909 } else if (tok >= TOK_IDENT && !tdef)
2910 tcc_error("unknown struct/union/enum");
2911 } else {
2912 v = anon_sym++;
2914 type1.t = a;
2915 type1.ref = NULL;
2916 /* we put an undefined size for struct/union */
2917 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2918 s->r = 0; /* default alignment is zero as gcc */
2919 /* put struct/union/enum name in type */
2920 do_decl:
2921 type->t = u;
2922 type->ref = s;
2924 if (tok == '{') {
2925 next();
2926 if (s->c != -1)
2927 tcc_error("struct/union/enum already defined");
2928 /* cannot be empty */
2929 c = 0;
2930 /* non empty enums are not allowed */
2931 if (a == TOK_ENUM) {
2932 for(;;) {
2933 v = tok;
2934 if (v < TOK_UIDENT)
2935 expect("identifier");
2936 ss = sym_find(v);
2937 if (ss && !local_stack)
2938 tcc_error("redefinition of enumerator '%s'",
2939 get_tok_str(v, NULL));
2940 next();
2941 if (tok == '=') {
2942 next();
2943 c = expr_const();
2945 /* enum symbols have static storage */
2946 ss = sym_push(v, &int_type, VT_CONST, c);
2947 ss->type.t |= VT_STATIC;
2948 if (tok != ',')
2949 break;
2950 next();
2951 c++;
2952 /* NOTE: we accept a trailing comma */
2953 if (tok == '}')
2954 break;
2956 s->c = type_size(&int_type, &align);
2957 skip('}');
2958 } else {
2959 maxalign = 1;
2960 ps = &s->next;
2961 prevbt = VT_INT;
2962 bit_pos = 0;
2963 offset = 0;
2964 flexible = 0;
2965 while (tok != '}') {
2966 parse_btype(&btype, &ad);
2967 while (1) {
2968 if (flexible)
2969 tcc_error("flexible array member '%s' not at the end of struct",
2970 get_tok_str(v, NULL));
2971 bit_size = -1;
2972 v = 0;
2973 type1 = btype;
2974 if (tok != ':') {
2975 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2976 if (v == 0) {
2977 if ((type1.t & VT_BTYPE) != VT_STRUCT)
2978 expect("identifier");
2979 else {
2980 int v = btype.ref->v;
2981 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
2982 if (tcc_state->ms_extensions == 0)
2983 expect("identifier");
2987 if (type_size(&type1, &align) < 0) {
2988 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
2989 flexible = 1;
2990 else
2991 tcc_error("field '%s' has incomplete type",
2992 get_tok_str(v, NULL));
2994 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2995 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2996 tcc_error("invalid type for '%s'",
2997 get_tok_str(v, NULL));
2999 if (tok == ':') {
3000 next();
3001 bit_size = expr_const();
3002 /* XXX: handle v = 0 case for messages */
3003 if (bit_size < 0)
3004 tcc_error("negative width in bit-field '%s'",
3005 get_tok_str(v, NULL));
3006 if (v && bit_size == 0)
3007 tcc_error("zero width for bit-field '%s'",
3008 get_tok_str(v, NULL));
3010 size = type_size(&type1, &align);
3011 if (ad.a.aligned) {
3012 if (align < ad.a.aligned)
3013 align = ad.a.aligned;
3014 } else if (ad.a.packed) {
3015 align = 1;
3016 } else if (*tcc_state->pack_stack_ptr) {
3017 if (align > *tcc_state->pack_stack_ptr)
3018 align = *tcc_state->pack_stack_ptr;
3020 lbit_pos = 0;
3021 if (bit_size >= 0) {
3022 bt = type1.t & VT_BTYPE;
3023 if (bt != VT_INT &&
3024 bt != VT_BYTE &&
3025 bt != VT_SHORT &&
3026 bt != VT_BOOL &&
3027 bt != VT_ENUM &&
3028 bt != VT_LLONG)
3029 tcc_error("bitfields must have scalar type");
3030 bsize = size * 8;
3031 if (bit_size > bsize) {
3032 tcc_error("width of '%s' exceeds its type",
3033 get_tok_str(v, NULL));
3034 } else if (bit_size == bsize) {
3035 /* no need for bit fields */
3036 bit_pos = 0;
3037 } else if (bit_size == 0) {
3038 /* XXX: what to do if only padding in a
3039 structure ? */
3040 /* zero size: means to pad */
3041 bit_pos = 0;
3042 } else {
3043 /* we do not have enough room ?
3044 did the type change?
3045 is it a union? */
3046 if ((bit_pos + bit_size) > bsize ||
3047 bt != prevbt || a == TOK_UNION)
3048 bit_pos = 0;
3049 lbit_pos = bit_pos;
3050 /* XXX: handle LSB first */
3051 type1.t |= VT_BITFIELD |
3052 (bit_pos << VT_STRUCT_SHIFT) |
3053 (bit_size << (VT_STRUCT_SHIFT + 6));
3054 bit_pos += bit_size;
3056 prevbt = bt;
3057 } else {
3058 bit_pos = 0;
3060 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3061 /* add new memory data only if starting
3062 bit field */
3063 if (lbit_pos == 0) {
3064 if (a == TOK_STRUCT) {
3065 c = (c + align - 1) & -align;
3066 offset = c;
3067 if (size > 0)
3068 c += size;
3069 } else {
3070 offset = 0;
3071 if (size > c)
3072 c = size;
3074 if (align > maxalign)
3075 maxalign = align;
3077 #if 0
3078 printf("add field %s offset=%d",
3079 get_tok_str(v, NULL), offset);
3080 if (type1.t & VT_BITFIELD) {
3081 printf(" pos=%d size=%d",
3082 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3083 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3085 printf("\n");
3086 #endif
3088 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3089 ass = type1.ref;
3090 while ((ass = ass->next) != NULL) {
3091 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3092 *ps = ss;
3093 ps = &ss->next;
3095 } else if (v) {
3096 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3097 *ps = ss;
3098 ps = &ss->next;
3100 if (tok == ';' || tok == TOK_EOF)
3101 break;
3102 skip(',');
3104 skip(';');
3106 skip('}');
3107 /* store size and alignment */
3108 s->c = (c + maxalign - 1) & -maxalign;
3109 s->r = maxalign;
3114 /* return 1 if basic type is a type size (short, long, long long) */
3115 ST_FUNC int is_btype_size(int bt)
3117 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3120 /* return 0 if no type declaration. otherwise, return the basic type
3121 and skip it.
3123 static int parse_btype(CType *type, AttributeDef *ad)
3125 int t, u, bt_size, complete, type_found, typespec_found;
3126 Sym *s;
3127 CType type1;
3129 memset(ad, 0, sizeof(AttributeDef));
3130 complete = 0;
3131 type_found = 0;
3132 typespec_found = 0;
3133 t = 0;
3134 while(1) {
3135 switch(tok) {
3136 case TOK_EXTENSION:
3137 /* currently, we really ignore extension */
3138 next();
3139 continue;
3141 /* basic types */
3142 case TOK_CHAR:
3143 u = VT_BYTE;
3144 basic_type:
3145 next();
3146 basic_type1:
3147 if (complete)
3148 tcc_error("too many basic types");
3149 t |= u;
3150 bt_size = is_btype_size (u & VT_BTYPE);
3151 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3152 complete = 1;
3153 typespec_found = 1;
3154 break;
3155 case TOK_VOID:
3156 u = VT_VOID;
3157 goto basic_type;
3158 case TOK_SHORT:
3159 u = VT_SHORT;
3160 goto basic_type;
3161 case TOK_INT:
3162 u = VT_INT;
3163 goto basic_type;
3164 case TOK_LONG:
3165 next();
3166 if ((t & VT_BTYPE) == VT_DOUBLE) {
3167 #ifndef TCC_TARGET_PE
3168 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3169 #endif
3170 } else if ((t & VT_BTYPE) == VT_LONG) {
3171 t = (t & ~VT_BTYPE) | VT_LLONG;
3172 } else {
3173 u = VT_LONG;
3174 goto basic_type1;
3176 break;
3177 #ifdef TCC_TARGET_ARM64
3178 case TOK_UINT128:
3179 /* GCC's __uint128_t appears in some Linux header files. Make it a
3180 synonym for long double to get the size and alignment right. */
3181 u = VT_LDOUBLE;
3182 goto basic_type;
3183 #endif
3184 case TOK_BOOL:
3185 u = VT_BOOL;
3186 goto basic_type;
3187 case TOK_FLOAT:
3188 u = VT_FLOAT;
3189 goto basic_type;
3190 case TOK_DOUBLE:
3191 next();
3192 if ((t & VT_BTYPE) == VT_LONG) {
3193 #ifdef TCC_TARGET_PE
3194 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3195 #else
3196 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3197 #endif
3198 } else {
3199 u = VT_DOUBLE;
3200 goto basic_type1;
3202 break;
3203 case TOK_ENUM:
3204 struct_decl(&type1, VT_ENUM, t & (VT_TYPEDEF | VT_EXTERN));
3205 basic_type2:
3206 u = type1.t;
3207 type->ref = type1.ref;
3208 goto basic_type1;
3209 case TOK_STRUCT:
3210 case TOK_UNION:
3211 struct_decl(&type1, VT_STRUCT, t & (VT_TYPEDEF | VT_EXTERN));
3212 goto basic_type2;
3214 /* type modifiers */
3215 case TOK_CONST1:
3216 case TOK_CONST2:
3217 case TOK_CONST3:
3218 t |= VT_CONSTANT;
3219 next();
3220 break;
3221 case TOK_VOLATILE1:
3222 case TOK_VOLATILE2:
3223 case TOK_VOLATILE3:
3224 t |= VT_VOLATILE;
3225 next();
3226 break;
3227 case TOK_SIGNED1:
3228 case TOK_SIGNED2:
3229 case TOK_SIGNED3:
3230 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3231 tcc_error("signed and unsigned modifier");
3232 typespec_found = 1;
3233 t |= VT_DEFSIGN;
3234 next();
3235 break;
3236 case TOK_REGISTER:
3237 case TOK_AUTO:
3238 case TOK_RESTRICT1:
3239 case TOK_RESTRICT2:
3240 case TOK_RESTRICT3:
3241 next();
3242 break;
3243 case TOK_UNSIGNED:
3244 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3245 tcc_error("signed and unsigned modifier");
3246 t |= VT_DEFSIGN | VT_UNSIGNED;
3247 next();
3248 typespec_found = 1;
3249 break;
3251 /* storage */
3252 case TOK_EXTERN:
3253 t |= VT_EXTERN;
3254 next();
3255 break;
3256 case TOK_STATIC:
3257 t |= VT_STATIC;
3258 next();
3259 break;
3260 case TOK_TYPEDEF:
3261 t |= VT_TYPEDEF;
3262 next();
3263 break;
3264 case TOK_INLINE1:
3265 case TOK_INLINE2:
3266 case TOK_INLINE3:
3267 t |= VT_INLINE;
3268 next();
3269 break;
3271 /* GNUC attribute */
3272 case TOK_ATTRIBUTE1:
3273 case TOK_ATTRIBUTE2:
3274 parse_attribute(ad);
3275 if (ad->a.mode) {
3276 u = ad->a.mode -1;
3277 t = (t & ~VT_BTYPE) | u;
3279 break;
3280 /* GNUC typeof */
3281 case TOK_TYPEOF1:
3282 case TOK_TYPEOF2:
3283 case TOK_TYPEOF3:
3284 next();
3285 parse_expr_type(&type1);
3286 /* remove all storage modifiers except typedef */
3287 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3288 goto basic_type2;
3289 default:
3290 if (typespec_found)
3291 goto the_end;
3292 s = sym_find(tok);
3293 if (!s || !(s->type.t & VT_TYPEDEF))
3294 goto the_end;
3295 t |= (s->type.t & ~VT_TYPEDEF);
3296 type->ref = s->type.ref;
3297 if (s->r) {
3298 /* get attributes from typedef */
3299 if (0 == ad->a.aligned)
3300 ad->a.aligned = s->a.aligned;
3301 if (0 == ad->a.func_call)
3302 ad->a.func_call = s->a.func_call;
3303 ad->a.packed |= s->a.packed;
3305 next();
3306 typespec_found = 1;
3307 break;
3309 type_found = 1;
3311 the_end:
3312 if (tcc_state->char_is_unsigned) {
3313 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3314 t |= VT_UNSIGNED;
3317 /* long is never used as type */
3318 if ((t & VT_BTYPE) == VT_LONG)
3319 #if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \
3320 defined TCC_TARGET_PE
3321 t = (t & ~VT_BTYPE) | VT_INT;
3322 #else
3323 t = (t & ~VT_BTYPE) | VT_LLONG;
3324 #endif
3325 type->t = t;
3326 return type_found;
3329 /* convert a function parameter type (array to pointer and function to
3330 function pointer) */
3331 static inline void convert_parameter_type(CType *pt)
3333 /* remove const and volatile qualifiers (XXX: const could be used
3334 to indicate a const function parameter */
3335 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3336 /* array must be transformed to pointer according to ANSI C */
3337 pt->t &= ~VT_ARRAY;
3338 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3339 mk_pointer(pt);
3343 ST_FUNC void parse_asm_str(CString *astr)
3345 skip('(');
3346 /* read the string */
3347 if (tok != TOK_STR)
3348 expect("string constant");
3349 cstr_new(astr);
3350 while (tok == TOK_STR) {
3351 /* XXX: add \0 handling too ? */
3352 cstr_cat(astr, tokc.cstr->data);
3353 next();
3355 cstr_ccat(astr, '\0');
3358 /* Parse an asm label and return the label
3359 * Don't forget to free the CString in the caller! */
3360 static void asm_label_instr(CString *astr)
3362 next();
3363 parse_asm_str(astr);
3364 skip(')');
3365 #ifdef ASM_DEBUG
3366 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3367 #endif
3370 static void post_type(CType *type, AttributeDef *ad)
3372 int n, l, t1, arg_size, align;
3373 Sym **plast, *s, *first;
3374 AttributeDef ad1;
3375 CType pt;
3377 if (tok == '(') {
3378 /* function declaration */
3379 next();
3380 l = 0;
3381 first = NULL;
3382 plast = &first;
3383 arg_size = 0;
3384 if (tok != ')') {
3385 for(;;) {
3386 /* read param name and compute offset */
3387 if (l != FUNC_OLD) {
3388 if (!parse_btype(&pt, &ad1)) {
3389 if (l) {
3390 tcc_error("invalid type");
3391 } else {
3392 l = FUNC_OLD;
3393 goto old_proto;
3396 l = FUNC_NEW;
3397 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3398 break;
3399 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3400 if ((pt.t & VT_BTYPE) == VT_VOID)
3401 tcc_error("parameter declared as void");
3402 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3403 } else {
3404 old_proto:
3405 n = tok;
3406 if (n < TOK_UIDENT)
3407 expect("identifier");
3408 pt.t = VT_INT;
3409 next();
3411 convert_parameter_type(&pt);
3412 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3413 *plast = s;
3414 plast = &s->next;
3415 if (tok == ')')
3416 break;
3417 skip(',');
3418 if (l == FUNC_NEW && tok == TOK_DOTS) {
3419 l = FUNC_ELLIPSIS;
3420 next();
3421 break;
3425 /* if no parameters, then old type prototype */
3426 if (l == 0)
3427 l = FUNC_OLD;
3428 skip(')');
3429 /* NOTE: const is ignored in returned type as it has a special
3430 meaning in gcc / C++ */
3431 type->t &= ~VT_CONSTANT;
3432 /* some ancient pre-K&R C allows a function to return an array
3433 and the array brackets to be put after the arguments, such
3434 that "int c()[]" means something like "int[] c()" */
3435 if (tok == '[') {
3436 next();
3437 skip(']'); /* only handle simple "[]" */
3438 type->t |= VT_PTR;
3440 /* we push a anonymous symbol which will contain the function prototype */
3441 ad->a.func_args = arg_size;
3442 s = sym_push(SYM_FIELD, type, 0, l);
3443 s->a = ad->a;
3444 s->next = first;
3445 type->t = VT_FUNC;
3446 type->ref = s;
3447 } else if (tok == '[') {
3448 /* array definition */
3449 next();
3450 if (tok == TOK_RESTRICT1)
3451 next();
3452 n = -1;
3453 t1 = 0;
3454 if (tok != ']') {
3455 if (!local_stack || nocode_wanted)
3456 vpushi(expr_const());
3457 else gexpr();
3458 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3459 n = vtop->c.i;
3460 if (n < 0)
3461 tcc_error("invalid array size");
3462 } else {
3463 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3464 tcc_error("size of variable length array should be an integer");
3465 t1 = VT_VLA;
3468 skip(']');
3469 /* parse next post type */
3470 post_type(type, ad);
3471 if (type->t == VT_FUNC)
3472 tcc_error("declaration of an array of functions");
3473 t1 |= type->t & VT_VLA;
3475 if (t1 & VT_VLA) {
3476 loc -= type_size(&int_type, &align);
3477 loc &= -align;
3478 n = loc;
3480 vla_runtime_type_size(type, &align);
3481 gen_op('*');
3482 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3483 vswap();
3484 vstore();
3486 if (n != -1)
3487 vpop();
3489 /* we push an anonymous symbol which will contain the array
3490 element type */
3491 s = sym_push(SYM_FIELD, type, 0, n);
3492 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3493 type->ref = s;
3497 /* Parse a type declaration (except basic type), and return the type
3498 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3499 expected. 'type' should contain the basic type. 'ad' is the
3500 attribute definition of the basic type. It can be modified by
3501 type_decl().
3503 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3505 Sym *s;
3506 CType type1, *type2;
3507 int qualifiers, storage;
3509 while (tok == '*') {
3510 qualifiers = 0;
3511 redo:
3512 next();
3513 switch(tok) {
3514 case TOK_CONST1:
3515 case TOK_CONST2:
3516 case TOK_CONST3:
3517 qualifiers |= VT_CONSTANT;
3518 goto redo;
3519 case TOK_VOLATILE1:
3520 case TOK_VOLATILE2:
3521 case TOK_VOLATILE3:
3522 qualifiers |= VT_VOLATILE;
3523 goto redo;
3524 case TOK_RESTRICT1:
3525 case TOK_RESTRICT2:
3526 case TOK_RESTRICT3:
3527 goto redo;
3529 mk_pointer(type);
3530 type->t |= qualifiers;
3533 /* XXX: clarify attribute handling */
3534 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3535 parse_attribute(ad);
3537 /* recursive type */
3538 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3539 type1.t = 0; /* XXX: same as int */
3540 if (tok == '(') {
3541 next();
3542 /* XXX: this is not correct to modify 'ad' at this point, but
3543 the syntax is not clear */
3544 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3545 parse_attribute(ad);
3546 type_decl(&type1, ad, v, td);
3547 skip(')');
3548 } else {
3549 /* type identifier */
3550 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3551 *v = tok;
3552 next();
3553 } else {
3554 if (!(td & TYPE_ABSTRACT))
3555 expect("identifier");
3556 *v = 0;
3559 storage = type->t & VT_STORAGE;
3560 type->t &= ~VT_STORAGE;
3561 if (storage & VT_STATIC) {
3562 int saved_nocode_wanted = nocode_wanted;
3563 nocode_wanted = 1;
3564 post_type(type, ad);
3565 nocode_wanted = saved_nocode_wanted;
3566 } else
3567 post_type(type, ad);
3568 type->t |= storage;
3569 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3570 parse_attribute(ad);
3572 if (!type1.t)
3573 return;
3574 /* append type at the end of type1 */
3575 type2 = &type1;
3576 for(;;) {
3577 s = type2->ref;
3578 type2 = &s->type;
3579 if (!type2->t) {
3580 *type2 = *type;
3581 break;
3584 *type = type1;
3587 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3588 ST_FUNC int lvalue_type(int t)
3590 int bt, r;
3591 r = VT_LVAL;
3592 bt = t & VT_BTYPE;
3593 if (bt == VT_BYTE || bt == VT_BOOL)
3594 r |= VT_LVAL_BYTE;
3595 else if (bt == VT_SHORT)
3596 r |= VT_LVAL_SHORT;
3597 else
3598 return r;
3599 if (t & VT_UNSIGNED)
3600 r |= VT_LVAL_UNSIGNED;
3601 return r;
3604 /* indirection with full error checking and bound check */
3605 ST_FUNC void indir(void)
3607 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3608 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3609 return;
3610 expect("pointer");
3612 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3613 gv(RC_INT);
3614 vtop->type = *pointed_type(&vtop->type);
3615 /* Arrays and functions are never lvalues */
3616 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3617 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3618 vtop->r |= lvalue_type(vtop->type.t);
3619 /* if bound checking, the referenced pointer must be checked */
3620 #ifdef CONFIG_TCC_BCHECK
3621 if (tcc_state->do_bounds_check)
3622 vtop->r |= VT_MUSTBOUND;
3623 #endif
3627 /* pass a parameter to a function and do type checking and casting */
3628 static void gfunc_param_typed(Sym *func, Sym *arg)
3630 int func_type;
3631 CType type;
3633 func_type = func->c;
3634 if (func_type == FUNC_OLD ||
3635 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3636 /* default casting : only need to convert float to double */
3637 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3638 type.t = VT_DOUBLE;
3639 gen_cast(&type);
3640 } else if (vtop->type.t & VT_BITFIELD) {
3641 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3642 gen_cast(&type);
3644 } else if (arg == NULL) {
3645 tcc_error("too many arguments to function");
3646 } else {
3647 type = arg->type;
3648 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3649 gen_assign_cast(&type);
3653 /* parse an expression of the form '(type)' or '(expr)' and return its
3654 type */
3655 static void parse_expr_type(CType *type)
3657 int n;
3658 AttributeDef ad;
3660 skip('(');
3661 if (parse_btype(type, &ad)) {
3662 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3663 } else {
3664 expr_type(type);
3666 skip(')');
3669 static void parse_type(CType *type)
3671 AttributeDef ad;
3672 int n;
3674 if (!parse_btype(type, &ad)) {
3675 expect("type");
3677 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3680 static void vpush_tokc(int t)
3682 CType type;
3683 type.t = t;
3684 type.ref = 0;
3685 vsetc(&type, VT_CONST, &tokc);
3688 ST_FUNC void unary(void)
3690 int n, t, align, size, r, sizeof_caller;
3691 CType type;
3692 Sym *s;
3693 AttributeDef ad;
3694 static int in_sizeof = 0;
3696 sizeof_caller = in_sizeof;
3697 in_sizeof = 0;
3698 /* XXX: GCC 2.95.3 does not generate a table although it should be
3699 better here */
3700 tok_next:
3701 switch(tok) {
3702 case TOK_EXTENSION:
3703 next();
3704 goto tok_next;
3705 case TOK_CINT:
3706 case TOK_CCHAR:
3707 case TOK_LCHAR:
3708 vpushi(tokc.i);
3709 next();
3710 break;
3711 case TOK_CUINT:
3712 vpush_tokc(VT_INT | VT_UNSIGNED);
3713 next();
3714 break;
3715 case TOK_CLLONG:
3716 vpush_tokc(VT_LLONG);
3717 next();
3718 break;
3719 case TOK_CULLONG:
3720 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3721 next();
3722 break;
3723 case TOK_CFLOAT:
3724 vpush_tokc(VT_FLOAT);
3725 next();
3726 break;
3727 case TOK_CDOUBLE:
3728 vpush_tokc(VT_DOUBLE);
3729 next();
3730 break;
3731 case TOK_CLDOUBLE:
3732 vpush_tokc(VT_LDOUBLE);
3733 next();
3734 break;
3735 case TOK___FUNCTION__:
3736 if (!gnu_ext)
3737 goto tok_identifier;
3738 /* fall thru */
3739 case TOK___FUNC__:
3741 void *ptr;
3742 int len;
3743 /* special function name identifier */
3744 len = strlen(funcname) + 1;
3745 /* generate char[len] type */
3746 type.t = VT_BYTE;
3747 mk_pointer(&type);
3748 type.t |= VT_ARRAY;
3749 type.ref->c = len;
3750 vpush_ref(&type, data_section, data_section->data_offset, len);
3751 ptr = section_ptr_add(data_section, len);
3752 memcpy(ptr, funcname, len);
3753 next();
3755 break;
3756 case TOK_LSTR:
3757 #ifdef TCC_TARGET_PE
3758 t = VT_SHORT | VT_UNSIGNED;
3759 #else
3760 t = VT_INT;
3761 #endif
3762 goto str_init;
3763 case TOK_STR:
3764 /* string parsing */
3765 t = VT_BYTE;
3766 str_init:
3767 if (tcc_state->warn_write_strings)
3768 t |= VT_CONSTANT;
3769 type.t = t;
3770 mk_pointer(&type);
3771 type.t |= VT_ARRAY;
3772 memset(&ad, 0, sizeof(AttributeDef));
3773 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3774 break;
3775 case '(':
3776 next();
3777 /* cast ? */
3778 if (parse_btype(&type, &ad)) {
3779 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3780 skip(')');
3781 /* check ISOC99 compound literal */
3782 if (tok == '{') {
3783 /* data is allocated locally by default */
3784 if (global_expr)
3785 r = VT_CONST;
3786 else
3787 r = VT_LOCAL;
3788 /* all except arrays are lvalues */
3789 if (!(type.t & VT_ARRAY))
3790 r |= lvalue_type(type.t);
3791 memset(&ad, 0, sizeof(AttributeDef));
3792 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3793 } else {
3794 if (sizeof_caller) {
3795 vpush(&type);
3796 return;
3798 unary();
3799 gen_cast(&type);
3801 } else if (tok == '{') {
3803 if (nocode_wanted)
3804 tcc_error("statement expression in global scope"); */
3805 /* this check breaks compilation of the linux 2.4.26 with the meesage:
3806 linux/include/net/tcp.h:945: error: statement expression in global scope */
3808 /* save all registers */
3809 save_regs(0);
3810 /* statement expression : we do not accept break/continue
3811 inside as GCC does */
3812 block(NULL, NULL, NULL, NULL, 0, 1);
3813 skip(')');
3814 } else {
3815 gexpr();
3816 skip(')');
3818 break;
3819 case '*':
3820 next();
3821 unary();
3822 indir();
3823 break;
3824 case '&':
3825 next();
3826 unary();
3827 /* functions names must be treated as function pointers,
3828 except for unary '&' and sizeof. Since we consider that
3829 functions are not lvalues, we only have to handle it
3830 there and in function calls. */
3831 /* arrays can also be used although they are not lvalues */
3832 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3833 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3834 test_lvalue();
3835 mk_pointer(&vtop->type);
3836 gaddrof();
3837 break;
3838 case '!':
3839 next();
3840 unary();
3841 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3842 CType boolean;
3843 boolean.t = VT_BOOL;
3844 gen_cast(&boolean);
3845 vtop->c.i = !vtop->c.i;
3846 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3847 vtop->c.i = vtop->c.i ^ 1;
3848 else if (!nocode_wanted) {
3849 save_regs(1);
3850 vseti(VT_JMP, gvtst(1, 0));
3852 else
3853 vtop--;
3854 break;
3855 case '~':
3856 next();
3857 unary();
3858 vpushi(-1);
3859 gen_op('^');
3860 break;
3861 case '+':
3862 next();
3863 unary();
3864 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3865 tcc_error("pointer not accepted for unary plus");
3866 /* In order to force cast, we add zero, except for floating point
3867 where we really need an noop (otherwise -0.0 will be transformed
3868 into +0.0). */
3869 if (!is_float(vtop->type.t)) {
3870 vpushi(0);
3871 gen_op('+');
3873 break;
3874 case TOK_SIZEOF:
3875 case TOK_ALIGNOF1:
3876 case TOK_ALIGNOF2:
3877 t = tok;
3878 next();
3879 in_sizeof++;
3880 unary_type(&type); // Perform a in_sizeof = 0;
3881 size = type_size(&type, &align);
3882 if (t == TOK_SIZEOF) {
3883 if (!(type.t & VT_VLA)) {
3884 if (size < 0)
3885 tcc_error("sizeof applied to an incomplete type");
3886 vpushs(size);
3887 } else {
3888 vla_runtime_type_size(&type, &align);
3890 } else {
3891 vpushs(align);
3893 vtop->type.t |= VT_UNSIGNED;
3894 break;
3896 case TOK_builtin_types_compatible_p:
3898 CType type1, type2;
3899 next();
3900 skip('(');
3901 parse_type(&type1);
3902 skip(',');
3903 parse_type(&type2);
3904 skip(')');
3905 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3906 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3907 vpushi(is_compatible_types(&type1, &type2));
3909 break;
3910 case TOK_builtin_constant_p:
3912 int saved_nocode_wanted, res;
3913 next();
3914 skip('(');
3915 saved_nocode_wanted = nocode_wanted;
3916 nocode_wanted = 1;
3917 gexpr();
3918 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3919 vpop();
3920 nocode_wanted = saved_nocode_wanted;
3921 skip(')');
3922 vpushi(res);
3924 break;
3925 case TOK_builtin_frame_address:
3926 case TOK_builtin_return_address:
3928 int tok1 = tok;
3929 int level;
3930 CType type;
3931 next();
3932 skip('(');
3933 if (tok != TOK_CINT || tokc.i < 0) {
3934 tcc_error("%s only takes positive integers",
3935 tok1 == TOK_builtin_return_address ?
3936 "__builtin_return_address" :
3937 "__builtin_frame_address");
3939 level = tokc.i;
3940 next();
3941 skip(')');
3942 type.t = VT_VOID;
3943 mk_pointer(&type);
3944 vset(&type, VT_LOCAL, 0); /* local frame */
3945 while (level--) {
3946 mk_pointer(&vtop->type);
3947 indir(); /* -> parent frame */
3949 if (tok1 == TOK_builtin_return_address) {
3950 // assume return address is just above frame pointer on stack
3951 vpushi(PTR_SIZE);
3952 gen_op('+');
3953 mk_pointer(&vtop->type);
3954 indir();
3957 break;
3958 #ifdef TCC_TARGET_X86_64
3959 #ifdef TCC_TARGET_PE
3960 case TOK_builtin_va_start:
3962 next();
3963 skip('(');
3964 expr_eq();
3965 skip(',');
3966 expr_eq();
3967 skip(')');
3968 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
3969 tcc_error("__builtin_va_start expects a local variable");
3970 vtop->r &= ~(VT_LVAL | VT_REF);
3971 vtop->type = char_pointer_type;
3972 vstore();
3974 break;
3975 #else
3976 case TOK_builtin_va_arg_types:
3978 CType type;
3979 next();
3980 skip('(');
3981 parse_type(&type);
3982 skip(')');
3983 vpushi(classify_x86_64_va_arg(&type));
3985 break;
3986 #endif
3987 #endif
3989 #ifdef TCC_TARGET_ARM64
3990 case TOK___va_start: {
3991 if (nocode_wanted)
3992 tcc_error("statement in global scope");
3993 next();
3994 skip('(');
3995 expr_eq();
3996 skip(',');
3997 expr_eq();
3998 skip(')');
3999 //xx check types
4000 gen_va_start();
4001 vpushi(0);
4002 vtop->type.t = VT_VOID;
4003 break;
4005 case TOK___va_arg: {
4006 if (nocode_wanted)
4007 tcc_error("statement in global scope");
4008 CType type;
4009 next();
4010 skip('(');
4011 expr_eq();
4012 skip(',');
4013 parse_type(&type);
4014 skip(')');
4015 //xx check types
4016 gen_va_arg(&type);
4017 vtop->type = type;
4018 break;
4020 case TOK___arm64_clear_cache: {
4021 next();
4022 skip('(');
4023 expr_eq();
4024 skip(',');
4025 expr_eq();
4026 skip(')');
4027 gen_clear_cache();
4028 vpushi(0);
4029 vtop->type.t = VT_VOID;
4030 break;
4032 #endif
4033 /* pre operations */
4034 case TOK_INC:
4035 case TOK_DEC:
4036 t = tok;
4037 next();
4038 unary();
4039 inc(0, t);
4040 break;
4041 case '-':
4042 next();
4043 unary();
4044 t = vtop->type.t & VT_BTYPE;
4045 if (is_float(t)) {
4046 /* In IEEE negate(x) isn't subtract(0,x), but rather
4047 subtract(-0, x). */
4048 vpush(&vtop->type);
4049 if (t == VT_FLOAT)
4050 vtop->c.f = -0.0f;
4051 else if (t == VT_DOUBLE)
4052 vtop->c.d = -0.0;
4053 else
4054 vtop->c.ld = -0.0;
4055 } else
4056 vpushi(0);
4057 vswap();
4058 gen_op('-');
4059 break;
4060 case TOK_LAND:
4061 if (!gnu_ext)
4062 goto tok_identifier;
4063 next();
4064 /* allow to take the address of a label */
4065 if (tok < TOK_UIDENT)
4066 expect("label identifier");
4067 s = label_find(tok);
4068 if (!s) {
4069 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4070 } else {
4071 if (s->r == LABEL_DECLARED)
4072 s->r = LABEL_FORWARD;
4074 if (!s->type.t) {
4075 s->type.t = VT_VOID;
4076 mk_pointer(&s->type);
4077 s->type.t |= VT_STATIC;
4079 vpushsym(&s->type, s);
4080 next();
4081 break;
4083 // special qnan , snan and infinity values
4084 case TOK___NAN__:
4085 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
4086 next();
4087 break;
4088 case TOK___SNAN__:
4089 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
4090 next();
4091 break;
4092 case TOK___INF__:
4093 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
4094 next();
4095 break;
4097 default:
4098 tok_identifier:
4099 t = tok;
4100 next();
4101 if (t < TOK_UIDENT)
4102 expect("identifier");
4103 s = sym_find(t);
4104 if (!s) {
4105 const char *name = get_tok_str(t, NULL);
4106 if (tok != '(')
4107 tcc_error("'%s' undeclared", name);
4108 /* for simple function calls, we tolerate undeclared
4109 external reference to int() function */
4110 if (tcc_state->warn_implicit_function_declaration
4111 #ifdef TCC_TARGET_PE
4112 /* people must be warned about using undeclared WINAPI functions
4113 (which usually start with uppercase letter) */
4114 || (name[0] >= 'A' && name[0] <= 'Z')
4115 #endif
4117 tcc_warning("implicit declaration of function '%s'", name);
4118 s = external_global_sym(t, &func_old_type, 0);
4120 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
4121 (VT_STATIC | VT_INLINE | VT_FUNC)) {
4122 /* if referencing an inline function, then we generate a
4123 symbol to it if not already done. It will have the
4124 effect to generate code for it at the end of the
4125 compilation unit. Inline function as always
4126 generated in the text section. */
4127 if (!s->c)
4128 put_extern_sym(s, text_section, 0, 0);
4129 r = VT_SYM | VT_CONST;
4130 } else {
4131 r = s->r;
4133 vset(&s->type, r, s->c);
4134 /* if forward reference, we must point to s */
4135 if (vtop->r & VT_SYM) {
4136 vtop->sym = s;
4137 vtop->c.ptr_offset = 0;
4139 break;
4142 /* post operations */
4143 while (1) {
4144 if (tok == TOK_INC || tok == TOK_DEC) {
4145 inc(1, tok);
4146 next();
4147 } else if (tok == '.' || tok == TOK_ARROW) {
4148 int qualifiers;
4149 /* field */
4150 if (tok == TOK_ARROW)
4151 indir();
4152 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4153 test_lvalue();
4154 gaddrof();
4155 next();
4156 /* expect pointer on structure */
4157 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4158 expect("struct or union");
4159 s = vtop->type.ref;
4160 /* find field */
4161 tok |= SYM_FIELD;
4162 while ((s = s->next) != NULL) {
4163 if (s->v == tok)
4164 break;
4166 if (!s)
4167 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
4168 /* add field offset to pointer */
4169 vtop->type = char_pointer_type; /* change type to 'char *' */
4170 vpushi(s->c);
4171 gen_op('+');
4172 /* change type to field type, and set to lvalue */
4173 vtop->type = s->type;
4174 vtop->type.t |= qualifiers;
4175 /* an array is never an lvalue */
4176 if (!(vtop->type.t & VT_ARRAY)) {
4177 vtop->r |= lvalue_type(vtop->type.t);
4178 #ifdef CONFIG_TCC_BCHECK
4179 /* if bound checking, the referenced pointer must be checked */
4180 if (tcc_state->do_bounds_check)
4181 vtop->r |= VT_MUSTBOUND;
4182 #endif
4184 next();
4185 } else if (tok == '[') {
4186 next();
4187 gexpr();
4188 gen_op('+');
4189 indir();
4190 skip(']');
4191 } else if (tok == '(') {
4192 SValue ret;
4193 Sym *sa;
4194 int nb_args, ret_nregs, ret_align, regsize, variadic;
4196 /* function call */
4197 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4198 /* pointer test (no array accepted) */
4199 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4200 vtop->type = *pointed_type(&vtop->type);
4201 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4202 goto error_func;
4203 } else {
4204 error_func:
4205 expect("function pointer");
4207 } else {
4208 vtop->r &= ~VT_LVAL; /* no lvalue */
4210 /* get return type */
4211 s = vtop->type.ref;
4212 next();
4213 sa = s->next; /* first parameter */
4214 nb_args = 0;
4215 ret.r2 = VT_CONST;
4216 /* compute first implicit argument if a structure is returned */
4217 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4218 variadic = (s->c == FUNC_ELLIPSIS);
4219 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4220 &ret_align, &regsize);
4221 if (!ret_nregs) {
4222 /* get some space for the returned structure */
4223 size = type_size(&s->type, &align);
4224 #ifdef TCC_TARGET_ARM64
4225 /* On arm64, a small struct is return in registers.
4226 It is much easier to write it to memory if we know
4227 that we are allowed to write some extra bytes, so
4228 round the allocated space up to a power of 2: */
4229 if (size < 16)
4230 while (size & (size - 1))
4231 size = (size | (size - 1)) + 1;
4232 #endif
4233 loc = (loc - size) & -align;
4234 ret.type = s->type;
4235 ret.r = VT_LOCAL | VT_LVAL;
4236 /* pass it as 'int' to avoid structure arg passing
4237 problems */
4238 vseti(VT_LOCAL, loc);
4239 ret.c = vtop->c;
4240 nb_args++;
4242 } else {
4243 ret_nregs = 1;
4244 ret.type = s->type;
4247 if (ret_nregs) {
4248 /* return in register */
4249 if (is_float(ret.type.t)) {
4250 ret.r = reg_fret(ret.type.t);
4251 #ifdef TCC_TARGET_X86_64
4252 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4253 ret.r2 = REG_QRET;
4254 #endif
4255 } else {
4256 #ifndef TCC_TARGET_ARM64
4257 #ifdef TCC_TARGET_X86_64
4258 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4259 #else
4260 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4261 #endif
4262 ret.r2 = REG_LRET;
4263 #endif
4264 ret.r = REG_IRET;
4266 ret.c.i = 0;
4268 if (tok != ')') {
4269 for(;;) {
4270 expr_eq();
4271 gfunc_param_typed(s, sa);
4272 nb_args++;
4273 if (sa)
4274 sa = sa->next;
4275 if (tok == ')')
4276 break;
4277 skip(',');
4280 if (sa)
4281 tcc_error("too few arguments to function");
4282 skip(')');
4283 if (!nocode_wanted) {
4284 gfunc_call(nb_args);
4285 } else {
4286 vtop -= (nb_args + 1);
4289 /* return value */
4290 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4291 vsetc(&ret.type, r, &ret.c);
4292 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4295 /* handle packed struct return */
4296 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4297 int addr, offset;
4299 size = type_size(&s->type, &align);
4300 /* We're writing whole regs often, make sure there's enough
4301 space. Assume register size is power of 2. */
4302 if (regsize > align)
4303 align = regsize;
4304 loc = (loc - size) & -align;
4305 addr = loc;
4306 offset = 0;
4307 for (;;) {
4308 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4309 vswap();
4310 vstore();
4311 vtop--;
4312 if (--ret_nregs == 0)
4313 break;
4314 offset += regsize;
4316 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4318 } else {
4319 break;
4324 ST_FUNC void expr_prod(void)
4326 int t;
4328 unary();
4329 while (tok == '*' || tok == '/' || tok == '%') {
4330 t = tok;
4331 next();
4332 unary();
4333 gen_op(t);
4337 ST_FUNC void expr_sum(void)
4339 int t;
4341 expr_prod();
4342 while (tok == '+' || tok == '-') {
4343 t = tok;
4344 next();
4345 expr_prod();
4346 gen_op(t);
4350 static void expr_shift(void)
4352 int t;
4354 expr_sum();
4355 while (tok == TOK_SHL || tok == TOK_SAR) {
4356 t = tok;
4357 next();
4358 expr_sum();
4359 gen_op(t);
4363 static void expr_cmp(void)
4365 int t;
4367 expr_shift();
4368 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4369 tok == TOK_ULT || tok == TOK_UGE) {
4370 t = tok;
4371 next();
4372 expr_shift();
4373 gen_op(t);
4377 static void expr_cmpeq(void)
4379 int t;
4381 expr_cmp();
4382 while (tok == TOK_EQ || tok == TOK_NE) {
4383 t = tok;
4384 next();
4385 expr_cmp();
4386 gen_op(t);
4390 static void expr_and(void)
4392 expr_cmpeq();
4393 while (tok == '&') {
4394 next();
4395 expr_cmpeq();
4396 gen_op('&');
4400 static void expr_xor(void)
4402 expr_and();
4403 while (tok == '^') {
4404 next();
4405 expr_and();
4406 gen_op('^');
4410 static void expr_or(void)
4412 expr_xor();
4413 while (tok == '|') {
4414 next();
4415 expr_xor();
4416 gen_op('|');
4420 /* XXX: fix this mess */
4421 static void expr_land_const(void)
4423 expr_or();
4424 while (tok == TOK_LAND) {
4425 next();
4426 expr_or();
4427 gen_op(TOK_LAND);
4431 /* XXX: fix this mess */
4432 static void expr_lor_const(void)
4434 expr_land_const();
4435 while (tok == TOK_LOR) {
4436 next();
4437 expr_land_const();
4438 gen_op(TOK_LOR);
4442 /* only used if non constant */
4443 static void expr_land(void)
4445 int t;
4447 expr_or();
4448 if (tok == TOK_LAND) {
4449 t = 0;
4450 save_regs(1);
4451 for(;;) {
4452 t = gvtst(1, t);
4453 if (tok != TOK_LAND) {
4454 vseti(VT_JMPI, t);
4455 break;
4457 next();
4458 expr_or();
4463 static void expr_lor(void)
4465 int t;
4467 expr_land();
4468 if (tok == TOK_LOR) {
4469 t = 0;
4470 save_regs(1);
4471 for(;;) {
4472 t = gvtst(0, t);
4473 if (tok != TOK_LOR) {
4474 vseti(VT_JMP, t);
4475 break;
4477 next();
4478 expr_land();
4483 /* XXX: better constant handling */
4484 static void expr_cond(void)
4486 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4487 SValue sv;
4488 CType type, type1, type2;
4490 if (const_wanted) {
4491 expr_lor_const();
4492 if (tok == '?') {
4493 CType boolean;
4494 int c;
4495 boolean.t = VT_BOOL;
4496 vdup();
4497 gen_cast(&boolean);
4498 c = vtop->c.i;
4499 vpop();
4500 next();
4501 if (tok != ':' || !gnu_ext) {
4502 vpop();
4503 gexpr();
4505 if (!c)
4506 vpop();
4507 skip(':');
4508 expr_cond();
4509 if (c)
4510 vpop();
4512 } else {
4513 expr_lor();
4514 if (tok == '?') {
4515 next();
4516 if (vtop != vstack) {
4517 /* needed to avoid having different registers saved in
4518 each branch */
4519 if (is_float(vtop->type.t)) {
4520 rc = RC_FLOAT;
4521 #ifdef TCC_TARGET_X86_64
4522 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4523 rc = RC_ST0;
4525 #endif
4527 else
4528 rc = RC_INT;
4529 gv(rc);
4530 save_regs(1);
4532 if (tok == ':' && gnu_ext) {
4533 gv_dup();
4534 tt = gvtst(1, 0);
4535 } else {
4536 tt = gvtst(1, 0);
4537 gexpr();
4539 type1 = vtop->type;
4540 sv = *vtop; /* save value to handle it later */
4541 vtop--; /* no vpop so that FP stack is not flushed */
4542 skip(':');
4543 u = gjmp(0);
4544 gsym(tt);
4545 expr_cond();
4546 type2 = vtop->type;
4548 t1 = type1.t;
4549 bt1 = t1 & VT_BTYPE;
4550 t2 = type2.t;
4551 bt2 = t2 & VT_BTYPE;
4552 /* cast operands to correct type according to ISOC rules */
4553 if (is_float(bt1) || is_float(bt2)) {
4554 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4555 type.t = VT_LDOUBLE;
4556 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4557 type.t = VT_DOUBLE;
4558 } else {
4559 type.t = VT_FLOAT;
4561 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4562 /* cast to biggest op */
4563 type.t = VT_LLONG;
4564 /* convert to unsigned if it does not fit in a long long */
4565 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4566 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4567 type.t |= VT_UNSIGNED;
4568 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4569 /* If one is a null ptr constant the result type
4570 is the other. */
4571 if (is_null_pointer (vtop))
4572 type = type1;
4573 else if (is_null_pointer (&sv))
4574 type = type2;
4575 /* XXX: test pointer compatibility, C99 has more elaborate
4576 rules here. */
4577 else
4578 type = type1;
4579 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4580 /* XXX: test function pointer compatibility */
4581 type = bt1 == VT_FUNC ? type1 : type2;
4582 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4583 /* XXX: test structure compatibility */
4584 type = bt1 == VT_STRUCT ? type1 : type2;
4585 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4586 /* NOTE: as an extension, we accept void on only one side */
4587 type.t = VT_VOID;
4588 } else {
4589 /* integer operations */
4590 type.t = VT_INT;
4591 /* convert to unsigned if it does not fit in an integer */
4592 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4593 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4594 type.t |= VT_UNSIGNED;
4597 /* now we convert second operand */
4598 gen_cast(&type);
4599 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4600 gaddrof();
4601 rc = RC_INT;
4602 if (is_float(type.t)) {
4603 rc = RC_FLOAT;
4604 #ifdef TCC_TARGET_X86_64
4605 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4606 rc = RC_ST0;
4608 #endif
4609 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4610 /* for long longs, we use fixed registers to avoid having
4611 to handle a complicated move */
4612 rc = RC_IRET;
4615 r2 = gv(rc);
4616 /* this is horrible, but we must also convert first
4617 operand */
4618 tt = gjmp(0);
4619 gsym(u);
4620 /* put again first value and cast it */
4621 *vtop = sv;
4622 gen_cast(&type);
4623 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4624 gaddrof();
4625 r1 = gv(rc);
4626 move_reg(r2, r1, type.t);
4627 vtop->r = r2;
4628 gsym(tt);
4633 static void expr_eq(void)
4635 int t;
4637 expr_cond();
4638 if (tok == '=' ||
4639 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4640 tok == TOK_A_XOR || tok == TOK_A_OR ||
4641 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4642 test_lvalue();
4643 t = tok;
4644 next();
4645 if (t == '=') {
4646 expr_eq();
4647 } else {
4648 vdup();
4649 expr_eq();
4650 gen_op(t & 0x7f);
4652 vstore();
4656 ST_FUNC void gexpr(void)
4658 while (1) {
4659 expr_eq();
4660 if (tok != ',')
4661 break;
4662 vpop();
4663 next();
4667 /* parse an expression and return its type without any side effect. */
4668 static void expr_type(CType *type)
4670 int saved_nocode_wanted;
4672 saved_nocode_wanted = nocode_wanted;
4673 nocode_wanted = 1;
4674 gexpr();
4675 *type = vtop->type;
4676 vpop();
4677 nocode_wanted = saved_nocode_wanted;
4680 /* parse a unary expression and return its type without any side
4681 effect. */
4682 static void unary_type(CType *type)
4684 int a;
4686 a = nocode_wanted;
4687 nocode_wanted = 1;
4688 unary();
4689 *type = vtop->type;
4690 vpop();
4691 nocode_wanted = a;
4694 /* parse a constant expression and return value in vtop. */
4695 static void expr_const1(void)
4697 int a;
4698 a = const_wanted;
4699 const_wanted = 1;
4700 expr_cond();
4701 const_wanted = a;
4704 /* parse an integer constant and return its value. */
4705 ST_FUNC int expr_const(void)
4707 int c;
4708 expr_const1();
4709 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4710 expect("constant expression");
4711 c = vtop->c.i;
4712 vpop();
4713 return c;
4716 /* return the label token if current token is a label, otherwise
4717 return zero */
4718 static int is_label(void)
4720 int last_tok;
4722 /* fast test first */
4723 if (tok < TOK_UIDENT)
4724 return 0;
4725 /* no need to save tokc because tok is an identifier */
4726 last_tok = tok;
4727 next();
4728 if (tok == ':') {
4729 next();
4730 return last_tok;
4731 } else {
4732 unget_tok(last_tok);
4733 return 0;
4737 static void label_or_decl(int l)
4739 int last_tok;
4741 /* fast test first */
4742 if (tok >= TOK_UIDENT)
4744 /* no need to save tokc because tok is an identifier */
4745 last_tok = tok;
4746 next();
4747 if (tok == ':') {
4748 unget_tok(last_tok);
4749 return;
4751 unget_tok(last_tok);
4753 decl(l);
4756 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4757 int case_reg, int is_expr)
4759 int a, b, c, d;
4760 Sym *s, *frame_bottom;
4762 /* generate line number info */
4763 if (tcc_state->do_debug &&
4764 (last_line_num != file->line_num || last_ind != ind)) {
4765 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4766 last_ind = ind;
4767 last_line_num = file->line_num;
4770 if (is_expr) {
4771 /* default return value is (void) */
4772 vpushi(0);
4773 vtop->type.t = VT_VOID;
4776 if (tok == TOK_IF) {
4777 /* if test */
4778 next();
4779 skip('(');
4780 gexpr();
4781 skip(')');
4782 a = gvtst(1, 0);
4783 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4784 c = tok;
4785 if (c == TOK_ELSE) {
4786 next();
4787 d = gjmp(0);
4788 gsym(a);
4789 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4790 gsym(d); /* patch else jmp */
4791 } else
4792 gsym(a);
4793 } else if (tok == TOK_WHILE) {
4794 next();
4795 d = ind;
4796 skip('(');
4797 gexpr();
4798 skip(')');
4799 a = gvtst(1, 0);
4800 b = 0;
4801 block(&a, &b, case_sym, def_sym, case_reg, 0);
4802 gjmp_addr(d);
4803 gsym(a);
4804 gsym_addr(b, d);
4805 } else if (tok == '{') {
4806 Sym *llabel;
4807 int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
4809 next();
4810 /* record local declaration stack position */
4811 s = local_stack;
4812 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4813 frame_bottom->next = scope_stack_bottom;
4814 scope_stack_bottom = frame_bottom;
4815 llabel = local_label_stack;
4817 /* save VLA state */
4818 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4819 if (saved_vla_sp_loc != &vla_sp_root_loc)
4820 vla_sp_loc = &block_vla_sp_loc;
4822 saved_vla_flags = vla_flags;
4823 vla_flags |= VLA_NEED_NEW_FRAME;
4825 /* handle local labels declarations */
4826 if (tok == TOK_LABEL) {
4827 next();
4828 for(;;) {
4829 if (tok < TOK_UIDENT)
4830 expect("label identifier");
4831 label_push(&local_label_stack, tok, LABEL_DECLARED);
4832 next();
4833 if (tok == ',') {
4834 next();
4835 } else {
4836 skip(';');
4837 break;
4841 while (tok != '}') {
4842 label_or_decl(VT_LOCAL);
4843 if (tok != '}') {
4844 if (is_expr)
4845 vpop();
4846 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4849 /* pop locally defined labels */
4850 label_pop(&local_label_stack, llabel);
4851 if(is_expr) {
4852 /* XXX: this solution makes only valgrind happy...
4853 triggered by gcc.c-torture/execute/20000917-1.c */
4854 Sym *p;
4855 switch(vtop->type.t & VT_BTYPE) {
4856 /* case VT_PTR: */
4857 /* this breaks a compilation of the linux kernel v2.4.26 */
4858 /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
4859 /* Look a commit a80acab: Display error on statement expressions with complex return type */
4860 /* A pointer is not a complex return type */
4861 case VT_STRUCT:
4862 case VT_ENUM:
4863 case VT_FUNC:
4864 for(p=vtop->type.ref;p;p=p->prev)
4865 if(p->prev==s)
4866 tcc_error("unsupported expression type");
4869 /* pop locally defined symbols */
4870 scope_stack_bottom = scope_stack_bottom->next;
4871 sym_pop(&local_stack, s);
4873 /* Pop VLA frames and restore stack pointer if required */
4874 if (saved_vla_sp_loc != &vla_sp_root_loc)
4875 *saved_vla_sp_loc = block_vla_sp_loc;
4876 if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
4877 vla_sp_loc = saved_vla_sp_loc;
4878 gen_vla_sp_restore(*vla_sp_loc);
4880 vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
4882 next();
4883 } else if (tok == TOK_RETURN) {
4884 next();
4885 if (tok != ';') {
4886 gexpr();
4887 gen_assign_cast(&func_vt);
4888 #ifdef TCC_TARGET_ARM64
4889 // Perhaps it would be better to use this for all backends:
4890 greturn();
4891 #else
4892 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4893 CType type, ret_type;
4894 int ret_align, ret_nregs, regsize;
4895 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
4896 &ret_align, &regsize);
4897 if (0 == ret_nregs) {
4898 /* if returning structure, must copy it to implicit
4899 first pointer arg location */
4900 type = func_vt;
4901 mk_pointer(&type);
4902 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4903 indir();
4904 vswap();
4905 /* copy structure value to pointer */
4906 vstore();
4907 } else {
4908 /* returning structure packed into registers */
4909 int r, size, addr, align;
4910 size = type_size(&func_vt,&align);
4911 if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))
4912 && (align & (ret_align-1))) {
4913 loc = (loc - size) & -align;
4914 addr = loc;
4915 type = func_vt;
4916 vset(&type, VT_LOCAL | VT_LVAL, addr);
4917 vswap();
4918 vstore();
4919 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
4921 vtop->type = ret_type;
4922 if (is_float(ret_type.t))
4923 r = rc_fret(ret_type.t);
4924 else
4925 r = RC_IRET;
4927 for (;;) {
4928 gv(r);
4929 if (--ret_nregs == 0)
4930 break;
4931 /* We assume that when a structure is returned in multiple
4932 registers, their classes are consecutive values of the
4933 suite s(n) = 2^n */
4934 r <<= 1;
4935 vtop->c.i += regsize;
4936 vtop->r = VT_LOCAL | VT_LVAL;
4939 } else if (is_float(func_vt.t)) {
4940 gv(rc_fret(func_vt.t));
4941 } else {
4942 gv(RC_IRET);
4944 #endif
4945 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4947 skip(';');
4948 rsym = gjmp(rsym); /* jmp */
4949 } else if (tok == TOK_BREAK) {
4950 /* compute jump */
4951 if (!bsym)
4952 tcc_error("cannot break");
4953 *bsym = gjmp(*bsym);
4954 next();
4955 skip(';');
4956 } else if (tok == TOK_CONTINUE) {
4957 /* compute jump */
4958 if (!csym)
4959 tcc_error("cannot continue");
4960 *csym = gjmp(*csym);
4961 next();
4962 skip(';');
4963 } else if (tok == TOK_FOR) {
4964 int e;
4965 next();
4966 skip('(');
4967 s = local_stack;
4968 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4969 frame_bottom->next = scope_stack_bottom;
4970 scope_stack_bottom = frame_bottom;
4971 if (tok != ';') {
4972 /* c99 for-loop init decl? */
4973 if (!decl0(VT_LOCAL, 1)) {
4974 /* no, regular for-loop init expr */
4975 gexpr();
4976 vpop();
4979 skip(';');
4980 d = ind;
4981 c = ind;
4982 a = 0;
4983 b = 0;
4984 if (tok != ';') {
4985 gexpr();
4986 a = gvtst(1, 0);
4988 skip(';');
4989 if (tok != ')') {
4990 e = gjmp(0);
4991 c = ind;
4992 gexpr();
4993 vpop();
4994 gjmp_addr(d);
4995 gsym(e);
4997 skip(')');
4998 block(&a, &b, case_sym, def_sym, case_reg, 0);
4999 gjmp_addr(c);
5000 gsym(a);
5001 gsym_addr(b, c);
5002 scope_stack_bottom = scope_stack_bottom->next;
5003 sym_pop(&local_stack, s);
5004 } else
5005 if (tok == TOK_DO) {
5006 next();
5007 a = 0;
5008 b = 0;
5009 d = ind;
5010 block(&a, &b, case_sym, def_sym, case_reg, 0);
5011 skip(TOK_WHILE);
5012 skip('(');
5013 gsym(b);
5014 gexpr();
5015 c = gvtst(0, 0);
5016 gsym_addr(c, d);
5017 skip(')');
5018 gsym(a);
5019 skip(';');
5020 } else
5021 if (tok == TOK_SWITCH) {
5022 next();
5023 skip('(');
5024 gexpr();
5025 /* XXX: other types than integer */
5026 case_reg = gv(RC_INT);
5027 vpop();
5028 skip(')');
5029 a = 0;
5030 b = gjmp(0); /* jump to first case */
5031 c = 0;
5032 block(&a, csym, &b, &c, case_reg, 0);
5033 /* if no default, jmp after switch */
5034 if (c == 0)
5035 c = ind;
5036 /* default label */
5037 gsym_addr(b, c);
5038 /* break label */
5039 gsym(a);
5040 } else
5041 if (tok == TOK_CASE) {
5042 int v1, v2;
5043 if (!case_sym)
5044 expect("switch");
5045 next();
5046 v1 = expr_const();
5047 v2 = v1;
5048 if (gnu_ext && tok == TOK_DOTS) {
5049 next();
5050 v2 = expr_const();
5051 if (v2 < v1)
5052 tcc_warning("empty case range");
5054 /* since a case is like a label, we must skip it with a jmp */
5055 b = gjmp(0);
5056 gsym(*case_sym);
5057 vseti(case_reg, 0);
5058 vdup();
5059 vpushi(v1);
5060 if (v1 == v2) {
5061 gen_op(TOK_EQ);
5062 *case_sym = gtst(1, 0);
5063 } else {
5064 gen_op(TOK_GE);
5065 *case_sym = gtst(1, 0);
5066 vseti(case_reg, 0);
5067 vpushi(v2);
5068 gen_op(TOK_LE);
5069 *case_sym = gtst(1, *case_sym);
5071 case_reg = gv(RC_INT);
5072 vpop();
5073 gsym(b);
5074 skip(':');
5075 is_expr = 0;
5076 goto block_after_label;
5077 } else
5078 if (tok == TOK_DEFAULT) {
5079 next();
5080 skip(':');
5081 if (!def_sym)
5082 expect("switch");
5083 if (*def_sym)
5084 tcc_error("too many 'default'");
5085 *def_sym = ind;
5086 is_expr = 0;
5087 goto block_after_label;
5088 } else
5089 if (tok == TOK_GOTO) {
5090 next();
5091 if (tok == '*' && gnu_ext) {
5092 /* computed goto */
5093 next();
5094 gexpr();
5095 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5096 expect("pointer");
5097 ggoto();
5098 } else if (tok >= TOK_UIDENT) {
5099 s = label_find(tok);
5100 /* put forward definition if needed */
5101 if (!s) {
5102 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5103 } else {
5104 if (s->r == LABEL_DECLARED)
5105 s->r = LABEL_FORWARD;
5107 /* label already defined */
5108 if (vla_flags & VLA_IN_SCOPE) {
5109 /* If VLAs are in use, save the current stack pointer and
5110 reset the stack pointer to what it was at function entry
5111 (label will restore stack pointer in inner scopes) */
5112 vla_sp_save();
5113 gen_vla_sp_restore(vla_sp_root_loc);
5115 if (s->r & LABEL_FORWARD)
5116 s->jnext = gjmp(s->jnext);
5117 else
5118 gjmp_addr(s->jnext);
5119 next();
5120 } else {
5121 expect("label identifier");
5123 skip(';');
5124 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
5125 asm_instr();
5126 } else {
5127 b = is_label();
5128 if (b) {
5129 /* label case */
5130 if (vla_flags & VLA_IN_SCOPE) {
5131 /* save/restore stack pointer across label
5132 this is a no-op when combined with the load immediately
5133 after the label unless we arrive via goto */
5134 vla_sp_save();
5136 s = label_find(b);
5137 if (s) {
5138 if (s->r == LABEL_DEFINED)
5139 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
5140 gsym(s->jnext);
5141 s->r = LABEL_DEFINED;
5142 } else {
5143 s = label_push(&global_label_stack, b, LABEL_DEFINED);
5145 s->jnext = ind;
5146 if (vla_flags & VLA_IN_SCOPE) {
5147 gen_vla_sp_restore(*vla_sp_loc);
5148 vla_flags |= VLA_NEED_NEW_FRAME;
5150 /* we accept this, but it is a mistake */
5151 block_after_label:
5152 if (tok == '}') {
5153 tcc_warning("deprecated use of label at end of compound statement");
5154 } else {
5155 if (is_expr)
5156 vpop();
5157 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
5159 } else {
5160 /* expression case */
5161 if (tok != ';') {
5162 if (is_expr) {
5163 vpop();
5164 gexpr();
5165 } else {
5166 gexpr();
5167 vpop();
5170 skip(';');
5175 /* t is the array or struct type. c is the array or struct
5176 address. cur_index/cur_field is the pointer to the current
5177 value. 'size_only' is true if only size info is needed (only used
5178 in arrays) */
5179 static void decl_designator(CType *type, Section *sec, unsigned long c,
5180 int *cur_index, Sym **cur_field,
5181 int size_only)
5183 Sym *s, *f;
5184 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5185 CType type1;
5187 notfirst = 0;
5188 elem_size = 0;
5189 nb_elems = 1;
5190 if (gnu_ext && (l = is_label()) != 0)
5191 goto struct_field;
5192 while (tok == '[' || tok == '.') {
5193 if (tok == '[') {
5194 if (!(type->t & VT_ARRAY))
5195 expect("array type");
5196 s = type->ref;
5197 next();
5198 index = expr_const();
5199 if (index < 0 || (s->c >= 0 && index >= s->c))
5200 expect("invalid index");
5201 if (tok == TOK_DOTS && gnu_ext) {
5202 next();
5203 index_last = expr_const();
5204 if (index_last < 0 ||
5205 (s->c >= 0 && index_last >= s->c) ||
5206 index_last < index)
5207 expect("invalid index");
5208 } else {
5209 index_last = index;
5211 skip(']');
5212 if (!notfirst)
5213 *cur_index = index_last;
5214 type = pointed_type(type);
5215 elem_size = type_size(type, &align);
5216 c += index * elem_size;
5217 /* NOTE: we only support ranges for last designator */
5218 nb_elems = index_last - index + 1;
5219 if (nb_elems != 1) {
5220 notfirst = 1;
5221 break;
5223 } else {
5224 next();
5225 l = tok;
5226 next();
5227 struct_field:
5228 if ((type->t & VT_BTYPE) != VT_STRUCT)
5229 expect("struct/union type");
5230 s = type->ref;
5231 l |= SYM_FIELD;
5232 f = s->next;
5233 while (f) {
5234 if (f->v == l)
5235 break;
5236 f = f->next;
5238 if (!f)
5239 expect("field");
5240 if (!notfirst)
5241 *cur_field = f;
5242 /* XXX: fix this mess by using explicit storage field */
5243 type1 = f->type;
5244 type1.t |= (type->t & ~VT_TYPE);
5245 type = &type1;
5246 c += f->c;
5248 notfirst = 1;
5250 if (notfirst) {
5251 if (tok == '=') {
5252 next();
5253 } else {
5254 if (!gnu_ext)
5255 expect("=");
5257 } else {
5258 if (type->t & VT_ARRAY) {
5259 index = *cur_index;
5260 type = pointed_type(type);
5261 c += index * type_size(type, &align);
5262 } else {
5263 f = *cur_field;
5264 if (!f)
5265 tcc_error("too many field init");
5266 /* XXX: fix this mess by using explicit storage field */
5267 type1 = f->type;
5268 type1.t |= (type->t & ~VT_TYPE);
5269 type = &type1;
5270 c += f->c;
5273 decl_initializer(type, sec, c, 0, size_only);
5275 /* XXX: make it more general */
5276 if (!size_only && nb_elems > 1) {
5277 unsigned long c_end;
5278 uint8_t *src, *dst;
5279 int i;
5281 if (!sec)
5282 tcc_error("range init not supported yet for dynamic storage");
5283 c_end = c + nb_elems * elem_size;
5284 if (c_end > sec->data_allocated)
5285 section_realloc(sec, c_end);
5286 src = sec->data + c;
5287 dst = src;
5288 for(i = 1; i < nb_elems; i++) {
5289 dst += elem_size;
5290 memcpy(dst, src, elem_size);
5295 #define EXPR_VAL 0
5296 #define EXPR_CONST 1
5297 #define EXPR_ANY 2
5299 /* store a value or an expression directly in global data or in local array */
5300 static void init_putv(CType *type, Section *sec, unsigned long c,
5301 int v, int expr_type)
5303 int saved_global_expr, bt, bit_pos, bit_size;
5304 void *ptr;
5305 unsigned long long bit_mask;
5306 CType dtype;
5308 switch(expr_type) {
5309 case EXPR_VAL:
5310 vpushi(v);
5311 break;
5312 case EXPR_CONST:
5313 /* compound literals must be allocated globally in this case */
5314 saved_global_expr = global_expr;
5315 global_expr = 1;
5316 expr_const1();
5317 global_expr = saved_global_expr;
5318 /* NOTE: symbols are accepted */
5319 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5320 tcc_error("initializer element is not constant");
5321 break;
5322 case EXPR_ANY:
5323 expr_eq();
5324 break;
5327 dtype = *type;
5328 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5330 if (sec) {
5331 /* XXX: not portable */
5332 /* XXX: generate error if incorrect relocation */
5333 gen_assign_cast(&dtype);
5334 bt = type->t & VT_BTYPE;
5335 /* we'll write at most 16 bytes */
5336 if (c + 16 > sec->data_allocated) {
5337 section_realloc(sec, c + 16);
5339 ptr = sec->data + c;
5340 /* XXX: make code faster ? */
5341 if (!(type->t & VT_BITFIELD)) {
5342 bit_pos = 0;
5343 bit_size = 32;
5344 bit_mask = -1LL;
5345 } else {
5346 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5347 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5348 bit_mask = (1LL << bit_size) - 1;
5350 if ((vtop->r & VT_SYM) &&
5351 (bt == VT_BYTE ||
5352 bt == VT_SHORT ||
5353 bt == VT_DOUBLE ||
5354 bt == VT_LDOUBLE ||
5355 bt == VT_LLONG ||
5356 (bt == VT_INT && bit_size != 32)))
5357 tcc_error("initializer element is not computable at load time");
5358 switch(bt) {
5359 /* XXX: when cross-compiling we assume that each type has the
5360 same representation on host and target, which is likely to
5361 be wrong in the case of long double */
5362 case VT_BOOL:
5363 vtop->c.i = (vtop->c.i != 0);
5364 case VT_BYTE:
5365 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5366 break;
5367 case VT_SHORT:
5368 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5369 break;
5370 case VT_DOUBLE:
5371 *(double *)ptr = vtop->c.d;
5372 break;
5373 case VT_LDOUBLE:
5374 *(long double *)ptr = vtop->c.ld;
5375 break;
5376 case VT_LLONG:
5377 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
5378 break;
5379 case VT_PTR: {
5380 addr_t val = (vtop->c.ptr_offset & bit_mask) << bit_pos;
5381 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5382 if (vtop->r & VT_SYM)
5383 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5384 else
5385 *(addr_t *)ptr |= val;
5386 #else
5387 if (vtop->r & VT_SYM)
5388 greloc(sec, vtop->sym, c, R_DATA_PTR);
5389 *(addr_t *)ptr |= val;
5390 #endif
5391 break;
5393 default: {
5394 int val = (vtop->c.i & bit_mask) << bit_pos;
5395 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5396 if (vtop->r & VT_SYM)
5397 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5398 else
5399 *(int *)ptr |= val;
5400 #else
5401 if (vtop->r & VT_SYM)
5402 greloc(sec, vtop->sym, c, R_DATA_PTR);
5403 *(int *)ptr |= val;
5404 #endif
5405 break;
5408 vtop--;
5409 } else {
5410 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5411 vswap();
5412 vstore();
5413 vpop();
5417 /* put zeros for variable based init */
5418 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5420 if (sec) {
5421 /* nothing to do because globals are already set to zero */
5422 } else {
5423 vpush_global_sym(&func_old_type, TOK_memset);
5424 vseti(VT_LOCAL, c);
5425 #ifdef TCC_TARGET_ARM
5426 vpushs(size);
5427 vpushi(0);
5428 #else
5429 vpushi(0);
5430 vpushs(size);
5431 #endif
5432 gfunc_call(3);
5436 /* 't' contains the type and storage info. 'c' is the offset of the
5437 object in section 'sec'. If 'sec' is NULL, it means stack based
5438 allocation. 'first' is true if array '{' must be read (multi
5439 dimension implicit array init handling). 'size_only' is true if
5440 size only evaluation is wanted (only for arrays). */
5441 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5442 int first, int size_only)
5444 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5445 int size1, align1, expr_type;
5446 Sym *s, *f;
5447 CType *t1;
5449 if (type->t & VT_VLA) {
5450 int a;
5452 /* save current stack pointer */
5453 if (vla_flags & VLA_NEED_NEW_FRAME) {
5454 vla_sp_save();
5455 vla_flags = VLA_IN_SCOPE;
5456 vla_sp_loc = &vla_sp_loc_tmp;
5459 vla_runtime_type_size(type, &a);
5460 gen_vla_alloc(type, a);
5461 vset(type, VT_LOCAL|VT_LVAL, c);
5462 vswap();
5463 vstore();
5464 vpop();
5465 } else if (type->t & VT_ARRAY) {
5466 s = type->ref;
5467 n = s->c;
5468 array_length = 0;
5469 t1 = pointed_type(type);
5470 size1 = type_size(t1, &align1);
5472 no_oblock = 1;
5473 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5474 tok == '{') {
5475 if (tok != '{')
5476 tcc_error("character array initializer must be a literal,"
5477 " optionally enclosed in braces");
5478 skip('{');
5479 no_oblock = 0;
5482 /* only parse strings here if correct type (otherwise: handle
5483 them as ((w)char *) expressions */
5484 if ((tok == TOK_LSTR &&
5485 #ifdef TCC_TARGET_PE
5486 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5487 #else
5488 (t1->t & VT_BTYPE) == VT_INT
5489 #endif
5490 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5491 while (tok == TOK_STR || tok == TOK_LSTR) {
5492 int cstr_len, ch;
5493 CString *cstr;
5495 cstr = tokc.cstr;
5496 /* compute maximum number of chars wanted */
5497 if (tok == TOK_STR)
5498 cstr_len = cstr->size;
5499 else
5500 cstr_len = cstr->size / sizeof(nwchar_t);
5501 cstr_len--;
5502 nb = cstr_len;
5503 if (n >= 0 && nb > (n - array_length))
5504 nb = n - array_length;
5505 if (!size_only) {
5506 if (cstr_len > nb)
5507 tcc_warning("initializer-string for array is too long");
5508 /* in order to go faster for common case (char
5509 string in global variable, we handle it
5510 specifically */
5511 if (sec && tok == TOK_STR && size1 == 1) {
5512 memcpy(sec->data + c + array_length, cstr->data, nb);
5513 } else {
5514 for(i=0;i<nb;i++) {
5515 if (tok == TOK_STR)
5516 ch = ((unsigned char *)cstr->data)[i];
5517 else
5518 ch = ((nwchar_t *)cstr->data)[i];
5519 init_putv(t1, sec, c + (array_length + i) * size1,
5520 ch, EXPR_VAL);
5524 array_length += nb;
5525 next();
5527 /* only add trailing zero if enough storage (no
5528 warning in this case since it is standard) */
5529 if (n < 0 || array_length < n) {
5530 if (!size_only) {
5531 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5533 array_length++;
5535 } else {
5536 index = 0;
5537 while (tok != '}') {
5538 decl_designator(type, sec, c, &index, NULL, size_only);
5539 if (n >= 0 && index >= n)
5540 tcc_error("index too large");
5541 /* must put zero in holes (note that doing it that way
5542 ensures that it even works with designators) */
5543 if (!size_only && array_length < index) {
5544 init_putz(t1, sec, c + array_length * size1,
5545 (index - array_length) * size1);
5547 index++;
5548 if (index > array_length)
5549 array_length = index;
5550 /* special test for multi dimensional arrays (may not
5551 be strictly correct if designators are used at the
5552 same time) */
5553 if (index >= n && no_oblock)
5554 break;
5555 if (tok == '}')
5556 break;
5557 skip(',');
5560 if (!no_oblock)
5561 skip('}');
5562 /* put zeros at the end */
5563 if (!size_only && n >= 0 && array_length < n) {
5564 init_putz(t1, sec, c + array_length * size1,
5565 (n - array_length) * size1);
5567 /* patch type size if needed */
5568 if (n < 0)
5569 s->c = array_length;
5570 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5571 (sec || !first || tok == '{')) {
5573 /* NOTE: the previous test is a specific case for automatic
5574 struct/union init */
5575 /* XXX: union needs only one init */
5577 int par_count = 0;
5578 if (tok == '(') {
5579 AttributeDef ad1;
5580 CType type1;
5581 next();
5582 if (tcc_state->old_struct_init_code) {
5583 /* an old version of struct initialization.
5584 It have a problems. But with a new version
5585 linux 2.4.26 can't load ramdisk.
5587 while (tok == '(') {
5588 par_count++;
5589 next();
5591 if (!parse_btype(&type1, &ad1))
5592 expect("cast");
5593 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5594 #if 0
5595 if (!is_assignable_types(type, &type1))
5596 tcc_error("invalid type for cast");
5597 #endif
5598 skip(')');
5600 else
5602 if (tok != '(') {
5603 if (!parse_btype(&type1, &ad1))
5604 expect("cast");
5605 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5606 #if 0
5607 if (!is_assignable_types(type, &type1))
5608 tcc_error("invalid type for cast");
5609 #endif
5610 skip(')');
5611 } else
5612 unget_tok(tok);
5616 no_oblock = 1;
5617 if (first || tok == '{') {
5618 skip('{');
5619 no_oblock = 0;
5621 s = type->ref;
5622 f = s->next;
5623 array_length = 0;
5624 index = 0;
5625 n = s->c;
5626 while (tok != '}') {
5627 decl_designator(type, sec, c, NULL, &f, size_only);
5628 index = f->c;
5629 if (!size_only && array_length < index) {
5630 init_putz(type, sec, c + array_length,
5631 index - array_length);
5633 index = index + type_size(&f->type, &align1);
5634 if (index > array_length)
5635 array_length = index;
5637 /* gr: skip fields from same union - ugly. */
5638 while (f->next) {
5639 int align = 0;
5640 int f_size = type_size(&f->type, &align);
5641 int f_type = (f->type.t & VT_BTYPE);
5643 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5644 /* test for same offset */
5645 if (f->next->c != f->c)
5646 break;
5647 if ((f_type == VT_STRUCT) && (f_size == 0)) {
5649 Lets assume a structure of size 0 can't be a member of the union.
5650 This allow to compile the following code from a linux kernel v2.4.26
5651 typedef struct { } rwlock_t;
5652 struct fs_struct {
5653 int count;
5654 rwlock_t lock;
5655 int umask;
5657 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
5658 tcc-0.9.23 can succesfully compile this version of the kernel.
5659 gcc don't have problems with this code too.
5661 break;
5663 /* if yes, test for bitfield shift */
5664 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5665 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5666 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5667 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5668 if (bit_pos_1 != bit_pos_2)
5669 break;
5671 f = f->next;
5674 f = f->next;
5675 if (no_oblock && f == NULL)
5676 break;
5677 if (tok == '}')
5678 break;
5679 skip(',');
5681 /* put zeros at the end */
5682 if (!size_only && array_length < n) {
5683 init_putz(type, sec, c + array_length,
5684 n - array_length);
5686 if (!no_oblock)
5687 skip('}');
5688 while (par_count) {
5689 skip(')');
5690 par_count--;
5692 } else if (tok == '{') {
5693 next();
5694 decl_initializer(type, sec, c, first, size_only);
5695 skip('}');
5696 } else if (size_only) {
5697 /* just skip expression */
5698 parlevel = parlevel1 = 0;
5699 while ((parlevel > 0 || parlevel1 > 0 ||
5700 (tok != '}' && tok != ',')) && tok != -1) {
5701 if (tok == '(')
5702 parlevel++;
5703 else if (tok == ')') {
5704 if (parlevel == 0 && parlevel1 == 0)
5705 break;
5706 parlevel--;
5708 else if (tok == '{')
5709 parlevel1++;
5710 else if (tok == '}') {
5711 if (parlevel == 0 && parlevel1 == 0)
5712 break;
5713 parlevel1--;
5715 next();
5717 } else {
5718 /* currently, we always use constant expression for globals
5719 (may change for scripting case) */
5720 expr_type = EXPR_CONST;
5721 if (!sec)
5722 expr_type = EXPR_ANY;
5723 init_putv(type, sec, c, 0, expr_type);
5727 /* parse an initializer for type 't' if 'has_init' is non zero, and
5728 allocate space in local or global data space ('r' is either
5729 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5730 variable 'v' with an associated name represented by 'asm_label' of
5731 scope 'scope' is declared before initializers are parsed. If 'v' is
5732 zero, then a reference to the new object is put in the value stack.
5733 If 'has_init' is 2, a special parsing is done to handle string
5734 constants. */
5735 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5736 int has_init, int v, char *asm_label,
5737 int scope)
5739 int size, align, addr, data_offset;
5740 int level;
5741 ParseState saved_parse_state = {0};
5742 TokenString init_str;
5743 Section *sec;
5744 Sym *flexible_array;
5746 flexible_array = NULL;
5747 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5748 Sym *field = type->ref->next;
5749 if (field) {
5750 while (field->next)
5751 field = field->next;
5752 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5753 flexible_array = field;
5757 size = type_size(type, &align);
5758 /* If unknown size, we must evaluate it before
5759 evaluating initializers because
5760 initializers can generate global data too
5761 (e.g. string pointers or ISOC99 compound
5762 literals). It also simplifies local
5763 initializers handling */
5764 tok_str_new(&init_str);
5765 if (size < 0 || (flexible_array && has_init)) {
5766 if (!has_init)
5767 tcc_error("unknown type size");
5768 /* get all init string */
5769 if (has_init == 2) {
5770 /* only get strings */
5771 while (tok == TOK_STR || tok == TOK_LSTR) {
5772 tok_str_add_tok(&init_str);
5773 next();
5775 } else {
5776 level = 0;
5777 while (level > 0 || (tok != ',' && tok != ';')) {
5778 if (tok < 0)
5779 tcc_error("unexpected end of file in initializer");
5780 tok_str_add_tok(&init_str);
5781 if (tok == '{')
5782 level++;
5783 else if (tok == '}') {
5784 level--;
5785 if (level <= 0) {
5786 next();
5787 break;
5790 next();
5793 tok_str_add(&init_str, -1);
5794 tok_str_add(&init_str, 0);
5796 /* compute size */
5797 save_parse_state(&saved_parse_state);
5799 macro_ptr = init_str.str;
5800 next();
5801 decl_initializer(type, NULL, 0, 1, 1);
5802 /* prepare second initializer parsing */
5803 macro_ptr = init_str.str;
5804 next();
5806 /* if still unknown size, error */
5807 size = type_size(type, &align);
5808 if (size < 0)
5809 tcc_error("unknown type size");
5811 if (flexible_array)
5812 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5813 /* take into account specified alignment if bigger */
5814 if (ad->a.aligned) {
5815 if (ad->a.aligned > align)
5816 align = ad->a.aligned;
5817 } else if (ad->a.packed) {
5818 align = 1;
5820 if ((r & VT_VALMASK) == VT_LOCAL) {
5821 sec = NULL;
5822 #ifdef CONFIG_TCC_BCHECK
5823 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5824 loc--;
5826 #endif
5827 loc = (loc - size) & -align;
5828 addr = loc;
5829 #ifdef CONFIG_TCC_BCHECK
5830 /* handles bounds */
5831 /* XXX: currently, since we do only one pass, we cannot track
5832 '&' operators, so we add only arrays */
5833 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5834 addr_t *bounds_ptr;
5835 /* add padding between regions */
5836 loc--;
5837 /* then add local bound info */
5838 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
5839 bounds_ptr[0] = addr;
5840 bounds_ptr[1] = size;
5842 #endif
5843 if (v) {
5844 /* local variable */
5845 sym_push(v, type, r, addr);
5846 } else {
5847 /* push local reference */
5848 vset(type, r, addr);
5850 } else {
5851 Sym *sym;
5853 sym = NULL;
5854 if (v && scope == VT_CONST) {
5855 /* see if the symbol was already defined */
5856 sym = sym_find(v);
5857 if (sym) {
5858 if (!is_compatible_types(&sym->type, type))
5859 tcc_error("incompatible types for redefinition of '%s'",
5860 get_tok_str(v, NULL));
5861 if (sym->type.t & VT_EXTERN) {
5862 /* if the variable is extern, it was not allocated */
5863 sym->type.t &= ~VT_EXTERN;
5864 /* set array size if it was omitted in extern
5865 declaration */
5866 if ((sym->type.t & VT_ARRAY) &&
5867 sym->type.ref->c < 0 &&
5868 type->ref->c >= 0)
5869 sym->type.ref->c = type->ref->c;
5870 } else {
5871 /* we accept several definitions of the same
5872 global variable. this is tricky, because we
5873 must play with the SHN_COMMON type of the symbol */
5874 /* XXX: should check if the variable was already
5875 initialized. It is incorrect to initialized it
5876 twice */
5877 /* no init data, we won't add more to the symbol */
5878 if (!has_init)
5879 goto no_alloc;
5884 /* allocate symbol in corresponding section */
5885 sec = ad->section;
5886 if (!sec) {
5887 if (has_init)
5888 sec = data_section;
5889 else if (tcc_state->nocommon)
5890 sec = bss_section;
5892 if (sec) {
5893 data_offset = sec->data_offset;
5894 data_offset = (data_offset + align - 1) & -align;
5895 addr = data_offset;
5896 /* very important to increment global pointer at this time
5897 because initializers themselves can create new initializers */
5898 data_offset += size;
5899 #ifdef CONFIG_TCC_BCHECK
5900 /* add padding if bound check */
5901 if (tcc_state->do_bounds_check)
5902 data_offset++;
5903 #endif
5904 sec->data_offset = data_offset;
5905 /* allocate section space to put the data */
5906 if (sec->sh_type != SHT_NOBITS &&
5907 data_offset > sec->data_allocated)
5908 section_realloc(sec, data_offset);
5909 /* align section if needed */
5910 if (align > sec->sh_addralign)
5911 sec->sh_addralign = align;
5912 } else {
5913 addr = 0; /* avoid warning */
5916 if (v) {
5917 if (scope != VT_CONST || !sym) {
5918 sym = sym_push(v, type, r | VT_SYM, 0);
5919 sym->asm_label = asm_label;
5921 /* update symbol definition */
5922 if (sec) {
5923 put_extern_sym(sym, sec, addr, size);
5924 } else {
5925 ElfW(Sym) *esym;
5926 /* put a common area */
5927 put_extern_sym(sym, NULL, align, size);
5928 /* XXX: find a nicer way */
5929 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5930 esym->st_shndx = SHN_COMMON;
5932 } else {
5933 /* push global reference */
5934 sym = get_sym_ref(type, sec, addr, size);
5935 vpushsym(type, sym);
5937 /* patch symbol weakness */
5938 if (type->t & VT_WEAK)
5939 weaken_symbol(sym);
5940 apply_visibility(sym, type);
5941 #ifdef CONFIG_TCC_BCHECK
5942 /* handles bounds now because the symbol must be defined
5943 before for the relocation */
5944 if (tcc_state->do_bounds_check) {
5945 addr_t *bounds_ptr;
5947 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5948 /* then add global bound info */
5949 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
5950 bounds_ptr[0] = 0; /* relocated */
5951 bounds_ptr[1] = size;
5953 #endif
5955 if (has_init || (type->t & VT_VLA)) {
5956 decl_initializer(type, sec, addr, 1, 0);
5957 /* restore parse state if needed */
5958 if (init_str.str) {
5959 tok_str_free(init_str.str);
5960 restore_parse_state(&saved_parse_state);
5962 /* patch flexible array member size back to -1, */
5963 /* for possible subsequent similar declarations */
5964 if (flexible_array)
5965 flexible_array->type.ref->c = -1;
5967 no_alloc: ;
5970 static void put_func_debug(Sym *sym)
5972 char buf[512];
5974 /* stabs info */
5975 /* XXX: we put here a dummy type */
5976 snprintf(buf, sizeof(buf), "%s:%c1",
5977 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5978 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5979 cur_text_section, sym->c);
5980 /* //gr gdb wants a line at the function */
5981 put_stabn(N_SLINE, 0, file->line_num, 0);
5982 last_ind = 0;
5983 last_line_num = 0;
5986 /* parse an old style function declaration list */
5987 /* XXX: check multiple parameter */
5988 static void func_decl_list(Sym *func_sym)
5990 AttributeDef ad;
5991 int v;
5992 Sym *s;
5993 CType btype, type;
5995 /* parse each declaration */
5996 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5997 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5998 if (!parse_btype(&btype, &ad))
5999 expect("declaration list");
6000 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6001 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6002 tok == ';') {
6003 /* we accept no variable after */
6004 } else {
6005 for(;;) {
6006 type = btype;
6007 type_decl(&type, &ad, &v, TYPE_DIRECT);
6008 /* find parameter in function parameter list */
6009 s = func_sym->next;
6010 while (s != NULL) {
6011 if ((s->v & ~SYM_FIELD) == v)
6012 goto found;
6013 s = s->next;
6015 tcc_error("declaration for parameter '%s' but no such parameter",
6016 get_tok_str(v, NULL));
6017 found:
6018 /* check that no storage specifier except 'register' was given */
6019 if (type.t & VT_STORAGE)
6020 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
6021 convert_parameter_type(&type);
6022 /* we can add the type (NOTE: it could be local to the function) */
6023 s->type = type;
6024 /* accept other parameters */
6025 if (tok == ',')
6026 next();
6027 else
6028 break;
6031 skip(';');
6035 /* parse a function defined by symbol 'sym' and generate its code in
6036 'cur_text_section' */
6037 static void gen_function(Sym *sym)
6039 int saved_nocode_wanted = nocode_wanted;
6040 nocode_wanted = 0;
6041 ind = cur_text_section->data_offset;
6042 /* NOTE: we patch the symbol size later */
6043 put_extern_sym(sym, cur_text_section, ind, 0);
6044 funcname = get_tok_str(sym->v, NULL);
6045 func_ind = ind;
6046 /* Initialize VLA state */
6047 vla_sp_loc = &vla_sp_root_loc;
6048 vla_flags = VLA_NEED_NEW_FRAME;
6049 /* put debug symbol */
6050 if (tcc_state->do_debug)
6051 put_func_debug(sym);
6052 /* push a dummy symbol to enable local sym storage */
6053 sym_push2(&local_stack, SYM_FIELD, 0, 0);
6054 gfunc_prolog(&sym->type);
6055 #ifdef CONFIG_TCC_BCHECK
6056 if (tcc_state->do_bounds_check
6057 && !strcmp(get_tok_str(sym->v, NULL), "main")) {
6058 int i;
6060 sym = local_stack;
6061 for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) {
6062 if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD)
6063 break;
6064 vpush_global_sym(&func_old_type, TOK___bound_main_arg);
6065 vset(&sym->type, sym->r, sym->c);
6066 gfunc_call(1);
6069 #endif
6070 rsym = 0;
6071 block(NULL, NULL, NULL, NULL, 0, 0);
6072 gsym(rsym);
6073 gfunc_epilog();
6074 cur_text_section->data_offset = ind;
6075 label_pop(&global_label_stack, NULL);
6076 /* reset local stack */
6077 scope_stack_bottom = NULL;
6078 sym_pop(&local_stack, NULL);
6079 /* end of function */
6080 /* patch symbol size */
6081 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
6082 ind - func_ind;
6083 /* patch symbol weakness (this definition overrules any prototype) */
6084 if (sym->type.t & VT_WEAK)
6085 weaken_symbol(sym);
6086 apply_visibility(sym, &sym->type);
6087 if (tcc_state->do_debug) {
6088 put_stabn(N_FUN, 0, 0, ind - func_ind);
6090 /* It's better to crash than to generate wrong code */
6091 cur_text_section = NULL;
6092 funcname = ""; /* for safety */
6093 func_vt.t = VT_VOID; /* for safety */
6094 func_var = 0; /* for safety */
6095 ind = 0; /* for safety */
6096 nocode_wanted = saved_nocode_wanted;
6099 ST_FUNC void gen_inline_functions(void)
6101 Sym *sym;
6102 int *str, inline_generated, i;
6103 struct InlineFunc *fn;
6105 /* iterate while inline function are referenced */
6106 for(;;) {
6107 inline_generated = 0;
6108 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6109 fn = tcc_state->inline_fns[i];
6110 sym = fn->sym;
6111 if (sym && sym->c) {
6112 /* the function was used: generate its code and
6113 convert it to a normal function */
6114 str = fn->token_str;
6115 fn->sym = NULL;
6116 if (file)
6117 pstrcpy(file->filename, sizeof file->filename, fn->filename);
6118 sym->r = VT_SYM | VT_CONST;
6119 sym->type.t &= ~VT_INLINE;
6121 macro_ptr = str;
6122 next();
6123 cur_text_section = text_section;
6124 gen_function(sym);
6125 macro_ptr = NULL; /* fail safe */
6127 inline_generated = 1;
6130 if (!inline_generated)
6131 break;
6133 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6134 fn = tcc_state->inline_fns[i];
6135 str = fn->token_str;
6136 tok_str_free(str);
6138 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
6141 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6142 static int decl0(int l, int is_for_loop_init)
6144 int v, has_init, r;
6145 CType type, btype;
6146 Sym *sym;
6147 AttributeDef ad;
6149 while (1) {
6150 if (!parse_btype(&btype, &ad)) {
6151 if (is_for_loop_init)
6152 return 0;
6153 /* skip redundant ';' */
6154 /* XXX: find more elegant solution */
6155 if (tok == ';') {
6156 next();
6157 continue;
6159 if (l == VT_CONST &&
6160 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6161 /* global asm block */
6162 asm_global_instr();
6163 continue;
6165 /* special test for old K&R protos without explicit int
6166 type. Only accepted when defining global data */
6167 if (l == VT_LOCAL || tok < TOK_DEFINE)
6168 break;
6169 btype.t = VT_INT;
6171 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6172 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6173 tok == ';') {
6174 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
6175 int v = btype.ref->v;
6176 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
6177 tcc_warning("unnamed struct/union that defines no instances");
6179 next();
6180 continue;
6182 while (1) { /* iterate thru each declaration */
6183 char *asm_label; // associated asm label
6184 type = btype;
6185 type_decl(&type, &ad, &v, TYPE_DIRECT);
6186 #if 0
6188 char buf[500];
6189 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6190 printf("type = '%s'\n", buf);
6192 #endif
6193 if ((type.t & VT_BTYPE) == VT_FUNC) {
6194 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
6195 tcc_error("function without file scope cannot be static");
6197 /* if old style function prototype, we accept a
6198 declaration list */
6199 sym = type.ref;
6200 if (sym->c == FUNC_OLD)
6201 func_decl_list(sym);
6204 asm_label = NULL;
6205 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6206 CString astr;
6208 asm_label_instr(&astr);
6209 asm_label = tcc_strdup(astr.data);
6210 cstr_free(&astr);
6212 /* parse one last attribute list, after asm label */
6213 parse_attribute(&ad);
6216 if (ad.a.weak)
6217 type.t |= VT_WEAK;
6218 #ifdef TCC_TARGET_PE
6219 if (ad.a.func_import)
6220 type.t |= VT_IMPORT;
6221 if (ad.a.func_export)
6222 type.t |= VT_EXPORT;
6223 #endif
6224 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6226 if (tok == '{') {
6227 if (l == VT_LOCAL)
6228 tcc_error("cannot use local functions");
6229 if ((type.t & VT_BTYPE) != VT_FUNC)
6230 expect("function definition");
6232 /* reject abstract declarators in function definition */
6233 sym = type.ref;
6234 while ((sym = sym->next) != NULL)
6235 if (!(sym->v & ~SYM_FIELD))
6236 expect("identifier");
6238 /* XXX: cannot do better now: convert extern line to static inline */
6239 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6240 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6242 sym = sym_find(v);
6243 if (sym) {
6244 Sym *ref;
6245 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6246 goto func_error1;
6248 ref = sym->type.ref;
6249 if (0 == ref->a.func_proto)
6250 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6252 /* use func_call from prototype if not defined */
6253 if (ref->a.func_call != FUNC_CDECL
6254 && type.ref->a.func_call == FUNC_CDECL)
6255 type.ref->a.func_call = ref->a.func_call;
6257 /* use export from prototype */
6258 if (ref->a.func_export)
6259 type.ref->a.func_export = 1;
6261 /* use static from prototype */
6262 if (sym->type.t & VT_STATIC)
6263 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6265 /* If the definition has no visibility use the
6266 one from prototype. */
6267 if (! (type.t & VT_VIS_MASK))
6268 type.t |= sym->type.t & VT_VIS_MASK;
6270 if (!is_compatible_types(&sym->type, &type)) {
6271 func_error1:
6272 tcc_error("incompatible types for redefinition of '%s'",
6273 get_tok_str(v, NULL));
6275 type.ref->a.func_proto = 0;
6276 /* if symbol is already defined, then put complete type */
6277 sym->type = type;
6278 } else {
6279 /* put function symbol */
6280 sym = global_identifier_push(v, type.t, 0);
6281 sym->type.ref = type.ref;
6284 /* static inline functions are just recorded as a kind
6285 of macro. Their code will be emitted at the end of
6286 the compilation unit only if they are used */
6287 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6288 (VT_INLINE | VT_STATIC)) {
6289 TokenString func_str;
6290 int block_level;
6291 struct InlineFunc *fn;
6292 const char *filename;
6294 tok_str_new(&func_str);
6296 block_level = 0;
6297 for(;;) {
6298 int t;
6299 if (tok == TOK_EOF)
6300 tcc_error("unexpected end of file");
6301 tok_str_add_tok(&func_str);
6302 t = tok;
6303 next();
6304 if (t == '{') {
6305 block_level++;
6306 } else if (t == '}') {
6307 block_level--;
6308 if (block_level == 0)
6309 break;
6312 tok_str_add(&func_str, -1);
6313 tok_str_add(&func_str, 0);
6314 filename = file ? file->filename : "";
6315 fn = tcc_malloc(sizeof *fn + strlen(filename));
6316 strcpy(fn->filename, filename);
6317 fn->sym = sym;
6318 fn->token_str = func_str.str;
6319 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6321 } else {
6322 /* compute text section */
6323 cur_text_section = ad.section;
6324 if (!cur_text_section)
6325 cur_text_section = text_section;
6326 sym->r = VT_SYM | VT_CONST;
6327 gen_function(sym);
6329 break;
6330 } else {
6331 if (btype.t & VT_TYPEDEF) {
6332 /* save typedefed type */
6333 /* XXX: test storage specifiers ? */
6334 sym = sym_push(v, &type, 0, 0);
6335 sym->a = ad.a;
6336 sym->type.t |= VT_TYPEDEF;
6337 } else {
6338 r = 0;
6339 if ((type.t & VT_BTYPE) == VT_FUNC) {
6340 /* external function definition */
6341 /* specific case for func_call attribute */
6342 ad.a.func_proto = 1;
6343 type.ref->a = ad.a;
6344 } else if (!(type.t & VT_ARRAY)) {
6345 /* not lvalue if array */
6346 r |= lvalue_type(type.t);
6348 has_init = (tok == '=');
6349 if (has_init && (type.t & VT_VLA))
6350 tcc_error("Variable length array cannot be initialized");
6351 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6352 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6353 !has_init && l == VT_CONST && type.ref->c < 0)) {
6354 /* external variable or function */
6355 /* NOTE: as GCC, uninitialized global static
6356 arrays of null size are considered as
6357 extern */
6358 sym = external_sym(v, &type, r, asm_label);
6360 if (ad.alias_target) {
6361 Section tsec;
6362 Elf32_Sym *esym;
6363 Sym *alias_target;
6365 alias_target = sym_find(ad.alias_target);
6366 if (!alias_target || !alias_target->c)
6367 tcc_error("unsupported forward __alias__ attribute");
6368 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6369 tsec.sh_num = esym->st_shndx;
6370 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6372 } else {
6373 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6374 if (type.t & VT_STATIC)
6375 r |= VT_CONST;
6376 else
6377 r |= l;
6378 if (has_init)
6379 next();
6380 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
6383 if (tok != ',') {
6384 if (is_for_loop_init)
6385 return 1;
6386 skip(';');
6387 break;
6389 next();
6391 ad.a.aligned = 0;
6394 return 0;
6397 ST_FUNC void decl(int l)
6399 decl0(l, 0);