Win: Enable use "*.def + *.c" files as library instead of *.a by "-l" option
[tinycc.git] / tccgen.c
blobb2a771784f9ad29bf3ba0b887f4bfd5633a9459e
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /********************************************************/
24 /* global variables */
26 /* loc : local variable index
27 ind : output code index
28 rsym: return symbol
29 anon_sym: anonymous symbol index
31 ST_DATA int rsym, anon_sym, ind, loc;
33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
34 ST_DATA Section *cur_text_section; /* current section where function code is generated */
35 #ifdef CONFIG_TCC_ASM
36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
37 #endif
38 #ifdef CONFIG_TCC_BCHECK
39 /* bound check related sections */
40 ST_DATA Section *bounds_section; /* contains global data bound description */
41 ST_DATA Section *lbounds_section; /* contains local data bound description */
42 #endif
43 /* symbol sections */
44 ST_DATA Section *symtab_section, *strtab_section;
45 /* debug sections */
46 ST_DATA Section *stab_section, *stabstr_section;
47 ST_DATA Sym *sym_free_first;
48 ST_DATA void **sym_pools;
49 ST_DATA int nb_sym_pools;
51 ST_DATA Sym *global_stack;
52 ST_DATA Sym *local_stack;
53 ST_DATA Sym *scope_stack_bottom;
54 ST_DATA Sym *define_stack;
55 ST_DATA Sym *global_label_stack;
56 ST_DATA Sym *local_label_stack;
58 ST_DATA int vla_sp_loc_tmp; /* vla_sp_loc is set to this when the value won't be needed later */
59 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
60 ST_DATA int *vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
61 ST_DATA int vla_flags; /* VLA_* flags */
63 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
65 ST_DATA int const_wanted; /* true if constant wanted */
66 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
67 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
68 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
69 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
70 ST_DATA int func_vc;
71 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
72 ST_DATA char *funcname;
74 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
76 /* ------------------------------------------------------------------------- */
77 static void gen_cast(CType *type);
78 static inline CType *pointed_type(CType *type);
79 static int is_compatible_types(CType *type1, CType *type2);
80 static int parse_btype(CType *type, AttributeDef *ad);
81 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
82 static void parse_expr_type(CType *type);
83 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
84 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
85 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
86 static int decl0(int l, int is_for_loop_init);
87 static void expr_eq(void);
88 static void unary_type(CType *type);
89 static void vla_runtime_type_size(CType *type, int *a);
90 static void vla_sp_save(void);
91 static int is_compatible_parameter_types(CType *type1, CType *type2);
92 static void expr_type(CType *type);
93 static int is_putz;
94 static int is_force;
96 ST_FUNC void vpush64(int ty, unsigned long long v);
97 ST_FUNC void vpush(CType *type);
98 ST_FUNC int gvtst(int inv, int t);
99 ST_FUNC int is_btype_size(int bt);
101 ST_INLN int is_float(int t)
103 int bt;
104 bt = t & VT_BTYPE;
105 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
108 /* we use our own 'finite' function to avoid potential problems with
109 non standard math libs */
110 /* XXX: endianness dependent */
111 ST_FUNC int ieee_finite(double d)
113 int p[4];
114 memcpy(p, &d, sizeof(double));
115 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
118 ST_FUNC void test_lvalue(void)
120 if (!(vtop->r & VT_LVAL))
121 expect("lvalue");
124 /* ------------------------------------------------------------------------- */
125 /* symbol allocator */
126 static Sym *__sym_malloc(void)
128 Sym *sym_pool, *sym, *last_sym;
129 int i;
131 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
132 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
134 last_sym = sym_free_first;
135 sym = sym_pool;
136 for(i = 0; i < SYM_POOL_NB; i++) {
137 sym->next = last_sym;
138 last_sym = sym;
139 sym++;
141 sym_free_first = last_sym;
142 return last_sym;
145 static inline Sym *sym_malloc(void)
147 Sym *sym;
148 sym = sym_free_first;
149 if (!sym)
150 sym = __sym_malloc();
151 sym_free_first = sym->next;
152 return sym;
155 ST_INLN void sym_free(Sym *sym)
157 sym->next = sym_free_first;
158 tcc_free(sym->asm_label);
159 sym_free_first = sym;
162 /* push, without hashing */
163 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
165 Sym *s;
166 if (ps == &local_stack) {
167 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
168 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
169 tcc_error("incompatible types for redefinition of '%s'",
170 get_tok_str(v, NULL));
172 s = sym_malloc();
173 s->asm_label = NULL;
174 s->v = v;
175 s->type.t = t;
176 s->type.ref = NULL;
177 #ifdef _WIN64
178 s->d = NULL;
179 #endif
180 s->c = c;
181 s->next = NULL;
182 /* add in stack */
183 s->prev = *ps;
184 *ps = s;
185 return s;
188 /* find a symbol and return its associated structure. 's' is the top
189 of the symbol stack */
190 ST_FUNC Sym *sym_find2(Sym *s, int v)
192 while (s) {
193 if (s->v == v)
194 return s;
195 else if (s->v == -1)
196 return NULL;
197 s = s->prev;
199 return NULL;
202 /* structure lookup */
203 ST_INLN Sym *struct_find(int v)
205 v -= TOK_IDENT;
206 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
207 return NULL;
208 return table_ident[v]->sym_struct;
211 /* find an identifier */
212 ST_INLN Sym *sym_find(int v)
214 v -= TOK_IDENT;
215 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
216 return NULL;
217 return table_ident[v]->sym_identifier;
220 /* push a given symbol on the symbol stack */
221 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
223 Sym *s, **ps;
224 TokenSym *ts;
226 if (local_stack)
227 ps = &local_stack;
228 else
229 ps = &global_stack;
230 s = sym_push2(ps, v, type->t, c);
231 s->type.ref = type->ref;
232 s->r = r;
233 /* don't record fields or anonymous symbols */
234 /* XXX: simplify */
235 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
236 /* record symbol in token array */
237 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
238 if (v & SYM_STRUCT)
239 ps = &ts->sym_struct;
240 else
241 ps = &ts->sym_identifier;
242 s->prev_tok = *ps;
243 *ps = s;
245 return s;
248 /* push a global identifier */
249 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
251 Sym *s, **ps;
252 s = sym_push2(&global_stack, v, t, c);
253 /* don't record anonymous symbol */
254 if (v < SYM_FIRST_ANOM) {
255 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
256 /* modify the top most local identifier, so that
257 sym_identifier will point to 's' when popped */
258 while (*ps != NULL)
259 ps = &(*ps)->prev_tok;
260 s->prev_tok = NULL;
261 *ps = s;
263 return s;
266 /* pop symbols until top reaches 'b' */
267 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
269 Sym *s, *ss, **ps;
270 TokenSym *ts;
271 int v;
273 s = *ptop;
274 while(s != b) {
275 ss = s->prev;
276 v = s->v;
277 /* remove symbol in token array */
278 /* XXX: simplify */
279 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
280 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
281 if (v & SYM_STRUCT)
282 ps = &ts->sym_struct;
283 else
284 ps = &ts->sym_identifier;
285 *ps = s->prev_tok;
287 sym_free(s);
288 s = ss;
290 *ptop = b;
293 static void weaken_symbol(Sym *sym)
295 sym->type.t |= VT_WEAK;
296 if (sym->c > 0) {
297 int esym_type;
298 ElfW(Sym) *esym;
300 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
301 esym_type = ELFW(ST_TYPE)(esym->st_info);
302 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
306 static void apply_visibility(Sym *sym, CType *type)
308 int vis = sym->type.t & VT_VIS_MASK;
309 int vis2 = type->t & VT_VIS_MASK;
310 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
311 vis = vis2;
312 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
314 else
315 vis = (vis < vis2) ? vis : vis2;
316 sym->type.t &= ~VT_VIS_MASK;
317 sym->type.t |= vis;
319 if (sym->c > 0) {
320 ElfW(Sym) *esym;
322 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
323 vis >>= VT_VIS_SHIFT;
324 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
328 /* ------------------------------------------------------------------------- */
330 ST_FUNC void swap(int *p, int *q)
332 int t;
333 t = *p;
334 *p = *q;
335 *q = t;
338 static void vsetc(CType *type, int r, CValue *vc)
340 int v;
342 if (vtop >= vstack + (VSTACK_SIZE - 1))
343 tcc_error("memory full (vstack)");
344 /* cannot let cpu flags if other instruction are generated. Also
345 avoid leaving VT_JMP anywhere except on the top of the stack
346 because it would complicate the code generator. */
347 if (vtop >= vstack) {
348 v = vtop->r & VT_VALMASK;
349 if (v == VT_CMP || (v & ~1) == VT_JMP)
350 gv(RC_INT);
352 vtop++;
353 vtop->type = *type;
354 vtop->r = r;
355 vtop->r2 = VT_CONST;
356 vtop->c = *vc;
359 /* push constant of type "type" with useless value */
360 ST_FUNC void vpush(CType *type)
362 CValue cval;
363 vsetc(type, VT_CONST, &cval);
366 /* push integer constant */
367 ST_FUNC void vpushi(int v)
369 CValue cval;
370 cval.i = v;
371 vsetc(&int_type, VT_CONST, &cval);
374 /* push a pointer sized constant */
375 static void vpushs(addr_t v)
377 CValue cval;
378 cval.ptr_offset = v;
379 vsetc(&size_type, VT_CONST, &cval);
382 /* push arbitrary 64bit constant */
383 ST_FUNC void vpush64(int ty, unsigned long long v)
385 CValue cval;
386 CType ctype;
387 ctype.t = ty;
388 ctype.ref = NULL;
389 cval.ull = v;
390 vsetc(&ctype, VT_CONST, &cval);
393 /* push long long constant */
394 static inline void vpushll(long long v)
396 vpush64(VT_LLONG, v);
399 /* push a symbol value of TYPE */
400 static inline void vpushsym(CType *type, Sym *sym)
402 CValue cval;
403 cval.ptr_offset = 0;
404 vsetc(type, VT_CONST | VT_SYM, &cval);
405 vtop->sym = sym;
408 /* Return a static symbol pointing to a section */
409 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
411 int v;
412 Sym *sym;
414 v = anon_sym++;
415 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
416 sym->type.ref = type->ref;
417 sym->r = VT_CONST | VT_SYM;
418 put_extern_sym(sym, sec, offset, size);
419 return sym;
422 /* push a reference to a section offset by adding a dummy symbol */
423 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
425 vpushsym(type, get_sym_ref(type, sec, offset, size));
428 /* define a new external reference to a symbol 'v' of type 'u' */
429 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
431 Sym *s;
433 s = sym_find(v);
434 if (!s) {
435 /* push forward reference */
436 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
437 s->type.ref = type->ref;
438 s->r = r | VT_CONST | VT_SYM;
440 return s;
443 /* define a new external reference to a symbol 'v' with alternate asm
444 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
445 is no alternate name (most cases) */
446 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
448 Sym *s;
450 s = sym_find(v);
451 if (!s) {
452 /* push forward reference */
453 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
454 s->asm_label = asm_label;
455 s->type.t |= VT_EXTERN;
456 } else if (s->type.ref == func_old_type.ref) {
457 s->type.ref = type->ref;
458 s->r = r | VT_CONST | VT_SYM;
459 s->type.t |= VT_EXTERN;
460 } else if (!is_compatible_types(&s->type, type)) {
461 tcc_error("incompatible types for redefinition of '%s'",
462 get_tok_str(v, NULL));
464 /* Merge some storage attributes. */
465 if (type->t & VT_WEAK)
466 weaken_symbol(s);
468 if (type->t & VT_VIS_MASK)
469 apply_visibility(s, type);
471 return s;
474 /* push a reference to global symbol v */
475 ST_FUNC void vpush_global_sym(CType *type, int v)
477 vpushsym(type, external_global_sym(v, type, 0));
480 ST_FUNC void vset(CType *type, int r, int v)
482 CValue cval;
484 cval.i = v;
485 vsetc(type, r, &cval);
488 static void vseti(int r, int v)
490 CType type;
491 type.t = VT_INT;
492 type.ref = 0;
493 vset(&type, r, v);
496 ST_FUNC void vswap(void)
498 SValue tmp;
499 /* cannot let cpu flags if other instruction are generated. Also
500 avoid leaving VT_JMP anywhere except on the top of the stack
501 because it would complicate the code generator. */
502 if (vtop >= vstack) {
503 int v = vtop->r & VT_VALMASK;
504 if (v == VT_CMP || (v & ~1) == VT_JMP)
505 gv(RC_INT);
507 tmp = vtop[0];
508 vtop[0] = vtop[-1];
509 vtop[-1] = tmp;
511 /* XXX: +2% overall speed possible with optimized memswap
513 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
517 ST_FUNC void vpushv(SValue *v)
519 if (vtop >= vstack + (VSTACK_SIZE - 1))
520 tcc_error("memory full (vstack)");
521 vtop++;
522 *vtop = *v;
525 static void vdup(void)
527 vpushv(vtop);
530 /* save r to the memory stack, and mark it as being free */
531 ST_FUNC void save_reg(int r)
533 int l, saved, size, align;
534 SValue *p, sv;
535 CType *type;
537 /* modify all stack values */
538 saved = 0;
539 l = 0;
540 for(p=vstack;p<=vtop;p++) {
541 if ((p->r & VT_VALMASK) == r ||
542 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
543 /* must save value on stack if not already done */
544 if (!saved) {
545 /* NOTE: must reload 'r' because r might be equal to r2 */
546 r = p->r & VT_VALMASK;
547 /* store register in the stack */
548 type = &p->type;
549 if ((p->r & VT_LVAL) ||
550 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
551 #ifdef TCC_TARGET_X86_64
552 type = &char_pointer_type;
553 #else
554 type = &int_type;
555 #endif
556 size = type_size(type, &align);
557 loc = (loc - size) & -align;
558 sv.type.t = type->t;
559 sv.r = VT_LOCAL | VT_LVAL;
560 sv.c.ul = loc;
561 store(r, &sv);
562 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
563 /* x86 specific: need to pop fp register ST0 if saved */
564 if (r == TREG_ST0) {
565 o(0xd8dd); /* fstp %st(0) */
567 #endif
568 #ifndef TCC_TARGET_X86_64
569 /* special long long case */
570 if ((type->t & VT_BTYPE) == VT_LLONG) {
571 sv.c.ul += 4;
572 store(p->r2, &sv);
574 #endif
575 l = loc;
576 saved = 1;
578 /* mark that stack entry as being saved on the stack */
579 if (p->r & VT_LVAL) {
580 /* also clear the bounded flag because the
581 relocation address of the function was stored in
582 p->c.ul */
583 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
584 } else {
585 p->r = lvalue_type(p->type.t) | VT_LOCAL;
587 p->r2 = VT_CONST;
588 p->c.ul = l;
593 #ifdef TCC_TARGET_ARM
594 /* find a register of class 'rc2' with at most one reference on stack.
595 * If none, call get_reg(rc) */
596 ST_FUNC int get_reg_ex(int rc, int rc2)
598 int r;
599 SValue *p;
601 for(r=0;r<NB_REGS;r++) {
602 if (reg_classes[r] & rc2) {
603 int n;
604 n=0;
605 for(p = vstack; p <= vtop; p++) {
606 if ((p->r & VT_VALMASK) == r ||
607 (p->r2 & VT_VALMASK) == r)
608 n++;
610 if (n <= 1)
611 return r;
614 return get_reg(rc);
616 #endif
618 /* find a free register of class 'rc'. If none, save one register */
619 ST_FUNC int get_reg(int rc)
621 int r;
622 SValue *p;
624 /* find a free register */
625 for(r=0;r<NB_REGS;r++) {
626 if (reg_classes[r] & rc) {
627 for(p=vstack;p<=vtop;p++) {
628 if ((p->r & VT_VALMASK) == r ||
629 (p->r2 & VT_VALMASK) == r)
630 goto notfound;
632 return r;
634 notfound: ;
637 /* no register left : free the first one on the stack (VERY
638 IMPORTANT to start from the bottom to ensure that we don't
639 spill registers used in gen_opi()) */
640 for(p=vstack;p<=vtop;p++) {
641 /* look at second register (if long long) */
642 r = p->r2 & VT_VALMASK;
643 if (r < VT_CONST && (reg_classes[r] & rc))
644 goto save_found;
645 r = p->r & VT_VALMASK;
646 if (r < VT_CONST && (reg_classes[r] & rc)) {
647 save_found:
648 save_reg(r);
649 return r;
652 /* Should never comes here */
653 return -1;
656 /* save registers up to (vtop - n) stack entry */
657 ST_FUNC void save_regs(int n)
659 int r;
660 SValue *p, *p1;
661 p1 = vtop - n;
662 for(p = vstack;p <= p1; p++) {
663 r = p->r & VT_VALMASK;
664 if (r < VT_CONST) {
665 save_reg(r);
670 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
671 if needed */
672 static void move_reg(int r, int s, int t)
674 SValue sv;
676 if (r != s) {
677 save_reg(r);
678 sv.type.t = t;
679 sv.type.ref = NULL;
680 sv.r = s;
681 sv.c.ul = 0;
682 load(r, &sv);
686 /* get address of vtop (vtop MUST BE an lvalue) */
687 static void gaddrof(void)
689 if (vtop->r & VT_REF)
690 gv(RC_INT);
691 vtop->r &= ~VT_LVAL;
692 /* tricky: if saved lvalue, then we can go back to lvalue */
693 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
694 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
699 #ifdef CONFIG_TCC_BCHECK
700 /* generate lvalue bound code */
701 static void gbound(void)
703 int lval_type;
704 CType type1;
706 vtop->r &= ~VT_MUSTBOUND;
707 /* if lvalue, then use checking code before dereferencing */
708 if (vtop->r & VT_LVAL) {
709 /* if not VT_BOUNDED value, then make one */
710 if (!(vtop->r & VT_BOUNDED)) {
711 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
712 /* must save type because we must set it to int to get pointer */
713 type1 = vtop->type;
714 vtop->type.t = VT_INT;
715 gaddrof();
716 vpushi(0);
717 gen_bounded_ptr_add();
718 vtop->r |= lval_type;
719 vtop->type = type1;
721 /* then check for dereferencing */
722 gen_bounded_ptr_deref();
725 #endif
727 /* store vtop a register belonging to class 'rc'. lvalues are
728 converted to values. Cannot be used if cannot be converted to
729 register value (such as structures). */
730 ST_FUNC int gv(int rc)
732 int r, bit_pos, bit_size, size, align, i;
733 int rc2;
735 /* NOTE: get_reg can modify vstack[] */
736 if (vtop->type.t & VT_BITFIELD) {
737 CType type;
738 int bits = 32;
739 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
740 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
741 /* remove bit field info to avoid loops */
742 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
743 /* cast to int to propagate signedness in following ops */
744 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
745 type.t = VT_LLONG;
746 bits = 64;
747 } else
748 type.t = VT_INT;
749 if((vtop->type.t & VT_UNSIGNED) ||
750 (vtop->type.t & VT_BTYPE) == VT_BOOL)
751 type.t |= VT_UNSIGNED;
752 gen_cast(&type);
753 /* generate shifts */
754 vpushi(bits - (bit_pos + bit_size));
755 gen_op(TOK_SHL);
756 vpushi(bits - bit_size);
757 /* NOTE: transformed to SHR if unsigned */
758 gen_op(TOK_SAR);
759 r = gv(rc);
760 } else {
761 if (is_float(vtop->type.t) &&
762 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
763 Sym *sym;
764 int *ptr;
765 unsigned long offset;
766 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
767 CValue check;
768 #endif
770 /* XXX: unify with initializers handling ? */
771 /* CPUs usually cannot use float constants, so we store them
772 generically in data segment */
773 size = type_size(&vtop->type, &align);
774 offset = (data_section->data_offset + align - 1) & -align;
775 data_section->data_offset = offset;
776 /* XXX: not portable yet */
777 #if defined(__i386__) || defined(__x86_64__)
778 /* Zero pad x87 tenbyte long doubles */
779 if (size == LDOUBLE_SIZE) {
780 vtop->c.tab[2] &= 0xffff;
781 #if LDOUBLE_SIZE == 16
782 vtop->c.tab[3] = 0;
783 #endif
785 #endif
786 ptr = section_ptr_add(data_section, size);
787 size = size >> 2;
788 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
789 check.d = 1;
790 if(check.tab[0])
791 for(i=0;i<size;i++)
792 ptr[i] = vtop->c.tab[size-1-i];
793 else
794 #endif
795 for(i=0;i<size;i++)
796 ptr[i] = vtop->c.tab[i];
797 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
798 vtop->r |= VT_LVAL | VT_SYM;
799 vtop->sym = sym;
800 vtop->c.ptr_offset = 0;
802 #ifdef CONFIG_TCC_BCHECK
803 if (vtop->r & VT_MUSTBOUND)
804 gbound();
805 #endif
807 r = vtop->r & VT_VALMASK;
808 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
809 if (rc == RC_IRET)
810 rc2 = RC_LRET;
811 #ifdef TCC_TARGET_X86_64
812 else if (rc == RC_FRET)
813 rc2 = RC_QRET;
814 #endif
816 /* need to reload if:
817 - constant
818 - lvalue (need to dereference pointer)
819 - already a register, but not in the right class */
820 if (r >= VT_CONST
821 || (vtop->r & VT_LVAL)
822 || !(reg_classes[r] & rc)
823 #ifdef TCC_TARGET_X86_64
824 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
825 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
826 #else
827 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
828 #endif
831 r = get_reg(rc);
832 #ifdef TCC_TARGET_X86_64
833 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
834 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
835 #else
836 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
837 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
838 unsigned long long ll;
839 #endif
840 int r2, original_type;
841 original_type = vtop->type.t;
842 /* two register type load : expand to two words
843 temporarily */
844 #ifndef TCC_TARGET_X86_64
845 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
846 /* load constant */
847 ll = vtop->c.ull;
848 vtop->c.ui = ll; /* first word */
849 load(r, vtop);
850 vtop->r = r; /* save register value */
851 vpushi(ll >> 32); /* second word */
852 } else
853 #endif
854 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
855 (vtop->r & VT_LVAL)) {
856 /* We do not want to modifier the long long
857 pointer here, so the safest (and less
858 efficient) is to save all the other registers
859 in the stack. XXX: totally inefficient. */
860 save_regs(1);
861 /* load from memory */
862 vtop->type.t = load_type;
863 load(r, vtop);
864 vdup();
865 vtop[-1].r = r; /* save register value */
866 /* increment pointer to get second word */
867 vtop->type.t = addr_type;
868 gaddrof();
869 vpushi(load_size);
870 gen_op('+');
871 vtop->r |= VT_LVAL;
872 vtop->type.t = load_type;
873 } else {
874 /* move registers */
875 load(r, vtop);
876 vdup();
877 vtop[-1].r = r; /* save register value */
878 vtop->r = vtop[-1].r2;
880 /* Allocate second register. Here we rely on the fact that
881 get_reg() tries first to free r2 of an SValue. */
882 r2 = get_reg(rc2);
883 load(r2, vtop);
884 vpop();
885 /* write second register */
886 vtop->r2 = r2;
887 vtop->type.t = original_type;
888 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
889 int t1, t;
890 /* lvalue of scalar type : need to use lvalue type
891 because of possible cast */
892 t = vtop->type.t;
893 t1 = t;
894 /* compute memory access type */
895 if (vtop->r & VT_REF)
896 #ifdef TCC_TARGET_X86_64
897 t = VT_PTR;
898 #else
899 t = VT_INT;
900 #endif
901 else if (vtop->r & VT_LVAL_BYTE)
902 t = VT_BYTE;
903 else if (vtop->r & VT_LVAL_SHORT)
904 t = VT_SHORT;
905 if (vtop->r & VT_LVAL_UNSIGNED)
906 t |= VT_UNSIGNED;
907 vtop->type.t = t;
908 load(r, vtop);
909 /* restore wanted type */
910 vtop->type.t = t1;
911 } else {
912 /* one register type load */
913 load(r, vtop);
916 vtop->r = r;
917 #ifdef TCC_TARGET_C67
918 /* uses register pairs for doubles */
919 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
920 vtop->r2 = r+1;
921 #endif
923 return r;
926 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
927 ST_FUNC void gv2(int rc1, int rc2)
929 int v;
931 /* generate more generic register first. But VT_JMP or VT_CMP
932 values must be generated first in all cases to avoid possible
933 reload errors */
934 v = vtop[0].r & VT_VALMASK;
935 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
936 vswap();
937 gv(rc1);
938 vswap();
939 gv(rc2);
940 /* test if reload is needed for first register */
941 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
942 vswap();
943 gv(rc1);
944 vswap();
946 } else {
947 gv(rc2);
948 vswap();
949 gv(rc1);
950 vswap();
951 /* test if reload is needed for first register */
952 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
953 gv(rc2);
958 /* wrapper around RC_FRET to return a register by type */
959 static int rc_fret(int t)
961 #ifdef TCC_TARGET_X86_64
962 if (t == VT_LDOUBLE) {
963 return RC_ST0;
965 #endif
966 return RC_FRET;
969 /* wrapper around REG_FRET to return a register by type */
970 static int reg_fret(int t)
972 #ifdef TCC_TARGET_X86_64
973 if (t == VT_LDOUBLE) {
974 return TREG_ST0;
976 #endif
977 return REG_FRET;
980 /* expand long long on stack in two int registers */
981 static void lexpand(void)
983 int u;
985 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
986 gv(RC_INT);
987 vdup();
988 vtop[0].r = vtop[-1].r2;
989 vtop[0].r2 = VT_CONST;
990 vtop[-1].r2 = VT_CONST;
991 vtop[0].type.t = VT_INT | u;
992 vtop[-1].type.t = VT_INT | u;
995 #ifdef TCC_TARGET_ARM
996 /* expand long long on stack */
997 ST_FUNC void lexpand_nr(void)
999 int u,v;
1001 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1002 vdup();
1003 vtop->r2 = VT_CONST;
1004 vtop->type.t = VT_INT | u;
1005 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1006 if (v == VT_CONST) {
1007 vtop[-1].c.ui = vtop->c.ull;
1008 vtop->c.ui = vtop->c.ull >> 32;
1009 vtop->r = VT_CONST;
1010 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1011 vtop->c.ui += 4;
1012 vtop->r = vtop[-1].r;
1013 } else if (v > VT_CONST) {
1014 vtop--;
1015 lexpand();
1016 } else
1017 vtop->r = vtop[-1].r2;
1018 vtop[-1].r2 = VT_CONST;
1019 vtop[-1].type.t = VT_INT | u;
1021 #endif
1023 #ifndef TCC_TARGET_X86_64
1024 /* build a long long from two ints */
1025 static void lbuild(int t)
1027 gv2(RC_INT, RC_INT);
1028 vtop[-1].r2 = vtop[0].r;
1029 vtop[-1].type.t = t;
1030 vpop();
1032 #endif
1034 /* rotate n first stack elements to the bottom
1035 I1 ... In -> I2 ... In I1 [top is right]
1037 ST_FUNC void vrotb(int n)
1039 int i;
1040 SValue tmp;
1042 tmp = vtop[-n + 1];
1043 for(i=-n+1;i!=0;i++)
1044 vtop[i] = vtop[i+1];
1045 vtop[0] = tmp;
1048 /* rotate the n elements before entry e towards the top
1049 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1051 ST_FUNC void vrote(SValue *e, int n)
1053 int i;
1054 SValue tmp;
1056 tmp = *e;
1057 for(i = 0;i < n - 1; i++)
1058 e[-i] = e[-i - 1];
1059 e[-n + 1] = tmp;
1062 /* rotate n first stack elements to the top
1063 I1 ... In -> In I1 ... I(n-1) [top is right]
1065 ST_FUNC void vrott(int n)
1067 vrote(vtop, n);
1070 /* pop stack value */
1071 ST_FUNC void vpop(void)
1073 int v;
1074 v = vtop->r & VT_VALMASK;
1075 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1076 /* for x86, we need to pop the FP stack */
1077 if (v == TREG_ST0 && !nocode_wanted) {
1078 o(0xd8dd); /* fstp %st(0) */
1079 } else
1080 #endif
1081 if (v == VT_JMP || v == VT_JMPI) {
1082 /* need to put correct jump if && or || without test */
1083 gsym(vtop->c.ul);
1085 vtop--;
1088 /* convert stack entry to register and duplicate its value in another
1089 register */
1090 static void gv_dup(void)
1092 int rc, t, r, r1;
1093 SValue sv;
1094 t = vtop->type.t;
1095 #ifndef TCC_TARGET_X86_64
1096 if ((t & VT_BTYPE) == VT_LLONG) {
1097 lexpand();
1098 gv_dup();
1099 vswap();
1100 vrotb(3);
1101 gv_dup();
1102 vrotb(4);
1103 /* stack: H L L1 H1 */
1104 lbuild(t);
1105 vrott(3);
1106 vswap();
1107 lbuild(t);
1108 vswap();
1109 } else
1110 #endif
1112 /* duplicate value */
1113 if (is_float(t)) {
1114 rc = RC_FLOAT;
1115 #ifdef TCC_TARGET_X86_64
1116 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1117 rc = RC_ST0;
1119 #endif
1120 }else
1121 rc = RC_INT;
1122 sv.type.t = t;
1123 r = gv(rc);
1124 r1 = get_reg(rc);
1125 sv.r = r;
1126 sv.c.ul = 0;
1127 load(r1, &sv); /* move r to r1 */
1128 vdup();
1129 /* duplicates value */
1130 if (r != r1)
1131 vtop->r = r1;
1135 /* Generate value test
1137 * Generate a test for any value (jump, comparison and integers) */
1138 ST_FUNC int gvtst(int inv, int t)
1140 int v = vtop->r & VT_VALMASK;
1141 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1142 vpushi(0);
1143 gen_op(TOK_NE);
1145 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1146 /* constant jmp optimization */
1147 if ((vtop->c.i != 0) != inv)
1148 t = gjmp(t);
1149 vtop--;
1150 return t;
1152 return gtst(inv, t);
1155 #ifndef TCC_TARGET_X86_64
1156 /* generate CPU independent (unsigned) long long operations */
1157 static void gen_opl(int op)
1159 int t, a, b, op1, c, i;
1160 int func;
1161 unsigned short reg_iret = REG_IRET;
1162 unsigned short reg_lret = REG_LRET;
1163 SValue tmp;
1165 switch(op) {
1166 case '/':
1167 case TOK_PDIV:
1168 func = TOK___divdi3;
1169 goto gen_func;
1170 case TOK_UDIV:
1171 func = TOK___udivdi3;
1172 goto gen_func;
1173 case '%':
1174 func = TOK___moddi3;
1175 goto gen_mod_func;
1176 case TOK_UMOD:
1177 func = TOK___umoddi3;
1178 gen_mod_func:
1179 #ifdef TCC_ARM_EABI
1180 reg_iret = TREG_R2;
1181 reg_lret = TREG_R3;
1182 #endif
1183 gen_func:
1184 /* call generic long long function */
1185 vpush_global_sym(&func_old_type, func);
1186 vrott(3);
1187 gfunc_call(2);
1188 vpushi(0);
1189 vtop->r = reg_iret;
1190 vtop->r2 = reg_lret;
1191 break;
1192 case '^':
1193 case '&':
1194 case '|':
1195 case '*':
1196 case '+':
1197 case '-':
1198 t = vtop->type.t;
1199 vswap();
1200 lexpand();
1201 vrotb(3);
1202 lexpand();
1203 /* stack: L1 H1 L2 H2 */
1204 tmp = vtop[0];
1205 vtop[0] = vtop[-3];
1206 vtop[-3] = tmp;
1207 tmp = vtop[-2];
1208 vtop[-2] = vtop[-3];
1209 vtop[-3] = tmp;
1210 vswap();
1211 /* stack: H1 H2 L1 L2 */
1212 if (op == '*') {
1213 vpushv(vtop - 1);
1214 vpushv(vtop - 1);
1215 gen_op(TOK_UMULL);
1216 lexpand();
1217 /* stack: H1 H2 L1 L2 ML MH */
1218 for(i=0;i<4;i++)
1219 vrotb(6);
1220 /* stack: ML MH H1 H2 L1 L2 */
1221 tmp = vtop[0];
1222 vtop[0] = vtop[-2];
1223 vtop[-2] = tmp;
1224 /* stack: ML MH H1 L2 H2 L1 */
1225 gen_op('*');
1226 vrotb(3);
1227 vrotb(3);
1228 gen_op('*');
1229 /* stack: ML MH M1 M2 */
1230 gen_op('+');
1231 gen_op('+');
1232 } else if (op == '+' || op == '-') {
1233 /* XXX: add non carry method too (for MIPS or alpha) */
1234 if (op == '+')
1235 op1 = TOK_ADDC1;
1236 else
1237 op1 = TOK_SUBC1;
1238 gen_op(op1);
1239 /* stack: H1 H2 (L1 op L2) */
1240 vrotb(3);
1241 vrotb(3);
1242 gen_op(op1 + 1); /* TOK_xxxC2 */
1243 } else {
1244 gen_op(op);
1245 /* stack: H1 H2 (L1 op L2) */
1246 vrotb(3);
1247 vrotb(3);
1248 /* stack: (L1 op L2) H1 H2 */
1249 gen_op(op);
1250 /* stack: (L1 op L2) (H1 op H2) */
1252 /* stack: L H */
1253 lbuild(t);
1254 break;
1255 case TOK_SAR:
1256 case TOK_SHR:
1257 case TOK_SHL:
1258 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1259 t = vtop[-1].type.t;
1260 vswap();
1261 lexpand();
1262 vrotb(3);
1263 /* stack: L H shift */
1264 c = (int)vtop->c.i;
1265 /* constant: simpler */
1266 /* NOTE: all comments are for SHL. the other cases are
1267 done by swaping words */
1268 vpop();
1269 if (op != TOK_SHL)
1270 vswap();
1271 if (c >= 32) {
1272 /* stack: L H */
1273 vpop();
1274 if (c > 32) {
1275 vpushi(c - 32);
1276 gen_op(op);
1278 if (op != TOK_SAR) {
1279 vpushi(0);
1280 } else {
1281 gv_dup();
1282 vpushi(31);
1283 gen_op(TOK_SAR);
1285 vswap();
1286 } else {
1287 vswap();
1288 gv_dup();
1289 /* stack: H L L */
1290 vpushi(c);
1291 gen_op(op);
1292 vswap();
1293 vpushi(32 - c);
1294 if (op == TOK_SHL)
1295 gen_op(TOK_SHR);
1296 else
1297 gen_op(TOK_SHL);
1298 vrotb(3);
1299 /* stack: L L H */
1300 vpushi(c);
1301 if (op == TOK_SHL)
1302 gen_op(TOK_SHL);
1303 else
1304 gen_op(TOK_SHR);
1305 gen_op('|');
1307 if (op != TOK_SHL)
1308 vswap();
1309 lbuild(t);
1310 } else {
1311 /* XXX: should provide a faster fallback on x86 ? */
1312 switch(op) {
1313 case TOK_SAR:
1314 func = TOK___ashrdi3;
1315 goto gen_func;
1316 case TOK_SHR:
1317 func = TOK___lshrdi3;
1318 goto gen_func;
1319 case TOK_SHL:
1320 func = TOK___ashldi3;
1321 goto gen_func;
1324 break;
1325 default:
1326 /* compare operations */
1327 t = vtop->type.t;
1328 vswap();
1329 lexpand();
1330 vrotb(3);
1331 lexpand();
1332 /* stack: L1 H1 L2 H2 */
1333 tmp = vtop[-1];
1334 vtop[-1] = vtop[-2];
1335 vtop[-2] = tmp;
1336 /* stack: L1 L2 H1 H2 */
1337 /* compare high */
1338 op1 = op;
1339 /* when values are equal, we need to compare low words. since
1340 the jump is inverted, we invert the test too. */
1341 if (op1 == TOK_LT)
1342 op1 = TOK_LE;
1343 else if (op1 == TOK_GT)
1344 op1 = TOK_GE;
1345 else if (op1 == TOK_ULT)
1346 op1 = TOK_ULE;
1347 else if (op1 == TOK_UGT)
1348 op1 = TOK_UGE;
1349 a = 0;
1350 b = 0;
1351 gen_op(op1);
1352 if (op1 != TOK_NE) {
1353 a = gvtst(1, 0);
1355 if (op != TOK_EQ) {
1356 /* generate non equal test */
1357 /* XXX: NOT PORTABLE yet */
1358 if (a == 0) {
1359 b = gvtst(0, 0);
1360 } else {
1361 #if defined(TCC_TARGET_I386)
1362 b = psym(0x850f, 0);
1363 #elif defined(TCC_TARGET_ARM)
1364 b = ind;
1365 o(0x1A000000 | encbranch(ind, 0, 1));
1366 #elif defined(TCC_TARGET_C67)
1367 tcc_error("not implemented");
1368 #else
1369 #error not supported
1370 #endif
1373 /* compare low. Always unsigned */
1374 op1 = op;
1375 if (op1 == TOK_LT)
1376 op1 = TOK_ULT;
1377 else if (op1 == TOK_LE)
1378 op1 = TOK_ULE;
1379 else if (op1 == TOK_GT)
1380 op1 = TOK_UGT;
1381 else if (op1 == TOK_GE)
1382 op1 = TOK_UGE;
1383 gen_op(op1);
1384 a = gvtst(1, a);
1385 gsym(b);
1386 vseti(VT_JMPI, a);
1387 break;
1390 #endif
1392 /* handle integer constant optimizations and various machine
1393 independent opt */
1394 static void gen_opic(int op)
1396 int c1, c2, t1, t2, n;
1397 SValue *v1, *v2;
1398 long long l1, l2;
1399 typedef unsigned long long U;
1401 v1 = vtop - 1;
1402 v2 = vtop;
1403 t1 = v1->type.t & VT_BTYPE;
1404 t2 = v2->type.t & VT_BTYPE;
1406 if (t1 == VT_LLONG)
1407 l1 = v1->c.ll;
1408 else if (v1->type.t & VT_UNSIGNED)
1409 l1 = v1->c.ui;
1410 else
1411 l1 = v1->c.i;
1413 if (t2 == VT_LLONG)
1414 l2 = v2->c.ll;
1415 else if (v2->type.t & VT_UNSIGNED)
1416 l2 = v2->c.ui;
1417 else
1418 l2 = v2->c.i;
1420 /* currently, we cannot do computations with forward symbols */
1421 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1422 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1423 if (c1 && c2) {
1424 switch(op) {
1425 case '+': l1 += l2; break;
1426 case '-': l1 -= l2; break;
1427 case '&': l1 &= l2; break;
1428 case '^': l1 ^= l2; break;
1429 case '|': l1 |= l2; break;
1430 case '*': l1 *= l2; break;
1432 case TOK_PDIV:
1433 case '/':
1434 case '%':
1435 case TOK_UDIV:
1436 case TOK_UMOD:
1437 /* if division by zero, generate explicit division */
1438 if (l2 == 0) {
1439 if (const_wanted)
1440 tcc_error("division by zero in constant");
1441 goto general_case;
1443 switch(op) {
1444 default: l1 /= l2; break;
1445 case '%': l1 %= l2; break;
1446 case TOK_UDIV: l1 = (U)l1 / l2; break;
1447 case TOK_UMOD: l1 = (U)l1 % l2; break;
1449 break;
1450 case TOK_SHL: l1 <<= l2; break;
1451 case TOK_SHR: l1 = (U)l1 >> l2; break;
1452 case TOK_SAR: l1 >>= l2; break;
1453 /* tests */
1454 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1455 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1456 case TOK_EQ: l1 = l1 == l2; break;
1457 case TOK_NE: l1 = l1 != l2; break;
1458 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1459 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1460 case TOK_LT: l1 = l1 < l2; break;
1461 case TOK_GE: l1 = l1 >= l2; break;
1462 case TOK_LE: l1 = l1 <= l2; break;
1463 case TOK_GT: l1 = l1 > l2; break;
1464 /* logical */
1465 case TOK_LAND: l1 = l1 && l2; break;
1466 case TOK_LOR: l1 = l1 || l2; break;
1467 default:
1468 goto general_case;
1470 v1->c.ll = l1;
1471 vtop--;
1472 } else {
1473 /* if commutative ops, put c2 as constant */
1474 if (c1 && (op == '+' || op == '&' || op == '^' ||
1475 op == '|' || op == '*')) {
1476 vswap();
1477 c2 = c1; //c = c1, c1 = c2, c2 = c;
1478 l2 = l1; //l = l1, l1 = l2, l2 = l;
1480 /* Filter out NOP operations like x*1, x-0, x&-1... */
1481 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1482 op == TOK_PDIV) &&
1483 l2 == 1) ||
1484 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1485 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1486 l2 == 0) ||
1487 (op == '&' &&
1488 l2 == -1))) {
1489 /* nothing to do */
1490 vtop--;
1491 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1492 /* try to use shifts instead of muls or divs */
1493 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1494 n = -1;
1495 while (l2) {
1496 l2 >>= 1;
1497 n++;
1499 vtop->c.ll = n;
1500 if (op == '*')
1501 op = TOK_SHL;
1502 else if (op == TOK_PDIV)
1503 op = TOK_SAR;
1504 else
1505 op = TOK_SHR;
1507 goto general_case;
1508 } else if (c2 && (op == '+' || op == '-') &&
1509 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1510 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1511 /* symbol + constant case */
1512 if (op == '-')
1513 l2 = -l2;
1514 vtop--;
1515 vtop->c.ll += l2;
1516 } else {
1517 general_case:
1518 if (!nocode_wanted) {
1519 /* call low level op generator */
1520 if (t1 == VT_LLONG || t2 == VT_LLONG)
1521 gen_opl(op);
1522 else
1523 gen_opi(op);
1524 } else {
1525 vtop--;
1531 /* generate a floating point operation with constant propagation */
1532 static void gen_opif(int op)
1534 int c1, c2;
1535 SValue *v1, *v2;
1536 long double f1, f2;
1538 v1 = vtop - 1;
1539 v2 = vtop;
1540 /* currently, we cannot do computations with forward symbols */
1541 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1542 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1543 if (c1 && c2) {
1544 if (v1->type.t == VT_FLOAT) {
1545 f1 = v1->c.f;
1546 f2 = v2->c.f;
1547 } else if (v1->type.t == VT_DOUBLE) {
1548 f1 = v1->c.d;
1549 f2 = v2->c.d;
1550 } else {
1551 f1 = v1->c.ld;
1552 f2 = v2->c.ld;
1555 /* NOTE: we only do constant propagation if finite number (not
1556 NaN or infinity) (ANSI spec) */
1557 if (!ieee_finite(f1) || !ieee_finite(f2))
1558 goto general_case;
1560 switch(op) {
1561 case '+': f1 += f2; break;
1562 case '-': f1 -= f2; break;
1563 case '*': f1 *= f2; break;
1564 case '/':
1565 if (f2 == 0.0) {
1566 if (const_wanted)
1567 tcc_error("division by zero in constant");
1568 goto general_case;
1570 f1 /= f2;
1571 break;
1572 /* XXX: also handles tests ? */
1573 default:
1574 goto general_case;
1576 /* XXX: overflow test ? */
1577 if (v1->type.t == VT_FLOAT) {
1578 v1->c.f = f1;
1579 } else if (v1->type.t == VT_DOUBLE) {
1580 v1->c.d = f1;
1581 } else {
1582 v1->c.ld = f1;
1584 vtop--;
1585 } else {
1586 general_case:
1587 if (!nocode_wanted) {
1588 gen_opf(op);
1589 } else {
1590 vtop--;
1595 static int pointed_size(CType *type)
1597 int align;
1598 return type_size(pointed_type(type), &align);
1601 static void vla_runtime_pointed_size(CType *type)
1603 int align;
1604 vla_runtime_type_size(pointed_type(type), &align);
1607 static inline int is_null_pointer(SValue *p)
1609 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1610 return 0;
1611 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1612 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1613 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0);
1616 static inline int is_integer_btype(int bt)
1618 return (bt == VT_BYTE || bt == VT_SHORT ||
1619 bt == VT_INT || bt == VT_LLONG);
1622 /* check types for comparison or subtraction of pointers */
1623 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1625 CType *type1, *type2, tmp_type1, tmp_type2;
1626 int bt1, bt2;
1628 /* null pointers are accepted for all comparisons as gcc */
1629 if (is_null_pointer(p1) || is_null_pointer(p2))
1630 return;
1631 type1 = &p1->type;
1632 type2 = &p2->type;
1633 bt1 = type1->t & VT_BTYPE;
1634 bt2 = type2->t & VT_BTYPE;
1635 /* accept comparison between pointer and integer with a warning */
1636 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1637 if (op != TOK_LOR && op != TOK_LAND )
1638 tcc_warning("comparison between pointer and integer");
1639 return;
1642 /* both must be pointers or implicit function pointers */
1643 if (bt1 == VT_PTR) {
1644 type1 = pointed_type(type1);
1645 } else if (bt1 != VT_FUNC)
1646 goto invalid_operands;
1648 if (bt2 == VT_PTR) {
1649 type2 = pointed_type(type2);
1650 } else if (bt2 != VT_FUNC) {
1651 invalid_operands:
1652 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1654 if ((type1->t & VT_BTYPE) == VT_VOID ||
1655 (type2->t & VT_BTYPE) == VT_VOID)
1656 return;
1657 tmp_type1 = *type1;
1658 tmp_type2 = *type2;
1659 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1660 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1661 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1662 /* gcc-like error if '-' is used */
1663 if (op == '-')
1664 goto invalid_operands;
1665 else
1666 tcc_warning("comparison of distinct pointer types lacks a cast");
1670 /* generic gen_op: handles types problems */
1671 ST_FUNC void gen_op(int op)
1673 int u, t1, t2, bt1, bt2, t;
1674 CType type1;
1676 t1 = vtop[-1].type.t;
1677 t2 = vtop[0].type.t;
1678 bt1 = t1 & VT_BTYPE;
1679 bt2 = t2 & VT_BTYPE;
1681 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1682 /* at least one operand is a pointer */
1683 /* relationnal op: must be both pointers */
1684 if (op >= TOK_ULT && op <= TOK_LOR) {
1685 check_comparison_pointer_types(vtop - 1, vtop, op);
1686 /* pointers are handled are unsigned */
1687 #ifdef TCC_TARGET_X86_64
1688 t = VT_LLONG | VT_UNSIGNED;
1689 #else
1690 t = VT_INT | VT_UNSIGNED;
1691 #endif
1692 goto std_op;
1694 /* if both pointers, then it must be the '-' op */
1695 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1696 if (op != '-')
1697 tcc_error("cannot use pointers here");
1698 check_comparison_pointer_types(vtop - 1, vtop, op);
1699 /* XXX: check that types are compatible */
1700 if (vtop[-1].type.t & VT_VLA) {
1701 vla_runtime_pointed_size(&vtop[-1].type);
1702 } else {
1703 vpushi(pointed_size(&vtop[-1].type));
1705 vrott(3);
1706 gen_opic(op);
1707 /* set to integer type */
1708 #ifdef TCC_TARGET_X86_64
1709 vtop->type.t = VT_LLONG;
1710 #else
1711 vtop->type.t = VT_INT;
1712 #endif
1713 vswap();
1714 gen_op(TOK_PDIV);
1715 } else {
1716 /* exactly one pointer : must be '+' or '-'. */
1717 if (op != '-' && op != '+')
1718 tcc_error("cannot use pointers here");
1719 /* Put pointer as first operand */
1720 if (bt2 == VT_PTR) {
1721 vswap();
1722 swap(&t1, &t2);
1724 type1 = vtop[-1].type;
1725 type1.t &= ~VT_ARRAY;
1726 if (vtop[-1].type.t & VT_VLA)
1727 vla_runtime_pointed_size(&vtop[-1].type);
1728 else {
1729 u = pointed_size(&vtop[-1].type);
1730 if (u < 0)
1731 tcc_error("unknown array element size");
1732 #ifdef TCC_TARGET_X86_64
1733 vpushll(u);
1734 #else
1735 /* XXX: cast to int ? (long long case) */
1736 vpushi(u);
1737 #endif
1739 gen_op('*');
1740 #ifdef CONFIG_TCC_BCHECK
1741 /* if evaluating constant expression, no code should be
1742 generated, so no bound check */
1743 if (tcc_state->do_bounds_check && !const_wanted) {
1744 /* if bounded pointers, we generate a special code to
1745 test bounds */
1746 if (op == '-') {
1747 vpushi(0);
1748 vswap();
1749 gen_op('-');
1751 gen_bounded_ptr_add();
1752 } else
1753 #endif
1755 gen_opic(op);
1757 /* put again type if gen_opic() swaped operands */
1758 vtop->type = type1;
1760 } else if (is_float(bt1) || is_float(bt2)) {
1761 /* compute bigger type and do implicit casts */
1762 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1763 t = VT_LDOUBLE;
1764 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1765 t = VT_DOUBLE;
1766 } else {
1767 t = VT_FLOAT;
1769 /* floats can only be used for a few operations */
1770 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1771 (op < TOK_ULT || op > TOK_GT))
1772 tcc_error("invalid operands for binary operation");
1773 goto std_op;
1774 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1775 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1776 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1777 t |= VT_UNSIGNED;
1778 goto std_op;
1779 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1780 /* cast to biggest op */
1781 t = VT_LLONG;
1782 /* convert to unsigned if it does not fit in a long long */
1783 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1784 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1785 t |= VT_UNSIGNED;
1786 goto std_op;
1787 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1788 tcc_error("comparison of struct");
1789 } else {
1790 /* integer operations */
1791 t = VT_INT;
1792 /* convert to unsigned if it does not fit in an integer */
1793 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1794 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1795 t |= VT_UNSIGNED;
1796 std_op:
1797 /* XXX: currently, some unsigned operations are explicit, so
1798 we modify them here */
1799 if (t & VT_UNSIGNED) {
1800 if (op == TOK_SAR)
1801 op = TOK_SHR;
1802 else if (op == '/')
1803 op = TOK_UDIV;
1804 else if (op == '%')
1805 op = TOK_UMOD;
1806 else if (op == TOK_LT)
1807 op = TOK_ULT;
1808 else if (op == TOK_GT)
1809 op = TOK_UGT;
1810 else if (op == TOK_LE)
1811 op = TOK_ULE;
1812 else if (op == TOK_GE)
1813 op = TOK_UGE;
1815 vswap();
1816 type1.t = t;
1817 gen_cast(&type1);
1818 vswap();
1819 /* special case for shifts and long long: we keep the shift as
1820 an integer */
1821 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1822 type1.t = VT_INT;
1823 gen_cast(&type1);
1824 if (is_float(t))
1825 gen_opif(op);
1826 else
1827 gen_opic(op);
1828 if (op >= TOK_ULT && op <= TOK_GT) {
1829 /* relationnal op: the result is an int */
1830 vtop->type.t = VT_INT;
1831 } else {
1832 vtop->type.t = t;
1837 #ifndef TCC_TARGET_ARM
1838 /* generic itof for unsigned long long case */
1839 static void gen_cvt_itof1(int t)
1841 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1842 (VT_LLONG | VT_UNSIGNED)) {
1844 if (t == VT_FLOAT)
1845 vpush_global_sym(&func_old_type, TOK___floatundisf);
1846 #if LDOUBLE_SIZE != 8
1847 else if (t == VT_LDOUBLE)
1848 vpush_global_sym(&func_old_type, TOK___floatundixf);
1849 #endif
1850 else
1851 vpush_global_sym(&func_old_type, TOK___floatundidf);
1852 vrott(2);
1853 gfunc_call(1);
1854 vpushi(0);
1855 vtop->r = reg_fret(t);
1856 } else {
1857 gen_cvt_itof(t);
1860 #endif
1862 /* generic ftoi for unsigned long long case */
1863 static void gen_cvt_ftoi1(int t)
1865 int st;
1867 if (t == (VT_LLONG | VT_UNSIGNED)) {
1868 /* not handled natively */
1869 st = vtop->type.t & VT_BTYPE;
1870 if (st == VT_FLOAT)
1871 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1872 #if LDOUBLE_SIZE != 8
1873 else if (st == VT_LDOUBLE)
1874 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1875 #endif
1876 else
1877 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1878 vrott(2);
1879 gfunc_call(1);
1880 vpushi(0);
1881 vtop->r = REG_IRET;
1882 vtop->r2 = REG_LRET;
1883 } else {
1884 gen_cvt_ftoi(t);
1888 /* force char or short cast */
1889 static void force_charshort_cast(int t)
1891 int bits, dbt;
1892 dbt = t & VT_BTYPE;
1893 /* XXX: add optimization if lvalue : just change type and offset */
1894 if (dbt == VT_BYTE)
1895 bits = 8;
1896 else
1897 bits = 16;
1898 if (t & VT_UNSIGNED) {
1899 vpushi((1 << bits) - 1);
1900 gen_op('&');
1901 } else {
1902 bits = 32 - bits;
1903 vpushi(bits);
1904 gen_op(TOK_SHL);
1905 /* result must be signed or the SAR is converted to an SHL
1906 This was not the case when "t" was a signed short
1907 and the last value on the stack was an unsigned int */
1908 vtop->type.t &= ~VT_UNSIGNED;
1909 vpushi(bits);
1910 gen_op(TOK_SAR);
1914 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1915 static void gen_cast(CType *type)
1917 int sbt, dbt, sf, df, c, p;
1919 /* special delayed cast for char/short */
1920 /* XXX: in some cases (multiple cascaded casts), it may still
1921 be incorrect */
1922 if (vtop->r & VT_MUSTCAST) {
1923 vtop->r &= ~VT_MUSTCAST;
1924 force_charshort_cast(vtop->type.t);
1927 /* bitfields first get cast to ints */
1928 if (vtop->type.t & VT_BITFIELD) {
1929 gv(RC_INT);
1932 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1933 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1935 if (sbt != dbt) {
1936 sf = is_float(sbt);
1937 df = is_float(dbt);
1938 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1939 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1940 if (c) {
1941 /* constant case: we can do it now */
1942 /* XXX: in ISOC, cannot do it if error in convert */
1943 if (sbt == VT_FLOAT)
1944 vtop->c.ld = vtop->c.f;
1945 else if (sbt == VT_DOUBLE)
1946 vtop->c.ld = vtop->c.d;
1948 if (df) {
1949 if ((sbt & VT_BTYPE) == VT_LLONG) {
1950 if (sbt & VT_UNSIGNED)
1951 vtop->c.ld = vtop->c.ull;
1952 else
1953 vtop->c.ld = vtop->c.ll;
1954 } else if(!sf) {
1955 if (sbt & VT_UNSIGNED)
1956 vtop->c.ld = vtop->c.ui;
1957 else
1958 vtop->c.ld = vtop->c.i;
1961 if (dbt == VT_FLOAT)
1962 vtop->c.f = (float)vtop->c.ld;
1963 else if (dbt == VT_DOUBLE)
1964 vtop->c.d = (double)vtop->c.ld;
1965 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1966 vtop->c.ull = (unsigned long long)vtop->c.ld;
1967 } else if (sf && dbt == VT_BOOL) {
1968 vtop->c.i = (vtop->c.ld != 0);
1969 } else {
1970 if(sf)
1971 vtop->c.ll = (long long)vtop->c.ld;
1972 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1973 vtop->c.ll = vtop->c.ull;
1974 else if (sbt & VT_UNSIGNED)
1975 vtop->c.ll = vtop->c.ui;
1976 #ifdef TCC_TARGET_X86_64
1977 else if (sbt == VT_PTR)
1979 #endif
1980 else if (sbt != VT_LLONG)
1981 vtop->c.ll = vtop->c.i;
1983 if (dbt == (VT_LLONG|VT_UNSIGNED))
1984 vtop->c.ull = vtop->c.ll;
1985 else if (dbt == VT_BOOL)
1986 vtop->c.i = (vtop->c.ll != 0);
1987 #ifdef TCC_TARGET_X86_64
1988 else if (dbt == VT_PTR)
1990 #endif
1991 else if (dbt != VT_LLONG) {
1992 int s, dt, warr = 0;
1993 long long ll;
1994 dt = dbt & VT_BTYPE;
1995 ll = vtop->c.ll;
1996 if (dt == VT_BYTE){
1997 if((ll != (unsigned char)ll) && (ll != (char)ll))
1998 warr = 1;
1999 s = 24;
2000 }else if (dt == VT_SHORT){
2001 if((ll != (unsigned short)ll) && (ll != (short)ll))
2002 warr = 1;
2003 s = 16;
2004 }else{
2005 if((ll != (unsigned int)ll) && (ll != (int)ll))
2006 warr = 1;
2007 s = 0;
2009 if(warr && !is_force){
2010 if(dt == VT_ENUM){
2011 tcc_warning("large integer implicitly truncated to unsigned type");
2012 dbt = VT_UNSIGNED;
2013 }else
2014 tcc_warning("overflow in implicit constant conversion");
2016 if(dbt & VT_UNSIGNED)
2017 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
2018 else
2019 vtop->c.i = ((int)vtop->c.ll << s) >> s;
2022 } else if (p && dbt == VT_BOOL) {
2023 vtop->r = VT_CONST;
2024 vtop->c.i = 1;
2025 } else if (!nocode_wanted) {
2026 /* non constant case: generate code */
2027 if (sf && df) {
2028 /* convert from fp to fp */
2029 gen_cvt_ftof(dbt);
2030 } else if (df) {
2031 /* convert int to fp */
2032 gen_cvt_itof1(dbt);
2033 } else if (sf) {
2034 /* convert fp to int */
2035 if (dbt == VT_BOOL) {
2036 vpushi(0);
2037 gen_op(TOK_NE);
2038 } else {
2039 /* we handle char/short/etc... with generic code */
2040 if (dbt != (VT_INT | VT_UNSIGNED) &&
2041 dbt != (VT_LLONG | VT_UNSIGNED) &&
2042 dbt != VT_LLONG)
2043 dbt = VT_INT;
2044 gen_cvt_ftoi1(dbt);
2045 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2046 /* additional cast for char/short... */
2047 vtop->type.t = dbt;
2048 gen_cast(type);
2051 #ifndef TCC_TARGET_X86_64
2052 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2053 if ((sbt & VT_BTYPE) != VT_LLONG) {
2054 /* scalar to long long */
2055 /* machine independent conversion */
2056 gv(RC_INT);
2057 /* generate high word */
2058 if (sbt == (VT_INT | VT_UNSIGNED)) {
2059 vpushi(0);
2060 gv(RC_INT);
2061 } else {
2062 if (sbt == VT_PTR) {
2063 /* cast from pointer to int before we apply
2064 shift operation, which pointers don't support*/
2065 gen_cast(&int_type);
2067 gv_dup();
2068 vpushi(31);
2069 gen_op(TOK_SAR);
2071 /* patch second register */
2072 vtop[-1].r2 = vtop->r;
2073 vpop();
2075 #else
2076 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2077 (dbt & VT_BTYPE) == VT_PTR ||
2078 (dbt & VT_BTYPE) == VT_FUNC) {
2079 if ((sbt & VT_BTYPE) != VT_LLONG &&
2080 (sbt & VT_BTYPE) != VT_PTR &&
2081 (sbt & VT_BTYPE) != VT_FUNC) {
2082 /* need to convert from 32bit to 64bit */
2083 int r = gv(RC_INT);
2084 if (sbt != (VT_INT | VT_UNSIGNED)) {
2085 /* x86_64 specific: movslq */
2086 o(0x6348);
2087 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2090 #endif
2091 } else if (dbt == VT_BOOL) {
2092 /* scalar to bool */
2093 vpushi(0);
2094 gen_op(TOK_NE);
2095 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2096 (dbt & VT_BTYPE) == VT_SHORT) {
2097 if (sbt == VT_PTR) {
2098 vtop->type.t = VT_INT;
2099 tcc_warning("nonportable conversion from pointer to char/short");
2101 force_charshort_cast(dbt);
2102 } else if ((dbt & VT_BTYPE) == VT_INT) {
2103 /* scalar to int */
2104 if (sbt == VT_LLONG) {
2105 /* from long long: just take low order word */
2106 lexpand();
2107 vpop();
2109 /* if lvalue and single word type, nothing to do because
2110 the lvalue already contains the real type size (see
2111 VT_LVAL_xxx constants) */
2114 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2115 /* if we are casting between pointer types,
2116 we must update the VT_LVAL_xxx size */
2117 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2118 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2120 vtop->type = *type;
2123 /* return type size as known at compile time. Put alignment at 'a' */
2124 ST_FUNC int type_size(CType *type, int *a)
2126 Sym *s;
2127 int bt;
2129 bt = type->t & VT_BTYPE;
2130 if (bt == VT_STRUCT) {
2131 /* struct/union */
2132 s = type->ref;
2133 *a = s->r;
2134 return s->c;
2135 } else if (bt == VT_PTR) {
2136 if (type->t & VT_ARRAY) {
2137 int ts;
2139 s = type->ref;
2140 ts = type_size(&s->type, a);
2142 if (ts < 0 && s->c < 0)
2143 ts = -ts;
2145 return ts * s->c;
2146 } else {
2147 *a = PTR_SIZE;
2148 return PTR_SIZE;
2150 } else if (bt == VT_LDOUBLE) {
2151 *a = LDOUBLE_ALIGN;
2152 return LDOUBLE_SIZE;
2153 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2154 #ifdef TCC_TARGET_I386
2155 #ifdef TCC_TARGET_PE
2156 *a = 8;
2157 #else
2158 *a = 4;
2159 #endif
2160 #elif defined(TCC_TARGET_ARM)
2161 #ifdef TCC_ARM_EABI
2162 *a = 8;
2163 #else
2164 *a = 4;
2165 #endif
2166 #else
2167 *a = 8;
2168 #endif
2169 return 8;
2170 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2171 *a = 4;
2172 return 4;
2173 } else if (bt == VT_SHORT) {
2174 *a = 2;
2175 return 2;
2176 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2177 *a = 8;
2178 return 16;
2179 } else {
2180 /* char, void, function, _Bool */
2181 *a = 1;
2182 return 1;
2186 /* push type size as known at runtime time on top of value stack. Put
2187 alignment at 'a' */
2188 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2190 if (type->t & VT_VLA) {
2191 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2192 } else {
2193 vpushi(type_size(type, a));
2197 static void vla_sp_save(void) {
2198 if (!(vla_flags & VLA_SP_LOC_SET)) {
2199 *vla_sp_loc = (loc -= PTR_SIZE);
2200 vla_flags |= VLA_SP_LOC_SET;
2202 if (!(vla_flags & VLA_SP_SAVED)) {
2203 gen_vla_sp_save(*vla_sp_loc);
2204 vla_flags |= VLA_SP_SAVED;
2208 /* return the pointed type of t */
2209 static inline CType *pointed_type(CType *type)
2211 return &type->ref->type;
2214 /* modify type so that its it is a pointer to type. */
2215 ST_FUNC void mk_pointer(CType *type)
2217 Sym *s;
2218 s = sym_push(SYM_FIELD, type, 0, -1);
2219 type->t = VT_PTR | (type->t & ~VT_TYPE);
2220 type->ref = s;
2223 /* compare function types. OLD functions match any new functions */
2224 static int is_compatible_func(CType *type1, CType *type2)
2226 Sym *s1, *s2;
2228 s1 = type1->ref;
2229 s2 = type2->ref;
2230 if (!is_compatible_types(&s1->type, &s2->type))
2231 return 0;
2232 /* check func_call */
2233 if (s1->a.func_call != s2->a.func_call)
2234 return 0;
2235 /* XXX: not complete */
2236 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2237 return 1;
2238 if (s1->c != s2->c)
2239 return 0;
2240 while (s1 != NULL) {
2241 if (s2 == NULL)
2242 return 0;
2243 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2244 return 0;
2245 s1 = s1->next;
2246 s2 = s2->next;
2248 if (s2)
2249 return 0;
2250 return 1;
2253 /* return true if type1 and type2 are the same. If unqualified is
2254 true, qualifiers on the types are ignored.
2256 - enums are not checked as gcc __builtin_types_compatible_p ()
2258 static int compare_types(CType *type1, CType *type2, int unqualified)
2260 int bt1, t1, t2;
2262 t1 = type1->t & VT_TYPE;
2263 t2 = type2->t & VT_TYPE;
2264 if (unqualified) {
2265 /* strip qualifiers before comparing */
2266 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2267 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2269 /* Default Vs explicit signedness only matters for char */
2270 if ((t1 & VT_BTYPE) != VT_BYTE) {
2271 t1 &= ~VT_DEFSIGN;
2272 t2 &= ~VT_DEFSIGN;
2274 /* XXX: bitfields ? */
2275 if (t1 != t2)
2276 return 0;
2277 /* test more complicated cases */
2278 bt1 = t1 & VT_BTYPE;
2279 if (bt1 == VT_PTR) {
2280 type1 = pointed_type(type1);
2281 type2 = pointed_type(type2);
2282 return is_compatible_types(type1, type2);
2283 } else if (bt1 == VT_STRUCT) {
2284 return (type1->ref == type2->ref);
2285 } else if (bt1 == VT_FUNC) {
2286 return is_compatible_func(type1, type2);
2287 } else {
2288 return 1;
2292 /* return true if type1 and type2 are exactly the same (including
2293 qualifiers).
2295 static int is_compatible_types(CType *type1, CType *type2)
2297 return compare_types(type1,type2,0);
2300 /* return true if type1 and type2 are the same (ignoring qualifiers).
2302 static int is_compatible_parameter_types(CType *type1, CType *type2)
2304 return compare_types(type1,type2,1);
2307 /* print a type. If 'varstr' is not NULL, then the variable is also
2308 printed in the type */
2309 /* XXX: union */
2310 /* XXX: add array and function pointers */
2311 static void type_to_str(char *buf, int buf_size,
2312 CType *type, const char *varstr)
2314 int bt, v, t;
2315 Sym *s, *sa;
2316 char buf1[256];
2317 const char *tstr;
2319 t = type->t & VT_TYPE;
2320 bt = t & VT_BTYPE;
2321 buf[0] = '\0';
2322 if (t & VT_CONSTANT)
2323 pstrcat(buf, buf_size, "const ");
2324 if (t & VT_VOLATILE)
2325 pstrcat(buf, buf_size, "volatile ");
2326 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2327 pstrcat(buf, buf_size, "unsigned ");
2328 else if (t & VT_DEFSIGN)
2329 pstrcat(buf, buf_size, "signed ");
2330 switch(bt) {
2331 case VT_VOID:
2332 tstr = "void";
2333 goto add_tstr;
2334 case VT_BOOL:
2335 tstr = "_Bool";
2336 goto add_tstr;
2337 case VT_BYTE:
2338 tstr = "char";
2339 goto add_tstr;
2340 case VT_SHORT:
2341 tstr = "short";
2342 goto add_tstr;
2343 case VT_INT:
2344 tstr = "int";
2345 goto add_tstr;
2346 case VT_LONG:
2347 tstr = "long";
2348 goto add_tstr;
2349 case VT_LLONG:
2350 tstr = "long long";
2351 goto add_tstr;
2352 case VT_FLOAT:
2353 tstr = "float";
2354 goto add_tstr;
2355 case VT_DOUBLE:
2356 tstr = "double";
2357 goto add_tstr;
2358 case VT_LDOUBLE:
2359 tstr = "long double";
2360 add_tstr:
2361 pstrcat(buf, buf_size, tstr);
2362 break;
2363 case VT_ENUM:
2364 case VT_STRUCT:
2365 if (bt == VT_STRUCT)
2366 tstr = "struct ";
2367 else
2368 tstr = "enum ";
2369 pstrcat(buf, buf_size, tstr);
2370 v = type->ref->v & ~SYM_STRUCT;
2371 if (v >= SYM_FIRST_ANOM)
2372 pstrcat(buf, buf_size, "<anonymous>");
2373 else
2374 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2375 break;
2376 case VT_FUNC:
2377 s = type->ref;
2378 type_to_str(buf, buf_size, &s->type, varstr);
2379 pstrcat(buf, buf_size, "(");
2380 sa = s->next;
2381 while (sa != NULL) {
2382 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2383 pstrcat(buf, buf_size, buf1);
2384 sa = sa->next;
2385 if (sa)
2386 pstrcat(buf, buf_size, ", ");
2388 pstrcat(buf, buf_size, ")");
2389 goto no_var;
2390 case VT_PTR:
2391 s = type->ref;
2392 pstrcpy(buf1, sizeof(buf1), "*");
2393 if (varstr)
2394 pstrcat(buf1, sizeof(buf1), varstr);
2395 type_to_str(buf, buf_size, &s->type, buf1);
2396 goto no_var;
2398 if (varstr) {
2399 pstrcat(buf, buf_size, " ");
2400 pstrcat(buf, buf_size, varstr);
2402 no_var: ;
2405 /* verify type compatibility to store vtop in 'dt' type, and generate
2406 casts if needed. */
2407 static void gen_assign_cast(CType *dt)
2409 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2410 char buf1[256], buf2[256];
2411 int dbt, sbt;
2413 st = &vtop->type; /* source type */
2414 dbt = dt->t & VT_BTYPE;
2415 sbt = st->t & VT_BTYPE;
2416 if (sbt == VT_VOID || dbt == VT_VOID)
2417 tcc_error("cannot cast from/to void");
2418 if (dt->t & VT_CONSTANT)
2419 tcc_warning("assignment of read-only location");
2420 switch(dbt) {
2421 case VT_PTR:
2422 /* special cases for pointers */
2423 /* '0' can also be a pointer */
2424 if (is_null_pointer(vtop))
2425 goto type_ok;
2426 /* accept implicit pointer to integer cast with warning */
2427 if (is_integer_btype(sbt)) {
2428 tcc_warning("assignment makes pointer from integer without a cast");
2429 goto type_ok;
2431 type1 = pointed_type(dt);
2432 /* a function is implicitely a function pointer */
2433 if (sbt == VT_FUNC) {
2434 if ((type1->t & VT_BTYPE) != VT_VOID &&
2435 !is_compatible_types(pointed_type(dt), st))
2436 tcc_warning("assignment from incompatible pointer type");
2437 goto type_ok;
2439 if (sbt != VT_PTR)
2440 goto error;
2441 type2 = pointed_type(st);
2442 if ((type1->t & VT_BTYPE) == VT_VOID ||
2443 (type2->t & VT_BTYPE) == VT_VOID) {
2444 /* void * can match anything */
2445 } else {
2446 /* exact type match, except for unsigned */
2447 tmp_type1 = *type1;
2448 tmp_type2 = *type2;
2449 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2450 VT_VOLATILE);
2451 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2452 VT_VOLATILE);
2453 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2454 tcc_warning("assignment from incompatible pointer type");
2456 /* check const and volatile */
2457 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2458 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2459 tcc_warning("assignment discards qualifiers from pointer target type");
2460 break;
2461 case VT_BYTE:
2462 case VT_SHORT:
2463 case VT_INT:
2464 case VT_LLONG:
2465 if (sbt == VT_PTR || sbt == VT_FUNC) {
2466 tcc_warning("assignment makes integer from pointer without a cast");
2468 if (sbt == VT_STRUCT)
2469 goto error;
2470 /* XXX: more tests */
2471 break;
2472 case VT_STRUCT:
2473 tmp_type1 = *dt;
2474 tmp_type2 = *st;
2475 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2476 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2477 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2478 error:
2479 type_to_str(buf1, sizeof(buf1), st, NULL);
2480 type_to_str(buf2, sizeof(buf2), dt, NULL);
2481 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2483 break;
2485 type_ok:
2486 gen_cast(dt);
2489 /* store vtop in lvalue pushed on stack */
2490 ST_FUNC void vstore(void)
2492 int sbt, dbt, ft, cc, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2494 ft = vtop[-1].type.t;
2495 sbt = vtop->type.t & VT_BTYPE;
2496 dbt = ft & VT_BTYPE;
2497 cc = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2498 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2499 (sbt == VT_INT && dbt == VT_SHORT))
2500 && !(vtop->type.t & VT_BITFIELD) && !cc) {
2501 /* optimize char/short casts */
2502 delayed_cast = VT_MUSTCAST;
2503 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2504 /* XXX: factorize */
2505 if (ft & VT_CONSTANT)
2506 tcc_warning("assignment of read-only location");
2507 } else {
2508 delayed_cast = 0;
2509 if (!(ft & VT_BITFIELD))
2510 gen_assign_cast(&vtop[-1].type);
2513 if (sbt == VT_STRUCT) {
2514 /* if structure, only generate pointer */
2515 /* structure assignment : generate memcpy */
2516 /* XXX: optimize if small size */
2517 if (!nocode_wanted) {
2518 size = type_size(&vtop->type, &align);
2520 /* destination */
2521 vswap();
2522 vtop->type.t = VT_PTR;
2523 gaddrof();
2525 /* address of memcpy() */
2526 #ifdef TCC_ARM_EABI
2527 if(!(align & 7))
2528 vpush_global_sym(&func_old_type, TOK_memcpy8);
2529 else if(!(align & 3))
2530 vpush_global_sym(&func_old_type, TOK_memcpy4);
2531 else
2532 #endif
2533 vpush_global_sym(&func_old_type, TOK_memcpy);
2535 vswap();
2536 /* source */
2537 vpushv(vtop - 2);
2538 vtop->type.t = VT_PTR;
2539 gaddrof();
2540 /* type size */
2541 vpushi(size);
2542 gfunc_call(3);
2543 } else {
2544 vswap();
2545 vpop();
2547 /* leave source on stack */
2548 } else if (ft & VT_BITFIELD) {
2549 /* bitfield store handling */
2550 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2551 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2552 /* remove bit field info to avoid loops */
2553 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2555 if((ft & VT_BTYPE) == VT_BOOL) {
2556 gen_cast(&vtop[-1].type);
2557 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2560 /* duplicate destination */
2561 vdup();
2562 vtop[-1] = vtop[-2];
2564 /* mask and shift source */
2565 if((ft & VT_BTYPE) != VT_BOOL) {
2566 if((ft & VT_BTYPE) == VT_LLONG) {
2567 vpushll((1ULL << bit_size) - 1ULL);
2568 } else {
2569 vpushi((1 << bit_size) - 1);
2571 gen_op('&');
2573 vpushi(bit_pos);
2574 gen_op(TOK_SHL);
2575 /* load destination, mask and or with source */
2576 vswap();
2577 if((ft & VT_BTYPE) == VT_LLONG) {
2578 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2579 } else {
2580 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2582 gen_op('&');
2583 gen_op('|');
2584 /* store result */
2585 vstore();
2586 } else {
2587 #ifdef CONFIG_TCC_BCHECK
2588 /* bound check case */
2589 if (vtop[-1].r & VT_MUSTBOUND) {
2590 vswap();
2591 gbound();
2592 vswap();
2594 #endif
2595 if (!nocode_wanted) {
2596 rc = RC_INT;
2597 if (is_float(ft)) {
2598 rc = RC_FLOAT;
2599 #ifdef TCC_TARGET_X86_64
2600 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2601 rc = RC_ST0;
2602 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2603 rc = RC_FRET;
2605 #endif
2607 r = gv(rc); /* generate value */
2608 /* if lvalue was saved on stack, must read it */
2609 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2610 SValue sv;
2611 t = get_reg(RC_INT);
2612 #ifdef TCC_TARGET_X86_64
2613 sv.type.t = VT_PTR;
2614 #else
2615 sv.type.t = VT_INT;
2616 #endif
2617 sv.r = VT_LOCAL | VT_LVAL;
2618 sv.c.ul = vtop[-1].c.ul;
2619 load(t, &sv);
2620 vtop[-1].r = t | VT_LVAL;
2622 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2623 #ifdef TCC_TARGET_X86_64
2624 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2625 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2626 #else
2627 if ((ft & VT_BTYPE) == VT_LLONG) {
2628 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2629 #endif
2630 vtop[-1].type.t = load_type;
2631 store(r, vtop - 1);
2632 vswap();
2633 /* convert to int to increment easily */
2634 vtop->type.t = addr_type;
2635 gaddrof();
2636 vpushi(load_size);
2637 gen_op('+');
2638 vtop->r |= VT_LVAL;
2639 vswap();
2640 vtop[-1].type.t = load_type;
2641 /* XXX: it works because r2 is spilled last ! */
2642 store(vtop->r2, vtop - 1);
2643 } else {
2644 store(r, vtop - 1);
2647 vswap();
2648 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2649 vtop->r |= delayed_cast;
2653 /* post defines POST/PRE add. c is the token ++ or -- */
2654 ST_FUNC void inc(int post, int c)
2656 test_lvalue();
2657 vdup(); /* save lvalue */
2658 if (post) {
2659 gv_dup(); /* duplicate value */
2660 vrotb(3);
2661 vrotb(3);
2663 /* add constant */
2664 vpushi(c - TOK_MID);
2665 gen_op('+');
2666 vstore(); /* store value */
2667 if (post)
2668 vpop(); /* if post op, return saved value */
2671 /* Parse GNUC __attribute__ extension. Currently, the following
2672 extensions are recognized:
2673 - aligned(n) : set data/function alignment.
2674 - packed : force data alignment to 1
2675 - section(x) : generate data/code in this section.
2676 - unused : currently ignored, but may be used someday.
2677 - regparm(n) : pass function parameters in registers (i386 only)
2679 static void parse_attribute(AttributeDef *ad)
2681 int t, n;
2683 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2684 next();
2685 skip('(');
2686 skip('(');
2687 while (tok != ')') {
2688 if (tok < TOK_IDENT)
2689 expect("attribute name");
2690 t = tok;
2691 next();
2692 switch(t) {
2693 case TOK_SECTION1:
2694 case TOK_SECTION2:
2695 skip('(');
2696 if (tok != TOK_STR)
2697 expect("section name");
2698 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2699 next();
2700 skip(')');
2701 break;
2702 case TOK_ALIAS1:
2703 case TOK_ALIAS2:
2704 skip('(');
2705 if (tok != TOK_STR)
2706 expect("alias(\"target\")");
2707 ad->alias_target = /* save string as token, for later */
2708 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2709 next();
2710 skip(')');
2711 break;
2712 case TOK_VISIBILITY1:
2713 case TOK_VISIBILITY2:
2714 skip('(');
2715 if (tok != TOK_STR)
2716 expect("visibility(\"default|hidden|internal|protected\")");
2717 if (!strcmp (tokc.cstr->data, "default"))
2718 ad->a.visibility = STV_DEFAULT;
2719 else if (!strcmp (tokc.cstr->data, "hidden"))
2720 ad->a.visibility = STV_HIDDEN;
2721 else if (!strcmp (tokc.cstr->data, "internal"))
2722 ad->a.visibility = STV_INTERNAL;
2723 else if (!strcmp (tokc.cstr->data, "protected"))
2724 ad->a.visibility = STV_PROTECTED;
2725 else
2726 expect("visibility(\"default|hidden|internal|protected\")");
2727 next();
2728 skip(')');
2729 break;
2730 case TOK_ALIGNED1:
2731 case TOK_ALIGNED2:
2732 if (tok == '(') {
2733 next();
2734 n = expr_const();
2735 if (n <= 0 || (n & (n - 1)) != 0)
2736 tcc_error("alignment must be a positive power of two");
2737 skip(')');
2738 } else {
2739 n = MAX_ALIGN;
2741 ad->a.aligned = n;
2742 break;
2743 case TOK_PACKED1:
2744 case TOK_PACKED2:
2745 ad->a.packed = 1;
2746 break;
2747 case TOK_WEAK1:
2748 case TOK_WEAK2:
2749 ad->a.weak = 1;
2750 break;
2751 case TOK_UNUSED1:
2752 case TOK_UNUSED2:
2753 /* currently, no need to handle it because tcc does not
2754 track unused objects */
2755 break;
2756 case TOK_NORETURN1:
2757 case TOK_NORETURN2:
2758 /* currently, no need to handle it because tcc does not
2759 track unused objects */
2760 break;
2761 case TOK_CDECL1:
2762 case TOK_CDECL2:
2763 case TOK_CDECL3:
2764 ad->a.func_call = FUNC_CDECL;
2765 break;
2766 case TOK_STDCALL1:
2767 case TOK_STDCALL2:
2768 case TOK_STDCALL3:
2769 ad->a.func_call = FUNC_STDCALL;
2770 break;
2771 #ifdef TCC_TARGET_I386
2772 case TOK_REGPARM1:
2773 case TOK_REGPARM2:
2774 skip('(');
2775 n = expr_const();
2776 if (n > 3)
2777 n = 3;
2778 else if (n < 0)
2779 n = 0;
2780 if (n > 0)
2781 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
2782 skip(')');
2783 break;
2784 case TOK_FASTCALL1:
2785 case TOK_FASTCALL2:
2786 case TOK_FASTCALL3:
2787 ad->a.func_call = FUNC_FASTCALLW;
2788 break;
2789 #endif
2790 case TOK_MODE:
2791 skip('(');
2792 switch(tok) {
2793 case TOK_MODE_DI:
2794 ad->a.mode = VT_LLONG + 1;
2795 break;
2796 case TOK_MODE_HI:
2797 ad->a.mode = VT_SHORT + 1;
2798 break;
2799 case TOK_MODE_SI:
2800 ad->a.mode = VT_INT + 1;
2801 break;
2802 default:
2803 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2804 break;
2806 next();
2807 skip(')');
2808 break;
2809 case TOK_DLLEXPORT:
2810 ad->a.func_export = 1;
2811 break;
2812 case TOK_DLLIMPORT:
2813 ad->a.func_import = 1;
2814 break;
2815 default:
2816 if (tcc_state->warn_unsupported)
2817 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2818 /* skip parameters */
2819 if (tok == '(') {
2820 int parenthesis = 0;
2821 do {
2822 if (tok == '(')
2823 parenthesis++;
2824 else if (tok == ')')
2825 parenthesis--;
2826 next();
2827 } while (parenthesis && tok != -1);
2829 break;
2831 if (tok != ',')
2832 break;
2833 next();
2835 skip(')');
2836 skip(')');
2840 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2841 static void struct_decl(CType *type, int u, int tdef)
2843 int a, v, size, align, maxalign, c, offset, flexible;
2844 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2845 Sym *s, *ss, *ass, **ps;
2846 AttributeDef ad;
2847 CType type1, btype;
2849 a = tok; /* save decl type */
2850 next();
2851 if (tok != '{') {
2852 v = tok;
2853 next();
2854 /* struct already defined ? return it */
2855 if (v < TOK_IDENT)
2856 expect("struct/union/enum name");
2857 s = struct_find(v);
2858 if (s) {
2859 if (s->type.t != a)
2860 tcc_error("invalid type: '%s'", get_tok_str(v, NULL));
2861 goto do_decl;
2862 } else if (tok >= TOK_IDENT && !tdef)
2863 tcc_error("unknown struct/union/enum");
2864 } else {
2865 v = anon_sym++;
2867 type1.t = a;
2868 type1.ref = NULL;
2869 /* we put an undefined size for struct/union */
2870 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2871 s->r = 0; /* default alignment is zero as gcc */
2872 /* put struct/union/enum name in type */
2873 do_decl:
2874 type->t = u;
2875 type->ref = s;
2877 if (tok == '{') {
2878 next();
2879 if (s->c != -1)
2880 tcc_error("struct/union/enum already defined");
2881 /* cannot be empty */
2882 c = 0;
2883 /* non empty enums are not allowed */
2884 if (a == TOK_ENUM) {
2885 for(;;) {
2886 v = tok;
2887 if (v < TOK_UIDENT)
2888 expect("identifier");
2889 ss = sym_find(v);
2890 if (ss && !local_stack)
2891 tcc_error("redefinition of enumerator '%s'",
2892 get_tok_str(v, NULL));
2893 next();
2894 if (tok == '=') {
2895 next();
2896 c = expr_const();
2898 /* enum symbols have static storage */
2899 ss = sym_push(v, &int_type, VT_CONST, c);
2900 ss->type.t |= VT_STATIC;
2901 if (tok != ',')
2902 break;
2903 next();
2904 c++;
2905 /* NOTE: we accept a trailing comma */
2906 if (tok == '}')
2907 break;
2909 s->c = type_size(&int_type, &align);
2910 skip('}');
2911 } else {
2912 maxalign = 1;
2913 ps = &s->next;
2914 prevbt = VT_INT;
2915 bit_pos = 0;
2916 offset = 0;
2917 flexible = 0;
2918 while (tok != '}') {
2919 parse_btype(&btype, &ad);
2920 while (1) {
2921 if (flexible)
2922 tcc_error("flexible array member '%s' not at the end of struct",
2923 get_tok_str(v, NULL));
2924 bit_size = -1;
2925 v = 0;
2926 type1 = btype;
2927 if (tok != ':') {
2928 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2929 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2930 expect("identifier");
2931 if (type_size(&type1, &align) < 0) {
2932 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY))
2933 flexible = 1;
2934 else
2935 tcc_error("field '%s' has incomplete type",
2936 get_tok_str(v, NULL));
2938 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2939 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2940 tcc_error("invalid type for '%s'",
2941 get_tok_str(v, NULL));
2943 if (tok == ':') {
2944 next();
2945 bit_size = expr_const();
2946 /* XXX: handle v = 0 case for messages */
2947 if (bit_size < 0)
2948 tcc_error("negative width in bit-field '%s'",
2949 get_tok_str(v, NULL));
2950 if (v && bit_size == 0)
2951 tcc_error("zero width for bit-field '%s'",
2952 get_tok_str(v, NULL));
2954 size = type_size(&type1, &align);
2955 if (ad.a.aligned) {
2956 if (align < ad.a.aligned)
2957 align = ad.a.aligned;
2958 } else if (ad.a.packed) {
2959 align = 1;
2960 } else if (*tcc_state->pack_stack_ptr) {
2961 if (align > *tcc_state->pack_stack_ptr)
2962 align = *tcc_state->pack_stack_ptr;
2964 lbit_pos = 0;
2965 if (bit_size >= 0) {
2966 bt = type1.t & VT_BTYPE;
2967 if (bt != VT_INT &&
2968 bt != VT_BYTE &&
2969 bt != VT_SHORT &&
2970 bt != VT_BOOL &&
2971 bt != VT_ENUM &&
2972 bt != VT_LLONG)
2973 tcc_error("bitfields must have scalar type");
2974 bsize = size * 8;
2975 if (bit_size > bsize) {
2976 tcc_error("width of '%s' exceeds its type",
2977 get_tok_str(v, NULL));
2978 } else if (bit_size == bsize) {
2979 /* no need for bit fields */
2980 bit_pos = 0;
2981 } else if (bit_size == 0) {
2982 /* XXX: what to do if only padding in a
2983 structure ? */
2984 /* zero size: means to pad */
2985 bit_pos = 0;
2986 } else {
2987 /* we do not have enough room ?
2988 did the type change?
2989 is it a union? */
2990 if ((bit_pos + bit_size) > bsize ||
2991 bt != prevbt || a == TOK_UNION)
2992 bit_pos = 0;
2993 lbit_pos = bit_pos;
2994 /* XXX: handle LSB first */
2995 type1.t |= VT_BITFIELD |
2996 (bit_pos << VT_STRUCT_SHIFT) |
2997 (bit_size << (VT_STRUCT_SHIFT + 6));
2998 bit_pos += bit_size;
3000 prevbt = bt;
3001 } else {
3002 bit_pos = 0;
3004 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3005 /* add new memory data only if starting
3006 bit field */
3007 if (lbit_pos == 0) {
3008 if (a == TOK_STRUCT) {
3009 c = (c + align - 1) & -align;
3010 offset = c;
3011 if (size > 0)
3012 c += size;
3013 } else {
3014 offset = 0;
3015 if (size > c)
3016 c = size;
3018 if (align > maxalign)
3019 maxalign = align;
3021 #if 0
3022 printf("add field %s offset=%d",
3023 get_tok_str(v, NULL), offset);
3024 if (type1.t & VT_BITFIELD) {
3025 printf(" pos=%d size=%d",
3026 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3027 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3029 printf("\n");
3030 #endif
3032 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3033 ass = type1.ref;
3034 while ((ass = ass->next) != NULL) {
3035 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3036 *ps = ss;
3037 ps = &ss->next;
3039 } else if (v) {
3040 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3041 *ps = ss;
3042 ps = &ss->next;
3044 if (tok == ';' || tok == TOK_EOF)
3045 break;
3046 skip(',');
3048 skip(';');
3050 skip('}');
3051 if (!c && flexible)
3052 tcc_error("flexible array member '%s' in otherwise empty struct", get_tok_str(v, NULL));
3053 /* store size and alignment */
3054 s->c = (c + maxalign - 1) & -maxalign;
3055 s->r = maxalign;
3060 /* return 1 if basic type is a type size (short, long, long long) */
3061 ST_FUNC int is_btype_size(int bt)
3063 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3066 /* return 0 if no type declaration. otherwise, return the basic type
3067 and skip it.
3069 static int parse_btype(CType *type, AttributeDef *ad)
3071 int t, u, bt_size, complete, type_found, typespec_found;
3072 Sym *s;
3073 CType type1;
3075 memset(ad, 0, sizeof(AttributeDef));
3076 complete = 0;
3077 type_found = 0;
3078 typespec_found = 0;
3079 t = 0;
3080 while(1) {
3081 switch(tok) {
3082 case TOK_EXTENSION:
3083 /* currently, we really ignore extension */
3084 next();
3085 continue;
3087 /* basic types */
3088 case TOK_CHAR:
3089 u = VT_BYTE;
3090 basic_type:
3091 next();
3092 basic_type1:
3093 if (complete)
3094 tcc_error("too many basic types");
3095 t |= u;
3096 bt_size = is_btype_size (u & VT_BTYPE);
3097 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3098 complete = 1;
3099 typespec_found = 1;
3100 break;
3101 case TOK_VOID:
3102 u = VT_VOID;
3103 goto basic_type;
3104 case TOK_SHORT:
3105 u = VT_SHORT;
3106 goto basic_type;
3107 case TOK_INT:
3108 u = VT_INT;
3109 goto basic_type;
3110 case TOK_LONG:
3111 next();
3112 if ((t & VT_BTYPE) == VT_DOUBLE) {
3113 #ifndef TCC_TARGET_PE
3114 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3115 #endif
3116 } else if ((t & VT_BTYPE) == VT_LONG) {
3117 t = (t & ~VT_BTYPE) | VT_LLONG;
3118 } else {
3119 u = VT_LONG;
3120 goto basic_type1;
3122 break;
3123 case TOK_BOOL:
3124 u = VT_BOOL;
3125 goto basic_type;
3126 case TOK_FLOAT:
3127 u = VT_FLOAT;
3128 goto basic_type;
3129 case TOK_DOUBLE:
3130 next();
3131 if ((t & VT_BTYPE) == VT_LONG) {
3132 #ifdef TCC_TARGET_PE
3133 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3134 #else
3135 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3136 #endif
3137 } else {
3138 u = VT_DOUBLE;
3139 goto basic_type1;
3141 break;
3142 case TOK_ENUM:
3143 struct_decl(&type1, VT_ENUM, t & VT_TYPEDEF);
3144 basic_type2:
3145 u = type1.t;
3146 type->ref = type1.ref;
3147 goto basic_type1;
3148 case TOK_STRUCT:
3149 case TOK_UNION:
3150 struct_decl(&type1, VT_STRUCT, t & VT_TYPEDEF);
3151 goto basic_type2;
3153 /* type modifiers */
3154 case TOK_CONST1:
3155 case TOK_CONST2:
3156 case TOK_CONST3:
3157 t |= VT_CONSTANT;
3158 next();
3159 break;
3160 case TOK_VOLATILE1:
3161 case TOK_VOLATILE2:
3162 case TOK_VOLATILE3:
3163 t |= VT_VOLATILE;
3164 next();
3165 break;
3166 case TOK_SIGNED1:
3167 case TOK_SIGNED2:
3168 case TOK_SIGNED3:
3169 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3170 tcc_error("signed and unsigned modifier");
3171 typespec_found = 1;
3172 t |= VT_DEFSIGN;
3173 next();
3174 break;
3175 case TOK_REGISTER:
3176 case TOK_AUTO:
3177 case TOK_RESTRICT1:
3178 case TOK_RESTRICT2:
3179 case TOK_RESTRICT3:
3180 next();
3181 break;
3182 case TOK_UNSIGNED:
3183 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3184 tcc_error("signed and unsigned modifier");
3185 t |= VT_DEFSIGN | VT_UNSIGNED;
3186 next();
3187 typespec_found = 1;
3188 break;
3190 /* storage */
3191 case TOK_EXTERN:
3192 t |= VT_EXTERN;
3193 next();
3194 break;
3195 case TOK_STATIC:
3196 t |= VT_STATIC;
3197 next();
3198 break;
3199 case TOK_TYPEDEF:
3200 t |= VT_TYPEDEF;
3201 next();
3202 break;
3203 case TOK_INLINE1:
3204 case TOK_INLINE2:
3205 case TOK_INLINE3:
3206 t |= VT_INLINE;
3207 next();
3208 break;
3210 /* GNUC attribute */
3211 case TOK_ATTRIBUTE1:
3212 case TOK_ATTRIBUTE2:
3213 parse_attribute(ad);
3214 if (ad->a.mode) {
3215 u = ad->a.mode -1;
3216 t = (t & ~VT_BTYPE) | u;
3218 break;
3219 /* GNUC typeof */
3220 case TOK_TYPEOF1:
3221 case TOK_TYPEOF2:
3222 case TOK_TYPEOF3:
3223 next();
3224 parse_expr_type(&type1);
3225 /* remove all storage modifiers except typedef */
3226 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3227 goto basic_type2;
3228 default:
3229 if (typespec_found)
3230 goto the_end;
3231 s = sym_find(tok);
3232 if (!s || !(s->type.t & VT_TYPEDEF))
3233 goto the_end;
3234 t |= (s->type.t & ~VT_TYPEDEF);
3235 type->ref = s->type.ref;
3236 if (s->r) {
3237 /* get attributes from typedef */
3238 if (0 == ad->a.aligned)
3239 ad->a.aligned = s->a.aligned;
3240 if (0 == ad->a.func_call)
3241 ad->a.func_call = s->a.func_call;
3242 ad->a.packed |= s->a.packed;
3244 next();
3245 typespec_found = 1;
3246 break;
3248 type_found = 1;
3250 the_end:
3251 if (tcc_state->char_is_unsigned) {
3252 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3253 t |= VT_UNSIGNED;
3256 /* long is never used as type */
3257 if ((t & VT_BTYPE) == VT_LONG)
3258 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3259 t = (t & ~VT_BTYPE) | VT_INT;
3260 #else
3261 t = (t & ~VT_BTYPE) | VT_LLONG;
3262 #endif
3263 type->t = t;
3264 return type_found;
3267 /* convert a function parameter type (array to pointer and function to
3268 function pointer) */
3269 static inline void convert_parameter_type(CType *pt)
3271 /* remove const and volatile qualifiers (XXX: const could be used
3272 to indicate a const function parameter */
3273 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3274 /* array must be transformed to pointer according to ANSI C */
3275 pt->t &= ~VT_ARRAY;
3276 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3277 mk_pointer(pt);
3281 ST_FUNC void parse_asm_str(CString *astr)
3283 skip('(');
3284 /* read the string */
3285 if (tok != TOK_STR)
3286 expect("string constant");
3287 cstr_new(astr);
3288 while (tok == TOK_STR) {
3289 /* XXX: add \0 handling too ? */
3290 cstr_cat(astr, tokc.cstr->data);
3291 next();
3293 cstr_ccat(astr, '\0');
3296 /* Parse an asm label and return the label
3297 * Don't forget to free the CString in the caller! */
3298 static void asm_label_instr(CString *astr)
3300 next();
3301 parse_asm_str(astr);
3302 skip(')');
3303 #ifdef ASM_DEBUG
3304 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3305 #endif
3308 static void post_type(CType *type, AttributeDef *ad)
3310 int n, l, t1, arg_size, align;
3311 Sym **plast, *s, *first;
3312 AttributeDef ad1;
3313 CType pt;
3315 if (tok == '(') {
3316 /* function declaration */
3317 next();
3318 l = 0;
3319 first = NULL;
3320 plast = &first;
3321 arg_size = 0;
3322 if (tok != ')') {
3323 for(;;) {
3324 /* read param name and compute offset */
3325 if (l != FUNC_OLD) {
3326 if (!parse_btype(&pt, &ad1)) {
3327 if (l) {
3328 tcc_error("invalid type");
3329 } else {
3330 l = FUNC_OLD;
3331 goto old_proto;
3334 l = FUNC_NEW;
3335 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3336 break;
3337 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3338 if ((pt.t & VT_BTYPE) == VT_VOID)
3339 tcc_error("parameter declared as void");
3340 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3341 } else {
3342 old_proto:
3343 n = tok;
3344 if (n < TOK_UIDENT)
3345 expect("identifier");
3346 pt.t = VT_INT;
3347 next();
3349 convert_parameter_type(&pt);
3350 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3351 *plast = s;
3352 plast = &s->next;
3353 if (tok == ')')
3354 break;
3355 skip(',');
3356 if (l == FUNC_NEW && tok == TOK_DOTS) {
3357 l = FUNC_ELLIPSIS;
3358 next();
3359 break;
3363 /* if no parameters, then old type prototype */
3364 if (l == 0)
3365 l = FUNC_OLD;
3366 skip(')');
3367 /* NOTE: const is ignored in returned type as it has a special
3368 meaning in gcc / C++ */
3369 type->t &= ~VT_CONSTANT;
3370 /* some ancient pre-K&R C allows a function to return an array
3371 and the array brackets to be put after the arguments, such
3372 that "int c()[]" means something like "int[] c()" */
3373 if (tok == '[') {
3374 next();
3375 skip(']'); /* only handle simple "[]" */
3376 type->t |= VT_PTR;
3378 /* we push a anonymous symbol which will contain the function prototype */
3379 ad->a.func_args = arg_size;
3380 s = sym_push(SYM_FIELD, type, 0, l);
3381 s->a = ad->a;
3382 s->next = first;
3383 type->t = VT_FUNC;
3384 type->ref = s;
3385 } else if (tok == '[') {
3386 /* array definition */
3387 next();
3388 if (tok == TOK_RESTRICT1)
3389 next();
3390 n = -1;
3391 t1 = 0;
3392 if (tok != ']') {
3393 if (!local_stack || nocode_wanted)
3394 vpushi(expr_const());
3395 else gexpr();
3396 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3397 n = vtop->c.i;
3398 if (n < 0)
3399 tcc_error("invalid array size");
3400 } else {
3401 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3402 tcc_error("size of variable length array should be an integer");
3403 t1 = VT_VLA;
3406 skip(']');
3407 /* parse next post type */
3408 post_type(type, ad);
3409 if (type->t == VT_FUNC)
3410 tcc_error("declaration of an array of functions");
3411 t1 |= type->t & VT_VLA;
3413 if (t1 & VT_VLA) {
3414 loc -= type_size(&int_type, &align);
3415 loc &= -align;
3416 n = loc;
3418 vla_runtime_type_size(type, &align);
3419 gen_op('*');
3420 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3421 vswap();
3422 vstore();
3424 if (n != -1)
3425 vpop();
3427 /* we push an anonymous symbol which will contain the array
3428 element type */
3429 s = sym_push(SYM_FIELD, type, 0, n);
3430 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3431 type->ref = s;
3435 /* Parse a type declaration (except basic type), and return the type
3436 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3437 expected. 'type' should contain the basic type. 'ad' is the
3438 attribute definition of the basic type. It can be modified by
3439 type_decl().
3441 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3443 Sym *s;
3444 CType type1, *type2;
3445 int qualifiers, storage;
3447 while (tok == '*') {
3448 qualifiers = 0;
3449 redo:
3450 next();
3451 switch(tok) {
3452 case TOK_CONST1:
3453 case TOK_CONST2:
3454 case TOK_CONST3:
3455 qualifiers |= VT_CONSTANT;
3456 goto redo;
3457 case TOK_VOLATILE1:
3458 case TOK_VOLATILE2:
3459 case TOK_VOLATILE3:
3460 qualifiers |= VT_VOLATILE;
3461 goto redo;
3462 case TOK_RESTRICT1:
3463 case TOK_RESTRICT2:
3464 case TOK_RESTRICT3:
3465 goto redo;
3467 mk_pointer(type);
3468 type->t |= qualifiers;
3471 /* XXX: clarify attribute handling */
3472 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3473 parse_attribute(ad);
3475 /* recursive type */
3476 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3477 type1.t = 0; /* XXX: same as int */
3478 if (tok == '(') {
3479 next();
3480 /* XXX: this is not correct to modify 'ad' at this point, but
3481 the syntax is not clear */
3482 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3483 parse_attribute(ad);
3484 type_decl(&type1, ad, v, td);
3485 skip(')');
3486 } else {
3487 /* type identifier */
3488 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3489 *v = tok;
3490 next();
3491 } else {
3492 if (!(td & TYPE_ABSTRACT))
3493 expect("identifier");
3494 *v = 0;
3497 storage = type->t & VT_STORAGE;
3498 type->t &= ~VT_STORAGE;
3499 if (storage & VT_STATIC) {
3500 int saved_nocode_wanted = nocode_wanted;
3501 nocode_wanted = 1;
3502 post_type(type, ad);
3503 nocode_wanted = saved_nocode_wanted;
3504 } else
3505 post_type(type, ad);
3506 type->t |= storage;
3507 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3508 parse_attribute(ad);
3510 if (!type1.t)
3511 return;
3512 /* append type at the end of type1 */
3513 type2 = &type1;
3514 for(;;) {
3515 s = type2->ref;
3516 type2 = &s->type;
3517 if (!type2->t) {
3518 *type2 = *type;
3519 break;
3522 *type = type1;
3525 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3526 ST_FUNC int lvalue_type(int t)
3528 int bt, r;
3529 r = VT_LVAL;
3530 bt = t & VT_BTYPE;
3531 if (bt == VT_BYTE || bt == VT_BOOL)
3532 r |= VT_LVAL_BYTE;
3533 else if (bt == VT_SHORT)
3534 r |= VT_LVAL_SHORT;
3535 else
3536 return r;
3537 if (t & VT_UNSIGNED)
3538 r |= VT_LVAL_UNSIGNED;
3539 return r;
3542 /* indirection with full error checking and bound check */
3543 ST_FUNC void indir(void)
3545 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3546 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3547 return;
3548 expect("pointer");
3550 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3551 gv(RC_INT);
3552 vtop->type = *pointed_type(&vtop->type);
3553 /* Arrays and functions are never lvalues */
3554 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3555 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3556 vtop->r |= lvalue_type(vtop->type.t);
3557 /* if bound checking, the referenced pointer must be checked */
3558 #ifdef CONFIG_TCC_BCHECK
3559 if (tcc_state->do_bounds_check)
3560 vtop->r |= VT_MUSTBOUND;
3561 #endif
3565 /* pass a parameter to a function and do type checking and casting */
3566 static void gfunc_param_typed(Sym *func, Sym *arg)
3568 int func_type;
3569 CType type;
3571 func_type = func->c;
3572 if (func_type == FUNC_OLD ||
3573 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3574 /* default casting : only need to convert float to double */
3575 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3576 type.t = VT_DOUBLE;
3577 gen_cast(&type);
3578 } else if (vtop->type.t & VT_BITFIELD) {
3579 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3580 gen_cast(&type);
3582 } else if (arg == NULL) {
3583 tcc_error("too many arguments to function");
3584 } else {
3585 type = arg->type;
3586 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3587 gen_assign_cast(&type);
3591 /* parse an expression of the form '(type)' or '(expr)' and return its
3592 type */
3593 static void parse_expr_type(CType *type)
3595 int n;
3596 AttributeDef ad;
3598 skip('(');
3599 if (parse_btype(type, &ad)) {
3600 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3601 } else {
3602 expr_type(type);
3604 skip(')');
3607 static void parse_type(CType *type)
3609 AttributeDef ad;
3610 int n;
3612 if (!parse_btype(type, &ad)) {
3613 expect("type");
3615 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3618 static void vpush_tokc(int t)
3620 CType type;
3621 type.t = t;
3622 type.ref = 0;
3623 vsetc(&type, VT_CONST, &tokc);
3626 ST_FUNC void unary(void)
3628 int n, t, align, size, r, sizeof_caller;
3629 CType type;
3630 Sym *s;
3631 AttributeDef ad;
3632 static int in_sizeof = 0;
3634 sizeof_caller = in_sizeof;
3635 in_sizeof = 0;
3636 /* XXX: GCC 2.95.3 does not generate a table although it should be
3637 better here */
3638 tok_next:
3639 switch(tok) {
3640 case TOK_EXTENSION:
3641 next();
3642 goto tok_next;
3643 case TOK_CINT:
3644 case TOK_CCHAR:
3645 case TOK_LCHAR:
3646 vpushi(tokc.i);
3647 next();
3648 break;
3649 case TOK_CUINT:
3650 vpush_tokc(VT_INT | VT_UNSIGNED);
3651 next();
3652 break;
3653 case TOK_CLLONG:
3654 vpush_tokc(VT_LLONG);
3655 next();
3656 break;
3657 case TOK_CULLONG:
3658 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3659 next();
3660 break;
3661 case TOK_CFLOAT:
3662 vpush_tokc(VT_FLOAT);
3663 next();
3664 break;
3665 case TOK_CDOUBLE:
3666 vpush_tokc(VT_DOUBLE);
3667 next();
3668 break;
3669 case TOK_CLDOUBLE:
3670 vpush_tokc(VT_LDOUBLE);
3671 next();
3672 break;
3673 case TOK___FUNCTION__:
3674 if (!gnu_ext)
3675 goto tok_identifier;
3676 /* fall thru */
3677 case TOK___FUNC__:
3679 void *ptr;
3680 int len;
3681 /* special function name identifier */
3682 len = strlen(funcname) + 1;
3683 /* generate char[len] type */
3684 type.t = VT_BYTE;
3685 mk_pointer(&type);
3686 type.t |= VT_ARRAY;
3687 type.ref->c = len;
3688 vpush_ref(&type, data_section, data_section->data_offset, len);
3689 ptr = section_ptr_add(data_section, len);
3690 memcpy(ptr, funcname, len);
3691 next();
3693 break;
3694 case TOK_LSTR:
3695 #ifdef TCC_TARGET_PE
3696 t = VT_SHORT | VT_UNSIGNED;
3697 #else
3698 t = VT_INT;
3699 #endif
3700 goto str_init;
3701 case TOK_STR:
3702 /* string parsing */
3703 t = VT_BYTE;
3704 str_init:
3705 if (tcc_state->warn_write_strings)
3706 t |= VT_CONSTANT;
3707 type.t = t;
3708 mk_pointer(&type);
3709 type.t |= VT_ARRAY;
3710 memset(&ad, 0, sizeof(AttributeDef));
3711 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3712 break;
3713 case '(':
3714 next();
3715 /* cast ? */
3716 if (parse_btype(&type, &ad)) {
3717 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3718 skip(')');
3719 /* check ISOC99 compound literal */
3720 if (tok == '{') {
3721 /* data is allocated locally by default */
3722 if (global_expr)
3723 r = VT_CONST;
3724 else
3725 r = VT_LOCAL;
3726 /* all except arrays are lvalues */
3727 if (!(type.t & VT_ARRAY))
3728 r |= lvalue_type(type.t);
3729 memset(&ad, 0, sizeof(AttributeDef));
3730 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3731 } else {
3732 if (sizeof_caller) {
3733 vpush(&type);
3734 return;
3736 unary();
3737 is_force = 1;
3738 gen_cast(&type);
3739 is_force = 0;
3741 } else if (tok == '{') {
3742 /* save all registers */
3743 save_regs(0);
3744 /* statement expression : we do not accept break/continue
3745 inside as GCC does */
3746 block(NULL, NULL, NULL, NULL, 0, 1);
3747 skip(')');
3748 } else {
3749 gexpr();
3750 skip(')');
3752 break;
3753 case '*':
3754 next();
3755 unary();
3756 indir();
3757 break;
3758 case '&':
3759 next();
3760 unary();
3761 /* functions names must be treated as function pointers,
3762 except for unary '&' and sizeof. Since we consider that
3763 functions are not lvalues, we only have to handle it
3764 there and in function calls. */
3765 /* arrays can also be used although they are not lvalues */
3766 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3767 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3768 test_lvalue();
3769 mk_pointer(&vtop->type);
3770 gaddrof();
3771 break;
3772 case '!':
3773 next();
3774 unary();
3775 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3776 CType boolean;
3777 boolean.t = VT_BOOL;
3778 gen_cast(&boolean);
3779 vtop->c.i = !vtop->c.i;
3780 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3781 vtop->c.i = vtop->c.i ^ 1;
3782 else {
3783 save_regs(1);
3784 vseti(VT_JMP, gvtst(1, 0));
3786 break;
3787 case '~':
3788 next();
3789 unary();
3790 vpushi(-1);
3791 gen_op('^');
3792 break;
3793 case '+':
3794 next();
3795 unary();
3796 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3797 tcc_error("pointer not accepted for unary plus");
3798 /* In order to force cast, we add zero, except for floating point
3799 where we really need an noop (otherwise -0.0 will be transformed
3800 into +0.0). */
3801 if (!is_float(vtop->type.t)) {
3802 vpushi(0);
3803 gen_op('+');
3805 break;
3806 case TOK_SIZEOF:
3807 case TOK_ALIGNOF1:
3808 case TOK_ALIGNOF2:
3809 t = tok;
3810 next();
3811 in_sizeof++;
3812 unary_type(&type); // Perform a in_sizeof = 0;
3813 size = type_size(&type, &align);
3814 if (t == TOK_SIZEOF) {
3815 if (!(type.t & VT_VLA)) {
3816 if (size < 0)
3817 tcc_error("sizeof applied to an incomplete type");
3818 if(type.t & VT_BITFIELD)
3819 tcc_error("'%s' applied to a bit-field", get_tok_str(t, NULL));
3820 vpushs(size);
3821 } else {
3822 vla_runtime_type_size(&type, &align);
3824 } else {
3825 vpushs(align);
3827 vtop->type.t |= VT_UNSIGNED;
3828 break;
3830 case TOK_builtin_types_compatible_p:
3832 CType type1, type2;
3833 next();
3834 skip('(');
3835 parse_type(&type1);
3836 skip(',');
3837 parse_type(&type2);
3838 skip(')');
3839 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3840 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3841 vpushi(is_compatible_types(&type1, &type2));
3843 break;
3844 case TOK_builtin_constant_p:
3846 int saved_nocode_wanted, res;
3847 next();
3848 skip('(');
3849 saved_nocode_wanted = nocode_wanted;
3850 nocode_wanted = 1;
3851 gexpr();
3852 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3853 vpop();
3854 nocode_wanted = saved_nocode_wanted;
3855 skip(')');
3856 vpushi(res);
3858 break;
3859 case TOK_builtin_frame_address:
3861 int level;
3862 CType type;
3863 next();
3864 skip('(');
3865 if (tok != TOK_CINT || tokc.i < 0) {
3866 tcc_error("__builtin_frame_address only takes positive integers");
3868 level = tokc.i;
3869 next();
3870 skip(')');
3871 type.t = VT_VOID;
3872 mk_pointer(&type);
3873 vset(&type, VT_LOCAL, 0); /* local frame */
3874 while (level--) {
3875 mk_pointer(&vtop->type);
3876 indir(); /* -> parent frame */
3879 break;
3880 #ifdef TCC_TARGET_X86_64
3881 #ifdef TCC_TARGET_PE
3882 case TOK_builtin_va_start:
3884 next();
3885 skip('(');
3886 expr_eq();
3887 skip(',');
3888 expr_eq();
3889 skip(')');
3890 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
3891 tcc_error("__builtin_va_start expects a local variable");
3892 vtop->r &= ~(VT_LVAL | VT_REF);
3893 vtop->type = char_pointer_type;
3894 vstore();
3896 break;
3897 #else
3898 case TOK_builtin_va_arg_types:
3900 CType type;
3901 next();
3902 skip('(');
3903 parse_type(&type);
3904 skip(')');
3905 vpushi(classify_x86_64_va_arg(&type));
3907 break;
3908 #endif
3909 #endif
3910 case TOK_INC:
3911 case TOK_DEC:
3912 t = tok;
3913 next();
3914 unary();
3915 inc(0, t);
3916 break;
3917 case '-':
3918 next();
3919 unary();
3920 t = vtop->type.t & VT_BTYPE;
3921 if (is_float(t)) {
3922 /* In IEEE negate(x) isn't subtract(0,x), but rather
3923 subtract(-0, x). */
3924 vpush(&vtop->type);
3925 if (t == VT_FLOAT)
3926 vtop->c.f = -0.0f;
3927 else if (t == VT_DOUBLE)
3928 vtop->c.d = -0.0;
3929 else
3930 vtop->c.ld = -0.0;
3931 } else
3932 vpushi(0);
3933 vswap();
3934 gen_op('-');
3935 break;
3936 case TOK_LAND:
3937 if (!gnu_ext)
3938 goto tok_identifier;
3939 next();
3940 /* allow to take the address of a label */
3941 if (tok < TOK_UIDENT)
3942 expect("label identifier");
3943 s = label_find(tok);
3944 if (!s) {
3945 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3946 } else {
3947 if (s->r == LABEL_DECLARED)
3948 s->r = LABEL_FORWARD;
3950 if (!s->type.t) {
3951 s->type.t = VT_VOID;
3952 mk_pointer(&s->type);
3953 s->type.t |= VT_STATIC;
3955 vpushsym(&s->type, s);
3956 next();
3957 break;
3959 // special qnan , snan and infinity values
3960 case TOK___NAN__:
3961 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3962 next();
3963 break;
3964 case TOK___SNAN__:
3965 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3966 next();
3967 break;
3968 case TOK___INF__:
3969 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3970 next();
3971 break;
3973 default:
3974 tok_identifier:
3975 t = tok;
3976 next();
3977 if (t < TOK_UIDENT)
3978 expect("identifier");
3979 s = sym_find(t);
3980 if (!s) {
3981 const char *name = get_tok_str(t, NULL);
3982 if (tok != '(')
3983 tcc_error("'%s' undeclared", name);
3984 /* for simple function calls, we tolerate undeclared
3985 external reference to int() function */
3986 if (tcc_state->warn_implicit_function_declaration
3987 #ifdef TCC_TARGET_PE
3988 /* people must be warned about using undeclared WINAPI functions
3989 (which usually start with uppercase letter) */
3990 || (name[0] >= 'A' && name[0] <= 'Z')
3991 #endif
3993 tcc_warning("implicit declaration of function '%s'", name);
3994 s = external_sym(t, &func_old_type, 0, NULL);
3996 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3997 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3998 /* if referencing an inline function, then we generate a
3999 symbol to it if not already done. It will have the
4000 effect to generate code for it at the end of the
4001 compilation unit. Inline function as always
4002 generated in the text section. */
4003 if (!s->c)
4004 put_extern_sym(s, text_section, 0, 0);
4005 r = VT_SYM | VT_CONST;
4006 } else {
4007 r = s->r;
4009 vset(&s->type, r, s->c);
4010 /* if forward reference, we must point to s */
4011 if (vtop->r & VT_SYM) {
4012 vtop->sym = s;
4013 vtop->c.ptr_offset = 0;
4015 break;
4018 /* post operations */
4019 while (1) {
4020 if (tok == TOK_INC || tok == TOK_DEC) {
4021 inc(1, tok);
4022 next();
4023 } else if (tok == '.' || tok == TOK_ARROW) {
4024 int qualifiers;
4025 /* field */
4026 if (tok == TOK_ARROW)
4027 indir();
4028 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4029 test_lvalue();
4030 gaddrof();
4031 next();
4032 /* expect pointer on structure */
4033 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4034 expect("struct or union");
4035 s = vtop->type.ref;
4036 /* find field */
4037 tok |= SYM_FIELD;
4038 while ((s = s->next) != NULL) {
4039 if (s->v == tok)
4040 break;
4042 if (!s)
4043 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
4044 /* add field offset to pointer */
4045 vtop->type = char_pointer_type; /* change type to 'char *' */
4046 vpushi(s->c);
4047 gen_op('+');
4048 /* change type to field type, and set to lvalue */
4049 vtop->type = s->type;
4050 vtop->type.t |= qualifiers;
4051 /* an array is never an lvalue */
4052 if (!(vtop->type.t & VT_ARRAY)) {
4053 vtop->r |= lvalue_type(vtop->type.t);
4054 #ifdef CONFIG_TCC_BCHECK
4055 /* if bound checking, the referenced pointer must be checked */
4056 if (tcc_state->do_bounds_check)
4057 vtop->r |= VT_MUSTBOUND;
4058 #endif
4060 next();
4061 } else if (tok == '[') {
4062 next();
4063 gexpr();
4064 gen_op('+');
4065 indir();
4066 skip(']');
4067 } else if (tok == '(') {
4068 SValue ret;
4069 Sym *sa;
4070 int nb_args, ret_nregs, ret_align, variadic;
4072 /* function call */
4073 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4074 /* pointer test (no array accepted) */
4075 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4076 vtop->type = *pointed_type(&vtop->type);
4077 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4078 goto error_func;
4079 } else {
4080 error_func:
4081 expect("function pointer");
4083 } else {
4084 vtop->r &= ~VT_LVAL; /* no lvalue */
4086 /* get return type */
4087 s = vtop->type.ref;
4088 next();
4089 sa = s->next; /* first parameter */
4090 nb_args = 0;
4091 ret.r2 = VT_CONST;
4092 /* compute first implicit argument if a structure is returned */
4093 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4094 variadic = (s->c == FUNC_ELLIPSIS);
4095 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4096 &ret_align);
4097 if (!ret_nregs) {
4098 /* get some space for the returned structure */
4099 size = type_size(&s->type, &align);
4100 loc = (loc - size) & -align;
4101 ret.type = s->type;
4102 ret.r = VT_LOCAL | VT_LVAL;
4103 /* pass it as 'int' to avoid structure arg passing
4104 problems */
4105 vseti(VT_LOCAL, loc);
4106 ret.c = vtop->c;
4107 nb_args++;
4109 } else {
4110 ret_nregs = 1;
4111 ret.type = s->type;
4114 if (ret_nregs) {
4115 /* return in register */
4116 if (is_float(ret.type.t)) {
4117 ret.r = reg_fret(ret.type.t);
4118 #ifdef TCC_TARGET_X86_64
4119 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4120 ret.r2 = REG_QRET;
4121 #endif
4122 } else {
4123 #ifdef TCC_TARGET_X86_64
4124 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4125 #else
4126 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4127 #endif
4128 ret.r2 = REG_LRET;
4129 ret.r = REG_IRET;
4131 ret.c.i = 0;
4133 if (tok != ')') {
4134 for(;;) {
4135 expr_eq();
4136 gfunc_param_typed(s, sa);
4137 nb_args++;
4138 if (sa)
4139 sa = sa->next;
4140 if (tok == ')')
4141 break;
4142 skip(',');
4145 if (sa)
4146 tcc_error("too few arguments to function");
4147 skip(')');
4148 if (!nocode_wanted) {
4149 gfunc_call(nb_args);
4150 } else {
4151 vtop -= (nb_args + 1);
4154 /* return value */
4155 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4156 vsetc(&ret.type, r, &ret.c);
4157 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4160 /* handle packed struct return */
4161 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4162 int addr, offset;
4164 size = type_size(&s->type, &align);
4165 loc = (loc - size) & -align;
4166 addr = loc;
4167 offset = 0;
4168 for (;;) {
4169 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4170 vswap();
4171 vstore();
4172 vtop--;
4173 if (--ret_nregs == 0)
4174 break;
4175 /* XXX: compatible with arm only: ret_align == register_size */
4176 offset += ret_align;
4178 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4180 } else {
4181 break;
4186 ST_FUNC void expr_prod(void)
4188 int t;
4190 unary();
4191 while (tok == '*' || tok == '/' || tok == '%') {
4192 t = tok;
4193 next();
4194 unary();
4195 gen_op(t);
4199 ST_FUNC void expr_sum(void)
4201 int t;
4203 expr_prod();
4204 while (tok == '+' || tok == '-') {
4205 t = tok;
4206 next();
4207 expr_prod();
4208 gen_op(t);
4212 static void expr_shift(void)
4214 int t;
4216 expr_sum();
4217 while (tok == TOK_SHL || tok == TOK_SAR) {
4218 t = tok;
4219 next();
4220 expr_sum();
4221 gen_op(t);
4225 static void expr_cmp(void)
4227 int t;
4229 expr_shift();
4230 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4231 tok == TOK_ULT || tok == TOK_UGE) {
4232 t = tok;
4233 next();
4234 expr_shift();
4235 gen_op(t);
4239 static void expr_cmpeq(void)
4241 int t;
4243 expr_cmp();
4244 while (tok == TOK_EQ || tok == TOK_NE) {
4245 t = tok;
4246 next();
4247 expr_cmp();
4248 gen_op(t);
4252 static void expr_and(void)
4254 expr_cmpeq();
4255 while (tok == '&') {
4256 next();
4257 expr_cmpeq();
4258 gen_op('&');
4262 static void expr_xor(void)
4264 expr_and();
4265 while (tok == '^') {
4266 next();
4267 expr_and();
4268 gen_op('^');
4272 static void expr_or(void)
4274 expr_xor();
4275 while (tok == '|') {
4276 next();
4277 expr_xor();
4278 gen_op('|');
4282 /* XXX: fix this mess */
4283 static void expr_land_const(void)
4285 expr_or();
4286 while (tok == TOK_LAND) {
4287 next();
4288 expr_or();
4289 gen_op(TOK_LAND);
4293 /* XXX: fix this mess */
4294 static void expr_lor_const(void)
4296 expr_land_const();
4297 while (tok == TOK_LOR) {
4298 next();
4299 expr_land_const();
4300 gen_op(TOK_LOR);
4304 /* only used if non constant */
4305 static void expr_land(void)
4307 int t;
4309 expr_or();
4310 if (tok == TOK_LAND) {
4311 t = 0;
4312 save_regs(1);
4313 for(;;) {
4314 t = gvtst(1, t);
4315 if (tok != TOK_LAND) {
4316 vseti(VT_JMPI, t);
4317 break;
4319 next();
4320 expr_or();
4325 static void expr_lor(void)
4327 int t;
4329 expr_land();
4330 if (tok == TOK_LOR) {
4331 t = 0;
4332 save_regs(1);
4333 for(;;) {
4334 t = gvtst(0, t);
4335 if (tok != TOK_LOR) {
4336 vseti(VT_JMP, t);
4337 break;
4339 next();
4340 expr_land();
4345 /* XXX: better constant handling */
4346 static void expr_cond(void)
4348 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4349 SValue sv;
4350 CType type, type1, type2;
4352 if (const_wanted) {
4353 expr_lor_const();
4354 if (tok == '?') {
4355 CType boolean;
4356 int c;
4357 boolean.t = VT_BOOL;
4358 vdup();
4359 gen_cast(&boolean);
4360 c = vtop->c.i;
4361 vpop();
4362 next();
4363 if (tok != ':' || !gnu_ext) {
4364 vpop();
4365 gexpr();
4367 if (!c)
4368 vpop();
4369 skip(':');
4370 expr_cond();
4371 if (c)
4372 vpop();
4374 } else {
4375 expr_lor();
4376 if (tok == '?') {
4377 next();
4378 if (vtop != vstack) {
4379 /* needed to avoid having different registers saved in
4380 each branch */
4381 if (is_float(vtop->type.t)) {
4382 rc = RC_FLOAT;
4383 #ifdef TCC_TARGET_X86_64
4384 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4385 rc = RC_ST0;
4387 #endif
4389 else
4390 rc = RC_INT;
4391 gv(rc);
4392 save_regs(1);
4394 if (tok == ':' && gnu_ext) {
4395 gv_dup();
4396 tt = gvtst(1, 0);
4397 } else {
4398 tt = gvtst(1, 0);
4399 gexpr();
4401 type1 = vtop->type;
4402 sv = *vtop; /* save value to handle it later */
4403 vtop--; /* no vpop so that FP stack is not flushed */
4404 skip(':');
4405 u = gjmp(0);
4406 gsym(tt);
4407 expr_cond();
4408 type2 = vtop->type;
4410 t1 = type1.t;
4411 bt1 = t1 & VT_BTYPE;
4412 t2 = type2.t;
4413 bt2 = t2 & VT_BTYPE;
4414 /* cast operands to correct type according to ISOC rules */
4415 if (is_float(bt1) || is_float(bt2)) {
4416 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4417 type.t = VT_LDOUBLE;
4418 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4419 type.t = VT_DOUBLE;
4420 } else {
4421 type.t = VT_FLOAT;
4423 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4424 /* cast to biggest op */
4425 type.t = VT_LLONG;
4426 /* convert to unsigned if it does not fit in a long long */
4427 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4428 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4429 type.t |= VT_UNSIGNED;
4430 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4431 /* If one is a null ptr constant the result type
4432 is the other. */
4433 if (is_null_pointer (vtop))
4434 type = type1;
4435 else if (is_null_pointer (&sv))
4436 type = type2;
4437 /* XXX: test pointer compatibility, C99 has more elaborate
4438 rules here. */
4439 else
4440 type = type1;
4441 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4442 /* XXX: test function pointer compatibility */
4443 type = bt1 == VT_FUNC ? type1 : type2;
4444 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4445 /* XXX: test structure compatibility */
4446 type = bt1 == VT_STRUCT ? type1 : type2;
4447 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4448 /* NOTE: as an extension, we accept void on only one side */
4449 type.t = VT_VOID;
4450 } else {
4451 /* integer operations */
4452 type.t = VT_INT;
4453 /* convert to unsigned if it does not fit in an integer */
4454 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4455 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4456 type.t |= VT_UNSIGNED;
4459 /* now we convert second operand */
4460 gen_cast(&type);
4461 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4462 gaddrof();
4463 rc = RC_INT;
4464 if (is_float(type.t)) {
4465 rc = RC_FLOAT;
4466 #ifdef TCC_TARGET_X86_64
4467 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4468 rc = RC_ST0;
4470 #endif
4471 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4472 /* for long longs, we use fixed registers to avoid having
4473 to handle a complicated move */
4474 rc = RC_IRET;
4477 r2 = gv(rc);
4478 /* this is horrible, but we must also convert first
4479 operand */
4480 tt = gjmp(0);
4481 gsym(u);
4482 /* put again first value and cast it */
4483 *vtop = sv;
4484 gen_cast(&type);
4485 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4486 gaddrof();
4487 r1 = gv(rc);
4488 move_reg(r2, r1, type.t);
4489 vtop->r = r2;
4490 gsym(tt);
4495 static void expr_eq(void)
4497 int t;
4499 expr_cond();
4500 if (tok == '=' ||
4501 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4502 tok == TOK_A_XOR || tok == TOK_A_OR ||
4503 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4504 test_lvalue();
4505 t = tok;
4506 next();
4507 if (t == '=') {
4508 expr_eq();
4509 } else {
4510 vdup();
4511 expr_eq();
4512 gen_op(t & 0x7f);
4514 vstore();
4518 ST_FUNC void gexpr(void)
4520 while (1) {
4521 expr_eq();
4522 if (tok != ',')
4523 break;
4524 vpop();
4525 next();
4529 /* parse an expression and return its type without any side effect. */
4530 static void expr_type(CType *type)
4532 int saved_nocode_wanted;
4534 saved_nocode_wanted = nocode_wanted;
4535 nocode_wanted = 1;
4536 gexpr();
4537 *type = vtop->type;
4538 vpop();
4539 nocode_wanted = saved_nocode_wanted;
4542 /* parse a unary expression and return its type without any side
4543 effect. */
4544 static void unary_type(CType *type)
4546 int a;
4548 a = nocode_wanted;
4549 nocode_wanted = 1;
4550 unary();
4551 *type = vtop->type;
4552 vpop();
4553 nocode_wanted = a;
4556 /* parse a constant expression and return value in vtop. */
4557 static void expr_const1(void)
4559 int a;
4560 a = const_wanted;
4561 const_wanted = 1;
4562 expr_cond();
4563 const_wanted = a;
4566 /* parse an integer constant and return its value. */
4567 ST_FUNC int expr_const(void)
4569 int c;
4570 expr_const1();
4571 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4572 expect("constant expression");
4573 c = vtop->c.i;
4574 vpop();
4575 return c;
4578 /* return the label token if current token is a label, otherwise
4579 return zero */
4580 static int is_label(void)
4582 int last_tok;
4584 /* fast test first */
4585 if (tok < TOK_UIDENT)
4586 return 0;
4587 /* no need to save tokc because tok is an identifier */
4588 last_tok = tok;
4589 next();
4590 if (tok == ':') {
4591 next();
4592 return last_tok;
4593 } else {
4594 unget_tok(last_tok);
4595 return 0;
4599 static void label_or_decl(int l)
4601 int last_tok;
4603 /* fast test first */
4604 if (tok >= TOK_UIDENT)
4606 /* no need to save tokc because tok is an identifier */
4607 last_tok = tok;
4608 next();
4609 if (tok == ':') {
4610 unget_tok(last_tok);
4611 return;
4613 unget_tok(last_tok);
4615 decl(l);
4618 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4619 int case_reg, int is_expr)
4621 int a, b, c, d;
4622 Sym *s, *frame_bottom;
4624 /* generate line number info */
4625 if (tcc_state->do_debug &&
4626 (last_line_num != file->line_num || last_ind != ind)) {
4627 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4628 last_ind = ind;
4629 last_line_num = file->line_num;
4632 if (is_expr) {
4633 /* default return value is (void) */
4634 vpushi(0);
4635 vtop->type.t = VT_VOID;
4638 if (tok == TOK_IF) {
4639 /* if test */
4640 next();
4641 skip('(');
4642 gexpr();
4643 skip(')');
4644 a = gvtst(1, 0);
4645 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4646 c = tok;
4647 if (c == TOK_ELSE) {
4648 next();
4649 d = gjmp(0);
4650 gsym(a);
4651 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4652 gsym(d); /* patch else jmp */
4653 } else
4654 gsym(a);
4655 } else if (tok == TOK_WHILE) {
4656 next();
4657 d = ind;
4658 skip('(');
4659 gexpr();
4660 skip(')');
4661 a = gvtst(1, 0);
4662 b = 0;
4663 block(&a, &b, case_sym, def_sym, case_reg, 0);
4664 gjmp_addr(d);
4665 gsym(a);
4666 gsym_addr(b, d);
4667 } else if (tok == '{') {
4668 Sym *llabel;
4669 int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
4671 next();
4672 /* record local declaration stack position */
4673 s = local_stack;
4674 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4675 frame_bottom->next = scope_stack_bottom;
4676 scope_stack_bottom = frame_bottom;
4677 llabel = local_label_stack;
4679 /* save VLA state */
4680 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4681 if (saved_vla_sp_loc != &vla_sp_root_loc)
4682 vla_sp_loc = &block_vla_sp_loc;
4684 saved_vla_flags = vla_flags;
4685 vla_flags |= VLA_NEED_NEW_FRAME;
4687 /* handle local labels declarations */
4688 if (tok == TOK_LABEL) {
4689 next();
4690 for(;;) {
4691 if (tok < TOK_UIDENT)
4692 expect("label identifier");
4693 label_push(&local_label_stack, tok, LABEL_DECLARED);
4694 next();
4695 if (tok == ',') {
4696 next();
4697 } else {
4698 skip(';');
4699 break;
4703 while (tok != '}') {
4704 label_or_decl(VT_LOCAL);
4705 if (tok != '}') {
4706 if (is_expr)
4707 vpop();
4708 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4711 /* pop locally defined labels */
4712 label_pop(&local_label_stack, llabel);
4713 if(is_expr) {
4714 /* XXX: this solution makes only valgrind happy...
4715 triggered by gcc.c-torture/execute/20000917-1.c */
4716 Sym *p;
4717 switch(vtop->type.t & VT_BTYPE) {
4718 case VT_PTR:
4719 case VT_STRUCT:
4720 case VT_ENUM:
4721 case VT_FUNC:
4722 for(p=vtop->type.ref;p;p=p->prev)
4723 if(p->prev==s)
4724 tcc_error("unsupported expression type");
4727 /* pop locally defined symbols */
4728 scope_stack_bottom = scope_stack_bottom->next;
4729 sym_pop(&local_stack, s);
4731 /* Pop VLA frames and restore stack pointer if required */
4732 if (saved_vla_sp_loc != &vla_sp_root_loc)
4733 *saved_vla_sp_loc = block_vla_sp_loc;
4734 if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
4735 vla_sp_loc = saved_vla_sp_loc;
4736 gen_vla_sp_restore(*vla_sp_loc);
4738 vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
4740 next();
4741 } else if (tok == TOK_RETURN) {
4742 next();
4743 if (tok != ';') {
4744 gexpr();
4745 gen_assign_cast(&func_vt);
4746 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4747 CType type, ret_type;
4748 int ret_align, ret_nregs;
4749 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
4750 &ret_align);
4751 if (0 == ret_nregs) {
4752 /* if returning structure, must copy it to implicit
4753 first pointer arg location */
4754 type = func_vt;
4755 mk_pointer(&type);
4756 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4757 indir();
4758 vswap();
4759 /* copy structure value to pointer */
4760 vstore();
4761 } else {
4762 /* returning structure packed into registers */
4763 int r, size, addr, align;
4764 size = type_size(&func_vt,&align);
4765 if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))
4766 && (align & (ret_align-1))) {
4767 loc = (loc - size) & -align;
4768 addr = loc;
4769 type = func_vt;
4770 vset(&type, VT_LOCAL | VT_LVAL, addr);
4771 vswap();
4772 vstore();
4773 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
4775 vtop->type = ret_type;
4776 if (is_float(ret_type.t))
4777 r = rc_fret(ret_type.t);
4778 else
4779 r = RC_IRET;
4781 for (;;) {
4782 gv(r);
4783 if (--ret_nregs == 0)
4784 break;
4785 /* We assume that when a structure is returned in multiple
4786 registers, their classes are consecutive values of the
4787 suite s(n) = 2^n */
4788 r <<= 1;
4789 /* XXX: compatible with arm only: ret_align == register_size */
4790 vtop->c.i += ret_align;
4791 vtop->r = VT_LOCAL | VT_LVAL;
4794 } else if (is_float(func_vt.t)) {
4795 gv(rc_fret(func_vt.t));
4796 } else {
4797 gv(RC_IRET);
4799 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4801 skip(';');
4802 rsym = gjmp(rsym); /* jmp */
4803 } else if (tok == TOK_BREAK) {
4804 /* compute jump */
4805 if (!bsym)
4806 tcc_error("cannot break");
4807 *bsym = gjmp(*bsym);
4808 next();
4809 skip(';');
4810 } else if (tok == TOK_CONTINUE) {
4811 /* compute jump */
4812 if (!csym)
4813 tcc_error("cannot continue");
4814 *csym = gjmp(*csym);
4815 next();
4816 skip(';');
4817 } else if (tok == TOK_FOR) {
4818 int e;
4819 next();
4820 skip('(');
4821 s = local_stack;
4822 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4823 frame_bottom->next = scope_stack_bottom;
4824 scope_stack_bottom = frame_bottom;
4825 if (tok != ';') {
4826 /* c99 for-loop init decl? */
4827 if (!decl0(VT_LOCAL, 1)) {
4828 /* no, regular for-loop init expr */
4829 gexpr();
4830 vpop();
4833 skip(';');
4834 d = ind;
4835 c = ind;
4836 a = 0;
4837 b = 0;
4838 if (tok != ';') {
4839 gexpr();
4840 a = gvtst(1, 0);
4842 skip(';');
4843 if (tok != ')') {
4844 e = gjmp(0);
4845 c = ind;
4846 gexpr();
4847 vpop();
4848 gjmp_addr(d);
4849 gsym(e);
4851 skip(')');
4852 block(&a, &b, case_sym, def_sym, case_reg, 0);
4853 gjmp_addr(c);
4854 gsym(a);
4855 gsym_addr(b, c);
4856 scope_stack_bottom = scope_stack_bottom->next;
4857 sym_pop(&local_stack, s);
4858 } else
4859 if (tok == TOK_DO) {
4860 next();
4861 a = 0;
4862 b = 0;
4863 d = ind;
4864 block(&a, &b, case_sym, def_sym, case_reg, 0);
4865 skip(TOK_WHILE);
4866 skip('(');
4867 gsym(b);
4868 gexpr();
4869 c = gvtst(0, 0);
4870 gsym_addr(c, d);
4871 skip(')');
4872 gsym(a);
4873 skip(';');
4874 } else
4875 if (tok == TOK_SWITCH) {
4876 next();
4877 skip('(');
4878 gexpr();
4879 /* XXX: other types than integer */
4880 case_reg = gv(RC_INT);
4881 vpop();
4882 skip(')');
4883 a = 0;
4884 b = gjmp(0); /* jump to first case */
4885 c = 0;
4886 block(&a, csym, &b, &c, case_reg, 0);
4887 /* if no default, jmp after switch */
4888 if (c == 0)
4889 c = ind;
4890 /* default label */
4891 gsym_addr(b, c);
4892 /* break label */
4893 gsym(a);
4894 } else
4895 if (tok == TOK_CASE) {
4896 int v1, v2;
4897 if (!case_sym)
4898 expect("switch");
4899 next();
4900 v1 = expr_const();
4901 v2 = v1;
4902 if (gnu_ext && tok == TOK_DOTS) {
4903 next();
4904 v2 = expr_const();
4905 if (v2 < v1)
4906 tcc_warning("empty case range");
4908 /* since a case is like a label, we must skip it with a jmp */
4909 b = gjmp(0);
4910 gsym(*case_sym);
4911 vseti(case_reg, 0);
4912 vpushi(v1);
4913 if (v1 == v2) {
4914 gen_op(TOK_EQ);
4915 *case_sym = gtst(1, 0);
4916 } else {
4917 gen_op(TOK_GE);
4918 *case_sym = gtst(1, 0);
4919 vseti(case_reg, 0);
4920 vpushi(v2);
4921 gen_op(TOK_LE);
4922 *case_sym = gtst(1, *case_sym);
4924 gsym(b);
4925 skip(':');
4926 is_expr = 0;
4927 goto block_after_label;
4928 } else
4929 if (tok == TOK_DEFAULT) {
4930 next();
4931 skip(':');
4932 if (!def_sym)
4933 expect("switch");
4934 if (*def_sym)
4935 tcc_error("too many 'default'");
4936 *def_sym = ind;
4937 is_expr = 0;
4938 goto block_after_label;
4939 } else
4940 if (tok == TOK_GOTO) {
4941 next();
4942 if (tok == '*' && gnu_ext) {
4943 /* computed goto */
4944 next();
4945 gexpr();
4946 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4947 expect("pointer");
4948 ggoto();
4949 } else if (tok >= TOK_UIDENT) {
4950 s = label_find(tok);
4951 /* put forward definition if needed */
4952 if (!s) {
4953 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4954 } else {
4955 if (s->r == LABEL_DECLARED)
4956 s->r = LABEL_FORWARD;
4958 /* label already defined */
4959 if (vla_flags & VLA_IN_SCOPE) {
4960 /* If VLAs are in use, save the current stack pointer and
4961 reset the stack pointer to what it was at function entry
4962 (label will restore stack pointer in inner scopes) */
4963 vla_sp_save();
4964 gen_vla_sp_restore(vla_sp_root_loc);
4966 if (s->r & LABEL_FORWARD)
4967 s->jnext = gjmp(s->jnext);
4968 else
4969 gjmp_addr(s->jnext);
4970 next();
4971 } else {
4972 expect("label identifier");
4974 skip(';');
4975 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4976 asm_instr();
4977 } else {
4978 b = is_label();
4979 if (b) {
4980 /* label case */
4981 if (vla_flags & VLA_IN_SCOPE) {
4982 /* save/restore stack pointer across label
4983 this is a no-op when combined with the load immediately
4984 after the label unless we arrive via goto */
4985 vla_sp_save();
4987 s = label_find(b);
4988 if (s) {
4989 if (s->r == LABEL_DEFINED)
4990 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4991 gsym(s->jnext);
4992 s->r = LABEL_DEFINED;
4993 } else {
4994 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4996 s->jnext = ind;
4997 if (vla_flags & VLA_IN_SCOPE) {
4998 gen_vla_sp_restore(*vla_sp_loc);
4999 vla_flags |= VLA_NEED_NEW_FRAME;
5001 /* we accept this, but it is a mistake */
5002 block_after_label:
5003 if (tok == '}') {
5004 tcc_warning("deprecated use of label at end of compound statement");
5005 } else {
5006 if (is_expr)
5007 vpop();
5008 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
5010 } else {
5011 /* expression case */
5012 if (tok != ';') {
5013 if (is_expr) {
5014 vpop();
5015 gexpr();
5016 } else {
5017 gexpr();
5018 vpop();
5021 skip(';');
5026 /* t is the array or struct type. c is the array or struct
5027 address. cur_index/cur_field is the pointer to the current
5028 value. 'size_only' is true if only size info is needed (only used
5029 in arrays) */
5030 static void decl_designator(CType *type, Section *sec, unsigned long c,
5031 int *cur_index, Sym **cur_field,
5032 int size_only)
5034 Sym *s, *f;
5035 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5036 CType type1;
5038 notfirst = 0;
5039 elem_size = 0;
5040 nb_elems = 1;
5041 if (gnu_ext && (l = is_label()) != 0)
5042 goto struct_field;
5043 s = type->ref;
5044 while (tok == '[' || tok == '.') {
5045 if (tok == '[') {
5046 if (!(type->t & VT_ARRAY))
5047 expect("array type");
5048 next();
5049 index = expr_const();
5050 if (index < 0 || (s->c >= 0 && index >= s->c))
5051 expect("invalid index");
5052 if (tok == TOK_DOTS && gnu_ext) {
5053 next();
5054 index_last = expr_const();
5055 if (index_last < 0 ||
5056 (s->c >= 0 && index_last >= s->c) ||
5057 index_last < index)
5058 expect("invalid index");
5059 } else {
5060 index_last = index;
5062 skip(']');
5063 if (!notfirst)
5064 *cur_index = index_last;
5065 type = pointed_type(type);
5066 elem_size = type_size(type, &align);
5067 c += index * elem_size;
5068 /* NOTE: we only support ranges for last designator */
5069 nb_elems = index_last - index + 1;
5070 if (nb_elems != 1) {
5071 notfirst = 1;
5072 break;
5074 } else {
5075 next();
5076 l = tok;
5077 next();
5078 struct_field:
5079 if ((type->t & VT_BTYPE) != VT_STRUCT)
5080 expect("struct/union type");
5081 l |= SYM_FIELD;
5082 f = s->next;
5083 while (f) {
5084 if (f->v == l)
5085 break;
5086 f = f->next;
5088 if (!f)
5089 expect("field");
5090 if (!notfirst)
5091 *cur_field = f;
5092 /* XXX: fix this mess by using explicit storage field */
5093 type1 = f->type;
5094 type1.t |= (type->t & ~VT_TYPE);
5095 type = &type1;
5096 c += f->c;
5098 notfirst = 1;
5100 if (notfirst) {
5101 if (tok == '=') {
5102 next();
5103 } else {
5104 if (!gnu_ext)
5105 expect("=");
5107 } else {
5108 if (type->t & VT_ARRAY) {
5109 index = *cur_index;
5110 if (s->c >= 0 && index >= s->c){
5111 if(!size_only)
5112 tcc_warning("excess elements in array initializer");
5113 type = NULL;
5114 size_only = 1;
5115 }else{
5116 type = pointed_type(type);
5117 c += index * type_size(type, &align);
5119 } else {
5120 f = *cur_field;
5121 if (f){
5122 /* XXX: fix this mess by using explicit storage field */
5123 type1 = f->type;
5124 type1.t |= (type->t & ~VT_TYPE);
5125 type = &type1;
5126 c += f->c;
5127 }else{
5128 if(!size_only)
5129 tcc_warning("excess elements in %s initializer",
5130 get_tok_str(s->type.t, NULL));
5131 type = NULL;
5132 size_only = 1;
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)
5294 goto Ignore;
5295 if (type->t & VT_VLA) {
5296 int a;
5298 /* save current stack pointer */
5299 if (vla_flags & VLA_NEED_NEW_FRAME) {
5300 vla_sp_save();
5301 vla_flags = VLA_IN_SCOPE;
5302 vla_sp_loc = &vla_sp_loc_tmp;
5305 vla_runtime_type_size(type, &a);
5306 gen_vla_alloc(type, a);
5307 vset(type, VT_LOCAL|VT_LVAL, c);
5308 vswap();
5309 vstore();
5310 vpop();
5311 } else if (type->t & VT_ARRAY) {
5312 s = type->ref;
5313 n = s->c;
5314 array_length = 0;
5315 t1 = pointed_type(type);
5316 size1 = type_size(t1, &align1);
5318 no_oblock = 1;
5319 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5320 tok == '{') {
5321 if (tok != '{')
5322 tcc_error("character array initializer must be a literal,"
5323 " optionally enclosed in braces");
5324 skip('{');
5325 no_oblock = 0;
5328 /* only parse strings here if correct type (otherwise: handle
5329 them as ((w)char *) expressions */
5330 if ((tok == TOK_LSTR &&
5331 #ifdef TCC_TARGET_PE
5332 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5333 #else
5334 (t1->t & VT_BTYPE) == VT_INT
5335 #endif
5336 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5337 while (tok == TOK_STR || tok == TOK_LSTR) {
5338 int cstr_len, ch;
5339 CString *cstr;
5341 cstr = tokc.cstr;
5342 /* compute maximum number of chars wanted */
5343 if (tok == TOK_STR)
5344 cstr_len = cstr->size;
5345 else
5346 cstr_len = cstr->size / sizeof(nwchar_t);
5347 cstr_len--;
5348 nb = cstr_len;
5349 if (n >= 0 && nb > (n - array_length))
5350 nb = n - array_length;
5351 if (!size_only) {
5352 if (cstr_len > nb)
5353 tcc_warning("initializer-string for array is too long");
5354 /* in order to go faster for common case (char
5355 string in global variable, we handle it
5356 specifically */
5357 if (sec && tok == TOK_STR && size1 == 1) {
5358 memcpy(sec->data + c + array_length, cstr->data, nb);
5359 } else {
5360 for(i=0;i<nb;i++) {
5361 if (tok == TOK_STR)
5362 ch = ((unsigned char *)cstr->data)[i];
5363 else
5364 ch = ((nwchar_t *)cstr->data)[i];
5365 init_putv(t1, sec, c + (array_length + i) * size1,
5366 ch, EXPR_VAL);
5370 array_length += nb;
5371 next();
5373 /* only add trailing zero if enough storage (no
5374 warning in this case since it is standard) */
5375 if (n < 0 || array_length < n) {
5376 if (!size_only) {
5377 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5379 array_length++;
5381 } else {
5382 index = 0;
5383 while (tok != '}') {
5384 decl_designator(type, sec, c, &index, NULL, size_only);
5385 /* must put zero in holes (note that doing it that way
5386 ensures that it even works with designators) */
5387 if (!is_putz && array_length < index)
5388 is_putz = 1;
5389 index++;
5390 if (index > array_length)
5391 array_length = index;
5392 /* special test for multi dimensional arrays (may not
5393 be strictly correct if designators are used at the
5394 same time) */
5395 if (index >= n && no_oblock)
5396 break;
5397 if (tok == '}')
5398 break;
5399 skip(',');
5402 if (!no_oblock)
5403 skip('}');
5404 /* put zeros at the end */
5405 if (!is_putz && n >= 0 && array_length < n)
5406 is_putz = 1;
5407 /* patch type size if needed */
5408 if (n < 0)
5409 s->c = array_length;
5410 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5411 (sec || !first || tok == '{')) {
5412 int par_count;
5414 /* NOTE: the previous test is a specific case for automatic
5415 struct/union init */
5416 /* XXX: union needs only one init */
5418 /* XXX: this test is incorrect for local initializers
5419 beginning with ( without {. It would be much more difficult
5420 to do it correctly (ideally, the expression parser should
5421 be used in all cases) */
5422 par_count = 0;
5423 if (tok == '(') {
5424 AttributeDef ad1;
5425 CType type1;
5426 next();
5427 while (tok == '(') {
5428 par_count++;
5429 next();
5431 if (!parse_btype(&type1, &ad1))
5432 expect("cast");
5433 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5434 #if 0
5435 if (!is_assignable_types(type, &type1))
5436 tcc_error("invalid type for cast");
5437 #endif
5438 skip(')');
5440 no_oblock = 1;
5441 if (first || tok == '{') {
5442 skip('{');
5443 no_oblock = 0;
5445 s = type->ref;
5446 f = s->next;
5447 array_length = 0;
5448 index = 0;
5449 n = s->c;
5450 while (tok != '}') {
5451 decl_designator(type, sec, c, NULL, &f, size_only);
5452 if(f){
5453 index = f->c;
5454 if (!is_putz && array_length < index)
5455 is_putz = 1;
5456 index = index + type_size(&f->type, &align1);
5457 if (index > array_length)
5458 array_length = index;
5460 /* gr: skip fields from same union - ugly. */
5461 while (f->next) {
5462 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5463 /* test for same offset */
5464 if (f->next->c != f->c)
5465 break;
5466 /* if yes, test for bitfield shift */
5467 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5468 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5469 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5470 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5471 if (bit_pos_1 != bit_pos_2)
5472 break;
5474 f = f->next;
5477 f = f->next;
5478 if (no_oblock && f == NULL)
5479 break;
5481 if (tok == '}')
5482 break;
5483 skip(',');
5485 if (!no_oblock)
5486 skip('}');
5487 /* put zeros at the end */
5488 if (!is_putz && array_length < n)
5489 is_putz = 1;
5490 while (par_count) {
5491 skip(')');
5492 par_count--;
5494 } else if (tok == '{') {
5495 next();
5496 decl_initializer(type, sec, c, first, size_only);
5497 skip('}');
5498 } else if (size_only) {
5499 Ignore:
5500 /* just skip expression */
5501 parlevel = parlevel1 = 0;
5502 while ((parlevel > 0 || parlevel1 > 0 ||
5503 (tok != '}' && tok != ',')) && tok != -1) {
5504 if (tok == '(')
5505 parlevel++;
5506 else if (tok == ')')
5507 parlevel--;
5508 else if (tok == '{')
5509 parlevel1++;
5510 else if (tok == '}')
5511 parlevel1--;
5512 next();
5514 } else {
5515 /* currently, we always use constant expression for globals
5516 (may change for scripting case) */
5517 expr_type = EXPR_CONST;
5518 if (!sec)
5519 expr_type = EXPR_ANY;
5520 init_putv(type, sec, c, 0, expr_type);
5524 /* parse an initializer for type 't' if 'has_init' is non zero, and
5525 allocate space in local or global data space ('r' is either
5526 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5527 variable 'v' with an associated name represented by 'asm_label' of
5528 scope 'scope' is declared before initializers are parsed. If 'v' is
5529 zero, then a reference to the new object is put in the value stack.
5530 If 'has_init' is 2, a special parsing is done to handle string
5531 constants. */
5532 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5533 int has_init, int v, char *asm_label,
5534 int scope)
5536 int size, align, addr, data_offset;
5537 int level;
5538 ParseState saved_parse_state = {0};
5539 TokenString init_str;
5540 Section *sec;
5541 Sym *flexible_array;
5543 flexible_array = NULL;
5544 is_putz = 0;
5545 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5546 Sym *field = type->ref->next;
5547 if (field) {
5548 while (field->next)
5549 field = field->next;
5550 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5551 flexible_array = field;
5555 size = type_size(type, &align);
5556 /* If unknown size, we must evaluate it before
5557 evaluating initializers because
5558 initializers can generate global data too
5559 (e.g. string pointers or ISOC99 compound
5560 literals). It also simplifies local
5561 initializers handling */
5562 tok_str_new(&init_str);
5563 if (size < 0 || ((((type->t & VT_BTYPE) == VT_STRUCT) || (type->t & VT_ARRAY)) &&
5564 has_init && (tok < TOK_IDENT))){
5565 if (!has_init)
5566 tcc_error("unknown type size");
5567 /* get all init string */
5568 if (has_init == 2) {
5569 /* only get strings */
5570 while (tok == TOK_STR || tok == TOK_LSTR) {
5571 tok_str_add_tok(&init_str);
5572 next();
5574 } else {
5575 level = 0;
5576 while (level > 0 || (tok != ',' && tok != ';')) {
5577 if (tok < 0)
5578 tcc_error("unexpected end of file in initializer");
5579 tok_str_add_tok(&init_str);
5580 if (tok == '{')
5581 level++;
5582 else if (tok == '}') {
5583 level--;
5584 if (level <= 0) {
5585 next();
5586 break;
5589 next();
5592 tok_str_add(&init_str, -1);
5593 tok_str_add(&init_str, 0);
5595 /* compute size */
5596 save_parse_state(&saved_parse_state);
5598 macro_ptr = init_str.str;
5599 next();
5600 decl_initializer(type, NULL, 0, 1, 1);
5601 /* prepare second initializer parsing */
5602 macro_ptr = init_str.str;
5603 next();
5605 /* if still unknown size, error */
5606 size = type_size(type, &align);
5607 if (size < 0)
5608 tcc_error("unknown type size");
5610 if (flexible_array)
5611 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5612 /* take into account specified alignment if bigger */
5613 if (ad->a.aligned) {
5614 if (ad->a.aligned > align)
5615 align = ad->a.aligned;
5616 } else if (ad->a.packed) {
5617 align = 1;
5619 if ((r & VT_VALMASK) == VT_LOCAL) {
5620 sec = NULL;
5621 #ifdef CONFIG_TCC_BCHECK
5622 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5623 loc--;
5625 #endif
5626 loc = (loc - size) & -align;
5627 addr = loc;
5628 #ifdef CONFIG_TCC_BCHECK
5629 /* handles bounds */
5630 /* XXX: currently, since we do only one pass, we cannot track
5631 '&' operators, so we add only arrays */
5632 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5633 unsigned long *bounds_ptr;
5634 /* add padding between regions */
5635 loc--;
5636 /* then add local bound info */
5637 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5638 bounds_ptr[0] = addr;
5639 bounds_ptr[1] = size;
5641 #endif
5642 if (v) {
5643 /* local variable */
5644 sym_push(v, type, r, addr);
5645 } else {
5646 /* push local reference */
5647 vset(type, r, addr);
5649 } else {
5650 Sym *sym;
5652 sym = NULL;
5653 if (v && scope == VT_CONST) {
5654 /* see if the symbol was already defined */
5655 sym = sym_find(v);
5656 if (sym) {
5657 if (!is_compatible_types(&sym->type, type))
5658 tcc_error("incompatible types for redefinition of '%s'",
5659 get_tok_str(v, NULL));
5660 if (sym->type.t & VT_EXTERN) {
5661 /* if the variable is extern, it was not allocated */
5662 sym->type.t &= ~VT_EXTERN;
5663 /* set array size if it was omitted in extern
5664 declaration */
5665 if ((sym->type.t & VT_ARRAY) &&
5666 sym->type.ref->c < 0 &&
5667 type->ref->c >= 0)
5668 sym->type.ref->c = type->ref->c;
5669 } else {
5670 /* we accept several definitions of the same
5671 global variable. this is tricky, because we
5672 must play with the SHN_COMMON type of the symbol */
5673 /* XXX: should check if the variable was already
5674 initialized. It is incorrect to initialized it
5675 twice */
5676 /* no init data, we won't add more to the symbol */
5677 if (!has_init)
5678 goto no_alloc;
5683 /* allocate symbol in corresponding section */
5684 sec = ad->section;
5685 if (!sec) {
5686 if (has_init)
5687 sec = data_section;
5688 else if (tcc_state->nocommon)
5689 sec = bss_section;
5691 if (sec) {
5692 data_offset = sec->data_offset;
5693 data_offset = (data_offset + align - 1) & -align;
5694 addr = data_offset;
5695 /* very important to increment global pointer at this time
5696 because initializers themselves can create new initializers */
5697 data_offset += size;
5698 #ifdef CONFIG_TCC_BCHECK
5699 /* add padding if bound check */
5700 if (tcc_state->do_bounds_check)
5701 data_offset++;
5702 #endif
5703 sec->data_offset = data_offset;
5704 /* allocate section space to put the data */
5705 if (sec->sh_type != SHT_NOBITS &&
5706 data_offset > sec->data_allocated)
5707 section_realloc(sec, data_offset);
5708 /* align section if needed */
5709 if (align > sec->sh_addralign)
5710 sec->sh_addralign = align;
5711 } else {
5712 addr = 0; /* avoid warning */
5715 if (v) {
5716 if (scope != VT_CONST || !sym) {
5717 sym = sym_push(v, type, r | VT_SYM, 0);
5718 sym->asm_label = asm_label;
5720 /* update symbol definition */
5721 if (sec) {
5722 put_extern_sym(sym, sec, addr, size);
5723 } else {
5724 ElfW(Sym) *esym;
5725 /* put a common area */
5726 put_extern_sym(sym, NULL, align, size);
5727 /* XXX: find a nicer way */
5728 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5729 esym->st_shndx = SHN_COMMON;
5731 } else {
5732 /* push global reference */
5733 sym = get_sym_ref(type, sec, addr, size);
5734 vpushsym(type, sym);
5736 /* patch symbol weakness */
5737 if (type->t & VT_WEAK)
5738 weaken_symbol(sym);
5739 apply_visibility(sym, type);
5740 #ifdef CONFIG_TCC_BCHECK
5741 /* handles bounds now because the symbol must be defined
5742 before for the relocation */
5743 if (tcc_state->do_bounds_check) {
5744 unsigned long *bounds_ptr;
5746 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5747 /* then add global bound info */
5748 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5749 bounds_ptr[0] = 0; /* relocated */
5750 bounds_ptr[1] = size;
5752 #endif
5754 if (has_init || (type->t & VT_VLA)) {
5755 if(is_putz)
5756 init_putz(type, sec, addr, size);
5757 decl_initializer(type, sec, addr, 1, 0);
5758 /* restore parse state if needed */
5759 if (init_str.str) {
5760 tok_str_free(init_str.str);
5761 restore_parse_state(&saved_parse_state);
5763 /* patch flexible array member size back to -1, */
5764 /* for possible subsequent similar declarations */
5765 if (flexible_array)
5766 flexible_array->type.ref->c = -1;
5768 no_alloc: ;
5771 static void put_func_debug(Sym *sym)
5773 char buf[512];
5775 /* stabs info */
5776 /* XXX: we put here a dummy type */
5777 snprintf(buf, sizeof(buf), "%s:%c1",
5778 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5779 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5780 cur_text_section, sym->c);
5781 /* //gr gdb wants a line at the function */
5782 put_stabn(N_SLINE, 0, file->line_num, 0);
5783 last_ind = 0;
5784 last_line_num = 0;
5787 /* parse an old style function declaration list */
5788 /* XXX: check multiple parameter */
5789 static void func_decl_list(Sym *func_sym)
5791 AttributeDef ad;
5792 int v;
5793 Sym *s;
5794 CType btype, type;
5796 /* parse each declaration */
5797 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5798 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5799 if (!parse_btype(&btype, &ad))
5800 expect("declaration list");
5801 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5802 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5803 tok == ';') {
5804 /* we accept no variable after */
5805 } else {
5806 for(;;) {
5807 type = btype;
5808 type_decl(&type, &ad, &v, TYPE_DIRECT);
5809 /* find parameter in function parameter list */
5810 s = func_sym->next;
5811 while (s != NULL) {
5812 if ((s->v & ~SYM_FIELD) == v)
5813 goto found;
5814 s = s->next;
5816 tcc_error("declaration for parameter '%s' but no such parameter",
5817 get_tok_str(v, NULL));
5818 found:
5819 /* check that no storage specifier except 'register' was given */
5820 if (type.t & VT_STORAGE)
5821 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5822 convert_parameter_type(&type);
5823 /* we can add the type (NOTE: it could be local to the function) */
5824 s->type = type;
5825 /* accept other parameters */
5826 if (tok == ',')
5827 next();
5828 else
5829 break;
5832 skip(';');
5836 /* parse a function defined by symbol 'sym' and generate its code in
5837 'cur_text_section' */
5838 static void gen_function(Sym *sym)
5840 int saved_nocode_wanted = nocode_wanted;
5841 nocode_wanted = 0;
5842 ind = cur_text_section->data_offset;
5843 /* NOTE: we patch the symbol size later */
5844 put_extern_sym(sym, cur_text_section, ind, 0);
5845 funcname = get_tok_str(sym->v, NULL);
5846 func_ind = ind;
5847 /* Initialize VLA state */
5848 vla_sp_loc = &vla_sp_root_loc;
5849 vla_flags = VLA_NEED_NEW_FRAME;
5850 /* put debug symbol */
5851 if (tcc_state->do_debug)
5852 put_func_debug(sym);
5853 /* push a dummy symbol to enable local sym storage */
5854 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5855 gfunc_prolog(&sym->type);
5856 #ifdef CONFIG_TCC_BCHECK
5857 if (tcc_state->do_bounds_check
5858 && !strcmp(get_tok_str(sym->v, NULL), "main")) {
5859 int i;
5861 sym = local_stack;
5862 for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) {
5863 if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD)
5864 break;
5865 vpush_global_sym(&func_old_type, TOK___bound_main_arg);
5866 vset(&sym->type, sym->r, sym->c);
5867 gfunc_call(1);
5870 #endif
5871 rsym = 0;
5872 block(NULL, NULL, NULL, NULL, 0, 0);
5873 gsym(rsym);
5874 gfunc_epilog();
5875 cur_text_section->data_offset = ind;
5876 label_pop(&global_label_stack, NULL);
5877 /* reset local stack */
5878 scope_stack_bottom = NULL;
5879 sym_pop(&local_stack, NULL);
5880 /* end of function */
5881 /* patch symbol size */
5882 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5883 ind - func_ind;
5884 /* patch symbol weakness (this definition overrules any prototype) */
5885 if (sym->type.t & VT_WEAK)
5886 weaken_symbol(sym);
5887 apply_visibility(sym, &sym->type);
5888 if (tcc_state->do_debug) {
5889 put_stabn(N_FUN, 0, 0, ind - func_ind);
5891 /* It's better to crash than to generate wrong code */
5892 cur_text_section = NULL;
5893 funcname = ""; /* for safety */
5894 func_vt.t = VT_VOID; /* for safety */
5895 func_var = 0; /* for safety */
5896 ind = 0; /* for safety */
5897 nocode_wanted = saved_nocode_wanted;
5900 ST_FUNC void gen_inline_functions(void)
5902 Sym *sym;
5903 int *str, inline_generated, i;
5904 struct InlineFunc *fn;
5906 /* iterate while inline function are referenced */
5907 for(;;) {
5908 inline_generated = 0;
5909 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5910 fn = tcc_state->inline_fns[i];
5911 sym = fn->sym;
5912 if (sym && sym->c) {
5913 /* the function was used: generate its code and
5914 convert it to a normal function */
5915 str = fn->token_str;
5916 fn->sym = NULL;
5917 if (file)
5918 pstrcpy(file->filename, sizeof file->filename, fn->filename);
5919 sym->r = VT_SYM | VT_CONST;
5920 sym->type.t &= ~VT_INLINE;
5922 macro_ptr = str;
5923 next();
5924 cur_text_section = text_section;
5925 gen_function(sym);
5926 macro_ptr = NULL; /* fail safe */
5928 inline_generated = 1;
5931 if (!inline_generated)
5932 break;
5934 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5935 fn = tcc_state->inline_fns[i];
5936 str = fn->token_str;
5937 tok_str_free(str);
5939 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5942 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5943 static int decl0(int l, int is_for_loop_init)
5945 int v, has_init, r;
5946 CType type, btype;
5947 Sym *sym;
5948 AttributeDef ad;
5950 while (1) {
5951 if (!parse_btype(&btype, &ad)) {
5952 if (is_for_loop_init)
5953 return 0;
5954 /* skip redundant ';' */
5955 /* XXX: find more elegant solution */
5956 if (tok == ';') {
5957 next();
5958 continue;
5960 if (l == VT_CONST &&
5961 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5962 /* global asm block */
5963 asm_global_instr();
5964 continue;
5966 /* special test for old K&R protos without explicit int
5967 type. Only accepted when defining global data */
5968 if (l == VT_LOCAL || tok < TOK_DEFINE)
5969 break;
5970 btype.t = VT_INT;
5972 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5973 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5974 tok == ';') {
5975 /* we accept no variable after */
5976 next();
5977 continue;
5979 while (1) { /* iterate thru each declaration */
5980 char *asm_label; // associated asm label
5981 type = btype;
5982 type_decl(&type, &ad, &v, TYPE_DIRECT);
5983 #if 0
5985 char buf[500];
5986 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5987 printf("type = '%s'\n", buf);
5989 #endif
5990 if ((type.t & VT_BTYPE) == VT_FUNC) {
5991 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5992 tcc_error("function without file scope cannot be static");
5994 /* if old style function prototype, we accept a
5995 declaration list */
5996 sym = type.ref;
5997 if (sym->c == FUNC_OLD)
5998 func_decl_list(sym);
6001 asm_label = NULL;
6002 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6003 CString astr;
6005 asm_label_instr(&astr);
6006 asm_label = tcc_strdup(astr.data);
6007 cstr_free(&astr);
6009 /* parse one last attribute list, after asm label */
6010 parse_attribute(&ad);
6013 if (ad.a.weak)
6014 type.t |= VT_WEAK;
6015 #ifdef TCC_TARGET_PE
6016 if (ad.a.func_import)
6017 type.t |= VT_IMPORT;
6018 if (ad.a.func_export)
6019 type.t |= VT_EXPORT;
6020 #endif
6021 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6023 if (tok == '{') {
6024 if (l == VT_LOCAL)
6025 tcc_error("cannot use local functions");
6026 if ((type.t & VT_BTYPE) != VT_FUNC)
6027 expect("function definition");
6029 /* reject abstract declarators in function definition */
6030 sym = type.ref;
6031 while ((sym = sym->next) != NULL)
6032 if (!(sym->v & ~SYM_FIELD))
6033 expect("identifier");
6035 /* XXX: cannot do better now: convert extern line to static inline */
6036 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6037 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6039 sym = sym_find(v);
6040 if (sym) {
6041 Sym *ref;
6042 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6043 goto func_error1;
6045 ref = sym->type.ref;
6046 if (0 == ref->a.func_proto)
6047 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6049 /* use func_call from prototype if not defined */
6050 if (ref->a.func_call != FUNC_CDECL
6051 && type.ref->a.func_call == FUNC_CDECL)
6052 type.ref->a.func_call = ref->a.func_call;
6054 /* use export from prototype */
6055 if (ref->a.func_export)
6056 type.ref->a.func_export = 1;
6058 /* use static from prototype */
6059 if (sym->type.t & VT_STATIC)
6060 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6062 /* If the definition has no visibility use the
6063 one from prototype. */
6064 if (! (type.t & VT_VIS_MASK))
6065 type.t |= sym->type.t & VT_VIS_MASK;
6067 if (!is_compatible_types(&sym->type, &type)) {
6068 func_error1:
6069 tcc_error("incompatible types for redefinition of '%s'",
6070 get_tok_str(v, NULL));
6072 type.ref->a.func_proto = 0;
6073 /* if symbol is already defined, then put complete type */
6074 sym->type = type;
6075 } else {
6076 /* put function symbol */
6077 sym = global_identifier_push(v, type.t, 0);
6078 sym->type.ref = type.ref;
6081 /* static inline functions are just recorded as a kind
6082 of macro. Their code will be emitted at the end of
6083 the compilation unit only if they are used */
6084 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6085 (VT_INLINE | VT_STATIC)) {
6086 TokenString func_str;
6087 int block_level;
6088 struct InlineFunc *fn;
6089 const char *filename;
6091 tok_str_new(&func_str);
6093 block_level = 0;
6094 for(;;) {
6095 int t;
6096 if (tok == TOK_EOF)
6097 tcc_error("unexpected end of file");
6098 tok_str_add_tok(&func_str);
6099 t = tok;
6100 next();
6101 if (t == '{') {
6102 block_level++;
6103 } else if (t == '}') {
6104 block_level--;
6105 if (block_level == 0)
6106 break;
6109 tok_str_add(&func_str, -1);
6110 tok_str_add(&func_str, 0);
6111 filename = file ? file->filename : "";
6112 fn = tcc_malloc(sizeof *fn + strlen(filename));
6113 strcpy(fn->filename, filename);
6114 fn->sym = sym;
6115 fn->token_str = func_str.str;
6116 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6118 } else {
6119 /* compute text section */
6120 cur_text_section = ad.section;
6121 if (!cur_text_section)
6122 cur_text_section = text_section;
6123 sym->r = VT_SYM | VT_CONST;
6124 gen_function(sym);
6126 break;
6127 } else {
6128 if (btype.t & VT_TYPEDEF) {
6129 /* save typedefed type */
6130 /* XXX: test storage specifiers ? */
6131 sym = sym_push(v, &type, 0, 0);
6132 sym->a = ad.a;
6133 sym->type.t |= VT_TYPEDEF;
6134 } else {
6135 r = 0;
6136 if ((type.t & VT_BTYPE) == VT_FUNC) {
6137 /* external function definition */
6138 /* specific case for func_call attribute */
6139 ad.a.func_proto = 1;
6140 type.ref->a = ad.a;
6141 } else if (!(type.t & VT_ARRAY)) {
6142 /* not lvalue if array */
6143 r |= lvalue_type(type.t);
6145 has_init = (tok == '=');
6146 if (has_init && (type.t & VT_VLA))
6147 tcc_error("Variable length array cannot be initialized");
6148 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6149 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6150 !has_init && l == VT_CONST && type.ref->c < 0)) {
6151 /* external variable or function */
6152 /* NOTE: as GCC, uninitialized global static
6153 arrays of null size are considered as
6154 extern */
6155 sym = external_sym(v, &type, r, asm_label);
6157 if (ad.alias_target) {
6158 Section tsec;
6159 Elf32_Sym *esym;
6160 Sym *alias_target;
6162 alias_target = sym_find(ad.alias_target);
6163 if (!alias_target || !alias_target->c)
6164 tcc_error("unsupported forward __alias__ attribute");
6165 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6166 tsec.sh_num = esym->st_shndx;
6167 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6169 } else {
6170 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6171 if (type.t & VT_STATIC)
6172 r |= VT_CONST;
6173 else
6174 r |= l;
6175 if (has_init)
6176 next();
6177 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
6180 if (tok != ',') {
6181 if (is_for_loop_init)
6182 return 1;
6183 skip(';');
6184 break;
6186 next();
6188 ad.a.aligned = 0;
6191 return 0;
6194 ST_FUNC void decl(int l)
6196 decl0(l, 0);