Fix va_arg bug, Fix type conversion bug, an increase of loc_stack () function is...
[tinycc.git] / tccgen.c
blob33240cfe017ef6a485bd4f05420a5f72c5f77cee
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;
73 ST_DATA int pop_stack;
75 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
77 /* ------------------------------------------------------------------------- */
78 static void gen_cast(CType *type);
79 static inline CType *pointed_type(CType *type);
80 static int is_compatible_types(CType *type1, CType *type2);
81 static int parse_btype(CType *type, AttributeDef *ad);
82 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
83 static void parse_expr_type(CType *type);
84 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
85 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
86 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
87 static int decl0(int l, int is_for_loop_init);
88 static void expr_eq(void);
89 static void unary_type(CType *type);
90 static void vla_runtime_type_size(CType *type, int *a);
91 static void vla_sp_save(void);
92 static int is_compatible_parameter_types(CType *type1, CType *type2);
93 static void expr_type(CType *type);
94 ST_FUNC void vpush64(int ty, unsigned long long v);
95 ST_FUNC void vpush(CType *type);
96 ST_FUNC int gtst(int inv, int t);
97 ST_FUNC int is_btype_size(int bt);
99 ST_INLN int is_float(int t)
101 int bt;
102 bt = t & VT_BTYPE;
103 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
106 /* we use our own 'finite' function to avoid potential problems with
107 non standard math libs */
108 /* XXX: endianness dependent */
109 ST_FUNC int ieee_finite(double d)
111 int p[4];
112 memcpy(p, &d, sizeof(double));
113 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
116 ST_FUNC void test_lvalue(void)
118 if (!(vtop->r & VT_LVAL))
119 expect("lvalue");
122 /* ------------------------------------------------------------------------- */
123 /* symbol allocator */
124 static Sym *__sym_malloc(void)
126 Sym *sym_pool, *sym, *last_sym;
127 int i;
129 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
130 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
132 last_sym = sym_free_first;
133 sym = sym_pool;
134 for(i = 0; i < SYM_POOL_NB; i++) {
135 sym->next = last_sym;
136 last_sym = sym;
137 sym++;
139 sym_free_first = last_sym;
140 return last_sym;
143 static inline Sym *sym_malloc(void)
145 Sym *sym;
146 sym = sym_free_first;
147 if (!sym)
148 sym = __sym_malloc();
149 sym_free_first = sym->next;
150 return sym;
153 ST_INLN void sym_free(Sym *sym)
155 sym->next = sym_free_first;
156 tcc_free(sym->asm_label);
157 sym_free_first = sym;
160 /* push, without hashing */
161 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
163 Sym *s;
164 if (ps == &local_stack) {
165 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
166 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
167 tcc_error("incompatible types for redefinition of '%s'",
168 get_tok_str(v, NULL));
170 s = sym_malloc();
171 s->asm_label = NULL;
172 s->v = v;
173 s->type.t = t;
174 s->type.ref = NULL;
175 #ifdef _WIN64
176 s->d = NULL;
177 #endif
178 s->c = c;
179 s->next = NULL;
180 /* add in stack */
181 s->prev = *ps;
182 *ps = s;
183 return s;
186 /* find a symbol and return its associated structure. 's' is the top
187 of the symbol stack */
188 ST_FUNC Sym *sym_find2(Sym *s, int v)
190 while (s) {
191 if (s->v == v)
192 return s;
193 else if (s->v == -1)
194 return NULL;
195 s = s->prev;
197 return NULL;
200 /* structure lookup */
201 ST_INLN Sym *struct_find(int v)
203 v -= TOK_IDENT;
204 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
205 return NULL;
206 return table_ident[v]->sym_struct;
209 /* find an identifier */
210 ST_INLN Sym *sym_find(int v)
212 v -= TOK_IDENT;
213 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
214 return NULL;
215 return table_ident[v]->sym_identifier;
218 /* push a given symbol on the symbol stack */
219 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
221 Sym *s, **ps;
222 TokenSym *ts;
224 if (local_stack)
225 ps = &local_stack;
226 else
227 ps = &global_stack;
228 s = sym_push2(ps, v, type->t, c);
229 s->type.ref = type->ref;
230 s->r = r;
231 /* don't record fields or anonymous symbols */
232 /* XXX: simplify */
233 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
234 /* record symbol in token array */
235 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
236 if (v & SYM_STRUCT)
237 ps = &ts->sym_struct;
238 else
239 ps = &ts->sym_identifier;
240 s->prev_tok = *ps;
241 *ps = s;
243 return s;
246 /* push a global identifier */
247 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
249 Sym *s, **ps;
250 s = sym_push2(&global_stack, v, t, c);
251 /* don't record anonymous symbol */
252 if (v < SYM_FIRST_ANOM) {
253 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
254 /* modify the top most local identifier, so that
255 sym_identifier will point to 's' when popped */
256 while (*ps != NULL)
257 ps = &(*ps)->prev_tok;
258 s->prev_tok = NULL;
259 *ps = s;
261 return s;
264 /* pop symbols until top reaches 'b' */
265 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
267 Sym *s, *ss, **ps;
268 TokenSym *ts;
269 int v;
271 s = *ptop;
272 while(s != b) {
273 ss = s->prev;
274 v = s->v;
275 /* remove symbol in token array */
276 /* XXX: simplify */
277 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
278 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
279 if (v & SYM_STRUCT)
280 ps = &ts->sym_struct;
281 else
282 ps = &ts->sym_identifier;
283 *ps = s->prev_tok;
285 sym_free(s);
286 s = ss;
288 *ptop = b;
291 static void weaken_symbol(Sym *sym)
293 sym->type.t |= VT_WEAK;
294 if (sym->c > 0) {
295 int esym_type;
296 ElfW(Sym) *esym;
298 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
299 esym_type = ELFW(ST_TYPE)(esym->st_info);
300 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
304 static void apply_visibility(Sym *sym, CType *type)
306 int vis = sym->type.t & VT_VIS_MASK;
307 int vis2 = type->t & VT_VIS_MASK;
308 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
309 vis = vis2;
310 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
312 else
313 vis = (vis < vis2) ? vis : vis2;
314 sym->type.t &= ~VT_VIS_MASK;
315 sym->type.t |= vis;
317 if (sym->c > 0) {
318 ElfW(Sym) *esym;
320 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
321 vis >>= VT_VIS_SHIFT;
322 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
326 /* ------------------------------------------------------------------------- */
328 ST_FUNC void swap(int *p, int *q)
330 int t;
331 t = *p;
332 *p = *q;
333 *q = t;
336 static void vsetc(CType *type, int r, CValue *vc)
338 int v;
340 if (vtop >= vstack + (VSTACK_SIZE - 1))
341 tcc_error("memory full (vstack)");
342 /* cannot let cpu flags if other instruction are generated. Also
343 avoid leaving VT_JMP anywhere except on the top of the stack
344 because it would complicate the code generator. */
345 if (vtop >= vstack) {
346 v = vtop->r & VT_VALMASK;
347 if (v == VT_CMP || (v & ~1) == VT_JMP)
348 gv(RC_INT);
350 vtop++;
351 vtop->type = *type;
352 vtop->r = r;
353 vtop->r2 = VT_CONST;
354 vtop->c = *vc;
357 /* push constant of type "type" with useless value */
358 ST_FUNC void vpush(CType *type)
360 CValue cval;
361 vsetc(type, VT_CONST, &cval);
364 /* push integer constant */
365 ST_FUNC void vpushi(int v)
367 CValue cval;
368 cval.i = v;
369 vsetc(&int_type, VT_CONST, &cval);
372 /* push a pointer sized constant */
373 static void vpushs(addr_t v)
375 CValue cval;
376 cval.ptr_offset = v;
377 vsetc(&size_type, VT_CONST, &cval);
380 /* push arbitrary 64bit constant */
381 ST_FUNC void vpush64(int ty, unsigned long long v)
383 CValue cval;
384 CType ctype;
385 ctype.t = ty;
386 ctype.ref = NULL;
387 cval.ull = v;
388 vsetc(&ctype, VT_CONST, &cval);
391 /* push long long constant */
392 static inline void vpushll(long long v)
394 vpush64(VT_LLONG, v);
397 /* push a symbol value of TYPE */
398 static inline void vpushsym(CType *type, Sym *sym)
400 CValue cval;
401 cval.ptr_offset = 0;
402 vsetc(type, VT_CONST | VT_SYM, &cval);
403 vtop->sym = sym;
406 /* Return a static symbol pointing to a section */
407 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
409 int v;
410 Sym *sym;
412 v = anon_sym++;
413 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
414 sym->type.ref = type->ref;
415 sym->r = VT_CONST | VT_SYM;
416 put_extern_sym(sym, sec, offset, size);
417 return sym;
420 /* push a reference to a section offset by adding a dummy symbol */
421 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
423 vpushsym(type, get_sym_ref(type, sec, offset, size));
426 /* define a new external reference to a symbol 'v' of type 'u' */
427 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
429 Sym *s;
431 s = sym_find(v);
432 if (!s) {
433 /* push forward reference */
434 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
435 s->type.ref = type->ref;
436 s->r = r | VT_CONST | VT_SYM;
438 return s;
441 /* define a new external reference to a symbol 'v' with alternate asm
442 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
443 is no alternate name (most cases) */
444 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
446 Sym *s;
448 s = sym_find(v);
449 if (!s) {
450 /* push forward reference */
451 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
452 s->asm_label = asm_label;
453 s->type.t |= VT_EXTERN;
454 } else if (s->type.ref == func_old_type.ref) {
455 s->type.ref = type->ref;
456 s->r = r | VT_CONST | VT_SYM;
457 s->type.t |= VT_EXTERN;
458 } else if (!is_compatible_types(&s->type, type)) {
459 tcc_error("incompatible types for redefinition of '%s'",
460 get_tok_str(v, NULL));
462 /* Merge some storage attributes. */
463 if (type->t & VT_WEAK)
464 weaken_symbol(s);
466 if (type->t & VT_VIS_MASK)
467 apply_visibility(s, type);
469 return s;
472 /* push a reference to global symbol v */
473 ST_FUNC void vpush_global_sym(CType *type, int v)
475 vpushsym(type, external_global_sym(v, type, 0));
478 ST_FUNC void vset(CType *type, int r, int v)
480 CValue cval;
482 cval.i = v;
483 vsetc(type, r, &cval);
486 static void vseti(int r, int v)
488 CType type;
489 type.t = VT_INT;
490 type.ref = 0;
491 vset(&type, r, v);
494 ST_FUNC void vswap(void)
496 SValue tmp;
497 /* cannot let cpu flags if other instruction are generated. Also
498 avoid leaving VT_JMP anywhere except on the top of the stack
499 because it would complicate the code generator. */
500 if (vtop >= vstack) {
501 int v = vtop->r & VT_VALMASK;
502 if (v == VT_CMP || (v & ~1) == VT_JMP)
503 gv(RC_INT);
505 tmp = vtop[0];
506 vtop[0] = vtop[-1];
507 vtop[-1] = tmp;
509 /* XXX: +2% overall speed possible with optimized memswap
511 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
515 ST_FUNC void vpushv(SValue *v)
517 if (vtop >= vstack + (VSTACK_SIZE - 1))
518 tcc_error("memory full (vstack)");
519 vtop++;
520 *vtop = *v;
523 static void vdup(void)
525 vpushv(vtop);
528 static int align_size(int size)
530 #ifdef TCC_TARGET_X86_64
531 if(size > 4)
532 return 8;
533 else
534 #endif
535 if(size > 2)
536 return 4;
537 else if(size > 1)
538 return 2;
539 else
540 return 1;
543 int loc_stack(int size, int is_sub){
544 int l, align;
545 align = align_size(size);
546 size = (size + align - 1) & - align;
547 if(is_sub){
548 pop_stack -= size;
549 if(pop_stack >= 0)
550 l = loc + pop_stack;
551 else{
552 loc += pop_stack;
553 l = loc &= -align;
554 pop_stack = 0;
556 }else{
557 pop_stack += size;
558 l = loc + pop_stack;
560 return l;
563 /* save r to the memory stack, and mark it as being free */
564 ST_FUNC void save_reg(int r)
566 int l, saved, size, align;
567 SValue *p, sv;
568 CType *type;
570 /* modify all stack values */
571 saved = 0;
572 l = 0;
573 for(p=vstack;p<=vtop;p++) {
574 if ((p->r & VT_VALMASK) == r ||
575 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
576 /* must save value on stack if not already done */
577 if (!saved) {
578 /* NOTE: must reload 'r' because r might be equal to r2 */
579 r = p->r & VT_VALMASK;
580 /* store register in the stack */
581 type = &p->type;
582 if ((p->r & VT_LVAL) ||
583 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
584 #ifdef TCC_TARGET_X86_64
585 type = &char_pointer_type;
586 #else
587 type = &int_type;
588 #endif
589 size = type_size(type, &align);
590 loc = (loc - size) & -align;
591 sv.type.t = type->t;
592 sv.r = VT_LOCAL | VT_LVAL;
593 sv.c.ul = loc;
594 store(r, &sv);
595 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
596 /* x86 specific: need to pop fp register ST0 if saved */
597 if (r == TREG_ST0) {
598 o(0xd8dd); /* fstp %st(0) */
600 #endif
601 #ifndef TCC_TARGET_X86_64
602 /* special long long case */
603 if ((type->t & VT_BTYPE) == VT_LLONG) {
604 sv.c.ul += 4;
605 store(p->r2, &sv);
607 #endif
608 l = loc;
609 saved = 1;
611 /* mark that stack entry as being saved on the stack */
612 if (p->r & VT_LVAL) {
613 /* also clear the bounded flag because the
614 relocation address of the function was stored in
615 p->c.ul */
616 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
617 } else {
618 p->r = lvalue_type(p->type.t) | VT_LOCAL;
620 p->r2 = VT_CONST;
621 p->c.ul = l;
626 #ifdef TCC_TARGET_ARM
627 /* find a register of class 'rc2' with at most one reference on stack.
628 * If none, call get_reg(rc) */
629 ST_FUNC int get_reg_ex(int rc, int rc2)
631 int r;
632 SValue *p;
634 for(r=0;r<NB_REGS;r++) {
635 if (reg_classes[r] & rc2) {
636 int n;
637 n=0;
638 for(p = vstack; p <= vtop; p++) {
639 if ((p->r & VT_VALMASK) == r ||
640 (p->r2 & VT_VALMASK) == r)
641 n++;
643 if (n <= 1)
644 return r;
647 return get_reg(rc);
649 #endif
651 /* find a free register of class 'rc'. If none, save one register */
652 ST_FUNC int get_reg(int rc)
654 int r;
655 SValue *p;
657 /* find a free register */
658 for(r=0;r<NB_REGS;r++) {
659 if (reg_classes[r] & rc) {
660 for(p=vstack;p<=vtop;p++) {
661 if ((p->r & VT_VALMASK) == r ||
662 (p->r2 & VT_VALMASK) == r)
663 goto notfound;
665 return r;
667 notfound: ;
670 /* no register left : free the first one on the stack (VERY
671 IMPORTANT to start from the bottom to ensure that we don't
672 spill registers used in gen_opi()) */
673 for(p=vstack;p<=vtop;p++) {
674 /* look at second register (if long long) */
675 r = p->r2 & VT_VALMASK;
676 if (r < VT_CONST && (reg_classes[r] & rc))
677 goto save_found;
678 r = p->r & VT_VALMASK;
679 if (r < VT_CONST && (reg_classes[r] & rc)) {
680 save_found:
681 save_reg(r);
682 return r;
685 /* Should never comes here */
686 return -1;
689 /* save registers up to (vtop - n) stack entry */
690 ST_FUNC void save_regs(int n)
692 int r;
693 SValue *p, *p1;
694 p1 = vtop - n;
695 for(p = vstack;p <= p1; p++) {
696 r = p->r & VT_VALMASK;
697 if (r < VT_CONST) {
698 save_reg(r);
703 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
704 if needed */
705 static void move_reg(int r, int s, int t)
707 SValue sv;
709 if (r != s) {
710 save_reg(r);
711 sv.type.t = t;
712 sv.type.ref = NULL;
713 sv.r = s;
714 sv.c.ul = 0;
715 load(r, &sv);
719 /* get address of vtop (vtop MUST BE an lvalue) */
720 static void gaddrof(void)
722 if (vtop->r & VT_REF)
723 gv(RC_INT);
724 vtop->r &= ~VT_LVAL;
725 /* tricky: if saved lvalue, then we can go back to lvalue */
726 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
727 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
732 #ifdef CONFIG_TCC_BCHECK
733 /* generate lvalue bound code */
734 static void gbound(void)
736 int lval_type;
737 CType type1;
739 vtop->r &= ~VT_MUSTBOUND;
740 /* if lvalue, then use checking code before dereferencing */
741 if (vtop->r & VT_LVAL) {
742 /* if not VT_BOUNDED value, then make one */
743 if (!(vtop->r & VT_BOUNDED)) {
744 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
745 /* must save type because we must set it to int to get pointer */
746 type1 = vtop->type;
747 vtop->type.t = VT_INT;
748 gaddrof();
749 vpushi(0);
750 gen_bounded_ptr_add();
751 vtop->r |= lval_type;
752 vtop->type = type1;
754 /* then check for dereferencing */
755 gen_bounded_ptr_deref();
758 #endif
760 /* store vtop a register belonging to class 'rc'. lvalues are
761 converted to values. Cannot be used if cannot be converted to
762 register value (such as structures). */
763 ST_FUNC int gv(int rc)
765 int r, bit_pos, bit_size, size, align, i;
766 int rc2;
768 /* NOTE: get_reg can modify vstack[] */
769 if (vtop->type.t & VT_BITFIELD) {
770 CType type;
771 int bits = 32;
772 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
773 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
774 /* remove bit field info to avoid loops */
775 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
776 /* cast to int to propagate signedness in following ops */
777 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
778 type.t = VT_LLONG;
779 bits = 64;
780 } else
781 type.t = VT_INT;
782 if((vtop->type.t & VT_UNSIGNED) ||
783 (vtop->type.t & VT_BTYPE) == VT_BOOL)
784 type.t |= VT_UNSIGNED;
785 gen_cast(&type);
786 /* generate shifts */
787 vpushi(bits - (bit_pos + bit_size));
788 gen_op(TOK_SHL);
789 vpushi(bits - bit_size);
790 /* NOTE: transformed to SHR if unsigned */
791 gen_op(TOK_SAR);
792 r = gv(rc);
793 } else {
794 if (is_float(vtop->type.t) &&
795 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
796 Sym *sym;
797 int *ptr;
798 unsigned long offset;
799 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
800 CValue check;
801 #endif
803 /* XXX: unify with initializers handling ? */
804 /* CPUs usually cannot use float constants, so we store them
805 generically in data segment */
806 size = type_size(&vtop->type, &align);
807 offset = (data_section->data_offset + align - 1) & -align;
808 data_section->data_offset = offset;
809 /* XXX: not portable yet */
810 #if defined(__i386__) || defined(__x86_64__)
811 /* Zero pad x87 tenbyte long doubles */
812 if (size == LDOUBLE_SIZE) {
813 vtop->c.tab[2] &= 0xffff;
814 #if LDOUBLE_SIZE == 16
815 vtop->c.tab[3] = 0;
816 #endif
818 #endif
819 ptr = section_ptr_add(data_section, size);
820 size = size >> 2;
821 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
822 check.d = 1;
823 if(check.tab[0])
824 for(i=0;i<size;i++)
825 ptr[i] = vtop->c.tab[size-1-i];
826 else
827 #endif
828 for(i=0;i<size;i++)
829 ptr[i] = vtop->c.tab[i];
830 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
831 vtop->r |= VT_LVAL | VT_SYM;
832 vtop->sym = sym;
833 vtop->c.ptr_offset = 0;
835 #ifdef CONFIG_TCC_BCHECK
836 if (vtop->r & VT_MUSTBOUND)
837 gbound();
838 #endif
840 r = vtop->r & VT_VALMASK;
841 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
842 if (rc == RC_IRET)
843 rc2 = RC_LRET;
844 #ifdef TCC_TARGET_X86_64
845 else if (rc == RC_FRET)
846 rc2 = RC_QRET;
847 #endif
849 /* need to reload if:
850 - constant
851 - lvalue (need to dereference pointer)
852 - already a register, but not in the right class */
853 if (r >= VT_CONST
854 || (vtop->r & VT_LVAL)
855 || !(reg_classes[r] & rc)
856 #ifdef TCC_TARGET_X86_64
857 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
858 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
859 #else
860 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
861 #endif
864 r = get_reg(rc);
865 #ifdef TCC_TARGET_X86_64
866 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
867 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
868 #else
869 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
870 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
871 unsigned long long ll;
872 #endif
873 int r2, original_type;
874 original_type = vtop->type.t;
875 /* two register type load : expand to two words
876 temporarily */
877 #ifndef TCC_TARGET_X86_64
878 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
879 /* load constant */
880 ll = vtop->c.ull;
881 vtop->c.ui = ll; /* first word */
882 load(r, vtop);
883 vtop->r = r; /* save register value */
884 vpushi(ll >> 32); /* second word */
885 } else
886 #endif
887 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
888 (vtop->r & VT_LVAL)) {
889 /* We do not want to modifier the long long
890 pointer here, so the safest (and less
891 efficient) is to save all the other registers
892 in the stack. XXX: totally inefficient. */
893 save_regs(1);
894 /* load from memory */
895 vtop->type.t = load_type;
896 load(r, vtop);
897 vdup();
898 vtop[-1].r = r; /* save register value */
899 /* increment pointer to get second word */
900 vtop->type.t = addr_type;
901 gaddrof();
902 vpushi(load_size);
903 gen_op('+');
904 vtop->r |= VT_LVAL;
905 vtop->type.t = load_type;
906 } else {
907 /* move registers */
908 load(r, vtop);
909 vdup();
910 vtop[-1].r = r; /* save register value */
911 vtop->r = vtop[-1].r2;
913 /* Allocate second register. Here we rely on the fact that
914 get_reg() tries first to free r2 of an SValue. */
915 r2 = get_reg(rc2);
916 load(r2, vtop);
917 vpop();
918 /* write second register */
919 vtop->r2 = r2;
920 vtop->type.t = original_type;
921 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
922 int t1, t;
923 /* lvalue of scalar type : need to use lvalue type
924 because of possible cast */
925 t = vtop->type.t;
926 t1 = t;
927 /* compute memory access type */
928 if (vtop->r & VT_REF)
929 #ifdef TCC_TARGET_X86_64
930 t = VT_PTR;
931 #else
932 t = VT_INT;
933 #endif
934 else if (vtop->r & VT_LVAL_BYTE)
935 t = VT_BYTE;
936 else if (vtop->r & VT_LVAL_SHORT)
937 t = VT_SHORT;
938 if (vtop->r & VT_LVAL_UNSIGNED)
939 t |= VT_UNSIGNED;
940 vtop->type.t = t;
941 load(r, vtop);
942 /* restore wanted type */
943 vtop->type.t = t1;
944 } else {
945 /* one register type load */
946 load(r, vtop);
948 vtop->r = r;
949 vtop->c.ptr_offset = 0;
951 #ifdef TCC_TARGET_C67
952 /* uses register pairs for doubles */
953 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
954 vtop->r2 = r+1;
955 #endif
957 return r;
960 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
961 ST_FUNC void gv2(int rc1, int rc2)
963 /* generate more generic register first. But VT_JMP or VT_CMP
964 values must be generated first in all cases to avoid possible
965 reload errors */
966 if (rc1 <= rc2) {
967 vswap();
968 gv(rc1);
969 vswap();
970 gv(rc2);
971 /* test if reload is needed for first register */
972 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
973 vswap();
974 gv(rc1);
975 vswap();
977 } else {
978 gv(rc2);
979 vswap();
980 gv(rc1);
981 vswap();
982 /* test if reload is needed for first register */
983 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
984 gv(rc2);
989 /* wrapper around RC_FRET to return a register by type */
990 static int rc_fret(int t)
992 #ifdef TCC_TARGET_X86_64
993 if (t == VT_LDOUBLE) {
994 return RC_ST0;
996 #endif
997 return RC_FRET;
1000 /* wrapper around REG_FRET to return a register by type */
1001 static int reg_fret(int t)
1003 #ifdef TCC_TARGET_X86_64
1004 if (t == VT_LDOUBLE) {
1005 return TREG_ST0;
1007 #endif
1008 return REG_FRET;
1011 /* expand long long on stack in two int registers */
1012 static void lexpand(void)
1014 int u;
1016 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1017 gv(RC_INT);
1018 vdup();
1019 vtop[0].r = vtop[-1].r2;
1020 vtop[0].r2 = VT_CONST;
1021 vtop[-1].r2 = VT_CONST;
1022 vtop[0].type.t = VT_INT | u;
1023 vtop[-1].type.t = VT_INT | u;
1026 #ifdef TCC_TARGET_ARM
1027 /* expand long long on stack */
1028 ST_FUNC void lexpand_nr(void)
1030 int u,v;
1032 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1033 vdup();
1034 vtop->r2 = VT_CONST;
1035 vtop->type.t = VT_INT | u;
1036 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1037 if (v == VT_CONST) {
1038 vtop[-1].c.ui = vtop->c.ull;
1039 vtop->c.ui = vtop->c.ull >> 32;
1040 vtop->r = VT_CONST;
1041 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1042 vtop->c.ui += 4;
1043 vtop->r = vtop[-1].r;
1044 } else if (v > VT_CONST) {
1045 vtop--;
1046 lexpand();
1047 } else
1048 vtop->r = vtop[-1].r2;
1049 vtop[-1].r2 = VT_CONST;
1050 vtop[-1].type.t = VT_INT | u;
1052 #endif
1054 #ifndef TCC_TARGET_X86_64
1055 /* build a long long from two ints */
1056 static void lbuild(int t)
1058 gv2(RC_INT, RC_INT);
1059 vtop[-1].r2 = vtop[0].r;
1060 vtop[-1].type.t = t;
1061 vpop();
1063 #endif
1065 /* rotate n first stack elements to the bottom
1066 I1 ... In -> I2 ... In I1 [top is right]
1068 ST_FUNC void vrotb(int n)
1070 int i;
1071 SValue tmp;
1073 tmp = vtop[-n + 1];
1074 for(i=-n+1;i!=0;i++)
1075 vtop[i] = vtop[i+1];
1076 vtop[0] = tmp;
1079 /* rotate the n elements before entry e towards the top
1080 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1082 ST_FUNC void vrote(SValue *e, int n)
1084 int i;
1085 SValue tmp;
1087 tmp = *e;
1088 for(i = 0;i < n - 1; i++)
1089 e[-i] = e[-i - 1];
1090 e[-n + 1] = tmp;
1093 /* rotate n first stack elements to the top
1094 I1 ... In -> In I1 ... I(n-1) [top is right]
1096 ST_FUNC void vrott(int n)
1098 vrote(vtop, n);
1101 /* pop stack value */
1102 ST_FUNC void vpop(void)
1104 int v;
1105 v = vtop->r & VT_VALMASK;
1106 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1107 /* for x86, we need to pop the FP stack */
1108 if (v == TREG_ST0 && !nocode_wanted) {
1109 o(0xd8dd); /* fstp %st(0) */
1110 } else
1111 #endif
1112 if (v == VT_JMP || v == VT_JMPI) {
1113 /* need to put correct jump if && or || without test */
1114 gsym(vtop->c.ul);
1116 vtop--;
1119 /* convert stack entry to register and duplicate its value in another
1120 register */
1121 static void gv_dup(void)
1123 int rc, t, r, r1;
1124 SValue sv;
1125 t = vtop->type.t;
1126 #ifndef TCC_TARGET_X86_64
1127 if ((t & VT_BTYPE) == VT_LLONG) {
1128 lexpand();
1129 gv_dup();
1130 vswap();
1131 vrotb(3);
1132 gv_dup();
1133 vrotb(4);
1134 /* stack: H L L1 H1 */
1135 lbuild(t);
1136 vrott(3);
1137 vswap();
1138 lbuild(t);
1139 vswap();
1140 } else
1141 #endif
1143 /* duplicate value */
1144 if (is_float(t)) {
1145 rc = RC_FLOAT;
1146 #ifdef TCC_TARGET_X86_64
1147 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1148 rc = RC_ST0;
1150 #endif
1151 }else
1152 rc = RC_INT;
1153 sv.type.t = t;
1154 r = gv(rc);
1155 r1 = get_reg(rc);
1156 sv.r = r;
1157 sv.c.ul = 0;
1158 load(r1, &sv); /* move r to r1 */
1159 vdup();
1160 /* duplicates value */
1161 if (r != r1)
1162 vtop->r = r1;
1165 #ifndef TCC_TARGET_X86_64
1166 /* generate CPU independent (unsigned) long long operations */
1167 static void gen_opl(int op)
1169 int t, a, b, op1, c, i;
1170 int func;
1171 unsigned short reg_iret = REG_IRET;
1172 unsigned short reg_lret = REG_LRET;
1173 SValue tmp;
1175 switch(op) {
1176 case '/':
1177 case TOK_PDIV:
1178 func = TOK___divdi3;
1179 goto gen_func;
1180 case TOK_UDIV:
1181 func = TOK___udivdi3;
1182 goto gen_func;
1183 case '%':
1184 func = TOK___moddi3;
1185 goto gen_mod_func;
1186 case TOK_UMOD:
1187 func = TOK___umoddi3;
1188 gen_mod_func:
1189 #ifdef TCC_ARM_EABI
1190 reg_iret = TREG_R2;
1191 reg_lret = TREG_R3;
1192 #endif
1193 gen_func:
1194 /* call generic long long function */
1195 vpush_global_sym(&func_old_type, func);
1196 vrott(3);
1197 gfunc_call(2);
1198 vpushi(0);
1199 vtop->r = reg_iret;
1200 vtop->r2 = reg_lret;
1201 break;
1202 case '^':
1203 case '&':
1204 case '|':
1205 case '*':
1206 case '+':
1207 case '-':
1208 t = vtop->type.t;
1209 vswap();
1210 lexpand();
1211 vrotb(3);
1212 lexpand();
1213 /* stack: L1 H1 L2 H2 */
1214 tmp = vtop[0];
1215 vtop[0] = vtop[-3];
1216 vtop[-3] = tmp;
1217 tmp = vtop[-2];
1218 vtop[-2] = vtop[-3];
1219 vtop[-3] = tmp;
1220 vswap();
1221 /* stack: H1 H2 L1 L2 */
1222 if (op == '*') {
1223 vpushv(vtop - 1);
1224 vpushv(vtop - 1);
1225 gen_op(TOK_UMULL);
1226 lexpand();
1227 /* stack: H1 H2 L1 L2 ML MH */
1228 for(i=0;i<4;i++)
1229 vrotb(6);
1230 /* stack: ML MH H1 H2 L1 L2 */
1231 tmp = vtop[0];
1232 vtop[0] = vtop[-2];
1233 vtop[-2] = tmp;
1234 /* stack: ML MH H1 L2 H2 L1 */
1235 gen_op('*');
1236 vrotb(3);
1237 vrotb(3);
1238 gen_op('*');
1239 /* stack: ML MH M1 M2 */
1240 gen_op('+');
1241 gen_op('+');
1242 } else if (op == '+' || op == '-') {
1243 /* XXX: add non carry method too (for MIPS or alpha) */
1244 if (op == '+')
1245 op1 = TOK_ADDC1;
1246 else
1247 op1 = TOK_SUBC1;
1248 gen_op(op1);
1249 /* stack: H1 H2 (L1 op L2) */
1250 vrotb(3);
1251 vrotb(3);
1252 gen_op(op1 + 1); /* TOK_xxxC2 */
1253 } else {
1254 gen_op(op);
1255 /* stack: H1 H2 (L1 op L2) */
1256 vrotb(3);
1257 vrotb(3);
1258 /* stack: (L1 op L2) H1 H2 */
1259 gen_op(op);
1260 /* stack: (L1 op L2) (H1 op H2) */
1262 /* stack: L H */
1263 lbuild(t);
1264 break;
1265 case TOK_SAR:
1266 case TOK_SHR:
1267 case TOK_SHL:
1268 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1269 t = vtop[-1].type.t;
1270 vswap();
1271 lexpand();
1272 vrotb(3);
1273 /* stack: L H shift */
1274 c = (int)vtop->c.i;
1275 /* constant: simpler */
1276 /* NOTE: all comments are for SHL. the other cases are
1277 done by swaping words */
1278 vpop();
1279 if (op != TOK_SHL)
1280 vswap();
1281 if (c >= 32) {
1282 /* stack: L H */
1283 vpop();
1284 if (c > 32) {
1285 vpushi(c - 32);
1286 gen_op(op);
1288 if (op != TOK_SAR) {
1289 vpushi(0);
1290 } else {
1291 gv_dup();
1292 vpushi(31);
1293 gen_op(TOK_SAR);
1295 vswap();
1296 } else {
1297 vswap();
1298 gv_dup();
1299 /* stack: H L L */
1300 vpushi(c);
1301 gen_op(op);
1302 vswap();
1303 vpushi(32 - c);
1304 if (op == TOK_SHL)
1305 gen_op(TOK_SHR);
1306 else
1307 gen_op(TOK_SHL);
1308 vrotb(3);
1309 /* stack: L L H */
1310 vpushi(c);
1311 if (op == TOK_SHL)
1312 gen_op(TOK_SHL);
1313 else
1314 gen_op(TOK_SHR);
1315 gen_op('|');
1317 if (op != TOK_SHL)
1318 vswap();
1319 lbuild(t);
1320 } else {
1321 /* XXX: should provide a faster fallback on x86 ? */
1322 switch(op) {
1323 case TOK_SAR:
1324 func = TOK___ashrdi3;
1325 goto gen_func;
1326 case TOK_SHR:
1327 func = TOK___lshrdi3;
1328 goto gen_func;
1329 case TOK_SHL:
1330 func = TOK___ashldi3;
1331 goto gen_func;
1334 break;
1335 default:
1336 /* compare operations */
1337 t = vtop->type.t;
1338 vswap();
1339 lexpand();
1340 vrotb(3);
1341 lexpand();
1342 /* stack: L1 H1 L2 H2 */
1343 tmp = vtop[-1];
1344 vtop[-1] = vtop[-2];
1345 vtop[-2] = tmp;
1346 /* stack: L1 L2 H1 H2 */
1347 /* compare high */
1348 op1 = op;
1349 /* when values are equal, we need to compare low words. since
1350 the jump is inverted, we invert the test too. */
1351 if (op1 == TOK_LT)
1352 op1 = TOK_LE;
1353 else if (op1 == TOK_GT)
1354 op1 = TOK_GE;
1355 else if (op1 == TOK_ULT)
1356 op1 = TOK_ULE;
1357 else if (op1 == TOK_UGT)
1358 op1 = TOK_UGE;
1359 a = 0;
1360 b = 0;
1361 gen_op(op1);
1362 if (op1 != TOK_NE) {
1363 a = gtst(1, 0);
1365 if (op != TOK_EQ) {
1366 /* generate non equal test */
1367 /* XXX: NOT PORTABLE yet */
1368 if (a == 0) {
1369 b = gtst(0, 0);
1370 } else {
1371 #if defined(TCC_TARGET_I386)
1372 b = psym(0x850f, 0);
1373 #elif defined(TCC_TARGET_ARM)
1374 b = ind;
1375 o(0x1A000000 | encbranch(ind, 0, 1));
1376 #elif defined(TCC_TARGET_C67)
1377 tcc_error("not implemented");
1378 #else
1379 #error not supported
1380 #endif
1383 /* compare low. Always unsigned */
1384 op1 = op;
1385 if (op1 == TOK_LT)
1386 op1 = TOK_ULT;
1387 else if (op1 == TOK_LE)
1388 op1 = TOK_ULE;
1389 else if (op1 == TOK_GT)
1390 op1 = TOK_UGT;
1391 else if (op1 == TOK_GE)
1392 op1 = TOK_UGE;
1393 gen_op(op1);
1394 a = gtst(1, a);
1395 gsym(b);
1396 vseti(VT_JMPI, a);
1397 break;
1400 #endif
1402 /* handle integer constant optimizations and various machine
1403 independent opt */
1404 static void gen_opic(int op)
1406 int c1, c2, t1, t2, n;
1407 SValue *v1, *v2;
1408 long long l1, l2;
1409 typedef unsigned long long U;
1411 v1 = vtop - 1;
1412 v2 = vtop;
1413 t1 = v1->type.t & VT_BTYPE;
1414 t2 = v2->type.t & VT_BTYPE;
1416 if (t1 == VT_LLONG)
1417 l1 = v1->c.ll;
1418 else if (v1->type.t & VT_UNSIGNED)
1419 l1 = v1->c.ui;
1420 else
1421 l1 = v1->c.i;
1423 if (t2 == VT_LLONG)
1424 l2 = v2->c.ll;
1425 else if (v2->type.t & VT_UNSIGNED)
1426 l2 = v2->c.ui;
1427 else
1428 l2 = v2->c.i;
1430 /* currently, we cannot do computations with forward symbols */
1431 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1432 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1433 if (c1 && c2) {
1434 switch(op) {
1435 case '+': l1 += l2; break;
1436 case '-': l1 -= l2; break;
1437 case '&': l1 &= l2; break;
1438 case '^': l1 ^= l2; break;
1439 case '|': l1 |= l2; break;
1440 case '*': l1 *= l2; break;
1442 case TOK_PDIV:
1443 case '/':
1444 case '%':
1445 case TOK_UDIV:
1446 case TOK_UMOD:
1447 /* if division by zero, generate explicit division */
1448 if (l2 == 0) {
1449 if (const_wanted)
1450 tcc_error("division by zero in constant");
1451 goto general_case;
1453 switch(op) {
1454 default: l1 /= l2; break;
1455 case '%': l1 %= l2; break;
1456 case TOK_UDIV: l1 = (U)l1 / l2; break;
1457 case TOK_UMOD: l1 = (U)l1 % l2; break;
1459 break;
1460 case TOK_SHL: l1 <<= l2; break;
1461 case TOK_SHR: l1 = (U)l1 >> l2; break;
1462 case TOK_SAR: l1 >>= l2; break;
1463 /* tests */
1464 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1465 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1466 case TOK_EQ: l1 = l1 == l2; break;
1467 case TOK_NE: l1 = l1 != l2; break;
1468 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1469 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1470 case TOK_LT: l1 = l1 < l2; break;
1471 case TOK_GE: l1 = l1 >= l2; break;
1472 case TOK_LE: l1 = l1 <= l2; break;
1473 case TOK_GT: l1 = l1 > l2; break;
1474 /* logical */
1475 case TOK_LAND: l1 = l1 && l2; break;
1476 case TOK_LOR: l1 = l1 || l2; break;
1477 default:
1478 goto general_case;
1480 v1->c.ll = l1;
1481 vtop--;
1482 } else {
1483 /* if commutative ops, put c2 as constant */
1484 if (c1 && (op == '+' || op == '&' || op == '^' ||
1485 op == '|' || op == '*')) {
1486 vswap();
1487 c2 = c1; //c = c1, c1 = c2, c2 = c;
1488 l2 = l1; //l = l1, l1 = l2, l2 = l;
1490 /* Filter out NOP operations like x*1, x-0, x&-1... */
1491 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1492 op == TOK_PDIV) &&
1493 l2 == 1) ||
1494 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1495 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1496 l2 == 0) ||
1497 (op == '&' &&
1498 l2 == -1))) {
1499 /* nothing to do */
1500 vtop--;
1501 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1502 /* try to use shifts instead of muls or divs */
1503 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1504 n = -1;
1505 while (l2) {
1506 l2 >>= 1;
1507 n++;
1509 vtop->c.ll = n;
1510 if (op == '*')
1511 op = TOK_SHL;
1512 else if (op == TOK_PDIV)
1513 op = TOK_SAR;
1514 else
1515 op = TOK_SHR;
1517 goto general_case;
1518 } else if (c2 && (op == '+' || op == '-') &&
1519 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1520 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1521 /* symbol + constant case */
1522 if (op == '-')
1523 l2 = -l2;
1524 vtop--;
1525 vtop->c.ll += l2;
1526 } else {
1527 general_case:
1528 if (!nocode_wanted) {
1529 /* call low level op generator */
1530 if (t1 == VT_LLONG || t2 == VT_LLONG)
1531 gen_opl(op);
1532 else
1533 gen_opi(op);
1534 } else {
1535 vtop--;
1541 /* generate a floating point operation with constant propagation */
1542 static void gen_opif(int op)
1544 int c1, c2;
1545 SValue *v1, *v2;
1546 long double f1, f2;
1548 v1 = vtop - 1;
1549 v2 = vtop;
1550 /* currently, we cannot do computations with forward symbols */
1551 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1552 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1553 if (c1 && c2) {
1554 if (v1->type.t == VT_FLOAT) {
1555 f1 = v1->c.f;
1556 f2 = v2->c.f;
1557 } else if (v1->type.t == VT_DOUBLE) {
1558 f1 = v1->c.d;
1559 f2 = v2->c.d;
1560 } else {
1561 f1 = v1->c.ld;
1562 f2 = v2->c.ld;
1565 /* NOTE: we only do constant propagation if finite number (not
1566 NaN or infinity) (ANSI spec) */
1567 if (!ieee_finite(f1) || !ieee_finite(f2))
1568 goto general_case;
1570 switch(op) {
1571 case '+': f1 += f2; break;
1572 case '-': f1 -= f2; break;
1573 case '*': f1 *= f2; break;
1574 case '/':
1575 if (f2 == 0.0) {
1576 if (const_wanted)
1577 tcc_error("division by zero in constant");
1578 goto general_case;
1580 f1 /= f2;
1581 break;
1582 /* XXX: also handles tests ? */
1583 default:
1584 goto general_case;
1586 /* XXX: overflow test ? */
1587 if (v1->type.t == VT_FLOAT) {
1588 v1->c.f = f1;
1589 } else if (v1->type.t == VT_DOUBLE) {
1590 v1->c.d = f1;
1591 } else {
1592 v1->c.ld = f1;
1594 vtop--;
1595 } else {
1596 general_case:
1597 if (!nocode_wanted) {
1598 gen_opf(op);
1599 } else {
1600 vtop--;
1605 static int pointed_size(CType *type)
1607 int align;
1608 return type_size(pointed_type(type), &align);
1611 static void vla_runtime_pointed_size(CType *type)
1613 int align;
1614 vla_runtime_type_size(pointed_type(type), &align);
1617 static inline int is_null_pointer(SValue *p)
1619 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1620 return 0;
1621 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1622 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1623 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0);
1626 static inline int is_integer_btype(int bt)
1628 return (bt == VT_BYTE || bt == VT_SHORT ||
1629 bt == VT_INT || bt == VT_LLONG);
1632 /* check types for comparison or subtraction of pointers */
1633 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1635 CType *type1, *type2, tmp_type1, tmp_type2;
1636 int bt1, bt2;
1638 /* null pointers are accepted for all comparisons as gcc */
1639 if (is_null_pointer(p1) || is_null_pointer(p2))
1640 return;
1641 type1 = &p1->type;
1642 type2 = &p2->type;
1643 bt1 = type1->t & VT_BTYPE;
1644 bt2 = type2->t & VT_BTYPE;
1645 /* accept comparison between pointer and integer with a warning */
1646 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1647 if (op != TOK_LOR && op != TOK_LAND )
1648 tcc_warning("comparison between pointer and integer");
1649 return;
1652 /* both must be pointers or implicit function pointers */
1653 if (bt1 == VT_PTR) {
1654 type1 = pointed_type(type1);
1655 } else if (bt1 != VT_FUNC)
1656 goto invalid_operands;
1658 if (bt2 == VT_PTR) {
1659 type2 = pointed_type(type2);
1660 } else if (bt2 != VT_FUNC) {
1661 invalid_operands:
1662 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1664 if ((type1->t & VT_BTYPE) == VT_VOID ||
1665 (type2->t & VT_BTYPE) == VT_VOID)
1666 return;
1667 tmp_type1 = *type1;
1668 tmp_type2 = *type2;
1669 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1670 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1671 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1672 /* gcc-like error if '-' is used */
1673 if (op == '-')
1674 goto invalid_operands;
1675 else
1676 tcc_warning("comparison of distinct pointer types lacks a cast");
1680 /* generic gen_op: handles types problems */
1681 ST_FUNC void gen_op(int op)
1683 int u, t1, t2, bt1, bt2, t;
1684 CType type1;
1686 t1 = vtop[-1].type.t;
1687 t2 = vtop[0].type.t;
1688 bt1 = t1 & VT_BTYPE;
1689 bt2 = t2 & VT_BTYPE;
1691 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1692 /* at least one operand is a pointer */
1693 /* relationnal op: must be both pointers */
1694 if (op >= TOK_ULT && op <= TOK_LOR) {
1695 check_comparison_pointer_types(vtop - 1, vtop, op);
1696 /* pointers are handled are unsigned */
1697 #ifdef TCC_TARGET_X86_64
1698 t = VT_LLONG | VT_UNSIGNED;
1699 #else
1700 t = VT_INT | VT_UNSIGNED;
1701 #endif
1702 goto std_op;
1704 /* if both pointers, then it must be the '-' op */
1705 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1706 if (op != '-')
1707 tcc_error("cannot use pointers here");
1708 check_comparison_pointer_types(vtop - 1, vtop, op);
1709 /* XXX: check that types are compatible */
1710 if (vtop[-1].type.t & VT_VLA) {
1711 vla_runtime_pointed_size(&vtop[-1].type);
1712 } else {
1713 vpushi(pointed_size(&vtop[-1].type));
1715 vrott(3);
1716 gen_opic(op);
1717 /* set to integer type */
1718 #ifdef TCC_TARGET_X86_64
1719 vtop->type.t = VT_LLONG;
1720 #else
1721 vtop->type.t = VT_INT;
1722 #endif
1723 vswap();
1724 gen_op(TOK_PDIV);
1725 } else {
1726 /* exactly one pointer : must be '+' or '-'. */
1727 if (op != '-' && op != '+')
1728 tcc_error("cannot use pointers here");
1729 /* Put pointer as first operand */
1730 if (bt2 == VT_PTR) {
1731 vswap();
1732 swap(&t1, &t2);
1734 type1 = vtop[-1].type;
1735 type1.t &= ~VT_ARRAY;
1736 if (vtop[-1].type.t & VT_VLA)
1737 vla_runtime_pointed_size(&vtop[-1].type);
1738 else {
1739 u = pointed_size(&vtop[-1].type);
1740 if (u < 0)
1741 tcc_error("unknown array element size");
1742 #ifdef TCC_TARGET_X86_64
1743 vpushll(u);
1744 #else
1745 /* XXX: cast to int ? (long long case) */
1746 vpushi(u);
1747 #endif
1749 gen_op('*');
1750 #ifdef CONFIG_TCC_BCHECK
1751 /* if evaluating constant expression, no code should be
1752 generated, so no bound check */
1753 if (tcc_state->do_bounds_check && !const_wanted) {
1754 /* if bounded pointers, we generate a special code to
1755 test bounds */
1756 if (op == '-') {
1757 vpushi(0);
1758 vswap();
1759 gen_op('-');
1761 gen_bounded_ptr_add();
1762 } else
1763 #endif
1765 gen_opic(op);
1767 /* put again type if gen_opic() swaped operands */
1768 vtop->type = type1;
1770 } else if (is_float(bt1) || is_float(bt2)) {
1771 /* compute bigger type and do implicit casts */
1772 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1773 t = VT_LDOUBLE;
1774 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1775 t = VT_DOUBLE;
1776 } else {
1777 t = VT_FLOAT;
1779 /* floats can only be used for a few operations */
1780 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1781 (op < TOK_ULT || op > TOK_GT))
1782 tcc_error("invalid operands for binary operation");
1783 goto std_op;
1784 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1785 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1786 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1787 t |= VT_UNSIGNED;
1788 goto std_op;
1789 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1790 /* cast to biggest op */
1791 t = VT_LLONG;
1792 /* convert to unsigned if it does not fit in a long long */
1793 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1794 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1795 t |= VT_UNSIGNED;
1796 goto std_op;
1797 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1798 tcc_error("comparison of struct");
1799 } else {
1800 /* integer operations */
1801 t = VT_INT;
1802 /* convert to unsigned if it does not fit in an integer */
1803 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1804 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1805 t |= VT_UNSIGNED;
1806 std_op:
1807 /* XXX: currently, some unsigned operations are explicit, so
1808 we modify them here */
1809 if (t & VT_UNSIGNED) {
1810 if (op == TOK_SAR)
1811 op = TOK_SHR;
1812 else if (op == '/')
1813 op = TOK_UDIV;
1814 else if (op == '%')
1815 op = TOK_UMOD;
1816 else if (op == TOK_LT)
1817 op = TOK_ULT;
1818 else if (op == TOK_GT)
1819 op = TOK_UGT;
1820 else if (op == TOK_LE)
1821 op = TOK_ULE;
1822 else if (op == TOK_GE)
1823 op = TOK_UGE;
1825 vswap();
1826 type1.t = t;
1827 gen_cast(&type1);
1828 vswap();
1829 /* special case for shifts and long long: we keep the shift as
1830 an integer */
1831 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1832 type1.t = VT_INT;
1833 gen_cast(&type1);
1834 if (is_float(t))
1835 gen_opif(op);
1836 else
1837 gen_opic(op);
1838 if (op >= TOK_ULT && op <= TOK_GT) {
1839 /* relationnal op: the result is an int */
1840 vtop->type.t = VT_INT;
1841 } else {
1842 vtop->type.t = t;
1847 #ifndef TCC_TARGET_ARM
1848 /* generic itof for unsigned long long case */
1849 static void gen_cvt_itof1(int t)
1851 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1852 (VT_LLONG | VT_UNSIGNED)) {
1854 if (t == VT_FLOAT)
1855 vpush_global_sym(&func_old_type, TOK___floatundisf);
1856 #if LDOUBLE_SIZE != 8
1857 else if (t == VT_LDOUBLE)
1858 vpush_global_sym(&func_old_type, TOK___floatundixf);
1859 #endif
1860 else
1861 vpush_global_sym(&func_old_type, TOK___floatundidf);
1862 vrott(2);
1863 gfunc_call(1);
1864 vpushi(0);
1865 vtop->r = reg_fret(t);
1866 } else {
1867 gen_cvt_itof(t);
1870 #endif
1872 /* generic ftoi for unsigned long long case */
1873 static void gen_cvt_ftoi1(int t)
1875 int st;
1877 if (t == (VT_LLONG | VT_UNSIGNED)) {
1878 /* not handled natively */
1879 st = vtop->type.t & VT_BTYPE;
1880 if (st == VT_FLOAT)
1881 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1882 #if LDOUBLE_SIZE != 8
1883 else if (st == VT_LDOUBLE)
1884 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1885 #endif
1886 else
1887 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1888 vrott(2);
1889 gfunc_call(1);
1890 vpushi(0);
1891 vtop->r = REG_IRET;
1892 vtop->r2 = REG_LRET;
1893 } else {
1894 gen_cvt_ftoi(t);
1898 /* force char or short cast */
1899 static void force_charshort_cast(int t)
1901 int bits, dbt;
1902 dbt = t & VT_BTYPE;
1903 /* XXX: add optimization if lvalue : just change type and offset */
1904 if (dbt == VT_BYTE)
1905 bits = 8;
1906 else
1907 bits = 16;
1908 if (t & VT_UNSIGNED) {
1909 vpushi((1 << bits) - 1);
1910 gen_op('&');
1911 } else {
1912 bits = 32 - bits;
1913 vpushi(bits);
1914 gen_op(TOK_SHL);
1915 /* result must be signed or the SAR is converted to an SHL
1916 This was not the case when "t" was a signed short
1917 and the last value on the stack was an unsigned int */
1918 vtop->type.t &= ~VT_UNSIGNED;
1919 vpushi(bits);
1920 gen_op(TOK_SAR);
1924 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1925 static void gen_cast(CType *type)
1927 int sbt, dbt, sf, df, c, p;
1929 /* special delayed cast for char/short */
1930 /* XXX: in some cases (multiple cascaded casts), it may still
1931 be incorrect */
1932 if (vtop->r & VT_MUSTCAST) {
1933 vtop->r &= ~VT_MUSTCAST;
1934 force_charshort_cast(vtop->type.t);
1937 /* bitfields first get cast to ints */
1938 if (vtop->type.t & VT_BITFIELD) {
1939 gv(RC_INT);
1942 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1943 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1945 if (sbt != dbt) {
1946 sf = is_float(sbt);
1947 df = is_float(dbt);
1948 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1949 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1950 if (c) {
1951 /* constant case: we can do it now */
1952 /* XXX: in ISOC, cannot do it if error in convert */
1953 if (sbt == VT_FLOAT)
1954 vtop->c.ld = vtop->c.f;
1955 else if (sbt == VT_DOUBLE)
1956 vtop->c.ld = vtop->c.d;
1958 if (df) {
1959 if ((sbt & VT_BTYPE) == VT_LLONG) {
1960 if (sbt & VT_UNSIGNED)
1961 vtop->c.ld = vtop->c.ull;
1962 else
1963 vtop->c.ld = vtop->c.ll;
1964 } else if(!sf) {
1965 if (sbt & VT_UNSIGNED)
1966 vtop->c.ld = vtop->c.ui;
1967 else
1968 vtop->c.ld = vtop->c.i;
1971 if (dbt == VT_FLOAT)
1972 vtop->c.f = (float)vtop->c.ld;
1973 else if (dbt == VT_DOUBLE)
1974 vtop->c.d = (double)vtop->c.ld;
1975 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1976 vtop->c.ull = (unsigned long long)vtop->c.ld;
1977 } else if (sf && dbt == VT_BOOL) {
1978 vtop->c.i = (vtop->c.ld != 0);
1979 } else {
1980 if(sf)
1981 vtop->c.ll = (long long)vtop->c.ld;
1982 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1983 vtop->c.ll = vtop->c.ull;
1984 else if (sbt & VT_UNSIGNED)
1985 vtop->c.ll = vtop->c.ui;
1986 #ifdef TCC_TARGET_X86_64
1987 else if (sbt == VT_PTR)
1989 #endif
1990 else if (sbt != VT_LLONG)
1991 vtop->c.ll = vtop->c.i;
1993 if (dbt == (VT_LLONG|VT_UNSIGNED))
1994 vtop->c.ull = vtop->c.ll;
1995 else if (dbt == VT_BOOL)
1996 vtop->c.i = (vtop->c.ll != 0);
1997 #ifdef TCC_TARGET_X86_64
1998 else if (dbt == VT_PTR)
2000 #endif
2001 else if (dbt != VT_LLONG) {
2002 int s = 0;
2003 if ((dbt & VT_BTYPE) == VT_BYTE)
2004 s = 24;
2005 else if ((dbt & VT_BTYPE) == VT_SHORT)
2006 s = 16;
2007 if(dbt & VT_UNSIGNED)
2008 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
2009 else
2010 vtop->c.i = ((int)vtop->c.ll << s) >> s;
2013 } else if (p && dbt == VT_BOOL) {
2014 vtop->r = VT_CONST;
2015 vtop->c.i = 1;
2016 } else if (!nocode_wanted) {
2017 /* non constant case: generate code */
2018 if (sf && df) {
2019 /* convert from fp to fp */
2020 gen_cvt_ftof(dbt);
2021 } else if (df) {
2022 /* convert int to fp */
2023 gen_cvt_itof1(dbt);
2024 } else if (sf) {
2025 /* convert fp to int */
2026 if (dbt == VT_BOOL) {
2027 vpushi(0);
2028 gen_op(TOK_NE);
2029 } else {
2030 /* we handle char/short/etc... with generic code */
2031 if (dbt != (VT_INT | VT_UNSIGNED) &&
2032 dbt != (VT_LLONG | VT_UNSIGNED) &&
2033 dbt != VT_LLONG)
2034 dbt = VT_INT;
2035 gen_cvt_ftoi1(dbt);
2036 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2037 /* additional cast for char/short... */
2038 vtop->type.t = dbt;
2039 gen_cast(type);
2042 #ifndef TCC_TARGET_X86_64
2043 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2044 if ((sbt & VT_BTYPE) != VT_LLONG) {
2045 /* scalar to long long */
2046 /* machine independent conversion */
2047 gv(RC_INT);
2048 /* generate high word */
2049 if (sbt == (VT_INT | VT_UNSIGNED)) {
2050 vpushi(0);
2051 gv(RC_INT);
2052 } else {
2053 if (sbt == VT_PTR) {
2054 /* cast from pointer to int before we apply
2055 shift operation, which pointers don't support*/
2056 gen_cast(&int_type);
2058 gv_dup();
2059 vpushi(31);
2060 gen_op(TOK_SAR);
2062 /* patch second register */
2063 vtop[-1].r2 = vtop->r;
2064 vpop();
2066 #else
2067 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2068 (dbt & VT_BTYPE) == VT_PTR ||
2069 (dbt & VT_BTYPE) == VT_FUNC) {
2070 if ((sbt & VT_BTYPE) != VT_LLONG &&
2071 (sbt & VT_BTYPE) != VT_PTR &&
2072 (sbt & VT_BTYPE) != VT_FUNC) {
2073 /* need to convert from 32bit to 64bit */
2074 int r = gv(RC_INT);
2075 if (sbt != (VT_INT | VT_UNSIGNED)) {
2076 /* x86_64 specific: movslq */
2077 o(0x6348);
2078 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2081 #endif
2082 } else if (dbt == VT_BOOL) {
2083 /* scalar to bool */
2084 vpushi(0);
2085 gen_op(TOK_NE);
2086 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2087 (dbt & VT_BTYPE) == VT_SHORT) {
2088 if (sbt == VT_PTR) {
2089 vtop->type.t = VT_INT;
2090 tcc_warning("nonportable conversion from pointer to char/short");
2092 force_charshort_cast(dbt);
2093 } else if ((dbt & VT_BTYPE) == VT_INT) {
2094 /* scalar to int */
2095 if (sbt == VT_LLONG) {
2096 /* from long long: just take low order word */
2097 lexpand();
2098 vpop();
2100 /* if lvalue and single word type, nothing to do because
2101 the lvalue already contains the real type size (see
2102 VT_LVAL_xxx constants) */
2105 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2106 /* if we are casting between pointer types,
2107 we must update the VT_LVAL_xxx size */
2108 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2109 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2111 vtop->type = *type;
2114 /* return type size as known at compile time. Put alignment at 'a' */
2115 ST_FUNC int type_size(CType *type, int *a)
2117 Sym *s;
2118 int bt;
2120 bt = type->t & VT_BTYPE;
2121 if (bt == VT_STRUCT) {
2122 /* struct/union */
2123 s = type->ref;
2124 *a = s->r;
2125 return s->c;
2126 } else if (bt == VT_PTR) {
2127 if (type->t & VT_ARRAY) {
2128 int ts;
2130 s = type->ref;
2131 ts = type_size(&s->type, a);
2133 if (ts < 0 && s->c < 0)
2134 ts = -ts;
2136 return ts * s->c;
2137 } else {
2138 *a = PTR_SIZE;
2139 return PTR_SIZE;
2141 } else if (bt == VT_LDOUBLE) {
2142 *a = LDOUBLE_ALIGN;
2143 return LDOUBLE_SIZE;
2144 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2145 #ifdef TCC_TARGET_I386
2146 #ifdef TCC_TARGET_PE
2147 *a = 8;
2148 #else
2149 *a = 4;
2150 #endif
2151 #elif defined(TCC_TARGET_ARM)
2152 #ifdef TCC_ARM_EABI
2153 *a = 8;
2154 #else
2155 *a = 4;
2156 #endif
2157 #else
2158 *a = 8;
2159 #endif
2160 return 8;
2161 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2162 *a = 4;
2163 return 4;
2164 } else if (bt == VT_SHORT) {
2165 *a = 2;
2166 return 2;
2167 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2168 *a = 8;
2169 return 16;
2170 } else {
2171 /* char, void, function, _Bool */
2172 *a = 1;
2173 return 1;
2177 /* push type size as known at runtime time on top of value stack. Put
2178 alignment at 'a' */
2179 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2181 if (type->t & VT_VLA) {
2182 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2183 } else {
2184 vpushi(type_size(type, a));
2188 static void vla_sp_save(void) {
2189 if (!(vla_flags & VLA_SP_LOC_SET)) {
2190 *vla_sp_loc = (loc -= PTR_SIZE);
2191 vla_flags |= VLA_SP_LOC_SET;
2193 if (!(vla_flags & VLA_SP_SAVED)) {
2194 gen_vla_sp_save(*vla_sp_loc);
2195 vla_flags |= VLA_SP_SAVED;
2199 /* return the pointed type of t */
2200 static inline CType *pointed_type(CType *type)
2202 return &type->ref->type;
2205 /* modify type so that its it is a pointer to type. */
2206 ST_FUNC void mk_pointer(CType *type)
2208 Sym *s;
2209 s = sym_push(SYM_FIELD, type, 0, -1);
2210 type->t = VT_PTR | (type->t & ~VT_TYPE);
2211 type->ref = s;
2214 /* compare function types. OLD functions match any new functions */
2215 static int is_compatible_func(CType *type1, CType *type2)
2217 Sym *s1, *s2;
2219 s1 = type1->ref;
2220 s2 = type2->ref;
2221 if (!is_compatible_types(&s1->type, &s2->type))
2222 return 0;
2223 /* check func_call */
2224 if (s1->a.func_call != s2->a.func_call)
2225 return 0;
2226 /* XXX: not complete */
2227 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2228 return 1;
2229 if (s1->c != s2->c)
2230 return 0;
2231 while (s1 != NULL) {
2232 if (s2 == NULL)
2233 return 0;
2234 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2235 return 0;
2236 s1 = s1->next;
2237 s2 = s2->next;
2239 if (s2)
2240 return 0;
2241 return 1;
2244 /* return true if type1 and type2 are the same. If unqualified is
2245 true, qualifiers on the types are ignored.
2247 - enums are not checked as gcc __builtin_types_compatible_p ()
2249 static int compare_types(CType *type1, CType *type2, int unqualified)
2251 int bt1, t1, t2;
2253 t1 = type1->t & VT_TYPE;
2254 t2 = type2->t & VT_TYPE;
2255 if (unqualified) {
2256 /* strip qualifiers before comparing */
2257 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2258 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2260 /* Default Vs explicit signedness only matters for char */
2261 if ((t1 & VT_BTYPE) != VT_BYTE) {
2262 t1 &= ~VT_DEFSIGN;
2263 t2 &= ~VT_DEFSIGN;
2265 /* XXX: bitfields ? */
2266 if (t1 != t2)
2267 return 0;
2268 /* test more complicated cases */
2269 bt1 = t1 & VT_BTYPE;
2270 if (bt1 == VT_PTR) {
2271 type1 = pointed_type(type1);
2272 type2 = pointed_type(type2);
2273 return is_compatible_types(type1, type2);
2274 } else if (bt1 == VT_STRUCT) {
2275 return (type1->ref == type2->ref);
2276 } else if (bt1 == VT_FUNC) {
2277 return is_compatible_func(type1, type2);
2278 } else {
2279 return 1;
2283 /* return true if type1 and type2 are exactly the same (including
2284 qualifiers).
2286 static int is_compatible_types(CType *type1, CType *type2)
2288 return compare_types(type1,type2,0);
2291 /* return true if type1 and type2 are the same (ignoring qualifiers).
2293 static int is_compatible_parameter_types(CType *type1, CType *type2)
2295 return compare_types(type1,type2,1);
2298 /* print a type. If 'varstr' is not NULL, then the variable is also
2299 printed in the type */
2300 /* XXX: union */
2301 /* XXX: add array and function pointers */
2302 static void type_to_str(char *buf, int buf_size,
2303 CType *type, const char *varstr)
2305 int bt, v, t;
2306 Sym *s, *sa;
2307 char buf1[256];
2308 const char *tstr;
2310 t = type->t & VT_TYPE;
2311 bt = t & VT_BTYPE;
2312 buf[0] = '\0';
2313 if (t & VT_CONSTANT)
2314 pstrcat(buf, buf_size, "const ");
2315 if (t & VT_VOLATILE)
2316 pstrcat(buf, buf_size, "volatile ");
2317 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2318 pstrcat(buf, buf_size, "unsigned ");
2319 else if (t & VT_DEFSIGN)
2320 pstrcat(buf, buf_size, "signed ");
2321 switch(bt) {
2322 case VT_VOID:
2323 tstr = "void";
2324 goto add_tstr;
2325 case VT_BOOL:
2326 tstr = "_Bool";
2327 goto add_tstr;
2328 case VT_BYTE:
2329 tstr = "char";
2330 goto add_tstr;
2331 case VT_SHORT:
2332 tstr = "short";
2333 goto add_tstr;
2334 case VT_INT:
2335 tstr = "int";
2336 goto add_tstr;
2337 case VT_LONG:
2338 tstr = "long";
2339 goto add_tstr;
2340 case VT_LLONG:
2341 tstr = "long long";
2342 goto add_tstr;
2343 case VT_FLOAT:
2344 tstr = "float";
2345 goto add_tstr;
2346 case VT_DOUBLE:
2347 tstr = "double";
2348 goto add_tstr;
2349 case VT_LDOUBLE:
2350 tstr = "long double";
2351 add_tstr:
2352 pstrcat(buf, buf_size, tstr);
2353 break;
2354 case VT_ENUM:
2355 case VT_STRUCT:
2356 if (bt == VT_STRUCT)
2357 tstr = "struct ";
2358 else
2359 tstr = "enum ";
2360 pstrcat(buf, buf_size, tstr);
2361 v = type->ref->v & ~SYM_STRUCT;
2362 if (v >= SYM_FIRST_ANOM)
2363 pstrcat(buf, buf_size, "<anonymous>");
2364 else
2365 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2366 break;
2367 case VT_FUNC:
2368 s = type->ref;
2369 type_to_str(buf, buf_size, &s->type, varstr);
2370 pstrcat(buf, buf_size, "(");
2371 sa = s->next;
2372 while (sa != NULL) {
2373 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2374 pstrcat(buf, buf_size, buf1);
2375 sa = sa->next;
2376 if (sa)
2377 pstrcat(buf, buf_size, ", ");
2379 pstrcat(buf, buf_size, ")");
2380 goto no_var;
2381 case VT_PTR:
2382 s = type->ref;
2383 pstrcpy(buf1, sizeof(buf1), "*");
2384 if (varstr)
2385 pstrcat(buf1, sizeof(buf1), varstr);
2386 type_to_str(buf, buf_size, &s->type, buf1);
2387 goto no_var;
2389 if (varstr) {
2390 pstrcat(buf, buf_size, " ");
2391 pstrcat(buf, buf_size, varstr);
2393 no_var: ;
2396 /* verify type compatibility to store vtop in 'dt' type, and generate
2397 casts if needed. */
2398 static void gen_assign_cast(CType *dt)
2400 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2401 char buf1[256], buf2[256];
2402 int dbt, sbt;
2404 st = &vtop->type; /* source type */
2405 dbt = dt->t & VT_BTYPE;
2406 sbt = st->t & VT_BTYPE;
2407 if (sbt == VT_VOID || dbt == VT_VOID)
2408 tcc_error("cannot cast from/to void");
2409 if (dt->t & VT_CONSTANT)
2410 tcc_warning("assignment of read-only location");
2411 switch(dbt) {
2412 case VT_PTR:
2413 /* special cases for pointers */
2414 /* '0' can also be a pointer */
2415 if (is_null_pointer(vtop))
2416 goto type_ok;
2417 /* accept implicit pointer to integer cast with warning */
2418 if (is_integer_btype(sbt)) {
2419 tcc_warning("assignment makes pointer from integer without a cast");
2420 goto type_ok;
2422 type1 = pointed_type(dt);
2423 /* a function is implicitely a function pointer */
2424 if (sbt == VT_FUNC) {
2425 if ((type1->t & VT_BTYPE) != VT_VOID &&
2426 !is_compatible_types(pointed_type(dt), st))
2427 tcc_warning("assignment from incompatible pointer type");
2428 goto type_ok;
2430 if (sbt != VT_PTR)
2431 goto error;
2432 type2 = pointed_type(st);
2433 if ((type1->t & VT_BTYPE) == VT_VOID ||
2434 (type2->t & VT_BTYPE) == VT_VOID) {
2435 /* void * can match anything */
2436 } else {
2437 /* exact type match, except for unsigned */
2438 tmp_type1 = *type1;
2439 tmp_type2 = *type2;
2440 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2441 VT_VOLATILE);
2442 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2443 VT_VOLATILE);
2444 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2445 tcc_warning("assignment from incompatible pointer type");
2447 /* check const and volatile */
2448 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2449 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2450 tcc_warning("assignment discards qualifiers from pointer target type");
2451 break;
2452 case VT_BYTE:
2453 case VT_SHORT:
2454 case VT_INT:
2455 case VT_LLONG:
2456 if (sbt == VT_PTR || sbt == VT_FUNC) {
2457 tcc_warning("assignment makes integer from pointer without a cast");
2459 /* XXX: more tests */
2460 break;
2461 case VT_STRUCT:
2462 tmp_type1 = *dt;
2463 tmp_type2 = *st;
2464 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2465 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2466 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2467 error:
2468 type_to_str(buf1, sizeof(buf1), st, NULL);
2469 type_to_str(buf2, sizeof(buf2), dt, NULL);
2470 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2472 break;
2474 type_ok:
2475 gen_cast(dt);
2478 static void vstore_im(){
2479 int rc, ft, sbt, dbt, t, r;
2480 ft = vtop[-1].type.t;
2481 sbt = vtop->type.t & VT_BTYPE;
2482 dbt = ft & VT_BTYPE;
2483 if (is_float(ft)) {
2484 rc = RC_FLOAT;
2485 #ifdef TCC_TARGET_X86_64
2486 if (dbt == VT_LDOUBLE) {
2487 rc = RC_ST0;
2489 #endif
2490 }else
2491 rc = RC_INT;
2492 r = gv(rc); /* generate value */
2493 /* if lvalue was saved on stack, must read it */
2494 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2495 SValue sv;
2496 t = get_reg(RC_INT);
2497 #ifdef TCC_TARGET_X86_64
2498 sv.type.t = VT_PTR;
2499 #else
2500 sv.type.t = VT_INT;
2501 #endif
2502 sv.r = VT_LOCAL | VT_LVAL;
2503 sv.c.ul = vtop[-1].c.ul;
2504 load(t, &sv);
2505 vtop[-1].r = t | VT_LVAL;
2506 vtop[-1].c.ul = 0;
2508 /* two word case handling : store second register at word + 4 */
2509 #ifdef TCC_TARGET_X86_64
2510 if ((dbt == VT_QLONG) || (dbt == VT_QFLOAT))
2511 #else
2512 if (dbt == VT_LLONG)
2513 #endif
2515 #ifdef TCC_TARGET_X86_64
2516 int load_size = 8, load_type = (sbt == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2517 #else
2518 int load_size = 4, load_type = VT_INT;
2519 #endif
2520 vtop[-1].type.t = load_type;
2521 store(r, vtop - 1);
2522 vswap();
2523 /* convert to int to increment easily */
2524 vtop->type = char_pointer_type;
2525 gaddrof();
2526 vpushi(load_size);
2527 gen_op('+');
2528 vtop->r |= VT_LVAL;
2529 vswap();
2530 vtop[-1].type.t = load_type;
2531 /* XXX: it works because r2 is spilled last ! */
2532 store(vtop->r2, vtop - 1);
2533 vtop->type.t = ft;
2534 vtop[-1].type.t = ft;
2535 } else {
2536 store(r, vtop - 1);
2540 /* store vtop in lvalue pushed on stack */
2541 ST_FUNC void vstore(void)
2543 int sbt, dbt, ft, size, align, bit_size, bit_pos, delayed_cast;
2545 ft = vtop[-1].type.t;
2546 sbt = vtop->type.t & VT_BTYPE;
2547 dbt = ft & VT_BTYPE;
2548 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2549 (sbt == VT_INT && dbt == VT_SHORT)) && !(vtop->type.t & VT_BITFIELD)) {
2550 /* optimize char/short casts */
2551 delayed_cast = VT_MUSTCAST;
2552 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2553 /* XXX: factorize */
2554 if (ft & VT_CONSTANT)
2555 tcc_warning("assignment of read-only location");
2556 } else {
2557 delayed_cast = 0;
2558 if (!(ft & VT_BITFIELD))
2559 gen_assign_cast(&vtop[-1].type);
2562 if (sbt == VT_STRUCT) {
2563 /* if structure, only generate pointer */
2564 /* structure assignment : generate memcpy */
2565 /* XXX: optimize if small size */
2566 if (!nocode_wanted) {
2567 size = type_size(&vtop->type, &align);
2569 /* destination */
2570 vswap();
2571 vtop->type.t = VT_PTR;
2572 gaddrof();
2574 /* address of memcpy() */
2575 #ifdef TCC_ARM_EABI
2576 if(!(align & 7))
2577 vpush_global_sym(&func_old_type, TOK_memcpy8);
2578 else if(!(align & 3))
2579 vpush_global_sym(&func_old_type, TOK_memcpy4);
2580 else
2581 #endif
2582 vpush_global_sym(&func_old_type, TOK_memcpy);
2584 vswap();
2585 /* source */
2586 vpushv(vtop - 2);
2587 vtop->type.t = VT_PTR;
2588 gaddrof();
2589 /* type size */
2590 vpushi(size);
2591 gfunc_call(3);
2592 } else {
2593 vswap();
2594 vpop();
2596 /* leave source on stack */
2597 } else if (ft & VT_BITFIELD) {
2598 /* bitfield store handling */
2599 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2600 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2601 /* remove bit field info to avoid loops */
2602 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2604 /* duplicate source into other register */
2605 if((ft & VT_BTYPE) == VT_BOOL) {
2606 gen_cast(&vtop[-1].type);
2607 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2610 /* duplicate destination */
2611 vdup();
2612 vtop[-1] = vtop[-2];
2614 /* duplicate destination */
2615 vdup();
2616 vtop[-1] = vtop[-2];
2618 /* mask and shift source */
2619 if((ft & VT_BTYPE) != VT_BOOL) {
2620 if((ft & VT_BTYPE) == VT_LLONG) {
2621 vpushll((1ULL << bit_size) - 1ULL);
2622 } else {
2623 vpushi((1 << bit_size) - 1);
2625 gen_op('&');
2627 vpushi(bit_pos);
2628 gen_op(TOK_SHL);
2629 /* load destination, mask and or with source */
2630 vswap();
2631 if((ft & VT_BTYPE) == VT_LLONG) {
2632 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2633 } else {
2634 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2636 gen_op('&');
2637 gen_op('|');
2638 /* store result */
2639 vstore();
2641 /* pop off shifted source from "duplicate source..." above */
2642 vpop();
2644 } else {
2645 #ifdef CONFIG_TCC_BCHECK
2646 /* bound check case */
2647 if (vtop[-1].r & VT_MUSTBOUND) {
2648 vswap();
2649 gbound();
2650 vswap();
2652 #endif
2653 if (!nocode_wanted) {
2654 vstore_im();
2656 vswap();
2657 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2658 vtop->r |= delayed_cast;
2662 /* post defines POST/PRE add. c is the token ++ or -- */
2663 ST_FUNC void inc(int post, int c)
2665 test_lvalue();
2666 vdup(); /* save lvalue */
2667 if (post) {
2668 gv_dup(); /* duplicate value */
2669 vrotb(3);
2670 vrotb(3);
2672 /* add constant */
2673 vpushi(c - TOK_MID);
2674 gen_op('+');
2675 vstore(); /* store value */
2676 if (post)
2677 vpop(); /* if post op, return saved value */
2680 /* Parse GNUC __attribute__ extension. Currently, the following
2681 extensions are recognized:
2682 - aligned(n) : set data/function alignment.
2683 - packed : force data alignment to 1
2684 - section(x) : generate data/code in this section.
2685 - unused : currently ignored, but may be used someday.
2686 - regparm(n) : pass function parameters in registers (i386 only)
2688 static void parse_attribute(AttributeDef *ad)
2690 int t, n;
2692 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2693 next();
2694 skip('(');
2695 skip('(');
2696 while (tok != ')') {
2697 if (tok < TOK_IDENT)
2698 expect("attribute name");
2699 t = tok;
2700 next();
2701 switch(t) {
2702 case TOK_SECTION1:
2703 case TOK_SECTION2:
2704 skip('(');
2705 if (tok != TOK_STR)
2706 expect("section name");
2707 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2708 next();
2709 skip(')');
2710 break;
2711 case TOK_ALIAS1:
2712 case TOK_ALIAS2:
2713 skip('(');
2714 if (tok != TOK_STR)
2715 expect("alias(\"target\")");
2716 ad->alias_target = /* save string as token, for later */
2717 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2718 next();
2719 skip(')');
2720 break;
2721 case TOK_VISIBILITY1:
2722 case TOK_VISIBILITY2:
2723 skip('(');
2724 if (tok != TOK_STR)
2725 expect("visibility(\"default|hidden|internal|protected\")");
2726 if (!strcmp (tokc.cstr->data, "default"))
2727 ad->a.visibility = STV_DEFAULT;
2728 else if (!strcmp (tokc.cstr->data, "hidden"))
2729 ad->a.visibility = STV_HIDDEN;
2730 else if (!strcmp (tokc.cstr->data, "internal"))
2731 ad->a.visibility = STV_INTERNAL;
2732 else if (!strcmp (tokc.cstr->data, "protected"))
2733 ad->a.visibility = STV_PROTECTED;
2734 else
2735 expect("visibility(\"default|hidden|internal|protected\")");
2736 next();
2737 skip(')');
2738 break;
2739 case TOK_ALIGNED1:
2740 case TOK_ALIGNED2:
2741 if (tok == '(') {
2742 next();
2743 n = expr_const();
2744 if (n <= 0 || (n & (n - 1)) != 0)
2745 tcc_error("alignment must be a positive power of two");
2746 skip(')');
2747 } else {
2748 n = MAX_ALIGN;
2750 ad->a.aligned = n;
2751 break;
2752 case TOK_PACKED1:
2753 case TOK_PACKED2:
2754 ad->a.packed = 1;
2755 break;
2756 case TOK_WEAK1:
2757 case TOK_WEAK2:
2758 ad->a.weak = 1;
2759 break;
2760 case TOK_UNUSED1:
2761 case TOK_UNUSED2:
2762 /* currently, no need to handle it because tcc does not
2763 track unused objects */
2764 break;
2765 case TOK_NORETURN1:
2766 case TOK_NORETURN2:
2767 /* currently, no need to handle it because tcc does not
2768 track unused objects */
2769 break;
2770 case TOK_CDECL1:
2771 case TOK_CDECL2:
2772 case TOK_CDECL3:
2773 ad->a.func_call = FUNC_CDECL;
2774 break;
2775 case TOK_STDCALL1:
2776 case TOK_STDCALL2:
2777 case TOK_STDCALL3:
2778 ad->a.func_call = FUNC_STDCALL;
2779 break;
2780 #ifdef TCC_TARGET_I386
2781 case TOK_REGPARM1:
2782 case TOK_REGPARM2:
2783 skip('(');
2784 n = expr_const();
2785 if (n > 3)
2786 n = 3;
2787 else if (n < 0)
2788 n = 0;
2789 if (n > 0)
2790 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
2791 skip(')');
2792 break;
2793 case TOK_FASTCALL1:
2794 case TOK_FASTCALL2:
2795 case TOK_FASTCALL3:
2796 ad->a.func_call = FUNC_FASTCALLW;
2797 break;
2798 #endif
2799 case TOK_MODE:
2800 skip('(');
2801 switch(tok) {
2802 case TOK_MODE_DI:
2803 ad->a.mode = VT_LLONG + 1;
2804 break;
2805 case TOK_MODE_HI:
2806 ad->a.mode = VT_SHORT + 1;
2807 break;
2808 case TOK_MODE_SI:
2809 ad->a.mode = VT_INT + 1;
2810 break;
2811 default:
2812 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2813 break;
2815 next();
2816 skip(')');
2817 break;
2818 case TOK_DLLEXPORT:
2819 ad->a.func_export = 1;
2820 break;
2821 case TOK_DLLIMPORT:
2822 ad->a.func_import = 1;
2823 break;
2824 default:
2825 if (tcc_state->warn_unsupported)
2826 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2827 /* skip parameters */
2828 if (tok == '(') {
2829 int parenthesis = 0;
2830 do {
2831 if (tok == '(')
2832 parenthesis++;
2833 else if (tok == ')')
2834 parenthesis--;
2835 next();
2836 } while (parenthesis && tok != -1);
2838 break;
2840 if (tok != ',')
2841 break;
2842 next();
2844 skip(')');
2845 skip(')');
2849 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2850 static void struct_decl(CType *type, int u, int tdef)
2852 int a, v, size, align, maxalign, c, offset, flexible;
2853 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2854 Sym *s, *ss, *ass, **ps;
2855 AttributeDef ad;
2856 CType type1, btype;
2858 a = tok; /* save decl type */
2859 next();
2860 if (tok != '{') {
2861 v = tok;
2862 next();
2863 /* struct already defined ? return it */
2864 if (v < TOK_IDENT)
2865 expect("struct/union/enum name");
2866 s = struct_find(v);
2867 if (s) {
2868 if (s->type.t != a)
2869 tcc_error("invalid type");
2870 goto do_decl;
2871 } else if (tok >= TOK_IDENT && !tdef)
2872 tcc_error("unknown struct/union/enum");
2873 } else {
2874 v = anon_sym++;
2876 type1.t = a;
2877 type1.ref = NULL;
2878 /* we put an undefined size for struct/union */
2879 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2880 s->r = 0; /* default alignment is zero as gcc */
2881 /* put struct/union/enum name in type */
2882 do_decl:
2883 type->t = u;
2884 type->ref = s;
2886 if (tok == '{') {
2887 next();
2888 if (s->c != -1)
2889 tcc_error("struct/union/enum already defined");
2890 /* cannot be empty */
2891 c = 0;
2892 /* non empty enums are not allowed */
2893 if (a == TOK_ENUM) {
2894 for(;;) {
2895 v = tok;
2896 if (v < TOK_UIDENT)
2897 expect("identifier");
2898 ss = sym_find(v);
2899 if (ss && !local_stack)
2900 tcc_error("redefinition of enumerator '%s'",
2901 get_tok_str(v, NULL));
2902 next();
2903 if (tok == '=') {
2904 next();
2905 c = expr_const();
2907 /* enum symbols have static storage */
2908 ss = sym_push(v, &int_type, VT_CONST, c);
2909 ss->type.t |= VT_STATIC;
2910 if (tok != ',')
2911 break;
2912 next();
2913 c++;
2914 /* NOTE: we accept a trailing comma */
2915 if (tok == '}')
2916 break;
2918 s->c = type_size(&int_type, &align);
2919 skip('}');
2920 } else {
2921 maxalign = 1;
2922 ps = &s->next;
2923 prevbt = VT_INT;
2924 bit_pos = 0;
2925 offset = 0;
2926 flexible = 0;
2927 while (tok != '}') {
2928 parse_btype(&btype, &ad);
2929 while (1) {
2930 if (flexible)
2931 tcc_error("flexible array member '%s' not at the end of struct",
2932 get_tok_str(v, NULL));
2933 bit_size = -1;
2934 v = 0;
2935 type1 = btype;
2936 if (tok != ':') {
2937 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2938 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2939 expect("identifier");
2940 if (type_size(&type1, &align) < 0) {
2941 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
2942 flexible = 1;
2943 else
2944 tcc_error("field '%s' has incomplete type",
2945 get_tok_str(v, NULL));
2947 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2948 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2949 tcc_error("invalid type for '%s'",
2950 get_tok_str(v, NULL));
2952 if (tok == ':') {
2953 next();
2954 bit_size = expr_const();
2955 /* XXX: handle v = 0 case for messages */
2956 if (bit_size < 0)
2957 tcc_error("negative width in bit-field '%s'",
2958 get_tok_str(v, NULL));
2959 if (v && bit_size == 0)
2960 tcc_error("zero width for bit-field '%s'",
2961 get_tok_str(v, NULL));
2963 size = type_size(&type1, &align);
2964 if (ad.a.aligned) {
2965 if (align < ad.a.aligned)
2966 align = ad.a.aligned;
2967 } else if (ad.a.packed) {
2968 align = 1;
2969 } else if (*tcc_state->pack_stack_ptr) {
2970 if (align > *tcc_state->pack_stack_ptr)
2971 align = *tcc_state->pack_stack_ptr;
2973 lbit_pos = 0;
2974 if (bit_size >= 0) {
2975 bt = type1.t & VT_BTYPE;
2976 if (bt != VT_INT &&
2977 bt != VT_BYTE &&
2978 bt != VT_SHORT &&
2979 bt != VT_BOOL &&
2980 bt != VT_ENUM &&
2981 bt != VT_LLONG)
2982 tcc_error("bitfields must have scalar type");
2983 bsize = size * 8;
2984 if (bit_size > bsize) {
2985 tcc_error("width of '%s' exceeds its type",
2986 get_tok_str(v, NULL));
2987 } else if (bit_size == bsize) {
2988 /* no need for bit fields */
2989 bit_pos = 0;
2990 } else if (bit_size == 0) {
2991 /* XXX: what to do if only padding in a
2992 structure ? */
2993 /* zero size: means to pad */
2994 bit_pos = 0;
2995 } else {
2996 /* we do not have enough room ?
2997 did the type change?
2998 is it a union? */
2999 if ((bit_pos + bit_size) > bsize ||
3000 bt != prevbt || a == TOK_UNION)
3001 bit_pos = 0;
3002 lbit_pos = bit_pos;
3003 /* XXX: handle LSB first */
3004 type1.t |= VT_BITFIELD |
3005 (bit_pos << VT_STRUCT_SHIFT) |
3006 (bit_size << (VT_STRUCT_SHIFT + 6));
3007 bit_pos += bit_size;
3009 prevbt = bt;
3010 } else {
3011 bit_pos = 0;
3013 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3014 /* add new memory data only if starting
3015 bit field */
3016 if (lbit_pos == 0) {
3017 if (a == TOK_STRUCT) {
3018 c = (c + align - 1) & -align;
3019 offset = c;
3020 if (size > 0)
3021 c += size;
3022 } else {
3023 offset = 0;
3024 if (size > c)
3025 c = size;
3027 if (align > maxalign)
3028 maxalign = align;
3030 #if 0
3031 printf("add field %s offset=%d",
3032 get_tok_str(v, NULL), offset);
3033 if (type1.t & VT_BITFIELD) {
3034 printf(" pos=%d size=%d",
3035 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3036 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3038 printf("\n");
3039 #endif
3041 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3042 ass = type1.ref;
3043 while ((ass = ass->next) != NULL) {
3044 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3045 *ps = ss;
3046 ps = &ss->next;
3048 } else if (v) {
3049 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3050 *ps = ss;
3051 ps = &ss->next;
3053 if (tok == ';' || tok == TOK_EOF)
3054 break;
3055 skip(',');
3057 skip(';');
3059 skip('}');
3060 /* store size and alignment */
3061 s->c = (c + maxalign - 1) & -maxalign;
3062 s->r = maxalign;
3067 /* return 1 if basic type is a type size (short, long, long long) */
3068 ST_FUNC int is_btype_size(int bt)
3070 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3073 /* return 0 if no type declaration. otherwise, return the basic type
3074 and skip it.
3076 static int parse_btype(CType *type, AttributeDef *ad)
3078 int t, u, bt_size, complete, type_found, typespec_found;
3079 Sym *s;
3080 CType type1;
3082 memset(ad, 0, sizeof(AttributeDef));
3083 complete = 0;
3084 type_found = 0;
3085 typespec_found = 0;
3086 t = 0;
3087 while(1) {
3088 switch(tok) {
3089 case TOK_EXTENSION:
3090 /* currently, we really ignore extension */
3091 next();
3092 continue;
3094 /* basic types */
3095 case TOK_CHAR:
3096 u = VT_BYTE;
3097 basic_type:
3098 next();
3099 basic_type1:
3100 if (complete)
3101 tcc_error("too many basic types");
3102 t |= u;
3103 bt_size = is_btype_size (u & VT_BTYPE);
3104 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3105 complete = 1;
3106 typespec_found = 1;
3107 break;
3108 case TOK_VOID:
3109 u = VT_VOID;
3110 goto basic_type;
3111 case TOK_SHORT:
3112 u = VT_SHORT;
3113 goto basic_type;
3114 case TOK_INT:
3115 u = VT_INT;
3116 goto basic_type;
3117 case TOK_LONG:
3118 next();
3119 if ((t & VT_BTYPE) == VT_DOUBLE) {
3120 #ifndef TCC_TARGET_PE
3121 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3122 #endif
3123 } else if ((t & VT_BTYPE) == VT_LONG) {
3124 t = (t & ~VT_BTYPE) | VT_LLONG;
3125 } else {
3126 u = VT_LONG;
3127 goto basic_type1;
3129 break;
3130 case TOK_BOOL:
3131 u = VT_BOOL;
3132 goto basic_type;
3133 case TOK_FLOAT:
3134 u = VT_FLOAT;
3135 goto basic_type;
3136 case TOK_DOUBLE:
3137 next();
3138 if ((t & VT_BTYPE) == VT_LONG) {
3139 #ifdef TCC_TARGET_PE
3140 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3141 #else
3142 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3143 #endif
3144 } else {
3145 u = VT_DOUBLE;
3146 goto basic_type1;
3148 break;
3149 case TOK_ENUM:
3150 struct_decl(&type1, VT_ENUM, t & VT_TYPEDEF);
3151 basic_type2:
3152 u = type1.t;
3153 type->ref = type1.ref;
3154 goto basic_type1;
3155 case TOK_STRUCT:
3156 case TOK_UNION:
3157 struct_decl(&type1, VT_STRUCT, t & VT_TYPEDEF);
3158 goto basic_type2;
3160 /* type modifiers */
3161 case TOK_CONST1:
3162 case TOK_CONST2:
3163 case TOK_CONST3:
3164 t |= VT_CONSTANT;
3165 next();
3166 break;
3167 case TOK_VOLATILE1:
3168 case TOK_VOLATILE2:
3169 case TOK_VOLATILE3:
3170 t |= VT_VOLATILE;
3171 next();
3172 break;
3173 case TOK_SIGNED1:
3174 case TOK_SIGNED2:
3175 case TOK_SIGNED3:
3176 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3177 tcc_error("signed and unsigned modifier");
3178 typespec_found = 1;
3179 t |= VT_DEFSIGN;
3180 next();
3181 break;
3182 case TOK_REGISTER:
3183 case TOK_AUTO:
3184 case TOK_RESTRICT1:
3185 case TOK_RESTRICT2:
3186 case TOK_RESTRICT3:
3187 next();
3188 break;
3189 case TOK_UNSIGNED:
3190 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3191 tcc_error("signed and unsigned modifier");
3192 t |= VT_DEFSIGN | VT_UNSIGNED;
3193 next();
3194 typespec_found = 1;
3195 break;
3197 /* storage */
3198 case TOK_EXTERN:
3199 t |= VT_EXTERN;
3200 next();
3201 break;
3202 case TOK_STATIC:
3203 t |= VT_STATIC;
3204 next();
3205 break;
3206 case TOK_TYPEDEF:
3207 t |= VT_TYPEDEF;
3208 next();
3209 break;
3210 case TOK_INLINE1:
3211 case TOK_INLINE2:
3212 case TOK_INLINE3:
3213 t |= VT_INLINE;
3214 next();
3215 break;
3217 /* GNUC attribute */
3218 case TOK_ATTRIBUTE1:
3219 case TOK_ATTRIBUTE2:
3220 parse_attribute(ad);
3221 if (ad->a.mode) {
3222 u = ad->a.mode -1;
3223 t = (t & ~VT_BTYPE) | u;
3225 break;
3226 /* GNUC typeof */
3227 case TOK_TYPEOF1:
3228 case TOK_TYPEOF2:
3229 case TOK_TYPEOF3:
3230 next();
3231 parse_expr_type(&type1);
3232 /* remove all storage modifiers except typedef */
3233 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3234 goto basic_type2;
3235 default:
3236 if (typespec_found)
3237 goto the_end;
3238 s = sym_find(tok);
3239 if (!s || !(s->type.t & VT_TYPEDEF))
3240 goto the_end;
3241 t |= (s->type.t & ~VT_TYPEDEF);
3242 type->ref = s->type.ref;
3243 if (s->r) {
3244 /* get attributes from typedef */
3245 if (0 == ad->a.aligned)
3246 ad->a.aligned = s->a.aligned;
3247 if (0 == ad->a.func_call)
3248 ad->a.func_call = s->a.func_call;
3249 ad->a.packed |= s->a.packed;
3251 next();
3252 typespec_found = 1;
3253 break;
3255 type_found = 1;
3257 the_end:
3258 if (tcc_state->char_is_unsigned) {
3259 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3260 t |= VT_UNSIGNED;
3263 /* long is never used as type */
3264 if ((t & VT_BTYPE) == VT_LONG)
3265 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3266 t = (t & ~VT_BTYPE) | VT_INT;
3267 #else
3268 t = (t & ~VT_BTYPE) | VT_LLONG;
3269 #endif
3270 type->t = t;
3271 return type_found;
3274 /* convert a function parameter type (array to pointer and function to
3275 function pointer) */
3276 static inline void convert_parameter_type(CType *pt)
3278 /* remove const and volatile qualifiers (XXX: const could be used
3279 to indicate a const function parameter */
3280 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3281 /* array must be transformed to pointer according to ANSI C */
3282 pt->t &= ~VT_ARRAY;
3283 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3284 mk_pointer(pt);
3288 ST_FUNC void parse_asm_str(CString *astr)
3290 skip('(');
3291 /* read the string */
3292 if (tok != TOK_STR)
3293 expect("string constant");
3294 cstr_new(astr);
3295 while (tok == TOK_STR) {
3296 /* XXX: add \0 handling too ? */
3297 cstr_cat(astr, tokc.cstr->data);
3298 next();
3300 cstr_ccat(astr, '\0');
3303 /* Parse an asm label and return the label
3304 * Don't forget to free the CString in the caller! */
3305 static void asm_label_instr(CString *astr)
3307 next();
3308 parse_asm_str(astr);
3309 skip(')');
3310 #ifdef ASM_DEBUG
3311 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3312 #endif
3315 static void post_type(CType *type, AttributeDef *ad)
3317 int n, l, t1, arg_size, align;
3318 Sym **plast, *s, *first;
3319 AttributeDef ad1;
3320 CType pt;
3322 if (tok == '(') {
3323 /* function declaration */
3324 next();
3325 l = 0;
3326 first = NULL;
3327 plast = &first;
3328 arg_size = 0;
3329 if (tok != ')') {
3330 for(;;) {
3331 /* read param name and compute offset */
3332 if (l != FUNC_OLD) {
3333 if (!parse_btype(&pt, &ad1)) {
3334 if (l) {
3335 tcc_error("invalid type");
3336 } else {
3337 l = FUNC_OLD;
3338 goto old_proto;
3341 l = FUNC_NEW;
3342 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3343 break;
3344 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3345 if ((pt.t & VT_BTYPE) == VT_VOID)
3346 tcc_error("parameter declared as void");
3347 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3348 } else {
3349 old_proto:
3350 n = tok;
3351 if (n < TOK_UIDENT)
3352 expect("identifier");
3353 pt.t = VT_INT;
3354 next();
3356 convert_parameter_type(&pt);
3357 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3358 *plast = s;
3359 plast = &s->next;
3360 if (tok == ')')
3361 break;
3362 skip(',');
3363 if (l == FUNC_NEW && tok == TOK_DOTS) {
3364 l = FUNC_ELLIPSIS;
3365 next();
3366 break;
3370 /* if no parameters, then old type prototype */
3371 if (l == 0)
3372 l = FUNC_OLD;
3373 skip(')');
3374 /* NOTE: const is ignored in returned type as it has a special
3375 meaning in gcc / C++ */
3376 type->t &= ~VT_CONSTANT;
3377 /* some ancient pre-K&R C allows a function to return an array
3378 and the array brackets to be put after the arguments, such
3379 that "int c()[]" means something like "int[] c()" */
3380 if (tok == '[') {
3381 next();
3382 skip(']'); /* only handle simple "[]" */
3383 type->t |= VT_PTR;
3385 /* we push a anonymous symbol which will contain the function prototype */
3386 ad->a.func_args = arg_size;
3387 s = sym_push(SYM_FIELD, type, 0, l);
3388 s->a = ad->a;
3389 s->next = first;
3390 type->t = VT_FUNC;
3391 type->ref = s;
3392 } else if (tok == '[') {
3393 /* array definition */
3394 next();
3395 if (tok == TOK_RESTRICT1)
3396 next();
3397 n = -1;
3398 t1 = 0;
3399 if (tok != ']') {
3400 if (!local_stack || nocode_wanted)
3401 vpushi(expr_const());
3402 else gexpr();
3403 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3404 n = vtop->c.i;
3405 if (n < 0)
3406 tcc_error("invalid array size");
3407 } else {
3408 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3409 tcc_error("size of variable length array should be an integer");
3410 t1 = VT_VLA;
3413 skip(']');
3414 /* parse next post type */
3415 post_type(type, ad);
3416 if (type->t == VT_FUNC)
3417 tcc_error("declaration of an array of functions");
3418 t1 |= type->t & VT_VLA;
3420 if (t1 & VT_VLA) {
3421 loc -= type_size(&int_type, &align);
3422 loc &= -align;
3423 n = loc;
3425 vla_runtime_type_size(type, &align);
3426 gen_op('*');
3427 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3428 vswap();
3429 vstore();
3431 if (n != -1)
3432 vpop();
3434 /* we push an anonymous symbol which will contain the array
3435 element type */
3436 s = sym_push(SYM_FIELD, type, 0, n);
3437 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3438 type->ref = s;
3442 /* Parse a type declaration (except basic type), and return the type
3443 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3444 expected. 'type' should contain the basic type. 'ad' is the
3445 attribute definition of the basic type. It can be modified by
3446 type_decl().
3448 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3450 Sym *s;
3451 CType type1, *type2;
3452 int qualifiers, storage;
3454 while (tok == '*') {
3455 qualifiers = 0;
3456 redo:
3457 next();
3458 switch(tok) {
3459 case TOK_CONST1:
3460 case TOK_CONST2:
3461 case TOK_CONST3:
3462 qualifiers |= VT_CONSTANT;
3463 goto redo;
3464 case TOK_VOLATILE1:
3465 case TOK_VOLATILE2:
3466 case TOK_VOLATILE3:
3467 qualifiers |= VT_VOLATILE;
3468 goto redo;
3469 case TOK_RESTRICT1:
3470 case TOK_RESTRICT2:
3471 case TOK_RESTRICT3:
3472 goto redo;
3474 mk_pointer(type);
3475 type->t |= qualifiers;
3478 /* XXX: clarify attribute handling */
3479 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3480 parse_attribute(ad);
3482 /* recursive type */
3483 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3484 type1.t = 0; /* XXX: same as int */
3485 if (tok == '(') {
3486 next();
3487 /* XXX: this is not correct to modify 'ad' at this point, but
3488 the syntax is not clear */
3489 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3490 parse_attribute(ad);
3491 type_decl(&type1, ad, v, td);
3492 skip(')');
3493 } else {
3494 /* type identifier */
3495 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3496 *v = tok;
3497 next();
3498 } else {
3499 if (!(td & TYPE_ABSTRACT))
3500 expect("identifier");
3501 *v = 0;
3504 storage = type->t & VT_STORAGE;
3505 type->t &= ~VT_STORAGE;
3506 if (storage & VT_STATIC) {
3507 int saved_nocode_wanted = nocode_wanted;
3508 nocode_wanted = 1;
3509 post_type(type, ad);
3510 nocode_wanted = saved_nocode_wanted;
3511 } else
3512 post_type(type, ad);
3513 type->t |= storage;
3514 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3515 parse_attribute(ad);
3517 if (!type1.t)
3518 return;
3519 /* append type at the end of type1 */
3520 type2 = &type1;
3521 for(;;) {
3522 s = type2->ref;
3523 type2 = &s->type;
3524 if (!type2->t) {
3525 *type2 = *type;
3526 break;
3529 *type = type1;
3532 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3533 ST_FUNC int lvalue_type(int t)
3535 int bt, r;
3536 r = VT_LVAL;
3537 bt = t & VT_BTYPE;
3538 if (bt == VT_BYTE || bt == VT_BOOL)
3539 r |= VT_LVAL_BYTE;
3540 else if (bt == VT_SHORT)
3541 r |= VT_LVAL_SHORT;
3542 else
3543 return r;
3544 if (t & VT_UNSIGNED)
3545 r |= VT_LVAL_UNSIGNED;
3546 return r;
3549 /* indirection with full error checking and bound check */
3550 ST_FUNC void indir(void)
3552 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3553 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3554 return;
3555 expect("pointer");
3557 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3558 gv(RC_INT);
3559 vtop->type = *pointed_type(&vtop->type);
3560 /* Arrays and functions are never lvalues */
3561 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3562 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3563 vtop->r |= lvalue_type(vtop->type.t);
3564 /* if bound checking, the referenced pointer must be checked */
3565 #ifdef CONFIG_TCC_BCHECK
3566 if (tcc_state->do_bounds_check)
3567 vtop->r |= VT_MUSTBOUND;
3568 #endif
3572 /* pass a parameter to a function and do type checking and casting */
3573 static void gfunc_param_typed(Sym *func, Sym *arg)
3575 int func_type;
3576 CType type;
3578 func_type = func->c;
3579 if (func_type == FUNC_OLD ||
3580 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3581 /* default casting : only need to convert float to double */
3582 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3583 type.t = VT_DOUBLE;
3584 gen_cast(&type);
3585 } else if (vtop->type.t & VT_BITFIELD) {
3586 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3587 gen_cast(&type);
3589 } else if (arg == NULL) {
3590 tcc_error("too many arguments to function");
3591 } else {
3592 type = arg->type;
3593 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3594 gen_assign_cast(&type);
3598 /* parse an expression of the form '(type)' or '(expr)' and return its
3599 type */
3600 static void parse_expr_type(CType *type)
3602 int n;
3603 AttributeDef ad;
3605 skip('(');
3606 if (parse_btype(type, &ad)) {
3607 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3608 } else {
3609 expr_type(type);
3611 skip(')');
3614 static void parse_type(CType *type)
3616 AttributeDef ad;
3617 int n;
3619 if (!parse_btype(type, &ad)) {
3620 expect("type");
3622 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3625 static void vpush_tokc(int t)
3627 CType type;
3628 type.t = t;
3629 type.ref = 0;
3630 vsetc(&type, VT_CONST, &tokc);
3633 ST_FUNC void unary(void)
3635 int n, t, align, size, r, sizeof_caller;
3636 CType type;
3637 Sym *s;
3638 AttributeDef ad;
3639 static int in_sizeof = 0;
3641 sizeof_caller = in_sizeof;
3642 in_sizeof = 0;
3643 /* XXX: GCC 2.95.3 does not generate a table although it should be
3644 better here */
3645 tok_next:
3646 switch(tok) {
3647 case TOK_EXTENSION:
3648 next();
3649 goto tok_next;
3650 case TOK_CINT:
3651 case TOK_CCHAR:
3652 case TOK_LCHAR:
3653 vpushi(tokc.i);
3654 next();
3655 break;
3656 case TOK_CUINT:
3657 vpush_tokc(VT_INT | VT_UNSIGNED);
3658 next();
3659 break;
3660 case TOK_CLLONG:
3661 vpush_tokc(VT_LLONG);
3662 next();
3663 break;
3664 case TOK_CULLONG:
3665 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3666 next();
3667 break;
3668 case TOK_CFLOAT:
3669 vpush_tokc(VT_FLOAT);
3670 next();
3671 break;
3672 case TOK_CDOUBLE:
3673 vpush_tokc(VT_DOUBLE);
3674 next();
3675 break;
3676 case TOK_CLDOUBLE:
3677 vpush_tokc(VT_LDOUBLE);
3678 next();
3679 break;
3680 case TOK___FUNCTION__:
3681 if (!gnu_ext)
3682 goto tok_identifier;
3683 /* fall thru */
3684 case TOK___FUNC__:
3686 void *ptr;
3687 int len;
3688 /* special function name identifier */
3689 len = strlen(funcname) + 1;
3690 /* generate char[len] type */
3691 type.t = VT_BYTE;
3692 mk_pointer(&type);
3693 type.t |= VT_ARRAY;
3694 type.ref->c = len;
3695 vpush_ref(&type, data_section, data_section->data_offset, len);
3696 ptr = section_ptr_add(data_section, len);
3697 memcpy(ptr, funcname, len);
3698 next();
3700 break;
3701 case TOK_LSTR:
3702 #ifdef TCC_TARGET_PE
3703 t = VT_SHORT | VT_UNSIGNED;
3704 #else
3705 t = VT_INT;
3706 #endif
3707 goto str_init;
3708 case TOK_STR:
3709 /* string parsing */
3710 t = VT_BYTE;
3711 str_init:
3712 if (tcc_state->warn_write_strings)
3713 t |= VT_CONSTANT;
3714 type.t = t;
3715 mk_pointer(&type);
3716 type.t |= VT_ARRAY;
3717 memset(&ad, 0, sizeof(AttributeDef));
3718 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3719 break;
3720 case '(':
3721 next();
3722 /* cast ? */
3723 if (parse_btype(&type, &ad)) {
3724 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3725 skip(')');
3726 /* check ISOC99 compound literal */
3727 if (tok == '{') {
3728 /* data is allocated locally by default */
3729 if (global_expr)
3730 r = VT_CONST;
3731 else
3732 r = VT_LOCAL;
3733 /* all except arrays are lvalues */
3734 if (!(type.t & VT_ARRAY))
3735 r |= lvalue_type(type.t);
3736 memset(&ad, 0, sizeof(AttributeDef));
3737 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3738 } else {
3739 if (sizeof_caller) {
3740 vpush(&type);
3741 return;
3743 unary();
3744 gen_cast(&type);
3746 } else if (tok == '{') {
3747 /* save all registers */
3748 save_regs(0);
3749 /* statement expression : we do not accept break/continue
3750 inside as GCC does */
3751 block(NULL, NULL, NULL, NULL, 0, 1);
3752 skip(')');
3753 } else {
3754 gexpr();
3755 skip(')');
3757 break;
3758 case '*':
3759 next();
3760 unary();
3761 indir();
3762 break;
3763 case '&':
3764 next();
3765 unary();
3766 /* functions names must be treated as function pointers,
3767 except for unary '&' and sizeof. Since we consider that
3768 functions are not lvalues, we only have to handle it
3769 there and in function calls. */
3770 /* arrays can also be used although they are not lvalues */
3771 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3772 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3773 test_lvalue();
3774 mk_pointer(&vtop->type);
3775 gaddrof();
3776 break;
3777 case '!':
3778 next();
3779 unary();
3780 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3781 CType boolean;
3782 boolean.t = VT_BOOL;
3783 gen_cast(&boolean);
3784 vtop->c.i = !vtop->c.i;
3785 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3786 vtop->c.i = vtop->c.i ^ 1;
3787 else {
3788 save_regs(1);
3789 vseti(VT_JMP, gtst(1, 0));
3791 break;
3792 case '~':
3793 next();
3794 unary();
3795 vpushi(-1);
3796 gen_op('^');
3797 break;
3798 case '+':
3799 next();
3800 unary();
3801 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3802 tcc_error("pointer not accepted for unary plus");
3803 /* In order to force cast, we add zero, except for floating point
3804 where we really need an noop (otherwise -0.0 will be transformed
3805 into +0.0). */
3806 if (!is_float(vtop->type.t)) {
3807 vpushi(0);
3808 gen_op('+');
3810 break;
3811 case TOK_SIZEOF:
3812 case TOK_ALIGNOF1:
3813 case TOK_ALIGNOF2:
3814 t = tok;
3815 next();
3816 in_sizeof++;
3817 unary_type(&type); // Perform a in_sizeof = 0;
3818 size = type_size(&type, &align);
3819 if (t == TOK_SIZEOF) {
3820 if (!(type.t & VT_VLA)) {
3821 if (size < 0)
3822 tcc_error("sizeof applied to an incomplete type");
3823 vpushs(size);
3824 } else {
3825 vla_runtime_type_size(&type, &align);
3827 } else {
3828 vpushs(align);
3830 vtop->type.t |= VT_UNSIGNED;
3831 break;
3833 case TOK_builtin_types_compatible_p:
3835 CType type1, type2;
3836 next();
3837 skip('(');
3838 parse_type(&type1);
3839 skip(',');
3840 parse_type(&type2);
3841 skip(')');
3842 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3843 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3844 vpushi(is_compatible_types(&type1, &type2));
3846 break;
3847 case TOK_builtin_constant_p:
3849 int saved_nocode_wanted, res;
3850 next();
3851 skip('(');
3852 saved_nocode_wanted = nocode_wanted;
3853 nocode_wanted = 1;
3854 gexpr();
3855 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3856 vpop();
3857 nocode_wanted = saved_nocode_wanted;
3858 skip(')');
3859 vpushi(res);
3861 break;
3862 case TOK_builtin_frame_address:
3864 int level;
3865 CType type;
3866 next();
3867 skip('(');
3868 if (tok != TOK_CINT || tokc.i < 0) {
3869 tcc_error("__builtin_frame_address only takes positive integers");
3871 level = tokc.i;
3872 next();
3873 skip(')');
3874 type.t = VT_VOID;
3875 mk_pointer(&type);
3876 vset(&type, VT_LOCAL, 0); /* local frame */
3877 while (level--) {
3878 mk_pointer(&vtop->type);
3879 indir(); /* -> parent frame */
3882 break;
3883 #ifdef TCC_TARGET_X86_64
3884 #ifdef TCC_TARGET_PE
3885 case TOK_builtin_va_start:
3887 next();
3888 skip('(');
3889 expr_eq();
3890 skip(',');
3891 expr_eq();
3892 skip(')');
3893 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
3894 tcc_error("__builtin_va_start expects a local variable");
3895 vtop->r &= ~(VT_LVAL | VT_REF);
3896 vtop->type = char_pointer_type;
3897 vstore();
3899 break;
3900 #else
3901 case TOK_builtin_va_arg_types:
3903 CType type;
3904 next();
3905 skip('(');
3906 parse_type(&type);
3907 skip(')');
3908 vpushi(classify_x86_64_va_arg(&type));
3910 break;
3911 #endif
3912 #endif
3913 case TOK_INC:
3914 case TOK_DEC:
3915 t = tok;
3916 next();
3917 unary();
3918 inc(0, t);
3919 break;
3920 case '-':
3921 next();
3922 unary();
3923 t = vtop->type.t & VT_BTYPE;
3924 if (is_float(t)) {
3925 /* In IEEE negate(x) isn't subtract(0,x), but rather
3926 subtract(-0, x). */
3927 vpush(&vtop->type);
3928 if (t == VT_FLOAT)
3929 vtop->c.f = -0.0f;
3930 else if (t == VT_DOUBLE)
3931 vtop->c.d = -0.0;
3932 else
3933 vtop->c.ld = -0.0;
3934 } else
3935 vpushi(0);
3936 vswap();
3937 gen_op('-');
3938 break;
3939 case TOK_LAND:
3940 if (!gnu_ext)
3941 goto tok_identifier;
3942 next();
3943 /* allow to take the address of a label */
3944 if (tok < TOK_UIDENT)
3945 expect("label identifier");
3946 s = label_find(tok);
3947 if (!s) {
3948 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3949 } else {
3950 if (s->r == LABEL_DECLARED)
3951 s->r = LABEL_FORWARD;
3953 if (!s->type.t) {
3954 s->type.t = VT_VOID;
3955 mk_pointer(&s->type);
3956 s->type.t |= VT_STATIC;
3958 vpushsym(&s->type, s);
3959 next();
3960 break;
3962 // special qnan , snan and infinity values
3963 case TOK___NAN__:
3964 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3965 next();
3966 break;
3967 case TOK___SNAN__:
3968 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3969 next();
3970 break;
3971 case TOK___INF__:
3972 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3973 next();
3974 break;
3976 default:
3977 tok_identifier:
3978 t = tok;
3979 next();
3980 if (t < TOK_UIDENT)
3981 expect("identifier");
3982 s = sym_find(t);
3983 if (!s) {
3984 const char *name = get_tok_str(t, NULL);
3985 if (tok != '(')
3986 tcc_error("'%s' undeclared", name);
3987 /* for simple function calls, we tolerate undeclared
3988 external reference to int() function */
3989 if (tcc_state->warn_implicit_function_declaration
3990 #ifdef TCC_TARGET_PE
3991 /* people must be warned about using undeclared WINAPI functions
3992 (which usually start with uppercase letter) */
3993 || (name[0] >= 'A' && name[0] <= 'Z')
3994 #endif
3996 tcc_warning("implicit declaration of function '%s'", name);
3997 s = external_global_sym(t, &func_old_type, 0);
3999 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
4000 (VT_STATIC | VT_INLINE | VT_FUNC)) {
4001 /* if referencing an inline function, then we generate a
4002 symbol to it if not already done. It will have the
4003 effect to generate code for it at the end of the
4004 compilation unit. Inline function as always
4005 generated in the text section. */
4006 if (!s->c)
4007 put_extern_sym(s, text_section, 0, 0);
4008 r = VT_SYM | VT_CONST;
4009 } else {
4010 r = s->r;
4012 vset(&s->type, r, s->c);
4013 /* if forward reference, we must point to s */
4014 if (vtop->r & VT_SYM) {
4015 vtop->sym = s;
4016 vtop->c.ptr_offset = 0;
4018 break;
4021 /* post operations */
4022 while (1) {
4023 if (tok == TOK_INC || tok == TOK_DEC) {
4024 inc(1, tok);
4025 next();
4026 } else if (tok == '.' || tok == TOK_ARROW) {
4027 int qualifiers;
4028 /* field */
4029 if (tok == TOK_ARROW)
4030 indir();
4031 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4032 test_lvalue();
4033 gaddrof();
4034 next();
4035 /* expect pointer on structure */
4036 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4037 expect("struct or union");
4038 s = vtop->type.ref;
4039 /* find field */
4040 tok |= SYM_FIELD;
4041 while ((s = s->next) != NULL) {
4042 if (s->v == tok)
4043 break;
4045 if (!s)
4046 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
4047 /* add field offset to pointer */
4048 vtop->type = char_pointer_type; /* change type to 'char *' */
4049 vpushi(s->c);
4050 gen_op('+');
4051 /* change type to field type, and set to lvalue */
4052 vtop->type = s->type;
4053 vtop->type.t |= qualifiers;
4054 /* an array is never an lvalue */
4055 if (!(vtop->type.t & VT_ARRAY)) {
4056 vtop->r |= lvalue_type(vtop->type.t);
4057 #ifdef CONFIG_TCC_BCHECK
4058 /* if bound checking, the referenced pointer must be checked */
4059 if (tcc_state->do_bounds_check)
4060 vtop->r |= VT_MUSTBOUND;
4061 #endif
4063 next();
4064 } else if (tok == '[') {
4065 next();
4066 gexpr();
4067 gen_op('+');
4068 indir();
4069 skip(']');
4070 } else if (tok == '(') {
4071 SValue ret;
4072 Sym *sa;
4073 int nb_args, ret_nregs, ret_align, variadic;
4075 /* function call */
4076 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4077 /* pointer test (no array accepted) */
4078 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4079 vtop->type = *pointed_type(&vtop->type);
4080 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4081 goto error_func;
4082 } else {
4083 error_func:
4084 expect("function pointer");
4086 } else {
4087 vtop->r &= ~VT_LVAL; /* no lvalue */
4089 /* get return type */
4090 s = vtop->type.ref;
4091 next();
4092 sa = s->next; /* first parameter */
4093 nb_args = 0;
4094 ret.r2 = VT_CONST;
4095 /* compute first implicit argument if a structure is returned */
4096 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4097 variadic = (s->c == FUNC_ELLIPSIS);
4098 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4099 &ret_align);
4100 if (!ret_nregs) {
4101 /* get some space for the returned structure */
4102 size = type_size(&s->type, &align);
4103 loc = (loc - size) & -align;
4104 ret.type = s->type;
4105 ret.r = VT_LOCAL | VT_LVAL;
4106 /* pass it as 'int' to avoid structure arg passing
4107 problems */
4108 vseti(VT_LOCAL, loc);
4109 ret.c = vtop->c;
4110 nb_args++;
4112 } else {
4113 ret_nregs = 1;
4114 ret.type = s->type;
4117 if (ret_nregs) {
4118 /* return in register */
4119 if (is_float(ret.type.t)) {
4120 ret.r = reg_fret(ret.type.t);
4121 #ifdef TCC_TARGET_X86_64
4122 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4123 ret.r2 = REG_QRET;
4124 #endif
4125 } else {
4126 #ifdef TCC_TARGET_X86_64
4127 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4128 #else
4129 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4130 #endif
4131 ret.r2 = REG_LRET;
4132 ret.r = REG_IRET;
4134 ret.c.i = 0;
4136 if (tok != ')') {
4137 for(;;) {
4138 expr_eq();
4139 gfunc_param_typed(s, sa);
4140 nb_args++;
4141 if (sa)
4142 sa = sa->next;
4143 if (tok == ')')
4144 break;
4145 skip(',');
4148 if (sa)
4149 tcc_error("too few arguments to function");
4150 skip(')');
4151 if (!nocode_wanted) {
4152 gfunc_call(nb_args);
4153 } else {
4154 vtop -= (nb_args + 1);
4157 /* return value */
4158 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4159 vsetc(&ret.type, r, &ret.c);
4160 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4163 /* handle packed struct return */
4164 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4165 int addr, offset;
4167 size = type_size(&s->type, &align);
4168 loc = (loc - size) & -align;
4169 addr = loc;
4170 offset = 0;
4171 for (;;) {
4172 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4173 vswap();
4174 vstore();
4175 vtop--;
4176 if (--ret_nregs == 0)
4177 break;
4178 /* XXX: compatible with arm only: ret_align == register_size */
4179 offset += ret_align;
4181 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4183 } else {
4184 break;
4189 ST_FUNC void expr_prod(void)
4191 int t;
4193 unary();
4194 while (tok == '*' || tok == '/' || tok == '%') {
4195 t = tok;
4196 next();
4197 unary();
4198 gen_op(t);
4202 ST_FUNC void expr_sum(void)
4204 int t;
4206 expr_prod();
4207 while (tok == '+' || tok == '-') {
4208 t = tok;
4209 next();
4210 expr_prod();
4211 gen_op(t);
4215 static void expr_shift(void)
4217 int t;
4219 expr_sum();
4220 while (tok == TOK_SHL || tok == TOK_SAR) {
4221 t = tok;
4222 next();
4223 expr_sum();
4224 gen_op(t);
4228 static void expr_cmp(void)
4230 int t;
4232 expr_shift();
4233 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4234 tok == TOK_ULT || tok == TOK_UGE) {
4235 t = tok;
4236 next();
4237 expr_shift();
4238 gen_op(t);
4242 static void expr_cmpeq(void)
4244 int t;
4246 expr_cmp();
4247 while (tok == TOK_EQ || tok == TOK_NE) {
4248 t = tok;
4249 next();
4250 expr_cmp();
4251 gen_op(t);
4255 static void expr_and(void)
4257 expr_cmpeq();
4258 while (tok == '&') {
4259 next();
4260 expr_cmpeq();
4261 gen_op('&');
4265 static void expr_xor(void)
4267 expr_and();
4268 while (tok == '^') {
4269 next();
4270 expr_and();
4271 gen_op('^');
4275 static void expr_or(void)
4277 expr_xor();
4278 while (tok == '|') {
4279 next();
4280 expr_xor();
4281 gen_op('|');
4285 /* XXX: fix this mess */
4286 static void expr_land_const(void)
4288 expr_or();
4289 while (tok == TOK_LAND) {
4290 next();
4291 expr_or();
4292 gen_op(TOK_LAND);
4296 /* XXX: fix this mess */
4297 static void expr_lor_const(void)
4299 expr_land_const();
4300 while (tok == TOK_LOR) {
4301 next();
4302 expr_land_const();
4303 gen_op(TOK_LOR);
4307 /* only used if non constant */
4308 static void expr_land(void)
4310 int t;
4312 expr_or();
4313 if (tok == TOK_LAND) {
4314 t = 0;
4315 save_regs(1);
4316 for(;;) {
4317 t = gtst(1, t);
4318 if (tok != TOK_LAND) {
4319 vseti(VT_JMPI, t);
4320 break;
4322 next();
4323 expr_or();
4328 static void expr_lor(void)
4330 int t;
4332 expr_land();
4333 if (tok == TOK_LOR) {
4334 t = 0;
4335 save_regs(1);
4336 for(;;) {
4337 t = gtst(0, t);
4338 if (tok != TOK_LOR) {
4339 vseti(VT_JMP, t);
4340 break;
4342 next();
4343 expr_land();
4348 /* XXX: better constant handling */
4349 static void expr_cond(void)
4351 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4352 SValue sv;
4353 CType type, type1, type2;
4355 if (const_wanted) {
4356 expr_lor_const();
4357 if (tok == '?') {
4358 CType boolean;
4359 int c;
4360 boolean.t = VT_BOOL;
4361 vdup();
4362 gen_cast(&boolean);
4363 c = vtop->c.i;
4364 vpop();
4365 next();
4366 if (tok != ':' || !gnu_ext) {
4367 vpop();
4368 gexpr();
4370 if (!c)
4371 vpop();
4372 skip(':');
4373 expr_cond();
4374 if (c)
4375 vpop();
4377 } else {
4378 expr_lor();
4379 if (tok == '?') {
4380 next();
4381 if (vtop != vstack) {
4382 /* needed to avoid having different registers saved in
4383 each branch */
4384 if (is_float(vtop->type.t)) {
4385 rc = RC_FLOAT;
4386 #ifdef TCC_TARGET_X86_64
4387 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4388 rc = RC_ST0;
4390 #endif
4392 else
4393 rc = RC_INT;
4394 gv(rc);
4395 save_regs(1);
4397 if (tok == ':' && gnu_ext) {
4398 gv_dup();
4399 tt = gtst(1, 0);
4400 } else {
4401 tt = gtst(1, 0);
4402 gexpr();
4404 type1 = vtop->type;
4405 sv = *vtop; /* save value to handle it later */
4406 vtop--; /* no vpop so that FP stack is not flushed */
4407 skip(':');
4408 u = gjmp(0);
4409 gsym(tt);
4410 expr_cond();
4411 type2 = vtop->type;
4413 t1 = type1.t;
4414 bt1 = t1 & VT_BTYPE;
4415 t2 = type2.t;
4416 bt2 = t2 & VT_BTYPE;
4417 /* cast operands to correct type according to ISOC rules */
4418 if (is_float(bt1) || is_float(bt2)) {
4419 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4420 type.t = VT_LDOUBLE;
4421 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4422 type.t = VT_DOUBLE;
4423 } else {
4424 type.t = VT_FLOAT;
4426 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4427 /* cast to biggest op */
4428 type.t = VT_LLONG;
4429 /* convert to unsigned if it does not fit in a long long */
4430 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4431 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4432 type.t |= VT_UNSIGNED;
4433 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4434 /* If one is a null ptr constant the result type
4435 is the other. */
4436 if (is_null_pointer (vtop))
4437 type = type1;
4438 else if (is_null_pointer (&sv))
4439 type = type2;
4440 /* XXX: test pointer compatibility, C99 has more elaborate
4441 rules here. */
4442 else
4443 type = type1;
4444 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4445 /* XXX: test function pointer compatibility */
4446 type = bt1 == VT_FUNC ? type1 : type2;
4447 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4448 /* XXX: test structure compatibility */
4449 type = bt1 == VT_STRUCT ? type1 : type2;
4450 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4451 /* NOTE: as an extension, we accept void on only one side */
4452 type.t = VT_VOID;
4453 } else {
4454 /* integer operations */
4455 type.t = VT_INT;
4456 /* convert to unsigned if it does not fit in an integer */
4457 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4458 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4459 type.t |= VT_UNSIGNED;
4462 /* now we convert second operand */
4463 gen_cast(&type);
4464 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4465 gaddrof();
4466 rc = RC_INT;
4467 if (is_float(type.t)) {
4468 rc = RC_FLOAT;
4469 #ifdef TCC_TARGET_X86_64
4470 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4471 rc = RC_ST0;
4473 #endif
4474 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4475 /* for long longs, we use fixed registers to avoid having
4476 to handle a complicated move */
4477 rc = RC_IRET;
4480 r2 = gv(rc);
4481 /* this is horrible, but we must also convert first
4482 operand */
4483 tt = gjmp(0);
4484 gsym(u);
4485 /* put again first value and cast it */
4486 *vtop = sv;
4487 gen_cast(&type);
4488 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4489 gaddrof();
4490 r1 = gv(rc);
4491 move_reg(r2, r1, type.t);
4492 vtop->r = r2;
4493 gsym(tt);
4498 static void expr_eq(void)
4500 int t;
4502 expr_cond();
4503 if (tok == '=' ||
4504 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4505 tok == TOK_A_XOR || tok == TOK_A_OR ||
4506 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4507 test_lvalue();
4508 t = tok;
4509 next();
4510 if (t == '=') {
4511 expr_eq();
4512 } else {
4513 vdup();
4514 expr_eq();
4515 gen_op(t & 0x7f);
4517 vstore();
4521 ST_FUNC void gexpr(void)
4523 while (1) {
4524 expr_eq();
4525 if (tok != ',')
4526 break;
4527 vpop();
4528 next();
4532 /* parse an expression and return its type without any side effect. */
4533 static void expr_type(CType *type)
4535 int saved_nocode_wanted;
4537 saved_nocode_wanted = nocode_wanted;
4538 nocode_wanted = 1;
4539 gexpr();
4540 *type = vtop->type;
4541 vpop();
4542 nocode_wanted = saved_nocode_wanted;
4545 /* parse a unary expression and return its type without any side
4546 effect. */
4547 static void unary_type(CType *type)
4549 int a;
4551 a = nocode_wanted;
4552 nocode_wanted = 1;
4553 unary();
4554 *type = vtop->type;
4555 vpop();
4556 nocode_wanted = a;
4559 /* parse a constant expression and return value in vtop. */
4560 static void expr_const1(void)
4562 int a;
4563 a = const_wanted;
4564 const_wanted = 1;
4565 expr_cond();
4566 const_wanted = a;
4569 /* parse an integer constant and return its value. */
4570 ST_FUNC int expr_const(void)
4572 int c;
4573 expr_const1();
4574 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4575 expect("constant expression");
4576 c = vtop->c.i;
4577 vpop();
4578 return c;
4581 /* return the label token if current token is a label, otherwise
4582 return zero */
4583 static int is_label(void)
4585 int last_tok;
4587 /* fast test first */
4588 if (tok < TOK_UIDENT)
4589 return 0;
4590 /* no need to save tokc because tok is an identifier */
4591 last_tok = tok;
4592 next();
4593 if (tok == ':') {
4594 next();
4595 return last_tok;
4596 } else {
4597 unget_tok(last_tok);
4598 return 0;
4602 static void label_or_decl(int l)
4604 int last_tok;
4606 /* fast test first */
4607 if (tok >= TOK_UIDENT)
4609 /* no need to save tokc because tok is an identifier */
4610 last_tok = tok;
4611 next();
4612 if (tok == ':') {
4613 unget_tok(last_tok);
4614 return;
4616 unget_tok(last_tok);
4618 decl(l);
4621 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4622 int case_reg, int is_expr)
4624 int a, b, c, d;
4625 Sym *s, *frame_bottom;
4627 /* generate line number info */
4628 if (tcc_state->do_debug &&
4629 (last_line_num != file->line_num || last_ind != ind)) {
4630 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4631 last_ind = ind;
4632 last_line_num = file->line_num;
4635 if (is_expr) {
4636 /* default return value is (void) */
4637 vpushi(0);
4638 vtop->type.t = VT_VOID;
4641 if (tok == TOK_IF) {
4642 /* if test */
4643 next();
4644 skip('(');
4645 gexpr();
4646 skip(')');
4647 a = gtst(1, 0);
4648 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4649 c = tok;
4650 if (c == TOK_ELSE) {
4651 next();
4652 d = gjmp(0);
4653 gsym(a);
4654 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4655 gsym(d); /* patch else jmp */
4656 } else
4657 gsym(a);
4658 } else if (tok == TOK_WHILE) {
4659 next();
4660 d = ind;
4661 skip('(');
4662 gexpr();
4663 skip(')');
4664 a = gtst(1, 0);
4665 b = 0;
4666 block(&a, &b, case_sym, def_sym, case_reg, 0);
4667 gjmp_addr(d);
4668 gsym(a);
4669 gsym_addr(b, d);
4670 } else if (tok == '{') {
4671 Sym *llabel;
4672 int saved_loc, saved_pop_stack, size;
4673 int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
4675 next();
4676 /* record local declaration stack position */
4677 s = local_stack;
4678 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4679 frame_bottom->next = scope_stack_bottom;
4680 scope_stack_bottom = frame_bottom;
4681 llabel = local_label_stack;
4683 saved_loc = loc;
4684 saved_pop_stack = pop_stack;
4686 /* save VLA state */
4687 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4688 if (saved_vla_sp_loc != &vla_sp_root_loc)
4689 vla_sp_loc = &block_vla_sp_loc;
4691 saved_vla_flags = vla_flags;
4692 vla_flags |= VLA_NEED_NEW_FRAME;
4694 /* handle local labels declarations */
4695 if (tok == TOK_LABEL) {
4696 next();
4697 for(;;) {
4698 if (tok < TOK_UIDENT)
4699 expect("label identifier");
4700 label_push(&local_label_stack, tok, LABEL_DECLARED);
4701 next();
4702 if (tok == ',') {
4703 next();
4704 } else {
4705 skip(';');
4706 break;
4710 while (tok != '}') {
4711 label_or_decl(VT_LOCAL);
4712 if (tok != '}') {
4713 if (is_expr)
4714 vpop();
4715 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4718 /* pop locally defined labels */
4719 label_pop(&local_label_stack, llabel);
4720 if(is_expr) {
4721 /* XXX: this solution makes only valgrind happy...
4722 triggered by gcc.c-torture/execute/20000917-1.c */
4723 Sym *p;
4724 switch(vtop->type.t & VT_BTYPE) {
4725 case VT_PTR:
4726 case VT_STRUCT:
4727 case VT_ENUM:
4728 case VT_FUNC:
4729 for(p=vtop->type.ref;p;p=p->prev)
4730 if(p->prev==s)
4731 tcc_error("unsupported expression type");
4734 /* pop locally defined symbols */
4735 scope_stack_bottom = scope_stack_bottom->next;
4736 sym_pop(&local_stack, s);
4738 size = -(loc - saved_loc);
4739 pop_stack = saved_pop_stack;
4740 if(size)
4741 pop_stack += size;
4743 /* Pop VLA frames and restore stack pointer if required */
4744 if (saved_vla_sp_loc != &vla_sp_root_loc)
4745 *saved_vla_sp_loc = block_vla_sp_loc;
4746 if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
4747 vla_sp_loc = saved_vla_sp_loc;
4748 gen_vla_sp_restore(*vla_sp_loc);
4750 vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
4752 next();
4753 } else if (tok == TOK_RETURN) {
4754 next();
4755 if (tok != ';') {
4756 gexpr();
4757 gen_assign_cast(&func_vt);
4758 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4759 CType type, ret_type;
4760 int ret_align, ret_nregs;
4761 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
4762 &ret_align);
4763 if (0 == ret_nregs) {
4764 /* if returning structure, must copy it to implicit
4765 first pointer arg location */
4766 type = func_vt;
4767 mk_pointer(&type);
4768 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4769 indir();
4770 vswap();
4771 /* copy structure value to pointer */
4772 vstore();
4773 } else {
4774 /* returning structure packed into registers */
4775 int r, size, addr, align;
4776 size = type_size(&func_vt,&align);
4777 if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))
4778 && (align & (ret_align-1))) {
4779 loc = (loc - size) & -align;
4780 addr = loc;
4781 type = func_vt;
4782 vset(&type, VT_LOCAL | VT_LVAL, addr);
4783 vswap();
4784 vstore();
4785 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
4787 vtop->type = ret_type;
4788 if (is_float(ret_type.t))
4789 r = rc_fret(ret_type.t);
4790 else
4791 r = RC_IRET;
4793 for (;;) {
4794 gv(r);
4795 if (--ret_nregs == 0)
4796 break;
4797 /* We assume that when a structure is returned in multiple
4798 registers, their classes are consecutive values of the
4799 suite s(n) = 2^n */
4800 r <<= 1;
4801 /* XXX: compatible with arm only: ret_align == register_size */
4802 vtop->c.i += ret_align;
4803 vtop->r = VT_LOCAL | VT_LVAL;
4806 } else if (is_float(func_vt.t)) {
4807 gv(rc_fret(func_vt.t));
4808 } else {
4809 gv(RC_IRET);
4811 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4813 skip(';');
4814 rsym = gjmp(rsym); /* jmp */
4815 } else if (tok == TOK_BREAK) {
4816 /* compute jump */
4817 if (!bsym)
4818 tcc_error("cannot break");
4819 *bsym = gjmp(*bsym);
4820 next();
4821 skip(';');
4822 } else if (tok == TOK_CONTINUE) {
4823 /* compute jump */
4824 if (!csym)
4825 tcc_error("cannot continue");
4826 *csym = gjmp(*csym);
4827 next();
4828 skip(';');
4829 } else if (tok == TOK_FOR) {
4830 int e;
4831 next();
4832 skip('(');
4833 s = local_stack;
4834 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4835 frame_bottom->next = scope_stack_bottom;
4836 scope_stack_bottom = frame_bottom;
4837 if (tok != ';') {
4838 /* c99 for-loop init decl? */
4839 if (!decl0(VT_LOCAL, 1)) {
4840 /* no, regular for-loop init expr */
4841 gexpr();
4842 vpop();
4845 skip(';');
4846 d = ind;
4847 c = ind;
4848 a = 0;
4849 b = 0;
4850 if (tok != ';') {
4851 gexpr();
4852 a = gtst(1, 0);
4854 skip(';');
4855 if (tok != ')') {
4856 e = gjmp(0);
4857 c = ind;
4858 gexpr();
4859 vpop();
4860 gjmp_addr(d);
4861 gsym(e);
4863 skip(')');
4864 block(&a, &b, case_sym, def_sym, case_reg, 0);
4865 gjmp_addr(c);
4866 gsym(a);
4867 gsym_addr(b, c);
4868 scope_stack_bottom = scope_stack_bottom->next;
4869 sym_pop(&local_stack, s);
4870 } else
4871 if (tok == TOK_DO) {
4872 next();
4873 a = 0;
4874 b = 0;
4875 d = ind;
4876 block(&a, &b, case_sym, def_sym, case_reg, 0);
4877 skip(TOK_WHILE);
4878 skip('(');
4879 gsym(b);
4880 gexpr();
4881 c = gtst(0, 0);
4882 gsym_addr(c, d);
4883 skip(')');
4884 gsym(a);
4885 skip(';');
4886 } else
4887 if (tok == TOK_SWITCH) {
4888 next();
4889 skip('(');
4890 gexpr();
4891 /* XXX: other types than integer */
4892 case_reg = gv(RC_INT);
4893 vpop();
4894 skip(')');
4895 a = 0;
4896 b = gjmp(0); /* jump to first case */
4897 c = 0;
4898 block(&a, csym, &b, &c, case_reg, 0);
4899 /* if no default, jmp after switch */
4900 if (c == 0)
4901 c = ind;
4902 /* default label */
4903 gsym_addr(b, c);
4904 /* break label */
4905 gsym(a);
4906 } else
4907 if (tok == TOK_CASE) {
4908 int v1, v2;
4909 if (!case_sym)
4910 expect("switch");
4911 next();
4912 v1 = expr_const();
4913 v2 = v1;
4914 if (gnu_ext && tok == TOK_DOTS) {
4915 next();
4916 v2 = expr_const();
4917 if (v2 < v1)
4918 tcc_warning("empty case range");
4920 /* since a case is like a label, we must skip it with a jmp */
4921 b = gjmp(0);
4922 gsym(*case_sym);
4923 vseti(case_reg, 0);
4924 vpushi(v1);
4925 if (v1 == v2) {
4926 gen_op(TOK_EQ);
4927 *case_sym = gtst(1, 0);
4928 } else {
4929 gen_op(TOK_GE);
4930 *case_sym = gtst(1, 0);
4931 vseti(case_reg, 0);
4932 vpushi(v2);
4933 gen_op(TOK_LE);
4934 *case_sym = gtst(1, *case_sym);
4936 gsym(b);
4937 skip(':');
4938 is_expr = 0;
4939 goto block_after_label;
4940 } else
4941 if (tok == TOK_DEFAULT) {
4942 next();
4943 skip(':');
4944 if (!def_sym)
4945 expect("switch");
4946 if (*def_sym)
4947 tcc_error("too many 'default'");
4948 *def_sym = ind;
4949 is_expr = 0;
4950 goto block_after_label;
4951 } else
4952 if (tok == TOK_GOTO) {
4953 next();
4954 if (tok == '*' && gnu_ext) {
4955 /* computed goto */
4956 next();
4957 gexpr();
4958 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4959 expect("pointer");
4960 ggoto();
4961 } else if (tok >= TOK_UIDENT) {
4962 s = label_find(tok);
4963 /* put forward definition if needed */
4964 if (!s) {
4965 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4966 } else {
4967 if (s->r == LABEL_DECLARED)
4968 s->r = LABEL_FORWARD;
4970 /* label already defined */
4971 if (vla_flags & VLA_IN_SCOPE) {
4972 /* If VLAs are in use, save the current stack pointer and
4973 reset the stack pointer to what it was at function entry
4974 (label will restore stack pointer in inner scopes) */
4975 vla_sp_save();
4976 gen_vla_sp_restore(vla_sp_root_loc);
4978 if (s->r & LABEL_FORWARD)
4979 s->jnext = gjmp(s->jnext);
4980 else
4981 gjmp_addr(s->jnext);
4982 next();
4983 } else {
4984 expect("label identifier");
4986 skip(';');
4987 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4988 asm_instr();
4989 } else {
4990 b = is_label();
4991 if (b) {
4992 /* label case */
4993 if (vla_flags & VLA_IN_SCOPE) {
4994 /* save/restore stack pointer across label
4995 this is a no-op when combined with the load immediately
4996 after the label unless we arrive via goto */
4997 vla_sp_save();
4999 s = label_find(b);
5000 if (s) {
5001 if (s->r == LABEL_DEFINED)
5002 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
5003 gsym(s->jnext);
5004 s->r = LABEL_DEFINED;
5005 } else {
5006 s = label_push(&global_label_stack, b, LABEL_DEFINED);
5008 s->jnext = ind;
5009 if (vla_flags & VLA_IN_SCOPE) {
5010 gen_vla_sp_restore(*vla_sp_loc);
5011 vla_flags |= VLA_NEED_NEW_FRAME;
5013 /* we accept this, but it is a mistake */
5014 block_after_label:
5015 if (tok == '}') {
5016 tcc_warning("deprecated use of label at end of compound statement");
5017 } else {
5018 if (is_expr)
5019 vpop();
5020 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
5022 } else {
5023 /* expression case */
5024 if (tok != ';') {
5025 if (is_expr) {
5026 vpop();
5027 gexpr();
5028 } else {
5029 gexpr();
5030 vpop();
5033 skip(';');
5038 /* t is the array or struct type. c is the array or struct
5039 address. cur_index/cur_field is the pointer to the current
5040 value. 'size_only' is true if only size info is needed (only used
5041 in arrays) */
5042 static void decl_designator(CType *type, Section *sec, unsigned long c,
5043 int *cur_index, Sym **cur_field,
5044 int size_only)
5046 Sym *s, *f;
5047 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5048 CType type1;
5050 notfirst = 0;
5051 elem_size = 0;
5052 nb_elems = 1;
5053 if (gnu_ext && (l = is_label()) != 0)
5054 goto struct_field;
5055 while (tok == '[' || tok == '.') {
5056 if (tok == '[') {
5057 if (!(type->t & VT_ARRAY))
5058 expect("array type");
5059 s = type->ref;
5060 next();
5061 index = expr_const();
5062 if (index < 0 || (s->c >= 0 && index >= s->c))
5063 expect("invalid index");
5064 if (tok == TOK_DOTS && gnu_ext) {
5065 next();
5066 index_last = expr_const();
5067 if (index_last < 0 ||
5068 (s->c >= 0 && index_last >= s->c) ||
5069 index_last < index)
5070 expect("invalid index");
5071 } else {
5072 index_last = index;
5074 skip(']');
5075 if (!notfirst)
5076 *cur_index = index_last;
5077 type = pointed_type(type);
5078 elem_size = type_size(type, &align);
5079 c += index * elem_size;
5080 /* NOTE: we only support ranges for last designator */
5081 nb_elems = index_last - index + 1;
5082 if (nb_elems != 1) {
5083 notfirst = 1;
5084 break;
5086 } else {
5087 next();
5088 l = tok;
5089 next();
5090 struct_field:
5091 if ((type->t & VT_BTYPE) != VT_STRUCT)
5092 expect("struct/union type");
5093 s = type->ref;
5094 l |= SYM_FIELD;
5095 f = s->next;
5096 while (f) {
5097 if (f->v == l)
5098 break;
5099 f = f->next;
5101 if (!f)
5102 expect("field");
5103 if (!notfirst)
5104 *cur_field = f;
5105 /* XXX: fix this mess by using explicit storage field */
5106 type1 = f->type;
5107 type1.t |= (type->t & ~VT_TYPE);
5108 type = &type1;
5109 c += f->c;
5111 notfirst = 1;
5113 if (notfirst) {
5114 if (tok == '=') {
5115 next();
5116 } else {
5117 if (!gnu_ext)
5118 expect("=");
5120 } else {
5121 if (type->t & VT_ARRAY) {
5122 index = *cur_index;
5123 type = pointed_type(type);
5124 c += index * type_size(type, &align);
5125 } else {
5126 f = *cur_field;
5127 if (!f)
5128 tcc_error("too many field init");
5129 /* XXX: fix this mess by using explicit storage field */
5130 type1 = f->type;
5131 type1.t |= (type->t & ~VT_TYPE);
5132 type = &type1;
5133 c += f->c;
5136 decl_initializer(type, sec, c, 0, size_only);
5138 /* XXX: make it more general */
5139 if (!size_only && nb_elems > 1) {
5140 unsigned long c_end;
5141 uint8_t *src, *dst;
5142 int i;
5144 if (!sec)
5145 tcc_error("range init not supported yet for dynamic storage");
5146 c_end = c + nb_elems * elem_size;
5147 if (c_end > sec->data_allocated)
5148 section_realloc(sec, c_end);
5149 src = sec->data + c;
5150 dst = src;
5151 for(i = 1; i < nb_elems; i++) {
5152 dst += elem_size;
5153 memcpy(dst, src, elem_size);
5158 #define EXPR_VAL 0
5159 #define EXPR_CONST 1
5160 #define EXPR_ANY 2
5162 /* store a value or an expression directly in global data or in local array */
5163 static void init_putv(CType *type, Section *sec, unsigned long c,
5164 int v, int expr_type)
5166 int saved_global_expr, bt, bit_pos, bit_size;
5167 void *ptr;
5168 unsigned long long bit_mask;
5169 CType dtype;
5171 switch(expr_type) {
5172 case EXPR_VAL:
5173 vpushi(v);
5174 break;
5175 case EXPR_CONST:
5176 /* compound literals must be allocated globally in this case */
5177 saved_global_expr = global_expr;
5178 global_expr = 1;
5179 expr_const1();
5180 global_expr = saved_global_expr;
5181 /* NOTE: symbols are accepted */
5182 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5183 tcc_error("initializer element is not constant");
5184 break;
5185 case EXPR_ANY:
5186 expr_eq();
5187 break;
5190 dtype = *type;
5191 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5193 if (sec) {
5194 /* XXX: not portable */
5195 /* XXX: generate error if incorrect relocation */
5196 gen_assign_cast(&dtype);
5197 bt = type->t & VT_BTYPE;
5198 /* we'll write at most 12 bytes */
5199 if (c + 12 > sec->data_allocated) {
5200 section_realloc(sec, c + 12);
5202 ptr = sec->data + c;
5203 /* XXX: make code faster ? */
5204 if (!(type->t & VT_BITFIELD)) {
5205 bit_pos = 0;
5206 bit_size = 32;
5207 bit_mask = -1LL;
5208 } else {
5209 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5210 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5211 bit_mask = (1LL << bit_size) - 1;
5213 if ((vtop->r & VT_SYM) &&
5214 (bt == VT_BYTE ||
5215 bt == VT_SHORT ||
5216 bt == VT_DOUBLE ||
5217 bt == VT_LDOUBLE ||
5218 bt == VT_LLONG ||
5219 (bt == VT_INT && bit_size != 32)))
5220 tcc_error("initializer element is not computable at load time");
5221 switch(bt) {
5222 case VT_BOOL:
5223 vtop->c.i = (vtop->c.i != 0);
5224 case VT_BYTE:
5225 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5226 break;
5227 case VT_SHORT:
5228 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5229 break;
5230 case VT_DOUBLE:
5231 *(double *)ptr = vtop->c.d;
5232 break;
5233 case VT_LDOUBLE:
5234 *(long double *)ptr = vtop->c.ld;
5235 break;
5236 case VT_LLONG:
5237 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
5238 break;
5239 case VT_PTR:
5240 if (vtop->r & VT_SYM) {
5241 greloc(sec, vtop->sym, c, R_DATA_PTR);
5243 *(addr_t *)ptr |= (vtop->c.ptr_offset & bit_mask) << bit_pos;
5244 break;
5245 default:
5246 if (vtop->r & VT_SYM) {
5247 greloc(sec, vtop->sym, c, R_DATA_PTR);
5249 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5250 break;
5252 vtop--;
5253 } else {
5254 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5255 vswap();
5256 vstore();
5257 vpop();
5261 /* put zeros for variable based init */
5262 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5264 if (sec) {
5265 /* nothing to do because globals are already set to zero */
5266 } else {
5267 vpush_global_sym(&func_old_type, TOK_memset);
5268 vseti(VT_LOCAL, c);
5269 #ifdef TCC_TARGET_ARM
5270 vpushs(size);
5271 vpushi(0);
5272 #else
5273 vpushi(0);
5274 vpushs(size);
5275 #endif
5276 gfunc_call(3);
5280 /* 't' contains the type and storage info. 'c' is the offset of the
5281 object in section 'sec'. If 'sec' is NULL, it means stack based
5282 allocation. 'first' is true if array '{' must be read (multi
5283 dimension implicit array init handling). 'size_only' is true if
5284 size only evaluation is wanted (only for arrays). */
5285 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5286 int first, int size_only)
5288 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5289 int size1, align1, expr_type;
5290 Sym *s, *f;
5291 CType *t1;
5293 if (type->t & VT_VLA) {
5294 int a;
5296 /* save current stack pointer */
5297 if (vla_flags & VLA_NEED_NEW_FRAME) {
5298 vla_sp_save();
5299 vla_flags = VLA_IN_SCOPE;
5300 vla_sp_loc = &vla_sp_loc_tmp;
5303 vla_runtime_type_size(type, &a);
5304 gen_vla_alloc(type, a);
5305 vset(type, VT_LOCAL|VT_LVAL, c);
5306 vswap();
5307 vstore();
5308 vpop();
5309 } else if (type->t & VT_ARRAY) {
5310 s = type->ref;
5311 n = s->c;
5312 array_length = 0;
5313 t1 = pointed_type(type);
5314 size1 = type_size(t1, &align1);
5316 no_oblock = 1;
5317 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5318 tok == '{') {
5319 if (tok != '{')
5320 tcc_error("character array initializer must be a literal,"
5321 " optionally enclosed in braces");
5322 skip('{');
5323 no_oblock = 0;
5326 /* only parse strings here if correct type (otherwise: handle
5327 them as ((w)char *) expressions */
5328 if ((tok == TOK_LSTR &&
5329 #ifdef TCC_TARGET_PE
5330 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5331 #else
5332 (t1->t & VT_BTYPE) == VT_INT
5333 #endif
5334 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5335 while (tok == TOK_STR || tok == TOK_LSTR) {
5336 int cstr_len, ch;
5337 CString *cstr;
5339 cstr = tokc.cstr;
5340 /* compute maximum number of chars wanted */
5341 if (tok == TOK_STR)
5342 cstr_len = cstr->size;
5343 else
5344 cstr_len = cstr->size / sizeof(nwchar_t);
5345 cstr_len--;
5346 nb = cstr_len;
5347 if (n >= 0 && nb > (n - array_length))
5348 nb = n - array_length;
5349 if (!size_only) {
5350 if (cstr_len > nb)
5351 tcc_warning("initializer-string for array is too long");
5352 /* in order to go faster for common case (char
5353 string in global variable, we handle it
5354 specifically */
5355 if (sec && tok == TOK_STR && size1 == 1) {
5356 memcpy(sec->data + c + array_length, cstr->data, nb);
5357 } else {
5358 for(i=0;i<nb;i++) {
5359 if (tok == TOK_STR)
5360 ch = ((unsigned char *)cstr->data)[i];
5361 else
5362 ch = ((nwchar_t *)cstr->data)[i];
5363 init_putv(t1, sec, c + (array_length + i) * size1,
5364 ch, EXPR_VAL);
5368 array_length += nb;
5369 next();
5371 /* only add trailing zero if enough storage (no
5372 warning in this case since it is standard) */
5373 if (n < 0 || array_length < n) {
5374 if (!size_only) {
5375 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5377 array_length++;
5379 } else {
5380 index = 0;
5381 while (tok != '}') {
5382 decl_designator(type, sec, c, &index, NULL, size_only);
5383 if (n >= 0 && index >= n)
5384 tcc_error("index too large");
5385 /* must put zero in holes (note that doing it that way
5386 ensures that it even works with designators) */
5387 if (!size_only && array_length < index) {
5388 init_putz(t1, sec, c + array_length * size1,
5389 (index - array_length) * size1);
5391 index++;
5392 if (index > array_length)
5393 array_length = index;
5394 /* special test for multi dimensional arrays (may not
5395 be strictly correct if designators are used at the
5396 same time) */
5397 if (index >= n && no_oblock)
5398 break;
5399 if (tok == '}')
5400 break;
5401 skip(',');
5404 if (!no_oblock)
5405 skip('}');
5406 /* put zeros at the end */
5407 if (!size_only && n >= 0 && array_length < n) {
5408 init_putz(t1, sec, c + array_length * size1,
5409 (n - array_length) * size1);
5411 /* patch type size if needed */
5412 if (n < 0)
5413 s->c = array_length;
5414 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5415 (sec || !first || tok == '{')) {
5416 int par_count;
5418 /* NOTE: the previous test is a specific case for automatic
5419 struct/union init */
5420 /* XXX: union needs only one init */
5422 /* XXX: this test is incorrect for local initializers
5423 beginning with ( without {. It would be much more difficult
5424 to do it correctly (ideally, the expression parser should
5425 be used in all cases) */
5426 par_count = 0;
5427 if (tok == '(') {
5428 AttributeDef ad1;
5429 CType type1;
5430 next();
5431 while (tok == '(') {
5432 par_count++;
5433 next();
5435 if (!parse_btype(&type1, &ad1))
5436 expect("cast");
5437 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5438 #if 0
5439 if (!is_assignable_types(type, &type1))
5440 tcc_error("invalid type for cast");
5441 #endif
5442 skip(')');
5444 no_oblock = 1;
5445 if (first || tok == '{') {
5446 skip('{');
5447 no_oblock = 0;
5449 s = type->ref;
5450 f = s->next;
5451 array_length = 0;
5452 index = 0;
5453 n = s->c;
5454 while (tok != '}') {
5455 decl_designator(type, sec, c, NULL, &f, size_only);
5456 index = f->c;
5457 if (!size_only && array_length < index) {
5458 init_putz(type, sec, c + array_length,
5459 index - array_length);
5461 index = index + type_size(&f->type, &align1);
5462 if (index > array_length)
5463 array_length = index;
5465 /* gr: skip fields from same union - ugly. */
5466 while (f->next) {
5467 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5468 /* test for same offset */
5469 if (f->next->c != f->c)
5470 break;
5471 /* if yes, test for bitfield shift */
5472 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5473 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5474 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5475 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5476 if (bit_pos_1 != bit_pos_2)
5477 break;
5479 f = f->next;
5482 f = f->next;
5483 if (no_oblock && f == NULL)
5484 break;
5485 if (tok == '}')
5486 break;
5487 skip(',');
5489 /* put zeros at the end */
5490 if (!size_only && array_length < n) {
5491 init_putz(type, sec, c + array_length,
5492 n - array_length);
5494 if (!no_oblock)
5495 skip('}');
5496 while (par_count) {
5497 skip(')');
5498 par_count--;
5500 } else if (tok == '{') {
5501 next();
5502 decl_initializer(type, sec, c, first, size_only);
5503 skip('}');
5504 } else if (size_only) {
5505 /* just skip expression */
5506 parlevel = parlevel1 = 0;
5507 while ((parlevel > 0 || parlevel1 > 0 ||
5508 (tok != '}' && tok != ',')) && tok != -1) {
5509 if (tok == '(')
5510 parlevel++;
5511 else if (tok == ')')
5512 parlevel--;
5513 else if (tok == '{')
5514 parlevel1++;
5515 else if (tok == '}')
5516 parlevel1--;
5517 next();
5519 } else {
5520 /* currently, we always use constant expression for globals
5521 (may change for scripting case) */
5522 expr_type = EXPR_CONST;
5523 if (!sec)
5524 expr_type = EXPR_ANY;
5525 init_putv(type, sec, c, 0, expr_type);
5529 /* parse an initializer for type 't' if 'has_init' is non zero, and
5530 allocate space in local or global data space ('r' is either
5531 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5532 variable 'v' with an associated name represented by 'asm_label' of
5533 scope 'scope' is declared before initializers are parsed. If 'v' is
5534 zero, then a reference to the new object is put in the value stack.
5535 If 'has_init' is 2, a special parsing is done to handle string
5536 constants. */
5537 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5538 int has_init, int v, char *asm_label,
5539 int scope)
5541 int size, align, addr, data_offset;
5542 int level;
5543 ParseState saved_parse_state = {0};
5544 TokenString init_str;
5545 Section *sec;
5546 Sym *flexible_array;
5548 flexible_array = NULL;
5549 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5550 Sym *field = type->ref->next;
5551 if (field) {
5552 while (field->next)
5553 field = field->next;
5554 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5555 flexible_array = field;
5559 size = type_size(type, &align);
5560 /* If unknown size, we must evaluate it before
5561 evaluating initializers because
5562 initializers can generate global data too
5563 (e.g. string pointers or ISOC99 compound
5564 literals). It also simplifies local
5565 initializers handling */
5566 tok_str_new(&init_str);
5567 if (size < 0 || (flexible_array && has_init)) {
5568 if (!has_init)
5569 tcc_error("unknown type size");
5570 /* get all init string */
5571 if (has_init == 2) {
5572 /* only get strings */
5573 while (tok == TOK_STR || tok == TOK_LSTR) {
5574 tok_str_add_tok(&init_str);
5575 next();
5577 } else {
5578 level = 0;
5579 while (level > 0 || (tok != ',' && tok != ';')) {
5580 if (tok < 0)
5581 tcc_error("unexpected end of file in initializer");
5582 tok_str_add_tok(&init_str);
5583 if (tok == '{')
5584 level++;
5585 else if (tok == '}') {
5586 level--;
5587 if (level <= 0) {
5588 next();
5589 break;
5592 next();
5595 tok_str_add(&init_str, -1);
5596 tok_str_add(&init_str, 0);
5598 /* compute size */
5599 save_parse_state(&saved_parse_state);
5601 macro_ptr = init_str.str;
5602 next();
5603 decl_initializer(type, NULL, 0, 1, 1);
5604 /* prepare second initializer parsing */
5605 macro_ptr = init_str.str;
5606 next();
5608 /* if still unknown size, error */
5609 size = type_size(type, &align);
5610 if (size < 0)
5611 tcc_error("unknown type size");
5613 if (flexible_array)
5614 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5615 /* take into account specified alignment if bigger */
5616 if (ad->a.aligned) {
5617 if (ad->a.aligned > align)
5618 align = ad->a.aligned;
5619 } else if (ad->a.packed) {
5620 align = 1;
5622 if ((r & VT_VALMASK) == VT_LOCAL) {
5623 sec = NULL;
5624 #ifdef CONFIG_TCC_BCHECK
5625 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5626 loc--;
5628 #endif
5629 loc = (loc - size) & -align;
5630 addr = loc;
5631 #ifdef CONFIG_TCC_BCHECK
5632 /* handles bounds */
5633 /* XXX: currently, since we do only one pass, we cannot track
5634 '&' operators, so we add only arrays */
5635 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5636 unsigned long *bounds_ptr;
5637 /* add padding between regions */
5638 loc--;
5639 /* then add local bound info */
5640 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5641 bounds_ptr[0] = addr;
5642 bounds_ptr[1] = size;
5644 #endif
5645 if (v) {
5646 /* local variable */
5647 sym_push(v, type, r, addr);
5648 } else {
5649 /* push local reference */
5650 vset(type, r, addr);
5652 } else {
5653 Sym *sym;
5655 sym = NULL;
5656 if (v && scope == VT_CONST) {
5657 /* see if the symbol was already defined */
5658 sym = sym_find(v);
5659 if (sym) {
5660 if (!is_compatible_types(&sym->type, type))
5661 tcc_error("incompatible types for redefinition of '%s'",
5662 get_tok_str(v, NULL));
5663 if (sym->type.t & VT_EXTERN) {
5664 /* if the variable is extern, it was not allocated */
5665 sym->type.t &= ~VT_EXTERN;
5666 /* set array size if it was omitted in extern
5667 declaration */
5668 if ((sym->type.t & VT_ARRAY) &&
5669 sym->type.ref->c < 0 &&
5670 type->ref->c >= 0)
5671 sym->type.ref->c = type->ref->c;
5672 } else {
5673 /* we accept several definitions of the same
5674 global variable. this is tricky, because we
5675 must play with the SHN_COMMON type of the symbol */
5676 /* XXX: should check if the variable was already
5677 initialized. It is incorrect to initialized it
5678 twice */
5679 /* no init data, we won't add more to the symbol */
5680 if (!has_init)
5681 goto no_alloc;
5686 /* allocate symbol in corresponding section */
5687 sec = ad->section;
5688 if (!sec) {
5689 if (has_init)
5690 sec = data_section;
5691 else if (tcc_state->nocommon)
5692 sec = bss_section;
5694 if (sec) {
5695 data_offset = sec->data_offset;
5696 data_offset = (data_offset + align - 1) & -align;
5697 addr = data_offset;
5698 /* very important to increment global pointer at this time
5699 because initializers themselves can create new initializers */
5700 data_offset += size;
5701 #ifdef CONFIG_TCC_BCHECK
5702 /* add padding if bound check */
5703 if (tcc_state->do_bounds_check)
5704 data_offset++;
5705 #endif
5706 sec->data_offset = data_offset;
5707 /* allocate section space to put the data */
5708 if (sec->sh_type != SHT_NOBITS &&
5709 data_offset > sec->data_allocated)
5710 section_realloc(sec, data_offset);
5711 /* align section if needed */
5712 if (align > sec->sh_addralign)
5713 sec->sh_addralign = align;
5714 } else {
5715 addr = 0; /* avoid warning */
5718 if (v) {
5719 if (scope != VT_CONST || !sym) {
5720 sym = sym_push(v, type, r | VT_SYM, 0);
5721 sym->asm_label = asm_label;
5723 /* update symbol definition */
5724 if (sec) {
5725 put_extern_sym(sym, sec, addr, size);
5726 } else {
5727 ElfW(Sym) *esym;
5728 /* put a common area */
5729 put_extern_sym(sym, NULL, align, size);
5730 /* XXX: find a nicer way */
5731 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5732 esym->st_shndx = SHN_COMMON;
5734 } else {
5735 /* push global reference */
5736 sym = get_sym_ref(type, sec, addr, size);
5737 vpushsym(type, sym);
5739 /* patch symbol weakness */
5740 if (type->t & VT_WEAK)
5741 weaken_symbol(sym);
5742 apply_visibility(sym, type);
5743 #ifdef CONFIG_TCC_BCHECK
5744 /* handles bounds now because the symbol must be defined
5745 before for the relocation */
5746 if (tcc_state->do_bounds_check) {
5747 unsigned long *bounds_ptr;
5749 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5750 /* then add global bound info */
5751 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5752 bounds_ptr[0] = 0; /* relocated */
5753 bounds_ptr[1] = size;
5755 #endif
5757 if (has_init || (type->t & VT_VLA)) {
5758 decl_initializer(type, sec, addr, 1, 0);
5759 /* restore parse state if needed */
5760 if (init_str.str) {
5761 tok_str_free(init_str.str);
5762 restore_parse_state(&saved_parse_state);
5764 /* patch flexible array member size back to -1, */
5765 /* for possible subsequent similar declarations */
5766 if (flexible_array)
5767 flexible_array->type.ref->c = -1;
5769 no_alloc: ;
5772 static void put_func_debug(Sym *sym)
5774 char buf[512];
5776 /* stabs info */
5777 /* XXX: we put here a dummy type */
5778 snprintf(buf, sizeof(buf), "%s:%c1",
5779 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5780 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5781 cur_text_section, sym->c);
5782 /* //gr gdb wants a line at the function */
5783 put_stabn(N_SLINE, 0, file->line_num, 0);
5784 last_ind = 0;
5785 last_line_num = 0;
5788 /* parse an old style function declaration list */
5789 /* XXX: check multiple parameter */
5790 static void func_decl_list(Sym *func_sym)
5792 AttributeDef ad;
5793 int v;
5794 Sym *s;
5795 CType btype, type;
5797 /* parse each declaration */
5798 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5799 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5800 if (!parse_btype(&btype, &ad))
5801 expect("declaration list");
5802 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5803 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5804 tok == ';') {
5805 /* we accept no variable after */
5806 } else {
5807 for(;;) {
5808 type = btype;
5809 type_decl(&type, &ad, &v, TYPE_DIRECT);
5810 /* find parameter in function parameter list */
5811 s = func_sym->next;
5812 while (s != NULL) {
5813 if ((s->v & ~SYM_FIELD) == v)
5814 goto found;
5815 s = s->next;
5817 tcc_error("declaration for parameter '%s' but no such parameter",
5818 get_tok_str(v, NULL));
5819 found:
5820 /* check that no storage specifier except 'register' was given */
5821 if (type.t & VT_STORAGE)
5822 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5823 convert_parameter_type(&type);
5824 /* we can add the type (NOTE: it could be local to the function) */
5825 s->type = type;
5826 /* accept other parameters */
5827 if (tok == ',')
5828 next();
5829 else
5830 break;
5833 skip(';');
5837 /* parse a function defined by symbol 'sym' and generate its code in
5838 'cur_text_section' */
5839 static void gen_function(Sym *sym)
5841 int saved_nocode_wanted = nocode_wanted;
5842 nocode_wanted = 0;
5843 ind = cur_text_section->data_offset;
5844 /* NOTE: we patch the symbol size later */
5845 put_extern_sym(sym, cur_text_section, ind, 0);
5846 funcname = get_tok_str(sym->v, NULL);
5847 func_ind = ind;
5848 /* Initialize VLA state */
5849 vla_sp_loc = &vla_sp_root_loc;
5850 vla_flags = VLA_NEED_NEW_FRAME;
5851 /* put debug symbol */
5852 if (tcc_state->do_debug)
5853 put_func_debug(sym);
5854 /* push a dummy symbol to enable local sym storage */
5855 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5856 gfunc_prolog(&sym->type);
5857 #ifdef CONFIG_TCC_BCHECK
5858 if (tcc_state->do_bounds_check
5859 && !strcmp(get_tok_str(sym->v, NULL), "main")) {
5860 int i;
5862 sym = local_stack;
5863 for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) {
5864 if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD)
5865 break;
5866 vpush_global_sym(&func_old_type, TOK___bound_main_arg);
5867 vset(&sym->type, sym->r, sym->c);
5868 gfunc_call(1);
5871 #endif
5872 rsym = 0;
5873 block(NULL, NULL, NULL, NULL, 0, 0);
5874 gsym(rsym);
5875 gfunc_epilog();
5876 cur_text_section->data_offset = ind;
5877 label_pop(&global_label_stack, NULL);
5878 /* reset local stack */
5879 scope_stack_bottom = NULL;
5880 sym_pop(&local_stack, NULL);
5881 /* end of function */
5882 /* patch symbol size */
5883 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5884 ind - func_ind;
5885 /* patch symbol weakness (this definition overrules any prototype) */
5886 if (sym->type.t & VT_WEAK)
5887 weaken_symbol(sym);
5888 apply_visibility(sym, &sym->type);
5889 if (tcc_state->do_debug) {
5890 put_stabn(N_FUN, 0, 0, ind - func_ind);
5892 /* It's better to crash than to generate wrong code */
5893 cur_text_section = NULL;
5894 funcname = ""; /* for safety */
5895 func_vt.t = VT_VOID; /* for safety */
5896 func_var = 0; /* for safety */
5897 ind = 0; /* for safety */
5898 nocode_wanted = saved_nocode_wanted;
5901 ST_FUNC void gen_inline_functions(void)
5903 Sym *sym;
5904 int *str, inline_generated, i;
5905 struct InlineFunc *fn;
5907 /* iterate while inline function are referenced */
5908 for(;;) {
5909 inline_generated = 0;
5910 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5911 fn = tcc_state->inline_fns[i];
5912 sym = fn->sym;
5913 if (sym && sym->c) {
5914 /* the function was used: generate its code and
5915 convert it to a normal function */
5916 str = fn->token_str;
5917 fn->sym = NULL;
5918 if (file)
5919 pstrcpy(file->filename, sizeof file->filename, fn->filename);
5920 sym->r = VT_SYM | VT_CONST;
5921 sym->type.t &= ~VT_INLINE;
5923 macro_ptr = str;
5924 next();
5925 cur_text_section = text_section;
5926 gen_function(sym);
5927 macro_ptr = NULL; /* fail safe */
5929 inline_generated = 1;
5932 if (!inline_generated)
5933 break;
5935 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5936 fn = tcc_state->inline_fns[i];
5937 str = fn->token_str;
5938 tok_str_free(str);
5940 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5943 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5944 static int decl0(int l, int is_for_loop_init)
5946 int v, has_init, r;
5947 CType type, btype;
5948 Sym *sym;
5949 AttributeDef ad;
5951 while (1) {
5952 if (!parse_btype(&btype, &ad)) {
5953 if (is_for_loop_init)
5954 return 0;
5955 /* skip redundant ';' */
5956 /* XXX: find more elegant solution */
5957 if (tok == ';') {
5958 next();
5959 continue;
5961 if (l == VT_CONST &&
5962 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5963 /* global asm block */
5964 asm_global_instr();
5965 continue;
5967 /* special test for old K&R protos without explicit int
5968 type. Only accepted when defining global data */
5969 if (l == VT_LOCAL || tok < TOK_DEFINE)
5970 break;
5971 btype.t = VT_INT;
5973 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5974 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5975 tok == ';') {
5976 /* we accept no variable after */
5977 next();
5978 continue;
5980 while (1) { /* iterate thru each declaration */
5981 char *asm_label; // associated asm label
5982 type = btype;
5983 type_decl(&type, &ad, &v, TYPE_DIRECT);
5984 #if 0
5986 char buf[500];
5987 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5988 printf("type = '%s'\n", buf);
5990 #endif
5991 if ((type.t & VT_BTYPE) == VT_FUNC) {
5992 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5993 tcc_error("function without file scope cannot be static");
5995 /* if old style function prototype, we accept a
5996 declaration list */
5997 sym = type.ref;
5998 if (sym->c == FUNC_OLD)
5999 func_decl_list(sym);
6002 asm_label = NULL;
6003 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6004 CString astr;
6006 asm_label_instr(&astr);
6007 asm_label = tcc_strdup(astr.data);
6008 cstr_free(&astr);
6010 /* parse one last attribute list, after asm label */
6011 parse_attribute(&ad);
6014 if (ad.a.weak)
6015 type.t |= VT_WEAK;
6016 #ifdef TCC_TARGET_PE
6017 if (ad.a.func_import)
6018 type.t |= VT_IMPORT;
6019 if (ad.a.func_export)
6020 type.t |= VT_EXPORT;
6021 #endif
6022 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6024 if (tok == '{') {
6025 if (l == VT_LOCAL)
6026 tcc_error("cannot use local functions");
6027 if ((type.t & VT_BTYPE) != VT_FUNC)
6028 expect("function definition");
6030 /* reject abstract declarators in function definition */
6031 sym = type.ref;
6032 while ((sym = sym->next) != NULL)
6033 if (!(sym->v & ~SYM_FIELD))
6034 expect("identifier");
6036 /* XXX: cannot do better now: convert extern line to static inline */
6037 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6038 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6040 sym = sym_find(v);
6041 if (sym) {
6042 Sym *ref;
6043 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6044 goto func_error1;
6046 ref = sym->type.ref;
6047 if (0 == ref->a.func_proto)
6048 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6050 /* use func_call from prototype if not defined */
6051 if (ref->a.func_call != FUNC_CDECL
6052 && type.ref->a.func_call == FUNC_CDECL)
6053 type.ref->a.func_call = ref->a.func_call;
6055 /* use export from prototype */
6056 if (ref->a.func_export)
6057 type.ref->a.func_export = 1;
6059 /* use static from prototype */
6060 if (sym->type.t & VT_STATIC)
6061 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6063 /* If the definition has no visibility use the
6064 one from prototype. */
6065 if (! (type.t & VT_VIS_MASK))
6066 type.t |= sym->type.t & VT_VIS_MASK;
6068 if (!is_compatible_types(&sym->type, &type)) {
6069 func_error1:
6070 tcc_error("incompatible types for redefinition of '%s'",
6071 get_tok_str(v, NULL));
6073 type.ref->a.func_proto = 0;
6074 /* if symbol is already defined, then put complete type */
6075 sym->type = type;
6076 } else {
6077 /* put function symbol */
6078 sym = global_identifier_push(v, type.t, 0);
6079 sym->type.ref = type.ref;
6082 /* static inline functions are just recorded as a kind
6083 of macro. Their code will be emitted at the end of
6084 the compilation unit only if they are used */
6085 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6086 (VT_INLINE | VT_STATIC)) {
6087 TokenString func_str;
6088 int block_level;
6089 struct InlineFunc *fn;
6090 const char *filename;
6092 tok_str_new(&func_str);
6094 block_level = 0;
6095 for(;;) {
6096 int t;
6097 if (tok == TOK_EOF)
6098 tcc_error("unexpected end of file");
6099 tok_str_add_tok(&func_str);
6100 t = tok;
6101 next();
6102 if (t == '{') {
6103 block_level++;
6104 } else if (t == '}') {
6105 block_level--;
6106 if (block_level == 0)
6107 break;
6110 tok_str_add(&func_str, -1);
6111 tok_str_add(&func_str, 0);
6112 filename = file ? file->filename : "";
6113 fn = tcc_malloc(sizeof *fn + strlen(filename));
6114 strcpy(fn->filename, filename);
6115 fn->sym = sym;
6116 fn->token_str = func_str.str;
6117 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6119 } else {
6120 /* compute text section */
6121 cur_text_section = ad.section;
6122 if (!cur_text_section)
6123 cur_text_section = text_section;
6124 sym->r = VT_SYM | VT_CONST;
6125 gen_function(sym);
6127 break;
6128 } else {
6129 if (btype.t & VT_TYPEDEF) {
6130 /* save typedefed type */
6131 /* XXX: test storage specifiers ? */
6132 sym = sym_push(v, &type, 0, 0);
6133 sym->a = ad.a;
6134 sym->type.t |= VT_TYPEDEF;
6135 } else {
6136 r = 0;
6137 if ((type.t & VT_BTYPE) == VT_FUNC) {
6138 /* external function definition */
6139 /* specific case for func_call attribute */
6140 ad.a.func_proto = 1;
6141 type.ref->a = ad.a;
6142 } else if (!(type.t & VT_ARRAY)) {
6143 /* not lvalue if array */
6144 r |= lvalue_type(type.t);
6146 has_init = (tok == '=');
6147 if (has_init && (type.t & VT_VLA))
6148 tcc_error("Variable length array cannot be initialized");
6149 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6150 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6151 !has_init && l == VT_CONST && type.ref->c < 0)) {
6152 /* external variable or function */
6153 /* NOTE: as GCC, uninitialized global static
6154 arrays of null size are considered as
6155 extern */
6156 sym = external_sym(v, &type, r, asm_label);
6158 if (ad.alias_target) {
6159 Section tsec;
6160 Elf32_Sym *esym;
6161 Sym *alias_target;
6163 alias_target = sym_find(ad.alias_target);
6164 if (!alias_target || !alias_target->c)
6165 tcc_error("unsupported forward __alias__ attribute");
6166 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6167 tsec.sh_num = esym->st_shndx;
6168 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6170 } else {
6171 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6172 if (type.t & VT_STATIC)
6173 r |= VT_CONST;
6174 else
6175 r |= l;
6176 if (has_init)
6177 next();
6178 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
6181 if (tok != ',') {
6182 if (is_for_loop_init)
6183 return 1;
6184 skip(';');
6185 break;
6187 next();
6189 ad.a.aligned = 0;
6192 return 0;
6195 ST_FUNC void decl(int l)
6197 decl0(l, 0);