Considering the effect of CH_EOF on line_num
[tinycc.git] / tccgen.c
blobd286dd47ddef74b121d632c5cf416b0a3b5db232
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_force;
95 ST_FUNC void vpush64(int ty, unsigned long long v);
96 ST_FUNC void vpush(CType *type);
97 ST_FUNC int gvtst(int inv, int t);
98 ST_FUNC int is_btype_size(int bt);
100 ST_INLN int is_float(int t)
102 int bt;
103 bt = t & VT_BTYPE;
104 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
107 /* we use our own 'finite' function to avoid potential problems with
108 non standard math libs */
109 /* XXX: endianness dependent */
110 ST_FUNC int ieee_finite(double d)
112 int p[4];
113 memcpy(p, &d, sizeof(double));
114 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
117 ST_FUNC void test_lvalue(void)
119 if (!(vtop->r & VT_LVAL))
120 expect("lvalue");
123 /* ------------------------------------------------------------------------- */
124 /* symbol allocator */
125 static Sym *__sym_malloc(void)
127 Sym *sym_pool, *sym, *last_sym;
128 int i;
130 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
131 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
133 last_sym = sym_free_first;
134 sym = sym_pool;
135 for(i = 0; i < SYM_POOL_NB; i++) {
136 sym->next = last_sym;
137 last_sym = sym;
138 sym++;
140 sym_free_first = last_sym;
141 return last_sym;
144 static inline Sym *sym_malloc(void)
146 Sym *sym;
147 sym = sym_free_first;
148 if (!sym)
149 sym = __sym_malloc();
150 sym_free_first = sym->next;
151 return sym;
154 ST_INLN void sym_free(Sym *sym)
156 sym->next = sym_free_first;
157 tcc_free(sym->asm_label);
158 sym_free_first = sym;
161 /* push, without hashing */
162 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
164 Sym *s;
165 if (ps == &local_stack) {
166 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
167 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
168 tcc_error("incompatible types for redefinition of '%s'",
169 get_tok_str(v, NULL));
171 s = sym_malloc();
172 s->asm_label = NULL;
173 s->v = v;
174 s->type.t = t;
175 s->type.ref = NULL;
176 #ifdef _WIN64
177 s->d = NULL;
178 #endif
179 s->c = c;
180 s->next = NULL;
181 /* add in stack */
182 s->prev = *ps;
183 *ps = s;
184 return s;
187 /* find a symbol and return its associated structure. 's' is the top
188 of the symbol stack */
189 ST_FUNC Sym *sym_find2(Sym *s, int v)
191 while (s) {
192 if (s->v == v)
193 return s;
194 else if (s->v == -1)
195 return NULL;
196 s = s->prev;
198 return NULL;
201 /* structure lookup */
202 ST_INLN Sym *struct_find(int v)
204 v -= TOK_IDENT;
205 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
206 return NULL;
207 return table_ident[v]->sym_struct;
210 /* find an identifier */
211 ST_INLN Sym *sym_find(int v)
213 v -= TOK_IDENT;
214 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
215 return NULL;
216 return table_ident[v]->sym_identifier;
219 /* push a given symbol on the symbol stack */
220 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
222 Sym *s, **ps;
223 TokenSym *ts;
225 if (local_stack)
226 ps = &local_stack;
227 else
228 ps = &global_stack;
229 s = sym_push2(ps, v, type->t, c);
230 s->type.ref = type->ref;
231 s->r = r;
232 /* don't record fields or anonymous symbols */
233 /* XXX: simplify */
234 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
235 /* record symbol in token array */
236 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
237 if (v & SYM_STRUCT)
238 ps = &ts->sym_struct;
239 else
240 ps = &ts->sym_identifier;
241 s->prev_tok = *ps;
242 *ps = s;
244 return s;
247 /* push a global identifier */
248 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
250 Sym *s, **ps;
251 s = sym_push2(&global_stack, v, t, c);
252 /* don't record anonymous symbol */
253 if (v < SYM_FIRST_ANOM) {
254 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
255 /* modify the top most local identifier, so that
256 sym_identifier will point to 's' when popped */
257 while (*ps != NULL)
258 ps = &(*ps)->prev_tok;
259 s->prev_tok = NULL;
260 *ps = s;
262 return s;
265 /* pop symbols until top reaches 'b' */
266 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
268 Sym *s, *ss, **ps;
269 TokenSym *ts;
270 int v;
272 s = *ptop;
273 while(s != b) {
274 ss = s->prev;
275 v = s->v;
276 /* remove symbol in token array */
277 /* XXX: simplify */
278 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
279 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
280 if (v & SYM_STRUCT)
281 ps = &ts->sym_struct;
282 else
283 ps = &ts->sym_identifier;
284 *ps = s->prev_tok;
286 sym_free(s);
287 s = ss;
289 *ptop = b;
292 static void weaken_symbol(Sym *sym)
294 sym->type.t |= VT_WEAK;
295 if (sym->c > 0) {
296 int esym_type;
297 ElfW(Sym) *esym;
299 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
300 esym_type = ELFW(ST_TYPE)(esym->st_info);
301 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
305 static void apply_visibility(Sym *sym, CType *type)
307 int vis = sym->type.t & VT_VIS_MASK;
308 int vis2 = type->t & VT_VIS_MASK;
309 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
310 vis = vis2;
311 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
313 else
314 vis = (vis < vis2) ? vis : vis2;
315 sym->type.t &= ~VT_VIS_MASK;
316 sym->type.t |= vis;
318 if (sym->c > 0) {
319 ElfW(Sym) *esym;
321 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
322 vis >>= VT_VIS_SHIFT;
323 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
327 /* ------------------------------------------------------------------------- */
329 ST_FUNC void swap(int *p, int *q)
331 int t;
332 t = *p;
333 *p = *q;
334 *q = t;
337 static void vsetc(CType *type, int r, CValue *vc)
339 int v;
341 if (vtop >= vstack + (VSTACK_SIZE - 1))
342 tcc_error("memory full (vstack)");
343 /* cannot let cpu flags if other instruction are generated. Also
344 avoid leaving VT_JMP anywhere except on the top of the stack
345 because it would complicate the code generator. */
346 if (vtop >= vstack) {
347 v = vtop->r & VT_VALMASK;
348 if (v == VT_CMP || (v & ~1) == VT_JMP)
349 gv(RC_INT);
351 vtop++;
352 vtop->type = *type;
353 vtop->r = r;
354 vtop->r2 = VT_CONST;
355 vtop->c = *vc;
358 /* push constant of type "type" with useless value */
359 ST_FUNC void vpush(CType *type)
361 CValue cval;
362 vsetc(type, VT_CONST, &cval);
365 /* push integer constant */
366 ST_FUNC void vpushi(int v)
368 CValue cval;
369 cval.i = v;
370 vsetc(&int_type, VT_CONST, &cval);
373 /* push a pointer sized constant */
374 static void vpushs(addr_t v)
376 CValue cval;
377 cval.ptr_offset = v;
378 vsetc(&size_type, VT_CONST, &cval);
381 /* push arbitrary 64bit constant */
382 ST_FUNC void vpush64(int ty, unsigned long long v)
384 CValue cval;
385 CType ctype;
386 ctype.t = ty;
387 ctype.ref = NULL;
388 cval.ull = v;
389 vsetc(&ctype, VT_CONST, &cval);
392 /* push long long constant */
393 static inline void vpushll(long long v)
395 vpush64(VT_LLONG, v);
398 /* push a symbol value of TYPE */
399 static inline void vpushsym(CType *type, Sym *sym)
401 CValue cval;
402 cval.ptr_offset = 0;
403 vsetc(type, VT_CONST | VT_SYM, &cval);
404 vtop->sym = sym;
407 /* Return a static symbol pointing to a section */
408 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
410 int v;
411 Sym *sym;
413 v = anon_sym++;
414 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
415 sym->type.ref = type->ref;
416 sym->r = VT_CONST | VT_SYM;
417 put_extern_sym(sym, sec, offset, size);
418 return sym;
421 /* push a reference to a section offset by adding a dummy symbol */
422 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
424 vpushsym(type, get_sym_ref(type, sec, offset, size));
427 /* define a new external reference to a symbol 'v' of type 'u' */
428 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
430 Sym *s;
432 s = sym_find(v);
433 if (!s) {
434 /* push forward reference */
435 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
436 s->type.ref = type->ref;
437 s->r = r | VT_CONST | VT_SYM;
439 return s;
442 /* define a new external reference to a symbol 'v' with alternate asm
443 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
444 is no alternate name (most cases) */
445 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
447 Sym *s;
449 s = sym_find(v);
450 if (!s) {
451 /* push forward reference */
452 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
453 s->asm_label = asm_label;
454 s->type.t |= VT_EXTERN;
455 } else if (s->type.ref == func_old_type.ref) {
456 s->type.ref = type->ref;
457 s->r = r | VT_CONST | VT_SYM;
458 s->type.t |= VT_EXTERN;
459 } else if (!is_compatible_types(&s->type, type)) {
460 tcc_error("incompatible types for redefinition of '%s'",
461 get_tok_str(v, NULL));
463 /* Merge some storage attributes. */
464 if (type->t & VT_WEAK)
465 weaken_symbol(s);
467 if (type->t & VT_VIS_MASK)
468 apply_visibility(s, type);
470 return s;
473 /* push a reference to global symbol v */
474 ST_FUNC void vpush_global_sym(CType *type, int v)
476 vpushsym(type, external_global_sym(v, type, 0));
479 ST_FUNC void vset(CType *type, int r, int v)
481 CValue cval;
483 cval.i = v;
484 vsetc(type, r, &cval);
487 static void vseti(int r, int v)
489 CType type;
490 type.t = VT_INT;
491 type.ref = 0;
492 vset(&type, r, v);
495 ST_FUNC void vswap(void)
497 SValue tmp;
498 /* cannot let cpu flags if other instruction are generated. Also
499 avoid leaving VT_JMP anywhere except on the top of the stack
500 because it would complicate the code generator. */
501 if (vtop >= vstack) {
502 int v = vtop->r & VT_VALMASK;
503 if (v == VT_CMP || (v & ~1) == VT_JMP)
504 gv(RC_INT);
506 tmp = vtop[0];
507 vtop[0] = vtop[-1];
508 vtop[-1] = tmp;
510 /* XXX: +2% overall speed possible with optimized memswap
512 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
516 ST_FUNC void vpushv(SValue *v)
518 if (vtop >= vstack + (VSTACK_SIZE - 1))
519 tcc_error("memory full (vstack)");
520 vtop++;
521 *vtop = *v;
524 static void vdup(void)
526 vpushv(vtop);
529 /* save r to the memory stack, and mark it as being free */
530 ST_FUNC void save_reg(int r)
532 int l, saved, size, align;
533 SValue *p, sv;
534 CType *type;
536 /* modify all stack values */
537 saved = 0;
538 l = 0;
539 for(p=vstack;p<=vtop;p++) {
540 if ((p->r & VT_VALMASK) == r ||
541 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
542 /* must save value on stack if not already done */
543 if (!saved) {
544 /* NOTE: must reload 'r' because r might be equal to r2 */
545 r = p->r & VT_VALMASK;
546 /* store register in the stack */
547 type = &p->type;
548 if ((p->r & VT_LVAL) ||
549 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
550 #ifdef TCC_TARGET_X86_64
551 type = &char_pointer_type;
552 #else
553 type = &int_type;
554 #endif
555 size = type_size(type, &align);
556 loc = (loc - size) & -align;
557 sv.type.t = type->t;
558 sv.r = VT_LOCAL | VT_LVAL;
559 sv.c.ul = loc;
560 store(r, &sv);
561 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
562 /* x86 specific: need to pop fp register ST0 if saved */
563 if (r == TREG_ST0) {
564 o(0xd8dd); /* fstp %st(0) */
566 #endif
567 #ifndef TCC_TARGET_X86_64
568 /* special long long case */
569 if ((type->t & VT_BTYPE) == VT_LLONG) {
570 sv.c.ul += 4;
571 store(p->r2, &sv);
573 #endif
574 l = loc;
575 saved = 1;
577 /* mark that stack entry as being saved on the stack */
578 if (p->r & VT_LVAL) {
579 /* also clear the bounded flag because the
580 relocation address of the function was stored in
581 p->c.ul */
582 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
583 } else {
584 p->r = lvalue_type(p->type.t) | VT_LOCAL;
586 p->r2 = VT_CONST;
587 p->c.ul = l;
592 #ifdef TCC_TARGET_ARM
593 /* find a register of class 'rc2' with at most one reference on stack.
594 * If none, call get_reg(rc) */
595 ST_FUNC int get_reg_ex(int rc, int rc2)
597 int r;
598 SValue *p;
600 for(r=0;r<NB_REGS;r++) {
601 if (reg_classes[r] & rc2) {
602 int n;
603 n=0;
604 for(p = vstack; p <= vtop; p++) {
605 if ((p->r & VT_VALMASK) == r ||
606 (p->r2 & VT_VALMASK) == r)
607 n++;
609 if (n <= 1)
610 return r;
613 return get_reg(rc);
615 #endif
617 /* find a free register of class 'rc'. If none, save one register */
618 ST_FUNC int get_reg(int rc)
620 int r;
621 SValue *p;
623 /* find a free register */
624 for(r=0;r<NB_REGS;r++) {
625 if (reg_classes[r] & rc) {
626 for(p=vstack;p<=vtop;p++) {
627 if ((p->r & VT_VALMASK) == r ||
628 (p->r2 & VT_VALMASK) == r)
629 goto notfound;
631 return r;
633 notfound: ;
636 /* no register left : free the first one on the stack (VERY
637 IMPORTANT to start from the bottom to ensure that we don't
638 spill registers used in gen_opi()) */
639 for(p=vstack;p<=vtop;p++) {
640 /* look at second register (if long long) */
641 r = p->r2 & VT_VALMASK;
642 if (r < VT_CONST && (reg_classes[r] & rc))
643 goto save_found;
644 r = p->r & VT_VALMASK;
645 if (r < VT_CONST && (reg_classes[r] & rc)) {
646 save_found:
647 save_reg(r);
648 return r;
651 /* Should never comes here */
652 return -1;
655 /* save registers up to (vtop - n) stack entry */
656 ST_FUNC void save_regs(int n)
658 int r;
659 SValue *p, *p1;
660 p1 = vtop - n;
661 for(p = vstack;p <= p1; p++) {
662 r = p->r & VT_VALMASK;
663 if (r < VT_CONST) {
664 save_reg(r);
669 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
670 if needed */
671 static void move_reg(int r, int s, int t)
673 SValue sv;
675 if (r != s) {
676 save_reg(r);
677 sv.type.t = t;
678 sv.type.ref = NULL;
679 sv.r = s;
680 sv.c.ul = 0;
681 load(r, &sv);
685 /* get address of vtop (vtop MUST BE an lvalue) */
686 static void gaddrof(void)
688 if (vtop->r & VT_REF)
689 gv(RC_INT);
690 vtop->r &= ~VT_LVAL;
691 /* tricky: if saved lvalue, then we can go back to lvalue */
692 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
693 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
698 #ifdef CONFIG_TCC_BCHECK
699 /* generate lvalue bound code */
700 static void gbound(void)
702 int lval_type;
703 CType type1;
705 vtop->r &= ~VT_MUSTBOUND;
706 /* if lvalue, then use checking code before dereferencing */
707 if (vtop->r & VT_LVAL) {
708 /* if not VT_BOUNDED value, then make one */
709 if (!(vtop->r & VT_BOUNDED)) {
710 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
711 /* must save type because we must set it to int to get pointer */
712 type1 = vtop->type;
713 vtop->type.t = VT_INT;
714 gaddrof();
715 vpushi(0);
716 gen_bounded_ptr_add();
717 vtop->r |= lval_type;
718 vtop->type = type1;
720 /* then check for dereferencing */
721 gen_bounded_ptr_deref();
724 #endif
726 /* store vtop a register belonging to class 'rc'. lvalues are
727 converted to values. Cannot be used if cannot be converted to
728 register value (such as structures). */
729 ST_FUNC int gv(int rc)
731 int r, bit_pos, bit_size, size, align, i;
732 int rc2;
734 /* NOTE: get_reg can modify vstack[] */
735 if (vtop->type.t & VT_BITFIELD) {
736 CType type;
737 int bits = 32;
738 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
739 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
740 /* remove bit field info to avoid loops */
741 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
742 /* cast to int to propagate signedness in following ops */
743 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
744 type.t = VT_LLONG;
745 bits = 64;
746 } else
747 type.t = VT_INT;
748 if((vtop->type.t & VT_UNSIGNED) ||
749 (vtop->type.t & VT_BTYPE) == VT_BOOL)
750 type.t |= VT_UNSIGNED;
751 gen_cast(&type);
752 /* generate shifts */
753 vpushi(bits - (bit_pos + bit_size));
754 gen_op(TOK_SHL);
755 vpushi(bits - bit_size);
756 /* NOTE: transformed to SHR if unsigned */
757 gen_op(TOK_SAR);
758 r = gv(rc);
759 } else {
760 if (is_float(vtop->type.t) &&
761 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
762 Sym *sym;
763 int *ptr;
764 unsigned long offset;
765 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
766 CValue check;
767 #endif
769 /* XXX: unify with initializers handling ? */
770 /* CPUs usually cannot use float constants, so we store them
771 generically in data segment */
772 size = type_size(&vtop->type, &align);
773 offset = (data_section->data_offset + align - 1) & -align;
774 data_section->data_offset = offset;
775 /* XXX: not portable yet */
776 #if defined(__i386__) || defined(__x86_64__)
777 /* Zero pad x87 tenbyte long doubles */
778 if (size == LDOUBLE_SIZE) {
779 vtop->c.tab[2] &= 0xffff;
780 #if LDOUBLE_SIZE == 16
781 vtop->c.tab[3] = 0;
782 #endif
784 #endif
785 ptr = section_ptr_add(data_section, size);
786 size = size >> 2;
787 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
788 check.d = 1;
789 if(check.tab[0])
790 for(i=0;i<size;i++)
791 ptr[i] = vtop->c.tab[size-1-i];
792 else
793 #endif
794 for(i=0;i<size;i++)
795 ptr[i] = vtop->c.tab[i];
796 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
797 vtop->r |= VT_LVAL | VT_SYM;
798 vtop->sym = sym;
799 vtop->c.ptr_offset = 0;
801 #ifdef CONFIG_TCC_BCHECK
802 if (vtop->r & VT_MUSTBOUND)
803 gbound();
804 #endif
806 r = vtop->r & VT_VALMASK;
807 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
808 if (rc == RC_IRET)
809 rc2 = RC_LRET;
810 #ifdef TCC_TARGET_X86_64
811 else if (rc == RC_FRET)
812 rc2 = RC_QRET;
813 #endif
815 /* need to reload if:
816 - constant
817 - lvalue (need to dereference pointer)
818 - already a register, but not in the right class */
819 if (r >= VT_CONST
820 || (vtop->r & VT_LVAL)
821 || !(reg_classes[r] & rc)
822 #ifdef TCC_TARGET_X86_64
823 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
824 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
825 #else
826 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
827 #endif
830 r = get_reg(rc);
831 #ifdef TCC_TARGET_X86_64
832 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
833 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
834 #else
835 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
836 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
837 unsigned long long ll;
838 #endif
839 int r2, original_type;
840 original_type = vtop->type.t;
841 /* two register type load : expand to two words
842 temporarily */
843 #ifndef TCC_TARGET_X86_64
844 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
845 /* load constant */
846 ll = vtop->c.ull;
847 vtop->c.ui = ll; /* first word */
848 load(r, vtop);
849 vtop->r = r; /* save register value */
850 vpushi(ll >> 32); /* second word */
851 } else
852 #endif
853 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
854 (vtop->r & VT_LVAL)) {
855 /* We do not want to modifier the long long
856 pointer here, so the safest (and less
857 efficient) is to save all the other registers
858 in the stack. XXX: totally inefficient. */
859 save_regs(1);
860 /* load from memory */
861 vtop->type.t = load_type;
862 load(r, vtop);
863 vdup();
864 vtop[-1].r = r; /* save register value */
865 /* increment pointer to get second word */
866 vtop->type.t = addr_type;
867 gaddrof();
868 vpushi(load_size);
869 gen_op('+');
870 vtop->r |= VT_LVAL;
871 vtop->type.t = load_type;
872 } else {
873 /* move registers */
874 load(r, vtop);
875 vdup();
876 vtop[-1].r = r; /* save register value */
877 vtop->r = vtop[-1].r2;
879 /* Allocate second register. Here we rely on the fact that
880 get_reg() tries first to free r2 of an SValue. */
881 r2 = get_reg(rc2);
882 load(r2, vtop);
883 vpop();
884 /* write second register */
885 vtop->r2 = r2;
886 vtop->type.t = original_type;
887 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
888 int t1, t;
889 /* lvalue of scalar type : need to use lvalue type
890 because of possible cast */
891 t = vtop->type.t;
892 t1 = t;
893 /* compute memory access type */
894 if (vtop->r & VT_REF)
895 #ifdef TCC_TARGET_X86_64
896 t = VT_PTR;
897 #else
898 t = VT_INT;
899 #endif
900 else if (vtop->r & VT_LVAL_BYTE)
901 t = VT_BYTE;
902 else if (vtop->r & VT_LVAL_SHORT)
903 t = VT_SHORT;
904 if (vtop->r & VT_LVAL_UNSIGNED)
905 t |= VT_UNSIGNED;
906 vtop->type.t = t;
907 load(r, vtop);
908 /* restore wanted type */
909 vtop->type.t = t1;
910 } else {
911 /* one register type load */
912 load(r, vtop);
915 vtop->r = r;
916 #ifdef TCC_TARGET_C67
917 /* uses register pairs for doubles */
918 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
919 vtop->r2 = r+1;
920 #endif
922 return r;
925 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
926 ST_FUNC void gv2(int rc1, int rc2)
928 int v;
930 /* generate more generic register first. But VT_JMP or VT_CMP
931 values must be generated first in all cases to avoid possible
932 reload errors */
933 v = vtop[0].r & VT_VALMASK;
934 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
935 vswap();
936 gv(rc1);
937 vswap();
938 gv(rc2);
939 /* test if reload is needed for first register */
940 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
941 vswap();
942 gv(rc1);
943 vswap();
945 } else {
946 gv(rc2);
947 vswap();
948 gv(rc1);
949 vswap();
950 /* test if reload is needed for first register */
951 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
952 gv(rc2);
957 /* wrapper around RC_FRET to return a register by type */
958 static int rc_fret(int t)
960 #ifdef TCC_TARGET_X86_64
961 if (t == VT_LDOUBLE) {
962 return RC_ST0;
964 #endif
965 return RC_FRET;
968 /* wrapper around REG_FRET to return a register by type */
969 static int reg_fret(int t)
971 #ifdef TCC_TARGET_X86_64
972 if (t == VT_LDOUBLE) {
973 return TREG_ST0;
975 #endif
976 return REG_FRET;
979 /* expand long long on stack in two int registers */
980 static void lexpand(void)
982 int u;
984 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
985 gv(RC_INT);
986 vdup();
987 vtop[0].r = vtop[-1].r2;
988 vtop[0].r2 = VT_CONST;
989 vtop[-1].r2 = VT_CONST;
990 vtop[0].type.t = VT_INT | u;
991 vtop[-1].type.t = VT_INT | u;
994 #ifdef TCC_TARGET_ARM
995 /* expand long long on stack */
996 ST_FUNC void lexpand_nr(void)
998 int u,v;
1000 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1001 vdup();
1002 vtop->r2 = VT_CONST;
1003 vtop->type.t = VT_INT | u;
1004 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1005 if (v == VT_CONST) {
1006 vtop[-1].c.ui = vtop->c.ull;
1007 vtop->c.ui = vtop->c.ull >> 32;
1008 vtop->r = VT_CONST;
1009 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1010 vtop->c.ui += 4;
1011 vtop->r = vtop[-1].r;
1012 } else if (v > VT_CONST) {
1013 vtop--;
1014 lexpand();
1015 } else
1016 vtop->r = vtop[-1].r2;
1017 vtop[-1].r2 = VT_CONST;
1018 vtop[-1].type.t = VT_INT | u;
1020 #endif
1022 #ifndef TCC_TARGET_X86_64
1023 /* build a long long from two ints */
1024 static void lbuild(int t)
1026 gv2(RC_INT, RC_INT);
1027 vtop[-1].r2 = vtop[0].r;
1028 vtop[-1].type.t = t;
1029 vpop();
1031 #endif
1033 /* rotate n first stack elements to the bottom
1034 I1 ... In -> I2 ... In I1 [top is right]
1036 ST_FUNC void vrotb(int n)
1038 int i;
1039 SValue tmp;
1041 tmp = vtop[-n + 1];
1042 for(i=-n+1;i!=0;i++)
1043 vtop[i] = vtop[i+1];
1044 vtop[0] = tmp;
1047 /* rotate the n elements before entry e towards the top
1048 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1050 ST_FUNC void vrote(SValue *e, int n)
1052 int i;
1053 SValue tmp;
1055 tmp = *e;
1056 for(i = 0;i < n - 1; i++)
1057 e[-i] = e[-i - 1];
1058 e[-n + 1] = tmp;
1061 /* rotate n first stack elements to the top
1062 I1 ... In -> In I1 ... I(n-1) [top is right]
1064 ST_FUNC void vrott(int n)
1066 vrote(vtop, n);
1069 /* pop stack value */
1070 ST_FUNC void vpop(void)
1072 int v;
1073 v = vtop->r & VT_VALMASK;
1074 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1075 /* for x86, we need to pop the FP stack */
1076 if (v == TREG_ST0 && !nocode_wanted) {
1077 o(0xd8dd); /* fstp %st(0) */
1078 } else
1079 #endif
1080 if (v == VT_JMP || v == VT_JMPI) {
1081 /* need to put correct jump if && or || without test */
1082 gsym(vtop->c.ul);
1084 vtop--;
1087 /* convert stack entry to register and duplicate its value in another
1088 register */
1089 static void gv_dup(void)
1091 int rc, t, r, r1;
1092 SValue sv;
1093 t = vtop->type.t;
1094 #ifndef TCC_TARGET_X86_64
1095 if ((t & VT_BTYPE) == VT_LLONG) {
1096 lexpand();
1097 gv_dup();
1098 vswap();
1099 vrotb(3);
1100 gv_dup();
1101 vrotb(4);
1102 /* stack: H L L1 H1 */
1103 lbuild(t);
1104 vrott(3);
1105 vswap();
1106 lbuild(t);
1107 vswap();
1108 } else
1109 #endif
1111 /* duplicate value */
1112 if (is_float(t)) {
1113 rc = RC_FLOAT;
1114 #ifdef TCC_TARGET_X86_64
1115 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1116 rc = RC_ST0;
1118 #endif
1119 }else
1120 rc = RC_INT;
1121 sv.type.t = t;
1122 r = gv(rc);
1123 r1 = get_reg(rc);
1124 sv.r = r;
1125 sv.c.ul = 0;
1126 load(r1, &sv); /* move r to r1 */
1127 vdup();
1128 /* duplicates value */
1129 if (r != r1)
1130 vtop->r = r1;
1134 /* Generate value test
1136 * Generate a test for any value (jump, comparison and integers) */
1137 ST_FUNC int gvtst(int inv, int t)
1139 int v = vtop->r & VT_VALMASK;
1140 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1141 vpushi(0);
1142 gen_op(TOK_NE);
1144 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1145 /* constant jmp optimization */
1146 if ((vtop->c.i != 0) != inv)
1147 t = gjmp(t);
1148 vtop--;
1149 return t;
1151 return gtst(inv, t);
1154 #ifndef TCC_TARGET_X86_64
1155 /* generate CPU independent (unsigned) long long operations */
1156 static void gen_opl(int op)
1158 int t, a, b, op1, c, i;
1159 int func;
1160 unsigned short reg_iret = REG_IRET;
1161 unsigned short reg_lret = REG_LRET;
1162 SValue tmp;
1164 switch(op) {
1165 case '/':
1166 case TOK_PDIV:
1167 func = TOK___divdi3;
1168 goto gen_func;
1169 case TOK_UDIV:
1170 func = TOK___udivdi3;
1171 goto gen_func;
1172 case '%':
1173 func = TOK___moddi3;
1174 goto gen_mod_func;
1175 case TOK_UMOD:
1176 func = TOK___umoddi3;
1177 gen_mod_func:
1178 #ifdef TCC_ARM_EABI
1179 reg_iret = TREG_R2;
1180 reg_lret = TREG_R3;
1181 #endif
1182 gen_func:
1183 /* call generic long long function */
1184 vpush_global_sym(&func_old_type, func);
1185 vrott(3);
1186 gfunc_call(2);
1187 vpushi(0);
1188 vtop->r = reg_iret;
1189 vtop->r2 = reg_lret;
1190 break;
1191 case '^':
1192 case '&':
1193 case '|':
1194 case '*':
1195 case '+':
1196 case '-':
1197 t = vtop->type.t;
1198 vswap();
1199 lexpand();
1200 vrotb(3);
1201 lexpand();
1202 /* stack: L1 H1 L2 H2 */
1203 tmp = vtop[0];
1204 vtop[0] = vtop[-3];
1205 vtop[-3] = tmp;
1206 tmp = vtop[-2];
1207 vtop[-2] = vtop[-3];
1208 vtop[-3] = tmp;
1209 vswap();
1210 /* stack: H1 H2 L1 L2 */
1211 if (op == '*') {
1212 vpushv(vtop - 1);
1213 vpushv(vtop - 1);
1214 gen_op(TOK_UMULL);
1215 lexpand();
1216 /* stack: H1 H2 L1 L2 ML MH */
1217 for(i=0;i<4;i++)
1218 vrotb(6);
1219 /* stack: ML MH H1 H2 L1 L2 */
1220 tmp = vtop[0];
1221 vtop[0] = vtop[-2];
1222 vtop[-2] = tmp;
1223 /* stack: ML MH H1 L2 H2 L1 */
1224 gen_op('*');
1225 vrotb(3);
1226 vrotb(3);
1227 gen_op('*');
1228 /* stack: ML MH M1 M2 */
1229 gen_op('+');
1230 gen_op('+');
1231 } else if (op == '+' || op == '-') {
1232 /* XXX: add non carry method too (for MIPS or alpha) */
1233 if (op == '+')
1234 op1 = TOK_ADDC1;
1235 else
1236 op1 = TOK_SUBC1;
1237 gen_op(op1);
1238 /* stack: H1 H2 (L1 op L2) */
1239 vrotb(3);
1240 vrotb(3);
1241 gen_op(op1 + 1); /* TOK_xxxC2 */
1242 } else {
1243 gen_op(op);
1244 /* stack: H1 H2 (L1 op L2) */
1245 vrotb(3);
1246 vrotb(3);
1247 /* stack: (L1 op L2) H1 H2 */
1248 gen_op(op);
1249 /* stack: (L1 op L2) (H1 op H2) */
1251 /* stack: L H */
1252 lbuild(t);
1253 break;
1254 case TOK_SAR:
1255 case TOK_SHR:
1256 case TOK_SHL:
1257 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1258 t = vtop[-1].type.t;
1259 vswap();
1260 lexpand();
1261 vrotb(3);
1262 /* stack: L H shift */
1263 c = (int)vtop->c.i;
1264 /* constant: simpler */
1265 /* NOTE: all comments are for SHL. the other cases are
1266 done by swaping words */
1267 vpop();
1268 if (op != TOK_SHL)
1269 vswap();
1270 if (c >= 32) {
1271 /* stack: L H */
1272 vpop();
1273 if (c > 32) {
1274 vpushi(c - 32);
1275 gen_op(op);
1277 if (op != TOK_SAR) {
1278 vpushi(0);
1279 } else {
1280 gv_dup();
1281 vpushi(31);
1282 gen_op(TOK_SAR);
1284 vswap();
1285 } else {
1286 vswap();
1287 gv_dup();
1288 /* stack: H L L */
1289 vpushi(c);
1290 gen_op(op);
1291 vswap();
1292 vpushi(32 - c);
1293 if (op == TOK_SHL)
1294 gen_op(TOK_SHR);
1295 else
1296 gen_op(TOK_SHL);
1297 vrotb(3);
1298 /* stack: L L H */
1299 vpushi(c);
1300 if (op == TOK_SHL)
1301 gen_op(TOK_SHL);
1302 else
1303 gen_op(TOK_SHR);
1304 gen_op('|');
1306 if (op != TOK_SHL)
1307 vswap();
1308 lbuild(t);
1309 } else {
1310 /* XXX: should provide a faster fallback on x86 ? */
1311 switch(op) {
1312 case TOK_SAR:
1313 func = TOK___ashrdi3;
1314 goto gen_func;
1315 case TOK_SHR:
1316 func = TOK___lshrdi3;
1317 goto gen_func;
1318 case TOK_SHL:
1319 func = TOK___ashldi3;
1320 goto gen_func;
1323 break;
1324 default:
1325 /* compare operations */
1326 t = vtop->type.t;
1327 vswap();
1328 lexpand();
1329 vrotb(3);
1330 lexpand();
1331 /* stack: L1 H1 L2 H2 */
1332 tmp = vtop[-1];
1333 vtop[-1] = vtop[-2];
1334 vtop[-2] = tmp;
1335 /* stack: L1 L2 H1 H2 */
1336 /* compare high */
1337 op1 = op;
1338 /* when values are equal, we need to compare low words. since
1339 the jump is inverted, we invert the test too. */
1340 if (op1 == TOK_LT)
1341 op1 = TOK_LE;
1342 else if (op1 == TOK_GT)
1343 op1 = TOK_GE;
1344 else if (op1 == TOK_ULT)
1345 op1 = TOK_ULE;
1346 else if (op1 == TOK_UGT)
1347 op1 = TOK_UGE;
1348 a = 0;
1349 b = 0;
1350 gen_op(op1);
1351 if (op1 != TOK_NE) {
1352 a = gvtst(1, 0);
1354 if (op != TOK_EQ) {
1355 /* generate non equal test */
1356 /* XXX: NOT PORTABLE yet */
1357 if (a == 0) {
1358 b = gvtst(0, 0);
1359 } else {
1360 #if defined(TCC_TARGET_I386)
1361 b = psym(0x850f, 0);
1362 #elif defined(TCC_TARGET_ARM)
1363 b = ind;
1364 o(0x1A000000 | encbranch(ind, 0, 1));
1365 #elif defined(TCC_TARGET_C67)
1366 tcc_error("not implemented");
1367 #else
1368 #error not supported
1369 #endif
1372 /* compare low. Always unsigned */
1373 op1 = op;
1374 if (op1 == TOK_LT)
1375 op1 = TOK_ULT;
1376 else if (op1 == TOK_LE)
1377 op1 = TOK_ULE;
1378 else if (op1 == TOK_GT)
1379 op1 = TOK_UGT;
1380 else if (op1 == TOK_GE)
1381 op1 = TOK_UGE;
1382 gen_op(op1);
1383 a = gvtst(1, a);
1384 gsym(b);
1385 vseti(VT_JMPI, a);
1386 break;
1389 #endif
1391 /* handle integer constant optimizations and various machine
1392 independent opt */
1393 static void gen_opic(int op)
1395 int c1, c2, t1, t2, n;
1396 SValue *v1, *v2;
1397 long long l1, l2;
1398 typedef unsigned long long U;
1400 v1 = vtop - 1;
1401 v2 = vtop;
1402 t1 = v1->type.t & VT_BTYPE;
1403 t2 = v2->type.t & VT_BTYPE;
1405 if (t1 == VT_LLONG)
1406 l1 = v1->c.ll;
1407 else if (v1->type.t & VT_UNSIGNED)
1408 l1 = v1->c.ui;
1409 else
1410 l1 = v1->c.i;
1412 if (t2 == VT_LLONG)
1413 l2 = v2->c.ll;
1414 else if (v2->type.t & VT_UNSIGNED)
1415 l2 = v2->c.ui;
1416 else
1417 l2 = v2->c.i;
1419 /* currently, we cannot do computations with forward symbols */
1420 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1421 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1422 if (c1 && c2) {
1423 switch(op) {
1424 case '+': l1 += l2; break;
1425 case '-': l1 -= l2; break;
1426 case '&': l1 &= l2; break;
1427 case '^': l1 ^= l2; break;
1428 case '|': l1 |= l2; break;
1429 case '*': l1 *= l2; break;
1431 case TOK_PDIV:
1432 case '/':
1433 case '%':
1434 case TOK_UDIV:
1435 case TOK_UMOD:
1436 /* if division by zero, generate explicit division */
1437 if (l2 == 0) {
1438 if (const_wanted)
1439 tcc_error("division by zero in constant");
1440 goto general_case;
1442 switch(op) {
1443 default: l1 /= l2; break;
1444 case '%': l1 %= l2; break;
1445 case TOK_UDIV: l1 = (U)l1 / l2; break;
1446 case TOK_UMOD: l1 = (U)l1 % l2; break;
1448 break;
1449 case TOK_SHL: l1 <<= l2; break;
1450 case TOK_SHR: l1 = (U)l1 >> l2; break;
1451 case TOK_SAR: l1 >>= l2; break;
1452 /* tests */
1453 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1454 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1455 case TOK_EQ: l1 = l1 == l2; break;
1456 case TOK_NE: l1 = l1 != l2; break;
1457 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1458 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1459 case TOK_LT: l1 = l1 < l2; break;
1460 case TOK_GE: l1 = l1 >= l2; break;
1461 case TOK_LE: l1 = l1 <= l2; break;
1462 case TOK_GT: l1 = l1 > l2; break;
1463 /* logical */
1464 case TOK_LAND: l1 = l1 && l2; break;
1465 case TOK_LOR: l1 = l1 || l2; break;
1466 default:
1467 goto general_case;
1469 v1->c.ll = l1;
1470 vtop--;
1471 } else {
1472 /* if commutative ops, put c2 as constant */
1473 if (c1 && (op == '+' || op == '&' || op == '^' ||
1474 op == '|' || op == '*')) {
1475 vswap();
1476 c2 = c1; //c = c1, c1 = c2, c2 = c;
1477 l2 = l1; //l = l1, l1 = l2, l2 = l;
1479 /* Filter out NOP operations like x*1, x-0, x&-1... */
1480 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1481 op == TOK_PDIV) &&
1482 l2 == 1) ||
1483 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1484 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1485 l2 == 0) ||
1486 (op == '&' &&
1487 l2 == -1))) {
1488 /* nothing to do */
1489 vtop--;
1490 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1491 /* try to use shifts instead of muls or divs */
1492 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1493 n = -1;
1494 while (l2) {
1495 l2 >>= 1;
1496 n++;
1498 vtop->c.ll = n;
1499 if (op == '*')
1500 op = TOK_SHL;
1501 else if (op == TOK_PDIV)
1502 op = TOK_SAR;
1503 else
1504 op = TOK_SHR;
1506 goto general_case;
1507 } else if (c2 && (op == '+' || op == '-') &&
1508 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1509 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1510 /* symbol + constant case */
1511 if (op == '-')
1512 l2 = -l2;
1513 vtop--;
1514 vtop->c.ll += l2;
1515 } else {
1516 general_case:
1517 if (!nocode_wanted) {
1518 /* call low level op generator */
1519 if (t1 == VT_LLONG || t2 == VT_LLONG)
1520 gen_opl(op);
1521 else
1522 gen_opi(op);
1523 } else {
1524 vtop--;
1530 /* generate a floating point operation with constant propagation */
1531 static void gen_opif(int op)
1533 int c1, c2;
1534 SValue *v1, *v2;
1535 long double f1, f2;
1537 v1 = vtop - 1;
1538 v2 = vtop;
1539 /* currently, we cannot do computations with forward symbols */
1540 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1541 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1542 if (c1 && c2) {
1543 if (v1->type.t == VT_FLOAT) {
1544 f1 = v1->c.f;
1545 f2 = v2->c.f;
1546 } else if (v1->type.t == VT_DOUBLE) {
1547 f1 = v1->c.d;
1548 f2 = v2->c.d;
1549 } else {
1550 f1 = v1->c.ld;
1551 f2 = v2->c.ld;
1554 /* NOTE: we only do constant propagation if finite number (not
1555 NaN or infinity) (ANSI spec) */
1556 if (!ieee_finite(f1) || !ieee_finite(f2))
1557 goto general_case;
1559 switch(op) {
1560 case '+': f1 += f2; break;
1561 case '-': f1 -= f2; break;
1562 case '*': f1 *= f2; break;
1563 case '/':
1564 if (f2 == 0.0) {
1565 if (const_wanted)
1566 tcc_error("division by zero in constant");
1567 goto general_case;
1569 f1 /= f2;
1570 break;
1571 /* XXX: also handles tests ? */
1572 default:
1573 goto general_case;
1575 /* XXX: overflow test ? */
1576 if (v1->type.t == VT_FLOAT) {
1577 v1->c.f = f1;
1578 } else if (v1->type.t == VT_DOUBLE) {
1579 v1->c.d = f1;
1580 } else {
1581 v1->c.ld = f1;
1583 vtop--;
1584 } else {
1585 general_case:
1586 if (!nocode_wanted) {
1587 gen_opf(op);
1588 } else {
1589 vtop--;
1594 static int pointed_size(CType *type)
1596 int align;
1597 return type_size(pointed_type(type), &align);
1600 static void vla_runtime_pointed_size(CType *type)
1602 int align;
1603 vla_runtime_type_size(pointed_type(type), &align);
1606 static inline int is_null_pointer(SValue *p)
1608 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1609 return 0;
1610 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1611 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1612 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0);
1615 static inline int is_integer_btype(int bt)
1617 return (bt == VT_BYTE || bt == VT_SHORT ||
1618 bt == VT_INT || bt == VT_LLONG);
1621 /* check types for comparison or subtraction of pointers */
1622 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1624 CType *type1, *type2, tmp_type1, tmp_type2;
1625 int bt1, bt2;
1627 /* null pointers are accepted for all comparisons as gcc */
1628 if (is_null_pointer(p1) || is_null_pointer(p2))
1629 return;
1630 type1 = &p1->type;
1631 type2 = &p2->type;
1632 bt1 = type1->t & VT_BTYPE;
1633 bt2 = type2->t & VT_BTYPE;
1634 /* accept comparison between pointer and integer with a warning */
1635 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1636 if (op != TOK_LOR && op != TOK_LAND )
1637 tcc_warning("comparison between pointer and integer");
1638 return;
1641 /* both must be pointers or implicit function pointers */
1642 if (bt1 == VT_PTR) {
1643 type1 = pointed_type(type1);
1644 } else if (bt1 != VT_FUNC)
1645 goto invalid_operands;
1647 if (bt2 == VT_PTR) {
1648 type2 = pointed_type(type2);
1649 } else if (bt2 != VT_FUNC) {
1650 invalid_operands:
1651 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1653 if ((type1->t & VT_BTYPE) == VT_VOID ||
1654 (type2->t & VT_BTYPE) == VT_VOID)
1655 return;
1656 tmp_type1 = *type1;
1657 tmp_type2 = *type2;
1658 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1659 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1660 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1661 /* gcc-like error if '-' is used */
1662 if (op == '-')
1663 goto invalid_operands;
1664 else
1665 tcc_warning("comparison of distinct pointer types lacks a cast");
1669 /* generic gen_op: handles types problems */
1670 ST_FUNC void gen_op(int op)
1672 int u, t1, t2, bt1, bt2, t;
1673 CType type1;
1675 t1 = vtop[-1].type.t;
1676 t2 = vtop[0].type.t;
1677 bt1 = t1 & VT_BTYPE;
1678 bt2 = t2 & VT_BTYPE;
1680 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1681 /* at least one operand is a pointer */
1682 /* relationnal op: must be both pointers */
1683 if (op >= TOK_ULT && op <= TOK_LOR) {
1684 check_comparison_pointer_types(vtop - 1, vtop, op);
1685 /* pointers are handled are unsigned */
1686 #ifdef TCC_TARGET_X86_64
1687 t = VT_LLONG | VT_UNSIGNED;
1688 #else
1689 t = VT_INT | VT_UNSIGNED;
1690 #endif
1691 goto std_op;
1693 /* if both pointers, then it must be the '-' op */
1694 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1695 if (op != '-')
1696 tcc_error("cannot use pointers here");
1697 check_comparison_pointer_types(vtop - 1, vtop, op);
1698 /* XXX: check that types are compatible */
1699 if (vtop[-1].type.t & VT_VLA) {
1700 vla_runtime_pointed_size(&vtop[-1].type);
1701 } else {
1702 vpushi(pointed_size(&vtop[-1].type));
1704 vrott(3);
1705 gen_opic(op);
1706 /* set to integer type */
1707 #ifdef TCC_TARGET_X86_64
1708 vtop->type.t = VT_LLONG;
1709 #else
1710 vtop->type.t = VT_INT;
1711 #endif
1712 vswap();
1713 gen_op(TOK_PDIV);
1714 } else {
1715 /* exactly one pointer : must be '+' or '-'. */
1716 if (op != '-' && op != '+')
1717 tcc_error("cannot use pointers here");
1718 /* Put pointer as first operand */
1719 if (bt2 == VT_PTR) {
1720 vswap();
1721 swap(&t1, &t2);
1723 type1 = vtop[-1].type;
1724 type1.t &= ~VT_ARRAY;
1725 if (vtop[-1].type.t & VT_VLA)
1726 vla_runtime_pointed_size(&vtop[-1].type);
1727 else {
1728 u = pointed_size(&vtop[-1].type);
1729 if (u < 0)
1730 tcc_error("unknown array element size");
1731 #ifdef TCC_TARGET_X86_64
1732 vpushll(u);
1733 #else
1734 /* XXX: cast to int ? (long long case) */
1735 vpushi(u);
1736 #endif
1738 gen_op('*');
1739 #ifdef CONFIG_TCC_BCHECK
1740 /* if evaluating constant expression, no code should be
1741 generated, so no bound check */
1742 if (tcc_state->do_bounds_check && !const_wanted) {
1743 /* if bounded pointers, we generate a special code to
1744 test bounds */
1745 if (op == '-') {
1746 vpushi(0);
1747 vswap();
1748 gen_op('-');
1750 gen_bounded_ptr_add();
1751 } else
1752 #endif
1754 gen_opic(op);
1756 /* put again type if gen_opic() swaped operands */
1757 vtop->type = type1;
1759 } else if (is_float(bt1) || is_float(bt2)) {
1760 /* compute bigger type and do implicit casts */
1761 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1762 t = VT_LDOUBLE;
1763 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1764 t = VT_DOUBLE;
1765 } else {
1766 t = VT_FLOAT;
1768 /* floats can only be used for a few operations */
1769 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1770 (op < TOK_ULT || op > TOK_GT))
1771 tcc_error("invalid operands for binary operation");
1772 goto std_op;
1773 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1774 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1775 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1776 t |= VT_UNSIGNED;
1777 goto std_op;
1778 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1779 /* cast to biggest op */
1780 t = VT_LLONG;
1781 /* convert to unsigned if it does not fit in a long long */
1782 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1783 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1784 t |= VT_UNSIGNED;
1785 goto std_op;
1786 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1787 tcc_error("comparison of struct");
1788 } else {
1789 /* integer operations */
1790 t = VT_INT;
1791 /* convert to unsigned if it does not fit in an integer */
1792 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1793 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1794 t |= VT_UNSIGNED;
1795 std_op:
1796 /* XXX: currently, some unsigned operations are explicit, so
1797 we modify them here */
1798 if (t & VT_UNSIGNED) {
1799 if (op == TOK_SAR)
1800 op = TOK_SHR;
1801 else if (op == '/')
1802 op = TOK_UDIV;
1803 else if (op == '%')
1804 op = TOK_UMOD;
1805 else if (op == TOK_LT)
1806 op = TOK_ULT;
1807 else if (op == TOK_GT)
1808 op = TOK_UGT;
1809 else if (op == TOK_LE)
1810 op = TOK_ULE;
1811 else if (op == TOK_GE)
1812 op = TOK_UGE;
1814 vswap();
1815 type1.t = t;
1816 gen_cast(&type1);
1817 vswap();
1818 /* special case for shifts and long long: we keep the shift as
1819 an integer */
1820 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1821 type1.t = VT_INT;
1822 gen_cast(&type1);
1823 if (is_float(t))
1824 gen_opif(op);
1825 else
1826 gen_opic(op);
1827 if (op >= TOK_ULT && op <= TOK_GT) {
1828 /* relationnal op: the result is an int */
1829 vtop->type.t = VT_INT;
1830 } else {
1831 vtop->type.t = t;
1836 #ifndef TCC_TARGET_ARM
1837 /* generic itof for unsigned long long case */
1838 static void gen_cvt_itof1(int t)
1840 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1841 (VT_LLONG | VT_UNSIGNED)) {
1843 if (t == VT_FLOAT)
1844 vpush_global_sym(&func_old_type, TOK___floatundisf);
1845 #if LDOUBLE_SIZE != 8
1846 else if (t == VT_LDOUBLE)
1847 vpush_global_sym(&func_old_type, TOK___floatundixf);
1848 #endif
1849 else
1850 vpush_global_sym(&func_old_type, TOK___floatundidf);
1851 vrott(2);
1852 gfunc_call(1);
1853 vpushi(0);
1854 vtop->r = reg_fret(t);
1855 } else {
1856 gen_cvt_itof(t);
1859 #endif
1861 /* generic ftoi for unsigned long long case */
1862 static void gen_cvt_ftoi1(int t)
1864 int st;
1866 if (t == (VT_LLONG | VT_UNSIGNED)) {
1867 /* not handled natively */
1868 st = vtop->type.t & VT_BTYPE;
1869 if (st == VT_FLOAT)
1870 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1871 #if LDOUBLE_SIZE != 8
1872 else if (st == VT_LDOUBLE)
1873 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1874 #endif
1875 else
1876 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1877 vrott(2);
1878 gfunc_call(1);
1879 vpushi(0);
1880 vtop->r = REG_IRET;
1881 vtop->r2 = REG_LRET;
1882 } else {
1883 gen_cvt_ftoi(t);
1887 /* force char or short cast */
1888 static void force_charshort_cast(int t)
1890 int bits, dbt;
1891 dbt = t & VT_BTYPE;
1892 /* XXX: add optimization if lvalue : just change type and offset */
1893 if (dbt == VT_BYTE)
1894 bits = 8;
1895 else
1896 bits = 16;
1897 if (t & VT_UNSIGNED) {
1898 vpushi((1 << bits) - 1);
1899 gen_op('&');
1900 } else {
1901 bits = 32 - bits;
1902 vpushi(bits);
1903 gen_op(TOK_SHL);
1904 /* result must be signed or the SAR is converted to an SHL
1905 This was not the case when "t" was a signed short
1906 and the last value on the stack was an unsigned int */
1907 vtop->type.t &= ~VT_UNSIGNED;
1908 vpushi(bits);
1909 gen_op(TOK_SAR);
1913 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1914 static void gen_cast(CType *type)
1916 int sbt, dbt, sf, df, c, p;
1918 /* special delayed cast for char/short */
1919 /* XXX: in some cases (multiple cascaded casts), it may still
1920 be incorrect */
1921 if (vtop->r & VT_MUSTCAST) {
1922 vtop->r &= ~VT_MUSTCAST;
1923 force_charshort_cast(vtop->type.t);
1926 /* bitfields first get cast to ints */
1927 if (vtop->type.t & VT_BITFIELD) {
1928 gv(RC_INT);
1931 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1932 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1934 if (sbt != dbt) {
1935 sf = is_float(sbt);
1936 df = is_float(dbt);
1937 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1938 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1939 if (c) {
1940 /* constant case: we can do it now */
1941 /* XXX: in ISOC, cannot do it if error in convert */
1942 if (sbt == VT_FLOAT)
1943 vtop->c.ld = vtop->c.f;
1944 else if (sbt == VT_DOUBLE)
1945 vtop->c.ld = vtop->c.d;
1947 if (df) {
1948 if ((sbt & VT_BTYPE) == VT_LLONG) {
1949 if (sbt & VT_UNSIGNED)
1950 vtop->c.ld = vtop->c.ull;
1951 else
1952 vtop->c.ld = vtop->c.ll;
1953 } else if(!sf) {
1954 if (sbt & VT_UNSIGNED)
1955 vtop->c.ld = vtop->c.ui;
1956 else
1957 vtop->c.ld = vtop->c.i;
1960 if (dbt == VT_FLOAT)
1961 vtop->c.f = (float)vtop->c.ld;
1962 else if (dbt == VT_DOUBLE)
1963 vtop->c.d = (double)vtop->c.ld;
1964 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1965 vtop->c.ull = (unsigned long long)vtop->c.ld;
1966 } else if (sf && dbt == VT_BOOL) {
1967 vtop->c.i = (vtop->c.ld != 0);
1968 } else {
1969 if(sf)
1970 vtop->c.ll = (long long)vtop->c.ld;
1971 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1972 vtop->c.ll = vtop->c.ull;
1973 else if (sbt & VT_UNSIGNED)
1974 vtop->c.ll = vtop->c.ui;
1975 #ifdef TCC_TARGET_X86_64
1976 else if (sbt == VT_PTR)
1978 #endif
1979 else if (sbt != VT_LLONG)
1980 vtop->c.ll = vtop->c.i;
1982 if (dbt == (VT_LLONG|VT_UNSIGNED))
1983 vtop->c.ull = vtop->c.ll;
1984 else if (dbt == VT_BOOL)
1985 vtop->c.i = (vtop->c.ll != 0);
1986 #ifdef TCC_TARGET_X86_64
1987 else if (dbt == VT_PTR)
1989 #endif
1990 else if (dbt != VT_LLONG) {
1991 int s, dt, warr = 0;
1992 long long ll;
1993 dt = dbt & VT_BTYPE;
1994 ll = vtop->c.ll;
1995 if (dt == VT_BYTE){
1996 if((ll != (unsigned char)ll) && (ll != (char)ll))
1997 warr = 1;
1998 s = 24;
1999 }else if (dt == VT_SHORT){
2000 if((ll != (unsigned short)ll) && (ll != (short)ll))
2001 warr = 1;
2002 s = 16;
2003 }else{
2004 if((ll != (unsigned int)ll) && (ll != (int)ll))
2005 warr = 1;
2006 s = 0;
2008 if(warr && !is_force){
2009 if(dt == VT_ENUM){
2010 tcc_warning("large integer implicitly truncated to unsigned type");
2011 dbt = VT_UNSIGNED;
2012 }else
2013 tcc_warning("overflow in implicit constant conversion");
2015 if(dbt & VT_UNSIGNED)
2016 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
2017 else
2018 vtop->c.i = ((int)vtop->c.ll << s) >> s;
2021 } else if (p && dbt == VT_BOOL) {
2022 vtop->r = VT_CONST;
2023 vtop->c.i = 1;
2024 } else if (!nocode_wanted) {
2025 /* non constant case: generate code */
2026 if (sf && df) {
2027 /* convert from fp to fp */
2028 gen_cvt_ftof(dbt);
2029 } else if (df) {
2030 /* convert int to fp */
2031 gen_cvt_itof1(dbt);
2032 } else if (sf) {
2033 /* convert fp to int */
2034 if (dbt == VT_BOOL) {
2035 vpushi(0);
2036 gen_op(TOK_NE);
2037 } else {
2038 /* we handle char/short/etc... with generic code */
2039 if (dbt != (VT_INT | VT_UNSIGNED) &&
2040 dbt != (VT_LLONG | VT_UNSIGNED) &&
2041 dbt != VT_LLONG)
2042 dbt = VT_INT;
2043 gen_cvt_ftoi1(dbt);
2044 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2045 /* additional cast for char/short... */
2046 vtop->type.t = dbt;
2047 gen_cast(type);
2050 #ifndef TCC_TARGET_X86_64
2051 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2052 if ((sbt & VT_BTYPE) != VT_LLONG) {
2053 /* scalar to long long */
2054 /* machine independent conversion */
2055 gv(RC_INT);
2056 /* generate high word */
2057 if (sbt == (VT_INT | VT_UNSIGNED)) {
2058 vpushi(0);
2059 gv(RC_INT);
2060 } else {
2061 if (sbt == VT_PTR) {
2062 /* cast from pointer to int before we apply
2063 shift operation, which pointers don't support*/
2064 gen_cast(&int_type);
2066 gv_dup();
2067 vpushi(31);
2068 gen_op(TOK_SAR);
2070 /* patch second register */
2071 vtop[-1].r2 = vtop->r;
2072 vpop();
2074 #else
2075 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2076 (dbt & VT_BTYPE) == VT_PTR ||
2077 (dbt & VT_BTYPE) == VT_FUNC) {
2078 if ((sbt & VT_BTYPE) != VT_LLONG &&
2079 (sbt & VT_BTYPE) != VT_PTR &&
2080 (sbt & VT_BTYPE) != VT_FUNC) {
2081 /* need to convert from 32bit to 64bit */
2082 int r = gv(RC_INT);
2083 if (sbt != (VT_INT | VT_UNSIGNED)) {
2084 /* x86_64 specific: movslq */
2085 o(0x6348);
2086 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2089 #endif
2090 } else if (dbt == VT_BOOL) {
2091 /* scalar to bool */
2092 vpushi(0);
2093 gen_op(TOK_NE);
2094 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2095 (dbt & VT_BTYPE) == VT_SHORT) {
2096 if (sbt == VT_PTR) {
2097 vtop->type.t = VT_INT;
2098 tcc_warning("nonportable conversion from pointer to char/short");
2100 force_charshort_cast(dbt);
2101 } else if ((dbt & VT_BTYPE) == VT_INT) {
2102 /* scalar to int */
2103 if (sbt == VT_LLONG) {
2104 /* from long long: just take low order word */
2105 lexpand();
2106 vpop();
2108 /* if lvalue and single word type, nothing to do because
2109 the lvalue already contains the real type size (see
2110 VT_LVAL_xxx constants) */
2113 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2114 /* if we are casting between pointer types,
2115 we must update the VT_LVAL_xxx size */
2116 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2117 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2119 vtop->type = *type;
2122 /* return type size as known at compile time. Put alignment at 'a' */
2123 ST_FUNC int type_size(CType *type, int *a)
2125 Sym *s;
2126 int bt;
2128 bt = type->t & VT_BTYPE;
2129 if (bt == VT_STRUCT) {
2130 /* struct/union */
2131 s = type->ref;
2132 *a = s->r;
2133 return s->c;
2134 } else if (bt == VT_PTR) {
2135 if (type->t & VT_ARRAY) {
2136 int ts;
2138 s = type->ref;
2139 ts = type_size(&s->type, a);
2141 if (ts < 0 && s->c < 0)
2142 ts = -ts;
2144 return ts * s->c;
2145 } else {
2146 *a = PTR_SIZE;
2147 return PTR_SIZE;
2149 } else if (bt == VT_LDOUBLE) {
2150 *a = LDOUBLE_ALIGN;
2151 return LDOUBLE_SIZE;
2152 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2153 #ifdef TCC_TARGET_I386
2154 #ifdef TCC_TARGET_PE
2155 *a = 8;
2156 #else
2157 *a = 4;
2158 #endif
2159 #elif defined(TCC_TARGET_ARM)
2160 #ifdef TCC_ARM_EABI
2161 *a = 8;
2162 #else
2163 *a = 4;
2164 #endif
2165 #else
2166 *a = 8;
2167 #endif
2168 return 8;
2169 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2170 *a = 4;
2171 return 4;
2172 } else if (bt == VT_SHORT) {
2173 *a = 2;
2174 return 2;
2175 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2176 *a = 8;
2177 return 16;
2178 } else {
2179 /* char, void, function, _Bool */
2180 *a = 1;
2181 return 1;
2185 /* push type size as known at runtime time on top of value stack. Put
2186 alignment at 'a' */
2187 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2189 if (type->t & VT_VLA) {
2190 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2191 } else {
2192 vpushi(type_size(type, a));
2196 static void vla_sp_save(void) {
2197 if (!(vla_flags & VLA_SP_LOC_SET)) {
2198 *vla_sp_loc = (loc -= PTR_SIZE);
2199 vla_flags |= VLA_SP_LOC_SET;
2201 if (!(vla_flags & VLA_SP_SAVED)) {
2202 gen_vla_sp_save(*vla_sp_loc);
2203 vla_flags |= VLA_SP_SAVED;
2207 /* return the pointed type of t */
2208 static inline CType *pointed_type(CType *type)
2210 return &type->ref->type;
2213 /* modify type so that its it is a pointer to type. */
2214 ST_FUNC void mk_pointer(CType *type)
2216 Sym *s;
2217 s = sym_push(SYM_FIELD, type, 0, -1);
2218 type->t = VT_PTR | (type->t & ~VT_TYPE);
2219 type->ref = s;
2222 /* compare function types. OLD functions match any new functions */
2223 static int is_compatible_func(CType *type1, CType *type2)
2225 Sym *s1, *s2;
2227 s1 = type1->ref;
2228 s2 = type2->ref;
2229 if (!is_compatible_types(&s1->type, &s2->type))
2230 return 0;
2231 /* check func_call */
2232 if (s1->a.func_call != s2->a.func_call)
2233 return 0;
2234 /* XXX: not complete */
2235 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2236 return 1;
2237 if (s1->c != s2->c)
2238 return 0;
2239 while (s1 != NULL) {
2240 if (s2 == NULL)
2241 return 0;
2242 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2243 return 0;
2244 s1 = s1->next;
2245 s2 = s2->next;
2247 if (s2)
2248 return 0;
2249 return 1;
2252 /* return true if type1 and type2 are the same. If unqualified is
2253 true, qualifiers on the types are ignored.
2255 - enums are not checked as gcc __builtin_types_compatible_p ()
2257 static int compare_types(CType *type1, CType *type2, int unqualified)
2259 int bt1, t1, t2;
2261 t1 = type1->t & VT_TYPE;
2262 t2 = type2->t & VT_TYPE;
2263 if (unqualified) {
2264 /* strip qualifiers before comparing */
2265 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2266 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2268 /* Default Vs explicit signedness only matters for char */
2269 if ((t1 & VT_BTYPE) != VT_BYTE) {
2270 t1 &= ~VT_DEFSIGN;
2271 t2 &= ~VT_DEFSIGN;
2273 /* XXX: bitfields ? */
2274 if (t1 != t2)
2275 return 0;
2276 /* test more complicated cases */
2277 bt1 = t1 & VT_BTYPE;
2278 if (bt1 == VT_PTR) {
2279 type1 = pointed_type(type1);
2280 type2 = pointed_type(type2);
2281 return is_compatible_types(type1, type2);
2282 } else if (bt1 == VT_STRUCT) {
2283 return (type1->ref == type2->ref);
2284 } else if (bt1 == VT_FUNC) {
2285 return is_compatible_func(type1, type2);
2286 } else {
2287 return 1;
2291 /* return true if type1 and type2 are exactly the same (including
2292 qualifiers).
2294 static int is_compatible_types(CType *type1, CType *type2)
2296 return compare_types(type1,type2,0);
2299 /* return true if type1 and type2 are the same (ignoring qualifiers).
2301 static int is_compatible_parameter_types(CType *type1, CType *type2)
2303 return compare_types(type1,type2,1);
2306 /* print a type. If 'varstr' is not NULL, then the variable is also
2307 printed in the type */
2308 /* XXX: union */
2309 /* XXX: add array and function pointers */
2310 static void type_to_str(char *buf, int buf_size,
2311 CType *type, const char *varstr)
2313 int bt, v, t;
2314 Sym *s, *sa;
2315 char buf1[256];
2316 const char *tstr;
2318 t = type->t & VT_TYPE;
2319 bt = t & VT_BTYPE;
2320 buf[0] = '\0';
2321 if (t & VT_CONSTANT)
2322 pstrcat(buf, buf_size, "const ");
2323 if (t & VT_VOLATILE)
2324 pstrcat(buf, buf_size, "volatile ");
2325 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2326 pstrcat(buf, buf_size, "unsigned ");
2327 else if (t & VT_DEFSIGN)
2328 pstrcat(buf, buf_size, "signed ");
2329 switch(bt) {
2330 case VT_VOID:
2331 tstr = "void";
2332 goto add_tstr;
2333 case VT_BOOL:
2334 tstr = "_Bool";
2335 goto add_tstr;
2336 case VT_BYTE:
2337 tstr = "char";
2338 goto add_tstr;
2339 case VT_SHORT:
2340 tstr = "short";
2341 goto add_tstr;
2342 case VT_INT:
2343 tstr = "int";
2344 goto add_tstr;
2345 case VT_LONG:
2346 tstr = "long";
2347 goto add_tstr;
2348 case VT_LLONG:
2349 tstr = "long long";
2350 goto add_tstr;
2351 case VT_FLOAT:
2352 tstr = "float";
2353 goto add_tstr;
2354 case VT_DOUBLE:
2355 tstr = "double";
2356 goto add_tstr;
2357 case VT_LDOUBLE:
2358 tstr = "long double";
2359 add_tstr:
2360 pstrcat(buf, buf_size, tstr);
2361 break;
2362 case VT_ENUM:
2363 case VT_STRUCT:
2364 if (bt == VT_STRUCT)
2365 tstr = "struct ";
2366 else
2367 tstr = "enum ";
2368 pstrcat(buf, buf_size, tstr);
2369 v = type->ref->v & ~SYM_STRUCT;
2370 if (v >= SYM_FIRST_ANOM)
2371 pstrcat(buf, buf_size, "<anonymous>");
2372 else
2373 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2374 break;
2375 case VT_FUNC:
2376 s = type->ref;
2377 type_to_str(buf, buf_size, &s->type, varstr);
2378 pstrcat(buf, buf_size, "(");
2379 sa = s->next;
2380 while (sa != NULL) {
2381 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2382 pstrcat(buf, buf_size, buf1);
2383 sa = sa->next;
2384 if (sa)
2385 pstrcat(buf, buf_size, ", ");
2387 pstrcat(buf, buf_size, ")");
2388 goto no_var;
2389 case VT_PTR:
2390 s = type->ref;
2391 pstrcpy(buf1, sizeof(buf1), "*");
2392 if (varstr)
2393 pstrcat(buf1, sizeof(buf1), varstr);
2394 type_to_str(buf, buf_size, &s->type, buf1);
2395 goto no_var;
2397 if (varstr) {
2398 pstrcat(buf, buf_size, " ");
2399 pstrcat(buf, buf_size, varstr);
2401 no_var: ;
2404 /* verify type compatibility to store vtop in 'dt' type, and generate
2405 casts if needed. */
2406 static void gen_assign_cast(CType *dt)
2408 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2409 char buf1[256], buf2[256];
2410 int dbt, sbt;
2412 st = &vtop->type; /* source type */
2413 dbt = dt->t & VT_BTYPE;
2414 sbt = st->t & VT_BTYPE;
2415 if (sbt == VT_VOID || dbt == VT_VOID)
2416 tcc_error("cannot cast from/to void");
2417 if (dt->t & VT_CONSTANT)
2418 tcc_warning("assignment of read-only location");
2419 switch(dbt) {
2420 case VT_PTR:
2421 /* special cases for pointers */
2422 /* '0' can also be a pointer */
2423 if (is_null_pointer(vtop))
2424 goto type_ok;
2425 /* accept implicit pointer to integer cast with warning */
2426 if (is_integer_btype(sbt)) {
2427 tcc_warning("assignment makes pointer from integer without a cast");
2428 goto type_ok;
2430 type1 = pointed_type(dt);
2431 /* a function is implicitely a function pointer */
2432 if (sbt == VT_FUNC) {
2433 if ((type1->t & VT_BTYPE) != VT_VOID &&
2434 !is_compatible_types(pointed_type(dt), st))
2435 tcc_warning("assignment from incompatible pointer type");
2436 goto type_ok;
2438 if (sbt != VT_PTR)
2439 goto error;
2440 type2 = pointed_type(st);
2441 if ((type1->t & VT_BTYPE) == VT_VOID ||
2442 (type2->t & VT_BTYPE) == VT_VOID) {
2443 /* void * can match anything */
2444 } else {
2445 /* exact type match, except for unsigned */
2446 tmp_type1 = *type1;
2447 tmp_type2 = *type2;
2448 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2449 VT_VOLATILE);
2450 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2451 VT_VOLATILE);
2452 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2453 tcc_warning("assignment from incompatible pointer type");
2455 /* check const and volatile */
2456 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2457 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2458 tcc_warning("assignment discards qualifiers from pointer target type");
2459 break;
2460 case VT_BYTE:
2461 case VT_SHORT:
2462 case VT_INT:
2463 case VT_LLONG:
2464 if (sbt == VT_PTR || sbt == VT_FUNC) {
2465 tcc_warning("assignment makes integer from pointer without a cast");
2467 if (sbt == VT_STRUCT)
2468 goto error;
2469 /* XXX: more tests */
2470 break;
2471 case VT_STRUCT:
2472 tmp_type1 = *dt;
2473 tmp_type2 = *st;
2474 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2475 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2476 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2477 error:
2478 type_to_str(buf1, sizeof(buf1), st, NULL);
2479 type_to_str(buf2, sizeof(buf2), dt, NULL);
2480 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2482 break;
2484 type_ok:
2485 gen_cast(dt);
2488 /* store vtop in lvalue pushed on stack */
2489 ST_FUNC void vstore(void)
2491 int sbt, dbt, ft, cc, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2493 ft = vtop[-1].type.t;
2494 sbt = vtop->type.t & VT_BTYPE;
2495 dbt = ft & VT_BTYPE;
2496 cc = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2497 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2498 (sbt == VT_INT && dbt == VT_SHORT))
2499 && !(vtop->type.t & VT_BITFIELD) && !cc) {
2500 /* optimize char/short casts */
2501 delayed_cast = VT_MUSTCAST;
2502 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2503 /* XXX: factorize */
2504 if (ft & VT_CONSTANT)
2505 tcc_warning("assignment of read-only location");
2506 } else {
2507 delayed_cast = 0;
2508 if (!(ft & VT_BITFIELD))
2509 gen_assign_cast(&vtop[-1].type);
2512 if (sbt == VT_STRUCT) {
2513 /* if structure, only generate pointer */
2514 /* structure assignment : generate memcpy */
2515 /* XXX: optimize if small size */
2516 if (!nocode_wanted) {
2517 size = type_size(&vtop->type, &align);
2519 /* destination */
2520 vswap();
2521 vtop->type.t = VT_PTR;
2522 gaddrof();
2524 /* address of memcpy() */
2525 #ifdef TCC_ARM_EABI
2526 if(!(align & 7))
2527 vpush_global_sym(&func_old_type, TOK_memcpy8);
2528 else if(!(align & 3))
2529 vpush_global_sym(&func_old_type, TOK_memcpy4);
2530 else
2531 #endif
2532 vpush_global_sym(&func_old_type, TOK_memcpy);
2534 vswap();
2535 /* source */
2536 vpushv(vtop - 2);
2537 vtop->type.t = VT_PTR;
2538 gaddrof();
2539 /* type size */
2540 vpushi(size);
2541 gfunc_call(3);
2542 } else {
2543 vswap();
2544 vpop();
2546 /* leave source on stack */
2547 } else if (ft & VT_BITFIELD) {
2548 /* bitfield store handling */
2549 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2550 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2551 /* remove bit field info to avoid loops */
2552 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2554 if((ft & VT_BTYPE) == VT_BOOL) {
2555 gen_cast(&vtop[-1].type);
2556 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2559 /* duplicate destination */
2560 vdup();
2561 vtop[-1] = vtop[-2];
2563 /* mask and shift source */
2564 if((ft & VT_BTYPE) != VT_BOOL) {
2565 if((ft & VT_BTYPE) == VT_LLONG) {
2566 vpushll((1ULL << bit_size) - 1ULL);
2567 } else {
2568 vpushi((1 << bit_size) - 1);
2570 gen_op('&');
2572 vpushi(bit_pos);
2573 gen_op(TOK_SHL);
2574 /* load destination, mask and or with source */
2575 vswap();
2576 if((ft & VT_BTYPE) == VT_LLONG) {
2577 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2578 } else {
2579 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2581 gen_op('&');
2582 gen_op('|');
2583 /* store result */
2584 vstore();
2585 } else {
2586 #ifdef CONFIG_TCC_BCHECK
2587 /* bound check case */
2588 if (vtop[-1].r & VT_MUSTBOUND) {
2589 vswap();
2590 gbound();
2591 vswap();
2593 #endif
2594 if (!nocode_wanted) {
2595 rc = RC_INT;
2596 if (is_float(ft)) {
2597 rc = RC_FLOAT;
2598 #ifdef TCC_TARGET_X86_64
2599 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2600 rc = RC_ST0;
2601 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2602 rc = RC_FRET;
2604 #endif
2606 r = gv(rc); /* generate value */
2607 /* if lvalue was saved on stack, must read it */
2608 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2609 SValue sv;
2610 t = get_reg(RC_INT);
2611 #ifdef TCC_TARGET_X86_64
2612 sv.type.t = VT_PTR;
2613 #else
2614 sv.type.t = VT_INT;
2615 #endif
2616 sv.r = VT_LOCAL | VT_LVAL;
2617 sv.c.ul = vtop[-1].c.ul;
2618 load(t, &sv);
2619 vtop[-1].r = t | VT_LVAL;
2621 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2622 #ifdef TCC_TARGET_X86_64
2623 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2624 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2625 #else
2626 if ((ft & VT_BTYPE) == VT_LLONG) {
2627 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2628 #endif
2629 vtop[-1].type.t = load_type;
2630 store(r, vtop - 1);
2631 vswap();
2632 /* convert to int to increment easily */
2633 vtop->type.t = addr_type;
2634 gaddrof();
2635 vpushi(load_size);
2636 gen_op('+');
2637 vtop->r |= VT_LVAL;
2638 vswap();
2639 vtop[-1].type.t = load_type;
2640 /* XXX: it works because r2 is spilled last ! */
2641 store(vtop->r2, vtop - 1);
2642 } else {
2643 store(r, vtop - 1);
2646 vswap();
2647 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2648 vtop->r |= delayed_cast;
2652 /* post defines POST/PRE add. c is the token ++ or -- */
2653 ST_FUNC void inc(int post, int c)
2655 test_lvalue();
2656 vdup(); /* save lvalue */
2657 if (post) {
2658 gv_dup(); /* duplicate value */
2659 vrotb(3);
2660 vrotb(3);
2662 /* add constant */
2663 vpushi(c - TOK_MID);
2664 gen_op('+');
2665 vstore(); /* store value */
2666 if (post)
2667 vpop(); /* if post op, return saved value */
2670 /* Parse GNUC __attribute__ extension. Currently, the following
2671 extensions are recognized:
2672 - aligned(n) : set data/function alignment.
2673 - packed : force data alignment to 1
2674 - section(x) : generate data/code in this section.
2675 - unused : currently ignored, but may be used someday.
2676 - regparm(n) : pass function parameters in registers (i386 only)
2678 static void parse_attribute(AttributeDef *ad)
2680 int t, n;
2682 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2683 next();
2684 skip('(');
2685 skip('(');
2686 while (tok != ')') {
2687 if (tok < TOK_IDENT)
2688 expect("attribute name");
2689 t = tok;
2690 next();
2691 switch(t) {
2692 case TOK_SECTION1:
2693 case TOK_SECTION2:
2694 skip('(');
2695 if (tok != TOK_STR)
2696 expect("section name");
2697 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2698 next();
2699 skip(')');
2700 break;
2701 case TOK_ALIAS1:
2702 case TOK_ALIAS2:
2703 skip('(');
2704 if (tok != TOK_STR)
2705 expect("alias(\"target\")");
2706 ad->alias_target = /* save string as token, for later */
2707 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2708 next();
2709 skip(')');
2710 break;
2711 case TOK_VISIBILITY1:
2712 case TOK_VISIBILITY2:
2713 skip('(');
2714 if (tok != TOK_STR)
2715 expect("visibility(\"default|hidden|internal|protected\")");
2716 if (!strcmp (tokc.cstr->data, "default"))
2717 ad->a.visibility = STV_DEFAULT;
2718 else if (!strcmp (tokc.cstr->data, "hidden"))
2719 ad->a.visibility = STV_HIDDEN;
2720 else if (!strcmp (tokc.cstr->data, "internal"))
2721 ad->a.visibility = STV_INTERNAL;
2722 else if (!strcmp (tokc.cstr->data, "protected"))
2723 ad->a.visibility = STV_PROTECTED;
2724 else
2725 expect("visibility(\"default|hidden|internal|protected\")");
2726 next();
2727 skip(')');
2728 break;
2729 case TOK_ALIGNED1:
2730 case TOK_ALIGNED2:
2731 if (tok == '(') {
2732 next();
2733 n = expr_const();
2734 if (n <= 0 || (n & (n - 1)) != 0)
2735 tcc_error("alignment must be a positive power of two");
2736 skip(')');
2737 } else {
2738 n = MAX_ALIGN;
2740 ad->a.aligned = n;
2741 break;
2742 case TOK_PACKED1:
2743 case TOK_PACKED2:
2744 ad->a.packed = 1;
2745 break;
2746 case TOK_WEAK1:
2747 case TOK_WEAK2:
2748 ad->a.weak = 1;
2749 break;
2750 case TOK_UNUSED1:
2751 case TOK_UNUSED2:
2752 /* currently, no need to handle it because tcc does not
2753 track unused objects */
2754 break;
2755 case TOK_NORETURN1:
2756 case TOK_NORETURN2:
2757 /* currently, no need to handle it because tcc does not
2758 track unused objects */
2759 break;
2760 case TOK_CDECL1:
2761 case TOK_CDECL2:
2762 case TOK_CDECL3:
2763 ad->a.func_call = FUNC_CDECL;
2764 break;
2765 case TOK_STDCALL1:
2766 case TOK_STDCALL2:
2767 case TOK_STDCALL3:
2768 ad->a.func_call = FUNC_STDCALL;
2769 break;
2770 #ifdef TCC_TARGET_I386
2771 case TOK_REGPARM1:
2772 case TOK_REGPARM2:
2773 skip('(');
2774 n = expr_const();
2775 if (n > 3)
2776 n = 3;
2777 else if (n < 0)
2778 n = 0;
2779 if (n > 0)
2780 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
2781 skip(')');
2782 break;
2783 case TOK_FASTCALL1:
2784 case TOK_FASTCALL2:
2785 case TOK_FASTCALL3:
2786 ad->a.func_call = FUNC_FASTCALLW;
2787 break;
2788 #endif
2789 case TOK_MODE:
2790 skip('(');
2791 switch(tok) {
2792 case TOK_MODE_DI:
2793 ad->a.mode = VT_LLONG + 1;
2794 break;
2795 case TOK_MODE_HI:
2796 ad->a.mode = VT_SHORT + 1;
2797 break;
2798 case TOK_MODE_SI:
2799 ad->a.mode = VT_INT + 1;
2800 break;
2801 default:
2802 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2803 break;
2805 next();
2806 skip(')');
2807 break;
2808 case TOK_DLLEXPORT:
2809 ad->a.func_export = 1;
2810 break;
2811 case TOK_DLLIMPORT:
2812 ad->a.func_import = 1;
2813 break;
2814 default:
2815 if (tcc_state->warn_unsupported)
2816 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2817 /* skip parameters */
2818 if (tok == '(') {
2819 int parenthesis = 0;
2820 do {
2821 if (tok == '(')
2822 parenthesis++;
2823 else if (tok == ')')
2824 parenthesis--;
2825 next();
2826 } while (parenthesis && tok != -1);
2828 break;
2830 if (tok != ',')
2831 break;
2832 next();
2834 skip(')');
2835 skip(')');
2839 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2840 static void struct_decl(CType *type, int u, int tdef)
2842 int a, v, size, align, maxalign, c, offset, flexible;
2843 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2844 Sym *s, *ss, *ass, **ps;
2845 AttributeDef ad;
2846 CType type1, btype;
2848 a = tok; /* save decl type */
2849 next();
2850 if (tok != '{') {
2851 v = tok;
2852 next();
2853 /* struct already defined ? return it */
2854 if (v < TOK_IDENT)
2855 expect("struct/union/enum name");
2856 s = struct_find(v);
2857 if (s) {
2858 if (s->type.t != a)
2859 tcc_error("invalid type: '%s'", get_tok_str(v, NULL));
2860 goto do_decl;
2861 } else if (tok >= TOK_IDENT && !tdef)
2862 tcc_error("unknown struct/union/enum");
2863 } else {
2864 v = anon_sym++;
2866 type1.t = a;
2867 type1.ref = NULL;
2868 /* we put an undefined size for struct/union */
2869 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2870 s->r = 0; /* default alignment is zero as gcc */
2871 /* put struct/union/enum name in type */
2872 do_decl:
2873 type->t = u;
2874 type->ref = s;
2876 if (tok == '{') {
2877 next();
2878 if (s->c != -1)
2879 tcc_error("struct/union/enum already defined");
2880 /* cannot be empty */
2881 c = 0;
2882 /* non empty enums are not allowed */
2883 if (a == TOK_ENUM) {
2884 for(;;) {
2885 v = tok;
2886 if (v < TOK_UIDENT)
2887 expect("identifier");
2888 ss = sym_find(v);
2889 if (ss && !local_stack)
2890 tcc_error("redefinition of enumerator '%s'",
2891 get_tok_str(v, NULL));
2892 next();
2893 if (tok == '=') {
2894 next();
2895 c = expr_const();
2897 /* enum symbols have static storage */
2898 ss = sym_push(v, &int_type, VT_CONST, c);
2899 ss->type.t |= VT_STATIC;
2900 if (tok != ',')
2901 break;
2902 next();
2903 c++;
2904 /* NOTE: we accept a trailing comma */
2905 if (tok == '}')
2906 break;
2908 s->c = type_size(&int_type, &align);
2909 skip('}');
2910 } else {
2911 maxalign = 1;
2912 ps = &s->next;
2913 prevbt = VT_INT;
2914 bit_pos = 0;
2915 offset = 0;
2916 flexible = 0;
2917 while (tok != '}') {
2918 parse_btype(&btype, &ad);
2919 while (1) {
2920 if (flexible)
2921 tcc_error("flexible array member '%s' not at the end of struct",
2922 get_tok_str(v, NULL));
2923 bit_size = -1;
2924 v = 0;
2925 type1 = btype;
2926 if (tok != ':') {
2927 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2928 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2929 expect("identifier");
2930 if (type_size(&type1, &align) < 0) {
2931 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY))
2932 flexible = 1;
2933 else
2934 tcc_error("field '%s' has incomplete type",
2935 get_tok_str(v, NULL));
2937 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2938 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2939 tcc_error("invalid type for '%s'",
2940 get_tok_str(v, NULL));
2942 if (tok == ':') {
2943 next();
2944 bit_size = expr_const();
2945 /* XXX: handle v = 0 case for messages */
2946 if (bit_size < 0)
2947 tcc_error("negative width in bit-field '%s'",
2948 get_tok_str(v, NULL));
2949 if (v && bit_size == 0)
2950 tcc_error("zero width for bit-field '%s'",
2951 get_tok_str(v, NULL));
2953 size = type_size(&type1, &align);
2954 if (ad.a.aligned) {
2955 if (align < ad.a.aligned)
2956 align = ad.a.aligned;
2957 } else if (ad.a.packed) {
2958 align = 1;
2959 } else if (*tcc_state->pack_stack_ptr) {
2960 if (align > *tcc_state->pack_stack_ptr)
2961 align = *tcc_state->pack_stack_ptr;
2963 lbit_pos = 0;
2964 if (bit_size >= 0) {
2965 bt = type1.t & VT_BTYPE;
2966 if (bt != VT_INT &&
2967 bt != VT_BYTE &&
2968 bt != VT_SHORT &&
2969 bt != VT_BOOL &&
2970 bt != VT_ENUM &&
2971 bt != VT_LLONG)
2972 tcc_error("bitfields must have scalar type");
2973 bsize = size * 8;
2974 if (bit_size > bsize) {
2975 tcc_error("width of '%s' exceeds its type",
2976 get_tok_str(v, NULL));
2977 } else if (bit_size == bsize) {
2978 /* no need for bit fields */
2979 bit_pos = 0;
2980 } else if (bit_size == 0) {
2981 /* XXX: what to do if only padding in a
2982 structure ? */
2983 /* zero size: means to pad */
2984 bit_pos = 0;
2985 } else {
2986 /* we do not have enough room ?
2987 did the type change?
2988 is it a union? */
2989 if ((bit_pos + bit_size) > bsize ||
2990 bt != prevbt || a == TOK_UNION)
2991 bit_pos = 0;
2992 lbit_pos = bit_pos;
2993 /* XXX: handle LSB first */
2994 type1.t |= VT_BITFIELD |
2995 (bit_pos << VT_STRUCT_SHIFT) |
2996 (bit_size << (VT_STRUCT_SHIFT + 6));
2997 bit_pos += bit_size;
2999 prevbt = bt;
3000 } else {
3001 bit_pos = 0;
3003 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3004 /* add new memory data only if starting
3005 bit field */
3006 if (lbit_pos == 0) {
3007 if (a == TOK_STRUCT) {
3008 c = (c + align - 1) & -align;
3009 offset = c;
3010 if (size > 0)
3011 c += size;
3012 } else {
3013 offset = 0;
3014 if (size > c)
3015 c = size;
3017 if (align > maxalign)
3018 maxalign = align;
3020 #if 0
3021 printf("add field %s offset=%d",
3022 get_tok_str(v, NULL), offset);
3023 if (type1.t & VT_BITFIELD) {
3024 printf(" pos=%d size=%d",
3025 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3026 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3028 printf("\n");
3029 #endif
3031 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3032 ass = type1.ref;
3033 while ((ass = ass->next) != NULL) {
3034 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3035 *ps = ss;
3036 ps = &ss->next;
3038 } else if (v) {
3039 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3040 *ps = ss;
3041 ps = &ss->next;
3043 if (tok == ';' || tok == TOK_EOF)
3044 break;
3045 skip(',');
3047 skip(';');
3049 skip('}');
3050 if (!c && flexible)
3051 tcc_error("flexible array member '%s' in otherwise empty struct", get_tok_str(v, NULL));
3052 /* store size and alignment */
3053 s->c = (c + maxalign - 1) & -maxalign;
3054 s->r = maxalign;
3059 /* return 1 if basic type is a type size (short, long, long long) */
3060 ST_FUNC int is_btype_size(int bt)
3062 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3065 /* return 0 if no type declaration. otherwise, return the basic type
3066 and skip it.
3068 static int parse_btype(CType *type, AttributeDef *ad)
3070 int t, u, bt_size, complete, type_found, typespec_found;
3071 Sym *s;
3072 CType type1;
3074 memset(ad, 0, sizeof(AttributeDef));
3075 complete = 0;
3076 type_found = 0;
3077 typespec_found = 0;
3078 t = 0;
3079 while(1) {
3080 switch(tok) {
3081 case TOK_EXTENSION:
3082 /* currently, we really ignore extension */
3083 next();
3084 continue;
3086 /* basic types */
3087 case TOK_CHAR:
3088 u = VT_BYTE;
3089 basic_type:
3090 next();
3091 basic_type1:
3092 if (complete)
3093 tcc_error("too many basic types");
3094 t |= u;
3095 bt_size = is_btype_size (u & VT_BTYPE);
3096 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3097 complete = 1;
3098 typespec_found = 1;
3099 break;
3100 case TOK_VOID:
3101 u = VT_VOID;
3102 goto basic_type;
3103 case TOK_SHORT:
3104 u = VT_SHORT;
3105 goto basic_type;
3106 case TOK_INT:
3107 u = VT_INT;
3108 goto basic_type;
3109 case TOK_LONG:
3110 next();
3111 if ((t & VT_BTYPE) == VT_DOUBLE) {
3112 #ifndef TCC_TARGET_PE
3113 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3114 #endif
3115 } else if ((t & VT_BTYPE) == VT_LONG) {
3116 t = (t & ~VT_BTYPE) | VT_LLONG;
3117 } else {
3118 u = VT_LONG;
3119 goto basic_type1;
3121 break;
3122 case TOK_BOOL:
3123 u = VT_BOOL;
3124 goto basic_type;
3125 case TOK_FLOAT:
3126 u = VT_FLOAT;
3127 goto basic_type;
3128 case TOK_DOUBLE:
3129 next();
3130 if ((t & VT_BTYPE) == VT_LONG) {
3131 #ifdef TCC_TARGET_PE
3132 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3133 #else
3134 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3135 #endif
3136 } else {
3137 u = VT_DOUBLE;
3138 goto basic_type1;
3140 break;
3141 case TOK_ENUM:
3142 struct_decl(&type1, VT_ENUM, t & VT_TYPEDEF);
3143 basic_type2:
3144 u = type1.t;
3145 type->ref = type1.ref;
3146 goto basic_type1;
3147 case TOK_STRUCT:
3148 case TOK_UNION:
3149 struct_decl(&type1, VT_STRUCT, t & VT_TYPEDEF);
3150 goto basic_type2;
3152 /* type modifiers */
3153 case TOK_CONST1:
3154 case TOK_CONST2:
3155 case TOK_CONST3:
3156 t |= VT_CONSTANT;
3157 next();
3158 break;
3159 case TOK_VOLATILE1:
3160 case TOK_VOLATILE2:
3161 case TOK_VOLATILE3:
3162 t |= VT_VOLATILE;
3163 next();
3164 break;
3165 case TOK_SIGNED1:
3166 case TOK_SIGNED2:
3167 case TOK_SIGNED3:
3168 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3169 tcc_error("signed and unsigned modifier");
3170 typespec_found = 1;
3171 t |= VT_DEFSIGN;
3172 next();
3173 break;
3174 case TOK_REGISTER:
3175 case TOK_AUTO:
3176 case TOK_RESTRICT1:
3177 case TOK_RESTRICT2:
3178 case TOK_RESTRICT3:
3179 next();
3180 break;
3181 case TOK_UNSIGNED:
3182 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3183 tcc_error("signed and unsigned modifier");
3184 t |= VT_DEFSIGN | VT_UNSIGNED;
3185 next();
3186 typespec_found = 1;
3187 break;
3189 /* storage */
3190 case TOK_EXTERN:
3191 t |= VT_EXTERN;
3192 next();
3193 break;
3194 case TOK_STATIC:
3195 t |= VT_STATIC;
3196 next();
3197 break;
3198 case TOK_TYPEDEF:
3199 t |= VT_TYPEDEF;
3200 next();
3201 break;
3202 case TOK_INLINE1:
3203 case TOK_INLINE2:
3204 case TOK_INLINE3:
3205 t |= VT_INLINE;
3206 next();
3207 break;
3209 /* GNUC attribute */
3210 case TOK_ATTRIBUTE1:
3211 case TOK_ATTRIBUTE2:
3212 parse_attribute(ad);
3213 if (ad->a.mode) {
3214 u = ad->a.mode -1;
3215 t = (t & ~VT_BTYPE) | u;
3217 break;
3218 /* GNUC typeof */
3219 case TOK_TYPEOF1:
3220 case TOK_TYPEOF2:
3221 case TOK_TYPEOF3:
3222 next();
3223 parse_expr_type(&type1);
3224 /* remove all storage modifiers except typedef */
3225 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3226 goto basic_type2;
3227 default:
3228 if (typespec_found)
3229 goto the_end;
3230 s = sym_find(tok);
3231 if (!s || !(s->type.t & VT_TYPEDEF))
3232 goto the_end;
3233 t |= (s->type.t & ~VT_TYPEDEF);
3234 type->ref = s->type.ref;
3235 if (s->r) {
3236 /* get attributes from typedef */
3237 if (0 == ad->a.aligned)
3238 ad->a.aligned = s->a.aligned;
3239 if (0 == ad->a.func_call)
3240 ad->a.func_call = s->a.func_call;
3241 ad->a.packed |= s->a.packed;
3243 next();
3244 typespec_found = 1;
3245 break;
3247 type_found = 1;
3249 the_end:
3250 if (tcc_state->char_is_unsigned) {
3251 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3252 t |= VT_UNSIGNED;
3255 /* long is never used as type */
3256 if ((t & VT_BTYPE) == VT_LONG)
3257 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3258 t = (t & ~VT_BTYPE) | VT_INT;
3259 #else
3260 t = (t & ~VT_BTYPE) | VT_LLONG;
3261 #endif
3262 type->t = t;
3263 return type_found;
3266 /* convert a function parameter type (array to pointer and function to
3267 function pointer) */
3268 static inline void convert_parameter_type(CType *pt)
3270 /* remove const and volatile qualifiers (XXX: const could be used
3271 to indicate a const function parameter */
3272 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3273 /* array must be transformed to pointer according to ANSI C */
3274 pt->t &= ~VT_ARRAY;
3275 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3276 mk_pointer(pt);
3280 ST_FUNC void parse_asm_str(CString *astr)
3282 skip('(');
3283 /* read the string */
3284 if (tok != TOK_STR)
3285 expect("string constant");
3286 cstr_new(astr);
3287 while (tok == TOK_STR) {
3288 /* XXX: add \0 handling too ? */
3289 cstr_cat(astr, tokc.cstr->data);
3290 next();
3292 cstr_ccat(astr, '\0');
3295 /* Parse an asm label and return the label
3296 * Don't forget to free the CString in the caller! */
3297 static void asm_label_instr(CString *astr)
3299 next();
3300 parse_asm_str(astr);
3301 skip(')');
3302 #ifdef ASM_DEBUG
3303 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3304 #endif
3307 static void post_type(CType *type, AttributeDef *ad)
3309 int n, l, t1, arg_size, align;
3310 Sym **plast, *s, *first;
3311 AttributeDef ad1;
3312 CType pt;
3314 if (tok == '(') {
3315 /* function declaration */
3316 next();
3317 l = 0;
3318 first = NULL;
3319 plast = &first;
3320 arg_size = 0;
3321 if (tok != ')') {
3322 for(;;) {
3323 /* read param name and compute offset */
3324 if (l != FUNC_OLD) {
3325 if (!parse_btype(&pt, &ad1)) {
3326 if (l) {
3327 tcc_error("invalid type");
3328 } else {
3329 l = FUNC_OLD;
3330 goto old_proto;
3333 l = FUNC_NEW;
3334 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3335 break;
3336 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3337 if ((pt.t & VT_BTYPE) == VT_VOID)
3338 tcc_error("parameter declared as void");
3339 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3340 } else {
3341 old_proto:
3342 n = tok;
3343 if (n < TOK_UIDENT)
3344 expect("identifier");
3345 pt.t = VT_INT;
3346 next();
3348 convert_parameter_type(&pt);
3349 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3350 *plast = s;
3351 plast = &s->next;
3352 if (tok == ')')
3353 break;
3354 skip(',');
3355 if (l == FUNC_NEW && tok == TOK_DOTS) {
3356 l = FUNC_ELLIPSIS;
3357 next();
3358 break;
3362 /* if no parameters, then old type prototype */
3363 if (l == 0)
3364 l = FUNC_OLD;
3365 skip(')');
3366 /* NOTE: const is ignored in returned type as it has a special
3367 meaning in gcc / C++ */
3368 type->t &= ~VT_CONSTANT;
3369 /* some ancient pre-K&R C allows a function to return an array
3370 and the array brackets to be put after the arguments, such
3371 that "int c()[]" means something like "int[] c()" */
3372 if (tok == '[') {
3373 next();
3374 skip(']'); /* only handle simple "[]" */
3375 type->t |= VT_PTR;
3377 /* we push a anonymous symbol which will contain the function prototype */
3378 ad->a.func_args = arg_size;
3379 s = sym_push(SYM_FIELD, type, 0, l);
3380 s->a = ad->a;
3381 s->next = first;
3382 type->t = VT_FUNC;
3383 type->ref = s;
3384 } else if (tok == '[') {
3385 /* array definition */
3386 next();
3387 if (tok == TOK_RESTRICT1)
3388 next();
3389 n = -1;
3390 t1 = 0;
3391 if (tok != ']') {
3392 if (!local_stack || nocode_wanted)
3393 vpushi(expr_const());
3394 else gexpr();
3395 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3396 n = vtop->c.i;
3397 if (n < 0)
3398 tcc_error("invalid array size");
3399 } else {
3400 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3401 tcc_error("size of variable length array should be an integer");
3402 t1 = VT_VLA;
3405 skip(']');
3406 /* parse next post type */
3407 post_type(type, ad);
3408 if (type->t == VT_FUNC)
3409 tcc_error("declaration of an array of functions");
3410 t1 |= type->t & VT_VLA;
3412 if (t1 & VT_VLA) {
3413 loc -= type_size(&int_type, &align);
3414 loc &= -align;
3415 n = loc;
3417 vla_runtime_type_size(type, &align);
3418 gen_op('*');
3419 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3420 vswap();
3421 vstore();
3423 if (n != -1)
3424 vpop();
3426 /* we push an anonymous symbol which will contain the array
3427 element type */
3428 s = sym_push(SYM_FIELD, type, 0, n);
3429 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3430 type->ref = s;
3434 /* Parse a type declaration (except basic type), and return the type
3435 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3436 expected. 'type' should contain the basic type. 'ad' is the
3437 attribute definition of the basic type. It can be modified by
3438 type_decl().
3440 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3442 Sym *s;
3443 CType type1, *type2;
3444 int qualifiers, storage;
3446 while (tok == '*') {
3447 qualifiers = 0;
3448 redo:
3449 next();
3450 switch(tok) {
3451 case TOK_CONST1:
3452 case TOK_CONST2:
3453 case TOK_CONST3:
3454 qualifiers |= VT_CONSTANT;
3455 goto redo;
3456 case TOK_VOLATILE1:
3457 case TOK_VOLATILE2:
3458 case TOK_VOLATILE3:
3459 qualifiers |= VT_VOLATILE;
3460 goto redo;
3461 case TOK_RESTRICT1:
3462 case TOK_RESTRICT2:
3463 case TOK_RESTRICT3:
3464 goto redo;
3466 mk_pointer(type);
3467 type->t |= qualifiers;
3470 /* XXX: clarify attribute handling */
3471 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3472 parse_attribute(ad);
3474 /* recursive type */
3475 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3476 type1.t = 0; /* XXX: same as int */
3477 if (tok == '(') {
3478 next();
3479 /* XXX: this is not correct to modify 'ad' at this point, but
3480 the syntax is not clear */
3481 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3482 parse_attribute(ad);
3483 type_decl(&type1, ad, v, td);
3484 skip(')');
3485 } else {
3486 /* type identifier */
3487 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3488 *v = tok;
3489 next();
3490 } else {
3491 if (!(td & TYPE_ABSTRACT))
3492 expect("identifier");
3493 *v = 0;
3496 storage = type->t & VT_STORAGE;
3497 type->t &= ~VT_STORAGE;
3498 if (storage & VT_STATIC) {
3499 int saved_nocode_wanted = nocode_wanted;
3500 nocode_wanted = 1;
3501 post_type(type, ad);
3502 nocode_wanted = saved_nocode_wanted;
3503 } else
3504 post_type(type, ad);
3505 type->t |= storage;
3506 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3507 parse_attribute(ad);
3509 if (!type1.t)
3510 return;
3511 /* append type at the end of type1 */
3512 type2 = &type1;
3513 for(;;) {
3514 s = type2->ref;
3515 type2 = &s->type;
3516 if (!type2->t) {
3517 *type2 = *type;
3518 break;
3521 *type = type1;
3524 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3525 ST_FUNC int lvalue_type(int t)
3527 int bt, r;
3528 r = VT_LVAL;
3529 bt = t & VT_BTYPE;
3530 if (bt == VT_BYTE || bt == VT_BOOL)
3531 r |= VT_LVAL_BYTE;
3532 else if (bt == VT_SHORT)
3533 r |= VT_LVAL_SHORT;
3534 else
3535 return r;
3536 if (t & VT_UNSIGNED)
3537 r |= VT_LVAL_UNSIGNED;
3538 return r;
3541 /* indirection with full error checking and bound check */
3542 ST_FUNC void indir(void)
3544 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3545 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3546 return;
3547 expect("pointer");
3549 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3550 gv(RC_INT);
3551 vtop->type = *pointed_type(&vtop->type);
3552 /* Arrays and functions are never lvalues */
3553 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3554 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3555 vtop->r |= lvalue_type(vtop->type.t);
3556 /* if bound checking, the referenced pointer must be checked */
3557 #ifdef CONFIG_TCC_BCHECK
3558 if (tcc_state->do_bounds_check)
3559 vtop->r |= VT_MUSTBOUND;
3560 #endif
3564 /* pass a parameter to a function and do type checking and casting */
3565 static void gfunc_param_typed(Sym *func, Sym *arg)
3567 int func_type;
3568 CType type;
3570 func_type = func->c;
3571 if (func_type == FUNC_OLD ||
3572 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3573 /* default casting : only need to convert float to double */
3574 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3575 type.t = VT_DOUBLE;
3576 gen_cast(&type);
3577 } else if (vtop->type.t & VT_BITFIELD) {
3578 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3579 gen_cast(&type);
3581 } else if (arg == NULL) {
3582 tcc_error("too many arguments to function");
3583 } else {
3584 type = arg->type;
3585 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3586 gen_assign_cast(&type);
3590 /* parse an expression of the form '(type)' or '(expr)' and return its
3591 type */
3592 static void parse_expr_type(CType *type)
3594 int n;
3595 AttributeDef ad;
3597 skip('(');
3598 if (parse_btype(type, &ad)) {
3599 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3600 } else {
3601 expr_type(type);
3603 skip(')');
3606 static void parse_type(CType *type)
3608 AttributeDef ad;
3609 int n;
3611 if (!parse_btype(type, &ad)) {
3612 expect("type");
3614 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3617 static void vpush_tokc(int t)
3619 CType type;
3620 type.t = t;
3621 type.ref = 0;
3622 vsetc(&type, VT_CONST, &tokc);
3625 ST_FUNC void unary(void)
3627 int n, t, align, size, r, sizeof_caller;
3628 CType type;
3629 Sym *s;
3630 AttributeDef ad;
3631 static int in_sizeof = 0;
3633 sizeof_caller = in_sizeof;
3634 in_sizeof = 0;
3635 /* XXX: GCC 2.95.3 does not generate a table although it should be
3636 better here */
3637 tok_next:
3638 switch(tok) {
3639 case TOK_EXTENSION:
3640 next();
3641 goto tok_next;
3642 case TOK_CINT:
3643 case TOK_CCHAR:
3644 case TOK_LCHAR:
3645 vpushi(tokc.i);
3646 next();
3647 break;
3648 case TOK_CUINT:
3649 vpush_tokc(VT_INT | VT_UNSIGNED);
3650 next();
3651 break;
3652 case TOK_CLLONG:
3653 vpush_tokc(VT_LLONG);
3654 next();
3655 break;
3656 case TOK_CULLONG:
3657 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3658 next();
3659 break;
3660 case TOK_CFLOAT:
3661 vpush_tokc(VT_FLOAT);
3662 next();
3663 break;
3664 case TOK_CDOUBLE:
3665 vpush_tokc(VT_DOUBLE);
3666 next();
3667 break;
3668 case TOK_CLDOUBLE:
3669 vpush_tokc(VT_LDOUBLE);
3670 next();
3671 break;
3672 case TOK___FUNCTION__:
3673 if (!gnu_ext)
3674 goto tok_identifier;
3675 /* fall thru */
3676 case TOK___FUNC__:
3678 void *ptr;
3679 int len;
3680 /* special function name identifier */
3681 len = strlen(funcname) + 1;
3682 /* generate char[len] type */
3683 type.t = VT_BYTE;
3684 mk_pointer(&type);
3685 type.t |= VT_ARRAY;
3686 type.ref->c = len;
3687 vpush_ref(&type, data_section, data_section->data_offset, len);
3688 ptr = section_ptr_add(data_section, len);
3689 memcpy(ptr, funcname, len);
3690 next();
3692 break;
3693 case TOK_LSTR:
3694 #ifdef TCC_TARGET_PE
3695 t = VT_SHORT | VT_UNSIGNED;
3696 #else
3697 t = VT_INT;
3698 #endif
3699 goto str_init;
3700 case TOK_STR:
3701 /* string parsing */
3702 t = VT_BYTE;
3703 str_init:
3704 if (tcc_state->warn_write_strings)
3705 t |= VT_CONSTANT;
3706 type.t = t;
3707 mk_pointer(&type);
3708 type.t |= VT_ARRAY;
3709 memset(&ad, 0, sizeof(AttributeDef));
3710 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3711 break;
3712 case '(':
3713 next();
3714 /* cast ? */
3715 if (parse_btype(&type, &ad)) {
3716 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3717 skip(')');
3718 /* check ISOC99 compound literal */
3719 if (tok == '{') {
3720 /* data is allocated locally by default */
3721 if (global_expr)
3722 r = VT_CONST;
3723 else
3724 r = VT_LOCAL;
3725 /* all except arrays are lvalues */
3726 if (!(type.t & VT_ARRAY))
3727 r |= lvalue_type(type.t);
3728 memset(&ad, 0, sizeof(AttributeDef));
3729 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3730 } else {
3731 if (sizeof_caller) {
3732 vpush(&type);
3733 return;
3735 unary();
3736 is_force = 1;
3737 gen_cast(&type);
3738 is_force = 0;
3740 } else if (tok == '{') {
3741 /* save all registers */
3742 save_regs(0);
3743 /* statement expression : we do not accept break/continue
3744 inside as GCC does */
3745 block(NULL, NULL, NULL, NULL, 0, 1);
3746 skip(')');
3747 } else {
3748 gexpr();
3749 skip(')');
3751 break;
3752 case '*':
3753 next();
3754 unary();
3755 indir();
3756 break;
3757 case '&':
3758 next();
3759 unary();
3760 /* functions names must be treated as function pointers,
3761 except for unary '&' and sizeof. Since we consider that
3762 functions are not lvalues, we only have to handle it
3763 there and in function calls. */
3764 /* arrays can also be used although they are not lvalues */
3765 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3766 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3767 test_lvalue();
3768 mk_pointer(&vtop->type);
3769 gaddrof();
3770 break;
3771 case '!':
3772 next();
3773 unary();
3774 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3775 CType boolean;
3776 boolean.t = VT_BOOL;
3777 gen_cast(&boolean);
3778 vtop->c.i = !vtop->c.i;
3779 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3780 vtop->c.i = vtop->c.i ^ 1;
3781 else {
3782 save_regs(1);
3783 vseti(VT_JMP, gvtst(1, 0));
3785 break;
3786 case '~':
3787 next();
3788 unary();
3789 vpushi(-1);
3790 gen_op('^');
3791 break;
3792 case '+':
3793 next();
3794 unary();
3795 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3796 tcc_error("pointer not accepted for unary plus");
3797 /* In order to force cast, we add zero, except for floating point
3798 where we really need an noop (otherwise -0.0 will be transformed
3799 into +0.0). */
3800 if (!is_float(vtop->type.t)) {
3801 vpushi(0);
3802 gen_op('+');
3804 break;
3805 case TOK_SIZEOF:
3806 case TOK_ALIGNOF1:
3807 case TOK_ALIGNOF2:
3808 t = tok;
3809 next();
3810 in_sizeof++;
3811 unary_type(&type); // Perform a in_sizeof = 0;
3812 size = type_size(&type, &align);
3813 if (t == TOK_SIZEOF) {
3814 if (!(type.t & VT_VLA)) {
3815 if (size < 0)
3816 tcc_error("sizeof applied to an incomplete type");
3817 if(type.t & VT_BITFIELD)
3818 tcc_error("'%s' applied to a bit-field", get_tok_str(t, NULL));
3819 vpushs(size);
3820 } else {
3821 vla_runtime_type_size(&type, &align);
3823 } else {
3824 vpushs(align);
3826 vtop->type.t |= VT_UNSIGNED;
3827 break;
3829 case TOK_builtin_types_compatible_p:
3831 CType type1, type2;
3832 next();
3833 skip('(');
3834 parse_type(&type1);
3835 skip(',');
3836 parse_type(&type2);
3837 skip(')');
3838 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3839 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3840 vpushi(is_compatible_types(&type1, &type2));
3842 break;
3843 case TOK_builtin_constant_p:
3845 int saved_nocode_wanted, res;
3846 next();
3847 skip('(');
3848 saved_nocode_wanted = nocode_wanted;
3849 nocode_wanted = 1;
3850 gexpr();
3851 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3852 vpop();
3853 nocode_wanted = saved_nocode_wanted;
3854 skip(')');
3855 vpushi(res);
3857 break;
3858 case TOK_builtin_frame_address:
3860 int level;
3861 CType type;
3862 next();
3863 skip('(');
3864 if (tok != TOK_CINT || tokc.i < 0) {
3865 tcc_error("__builtin_frame_address only takes positive integers");
3867 level = tokc.i;
3868 next();
3869 skip(')');
3870 type.t = VT_VOID;
3871 mk_pointer(&type);
3872 vset(&type, VT_LOCAL, 0); /* local frame */
3873 while (level--) {
3874 mk_pointer(&vtop->type);
3875 indir(); /* -> parent frame */
3878 break;
3879 #ifdef TCC_TARGET_X86_64
3880 #ifdef TCC_TARGET_PE
3881 case TOK_builtin_va_start:
3883 next();
3884 skip('(');
3885 expr_eq();
3886 skip(',');
3887 expr_eq();
3888 skip(')');
3889 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
3890 tcc_error("__builtin_va_start expects a local variable");
3891 vtop->r &= ~(VT_LVAL | VT_REF);
3892 vtop->type = char_pointer_type;
3893 vstore();
3895 break;
3896 #else
3897 case TOK_builtin_va_arg_types:
3899 CType type;
3900 next();
3901 skip('(');
3902 parse_type(&type);
3903 skip(')');
3904 vpushi(classify_x86_64_va_arg(&type));
3906 break;
3907 #endif
3908 #endif
3909 case TOK_INC:
3910 case TOK_DEC:
3911 t = tok;
3912 next();
3913 unary();
3914 inc(0, t);
3915 break;
3916 case '-':
3917 next();
3918 unary();
3919 t = vtop->type.t & VT_BTYPE;
3920 if (is_float(t)) {
3921 /* In IEEE negate(x) isn't subtract(0,x), but rather
3922 subtract(-0, x). */
3923 vpush(&vtop->type);
3924 if (t == VT_FLOAT)
3925 vtop->c.f = -0.0f;
3926 else if (t == VT_DOUBLE)
3927 vtop->c.d = -0.0;
3928 else
3929 vtop->c.ld = -0.0;
3930 } else
3931 vpushi(0);
3932 vswap();
3933 gen_op('-');
3934 break;
3935 case TOK_LAND:
3936 if (!gnu_ext)
3937 goto tok_identifier;
3938 next();
3939 /* allow to take the address of a label */
3940 if (tok < TOK_UIDENT)
3941 expect("label identifier");
3942 s = label_find(tok);
3943 if (!s) {
3944 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3945 } else {
3946 if (s->r == LABEL_DECLARED)
3947 s->r = LABEL_FORWARD;
3949 if (!s->type.t) {
3950 s->type.t = VT_VOID;
3951 mk_pointer(&s->type);
3952 s->type.t |= VT_STATIC;
3954 vpushsym(&s->type, s);
3955 next();
3956 break;
3958 // special qnan , snan and infinity values
3959 case TOK___NAN__:
3960 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3961 next();
3962 break;
3963 case TOK___SNAN__:
3964 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3965 next();
3966 break;
3967 case TOK___INF__:
3968 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3969 next();
3970 break;
3972 default:
3973 tok_identifier:
3974 t = tok;
3975 next();
3976 if (t < TOK_UIDENT)
3977 expect("identifier");
3978 s = sym_find(t);
3979 if (!s) {
3980 const char *name = get_tok_str(t, NULL);
3981 if (tok != '(')
3982 tcc_error("'%s' undeclared", name);
3983 /* for simple function calls, we tolerate undeclared
3984 external reference to int() function */
3985 if (tcc_state->warn_implicit_function_declaration
3986 #ifdef TCC_TARGET_PE
3987 /* people must be warned about using undeclared WINAPI functions
3988 (which usually start with uppercase letter) */
3989 || (name[0] >= 'A' && name[0] <= 'Z')
3990 #endif
3992 tcc_warning("implicit declaration of function '%s'", name);
3993 s = external_sym(t, &func_old_type, 0, NULL);
3995 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3996 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3997 /* if referencing an inline function, then we generate a
3998 symbol to it if not already done. It will have the
3999 effect to generate code for it at the end of the
4000 compilation unit. Inline function as always
4001 generated in the text section. */
4002 if (!s->c)
4003 put_extern_sym(s, text_section, 0, 0);
4004 r = VT_SYM | VT_CONST;
4005 } else {
4006 r = s->r;
4008 vset(&s->type, r, s->c);
4009 /* if forward reference, we must point to s */
4010 if (vtop->r & VT_SYM) {
4011 vtop->sym = s;
4012 vtop->c.ptr_offset = 0;
4014 break;
4017 /* post operations */
4018 while (1) {
4019 if (tok == TOK_INC || tok == TOK_DEC) {
4020 inc(1, tok);
4021 next();
4022 } else if (tok == '.' || tok == TOK_ARROW) {
4023 int qualifiers;
4024 /* field */
4025 if (tok == TOK_ARROW)
4026 indir();
4027 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4028 test_lvalue();
4029 gaddrof();
4030 next();
4031 /* expect pointer on structure */
4032 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4033 expect("struct or union");
4034 s = vtop->type.ref;
4035 /* find field */
4036 tok |= SYM_FIELD;
4037 while ((s = s->next) != NULL) {
4038 if (s->v == tok)
4039 break;
4041 if (!s)
4042 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
4043 /* add field offset to pointer */
4044 vtop->type = char_pointer_type; /* change type to 'char *' */
4045 vpushi(s->c);
4046 gen_op('+');
4047 /* change type to field type, and set to lvalue */
4048 vtop->type = s->type;
4049 vtop->type.t |= qualifiers;
4050 /* an array is never an lvalue */
4051 if (!(vtop->type.t & VT_ARRAY)) {
4052 vtop->r |= lvalue_type(vtop->type.t);
4053 #ifdef CONFIG_TCC_BCHECK
4054 /* if bound checking, the referenced pointer must be checked */
4055 if (tcc_state->do_bounds_check)
4056 vtop->r |= VT_MUSTBOUND;
4057 #endif
4059 next();
4060 } else if (tok == '[') {
4061 next();
4062 gexpr();
4063 gen_op('+');
4064 indir();
4065 skip(']');
4066 } else if (tok == '(') {
4067 SValue ret;
4068 Sym *sa;
4069 int nb_args, ret_nregs, ret_align, variadic;
4071 /* function call */
4072 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4073 /* pointer test (no array accepted) */
4074 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4075 vtop->type = *pointed_type(&vtop->type);
4076 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4077 goto error_func;
4078 } else {
4079 error_func:
4080 expect("function pointer");
4082 } else {
4083 vtop->r &= ~VT_LVAL; /* no lvalue */
4085 /* get return type */
4086 s = vtop->type.ref;
4087 next();
4088 sa = s->next; /* first parameter */
4089 nb_args = 0;
4090 ret.r2 = VT_CONST;
4091 /* compute first implicit argument if a structure is returned */
4092 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4093 variadic = (s->c == FUNC_ELLIPSIS);
4094 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4095 &ret_align);
4096 if (!ret_nregs) {
4097 /* get some space for the returned structure */
4098 size = type_size(&s->type, &align);
4099 loc = (loc - size) & -align;
4100 ret.type = s->type;
4101 ret.r = VT_LOCAL | VT_LVAL;
4102 /* pass it as 'int' to avoid structure arg passing
4103 problems */
4104 vseti(VT_LOCAL, loc);
4105 ret.c = vtop->c;
4106 nb_args++;
4108 } else {
4109 ret_nregs = 1;
4110 ret.type = s->type;
4113 if (ret_nregs) {
4114 /* return in register */
4115 if (is_float(ret.type.t)) {
4116 ret.r = reg_fret(ret.type.t);
4117 #ifdef TCC_TARGET_X86_64
4118 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4119 ret.r2 = REG_QRET;
4120 #endif
4121 } else {
4122 #ifdef TCC_TARGET_X86_64
4123 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4124 #else
4125 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4126 #endif
4127 ret.r2 = REG_LRET;
4128 ret.r = REG_IRET;
4130 ret.c.i = 0;
4132 if (tok != ')') {
4133 for(;;) {
4134 expr_eq();
4135 gfunc_param_typed(s, sa);
4136 nb_args++;
4137 if (sa)
4138 sa = sa->next;
4139 if (tok == ')')
4140 break;
4141 skip(',');
4144 if (sa)
4145 tcc_error("too few arguments to function");
4146 skip(')');
4147 if (!nocode_wanted) {
4148 gfunc_call(nb_args);
4149 } else {
4150 vtop -= (nb_args + 1);
4153 /* return value */
4154 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4155 vsetc(&ret.type, r, &ret.c);
4156 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4159 /* handle packed struct return */
4160 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4161 int addr, offset;
4163 size = type_size(&s->type, &align);
4164 loc = (loc - size) & -align;
4165 addr = loc;
4166 offset = 0;
4167 for (;;) {
4168 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4169 vswap();
4170 vstore();
4171 vtop--;
4172 if (--ret_nregs == 0)
4173 break;
4174 /* XXX: compatible with arm only: ret_align == register_size */
4175 offset += ret_align;
4177 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4179 } else {
4180 break;
4185 ST_FUNC void expr_prod(void)
4187 int t;
4189 unary();
4190 while (tok == '*' || tok == '/' || tok == '%') {
4191 t = tok;
4192 next();
4193 unary();
4194 gen_op(t);
4198 ST_FUNC void expr_sum(void)
4200 int t;
4202 expr_prod();
4203 while (tok == '+' || tok == '-') {
4204 t = tok;
4205 next();
4206 expr_prod();
4207 gen_op(t);
4211 static void expr_shift(void)
4213 int t;
4215 expr_sum();
4216 while (tok == TOK_SHL || tok == TOK_SAR) {
4217 t = tok;
4218 next();
4219 expr_sum();
4220 gen_op(t);
4224 static void expr_cmp(void)
4226 int t;
4228 expr_shift();
4229 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4230 tok == TOK_ULT || tok == TOK_UGE) {
4231 t = tok;
4232 next();
4233 expr_shift();
4234 gen_op(t);
4238 static void expr_cmpeq(void)
4240 int t;
4242 expr_cmp();
4243 while (tok == TOK_EQ || tok == TOK_NE) {
4244 t = tok;
4245 next();
4246 expr_cmp();
4247 gen_op(t);
4251 static void expr_and(void)
4253 expr_cmpeq();
4254 while (tok == '&') {
4255 next();
4256 expr_cmpeq();
4257 gen_op('&');
4261 static void expr_xor(void)
4263 expr_and();
4264 while (tok == '^') {
4265 next();
4266 expr_and();
4267 gen_op('^');
4271 static void expr_or(void)
4273 expr_xor();
4274 while (tok == '|') {
4275 next();
4276 expr_xor();
4277 gen_op('|');
4281 /* XXX: fix this mess */
4282 static void expr_land_const(void)
4284 expr_or();
4285 while (tok == TOK_LAND) {
4286 next();
4287 expr_or();
4288 gen_op(TOK_LAND);
4292 /* XXX: fix this mess */
4293 static void expr_lor_const(void)
4295 expr_land_const();
4296 while (tok == TOK_LOR) {
4297 next();
4298 expr_land_const();
4299 gen_op(TOK_LOR);
4303 /* only used if non constant */
4304 static void expr_land(void)
4306 int t;
4308 expr_or();
4309 if (tok == TOK_LAND) {
4310 t = 0;
4311 save_regs(1);
4312 for(;;) {
4313 t = gvtst(1, t);
4314 if (tok != TOK_LAND) {
4315 vseti(VT_JMPI, t);
4316 break;
4318 next();
4319 expr_or();
4324 static void expr_lor(void)
4326 int t;
4328 expr_land();
4329 if (tok == TOK_LOR) {
4330 t = 0;
4331 save_regs(1);
4332 for(;;) {
4333 t = gvtst(0, t);
4334 if (tok != TOK_LOR) {
4335 vseti(VT_JMP, t);
4336 break;
4338 next();
4339 expr_land();
4344 /* XXX: better constant handling */
4345 static void expr_cond(void)
4347 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4348 SValue sv;
4349 CType type, type1, type2;
4351 if (const_wanted) {
4352 expr_lor_const();
4353 if (tok == '?') {
4354 CType boolean;
4355 int c;
4356 boolean.t = VT_BOOL;
4357 vdup();
4358 gen_cast(&boolean);
4359 c = vtop->c.i;
4360 vpop();
4361 next();
4362 if (tok != ':' || !gnu_ext) {
4363 vpop();
4364 gexpr();
4366 if (!c)
4367 vpop();
4368 skip(':');
4369 expr_cond();
4370 if (c)
4371 vpop();
4373 } else {
4374 expr_lor();
4375 if (tok == '?') {
4376 next();
4377 if (vtop != vstack) {
4378 /* needed to avoid having different registers saved in
4379 each branch */
4380 if (is_float(vtop->type.t)) {
4381 rc = RC_FLOAT;
4382 #ifdef TCC_TARGET_X86_64
4383 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4384 rc = RC_ST0;
4386 #endif
4388 else
4389 rc = RC_INT;
4390 gv(rc);
4391 save_regs(1);
4393 if (tok == ':' && gnu_ext) {
4394 gv_dup();
4395 tt = gvtst(1, 0);
4396 } else {
4397 tt = gvtst(1, 0);
4398 gexpr();
4400 type1 = vtop->type;
4401 sv = *vtop; /* save value to handle it later */
4402 vtop--; /* no vpop so that FP stack is not flushed */
4403 skip(':');
4404 u = gjmp(0);
4405 gsym(tt);
4406 expr_cond();
4407 type2 = vtop->type;
4409 t1 = type1.t;
4410 bt1 = t1 & VT_BTYPE;
4411 t2 = type2.t;
4412 bt2 = t2 & VT_BTYPE;
4413 /* cast operands to correct type according to ISOC rules */
4414 if (is_float(bt1) || is_float(bt2)) {
4415 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4416 type.t = VT_LDOUBLE;
4417 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4418 type.t = VT_DOUBLE;
4419 } else {
4420 type.t = VT_FLOAT;
4422 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4423 /* cast to biggest op */
4424 type.t = VT_LLONG;
4425 /* convert to unsigned if it does not fit in a long long */
4426 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4427 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4428 type.t |= VT_UNSIGNED;
4429 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4430 /* If one is a null ptr constant the result type
4431 is the other. */
4432 if (is_null_pointer (vtop))
4433 type = type1;
4434 else if (is_null_pointer (&sv))
4435 type = type2;
4436 /* XXX: test pointer compatibility, C99 has more elaborate
4437 rules here. */
4438 else
4439 type = type1;
4440 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4441 /* XXX: test function pointer compatibility */
4442 type = bt1 == VT_FUNC ? type1 : type2;
4443 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4444 /* XXX: test structure compatibility */
4445 type = bt1 == VT_STRUCT ? type1 : type2;
4446 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4447 /* NOTE: as an extension, we accept void on only one side */
4448 type.t = VT_VOID;
4449 } else {
4450 /* integer operations */
4451 type.t = VT_INT;
4452 /* convert to unsigned if it does not fit in an integer */
4453 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4454 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4455 type.t |= VT_UNSIGNED;
4458 /* now we convert second operand */
4459 gen_cast(&type);
4460 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4461 gaddrof();
4462 rc = RC_INT;
4463 if (is_float(type.t)) {
4464 rc = RC_FLOAT;
4465 #ifdef TCC_TARGET_X86_64
4466 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4467 rc = RC_ST0;
4469 #endif
4470 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4471 /* for long longs, we use fixed registers to avoid having
4472 to handle a complicated move */
4473 rc = RC_IRET;
4476 r2 = gv(rc);
4477 /* this is horrible, but we must also convert first
4478 operand */
4479 tt = gjmp(0);
4480 gsym(u);
4481 /* put again first value and cast it */
4482 *vtop = sv;
4483 gen_cast(&type);
4484 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4485 gaddrof();
4486 r1 = gv(rc);
4487 move_reg(r2, r1, type.t);
4488 vtop->r = r2;
4489 gsym(tt);
4494 static void expr_eq(void)
4496 int t;
4498 expr_cond();
4499 if (tok == '=' ||
4500 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4501 tok == TOK_A_XOR || tok == TOK_A_OR ||
4502 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4503 test_lvalue();
4504 t = tok;
4505 next();
4506 if (t == '=') {
4507 expr_eq();
4508 } else {
4509 vdup();
4510 expr_eq();
4511 gen_op(t & 0x7f);
4513 vstore();
4517 ST_FUNC void gexpr(void)
4519 while (1) {
4520 expr_eq();
4521 if (tok != ',')
4522 break;
4523 vpop();
4524 next();
4528 /* parse an expression and return its type without any side effect. */
4529 static void expr_type(CType *type)
4531 int saved_nocode_wanted;
4533 saved_nocode_wanted = nocode_wanted;
4534 nocode_wanted = 1;
4535 gexpr();
4536 *type = vtop->type;
4537 vpop();
4538 nocode_wanted = saved_nocode_wanted;
4541 /* parse a unary expression and return its type without any side
4542 effect. */
4543 static void unary_type(CType *type)
4545 int a;
4547 a = nocode_wanted;
4548 nocode_wanted = 1;
4549 unary();
4550 *type = vtop->type;
4551 vpop();
4552 nocode_wanted = a;
4555 /* parse a constant expression and return value in vtop. */
4556 static void expr_const1(void)
4558 int a;
4559 a = const_wanted;
4560 const_wanted = 1;
4561 expr_cond();
4562 const_wanted = a;
4565 /* parse an integer constant and return its value. */
4566 ST_FUNC int expr_const(void)
4568 int c;
4569 expr_const1();
4570 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4571 expect("constant expression");
4572 c = vtop->c.i;
4573 vpop();
4574 return c;
4577 /* return the label token if current token is a label, otherwise
4578 return zero */
4579 static int is_label(void)
4581 int last_tok;
4583 /* fast test first */
4584 if (tok < TOK_UIDENT)
4585 return 0;
4586 /* no need to save tokc because tok is an identifier */
4587 last_tok = tok;
4588 next();
4589 if (tok == ':') {
4590 next();
4591 return last_tok;
4592 } else {
4593 unget_tok(last_tok);
4594 return 0;
4598 static void label_or_decl(int l)
4600 int last_tok;
4602 /* fast test first */
4603 if (tok >= TOK_UIDENT)
4605 /* no need to save tokc because tok is an identifier */
4606 last_tok = tok;
4607 next();
4608 if (tok == ':') {
4609 unget_tok(last_tok);
4610 return;
4612 unget_tok(last_tok);
4614 decl(l);
4617 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4618 int case_reg, int is_expr)
4620 int a, b, c, d;
4621 Sym *s, *frame_bottom;
4623 /* generate line number info */
4624 if (tcc_state->do_debug &&
4625 (last_line_num != file->line_num || last_ind != ind)) {
4626 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4627 last_ind = ind;
4628 last_line_num = file->line_num;
4631 if (is_expr) {
4632 /* default return value is (void) */
4633 vpushi(0);
4634 vtop->type.t = VT_VOID;
4637 if (tok == TOK_IF) {
4638 /* if test */
4639 next();
4640 skip('(');
4641 gexpr();
4642 skip(')');
4643 a = gvtst(1, 0);
4644 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4645 c = tok;
4646 if (c == TOK_ELSE) {
4647 next();
4648 d = gjmp(0);
4649 gsym(a);
4650 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4651 gsym(d); /* patch else jmp */
4652 } else
4653 gsym(a);
4654 } else if (tok == TOK_WHILE) {
4655 next();
4656 d = ind;
4657 skip('(');
4658 gexpr();
4659 skip(')');
4660 a = gvtst(1, 0);
4661 b = 0;
4662 block(&a, &b, case_sym, def_sym, case_reg, 0);
4663 gjmp_addr(d);
4664 gsym(a);
4665 gsym_addr(b, d);
4666 } else if (tok == '{') {
4667 Sym *llabel;
4668 int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
4670 next();
4671 /* record local declaration stack position */
4672 s = local_stack;
4673 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4674 frame_bottom->next = scope_stack_bottom;
4675 scope_stack_bottom = frame_bottom;
4676 llabel = local_label_stack;
4678 /* save VLA state */
4679 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4680 if (saved_vla_sp_loc != &vla_sp_root_loc)
4681 vla_sp_loc = &block_vla_sp_loc;
4683 saved_vla_flags = vla_flags;
4684 vla_flags |= VLA_NEED_NEW_FRAME;
4686 /* handle local labels declarations */
4687 if (tok == TOK_LABEL) {
4688 next();
4689 for(;;) {
4690 if (tok < TOK_UIDENT)
4691 expect("label identifier");
4692 label_push(&local_label_stack, tok, LABEL_DECLARED);
4693 next();
4694 if (tok == ',') {
4695 next();
4696 } else {
4697 skip(';');
4698 break;
4702 while (tok != '}') {
4703 label_or_decl(VT_LOCAL);
4704 if (tok != '}') {
4705 if (is_expr)
4706 vpop();
4707 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4710 /* pop locally defined labels */
4711 label_pop(&local_label_stack, llabel);
4712 if(is_expr) {
4713 /* XXX: this solution makes only valgrind happy...
4714 triggered by gcc.c-torture/execute/20000917-1.c */
4715 Sym *p;
4716 switch(vtop->type.t & VT_BTYPE) {
4717 case VT_PTR:
4718 case VT_STRUCT:
4719 case VT_ENUM:
4720 case VT_FUNC:
4721 for(p=vtop->type.ref;p;p=p->prev)
4722 if(p->prev==s)
4723 tcc_error("unsupported expression type");
4726 /* pop locally defined symbols */
4727 scope_stack_bottom = scope_stack_bottom->next;
4728 sym_pop(&local_stack, s);
4730 /* Pop VLA frames and restore stack pointer if required */
4731 if (saved_vla_sp_loc != &vla_sp_root_loc)
4732 *saved_vla_sp_loc = block_vla_sp_loc;
4733 if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
4734 vla_sp_loc = saved_vla_sp_loc;
4735 gen_vla_sp_restore(*vla_sp_loc);
4737 vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
4739 next();
4740 } else if (tok == TOK_RETURN) {
4741 next();
4742 if (tok != ';') {
4743 gexpr();
4744 gen_assign_cast(&func_vt);
4745 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4746 CType type, ret_type;
4747 int ret_align, ret_nregs;
4748 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
4749 &ret_align);
4750 if (0 == ret_nregs) {
4751 /* if returning structure, must copy it to implicit
4752 first pointer arg location */
4753 type = func_vt;
4754 mk_pointer(&type);
4755 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4756 indir();
4757 vswap();
4758 /* copy structure value to pointer */
4759 vstore();
4760 } else {
4761 /* returning structure packed into registers */
4762 int r, size, addr, align;
4763 size = type_size(&func_vt,&align);
4764 if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))
4765 && (align & (ret_align-1))) {
4766 loc = (loc - size) & -align;
4767 addr = loc;
4768 type = func_vt;
4769 vset(&type, VT_LOCAL | VT_LVAL, addr);
4770 vswap();
4771 vstore();
4772 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
4774 vtop->type = ret_type;
4775 if (is_float(ret_type.t))
4776 r = rc_fret(ret_type.t);
4777 else
4778 r = RC_IRET;
4780 for (;;) {
4781 gv(r);
4782 if (--ret_nregs == 0)
4783 break;
4784 /* We assume that when a structure is returned in multiple
4785 registers, their classes are consecutive values of the
4786 suite s(n) = 2^n */
4787 r <<= 1;
4788 /* XXX: compatible with arm only: ret_align == register_size */
4789 vtop->c.i += ret_align;
4790 vtop->r = VT_LOCAL | VT_LVAL;
4793 } else if (is_float(func_vt.t)) {
4794 gv(rc_fret(func_vt.t));
4795 } else {
4796 gv(RC_IRET);
4798 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4800 skip(';');
4801 rsym = gjmp(rsym); /* jmp */
4802 } else if (tok == TOK_BREAK) {
4803 /* compute jump */
4804 if (!bsym)
4805 tcc_error("cannot break");
4806 *bsym = gjmp(*bsym);
4807 next();
4808 skip(';');
4809 } else if (tok == TOK_CONTINUE) {
4810 /* compute jump */
4811 if (!csym)
4812 tcc_error("cannot continue");
4813 *csym = gjmp(*csym);
4814 next();
4815 skip(';');
4816 } else if (tok == TOK_FOR) {
4817 int e;
4818 next();
4819 skip('(');
4820 s = local_stack;
4821 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4822 frame_bottom->next = scope_stack_bottom;
4823 scope_stack_bottom = frame_bottom;
4824 if (tok != ';') {
4825 /* c99 for-loop init decl? */
4826 if (!decl0(VT_LOCAL, 1)) {
4827 /* no, regular for-loop init expr */
4828 gexpr();
4829 vpop();
4832 skip(';');
4833 d = ind;
4834 c = ind;
4835 a = 0;
4836 b = 0;
4837 if (tok != ';') {
4838 gexpr();
4839 a = gvtst(1, 0);
4841 skip(';');
4842 if (tok != ')') {
4843 e = gjmp(0);
4844 c = ind;
4845 gexpr();
4846 vpop();
4847 gjmp_addr(d);
4848 gsym(e);
4850 skip(')');
4851 block(&a, &b, case_sym, def_sym, case_reg, 0);
4852 gjmp_addr(c);
4853 gsym(a);
4854 gsym_addr(b, c);
4855 scope_stack_bottom = scope_stack_bottom->next;
4856 sym_pop(&local_stack, s);
4857 } else
4858 if (tok == TOK_DO) {
4859 next();
4860 a = 0;
4861 b = 0;
4862 d = ind;
4863 block(&a, &b, case_sym, def_sym, case_reg, 0);
4864 skip(TOK_WHILE);
4865 skip('(');
4866 gsym(b);
4867 gexpr();
4868 c = gvtst(0, 0);
4869 gsym_addr(c, d);
4870 skip(')');
4871 gsym(a);
4872 skip(';');
4873 } else
4874 if (tok == TOK_SWITCH) {
4875 next();
4876 skip('(');
4877 gexpr();
4878 /* XXX: other types than integer */
4879 case_reg = gv(RC_INT);
4880 vpop();
4881 skip(')');
4882 a = 0;
4883 b = gjmp(0); /* jump to first case */
4884 c = 0;
4885 block(&a, csym, &b, &c, case_reg, 0);
4886 /* if no default, jmp after switch */
4887 if (c == 0)
4888 c = ind;
4889 /* default label */
4890 gsym_addr(b, c);
4891 /* break label */
4892 gsym(a);
4893 } else
4894 if (tok == TOK_CASE) {
4895 int v1, v2;
4896 if (!case_sym)
4897 expect("switch");
4898 next();
4899 v1 = expr_const();
4900 v2 = v1;
4901 if (gnu_ext && tok == TOK_DOTS) {
4902 next();
4903 v2 = expr_const();
4904 if (v2 < v1)
4905 tcc_warning("empty case range");
4907 /* since a case is like a label, we must skip it with a jmp */
4908 b = gjmp(0);
4909 gsym(*case_sym);
4910 vseti(case_reg, 0);
4911 vpushi(v1);
4912 if (v1 == v2) {
4913 gen_op(TOK_EQ);
4914 *case_sym = gtst(1, 0);
4915 } else {
4916 gen_op(TOK_GE);
4917 *case_sym = gtst(1, 0);
4918 vseti(case_reg, 0);
4919 vpushi(v2);
4920 gen_op(TOK_LE);
4921 *case_sym = gtst(1, *case_sym);
4923 gsym(b);
4924 skip(':');
4925 is_expr = 0;
4926 goto block_after_label;
4927 } else
4928 if (tok == TOK_DEFAULT) {
4929 next();
4930 skip(':');
4931 if (!def_sym)
4932 expect("switch");
4933 if (*def_sym)
4934 tcc_error("too many 'default'");
4935 *def_sym = ind;
4936 is_expr = 0;
4937 goto block_after_label;
4938 } else
4939 if (tok == TOK_GOTO) {
4940 next();
4941 if (tok == '*' && gnu_ext) {
4942 /* computed goto */
4943 next();
4944 gexpr();
4945 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4946 expect("pointer");
4947 ggoto();
4948 } else if (tok >= TOK_UIDENT) {
4949 s = label_find(tok);
4950 /* put forward definition if needed */
4951 if (!s) {
4952 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4953 } else {
4954 if (s->r == LABEL_DECLARED)
4955 s->r = LABEL_FORWARD;
4957 /* label already defined */
4958 if (vla_flags & VLA_IN_SCOPE) {
4959 /* If VLAs are in use, save the current stack pointer and
4960 reset the stack pointer to what it was at function entry
4961 (label will restore stack pointer in inner scopes) */
4962 vla_sp_save();
4963 gen_vla_sp_restore(vla_sp_root_loc);
4965 if (s->r & LABEL_FORWARD)
4966 s->jnext = gjmp(s->jnext);
4967 else
4968 gjmp_addr(s->jnext);
4969 next();
4970 } else {
4971 expect("label identifier");
4973 skip(';');
4974 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4975 asm_instr();
4976 } else {
4977 b = is_label();
4978 if (b) {
4979 /* label case */
4980 if (vla_flags & VLA_IN_SCOPE) {
4981 /* save/restore stack pointer across label
4982 this is a no-op when combined with the load immediately
4983 after the label unless we arrive via goto */
4984 vla_sp_save();
4986 s = label_find(b);
4987 if (s) {
4988 if (s->r == LABEL_DEFINED)
4989 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4990 gsym(s->jnext);
4991 s->r = LABEL_DEFINED;
4992 } else {
4993 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4995 s->jnext = ind;
4996 if (vla_flags & VLA_IN_SCOPE) {
4997 gen_vla_sp_restore(*vla_sp_loc);
4998 vla_flags |= VLA_NEED_NEW_FRAME;
5000 /* we accept this, but it is a mistake */
5001 block_after_label:
5002 if (tok == '}') {
5003 tcc_warning("deprecated use of label at end of compound statement");
5004 } else {
5005 if (is_expr)
5006 vpop();
5007 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
5009 } else {
5010 /* expression case */
5011 if (tok != ';') {
5012 if (is_expr) {
5013 vpop();
5014 gexpr();
5015 } else {
5016 gexpr();
5017 vpop();
5020 skip(';');
5025 /* t is the array or struct type. c is the array or struct
5026 address. cur_index/cur_field is the pointer to the current
5027 value. 'size_only' is true if only size info is needed (only used
5028 in arrays) */
5029 static void decl_designator(CType *type, Section *sec, unsigned long c,
5030 int *cur_index, Sym **cur_field,
5031 int size_only)
5033 Sym *s, *f;
5034 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5035 CType type1;
5037 notfirst = 0;
5038 elem_size = 0;
5039 nb_elems = 1;
5040 if (gnu_ext && (l = is_label()) != 0)
5041 goto struct_field;
5042 while (tok == '[' || tok == '.') {
5043 if (tok == '[') {
5044 if (!(type->t & VT_ARRAY))
5045 expect("array type");
5046 s = type->ref;
5047 next();
5048 index = expr_const();
5049 if (index < 0 || (s->c >= 0 && index >= s->c))
5050 expect("invalid index");
5051 if (tok == TOK_DOTS && gnu_ext) {
5052 next();
5053 index_last = expr_const();
5054 if (index_last < 0 ||
5055 (s->c >= 0 && index_last >= s->c) ||
5056 index_last < index)
5057 expect("invalid index");
5058 } else {
5059 index_last = index;
5061 skip(']');
5062 if (!notfirst)
5063 *cur_index = index_last;
5064 type = pointed_type(type);
5065 elem_size = type_size(type, &align);
5066 c += index * elem_size;
5067 /* NOTE: we only support ranges for last designator */
5068 nb_elems = index_last - index + 1;
5069 if (nb_elems != 1) {
5070 notfirst = 1;
5071 break;
5073 } else {
5074 next();
5075 l = tok;
5076 next();
5077 struct_field:
5078 if ((type->t & VT_BTYPE) != VT_STRUCT)
5079 expect("struct/union type");
5080 s = type->ref;
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 type = pointed_type(type);
5111 c += index * type_size(type, &align);
5112 } else {
5113 f = *cur_field;
5114 if (!f)
5115 tcc_error("too many field init");
5116 /* XXX: fix this mess by using explicit storage field */
5117 type1 = f->type;
5118 type1.t |= (type->t & ~VT_TYPE);
5119 type = &type1;
5120 c += f->c;
5123 decl_initializer(type, sec, c, 0, size_only);
5125 /* XXX: make it more general */
5126 if (!size_only && nb_elems > 1) {
5127 unsigned long c_end;
5128 uint8_t *src, *dst;
5129 int i;
5131 if (!sec)
5132 tcc_error("range init not supported yet for dynamic storage");
5133 c_end = c + nb_elems * elem_size;
5134 if (c_end > sec->data_allocated)
5135 section_realloc(sec, c_end);
5136 src = sec->data + c;
5137 dst = src;
5138 for(i = 1; i < nb_elems; i++) {
5139 dst += elem_size;
5140 memcpy(dst, src, elem_size);
5145 #define EXPR_VAL 0
5146 #define EXPR_CONST 1
5147 #define EXPR_ANY 2
5149 /* store a value or an expression directly in global data or in local array */
5150 static void init_putv(CType *type, Section *sec, unsigned long c,
5151 int v, int expr_type)
5153 int saved_global_expr, bt, bit_pos, bit_size;
5154 void *ptr;
5155 unsigned long long bit_mask;
5156 CType dtype;
5158 switch(expr_type) {
5159 case EXPR_VAL:
5160 vpushi(v);
5161 break;
5162 case EXPR_CONST:
5163 /* compound literals must be allocated globally in this case */
5164 saved_global_expr = global_expr;
5165 global_expr = 1;
5166 expr_const1();
5167 global_expr = saved_global_expr;
5168 /* NOTE: symbols are accepted */
5169 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5170 tcc_error("initializer element is not constant");
5171 break;
5172 case EXPR_ANY:
5173 expr_eq();
5174 break;
5177 dtype = *type;
5178 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5180 if (sec) {
5181 /* XXX: not portable */
5182 /* XXX: generate error if incorrect relocation */
5183 gen_assign_cast(&dtype);
5184 bt = type->t & VT_BTYPE;
5185 /* we'll write at most 12 bytes */
5186 if (c + 12 > sec->data_allocated) {
5187 section_realloc(sec, c + 12);
5189 ptr = sec->data + c;
5190 /* XXX: make code faster ? */
5191 if (!(type->t & VT_BITFIELD)) {
5192 bit_pos = 0;
5193 bit_size = 32;
5194 bit_mask = -1LL;
5195 } else {
5196 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5197 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5198 bit_mask = (1LL << bit_size) - 1;
5200 if ((vtop->r & VT_SYM) &&
5201 (bt == VT_BYTE ||
5202 bt == VT_SHORT ||
5203 bt == VT_DOUBLE ||
5204 bt == VT_LDOUBLE ||
5205 bt == VT_LLONG ||
5206 (bt == VT_INT && bit_size != 32)))
5207 tcc_error("initializer element is not computable at load time");
5208 switch(bt) {
5209 case VT_BOOL:
5210 vtop->c.i = (vtop->c.i != 0);
5211 case VT_BYTE:
5212 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5213 break;
5214 case VT_SHORT:
5215 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5216 break;
5217 case VT_DOUBLE:
5218 *(double *)ptr = vtop->c.d;
5219 break;
5220 case VT_LDOUBLE:
5221 *(long double *)ptr = vtop->c.ld;
5222 break;
5223 case VT_LLONG:
5224 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
5225 break;
5226 case VT_PTR:
5227 if (vtop->r & VT_SYM) {
5228 greloc(sec, vtop->sym, c, R_DATA_PTR);
5230 *(addr_t *)ptr |= (vtop->c.ptr_offset & bit_mask) << bit_pos;
5231 break;
5232 default:
5233 if (vtop->r & VT_SYM) {
5234 greloc(sec, vtop->sym, c, R_DATA_PTR);
5236 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5237 break;
5239 vtop--;
5240 } else {
5241 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5242 vswap();
5243 vstore();
5244 vpop();
5248 /* put zeros for variable based init */
5249 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5251 if (sec) {
5252 /* nothing to do because globals are already set to zero */
5253 } else {
5254 vpush_global_sym(&func_old_type, TOK_memset);
5255 vseti(VT_LOCAL, c);
5256 #ifdef TCC_TARGET_ARM
5257 vpushs(size);
5258 vpushi(0);
5259 #else
5260 vpushi(0);
5261 vpushs(size);
5262 #endif
5263 gfunc_call(3);
5267 /* 't' contains the type and storage info. 'c' is the offset of the
5268 object in section 'sec'. If 'sec' is NULL, it means stack based
5269 allocation. 'first' is true if array '{' must be read (multi
5270 dimension implicit array init handling). 'size_only' is true if
5271 size only evaluation is wanted (only for arrays). */
5272 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5273 int first, int size_only)
5275 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5276 int size1, align1, expr_type;
5277 Sym *s, *f;
5278 CType *t1;
5280 if (type->t & VT_VLA) {
5281 int a;
5283 /* save current stack pointer */
5284 if (vla_flags & VLA_NEED_NEW_FRAME) {
5285 vla_sp_save();
5286 vla_flags = VLA_IN_SCOPE;
5287 vla_sp_loc = &vla_sp_loc_tmp;
5290 vla_runtime_type_size(type, &a);
5291 gen_vla_alloc(type, a);
5292 vset(type, VT_LOCAL|VT_LVAL, c);
5293 vswap();
5294 vstore();
5295 vpop();
5296 } else if (type->t & VT_ARRAY) {
5297 s = type->ref;
5298 n = s->c;
5299 array_length = 0;
5300 t1 = pointed_type(type);
5301 size1 = type_size(t1, &align1);
5303 no_oblock = 1;
5304 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5305 tok == '{') {
5306 if (tok != '{')
5307 tcc_error("character array initializer must be a literal,"
5308 " optionally enclosed in braces");
5309 skip('{');
5310 no_oblock = 0;
5313 /* only parse strings here if correct type (otherwise: handle
5314 them as ((w)char *) expressions */
5315 if ((tok == TOK_LSTR &&
5316 #ifdef TCC_TARGET_PE
5317 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5318 #else
5319 (t1->t & VT_BTYPE) == VT_INT
5320 #endif
5321 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5322 while (tok == TOK_STR || tok == TOK_LSTR) {
5323 int cstr_len, ch;
5324 CString *cstr;
5326 cstr = tokc.cstr;
5327 /* compute maximum number of chars wanted */
5328 if (tok == TOK_STR)
5329 cstr_len = cstr->size;
5330 else
5331 cstr_len = cstr->size / sizeof(nwchar_t);
5332 cstr_len--;
5333 nb = cstr_len;
5334 if (n >= 0 && nb > (n - array_length))
5335 nb = n - array_length;
5336 if (!size_only) {
5337 if (cstr_len > nb)
5338 tcc_warning("initializer-string for array is too long");
5339 /* in order to go faster for common case (char
5340 string in global variable, we handle it
5341 specifically */
5342 if (sec && tok == TOK_STR && size1 == 1) {
5343 memcpy(sec->data + c + array_length, cstr->data, nb);
5344 } else {
5345 for(i=0;i<nb;i++) {
5346 if (tok == TOK_STR)
5347 ch = ((unsigned char *)cstr->data)[i];
5348 else
5349 ch = ((nwchar_t *)cstr->data)[i];
5350 init_putv(t1, sec, c + (array_length + i) * size1,
5351 ch, EXPR_VAL);
5355 array_length += nb;
5356 next();
5358 /* only add trailing zero if enough storage (no
5359 warning in this case since it is standard) */
5360 if (n < 0 || array_length < n) {
5361 if (!size_only) {
5362 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5364 array_length++;
5366 } else {
5367 index = 0;
5368 while (tok != '}') {
5369 decl_designator(type, sec, c, &index, NULL, size_only);
5370 if (n >= 0 && index >= n)
5371 tcc_error("index too large");
5372 /* must put zero in holes (note that doing it that way
5373 ensures that it even works with designators) */
5374 if (!size_only && array_length < index) {
5375 init_putz(t1, sec, c + array_length * size1,
5376 (index - array_length) * size1);
5378 index++;
5379 if (index > array_length)
5380 array_length = index;
5381 /* special test for multi dimensional arrays (may not
5382 be strictly correct if designators are used at the
5383 same time) */
5384 if (index >= n && no_oblock)
5385 break;
5386 if (tok == '}')
5387 break;
5388 skip(',');
5391 if (!no_oblock)
5392 skip('}');
5393 /* put zeros at the end */
5394 if (!size_only && n >= 0 && array_length < n) {
5395 init_putz(t1, sec, c + array_length * size1,
5396 (n - array_length) * size1);
5398 /* patch type size if needed */
5399 if (n < 0)
5400 s->c = array_length;
5401 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5402 (sec || !first || tok == '{')) {
5403 int par_count;
5405 /* NOTE: the previous test is a specific case for automatic
5406 struct/union init */
5407 /* XXX: union needs only one init */
5409 /* XXX: this test is incorrect for local initializers
5410 beginning with ( without {. It would be much more difficult
5411 to do it correctly (ideally, the expression parser should
5412 be used in all cases) */
5413 par_count = 0;
5414 if (tok == '(') {
5415 AttributeDef ad1;
5416 CType type1;
5417 next();
5418 while (tok == '(') {
5419 par_count++;
5420 next();
5422 if (!parse_btype(&type1, &ad1))
5423 expect("cast");
5424 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5425 #if 0
5426 if (!is_assignable_types(type, &type1))
5427 tcc_error("invalid type for cast");
5428 #endif
5429 skip(')');
5431 no_oblock = 1;
5432 if (first || tok == '{') {
5433 skip('{');
5434 no_oblock = 0;
5436 s = type->ref;
5437 f = s->next;
5438 array_length = 0;
5439 index = 0;
5440 n = s->c;
5441 while (tok != '}') {
5442 decl_designator(type, sec, c, NULL, &f, size_only);
5443 index = f->c;
5444 if (!size_only && array_length < index) {
5445 init_putz(type, sec, c + array_length,
5446 index - array_length);
5448 index = index + type_size(&f->type, &align1);
5449 if (index > array_length)
5450 array_length = index;
5452 /* gr: skip fields from same union - ugly. */
5453 while (f->next) {
5454 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5455 /* test for same offset */
5456 if (f->next->c != f->c)
5457 break;
5458 /* if yes, test for bitfield shift */
5459 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5460 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5461 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5462 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5463 if (bit_pos_1 != bit_pos_2)
5464 break;
5466 f = f->next;
5469 f = f->next;
5470 if (no_oblock && f == NULL)
5471 break;
5472 if (tok == '}')
5473 break;
5474 skip(',');
5476 /* put zeros at the end */
5477 if (!size_only && array_length < n) {
5478 init_putz(type, sec, c + array_length,
5479 n - array_length);
5481 if (!no_oblock)
5482 skip('}');
5483 while (par_count) {
5484 skip(')');
5485 par_count--;
5487 } else if (tok == '{') {
5488 next();
5489 decl_initializer(type, sec, c, first, size_only);
5490 skip('}');
5491 } else if (size_only) {
5492 /* just skip expression */
5493 parlevel = parlevel1 = 0;
5494 while ((parlevel > 0 || parlevel1 > 0 ||
5495 (tok != '}' && tok != ',')) && tok != -1) {
5496 if (tok == '(')
5497 parlevel++;
5498 else if (tok == ')')
5499 parlevel--;
5500 else if (tok == '{')
5501 parlevel1++;
5502 else if (tok == '}')
5503 parlevel1--;
5504 next();
5506 } else {
5507 /* currently, we always use constant expression for globals
5508 (may change for scripting case) */
5509 expr_type = EXPR_CONST;
5510 if (!sec)
5511 expr_type = EXPR_ANY;
5512 init_putv(type, sec, c, 0, expr_type);
5516 /* parse an initializer for type 't' if 'has_init' is non zero, and
5517 allocate space in local or global data space ('r' is either
5518 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5519 variable 'v' with an associated name represented by 'asm_label' of
5520 scope 'scope' is declared before initializers are parsed. If 'v' is
5521 zero, then a reference to the new object is put in the value stack.
5522 If 'has_init' is 2, a special parsing is done to handle string
5523 constants. */
5524 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5525 int has_init, int v, char *asm_label,
5526 int scope)
5528 int size, align, addr, data_offset;
5529 int level;
5530 ParseState saved_parse_state = {0};
5531 TokenString init_str;
5532 Section *sec;
5533 Sym *flexible_array;
5535 flexible_array = NULL;
5536 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5537 Sym *field = type->ref->next;
5538 if (field) {
5539 while (field->next)
5540 field = field->next;
5541 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5542 flexible_array = field;
5546 size = type_size(type, &align);
5547 /* If unknown size, we must evaluate it before
5548 evaluating initializers because
5549 initializers can generate global data too
5550 (e.g. string pointers or ISOC99 compound
5551 literals). It also simplifies local
5552 initializers handling */
5553 tok_str_new(&init_str);
5554 if (size < 0 || (flexible_array && has_init)) {
5555 if (!has_init)
5556 tcc_error("unknown type size");
5557 /* get all init string */
5558 if (has_init == 2) {
5559 /* only get strings */
5560 while (tok == TOK_STR || tok == TOK_LSTR) {
5561 tok_str_add_tok(&init_str);
5562 next();
5564 } else {
5565 level = 0;
5566 while (level > 0 || (tok != ',' && tok != ';')) {
5567 if (tok < 0)
5568 tcc_error("unexpected end of file in initializer");
5569 tok_str_add_tok(&init_str);
5570 if (tok == '{')
5571 level++;
5572 else if (tok == '}') {
5573 level--;
5574 if (level <= 0) {
5575 next();
5576 break;
5579 next();
5582 tok_str_add(&init_str, -1);
5583 tok_str_add(&init_str, 0);
5585 /* compute size */
5586 save_parse_state(&saved_parse_state);
5588 macro_ptr = init_str.str;
5589 next();
5590 decl_initializer(type, NULL, 0, 1, 1);
5591 /* prepare second initializer parsing */
5592 macro_ptr = init_str.str;
5593 next();
5595 /* if still unknown size, error */
5596 size = type_size(type, &align);
5597 if (size < 0)
5598 tcc_error("unknown type size");
5600 if (flexible_array)
5601 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5602 /* take into account specified alignment if bigger */
5603 if (ad->a.aligned) {
5604 if (ad->a.aligned > align)
5605 align = ad->a.aligned;
5606 } else if (ad->a.packed) {
5607 align = 1;
5609 if ((r & VT_VALMASK) == VT_LOCAL) {
5610 sec = NULL;
5611 #ifdef CONFIG_TCC_BCHECK
5612 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5613 loc--;
5615 #endif
5616 loc = (loc - size) & -align;
5617 addr = loc;
5618 #ifdef CONFIG_TCC_BCHECK
5619 /* handles bounds */
5620 /* XXX: currently, since we do only one pass, we cannot track
5621 '&' operators, so we add only arrays */
5622 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5623 unsigned long *bounds_ptr;
5624 /* add padding between regions */
5625 loc--;
5626 /* then add local bound info */
5627 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5628 bounds_ptr[0] = addr;
5629 bounds_ptr[1] = size;
5631 #endif
5632 if (v) {
5633 /* local variable */
5634 sym_push(v, type, r, addr);
5635 } else {
5636 /* push local reference */
5637 vset(type, r, addr);
5639 } else {
5640 Sym *sym;
5642 sym = NULL;
5643 if (v && scope == VT_CONST) {
5644 /* see if the symbol was already defined */
5645 sym = sym_find(v);
5646 if (sym) {
5647 if (!is_compatible_types(&sym->type, type))
5648 tcc_error("incompatible types for redefinition of '%s'",
5649 get_tok_str(v, NULL));
5650 if (sym->type.t & VT_EXTERN) {
5651 /* if the variable is extern, it was not allocated */
5652 sym->type.t &= ~VT_EXTERN;
5653 /* set array size if it was omitted in extern
5654 declaration */
5655 if ((sym->type.t & VT_ARRAY) &&
5656 sym->type.ref->c < 0 &&
5657 type->ref->c >= 0)
5658 sym->type.ref->c = type->ref->c;
5659 } else {
5660 /* we accept several definitions of the same
5661 global variable. this is tricky, because we
5662 must play with the SHN_COMMON type of the symbol */
5663 /* XXX: should check if the variable was already
5664 initialized. It is incorrect to initialized it
5665 twice */
5666 /* no init data, we won't add more to the symbol */
5667 if (!has_init)
5668 goto no_alloc;
5673 /* allocate symbol in corresponding section */
5674 sec = ad->section;
5675 if (!sec) {
5676 if (has_init)
5677 sec = data_section;
5678 else if (tcc_state->nocommon)
5679 sec = bss_section;
5681 if (sec) {
5682 data_offset = sec->data_offset;
5683 data_offset = (data_offset + align - 1) & -align;
5684 addr = data_offset;
5685 /* very important to increment global pointer at this time
5686 because initializers themselves can create new initializers */
5687 data_offset += size;
5688 #ifdef CONFIG_TCC_BCHECK
5689 /* add padding if bound check */
5690 if (tcc_state->do_bounds_check)
5691 data_offset++;
5692 #endif
5693 sec->data_offset = data_offset;
5694 /* allocate section space to put the data */
5695 if (sec->sh_type != SHT_NOBITS &&
5696 data_offset > sec->data_allocated)
5697 section_realloc(sec, data_offset);
5698 /* align section if needed */
5699 if (align > sec->sh_addralign)
5700 sec->sh_addralign = align;
5701 } else {
5702 addr = 0; /* avoid warning */
5705 if (v) {
5706 if (scope != VT_CONST || !sym) {
5707 sym = sym_push(v, type, r | VT_SYM, 0);
5708 sym->asm_label = asm_label;
5710 /* update symbol definition */
5711 if (sec) {
5712 put_extern_sym(sym, sec, addr, size);
5713 } else {
5714 ElfW(Sym) *esym;
5715 /* put a common area */
5716 put_extern_sym(sym, NULL, align, size);
5717 /* XXX: find a nicer way */
5718 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5719 esym->st_shndx = SHN_COMMON;
5721 } else {
5722 /* push global reference */
5723 sym = get_sym_ref(type, sec, addr, size);
5724 vpushsym(type, sym);
5726 /* patch symbol weakness */
5727 if (type->t & VT_WEAK)
5728 weaken_symbol(sym);
5729 apply_visibility(sym, type);
5730 #ifdef CONFIG_TCC_BCHECK
5731 /* handles bounds now because the symbol must be defined
5732 before for the relocation */
5733 if (tcc_state->do_bounds_check) {
5734 unsigned long *bounds_ptr;
5736 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5737 /* then add global bound info */
5738 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5739 bounds_ptr[0] = 0; /* relocated */
5740 bounds_ptr[1] = size;
5742 #endif
5744 if (has_init || (type->t & VT_VLA)) {
5745 decl_initializer(type, sec, addr, 1, 0);
5746 /* restore parse state if needed */
5747 if (init_str.str) {
5748 tok_str_free(init_str.str);
5749 restore_parse_state(&saved_parse_state);
5751 /* patch flexible array member size back to -1, */
5752 /* for possible subsequent similar declarations */
5753 if (flexible_array)
5754 flexible_array->type.ref->c = -1;
5756 no_alloc: ;
5759 static void put_func_debug(Sym *sym)
5761 char buf[512];
5763 /* stabs info */
5764 /* XXX: we put here a dummy type */
5765 snprintf(buf, sizeof(buf), "%s:%c1",
5766 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5767 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5768 cur_text_section, sym->c);
5769 /* //gr gdb wants a line at the function */
5770 put_stabn(N_SLINE, 0, file->line_num, 0);
5771 last_ind = 0;
5772 last_line_num = 0;
5775 /* parse an old style function declaration list */
5776 /* XXX: check multiple parameter */
5777 static void func_decl_list(Sym *func_sym)
5779 AttributeDef ad;
5780 int v;
5781 Sym *s;
5782 CType btype, type;
5784 /* parse each declaration */
5785 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5786 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5787 if (!parse_btype(&btype, &ad))
5788 expect("declaration list");
5789 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5790 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5791 tok == ';') {
5792 /* we accept no variable after */
5793 } else {
5794 for(;;) {
5795 type = btype;
5796 type_decl(&type, &ad, &v, TYPE_DIRECT);
5797 /* find parameter in function parameter list */
5798 s = func_sym->next;
5799 while (s != NULL) {
5800 if ((s->v & ~SYM_FIELD) == v)
5801 goto found;
5802 s = s->next;
5804 tcc_error("declaration for parameter '%s' but no such parameter",
5805 get_tok_str(v, NULL));
5806 found:
5807 /* check that no storage specifier except 'register' was given */
5808 if (type.t & VT_STORAGE)
5809 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5810 convert_parameter_type(&type);
5811 /* we can add the type (NOTE: it could be local to the function) */
5812 s->type = type;
5813 /* accept other parameters */
5814 if (tok == ',')
5815 next();
5816 else
5817 break;
5820 skip(';');
5824 /* parse a function defined by symbol 'sym' and generate its code in
5825 'cur_text_section' */
5826 static void gen_function(Sym *sym)
5828 int saved_nocode_wanted = nocode_wanted;
5829 nocode_wanted = 0;
5830 ind = cur_text_section->data_offset;
5831 /* NOTE: we patch the symbol size later */
5832 put_extern_sym(sym, cur_text_section, ind, 0);
5833 funcname = get_tok_str(sym->v, NULL);
5834 func_ind = ind;
5835 /* Initialize VLA state */
5836 vla_sp_loc = &vla_sp_root_loc;
5837 vla_flags = VLA_NEED_NEW_FRAME;
5838 /* put debug symbol */
5839 if (tcc_state->do_debug)
5840 put_func_debug(sym);
5841 /* push a dummy symbol to enable local sym storage */
5842 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5843 gfunc_prolog(&sym->type);
5844 #ifdef CONFIG_TCC_BCHECK
5845 if (tcc_state->do_bounds_check
5846 && !strcmp(get_tok_str(sym->v, NULL), "main")) {
5847 int i;
5849 sym = local_stack;
5850 for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) {
5851 if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD)
5852 break;
5853 vpush_global_sym(&func_old_type, TOK___bound_main_arg);
5854 vset(&sym->type, sym->r, sym->c);
5855 gfunc_call(1);
5858 #endif
5859 rsym = 0;
5860 block(NULL, NULL, NULL, NULL, 0, 0);
5861 gsym(rsym);
5862 gfunc_epilog();
5863 cur_text_section->data_offset = ind;
5864 label_pop(&global_label_stack, NULL);
5865 /* reset local stack */
5866 scope_stack_bottom = NULL;
5867 sym_pop(&local_stack, NULL);
5868 /* end of function */
5869 /* patch symbol size */
5870 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5871 ind - func_ind;
5872 /* patch symbol weakness (this definition overrules any prototype) */
5873 if (sym->type.t & VT_WEAK)
5874 weaken_symbol(sym);
5875 apply_visibility(sym, &sym->type);
5876 if (tcc_state->do_debug) {
5877 put_stabn(N_FUN, 0, 0, ind - func_ind);
5879 /* It's better to crash than to generate wrong code */
5880 cur_text_section = NULL;
5881 funcname = ""; /* for safety */
5882 func_vt.t = VT_VOID; /* for safety */
5883 func_var = 0; /* for safety */
5884 ind = 0; /* for safety */
5885 nocode_wanted = saved_nocode_wanted;
5888 ST_FUNC void gen_inline_functions(void)
5890 Sym *sym;
5891 int *str, inline_generated, i;
5892 struct InlineFunc *fn;
5894 /* iterate while inline function are referenced */
5895 for(;;) {
5896 inline_generated = 0;
5897 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5898 fn = tcc_state->inline_fns[i];
5899 sym = fn->sym;
5900 if (sym && sym->c) {
5901 /* the function was used: generate its code and
5902 convert it to a normal function */
5903 str = fn->token_str;
5904 fn->sym = NULL;
5905 if (file)
5906 pstrcpy(file->filename, sizeof file->filename, fn->filename);
5907 sym->r = VT_SYM | VT_CONST;
5908 sym->type.t &= ~VT_INLINE;
5910 macro_ptr = str;
5911 next();
5912 cur_text_section = text_section;
5913 gen_function(sym);
5914 macro_ptr = NULL; /* fail safe */
5916 inline_generated = 1;
5919 if (!inline_generated)
5920 break;
5922 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5923 fn = tcc_state->inline_fns[i];
5924 str = fn->token_str;
5925 tok_str_free(str);
5927 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5930 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5931 static int decl0(int l, int is_for_loop_init)
5933 int v, has_init, r;
5934 CType type, btype;
5935 Sym *sym;
5936 AttributeDef ad;
5938 while (1) {
5939 if (!parse_btype(&btype, &ad)) {
5940 if (is_for_loop_init)
5941 return 0;
5942 /* skip redundant ';' */
5943 /* XXX: find more elegant solution */
5944 if (tok == ';') {
5945 next();
5946 continue;
5948 if (l == VT_CONST &&
5949 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5950 /* global asm block */
5951 asm_global_instr();
5952 continue;
5954 /* special test for old K&R protos without explicit int
5955 type. Only accepted when defining global data */
5956 if (l == VT_LOCAL || tok < TOK_DEFINE)
5957 break;
5958 btype.t = VT_INT;
5960 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5961 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5962 tok == ';') {
5963 /* we accept no variable after */
5964 next();
5965 continue;
5967 while (1) { /* iterate thru each declaration */
5968 char *asm_label; // associated asm label
5969 type = btype;
5970 type_decl(&type, &ad, &v, TYPE_DIRECT);
5971 #if 0
5973 char buf[500];
5974 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5975 printf("type = '%s'\n", buf);
5977 #endif
5978 if ((type.t & VT_BTYPE) == VT_FUNC) {
5979 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5980 tcc_error("function without file scope cannot be static");
5982 /* if old style function prototype, we accept a
5983 declaration list */
5984 sym = type.ref;
5985 if (sym->c == FUNC_OLD)
5986 func_decl_list(sym);
5989 asm_label = NULL;
5990 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5991 CString astr;
5993 asm_label_instr(&astr);
5994 asm_label = tcc_strdup(astr.data);
5995 cstr_free(&astr);
5997 /* parse one last attribute list, after asm label */
5998 parse_attribute(&ad);
6001 if (ad.a.weak)
6002 type.t |= VT_WEAK;
6003 #ifdef TCC_TARGET_PE
6004 if (ad.a.func_import)
6005 type.t |= VT_IMPORT;
6006 if (ad.a.func_export)
6007 type.t |= VT_EXPORT;
6008 #endif
6009 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6011 if (tok == '{') {
6012 if (l == VT_LOCAL)
6013 tcc_error("cannot use local functions");
6014 if ((type.t & VT_BTYPE) != VT_FUNC)
6015 expect("function definition");
6017 /* reject abstract declarators in function definition */
6018 sym = type.ref;
6019 while ((sym = sym->next) != NULL)
6020 if (!(sym->v & ~SYM_FIELD))
6021 expect("identifier");
6023 /* XXX: cannot do better now: convert extern line to static inline */
6024 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6025 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6027 sym = sym_find(v);
6028 if (sym) {
6029 Sym *ref;
6030 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6031 goto func_error1;
6033 ref = sym->type.ref;
6034 if (0 == ref->a.func_proto)
6035 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6037 /* use func_call from prototype if not defined */
6038 if (ref->a.func_call != FUNC_CDECL
6039 && type.ref->a.func_call == FUNC_CDECL)
6040 type.ref->a.func_call = ref->a.func_call;
6042 /* use export from prototype */
6043 if (ref->a.func_export)
6044 type.ref->a.func_export = 1;
6046 /* use static from prototype */
6047 if (sym->type.t & VT_STATIC)
6048 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6050 /* If the definition has no visibility use the
6051 one from prototype. */
6052 if (! (type.t & VT_VIS_MASK))
6053 type.t |= sym->type.t & VT_VIS_MASK;
6055 if (!is_compatible_types(&sym->type, &type)) {
6056 func_error1:
6057 tcc_error("incompatible types for redefinition of '%s'",
6058 get_tok_str(v, NULL));
6060 type.ref->a.func_proto = 0;
6061 /* if symbol is already defined, then put complete type */
6062 sym->type = type;
6063 } else {
6064 /* put function symbol */
6065 sym = global_identifier_push(v, type.t, 0);
6066 sym->type.ref = type.ref;
6069 /* static inline functions are just recorded as a kind
6070 of macro. Their code will be emitted at the end of
6071 the compilation unit only if they are used */
6072 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6073 (VT_INLINE | VT_STATIC)) {
6074 TokenString func_str;
6075 int block_level;
6076 struct InlineFunc *fn;
6077 const char *filename;
6079 tok_str_new(&func_str);
6081 block_level = 0;
6082 for(;;) {
6083 int t;
6084 if (tok == TOK_EOF)
6085 tcc_error("unexpected end of file");
6086 tok_str_add_tok(&func_str);
6087 t = tok;
6088 next();
6089 if (t == '{') {
6090 block_level++;
6091 } else if (t == '}') {
6092 block_level--;
6093 if (block_level == 0)
6094 break;
6097 tok_str_add(&func_str, -1);
6098 tok_str_add(&func_str, 0);
6099 filename = file ? file->filename : "";
6100 fn = tcc_malloc(sizeof *fn + strlen(filename));
6101 strcpy(fn->filename, filename);
6102 fn->sym = sym;
6103 fn->token_str = func_str.str;
6104 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6106 } else {
6107 /* compute text section */
6108 cur_text_section = ad.section;
6109 if (!cur_text_section)
6110 cur_text_section = text_section;
6111 sym->r = VT_SYM | VT_CONST;
6112 gen_function(sym);
6114 break;
6115 } else {
6116 if (btype.t & VT_TYPEDEF) {
6117 /* save typedefed type */
6118 /* XXX: test storage specifiers ? */
6119 sym = sym_push(v, &type, 0, 0);
6120 sym->a = ad.a;
6121 sym->type.t |= VT_TYPEDEF;
6122 } else {
6123 r = 0;
6124 if ((type.t & VT_BTYPE) == VT_FUNC) {
6125 /* external function definition */
6126 /* specific case for func_call attribute */
6127 ad.a.func_proto = 1;
6128 type.ref->a = ad.a;
6129 } else if (!(type.t & VT_ARRAY)) {
6130 /* not lvalue if array */
6131 r |= lvalue_type(type.t);
6133 has_init = (tok == '=');
6134 if (has_init && (type.t & VT_VLA))
6135 tcc_error("Variable length array cannot be initialized");
6136 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6137 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6138 !has_init && l == VT_CONST && type.ref->c < 0)) {
6139 /* external variable or function */
6140 /* NOTE: as GCC, uninitialized global static
6141 arrays of null size are considered as
6142 extern */
6143 sym = external_sym(v, &type, r, asm_label);
6145 if (ad.alias_target) {
6146 Section tsec;
6147 Elf32_Sym *esym;
6148 Sym *alias_target;
6150 alias_target = sym_find(ad.alias_target);
6151 if (!alias_target || !alias_target->c)
6152 tcc_error("unsupported forward __alias__ attribute");
6153 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6154 tsec.sh_num = esym->st_shndx;
6155 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6157 } else {
6158 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6159 if (type.t & VT_STATIC)
6160 r |= VT_CONST;
6161 else
6162 r |= l;
6163 if (has_init)
6164 next();
6165 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
6168 if (tok != ',') {
6169 if (is_for_loop_init)
6170 return 1;
6171 skip(';');
6172 break;
6174 next();
6176 ad.a.aligned = 0;
6179 return 0;
6182 ST_FUNC void decl(int l)
6184 decl0(l, 0);