Add warning 3
[tinycc.git] / tccgen.c
blob9076da5169672f92109aaeb162e5c3c2bc72df03
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /********************************************************/
24 /* global variables */
26 /* loc : local variable index
27 ind : output code index
28 rsym: return symbol
29 anon_sym: anonymous symbol index
31 ST_DATA int rsym, anon_sym, ind, loc;
33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
34 ST_DATA Section *cur_text_section; /* current section where function code is generated */
35 #ifdef CONFIG_TCC_ASM
36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
37 #endif
38 #ifdef CONFIG_TCC_BCHECK
39 /* bound check related sections */
40 ST_DATA Section *bounds_section; /* contains global data bound description */
41 ST_DATA Section *lbounds_section; /* contains local data bound description */
42 #endif
43 /* symbol sections */
44 ST_DATA Section *symtab_section, *strtab_section;
45 /* debug sections */
46 ST_DATA Section *stab_section, *stabstr_section;
47 ST_DATA Sym *sym_free_first;
48 ST_DATA void **sym_pools;
49 ST_DATA int nb_sym_pools;
51 ST_DATA Sym *global_stack;
52 ST_DATA Sym *local_stack;
53 ST_DATA Sym *scope_stack_bottom;
54 ST_DATA Sym *define_stack;
55 ST_DATA Sym *global_label_stack;
56 ST_DATA Sym *local_label_stack;
58 ST_DATA int vla_sp_loc_tmp; /* vla_sp_loc is set to this when the value won't be needed later */
59 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
60 ST_DATA int *vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
61 ST_DATA int vla_flags; /* VLA_* flags */
63 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
65 ST_DATA int const_wanted; /* true if constant wanted */
66 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
67 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
68 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
69 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
70 ST_DATA int func_vc;
71 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
72 ST_DATA char *funcname;
74 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
76 /* ------------------------------------------------------------------------- */
77 static void gen_cast(CType *type);
78 static inline CType *pointed_type(CType *type);
79 static int is_compatible_types(CType *type1, CType *type2);
80 static int parse_btype(CType *type, AttributeDef *ad);
81 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
82 static void parse_expr_type(CType *type);
83 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
84 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
85 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
86 static int decl0(int l, int is_for_loop_init);
87 static void expr_eq(void);
88 static void unary_type(CType *type);
89 static void vla_runtime_type_size(CType *type, int *a);
90 static void vla_sp_save(void);
91 static int is_compatible_parameter_types(CType *type1, CType *type2);
92 static void expr_type(CType *type);
93 ST_FUNC void vpush64(int ty, unsigned long long v);
94 ST_FUNC void vpush(CType *type);
95 ST_FUNC int gvtst(int inv, int t);
96 ST_FUNC int is_btype_size(int bt);
98 ST_INLN int is_float(int t)
100 int bt;
101 bt = t & VT_BTYPE;
102 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
105 /* we use our own 'finite' function to avoid potential problems with
106 non standard math libs */
107 /* XXX: endianness dependent */
108 ST_FUNC int ieee_finite(double d)
110 int p[4];
111 memcpy(p, &d, sizeof(double));
112 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
115 ST_FUNC void test_lvalue(void)
117 if (!(vtop->r & VT_LVAL))
118 expect("lvalue");
121 /* ------------------------------------------------------------------------- */
122 /* symbol allocator */
123 static Sym *__sym_malloc(void)
125 Sym *sym_pool, *sym, *last_sym;
126 int i;
128 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
129 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
131 last_sym = sym_free_first;
132 sym = sym_pool;
133 for(i = 0; i < SYM_POOL_NB; i++) {
134 sym->next = last_sym;
135 last_sym = sym;
136 sym++;
138 sym_free_first = last_sym;
139 return last_sym;
142 static inline Sym *sym_malloc(void)
144 Sym *sym;
145 sym = sym_free_first;
146 if (!sym)
147 sym = __sym_malloc();
148 sym_free_first = sym->next;
149 return sym;
152 ST_INLN void sym_free(Sym *sym)
154 sym->next = sym_free_first;
155 tcc_free(sym->asm_label);
156 sym_free_first = sym;
159 /* push, without hashing */
160 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
162 Sym *s;
163 if (ps == &local_stack) {
164 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
165 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
166 tcc_error("incompatible types for redefinition of '%s'",
167 get_tok_str(v, NULL));
169 s = sym_malloc();
170 s->asm_label = NULL;
171 s->v = v;
172 s->type.t = t;
173 s->type.ref = NULL;
174 #ifdef _WIN64
175 s->d = NULL;
176 #endif
177 s->c = c;
178 s->next = NULL;
179 /* add in stack */
180 s->prev = *ps;
181 *ps = s;
182 return s;
185 /* find a symbol and return its associated structure. 's' is the top
186 of the symbol stack */
187 ST_FUNC Sym *sym_find2(Sym *s, int v)
189 while (s) {
190 if (s->v == v)
191 return s;
192 else if (s->v == -1)
193 return NULL;
194 s = s->prev;
196 return NULL;
199 /* structure lookup */
200 ST_INLN Sym *struct_find(int v)
202 v -= TOK_IDENT;
203 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
204 return NULL;
205 return table_ident[v]->sym_struct;
208 /* find an identifier */
209 ST_INLN Sym *sym_find(int v)
211 v -= TOK_IDENT;
212 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
213 return NULL;
214 return table_ident[v]->sym_identifier;
217 /* push a given symbol on the symbol stack */
218 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
220 Sym *s, **ps;
221 TokenSym *ts;
223 if (local_stack)
224 ps = &local_stack;
225 else
226 ps = &global_stack;
227 s = sym_push2(ps, v, type->t, c);
228 s->type.ref = type->ref;
229 s->r = r;
230 /* don't record fields or anonymous symbols */
231 /* XXX: simplify */
232 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
233 /* record symbol in token array */
234 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
235 if (v & SYM_STRUCT)
236 ps = &ts->sym_struct;
237 else
238 ps = &ts->sym_identifier;
239 s->prev_tok = *ps;
240 *ps = s;
242 return s;
245 /* push a global identifier */
246 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
248 Sym *s, **ps;
249 s = sym_push2(&global_stack, v, t, c);
250 /* don't record anonymous symbol */
251 if (v < SYM_FIRST_ANOM) {
252 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
253 /* modify the top most local identifier, so that
254 sym_identifier will point to 's' when popped */
255 while (*ps != NULL)
256 ps = &(*ps)->prev_tok;
257 s->prev_tok = NULL;
258 *ps = s;
260 return s;
263 /* pop symbols until top reaches 'b' */
264 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
266 Sym *s, *ss, **ps;
267 TokenSym *ts;
268 int v;
270 s = *ptop;
271 while(s != b) {
272 ss = s->prev;
273 v = s->v;
274 /* remove symbol in token array */
275 /* XXX: simplify */
276 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
277 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
278 if (v & SYM_STRUCT)
279 ps = &ts->sym_struct;
280 else
281 ps = &ts->sym_identifier;
282 *ps = s->prev_tok;
284 sym_free(s);
285 s = ss;
287 *ptop = b;
290 static void weaken_symbol(Sym *sym)
292 sym->type.t |= VT_WEAK;
293 if (sym->c > 0) {
294 int esym_type;
295 ElfW(Sym) *esym;
297 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
298 esym_type = ELFW(ST_TYPE)(esym->st_info);
299 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
303 static void apply_visibility(Sym *sym, CType *type)
305 int vis = sym->type.t & VT_VIS_MASK;
306 int vis2 = type->t & VT_VIS_MASK;
307 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
308 vis = vis2;
309 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
311 else
312 vis = (vis < vis2) ? vis : vis2;
313 sym->type.t &= ~VT_VIS_MASK;
314 sym->type.t |= vis;
316 if (sym->c > 0) {
317 ElfW(Sym) *esym;
319 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
320 vis >>= VT_VIS_SHIFT;
321 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
325 /* ------------------------------------------------------------------------- */
327 ST_FUNC void swap(int *p, int *q)
329 int t;
330 t = *p;
331 *p = *q;
332 *q = t;
335 static void vsetc(CType *type, int r, CValue *vc)
337 int v;
339 if (vtop >= vstack + (VSTACK_SIZE - 1))
340 tcc_error("memory full (vstack)");
341 /* cannot let cpu flags if other instruction are generated. Also
342 avoid leaving VT_JMP anywhere except on the top of the stack
343 because it would complicate the code generator. */
344 if (vtop >= vstack) {
345 v = vtop->r & VT_VALMASK;
346 if (v == VT_CMP || (v & ~1) == VT_JMP)
347 gv(RC_INT);
349 vtop++;
350 vtop->type = *type;
351 vtop->r = r;
352 vtop->r2 = VT_CONST;
353 vtop->c = *vc;
356 /* push constant of type "type" with useless value */
357 ST_FUNC void vpush(CType *type)
359 CValue cval;
360 vsetc(type, VT_CONST, &cval);
363 /* push integer constant */
364 ST_FUNC void vpushi(int v)
366 CValue cval;
367 cval.i = v;
368 vsetc(&int_type, VT_CONST, &cval);
371 /* push a pointer sized constant */
372 static void vpushs(addr_t v)
374 CValue cval;
375 cval.ptr_offset = v;
376 vsetc(&size_type, VT_CONST, &cval);
379 /* push arbitrary 64bit constant */
380 ST_FUNC void vpush64(int ty, unsigned long long v)
382 CValue cval;
383 CType ctype;
384 ctype.t = ty;
385 ctype.ref = NULL;
386 cval.ull = v;
387 vsetc(&ctype, VT_CONST, &cval);
390 /* push long long constant */
391 static inline void vpushll(long long v)
393 vpush64(VT_LLONG, v);
396 /* push a symbol value of TYPE */
397 static inline void vpushsym(CType *type, Sym *sym)
399 CValue cval;
400 cval.ptr_offset = 0;
401 vsetc(type, VT_CONST | VT_SYM, &cval);
402 vtop->sym = sym;
405 /* Return a static symbol pointing to a section */
406 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
408 int v;
409 Sym *sym;
411 v = anon_sym++;
412 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
413 sym->type.ref = type->ref;
414 sym->r = VT_CONST | VT_SYM;
415 put_extern_sym(sym, sec, offset, size);
416 return sym;
419 /* push a reference to a section offset by adding a dummy symbol */
420 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
422 vpushsym(type, get_sym_ref(type, sec, offset, size));
425 /* define a new external reference to a symbol 'v' of type 'u' */
426 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
428 Sym *s;
430 s = sym_find(v);
431 if (!s) {
432 /* push forward reference */
433 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
434 s->type.ref = type->ref;
435 s->r = r | VT_CONST | VT_SYM;
437 return s;
440 /* define a new external reference to a symbol 'v' with alternate asm
441 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
442 is no alternate name (most cases) */
443 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
445 Sym *s;
447 s = sym_find(v);
448 if (!s) {
449 /* push forward reference */
450 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
451 s->asm_label = asm_label;
452 s->type.t |= VT_EXTERN;
453 } else if (s->type.ref == func_old_type.ref) {
454 s->type.ref = type->ref;
455 s->r = r | VT_CONST | VT_SYM;
456 s->type.t |= VT_EXTERN;
457 } else if (!is_compatible_types(&s->type, type)) {
458 tcc_error("incompatible types for redefinition of '%s'",
459 get_tok_str(v, NULL));
461 /* Merge some storage attributes. */
462 if (type->t & VT_WEAK)
463 weaken_symbol(s);
465 if (type->t & VT_VIS_MASK)
466 apply_visibility(s, type);
468 return s;
471 /* push a reference to global symbol v */
472 ST_FUNC void vpush_global_sym(CType *type, int v)
474 vpushsym(type, external_global_sym(v, type, 0));
477 ST_FUNC void vset(CType *type, int r, int v)
479 CValue cval;
481 cval.i = v;
482 vsetc(type, r, &cval);
485 static void vseti(int r, int v)
487 CType type;
488 type.t = VT_INT;
489 type.ref = 0;
490 vset(&type, r, v);
493 ST_FUNC void vswap(void)
495 SValue tmp;
496 /* cannot let cpu flags if other instruction are generated. Also
497 avoid leaving VT_JMP anywhere except on the top of the stack
498 because it would complicate the code generator. */
499 if (vtop >= vstack) {
500 int v = vtop->r & VT_VALMASK;
501 if (v == VT_CMP || (v & ~1) == VT_JMP)
502 gv(RC_INT);
504 tmp = vtop[0];
505 vtop[0] = vtop[-1];
506 vtop[-1] = tmp;
508 /* XXX: +2% overall speed possible with optimized memswap
510 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
514 ST_FUNC void vpushv(SValue *v)
516 if (vtop >= vstack + (VSTACK_SIZE - 1))
517 tcc_error("memory full (vstack)");
518 vtop++;
519 *vtop = *v;
522 static void vdup(void)
524 vpushv(vtop);
527 /* save r to the memory stack, and mark it as being free */
528 ST_FUNC void save_reg(int r)
530 int l, saved, size, align;
531 SValue *p, sv;
532 CType *type;
534 /* modify all stack values */
535 saved = 0;
536 l = 0;
537 for(p=vstack;p<=vtop;p++) {
538 if ((p->r & VT_VALMASK) == r ||
539 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
540 /* must save value on stack if not already done */
541 if (!saved) {
542 /* NOTE: must reload 'r' because r might be equal to r2 */
543 r = p->r & VT_VALMASK;
544 /* store register in the stack */
545 type = &p->type;
546 if ((p->r & VT_LVAL) ||
547 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
548 #ifdef TCC_TARGET_X86_64
549 type = &char_pointer_type;
550 #else
551 type = &int_type;
552 #endif
553 size = type_size(type, &align);
554 loc = (loc - size) & -align;
555 sv.type.t = type->t;
556 sv.r = VT_LOCAL | VT_LVAL;
557 sv.c.ul = loc;
558 store(r, &sv);
559 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
560 /* x86 specific: need to pop fp register ST0 if saved */
561 if (r == TREG_ST0) {
562 o(0xd8dd); /* fstp %st(0) */
564 #endif
565 #ifndef TCC_TARGET_X86_64
566 /* special long long case */
567 if ((type->t & VT_BTYPE) == VT_LLONG) {
568 sv.c.ul += 4;
569 store(p->r2, &sv);
571 #endif
572 l = loc;
573 saved = 1;
575 /* mark that stack entry as being saved on the stack */
576 if (p->r & VT_LVAL) {
577 /* also clear the bounded flag because the
578 relocation address of the function was stored in
579 p->c.ul */
580 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
581 } else {
582 p->r = lvalue_type(p->type.t) | VT_LOCAL;
584 p->r2 = VT_CONST;
585 p->c.ul = l;
590 #ifdef TCC_TARGET_ARM
591 /* find a register of class 'rc2' with at most one reference on stack.
592 * If none, call get_reg(rc) */
593 ST_FUNC int get_reg_ex(int rc, int rc2)
595 int r;
596 SValue *p;
598 for(r=0;r<NB_REGS;r++) {
599 if (reg_classes[r] & rc2) {
600 int n;
601 n=0;
602 for(p = vstack; p <= vtop; p++) {
603 if ((p->r & VT_VALMASK) == r ||
604 (p->r2 & VT_VALMASK) == r)
605 n++;
607 if (n <= 1)
608 return r;
611 return get_reg(rc);
613 #endif
615 /* find a free register of class 'rc'. If none, save one register */
616 ST_FUNC int get_reg(int rc)
618 int r;
619 SValue *p;
621 /* find a free register */
622 for(r=0;r<NB_REGS;r++) {
623 if (reg_classes[r] & rc) {
624 for(p=vstack;p<=vtop;p++) {
625 if ((p->r & VT_VALMASK) == r ||
626 (p->r2 & VT_VALMASK) == r)
627 goto notfound;
629 return r;
631 notfound: ;
634 /* no register left : free the first one on the stack (VERY
635 IMPORTANT to start from the bottom to ensure that we don't
636 spill registers used in gen_opi()) */
637 for(p=vstack;p<=vtop;p++) {
638 /* look at second register (if long long) */
639 r = p->r2 & VT_VALMASK;
640 if (r < VT_CONST && (reg_classes[r] & rc))
641 goto save_found;
642 r = p->r & VT_VALMASK;
643 if (r < VT_CONST && (reg_classes[r] & rc)) {
644 save_found:
645 save_reg(r);
646 return r;
649 /* Should never comes here */
650 return -1;
653 /* save registers up to (vtop - n) stack entry */
654 ST_FUNC void save_regs(int n)
656 int r;
657 SValue *p, *p1;
658 p1 = vtop - n;
659 for(p = vstack;p <= p1; p++) {
660 r = p->r & VT_VALMASK;
661 if (r < VT_CONST) {
662 save_reg(r);
667 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
668 if needed */
669 static void move_reg(int r, int s, int t)
671 SValue sv;
673 if (r != s) {
674 save_reg(r);
675 sv.type.t = t;
676 sv.type.ref = NULL;
677 sv.r = s;
678 sv.c.ul = 0;
679 load(r, &sv);
683 /* get address of vtop (vtop MUST BE an lvalue) */
684 static void gaddrof(void)
686 if (vtop->r & VT_REF)
687 gv(RC_INT);
688 vtop->r &= ~VT_LVAL;
689 /* tricky: if saved lvalue, then we can go back to lvalue */
690 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
691 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
696 #ifdef CONFIG_TCC_BCHECK
697 /* generate lvalue bound code */
698 static void gbound(void)
700 int lval_type;
701 CType type1;
703 vtop->r &= ~VT_MUSTBOUND;
704 /* if lvalue, then use checking code before dereferencing */
705 if (vtop->r & VT_LVAL) {
706 /* if not VT_BOUNDED value, then make one */
707 if (!(vtop->r & VT_BOUNDED)) {
708 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
709 /* must save type because we must set it to int to get pointer */
710 type1 = vtop->type;
711 vtop->type.t = VT_INT;
712 gaddrof();
713 vpushi(0);
714 gen_bounded_ptr_add();
715 vtop->r |= lval_type;
716 vtop->type = type1;
718 /* then check for dereferencing */
719 gen_bounded_ptr_deref();
722 #endif
724 /* store vtop a register belonging to class 'rc'. lvalues are
725 converted to values. Cannot be used if cannot be converted to
726 register value (such as structures). */
727 ST_FUNC int gv(int rc)
729 int r, bit_pos, bit_size, size, align, i;
730 int rc2;
732 /* NOTE: get_reg can modify vstack[] */
733 if (vtop->type.t & VT_BITFIELD) {
734 CType type;
735 int bits = 32;
736 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
737 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
738 /* remove bit field info to avoid loops */
739 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
740 /* cast to int to propagate signedness in following ops */
741 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
742 type.t = VT_LLONG;
743 bits = 64;
744 } else
745 type.t = VT_INT;
746 if((vtop->type.t & VT_UNSIGNED) ||
747 (vtop->type.t & VT_BTYPE) == VT_BOOL)
748 type.t |= VT_UNSIGNED;
749 gen_cast(&type);
750 /* generate shifts */
751 vpushi(bits - (bit_pos + bit_size));
752 gen_op(TOK_SHL);
753 vpushi(bits - bit_size);
754 /* NOTE: transformed to SHR if unsigned */
755 gen_op(TOK_SAR);
756 r = gv(rc);
757 } else {
758 if (is_float(vtop->type.t) &&
759 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
760 Sym *sym;
761 int *ptr;
762 unsigned long offset;
763 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
764 CValue check;
765 #endif
767 /* XXX: unify with initializers handling ? */
768 /* CPUs usually cannot use float constants, so we store them
769 generically in data segment */
770 size = type_size(&vtop->type, &align);
771 offset = (data_section->data_offset + align - 1) & -align;
772 data_section->data_offset = offset;
773 /* XXX: not portable yet */
774 #if defined(__i386__) || defined(__x86_64__)
775 /* Zero pad x87 tenbyte long doubles */
776 if (size == LDOUBLE_SIZE) {
777 vtop->c.tab[2] &= 0xffff;
778 #if LDOUBLE_SIZE == 16
779 vtop->c.tab[3] = 0;
780 #endif
782 #endif
783 ptr = section_ptr_add(data_section, size);
784 size = size >> 2;
785 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
786 check.d = 1;
787 if(check.tab[0])
788 for(i=0;i<size;i++)
789 ptr[i] = vtop->c.tab[size-1-i];
790 else
791 #endif
792 for(i=0;i<size;i++)
793 ptr[i] = vtop->c.tab[i];
794 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
795 vtop->r |= VT_LVAL | VT_SYM;
796 vtop->sym = sym;
797 vtop->c.ptr_offset = 0;
799 #ifdef CONFIG_TCC_BCHECK
800 if (vtop->r & VT_MUSTBOUND)
801 gbound();
802 #endif
804 r = vtop->r & VT_VALMASK;
805 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
806 if (rc == RC_IRET)
807 rc2 = RC_LRET;
808 #ifdef TCC_TARGET_X86_64
809 else if (rc == RC_FRET)
810 rc2 = RC_QRET;
811 #endif
813 /* need to reload if:
814 - constant
815 - lvalue (need to dereference pointer)
816 - already a register, but not in the right class */
817 if (r >= VT_CONST
818 || (vtop->r & VT_LVAL)
819 || !(reg_classes[r] & rc)
820 #ifdef TCC_TARGET_X86_64
821 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
822 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
823 #else
824 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
825 #endif
828 r = get_reg(rc);
829 #ifdef TCC_TARGET_X86_64
830 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
831 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
832 #else
833 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
834 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
835 unsigned long long ll;
836 #endif
837 int r2, original_type;
838 original_type = vtop->type.t;
839 /* two register type load : expand to two words
840 temporarily */
841 #ifndef TCC_TARGET_X86_64
842 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
843 /* load constant */
844 ll = vtop->c.ull;
845 vtop->c.ui = ll; /* first word */
846 load(r, vtop);
847 vtop->r = r; /* save register value */
848 vpushi(ll >> 32); /* second word */
849 } else
850 #endif
851 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
852 (vtop->r & VT_LVAL)) {
853 /* We do not want to modifier the long long
854 pointer here, so the safest (and less
855 efficient) is to save all the other registers
856 in the stack. XXX: totally inefficient. */
857 save_regs(1);
858 /* load from memory */
859 vtop->type.t = load_type;
860 load(r, vtop);
861 vdup();
862 vtop[-1].r = r; /* save register value */
863 /* increment pointer to get second word */
864 vtop->type.t = addr_type;
865 gaddrof();
866 vpushi(load_size);
867 gen_op('+');
868 vtop->r |= VT_LVAL;
869 vtop->type.t = load_type;
870 } else {
871 /* move registers */
872 load(r, vtop);
873 vdup();
874 vtop[-1].r = r; /* save register value */
875 vtop->r = vtop[-1].r2;
877 /* Allocate second register. Here we rely on the fact that
878 get_reg() tries first to free r2 of an SValue. */
879 r2 = get_reg(rc2);
880 load(r2, vtop);
881 vpop();
882 /* write second register */
883 vtop->r2 = r2;
884 vtop->type.t = original_type;
885 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
886 int t1, t;
887 /* lvalue of scalar type : need to use lvalue type
888 because of possible cast */
889 t = vtop->type.t;
890 t1 = t;
891 /* compute memory access type */
892 if (vtop->r & VT_REF)
893 #ifdef TCC_TARGET_X86_64
894 t = VT_PTR;
895 #else
896 t = VT_INT;
897 #endif
898 else if (vtop->r & VT_LVAL_BYTE)
899 t = VT_BYTE;
900 else if (vtop->r & VT_LVAL_SHORT)
901 t = VT_SHORT;
902 if (vtop->r & VT_LVAL_UNSIGNED)
903 t |= VT_UNSIGNED;
904 vtop->type.t = t;
905 load(r, vtop);
906 /* restore wanted type */
907 vtop->type.t = t1;
908 } else {
909 /* one register type load */
910 load(r, vtop);
913 vtop->r = r;
914 #ifdef TCC_TARGET_C67
915 /* uses register pairs for doubles */
916 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
917 vtop->r2 = r+1;
918 #endif
920 return r;
923 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
924 ST_FUNC void gv2(int rc1, int rc2)
926 int v;
928 /* generate more generic register first. But VT_JMP or VT_CMP
929 values must be generated first in all cases to avoid possible
930 reload errors */
931 v = vtop[0].r & VT_VALMASK;
932 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
933 vswap();
934 gv(rc1);
935 vswap();
936 gv(rc2);
937 /* test if reload is needed for first register */
938 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
939 vswap();
940 gv(rc1);
941 vswap();
943 } else {
944 gv(rc2);
945 vswap();
946 gv(rc1);
947 vswap();
948 /* test if reload is needed for first register */
949 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
950 gv(rc2);
955 /* wrapper around RC_FRET to return a register by type */
956 static int rc_fret(int t)
958 #ifdef TCC_TARGET_X86_64
959 if (t == VT_LDOUBLE) {
960 return RC_ST0;
962 #endif
963 return RC_FRET;
966 /* wrapper around REG_FRET to return a register by type */
967 static int reg_fret(int t)
969 #ifdef TCC_TARGET_X86_64
970 if (t == VT_LDOUBLE) {
971 return TREG_ST0;
973 #endif
974 return REG_FRET;
977 /* expand long long on stack in two int registers */
978 static void lexpand(void)
980 int u;
982 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
983 gv(RC_INT);
984 vdup();
985 vtop[0].r = vtop[-1].r2;
986 vtop[0].r2 = VT_CONST;
987 vtop[-1].r2 = VT_CONST;
988 vtop[0].type.t = VT_INT | u;
989 vtop[-1].type.t = VT_INT | u;
992 #ifdef TCC_TARGET_ARM
993 /* expand long long on stack */
994 ST_FUNC void lexpand_nr(void)
996 int u,v;
998 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
999 vdup();
1000 vtop->r2 = VT_CONST;
1001 vtop->type.t = VT_INT | u;
1002 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1003 if (v == VT_CONST) {
1004 vtop[-1].c.ui = vtop->c.ull;
1005 vtop->c.ui = vtop->c.ull >> 32;
1006 vtop->r = VT_CONST;
1007 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1008 vtop->c.ui += 4;
1009 vtop->r = vtop[-1].r;
1010 } else if (v > VT_CONST) {
1011 vtop--;
1012 lexpand();
1013 } else
1014 vtop->r = vtop[-1].r2;
1015 vtop[-1].r2 = VT_CONST;
1016 vtop[-1].type.t = VT_INT | u;
1018 #endif
1020 /* build a long long from two ints */
1021 static void lbuild(int t)
1023 gv2(RC_INT, RC_INT);
1024 vtop[-1].r2 = vtop[0].r;
1025 vtop[-1].type.t = t;
1026 vpop();
1029 /* rotate n first stack elements to the bottom
1030 I1 ... In -> I2 ... In I1 [top is right]
1032 ST_FUNC void vrotb(int n)
1034 int i;
1035 SValue tmp;
1037 tmp = vtop[-n + 1];
1038 for(i=-n+1;i!=0;i++)
1039 vtop[i] = vtop[i+1];
1040 vtop[0] = tmp;
1043 /* rotate the n elements before entry e towards the top
1044 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1046 ST_FUNC void vrote(SValue *e, int n)
1048 int i;
1049 SValue tmp;
1051 tmp = *e;
1052 for(i = 0;i < n - 1; i++)
1053 e[-i] = e[-i - 1];
1054 e[-n + 1] = tmp;
1057 /* rotate n first stack elements to the top
1058 I1 ... In -> In I1 ... I(n-1) [top is right]
1060 ST_FUNC void vrott(int n)
1062 vrote(vtop, n);
1065 /* pop stack value */
1066 ST_FUNC void vpop(void)
1068 int v;
1069 v = vtop->r & VT_VALMASK;
1070 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1071 /* for x86, we need to pop the FP stack */
1072 if (v == TREG_ST0 && !nocode_wanted) {
1073 o(0xd8dd); /* fstp %st(0) */
1074 } else
1075 #endif
1076 if (v == VT_JMP || v == VT_JMPI) {
1077 /* need to put correct jump if && or || without test */
1078 gsym(vtop->c.ul);
1080 vtop--;
1083 /* convert stack entry to register and duplicate its value in another
1084 register */
1085 static void gv_dup(void)
1087 int rc, t, r, r1;
1088 SValue sv;
1090 t = vtop->type.t;
1091 if ((t & VT_BTYPE) == VT_LLONG) {
1092 lexpand();
1093 gv_dup();
1094 vswap();
1095 vrotb(3);
1096 gv_dup();
1097 vrotb(4);
1098 /* stack: H L L1 H1 */
1099 lbuild(t);
1100 vrotb(3);
1101 vrotb(3);
1102 vswap();
1103 lbuild(t);
1104 vswap();
1105 } else {
1106 /* duplicate value */
1107 rc = RC_INT;
1108 sv.type.t = VT_INT;
1109 if (is_float(t)) {
1110 rc = RC_FLOAT;
1111 #ifdef TCC_TARGET_X86_64
1112 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1113 rc = RC_ST0;
1115 #endif
1116 sv.type.t = t;
1118 r = gv(rc);
1119 r1 = get_reg(rc);
1120 sv.r = r;
1121 sv.c.ul = 0;
1122 load(r1, &sv); /* move r to r1 */
1123 vdup();
1124 /* duplicates value */
1125 if (r != r1)
1126 vtop->r = r1;
1130 /* Generate value test
1132 * Generate a test for any value (jump, comparison and integers) */
1133 ST_FUNC int gvtst(int inv, int t)
1135 int v = vtop->r & VT_VALMASK;
1136 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1137 vpushi(0);
1138 gen_op(TOK_NE);
1140 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1141 /* constant jmp optimization */
1142 if ((vtop->c.i != 0) != inv)
1143 t = gjmp(t);
1144 vtop--;
1145 return t;
1147 return gtst(inv, t);
1150 #ifndef TCC_TARGET_X86_64
1151 /* generate CPU independent (unsigned) long long operations */
1152 static void gen_opl(int op)
1154 int t, a, b, op1, c, i;
1155 int func;
1156 unsigned short reg_iret = REG_IRET;
1157 unsigned short reg_lret = REG_LRET;
1158 SValue tmp;
1160 switch(op) {
1161 case '/':
1162 case TOK_PDIV:
1163 func = TOK___divdi3;
1164 goto gen_func;
1165 case TOK_UDIV:
1166 func = TOK___udivdi3;
1167 goto gen_func;
1168 case '%':
1169 func = TOK___moddi3;
1170 goto gen_mod_func;
1171 case TOK_UMOD:
1172 func = TOK___umoddi3;
1173 gen_mod_func:
1174 #ifdef TCC_ARM_EABI
1175 reg_iret = TREG_R2;
1176 reg_lret = TREG_R3;
1177 #endif
1178 gen_func:
1179 /* call generic long long function */
1180 vpush_global_sym(&func_old_type, func);
1181 vrott(3);
1182 gfunc_call(2);
1183 vpushi(0);
1184 vtop->r = reg_iret;
1185 vtop->r2 = reg_lret;
1186 break;
1187 case '^':
1188 case '&':
1189 case '|':
1190 case '*':
1191 case '+':
1192 case '-':
1193 t = vtop->type.t;
1194 vswap();
1195 lexpand();
1196 vrotb(3);
1197 lexpand();
1198 /* stack: L1 H1 L2 H2 */
1199 tmp = vtop[0];
1200 vtop[0] = vtop[-3];
1201 vtop[-3] = tmp;
1202 tmp = vtop[-2];
1203 vtop[-2] = vtop[-3];
1204 vtop[-3] = tmp;
1205 vswap();
1206 /* stack: H1 H2 L1 L2 */
1207 if (op == '*') {
1208 vpushv(vtop - 1);
1209 vpushv(vtop - 1);
1210 gen_op(TOK_UMULL);
1211 lexpand();
1212 /* stack: H1 H2 L1 L2 ML MH */
1213 for(i=0;i<4;i++)
1214 vrotb(6);
1215 /* stack: ML MH H1 H2 L1 L2 */
1216 tmp = vtop[0];
1217 vtop[0] = vtop[-2];
1218 vtop[-2] = tmp;
1219 /* stack: ML MH H1 L2 H2 L1 */
1220 gen_op('*');
1221 vrotb(3);
1222 vrotb(3);
1223 gen_op('*');
1224 /* stack: ML MH M1 M2 */
1225 gen_op('+');
1226 gen_op('+');
1227 } else if (op == '+' || op == '-') {
1228 /* XXX: add non carry method too (for MIPS or alpha) */
1229 if (op == '+')
1230 op1 = TOK_ADDC1;
1231 else
1232 op1 = TOK_SUBC1;
1233 gen_op(op1);
1234 /* stack: H1 H2 (L1 op L2) */
1235 vrotb(3);
1236 vrotb(3);
1237 gen_op(op1 + 1); /* TOK_xxxC2 */
1238 } else {
1239 gen_op(op);
1240 /* stack: H1 H2 (L1 op L2) */
1241 vrotb(3);
1242 vrotb(3);
1243 /* stack: (L1 op L2) H1 H2 */
1244 gen_op(op);
1245 /* stack: (L1 op L2) (H1 op H2) */
1247 /* stack: L H */
1248 lbuild(t);
1249 break;
1250 case TOK_SAR:
1251 case TOK_SHR:
1252 case TOK_SHL:
1253 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1254 t = vtop[-1].type.t;
1255 vswap();
1256 lexpand();
1257 vrotb(3);
1258 /* stack: L H shift */
1259 c = (int)vtop->c.i;
1260 /* constant: simpler */
1261 /* NOTE: all comments are for SHL. the other cases are
1262 done by swaping words */
1263 vpop();
1264 if (op != TOK_SHL)
1265 vswap();
1266 if (c >= 32) {
1267 /* stack: L H */
1268 vpop();
1269 if (c > 32) {
1270 vpushi(c - 32);
1271 gen_op(op);
1273 if (op != TOK_SAR) {
1274 vpushi(0);
1275 } else {
1276 gv_dup();
1277 vpushi(31);
1278 gen_op(TOK_SAR);
1280 vswap();
1281 } else {
1282 vswap();
1283 gv_dup();
1284 /* stack: H L L */
1285 vpushi(c);
1286 gen_op(op);
1287 vswap();
1288 vpushi(32 - c);
1289 if (op == TOK_SHL)
1290 gen_op(TOK_SHR);
1291 else
1292 gen_op(TOK_SHL);
1293 vrotb(3);
1294 /* stack: L L H */
1295 vpushi(c);
1296 if (op == TOK_SHL)
1297 gen_op(TOK_SHL);
1298 else
1299 gen_op(TOK_SHR);
1300 gen_op('|');
1302 if (op != TOK_SHL)
1303 vswap();
1304 lbuild(t);
1305 } else {
1306 /* XXX: should provide a faster fallback on x86 ? */
1307 switch(op) {
1308 case TOK_SAR:
1309 func = TOK___ashrdi3;
1310 goto gen_func;
1311 case TOK_SHR:
1312 func = TOK___lshrdi3;
1313 goto gen_func;
1314 case TOK_SHL:
1315 func = TOK___ashldi3;
1316 goto gen_func;
1319 break;
1320 default:
1321 /* compare operations */
1322 t = vtop->type.t;
1323 vswap();
1324 lexpand();
1325 vrotb(3);
1326 lexpand();
1327 /* stack: L1 H1 L2 H2 */
1328 tmp = vtop[-1];
1329 vtop[-1] = vtop[-2];
1330 vtop[-2] = tmp;
1331 /* stack: L1 L2 H1 H2 */
1332 /* compare high */
1333 op1 = op;
1334 /* when values are equal, we need to compare low words. since
1335 the jump is inverted, we invert the test too. */
1336 if (op1 == TOK_LT)
1337 op1 = TOK_LE;
1338 else if (op1 == TOK_GT)
1339 op1 = TOK_GE;
1340 else if (op1 == TOK_ULT)
1341 op1 = TOK_ULE;
1342 else if (op1 == TOK_UGT)
1343 op1 = TOK_UGE;
1344 a = 0;
1345 b = 0;
1346 gen_op(op1);
1347 if (op1 != TOK_NE) {
1348 a = gvtst(1, 0);
1350 if (op != TOK_EQ) {
1351 /* generate non equal test */
1352 /* XXX: NOT PORTABLE yet */
1353 if (a == 0) {
1354 b = gvtst(0, 0);
1355 } else {
1356 #if defined(TCC_TARGET_I386)
1357 b = psym(0x850f, 0);
1358 #elif defined(TCC_TARGET_ARM)
1359 b = ind;
1360 o(0x1A000000 | encbranch(ind, 0, 1));
1361 #elif defined(TCC_TARGET_C67)
1362 tcc_error("not implemented");
1363 #else
1364 #error not supported
1365 #endif
1368 /* compare low. Always unsigned */
1369 op1 = op;
1370 if (op1 == TOK_LT)
1371 op1 = TOK_ULT;
1372 else if (op1 == TOK_LE)
1373 op1 = TOK_ULE;
1374 else if (op1 == TOK_GT)
1375 op1 = TOK_UGT;
1376 else if (op1 == TOK_GE)
1377 op1 = TOK_UGE;
1378 gen_op(op1);
1379 a = gvtst(1, a);
1380 gsym(b);
1381 vseti(VT_JMPI, a);
1382 break;
1385 #endif
1387 /* handle integer constant optimizations and various machine
1388 independent opt */
1389 static void gen_opic(int op)
1391 int c1, c2, t1, t2, n;
1392 SValue *v1, *v2;
1393 long long l1, l2;
1394 typedef unsigned long long U;
1396 v1 = vtop - 1;
1397 v2 = vtop;
1398 t1 = v1->type.t & VT_BTYPE;
1399 t2 = v2->type.t & VT_BTYPE;
1401 if (t1 == VT_LLONG)
1402 l1 = v1->c.ll;
1403 else if (v1->type.t & VT_UNSIGNED)
1404 l1 = v1->c.ui;
1405 else
1406 l1 = v1->c.i;
1408 if (t2 == VT_LLONG)
1409 l2 = v2->c.ll;
1410 else if (v2->type.t & VT_UNSIGNED)
1411 l2 = v2->c.ui;
1412 else
1413 l2 = v2->c.i;
1415 /* currently, we cannot do computations with forward symbols */
1416 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1417 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1418 if (c1 && c2) {
1419 switch(op) {
1420 case '+': l1 += l2; break;
1421 case '-': l1 -= l2; break;
1422 case '&': l1 &= l2; break;
1423 case '^': l1 ^= l2; break;
1424 case '|': l1 |= l2; break;
1425 case '*': l1 *= l2; break;
1427 case TOK_PDIV:
1428 case '/':
1429 case '%':
1430 case TOK_UDIV:
1431 case TOK_UMOD:
1432 /* if division by zero, generate explicit division */
1433 if (l2 == 0) {
1434 if (const_wanted)
1435 tcc_error("division by zero in constant");
1436 goto general_case;
1438 switch(op) {
1439 default: l1 /= l2; break;
1440 case '%': l1 %= l2; break;
1441 case TOK_UDIV: l1 = (U)l1 / l2; break;
1442 case TOK_UMOD: l1 = (U)l1 % l2; break;
1444 break;
1445 case TOK_SHL: l1 <<= l2; break;
1446 case TOK_SHR: l1 = (U)l1 >> l2; break;
1447 case TOK_SAR: l1 >>= l2; break;
1448 /* tests */
1449 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1450 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1451 case TOK_EQ: l1 = l1 == l2; break;
1452 case TOK_NE: l1 = l1 != l2; break;
1453 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1454 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1455 case TOK_LT: l1 = l1 < l2; break;
1456 case TOK_GE: l1 = l1 >= l2; break;
1457 case TOK_LE: l1 = l1 <= l2; break;
1458 case TOK_GT: l1 = l1 > l2; break;
1459 /* logical */
1460 case TOK_LAND: l1 = l1 && l2; break;
1461 case TOK_LOR: l1 = l1 || l2; break;
1462 default:
1463 goto general_case;
1465 v1->c.ll = l1;
1466 vtop--;
1467 } else {
1468 /* if commutative ops, put c2 as constant */
1469 if (c1 && (op == '+' || op == '&' || op == '^' ||
1470 op == '|' || op == '*')) {
1471 vswap();
1472 c2 = c1; //c = c1, c1 = c2, c2 = c;
1473 l2 = l1; //l = l1, l1 = l2, l2 = l;
1475 /* Filter out NOP operations like x*1, x-0, x&-1... */
1476 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1477 op == TOK_PDIV) &&
1478 l2 == 1) ||
1479 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1480 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1481 l2 == 0) ||
1482 (op == '&' &&
1483 l2 == -1))) {
1484 /* nothing to do */
1485 vtop--;
1486 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1487 /* try to use shifts instead of muls or divs */
1488 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1489 n = -1;
1490 while (l2) {
1491 l2 >>= 1;
1492 n++;
1494 vtop->c.ll = n;
1495 if (op == '*')
1496 op = TOK_SHL;
1497 else if (op == TOK_PDIV)
1498 op = TOK_SAR;
1499 else
1500 op = TOK_SHR;
1502 goto general_case;
1503 } else if (c2 && (op == '+' || op == '-') &&
1504 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1505 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1506 /* symbol + constant case */
1507 if (op == '-')
1508 l2 = -l2;
1509 vtop--;
1510 vtop->c.ll += l2;
1511 } else {
1512 general_case:
1513 if (!nocode_wanted) {
1514 /* call low level op generator */
1515 if (t1 == VT_LLONG || t2 == VT_LLONG)
1516 gen_opl(op);
1517 else
1518 gen_opi(op);
1519 } else {
1520 vtop--;
1526 /* generate a floating point operation with constant propagation */
1527 static void gen_opif(int op)
1529 int c1, c2;
1530 SValue *v1, *v2;
1531 long double f1, f2;
1533 v1 = vtop - 1;
1534 v2 = vtop;
1535 /* currently, we cannot do computations with forward symbols */
1536 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1537 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1538 if (c1 && c2) {
1539 if (v1->type.t == VT_FLOAT) {
1540 f1 = v1->c.f;
1541 f2 = v2->c.f;
1542 } else if (v1->type.t == VT_DOUBLE) {
1543 f1 = v1->c.d;
1544 f2 = v2->c.d;
1545 } else {
1546 f1 = v1->c.ld;
1547 f2 = v2->c.ld;
1550 /* NOTE: we only do constant propagation if finite number (not
1551 NaN or infinity) (ANSI spec) */
1552 if (!ieee_finite(f1) || !ieee_finite(f2))
1553 goto general_case;
1555 switch(op) {
1556 case '+': f1 += f2; break;
1557 case '-': f1 -= f2; break;
1558 case '*': f1 *= f2; break;
1559 case '/':
1560 if (f2 == 0.0) {
1561 if (const_wanted)
1562 tcc_error("division by zero in constant");
1563 goto general_case;
1565 f1 /= f2;
1566 break;
1567 /* XXX: also handles tests ? */
1568 default:
1569 goto general_case;
1571 /* XXX: overflow test ? */
1572 if (v1->type.t == VT_FLOAT) {
1573 v1->c.f = f1;
1574 } else if (v1->type.t == VT_DOUBLE) {
1575 v1->c.d = f1;
1576 } else {
1577 v1->c.ld = f1;
1579 vtop--;
1580 } else {
1581 general_case:
1582 if (!nocode_wanted) {
1583 gen_opf(op);
1584 } else {
1585 vtop--;
1590 static int pointed_size(CType *type)
1592 int align;
1593 return type_size(pointed_type(type), &align);
1596 static void vla_runtime_pointed_size(CType *type)
1598 int align;
1599 vla_runtime_type_size(pointed_type(type), &align);
1602 static inline int is_null_pointer(SValue *p)
1604 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1605 return 0;
1606 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1607 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1608 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0);
1611 static inline int is_integer_btype(int bt)
1613 return (bt == VT_BYTE || bt == VT_SHORT ||
1614 bt == VT_INT || bt == VT_LLONG);
1617 /* check types for comparison or subtraction of pointers */
1618 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1620 CType *type1, *type2, tmp_type1, tmp_type2;
1621 int bt1, bt2;
1623 /* null pointers are accepted for all comparisons as gcc */
1624 if (is_null_pointer(p1) || is_null_pointer(p2))
1625 return;
1626 type1 = &p1->type;
1627 type2 = &p2->type;
1628 bt1 = type1->t & VT_BTYPE;
1629 bt2 = type2->t & VT_BTYPE;
1630 /* accept comparison between pointer and integer with a warning */
1631 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1632 if (op != TOK_LOR && op != TOK_LAND )
1633 tcc_warning("comparison between pointer and integer");
1634 return;
1637 /* both must be pointers or implicit function pointers */
1638 if (bt1 == VT_PTR) {
1639 type1 = pointed_type(type1);
1640 } else if (bt1 != VT_FUNC)
1641 goto invalid_operands;
1643 if (bt2 == VT_PTR) {
1644 type2 = pointed_type(type2);
1645 } else if (bt2 != VT_FUNC) {
1646 invalid_operands:
1647 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1649 if ((type1->t & VT_BTYPE) == VT_VOID ||
1650 (type2->t & VT_BTYPE) == VT_VOID)
1651 return;
1652 tmp_type1 = *type1;
1653 tmp_type2 = *type2;
1654 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1655 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1656 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1657 /* gcc-like error if '-' is used */
1658 if (op == '-')
1659 goto invalid_operands;
1660 else
1661 tcc_warning("comparison of distinct pointer types lacks a cast");
1665 /* generic gen_op: handles types problems */
1666 ST_FUNC void gen_op(int op)
1668 int u, t1, t2, bt1, bt2, t;
1669 CType type1;
1671 t1 = vtop[-1].type.t;
1672 t2 = vtop[0].type.t;
1673 bt1 = t1 & VT_BTYPE;
1674 bt2 = t2 & VT_BTYPE;
1676 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1677 /* at least one operand is a pointer */
1678 /* relationnal op: must be both pointers */
1679 if (op >= TOK_ULT && op <= TOK_LOR) {
1680 check_comparison_pointer_types(vtop - 1, vtop, op);
1681 /* pointers are handled are unsigned */
1682 #ifdef TCC_TARGET_X86_64
1683 t = VT_LLONG | VT_UNSIGNED;
1684 #else
1685 t = VT_INT | VT_UNSIGNED;
1686 #endif
1687 goto std_op;
1689 /* if both pointers, then it must be the '-' op */
1690 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1691 if (op != '-')
1692 tcc_error("cannot use pointers here");
1693 check_comparison_pointer_types(vtop - 1, vtop, op);
1694 /* XXX: check that types are compatible */
1695 if (vtop[-1].type.t & VT_VLA) {
1696 vla_runtime_pointed_size(&vtop[-1].type);
1697 } else {
1698 vpushi(pointed_size(&vtop[-1].type));
1700 vrott(3);
1701 gen_opic(op);
1702 /* set to integer type */
1703 #ifdef TCC_TARGET_X86_64
1704 vtop->type.t = VT_LLONG;
1705 #else
1706 vtop->type.t = VT_INT;
1707 #endif
1708 vswap();
1709 gen_op(TOK_PDIV);
1710 } else {
1711 /* exactly one pointer : must be '+' or '-'. */
1712 if (op != '-' && op != '+')
1713 tcc_error("cannot use pointers here");
1714 /* Put pointer as first operand */
1715 if (bt2 == VT_PTR) {
1716 vswap();
1717 swap(&t1, &t2);
1719 type1 = vtop[-1].type;
1720 type1.t &= ~VT_ARRAY;
1721 if (vtop[-1].type.t & VT_VLA)
1722 vla_runtime_pointed_size(&vtop[-1].type);
1723 else {
1724 u = pointed_size(&vtop[-1].type);
1725 if (u < 0)
1726 tcc_error("unknown array element size");
1727 #ifdef TCC_TARGET_X86_64
1728 vpushll(u);
1729 #else
1730 /* XXX: cast to int ? (long long case) */
1731 vpushi(u);
1732 #endif
1734 gen_op('*');
1735 #ifdef CONFIG_TCC_BCHECK
1736 /* if evaluating constant expression, no code should be
1737 generated, so no bound check */
1738 if (tcc_state->do_bounds_check && !const_wanted) {
1739 /* if bounded pointers, we generate a special code to
1740 test bounds */
1741 if (op == '-') {
1742 vpushi(0);
1743 vswap();
1744 gen_op('-');
1746 gen_bounded_ptr_add();
1747 } else
1748 #endif
1750 gen_opic(op);
1752 /* put again type if gen_opic() swaped operands */
1753 vtop->type = type1;
1755 } else if (is_float(bt1) || is_float(bt2)) {
1756 /* compute bigger type and do implicit casts */
1757 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1758 t = VT_LDOUBLE;
1759 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1760 t = VT_DOUBLE;
1761 } else {
1762 t = VT_FLOAT;
1764 /* floats can only be used for a few operations */
1765 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1766 (op < TOK_ULT || op > TOK_GT))
1767 tcc_error("invalid operands for binary operation");
1768 goto std_op;
1769 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1770 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1771 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1772 t |= VT_UNSIGNED;
1773 goto std_op;
1774 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1775 /* cast to biggest op */
1776 t = VT_LLONG;
1777 /* convert to unsigned if it does not fit in a long long */
1778 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1779 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1780 t |= VT_UNSIGNED;
1781 goto std_op;
1782 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1783 tcc_error("comparison of struct");
1784 } else {
1785 /* integer operations */
1786 t = VT_INT;
1787 /* convert to unsigned if it does not fit in an integer */
1788 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1789 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1790 t |= VT_UNSIGNED;
1791 std_op:
1792 /* XXX: currently, some unsigned operations are explicit, so
1793 we modify them here */
1794 if (t & VT_UNSIGNED) {
1795 if (op == TOK_SAR)
1796 op = TOK_SHR;
1797 else if (op == '/')
1798 op = TOK_UDIV;
1799 else if (op == '%')
1800 op = TOK_UMOD;
1801 else if (op == TOK_LT)
1802 op = TOK_ULT;
1803 else if (op == TOK_GT)
1804 op = TOK_UGT;
1805 else if (op == TOK_LE)
1806 op = TOK_ULE;
1807 else if (op == TOK_GE)
1808 op = TOK_UGE;
1810 vswap();
1811 type1.t = t;
1812 gen_cast(&type1);
1813 vswap();
1814 /* special case for shifts and long long: we keep the shift as
1815 an integer */
1816 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1817 type1.t = VT_INT;
1818 gen_cast(&type1);
1819 if (is_float(t))
1820 gen_opif(op);
1821 else
1822 gen_opic(op);
1823 if (op >= TOK_ULT && op <= TOK_GT) {
1824 /* relationnal op: the result is an int */
1825 vtop->type.t = VT_INT;
1826 } else {
1827 vtop->type.t = t;
1832 #ifndef TCC_TARGET_ARM
1833 /* generic itof for unsigned long long case */
1834 static void gen_cvt_itof1(int t)
1836 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1837 (VT_LLONG | VT_UNSIGNED)) {
1839 if (t == VT_FLOAT)
1840 vpush_global_sym(&func_old_type, TOK___floatundisf);
1841 #if LDOUBLE_SIZE != 8
1842 else if (t == VT_LDOUBLE)
1843 vpush_global_sym(&func_old_type, TOK___floatundixf);
1844 #endif
1845 else
1846 vpush_global_sym(&func_old_type, TOK___floatundidf);
1847 vrott(2);
1848 gfunc_call(1);
1849 vpushi(0);
1850 vtop->r = reg_fret(t);
1851 } else {
1852 gen_cvt_itof(t);
1855 #endif
1857 /* generic ftoi for unsigned long long case */
1858 static void gen_cvt_ftoi1(int t)
1860 int st;
1862 if (t == (VT_LLONG | VT_UNSIGNED)) {
1863 /* not handled natively */
1864 st = vtop->type.t & VT_BTYPE;
1865 if (st == VT_FLOAT)
1866 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1867 #if LDOUBLE_SIZE != 8
1868 else if (st == VT_LDOUBLE)
1869 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1870 #endif
1871 else
1872 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1873 vrott(2);
1874 gfunc_call(1);
1875 vpushi(0);
1876 vtop->r = REG_IRET;
1877 vtop->r2 = REG_LRET;
1878 } else {
1879 gen_cvt_ftoi(t);
1883 /* force char or short cast */
1884 static void force_charshort_cast(int t)
1886 int bits, dbt;
1887 dbt = t & VT_BTYPE;
1888 /* XXX: add optimization if lvalue : just change type and offset */
1889 if (dbt == VT_BYTE)
1890 bits = 8;
1891 else
1892 bits = 16;
1893 if (t & VT_UNSIGNED) {
1894 vpushi((1 << bits) - 1);
1895 gen_op('&');
1896 } else {
1897 bits = 32 - bits;
1898 vpushi(bits);
1899 gen_op(TOK_SHL);
1900 /* result must be signed or the SAR is converted to an SHL
1901 This was not the case when "t" was a signed short
1902 and the last value on the stack was an unsigned int */
1903 vtop->type.t &= ~VT_UNSIGNED;
1904 vpushi(bits);
1905 gen_op(TOK_SAR);
1909 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1910 static void gen_cast(CType *type)
1912 int sbt, dbt, sf, df, c, p;
1914 /* special delayed cast for char/short */
1915 /* XXX: in some cases (multiple cascaded casts), it may still
1916 be incorrect */
1917 if (vtop->r & VT_MUSTCAST) {
1918 vtop->r &= ~VT_MUSTCAST;
1919 force_charshort_cast(vtop->type.t);
1922 /* bitfields first get cast to ints */
1923 if (vtop->type.t & VT_BITFIELD) {
1924 gv(RC_INT);
1927 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1928 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1930 if (sbt != dbt) {
1931 sf = is_float(sbt);
1932 df = is_float(dbt);
1933 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1934 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1935 if (c) {
1936 /* constant case: we can do it now */
1937 /* XXX: in ISOC, cannot do it if error in convert */
1938 if (sbt == VT_FLOAT)
1939 vtop->c.ld = vtop->c.f;
1940 else if (sbt == VT_DOUBLE)
1941 vtop->c.ld = vtop->c.d;
1943 if (df) {
1944 if ((sbt & VT_BTYPE) == VT_LLONG) {
1945 if (sbt & VT_UNSIGNED)
1946 vtop->c.ld = vtop->c.ull;
1947 else
1948 vtop->c.ld = vtop->c.ll;
1949 } else if(!sf) {
1950 if (sbt & VT_UNSIGNED)
1951 vtop->c.ld = vtop->c.ui;
1952 else
1953 vtop->c.ld = vtop->c.i;
1956 if (dbt == VT_FLOAT)
1957 vtop->c.f = (float)vtop->c.ld;
1958 else if (dbt == VT_DOUBLE)
1959 vtop->c.d = (double)vtop->c.ld;
1960 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1961 vtop->c.ull = (unsigned long long)vtop->c.ld;
1962 } else if (sf && dbt == VT_BOOL) {
1963 vtop->c.i = (vtop->c.ld != 0);
1964 } else {
1965 if(sf)
1966 vtop->c.ll = (long long)vtop->c.ld;
1967 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1968 vtop->c.ll = vtop->c.ull;
1969 else if (sbt & VT_UNSIGNED)
1970 vtop->c.ll = vtop->c.ui;
1971 #ifdef TCC_TARGET_X86_64
1972 else if (sbt == VT_PTR)
1974 #endif
1975 else if (sbt != VT_LLONG)
1976 vtop->c.ll = vtop->c.i;
1978 if (dbt == (VT_LLONG|VT_UNSIGNED))
1979 vtop->c.ull = vtop->c.ll;
1980 else if (dbt == VT_BOOL)
1981 vtop->c.i = (vtop->c.ll != 0);
1982 #ifdef TCC_TARGET_X86_64
1983 else if (dbt == VT_PTR)
1985 #endif
1986 else if (dbt != VT_LLONG) {
1987 int s = 0;
1988 if ((dbt & VT_BTYPE) == VT_BYTE)
1989 s = 24;
1990 else if ((dbt & VT_BTYPE) == VT_SHORT)
1991 s = 16;
1992 if(dbt & VT_UNSIGNED)
1993 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1994 else
1995 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1998 } else if (p && dbt == VT_BOOL) {
1999 vtop->r = VT_CONST;
2000 vtop->c.i = 1;
2001 } else if (!nocode_wanted) {
2002 /* non constant case: generate code */
2003 if (sf && df) {
2004 /* convert from fp to fp */
2005 gen_cvt_ftof(dbt);
2006 } else if (df) {
2007 /* convert int to fp */
2008 gen_cvt_itof1(dbt);
2009 } else if (sf) {
2010 /* convert fp to int */
2011 if (dbt == VT_BOOL) {
2012 vpushi(0);
2013 gen_op(TOK_NE);
2014 } else {
2015 /* we handle char/short/etc... with generic code */
2016 if (dbt != (VT_INT | VT_UNSIGNED) &&
2017 dbt != (VT_LLONG | VT_UNSIGNED) &&
2018 dbt != VT_LLONG)
2019 dbt = VT_INT;
2020 gen_cvt_ftoi1(dbt);
2021 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2022 /* additional cast for char/short... */
2023 vtop->type.t = dbt;
2024 gen_cast(type);
2027 #ifndef TCC_TARGET_X86_64
2028 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2029 if ((sbt & VT_BTYPE) != VT_LLONG) {
2030 /* scalar to long long */
2031 /* machine independent conversion */
2032 gv(RC_INT);
2033 /* generate high word */
2034 if (sbt == (VT_INT | VT_UNSIGNED)) {
2035 vpushi(0);
2036 gv(RC_INT);
2037 } else {
2038 if (sbt == VT_PTR) {
2039 /* cast from pointer to int before we apply
2040 shift operation, which pointers don't support*/
2041 gen_cast(&int_type);
2043 gv_dup();
2044 vpushi(31);
2045 gen_op(TOK_SAR);
2047 /* patch second register */
2048 vtop[-1].r2 = vtop->r;
2049 vpop();
2051 #else
2052 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2053 (dbt & VT_BTYPE) == VT_PTR ||
2054 (dbt & VT_BTYPE) == VT_FUNC) {
2055 if ((sbt & VT_BTYPE) != VT_LLONG &&
2056 (sbt & VT_BTYPE) != VT_PTR &&
2057 (sbt & VT_BTYPE) != VT_FUNC) {
2058 /* need to convert from 32bit to 64bit */
2059 int r = gv(RC_INT);
2060 if (sbt != (VT_INT | VT_UNSIGNED)) {
2061 /* x86_64 specific: movslq */
2062 o(0x6348);
2063 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2066 #endif
2067 } else if (dbt == VT_BOOL) {
2068 /* scalar to bool */
2069 vpushi(0);
2070 gen_op(TOK_NE);
2071 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2072 (dbt & VT_BTYPE) == VT_SHORT) {
2073 if (sbt == VT_PTR) {
2074 vtop->type.t = VT_INT;
2075 tcc_warning("nonportable conversion from pointer to char/short");
2077 force_charshort_cast(dbt);
2078 } else if ((dbt & VT_BTYPE) == VT_INT) {
2079 /* scalar to int */
2080 if (sbt == VT_LLONG) {
2081 /* from long long: just take low order word */
2082 lexpand();
2083 vpop();
2085 /* if lvalue and single word type, nothing to do because
2086 the lvalue already contains the real type size (see
2087 VT_LVAL_xxx constants) */
2090 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2091 /* if we are casting between pointer types,
2092 we must update the VT_LVAL_xxx size */
2093 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2094 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2096 vtop->type = *type;
2099 /* return type size as known at compile time. Put alignment at 'a' */
2100 ST_FUNC int type_size(CType *type, int *a)
2102 Sym *s;
2103 int bt;
2105 bt = type->t & VT_BTYPE;
2106 if (bt == VT_STRUCT) {
2107 /* struct/union */
2108 s = type->ref;
2109 *a = s->r;
2110 return s->c;
2111 } else if (bt == VT_PTR) {
2112 if (type->t & VT_ARRAY) {
2113 int ts;
2115 s = type->ref;
2116 ts = type_size(&s->type, a);
2118 if (ts < 0 && s->c < 0)
2119 ts = -ts;
2121 return ts * s->c;
2122 } else {
2123 *a = PTR_SIZE;
2124 return PTR_SIZE;
2126 } else if (bt == VT_LDOUBLE) {
2127 *a = LDOUBLE_ALIGN;
2128 return LDOUBLE_SIZE;
2129 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2130 #ifdef TCC_TARGET_I386
2131 #ifdef TCC_TARGET_PE
2132 *a = 8;
2133 #else
2134 *a = 4;
2135 #endif
2136 #elif defined(TCC_TARGET_ARM)
2137 #ifdef TCC_ARM_EABI
2138 *a = 8;
2139 #else
2140 *a = 4;
2141 #endif
2142 #else
2143 *a = 8;
2144 #endif
2145 return 8;
2146 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2147 *a = 4;
2148 return 4;
2149 } else if (bt == VT_SHORT) {
2150 *a = 2;
2151 return 2;
2152 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2153 *a = 8;
2154 return 16;
2155 } else {
2156 /* char, void, function, _Bool */
2157 *a = 1;
2158 return 1;
2162 /* push type size as known at runtime time on top of value stack. Put
2163 alignment at 'a' */
2164 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2166 if (type->t & VT_VLA) {
2167 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2168 } else {
2169 vpushi(type_size(type, a));
2173 static void vla_sp_save(void) {
2174 if (!(vla_flags & VLA_SP_LOC_SET)) {
2175 *vla_sp_loc = (loc -= PTR_SIZE);
2176 vla_flags |= VLA_SP_LOC_SET;
2178 if (!(vla_flags & VLA_SP_SAVED)) {
2179 gen_vla_sp_save(*vla_sp_loc);
2180 vla_flags |= VLA_SP_SAVED;
2184 /* return the pointed type of t */
2185 static inline CType *pointed_type(CType *type)
2187 return &type->ref->type;
2190 /* modify type so that its it is a pointer to type. */
2191 ST_FUNC void mk_pointer(CType *type)
2193 Sym *s;
2194 s = sym_push(SYM_FIELD, type, 0, -1);
2195 type->t = VT_PTR | (type->t & ~VT_TYPE);
2196 type->ref = s;
2199 /* compare function types. OLD functions match any new functions */
2200 static int is_compatible_func(CType *type1, CType *type2)
2202 Sym *s1, *s2;
2204 s1 = type1->ref;
2205 s2 = type2->ref;
2206 if (!is_compatible_types(&s1->type, &s2->type))
2207 return 0;
2208 /* check func_call */
2209 if (s1->a.func_call != s2->a.func_call)
2210 return 0;
2211 /* XXX: not complete */
2212 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2213 return 1;
2214 if (s1->c != s2->c)
2215 return 0;
2216 while (s1 != NULL) {
2217 if (s2 == NULL)
2218 return 0;
2219 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2220 return 0;
2221 s1 = s1->next;
2222 s2 = s2->next;
2224 if (s2)
2225 return 0;
2226 return 1;
2229 /* return true if type1 and type2 are the same. If unqualified is
2230 true, qualifiers on the types are ignored.
2232 - enums are not checked as gcc __builtin_types_compatible_p ()
2234 static int compare_types(CType *type1, CType *type2, int unqualified)
2236 int bt1, t1, t2;
2238 t1 = type1->t & VT_TYPE;
2239 t2 = type2->t & VT_TYPE;
2240 if (unqualified) {
2241 /* strip qualifiers before comparing */
2242 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2243 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2245 /* Default Vs explicit signedness only matters for char */
2246 if ((t1 & VT_BTYPE) != VT_BYTE) {
2247 t1 &= ~VT_DEFSIGN;
2248 t2 &= ~VT_DEFSIGN;
2250 /* XXX: bitfields ? */
2251 if (t1 != t2)
2252 return 0;
2253 /* test more complicated cases */
2254 bt1 = t1 & VT_BTYPE;
2255 if (bt1 == VT_PTR) {
2256 type1 = pointed_type(type1);
2257 type2 = pointed_type(type2);
2258 return is_compatible_types(type1, type2);
2259 } else if (bt1 == VT_STRUCT) {
2260 return (type1->ref == type2->ref);
2261 } else if (bt1 == VT_FUNC) {
2262 return is_compatible_func(type1, type2);
2263 } else {
2264 return 1;
2268 /* return true if type1 and type2 are exactly the same (including
2269 qualifiers).
2271 static int is_compatible_types(CType *type1, CType *type2)
2273 return compare_types(type1,type2,0);
2276 /* return true if type1 and type2 are the same (ignoring qualifiers).
2278 static int is_compatible_parameter_types(CType *type1, CType *type2)
2280 return compare_types(type1,type2,1);
2283 /* print a type. If 'varstr' is not NULL, then the variable is also
2284 printed in the type */
2285 /* XXX: union */
2286 /* XXX: add array and function pointers */
2287 static void type_to_str(char *buf, int buf_size,
2288 CType *type, const char *varstr)
2290 int bt, v, t;
2291 Sym *s, *sa;
2292 char buf1[256];
2293 const char *tstr;
2295 t = type->t & VT_TYPE;
2296 bt = t & VT_BTYPE;
2297 buf[0] = '\0';
2298 if (t & VT_CONSTANT)
2299 pstrcat(buf, buf_size, "const ");
2300 if (t & VT_VOLATILE)
2301 pstrcat(buf, buf_size, "volatile ");
2302 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2303 pstrcat(buf, buf_size, "unsigned ");
2304 else if (t & VT_DEFSIGN)
2305 pstrcat(buf, buf_size, "signed ");
2306 switch(bt) {
2307 case VT_VOID:
2308 tstr = "void";
2309 goto add_tstr;
2310 case VT_BOOL:
2311 tstr = "_Bool";
2312 goto add_tstr;
2313 case VT_BYTE:
2314 tstr = "char";
2315 goto add_tstr;
2316 case VT_SHORT:
2317 tstr = "short";
2318 goto add_tstr;
2319 case VT_INT:
2320 tstr = "int";
2321 goto add_tstr;
2322 case VT_LONG:
2323 tstr = "long";
2324 goto add_tstr;
2325 case VT_LLONG:
2326 tstr = "long long";
2327 goto add_tstr;
2328 case VT_FLOAT:
2329 tstr = "float";
2330 goto add_tstr;
2331 case VT_DOUBLE:
2332 tstr = "double";
2333 goto add_tstr;
2334 case VT_LDOUBLE:
2335 tstr = "long double";
2336 add_tstr:
2337 pstrcat(buf, buf_size, tstr);
2338 break;
2339 case VT_ENUM:
2340 case VT_STRUCT:
2341 if (bt == VT_STRUCT)
2342 tstr = "struct ";
2343 else
2344 tstr = "enum ";
2345 pstrcat(buf, buf_size, tstr);
2346 v = type->ref->v & ~SYM_STRUCT;
2347 if (v >= SYM_FIRST_ANOM)
2348 pstrcat(buf, buf_size, "<anonymous>");
2349 else
2350 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2351 break;
2352 case VT_FUNC:
2353 s = type->ref;
2354 type_to_str(buf, buf_size, &s->type, varstr);
2355 pstrcat(buf, buf_size, "(");
2356 sa = s->next;
2357 while (sa != NULL) {
2358 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2359 pstrcat(buf, buf_size, buf1);
2360 sa = sa->next;
2361 if (sa)
2362 pstrcat(buf, buf_size, ", ");
2364 pstrcat(buf, buf_size, ")");
2365 goto no_var;
2366 case VT_PTR:
2367 s = type->ref;
2368 pstrcpy(buf1, sizeof(buf1), "*");
2369 if (varstr)
2370 pstrcat(buf1, sizeof(buf1), varstr);
2371 type_to_str(buf, buf_size, &s->type, buf1);
2372 goto no_var;
2374 if (varstr) {
2375 pstrcat(buf, buf_size, " ");
2376 pstrcat(buf, buf_size, varstr);
2378 no_var: ;
2381 /* verify type compatibility to store vtop in 'dt' type, and generate
2382 casts if needed. */
2383 static void gen_assign_cast(CType *dt)
2385 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2386 char buf1[256], buf2[256];
2387 int dbt, sbt;
2389 st = &vtop->type; /* source type */
2390 dbt = dt->t & VT_BTYPE;
2391 sbt = st->t & VT_BTYPE;
2392 if (sbt == VT_VOID || dbt == VT_VOID)
2393 tcc_error("cannot cast from/to void");
2394 if (dt->t & VT_CONSTANT)
2395 tcc_warning("assignment of read-only location");
2396 switch(dbt) {
2397 case VT_PTR:
2398 /* special cases for pointers */
2399 /* '0' can also be a pointer */
2400 if (is_null_pointer(vtop))
2401 goto type_ok;
2402 /* accept implicit pointer to integer cast with warning */
2403 if (is_integer_btype(sbt)) {
2404 tcc_warning("assignment makes pointer from integer without a cast");
2405 goto type_ok;
2407 type1 = pointed_type(dt);
2408 /* a function is implicitely a function pointer */
2409 if (sbt == VT_FUNC) {
2410 if ((type1->t & VT_BTYPE) != VT_VOID &&
2411 !is_compatible_types(pointed_type(dt), st))
2412 tcc_warning("assignment from incompatible pointer type");
2413 goto type_ok;
2415 if (sbt != VT_PTR)
2416 goto error;
2417 type2 = pointed_type(st);
2418 if ((type1->t & VT_BTYPE) == VT_VOID ||
2419 (type2->t & VT_BTYPE) == VT_VOID) {
2420 /* void * can match anything */
2421 } else {
2422 /* exact type match, except for unsigned */
2423 tmp_type1 = *type1;
2424 tmp_type2 = *type2;
2425 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2426 VT_VOLATILE);
2427 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2428 VT_VOLATILE);
2429 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2430 tcc_warning("assignment from incompatible pointer type");
2432 /* check const and volatile */
2433 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2434 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2435 tcc_warning("assignment discards qualifiers from pointer target type");
2436 break;
2437 case VT_BYTE:
2438 case VT_SHORT:
2439 case VT_INT:
2440 case VT_LLONG:
2441 if (sbt == VT_PTR || sbt == VT_FUNC) {
2442 tcc_warning("assignment makes integer from pointer without a cast");
2444 if (sbt == VT_STRUCT)
2445 goto error;
2446 /* XXX: more tests */
2447 break;
2448 case VT_STRUCT:
2449 tmp_type1 = *dt;
2450 tmp_type2 = *st;
2451 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2452 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2453 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2454 error:
2455 type_to_str(buf1, sizeof(buf1), st, NULL);
2456 type_to_str(buf2, sizeof(buf2), dt, NULL);
2457 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2459 break;
2461 type_ok:
2462 gen_cast(dt);
2465 /* store vtop in lvalue pushed on stack */
2466 ST_FUNC void vstore(void)
2468 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2470 ft = vtop[-1].type.t;
2471 sbt = vtop->type.t & VT_BTYPE;
2472 dbt = ft & VT_BTYPE;
2473 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2474 (sbt == VT_INT && dbt == VT_SHORT))
2475 && !(vtop->type.t & VT_BITFIELD)) {
2476 /* optimize char/short casts */
2477 delayed_cast = VT_MUSTCAST;
2478 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2479 /* XXX: factorize */
2480 if (ft & VT_CONSTANT)
2481 tcc_warning("assignment of read-only location");
2482 } else {
2483 delayed_cast = 0;
2484 if (!(ft & VT_BITFIELD))
2485 gen_assign_cast(&vtop[-1].type);
2488 if (sbt == VT_STRUCT) {
2489 /* if structure, only generate pointer */
2490 /* structure assignment : generate memcpy */
2491 /* XXX: optimize if small size */
2492 if (!nocode_wanted) {
2493 size = type_size(&vtop->type, &align);
2495 /* destination */
2496 vswap();
2497 vtop->type.t = VT_PTR;
2498 gaddrof();
2500 /* address of memcpy() */
2501 #ifdef TCC_ARM_EABI
2502 if(!(align & 7))
2503 vpush_global_sym(&func_old_type, TOK_memcpy8);
2504 else if(!(align & 3))
2505 vpush_global_sym(&func_old_type, TOK_memcpy4);
2506 else
2507 #endif
2508 vpush_global_sym(&func_old_type, TOK_memcpy);
2510 vswap();
2511 /* source */
2512 vpushv(vtop - 2);
2513 vtop->type.t = VT_PTR;
2514 gaddrof();
2515 /* type size */
2516 vpushi(size);
2517 gfunc_call(3);
2518 } else {
2519 vswap();
2520 vpop();
2522 /* leave source on stack */
2523 } else if (ft & VT_BITFIELD) {
2524 /* bitfield store handling */
2525 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2526 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2527 /* remove bit field info to avoid loops */
2528 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2530 /* duplicate source into other register */
2531 gv_dup();
2532 vswap();
2533 vrott(3);
2535 if((ft & VT_BTYPE) == VT_BOOL) {
2536 gen_cast(&vtop[-1].type);
2537 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2540 /* duplicate destination */
2541 vdup();
2542 vtop[-1] = vtop[-2];
2544 /* mask and shift source */
2545 if((ft & VT_BTYPE) != VT_BOOL) {
2546 if((ft & VT_BTYPE) == VT_LLONG) {
2547 vpushll((1ULL << bit_size) - 1ULL);
2548 } else {
2549 vpushi((1 << bit_size) - 1);
2551 gen_op('&');
2553 vpushi(bit_pos);
2554 gen_op(TOK_SHL);
2555 /* load destination, mask and or with source */
2556 vswap();
2557 if((ft & VT_BTYPE) == VT_LLONG) {
2558 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2559 } else {
2560 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2562 gen_op('&');
2563 gen_op('|');
2564 /* store result */
2565 vstore();
2567 /* pop off shifted source from "duplicate source..." above */
2568 vpop();
2570 } else {
2571 #ifdef CONFIG_TCC_BCHECK
2572 /* bound check case */
2573 if (vtop[-1].r & VT_MUSTBOUND) {
2574 vswap();
2575 gbound();
2576 vswap();
2578 #endif
2579 if (!nocode_wanted) {
2580 rc = RC_INT;
2581 if (is_float(ft)) {
2582 rc = RC_FLOAT;
2583 #ifdef TCC_TARGET_X86_64
2584 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2585 rc = RC_ST0;
2586 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2587 rc = RC_FRET;
2589 #endif
2591 r = gv(rc); /* generate value */
2592 /* if lvalue was saved on stack, must read it */
2593 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2594 SValue sv;
2595 t = get_reg(RC_INT);
2596 #ifdef TCC_TARGET_X86_64
2597 sv.type.t = VT_PTR;
2598 #else
2599 sv.type.t = VT_INT;
2600 #endif
2601 sv.r = VT_LOCAL | VT_LVAL;
2602 sv.c.ul = vtop[-1].c.ul;
2603 load(t, &sv);
2604 vtop[-1].r = t | VT_LVAL;
2606 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2607 #ifdef TCC_TARGET_X86_64
2608 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2609 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2610 #else
2611 if ((ft & VT_BTYPE) == VT_LLONG) {
2612 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2613 #endif
2614 vtop[-1].type.t = load_type;
2615 store(r, vtop - 1);
2616 vswap();
2617 /* convert to int to increment easily */
2618 vtop->type.t = addr_type;
2619 gaddrof();
2620 vpushi(load_size);
2621 gen_op('+');
2622 vtop->r |= VT_LVAL;
2623 vswap();
2624 vtop[-1].type.t = load_type;
2625 /* XXX: it works because r2 is spilled last ! */
2626 store(vtop->r2, vtop - 1);
2627 } else {
2628 store(r, vtop - 1);
2631 vswap();
2632 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2633 vtop->r |= delayed_cast;
2637 /* post defines POST/PRE add. c is the token ++ or -- */
2638 ST_FUNC void inc(int post, int c)
2640 test_lvalue();
2641 vdup(); /* save lvalue */
2642 if (post) {
2643 gv_dup(); /* duplicate value */
2644 vrotb(3);
2645 vrotb(3);
2647 /* add constant */
2648 vpushi(c - TOK_MID);
2649 gen_op('+');
2650 vstore(); /* store value */
2651 if (post)
2652 vpop(); /* if post op, return saved value */
2655 /* Parse GNUC __attribute__ extension. Currently, the following
2656 extensions are recognized:
2657 - aligned(n) : set data/function alignment.
2658 - packed : force data alignment to 1
2659 - section(x) : generate data/code in this section.
2660 - unused : currently ignored, but may be used someday.
2661 - regparm(n) : pass function parameters in registers (i386 only)
2663 static void parse_attribute(AttributeDef *ad)
2665 int t, n;
2667 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2668 next();
2669 skip('(');
2670 skip('(');
2671 while (tok != ')') {
2672 if (tok < TOK_IDENT)
2673 expect("attribute name");
2674 t = tok;
2675 next();
2676 switch(t) {
2677 case TOK_SECTION1:
2678 case TOK_SECTION2:
2679 skip('(');
2680 if (tok != TOK_STR)
2681 expect("section name");
2682 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2683 next();
2684 skip(')');
2685 break;
2686 case TOK_ALIAS1:
2687 case TOK_ALIAS2:
2688 skip('(');
2689 if (tok != TOK_STR)
2690 expect("alias(\"target\")");
2691 ad->alias_target = /* save string as token, for later */
2692 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2693 next();
2694 skip(')');
2695 break;
2696 case TOK_VISIBILITY1:
2697 case TOK_VISIBILITY2:
2698 skip('(');
2699 if (tok != TOK_STR)
2700 expect("visibility(\"default|hidden|internal|protected\")");
2701 if (!strcmp (tokc.cstr->data, "default"))
2702 ad->a.visibility = STV_DEFAULT;
2703 else if (!strcmp (tokc.cstr->data, "hidden"))
2704 ad->a.visibility = STV_HIDDEN;
2705 else if (!strcmp (tokc.cstr->data, "internal"))
2706 ad->a.visibility = STV_INTERNAL;
2707 else if (!strcmp (tokc.cstr->data, "protected"))
2708 ad->a.visibility = STV_PROTECTED;
2709 else
2710 expect("visibility(\"default|hidden|internal|protected\")");
2711 next();
2712 skip(')');
2713 break;
2714 case TOK_ALIGNED1:
2715 case TOK_ALIGNED2:
2716 if (tok == '(') {
2717 next();
2718 n = expr_const();
2719 if (n <= 0 || (n & (n - 1)) != 0)
2720 tcc_error("alignment must be a positive power of two");
2721 skip(')');
2722 } else {
2723 n = MAX_ALIGN;
2725 ad->a.aligned = n;
2726 break;
2727 case TOK_PACKED1:
2728 case TOK_PACKED2:
2729 ad->a.packed = 1;
2730 break;
2731 case TOK_WEAK1:
2732 case TOK_WEAK2:
2733 ad->a.weak = 1;
2734 break;
2735 case TOK_UNUSED1:
2736 case TOK_UNUSED2:
2737 /* currently, no need to handle it because tcc does not
2738 track unused objects */
2739 break;
2740 case TOK_NORETURN1:
2741 case TOK_NORETURN2:
2742 /* currently, no need to handle it because tcc does not
2743 track unused objects */
2744 break;
2745 case TOK_CDECL1:
2746 case TOK_CDECL2:
2747 case TOK_CDECL3:
2748 ad->a.func_call = FUNC_CDECL;
2749 break;
2750 case TOK_STDCALL1:
2751 case TOK_STDCALL2:
2752 case TOK_STDCALL3:
2753 ad->a.func_call = FUNC_STDCALL;
2754 break;
2755 #ifdef TCC_TARGET_I386
2756 case TOK_REGPARM1:
2757 case TOK_REGPARM2:
2758 skip('(');
2759 n = expr_const();
2760 if (n > 3)
2761 n = 3;
2762 else if (n < 0)
2763 n = 0;
2764 if (n > 0)
2765 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
2766 skip(')');
2767 break;
2768 case TOK_FASTCALL1:
2769 case TOK_FASTCALL2:
2770 case TOK_FASTCALL3:
2771 ad->a.func_call = FUNC_FASTCALLW;
2772 break;
2773 #endif
2774 case TOK_MODE:
2775 skip('(');
2776 switch(tok) {
2777 case TOK_MODE_DI:
2778 ad->a.mode = VT_LLONG + 1;
2779 break;
2780 case TOK_MODE_HI:
2781 ad->a.mode = VT_SHORT + 1;
2782 break;
2783 case TOK_MODE_SI:
2784 ad->a.mode = VT_INT + 1;
2785 break;
2786 default:
2787 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2788 break;
2790 next();
2791 skip(')');
2792 break;
2793 case TOK_DLLEXPORT:
2794 ad->a.func_export = 1;
2795 break;
2796 case TOK_DLLIMPORT:
2797 ad->a.func_import = 1;
2798 break;
2799 default:
2800 if (tcc_state->warn_unsupported)
2801 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2802 /* skip parameters */
2803 if (tok == '(') {
2804 int parenthesis = 0;
2805 do {
2806 if (tok == '(')
2807 parenthesis++;
2808 else if (tok == ')')
2809 parenthesis--;
2810 next();
2811 } while (parenthesis && tok != -1);
2813 break;
2815 if (tok != ',')
2816 break;
2817 next();
2819 skip(')');
2820 skip(')');
2824 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2825 static void struct_decl(CType *type, int u, int tdef)
2827 int a, v, size, align, maxalign, c, offset, flexible;
2828 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2829 Sym *s, *ss, *ass, **ps;
2830 AttributeDef ad;
2831 CType type1, btype;
2833 a = tok; /* save decl type */
2834 next();
2835 if (tok != '{') {
2836 v = tok;
2837 next();
2838 /* struct already defined ? return it */
2839 if (v < TOK_IDENT)
2840 expect("struct/union/enum name");
2841 s = struct_find(v);
2842 if (s) {
2843 if (s->type.t != a)
2844 tcc_error("invalid type: '%s'", get_tok_str(v, NULL));
2845 goto do_decl;
2846 } else if (tok >= TOK_IDENT && !tdef)
2847 tcc_error("unknown struct/union/enum");
2848 } else {
2849 v = anon_sym++;
2851 type1.t = a;
2852 type1.ref = NULL;
2853 /* we put an undefined size for struct/union */
2854 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2855 s->r = 0; /* default alignment is zero as gcc */
2856 /* put struct/union/enum name in type */
2857 do_decl:
2858 type->t = u;
2859 type->ref = s;
2861 if (tok == '{') {
2862 next();
2863 if (s->c != -1)
2864 tcc_error("struct/union/enum already defined");
2865 /* cannot be empty */
2866 c = 0;
2867 /* non empty enums are not allowed */
2868 if (a == TOK_ENUM) {
2869 for(;;) {
2870 v = tok;
2871 if (v < TOK_UIDENT)
2872 expect("identifier");
2873 ss = sym_find(v);
2874 if (ss && !local_stack)
2875 tcc_error("redefinition of enumerator '%s'",
2876 get_tok_str(v, NULL));
2877 next();
2878 if (tok == '=') {
2879 next();
2880 c = expr_const();
2882 /* enum symbols have static storage */
2883 ss = sym_push(v, &int_type, VT_CONST, c);
2884 ss->type.t |= VT_STATIC;
2885 if (tok != ',')
2886 break;
2887 next();
2888 c++;
2889 /* NOTE: we accept a trailing comma */
2890 if (tok == '}')
2891 break;
2893 s->c = type_size(&int_type, &align);
2894 skip('}');
2895 } else {
2896 maxalign = 1;
2897 ps = &s->next;
2898 prevbt = VT_INT;
2899 bit_pos = 0;
2900 offset = 0;
2901 flexible = 0;
2902 while (tok != '}') {
2903 parse_btype(&btype, &ad);
2904 while (1) {
2905 if (flexible)
2906 tcc_error("flexible array member '%s' not at the end of struct",
2907 get_tok_str(v, NULL));
2908 bit_size = -1;
2909 v = 0;
2910 type1 = btype;
2911 if (tok != ':') {
2912 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2913 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2914 expect("identifier");
2915 if (type_size(&type1, &align) < 0) {
2916 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY))
2917 flexible = 1;
2918 else
2919 tcc_error("field '%s' has incomplete type",
2920 get_tok_str(v, NULL));
2922 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2923 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2924 tcc_error("invalid type for '%s'",
2925 get_tok_str(v, NULL));
2927 if (tok == ':') {
2928 next();
2929 bit_size = expr_const();
2930 /* XXX: handle v = 0 case for messages */
2931 if (bit_size < 0)
2932 tcc_error("negative width in bit-field '%s'",
2933 get_tok_str(v, NULL));
2934 if (v && bit_size == 0)
2935 tcc_error("zero width for bit-field '%s'",
2936 get_tok_str(v, NULL));
2938 size = type_size(&type1, &align);
2939 if (ad.a.aligned) {
2940 if (align < ad.a.aligned)
2941 align = ad.a.aligned;
2942 } else if (ad.a.packed) {
2943 align = 1;
2944 } else if (*tcc_state->pack_stack_ptr) {
2945 if (align > *tcc_state->pack_stack_ptr)
2946 align = *tcc_state->pack_stack_ptr;
2948 lbit_pos = 0;
2949 if (bit_size >= 0) {
2950 bt = type1.t & VT_BTYPE;
2951 if (bt != VT_INT &&
2952 bt != VT_BYTE &&
2953 bt != VT_SHORT &&
2954 bt != VT_BOOL &&
2955 bt != VT_ENUM &&
2956 bt != VT_LLONG)
2957 tcc_error("bitfields must have scalar type");
2958 bsize = size * 8;
2959 if (bit_size > bsize) {
2960 tcc_error("width of '%s' exceeds its type",
2961 get_tok_str(v, NULL));
2962 } else if (bit_size == bsize) {
2963 /* no need for bit fields */
2964 bit_pos = 0;
2965 } else if (bit_size == 0) {
2966 /* XXX: what to do if only padding in a
2967 structure ? */
2968 /* zero size: means to pad */
2969 bit_pos = 0;
2970 } else {
2971 /* we do not have enough room ?
2972 did the type change?
2973 is it a union? */
2974 if ((bit_pos + bit_size) > bsize ||
2975 bt != prevbt || a == TOK_UNION)
2976 bit_pos = 0;
2977 lbit_pos = bit_pos;
2978 /* XXX: handle LSB first */
2979 type1.t |= VT_BITFIELD |
2980 (bit_pos << VT_STRUCT_SHIFT) |
2981 (bit_size << (VT_STRUCT_SHIFT + 6));
2982 bit_pos += bit_size;
2984 prevbt = bt;
2985 } else {
2986 bit_pos = 0;
2988 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2989 /* add new memory data only if starting
2990 bit field */
2991 if (lbit_pos == 0) {
2992 if (a == TOK_STRUCT) {
2993 c = (c + align - 1) & -align;
2994 offset = c;
2995 if (size > 0)
2996 c += size;
2997 } else {
2998 offset = 0;
2999 if (size > c)
3000 c = size;
3002 if (align > maxalign)
3003 maxalign = align;
3005 #if 0
3006 printf("add field %s offset=%d",
3007 get_tok_str(v, NULL), offset);
3008 if (type1.t & VT_BITFIELD) {
3009 printf(" pos=%d size=%d",
3010 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3011 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3013 printf("\n");
3014 #endif
3016 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3017 ass = type1.ref;
3018 while ((ass = ass->next) != NULL) {
3019 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3020 *ps = ss;
3021 ps = &ss->next;
3023 } else if (v) {
3024 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3025 *ps = ss;
3026 ps = &ss->next;
3028 if (tok == ';' || tok == TOK_EOF)
3029 break;
3030 skip(',');
3032 skip(';');
3034 skip('}');
3035 if (!c && flexible)
3036 tcc_error("flexible array member '%s' in otherwise empty struct", get_tok_str(v, NULL));
3037 /* store size and alignment */
3038 s->c = (c + maxalign - 1) & -maxalign;
3039 s->r = maxalign;
3044 /* return 1 if basic type is a type size (short, long, long long) */
3045 ST_FUNC int is_btype_size(int bt)
3047 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3050 /* return 0 if no type declaration. otherwise, return the basic type
3051 and skip it.
3053 static int parse_btype(CType *type, AttributeDef *ad)
3055 int t, u, bt_size, complete, type_found, typespec_found;
3056 Sym *s;
3057 CType type1;
3059 memset(ad, 0, sizeof(AttributeDef));
3060 complete = 0;
3061 type_found = 0;
3062 typespec_found = 0;
3063 t = 0;
3064 while(1) {
3065 switch(tok) {
3066 case TOK_EXTENSION:
3067 /* currently, we really ignore extension */
3068 next();
3069 continue;
3071 /* basic types */
3072 case TOK_CHAR:
3073 u = VT_BYTE;
3074 basic_type:
3075 next();
3076 basic_type1:
3077 if (complete)
3078 tcc_error("too many basic types");
3079 t |= u;
3080 bt_size = is_btype_size (u & VT_BTYPE);
3081 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3082 complete = 1;
3083 typespec_found = 1;
3084 break;
3085 case TOK_VOID:
3086 u = VT_VOID;
3087 goto basic_type;
3088 case TOK_SHORT:
3089 u = VT_SHORT;
3090 goto basic_type;
3091 case TOK_INT:
3092 u = VT_INT;
3093 goto basic_type;
3094 case TOK_LONG:
3095 next();
3096 if ((t & VT_BTYPE) == VT_DOUBLE) {
3097 #ifndef TCC_TARGET_PE
3098 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3099 #endif
3100 } else if ((t & VT_BTYPE) == VT_LONG) {
3101 t = (t & ~VT_BTYPE) | VT_LLONG;
3102 } else {
3103 u = VT_LONG;
3104 goto basic_type1;
3106 break;
3107 case TOK_BOOL:
3108 u = VT_BOOL;
3109 goto basic_type;
3110 case TOK_FLOAT:
3111 u = VT_FLOAT;
3112 goto basic_type;
3113 case TOK_DOUBLE:
3114 next();
3115 if ((t & VT_BTYPE) == VT_LONG) {
3116 #ifdef TCC_TARGET_PE
3117 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3118 #else
3119 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3120 #endif
3121 } else {
3122 u = VT_DOUBLE;
3123 goto basic_type1;
3125 break;
3126 case TOK_ENUM:
3127 struct_decl(&type1, VT_ENUM, t & VT_TYPEDEF);
3128 basic_type2:
3129 u = type1.t;
3130 type->ref = type1.ref;
3131 goto basic_type1;
3132 case TOK_STRUCT:
3133 case TOK_UNION:
3134 struct_decl(&type1, VT_STRUCT, t & VT_TYPEDEF);
3135 goto basic_type2;
3137 /* type modifiers */
3138 case TOK_CONST1:
3139 case TOK_CONST2:
3140 case TOK_CONST3:
3141 t |= VT_CONSTANT;
3142 next();
3143 break;
3144 case TOK_VOLATILE1:
3145 case TOK_VOLATILE2:
3146 case TOK_VOLATILE3:
3147 t |= VT_VOLATILE;
3148 next();
3149 break;
3150 case TOK_SIGNED1:
3151 case TOK_SIGNED2:
3152 case TOK_SIGNED3:
3153 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3154 tcc_error("signed and unsigned modifier");
3155 typespec_found = 1;
3156 t |= VT_DEFSIGN;
3157 next();
3158 break;
3159 case TOK_REGISTER:
3160 case TOK_AUTO:
3161 case TOK_RESTRICT1:
3162 case TOK_RESTRICT2:
3163 case TOK_RESTRICT3:
3164 next();
3165 break;
3166 case TOK_UNSIGNED:
3167 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3168 tcc_error("signed and unsigned modifier");
3169 t |= VT_DEFSIGN | VT_UNSIGNED;
3170 next();
3171 typespec_found = 1;
3172 break;
3174 /* storage */
3175 case TOK_EXTERN:
3176 t |= VT_EXTERN;
3177 next();
3178 break;
3179 case TOK_STATIC:
3180 t |= VT_STATIC;
3181 next();
3182 break;
3183 case TOK_TYPEDEF:
3184 t |= VT_TYPEDEF;
3185 next();
3186 break;
3187 case TOK_INLINE1:
3188 case TOK_INLINE2:
3189 case TOK_INLINE3:
3190 t |= VT_INLINE;
3191 next();
3192 break;
3194 /* GNUC attribute */
3195 case TOK_ATTRIBUTE1:
3196 case TOK_ATTRIBUTE2:
3197 parse_attribute(ad);
3198 if (ad->a.mode) {
3199 u = ad->a.mode -1;
3200 t = (t & ~VT_BTYPE) | u;
3202 break;
3203 /* GNUC typeof */
3204 case TOK_TYPEOF1:
3205 case TOK_TYPEOF2:
3206 case TOK_TYPEOF3:
3207 next();
3208 parse_expr_type(&type1);
3209 /* remove all storage modifiers except typedef */
3210 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3211 goto basic_type2;
3212 default:
3213 if (typespec_found)
3214 goto the_end;
3215 s = sym_find(tok);
3216 if (!s || !(s->type.t & VT_TYPEDEF))
3217 goto the_end;
3218 t |= (s->type.t & ~VT_TYPEDEF);
3219 type->ref = s->type.ref;
3220 if (s->r) {
3221 /* get attributes from typedef */
3222 if (0 == ad->a.aligned)
3223 ad->a.aligned = s->a.aligned;
3224 if (0 == ad->a.func_call)
3225 ad->a.func_call = s->a.func_call;
3226 ad->a.packed |= s->a.packed;
3228 next();
3229 typespec_found = 1;
3230 break;
3232 type_found = 1;
3234 the_end:
3235 if (tcc_state->char_is_unsigned) {
3236 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3237 t |= VT_UNSIGNED;
3240 /* long is never used as type */
3241 if ((t & VT_BTYPE) == VT_LONG)
3242 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3243 t = (t & ~VT_BTYPE) | VT_INT;
3244 #else
3245 t = (t & ~VT_BTYPE) | VT_LLONG;
3246 #endif
3247 type->t = t;
3248 return type_found;
3251 /* convert a function parameter type (array to pointer and function to
3252 function pointer) */
3253 static inline void convert_parameter_type(CType *pt)
3255 /* remove const and volatile qualifiers (XXX: const could be used
3256 to indicate a const function parameter */
3257 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3258 /* array must be transformed to pointer according to ANSI C */
3259 pt->t &= ~VT_ARRAY;
3260 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3261 mk_pointer(pt);
3265 ST_FUNC void parse_asm_str(CString *astr)
3267 skip('(');
3268 /* read the string */
3269 if (tok != TOK_STR)
3270 expect("string constant");
3271 cstr_new(astr);
3272 while (tok == TOK_STR) {
3273 /* XXX: add \0 handling too ? */
3274 cstr_cat(astr, tokc.cstr->data);
3275 next();
3277 cstr_ccat(astr, '\0');
3280 /* Parse an asm label and return the label
3281 * Don't forget to free the CString in the caller! */
3282 static void asm_label_instr(CString *astr)
3284 next();
3285 parse_asm_str(astr);
3286 skip(')');
3287 #ifdef ASM_DEBUG
3288 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3289 #endif
3292 static void post_type(CType *type, AttributeDef *ad)
3294 int n, l, t1, arg_size, align;
3295 Sym **plast, *s, *first;
3296 AttributeDef ad1;
3297 CType pt;
3299 if (tok == '(') {
3300 /* function declaration */
3301 next();
3302 l = 0;
3303 first = NULL;
3304 plast = &first;
3305 arg_size = 0;
3306 if (tok != ')') {
3307 for(;;) {
3308 /* read param name and compute offset */
3309 if (l != FUNC_OLD) {
3310 if (!parse_btype(&pt, &ad1)) {
3311 if (l) {
3312 tcc_error("invalid type");
3313 } else {
3314 l = FUNC_OLD;
3315 goto old_proto;
3318 l = FUNC_NEW;
3319 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3320 break;
3321 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3322 if ((pt.t & VT_BTYPE) == VT_VOID)
3323 tcc_error("parameter declared as void");
3324 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3325 } else {
3326 old_proto:
3327 n = tok;
3328 if (n < TOK_UIDENT)
3329 expect("identifier");
3330 pt.t = VT_INT;
3331 next();
3333 convert_parameter_type(&pt);
3334 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3335 *plast = s;
3336 plast = &s->next;
3337 if (tok == ')')
3338 break;
3339 skip(',');
3340 if (l == FUNC_NEW && tok == TOK_DOTS) {
3341 l = FUNC_ELLIPSIS;
3342 next();
3343 break;
3347 /* if no parameters, then old type prototype */
3348 if (l == 0)
3349 l = FUNC_OLD;
3350 skip(')');
3351 /* NOTE: const is ignored in returned type as it has a special
3352 meaning in gcc / C++ */
3353 type->t &= ~VT_CONSTANT;
3354 /* some ancient pre-K&R C allows a function to return an array
3355 and the array brackets to be put after the arguments, such
3356 that "int c()[]" means something like "int[] c()" */
3357 if (tok == '[') {
3358 next();
3359 skip(']'); /* only handle simple "[]" */
3360 type->t |= VT_PTR;
3362 /* we push a anonymous symbol which will contain the function prototype */
3363 ad->a.func_args = arg_size;
3364 s = sym_push(SYM_FIELD, type, 0, l);
3365 s->a = ad->a;
3366 s->next = first;
3367 type->t = VT_FUNC;
3368 type->ref = s;
3369 } else if (tok == '[') {
3370 /* array definition */
3371 next();
3372 if (tok == TOK_RESTRICT1)
3373 next();
3374 n = -1;
3375 t1 = 0;
3376 if (tok != ']') {
3377 if (!local_stack || nocode_wanted)
3378 vpushi(expr_const());
3379 else gexpr();
3380 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3381 n = vtop->c.i;
3382 if (n < 0)
3383 tcc_error("invalid array size");
3384 } else {
3385 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3386 tcc_error("size of variable length array should be an integer");
3387 t1 = VT_VLA;
3390 skip(']');
3391 /* parse next post type */
3392 post_type(type, ad);
3393 if (type->t == VT_FUNC)
3394 tcc_error("declaration of an array of functions");
3395 t1 |= type->t & VT_VLA;
3397 if (t1 & VT_VLA) {
3398 loc -= type_size(&int_type, &align);
3399 loc &= -align;
3400 n = loc;
3402 vla_runtime_type_size(type, &align);
3403 gen_op('*');
3404 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3405 vswap();
3406 vstore();
3408 if (n != -1)
3409 vpop();
3411 /* we push an anonymous symbol which will contain the array
3412 element type */
3413 s = sym_push(SYM_FIELD, type, 0, n);
3414 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3415 type->ref = s;
3419 /* Parse a type declaration (except basic type), and return the type
3420 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3421 expected. 'type' should contain the basic type. 'ad' is the
3422 attribute definition of the basic type. It can be modified by
3423 type_decl().
3425 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3427 Sym *s;
3428 CType type1, *type2;
3429 int qualifiers, storage;
3431 while (tok == '*') {
3432 qualifiers = 0;
3433 redo:
3434 next();
3435 switch(tok) {
3436 case TOK_CONST1:
3437 case TOK_CONST2:
3438 case TOK_CONST3:
3439 qualifiers |= VT_CONSTANT;
3440 goto redo;
3441 case TOK_VOLATILE1:
3442 case TOK_VOLATILE2:
3443 case TOK_VOLATILE3:
3444 qualifiers |= VT_VOLATILE;
3445 goto redo;
3446 case TOK_RESTRICT1:
3447 case TOK_RESTRICT2:
3448 case TOK_RESTRICT3:
3449 goto redo;
3451 mk_pointer(type);
3452 type->t |= qualifiers;
3455 /* XXX: clarify attribute handling */
3456 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3457 parse_attribute(ad);
3459 /* recursive type */
3460 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3461 type1.t = 0; /* XXX: same as int */
3462 if (tok == '(') {
3463 next();
3464 /* XXX: this is not correct to modify 'ad' at this point, but
3465 the syntax is not clear */
3466 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3467 parse_attribute(ad);
3468 type_decl(&type1, ad, v, td);
3469 skip(')');
3470 } else {
3471 /* type identifier */
3472 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3473 *v = tok;
3474 next();
3475 } else {
3476 if (!(td & TYPE_ABSTRACT))
3477 expect("identifier");
3478 *v = 0;
3481 storage = type->t & VT_STORAGE;
3482 type->t &= ~VT_STORAGE;
3483 if (storage & VT_STATIC) {
3484 int saved_nocode_wanted = nocode_wanted;
3485 nocode_wanted = 1;
3486 post_type(type, ad);
3487 nocode_wanted = saved_nocode_wanted;
3488 } else
3489 post_type(type, ad);
3490 type->t |= storage;
3491 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3492 parse_attribute(ad);
3494 if (!type1.t)
3495 return;
3496 /* append type at the end of type1 */
3497 type2 = &type1;
3498 for(;;) {
3499 s = type2->ref;
3500 type2 = &s->type;
3501 if (!type2->t) {
3502 *type2 = *type;
3503 break;
3506 *type = type1;
3509 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3510 ST_FUNC int lvalue_type(int t)
3512 int bt, r;
3513 r = VT_LVAL;
3514 bt = t & VT_BTYPE;
3515 if (bt == VT_BYTE || bt == VT_BOOL)
3516 r |= VT_LVAL_BYTE;
3517 else if (bt == VT_SHORT)
3518 r |= VT_LVAL_SHORT;
3519 else
3520 return r;
3521 if (t & VT_UNSIGNED)
3522 r |= VT_LVAL_UNSIGNED;
3523 return r;
3526 /* indirection with full error checking and bound check */
3527 ST_FUNC void indir(void)
3529 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3530 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3531 return;
3532 expect("pointer");
3534 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3535 gv(RC_INT);
3536 vtop->type = *pointed_type(&vtop->type);
3537 /* Arrays and functions are never lvalues */
3538 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3539 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3540 vtop->r |= lvalue_type(vtop->type.t);
3541 /* if bound checking, the referenced pointer must be checked */
3542 #ifdef CONFIG_TCC_BCHECK
3543 if (tcc_state->do_bounds_check)
3544 vtop->r |= VT_MUSTBOUND;
3545 #endif
3549 /* pass a parameter to a function and do type checking and casting */
3550 static void gfunc_param_typed(Sym *func, Sym *arg)
3552 int func_type;
3553 CType type;
3555 func_type = func->c;
3556 if (func_type == FUNC_OLD ||
3557 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3558 /* default casting : only need to convert float to double */
3559 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3560 type.t = VT_DOUBLE;
3561 gen_cast(&type);
3562 } else if (vtop->type.t & VT_BITFIELD) {
3563 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3564 gen_cast(&type);
3566 } else if (arg == NULL) {
3567 tcc_error("too many arguments to function");
3568 } else {
3569 type = arg->type;
3570 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3571 gen_assign_cast(&type);
3575 /* parse an expression of the form '(type)' or '(expr)' and return its
3576 type */
3577 static void parse_expr_type(CType *type)
3579 int n;
3580 AttributeDef ad;
3582 skip('(');
3583 if (parse_btype(type, &ad)) {
3584 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3585 } else {
3586 expr_type(type);
3588 skip(')');
3591 static void parse_type(CType *type)
3593 AttributeDef ad;
3594 int n;
3596 if (!parse_btype(type, &ad)) {
3597 expect("type");
3599 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3602 static void vpush_tokc(int t)
3604 CType type;
3605 type.t = t;
3606 type.ref = 0;
3607 vsetc(&type, VT_CONST, &tokc);
3610 ST_FUNC void unary(void)
3612 int n, t, align, size, r, sizeof_caller;
3613 CType type;
3614 Sym *s;
3615 AttributeDef ad;
3616 static int in_sizeof = 0;
3618 sizeof_caller = in_sizeof;
3619 in_sizeof = 0;
3620 /* XXX: GCC 2.95.3 does not generate a table although it should be
3621 better here */
3622 tok_next:
3623 switch(tok) {
3624 case TOK_EXTENSION:
3625 next();
3626 goto tok_next;
3627 case TOK_CINT:
3628 case TOK_CCHAR:
3629 case TOK_LCHAR:
3630 vpushi(tokc.i);
3631 next();
3632 break;
3633 case TOK_CUINT:
3634 vpush_tokc(VT_INT | VT_UNSIGNED);
3635 next();
3636 break;
3637 case TOK_CLLONG:
3638 vpush_tokc(VT_LLONG);
3639 next();
3640 break;
3641 case TOK_CULLONG:
3642 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3643 next();
3644 break;
3645 case TOK_CFLOAT:
3646 vpush_tokc(VT_FLOAT);
3647 next();
3648 break;
3649 case TOK_CDOUBLE:
3650 vpush_tokc(VT_DOUBLE);
3651 next();
3652 break;
3653 case TOK_CLDOUBLE:
3654 vpush_tokc(VT_LDOUBLE);
3655 next();
3656 break;
3657 case TOK___FUNCTION__:
3658 if (!gnu_ext)
3659 goto tok_identifier;
3660 /* fall thru */
3661 case TOK___FUNC__:
3663 void *ptr;
3664 int len;
3665 /* special function name identifier */
3666 len = strlen(funcname) + 1;
3667 /* generate char[len] type */
3668 type.t = VT_BYTE;
3669 mk_pointer(&type);
3670 type.t |= VT_ARRAY;
3671 type.ref->c = len;
3672 vpush_ref(&type, data_section, data_section->data_offset, len);
3673 ptr = section_ptr_add(data_section, len);
3674 memcpy(ptr, funcname, len);
3675 next();
3677 break;
3678 case TOK_LSTR:
3679 #ifdef TCC_TARGET_PE
3680 t = VT_SHORT | VT_UNSIGNED;
3681 #else
3682 t = VT_INT;
3683 #endif
3684 goto str_init;
3685 case TOK_STR:
3686 /* string parsing */
3687 t = VT_BYTE;
3688 str_init:
3689 if (tcc_state->warn_write_strings)
3690 t |= VT_CONSTANT;
3691 type.t = t;
3692 mk_pointer(&type);
3693 type.t |= VT_ARRAY;
3694 memset(&ad, 0, sizeof(AttributeDef));
3695 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3696 break;
3697 case '(':
3698 next();
3699 /* cast ? */
3700 if (parse_btype(&type, &ad)) {
3701 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3702 skip(')');
3703 /* check ISOC99 compound literal */
3704 if (tok == '{') {
3705 /* data is allocated locally by default */
3706 if (global_expr)
3707 r = VT_CONST;
3708 else
3709 r = VT_LOCAL;
3710 /* all except arrays are lvalues */
3711 if (!(type.t & VT_ARRAY))
3712 r |= lvalue_type(type.t);
3713 memset(&ad, 0, sizeof(AttributeDef));
3714 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3715 } else {
3716 if (sizeof_caller) {
3717 vpush(&type);
3718 return;
3720 unary();
3721 gen_cast(&type);
3723 } else if (tok == '{') {
3724 /* save all registers */
3725 save_regs(0);
3726 /* statement expression : we do not accept break/continue
3727 inside as GCC does */
3728 block(NULL, NULL, NULL, NULL, 0, 1);
3729 skip(')');
3730 } else {
3731 gexpr();
3732 skip(')');
3734 break;
3735 case '*':
3736 next();
3737 unary();
3738 indir();
3739 break;
3740 case '&':
3741 next();
3742 unary();
3743 /* functions names must be treated as function pointers,
3744 except for unary '&' and sizeof. Since we consider that
3745 functions are not lvalues, we only have to handle it
3746 there and in function calls. */
3747 /* arrays can also be used although they are not lvalues */
3748 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3749 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3750 test_lvalue();
3751 mk_pointer(&vtop->type);
3752 gaddrof();
3753 break;
3754 case '!':
3755 next();
3756 unary();
3757 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3758 CType boolean;
3759 boolean.t = VT_BOOL;
3760 gen_cast(&boolean);
3761 vtop->c.i = !vtop->c.i;
3762 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3763 vtop->c.i = vtop->c.i ^ 1;
3764 else {
3765 save_regs(1);
3766 vseti(VT_JMP, gvtst(1, 0));
3768 break;
3769 case '~':
3770 next();
3771 unary();
3772 vpushi(-1);
3773 gen_op('^');
3774 break;
3775 case '+':
3776 next();
3777 unary();
3778 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3779 tcc_error("pointer not accepted for unary plus");
3780 /* In order to force cast, we add zero, except for floating point
3781 where we really need an noop (otherwise -0.0 will be transformed
3782 into +0.0). */
3783 if (!is_float(vtop->type.t)) {
3784 vpushi(0);
3785 gen_op('+');
3787 break;
3788 case TOK_SIZEOF:
3789 case TOK_ALIGNOF1:
3790 case TOK_ALIGNOF2:
3791 t = tok;
3792 next();
3793 in_sizeof++;
3794 unary_type(&type); // Perform a in_sizeof = 0;
3795 size = type_size(&type, &align);
3796 if (t == TOK_SIZEOF) {
3797 if (!(type.t & VT_VLA)) {
3798 if (size < 0)
3799 tcc_error("sizeof applied to an incomplete type");
3800 if(type.t & VT_BITFIELD)
3801 tcc_error("'%s' applied to a bit-field", get_tok_str(t, NULL));
3802 vpushs(size);
3803 } else {
3804 vla_runtime_type_size(&type, &align);
3806 } else {
3807 vpushs(align);
3809 vtop->type.t |= VT_UNSIGNED;
3810 break;
3812 case TOK_builtin_types_compatible_p:
3814 CType type1, type2;
3815 next();
3816 skip('(');
3817 parse_type(&type1);
3818 skip(',');
3819 parse_type(&type2);
3820 skip(')');
3821 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3822 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3823 vpushi(is_compatible_types(&type1, &type2));
3825 break;
3826 case TOK_builtin_constant_p:
3828 int saved_nocode_wanted, res;
3829 next();
3830 skip('(');
3831 saved_nocode_wanted = nocode_wanted;
3832 nocode_wanted = 1;
3833 gexpr();
3834 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3835 vpop();
3836 nocode_wanted = saved_nocode_wanted;
3837 skip(')');
3838 vpushi(res);
3840 break;
3841 case TOK_builtin_frame_address:
3843 int level;
3844 CType type;
3845 next();
3846 skip('(');
3847 if (tok != TOK_CINT || tokc.i < 0) {
3848 tcc_error("__builtin_frame_address only takes positive integers");
3850 level = tokc.i;
3851 next();
3852 skip(')');
3853 type.t = VT_VOID;
3854 mk_pointer(&type);
3855 vset(&type, VT_LOCAL, 0); /* local frame */
3856 while (level--) {
3857 mk_pointer(&vtop->type);
3858 indir(); /* -> parent frame */
3861 break;
3862 #ifdef TCC_TARGET_X86_64
3863 #ifdef TCC_TARGET_PE
3864 case TOK_builtin_va_start:
3866 next();
3867 skip('(');
3868 expr_eq();
3869 skip(',');
3870 expr_eq();
3871 skip(')');
3872 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
3873 tcc_error("__builtin_va_start expects a local variable");
3874 vtop->r &= ~(VT_LVAL | VT_REF);
3875 vtop->type = char_pointer_type;
3876 vstore();
3878 break;
3879 #else
3880 case TOK_builtin_va_arg_types:
3882 CType type;
3883 next();
3884 skip('(');
3885 parse_type(&type);
3886 skip(')');
3887 vpushi(classify_x86_64_va_arg(&type));
3889 break;
3890 #endif
3891 #endif
3892 case TOK_INC:
3893 case TOK_DEC:
3894 t = tok;
3895 next();
3896 unary();
3897 inc(0, t);
3898 break;
3899 case '-':
3900 next();
3901 unary();
3902 t = vtop->type.t & VT_BTYPE;
3903 if (is_float(t)) {
3904 /* In IEEE negate(x) isn't subtract(0,x), but rather
3905 subtract(-0, x). */
3906 vpush(&vtop->type);
3907 if (t == VT_FLOAT)
3908 vtop->c.f = -0.0f;
3909 else if (t == VT_DOUBLE)
3910 vtop->c.d = -0.0;
3911 else
3912 vtop->c.ld = -0.0;
3913 } else
3914 vpushi(0);
3915 vswap();
3916 gen_op('-');
3917 break;
3918 case TOK_LAND:
3919 if (!gnu_ext)
3920 goto tok_identifier;
3921 next();
3922 /* allow to take the address of a label */
3923 if (tok < TOK_UIDENT)
3924 expect("label identifier");
3925 s = label_find(tok);
3926 if (!s) {
3927 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3928 } else {
3929 if (s->r == LABEL_DECLARED)
3930 s->r = LABEL_FORWARD;
3932 if (!s->type.t) {
3933 s->type.t = VT_VOID;
3934 mk_pointer(&s->type);
3935 s->type.t |= VT_STATIC;
3937 vpushsym(&s->type, s);
3938 next();
3939 break;
3941 // special qnan , snan and infinity values
3942 case TOK___NAN__:
3943 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3944 next();
3945 break;
3946 case TOK___SNAN__:
3947 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3948 next();
3949 break;
3950 case TOK___INF__:
3951 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3952 next();
3953 break;
3955 default:
3956 tok_identifier:
3957 t = tok;
3958 next();
3959 if (t < TOK_UIDENT)
3960 expect("identifier");
3961 s = sym_find(t);
3962 if (!s) {
3963 const char *name = get_tok_str(t, NULL);
3964 if (tok != '(')
3965 tcc_error("'%s' undeclared", name);
3966 /* for simple function calls, we tolerate undeclared
3967 external reference to int() function */
3968 if (tcc_state->warn_implicit_function_declaration
3969 #ifdef TCC_TARGET_PE
3970 /* people must be warned about using undeclared WINAPI functions
3971 (which usually start with uppercase letter) */
3972 || (name[0] >= 'A' && name[0] <= 'Z')
3973 #endif
3975 tcc_warning("implicit declaration of function '%s'", name);
3976 s = external_global_sym(t, &func_old_type, 0);
3978 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3979 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3980 /* if referencing an inline function, then we generate a
3981 symbol to it if not already done. It will have the
3982 effect to generate code for it at the end of the
3983 compilation unit. Inline function as always
3984 generated in the text section. */
3985 if (!s->c)
3986 put_extern_sym(s, text_section, 0, 0);
3987 r = VT_SYM | VT_CONST;
3988 } else {
3989 r = s->r;
3991 vset(&s->type, r, s->c);
3992 /* if forward reference, we must point to s */
3993 if (vtop->r & VT_SYM) {
3994 vtop->sym = s;
3995 vtop->c.ptr_offset = 0;
3997 break;
4000 /* post operations */
4001 while (1) {
4002 if (tok == TOK_INC || tok == TOK_DEC) {
4003 inc(1, tok);
4004 next();
4005 } else if (tok == '.' || tok == TOK_ARROW) {
4006 int qualifiers;
4007 /* field */
4008 if (tok == TOK_ARROW)
4009 indir();
4010 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4011 test_lvalue();
4012 gaddrof();
4013 next();
4014 /* expect pointer on structure */
4015 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4016 expect("struct or union");
4017 s = vtop->type.ref;
4018 /* find field */
4019 tok |= SYM_FIELD;
4020 while ((s = s->next) != NULL) {
4021 if (s->v == tok)
4022 break;
4024 if (!s)
4025 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
4026 /* add field offset to pointer */
4027 vtop->type = char_pointer_type; /* change type to 'char *' */
4028 vpushi(s->c);
4029 gen_op('+');
4030 /* change type to field type, and set to lvalue */
4031 vtop->type = s->type;
4032 vtop->type.t |= qualifiers;
4033 /* an array is never an lvalue */
4034 if (!(vtop->type.t & VT_ARRAY)) {
4035 vtop->r |= lvalue_type(vtop->type.t);
4036 #ifdef CONFIG_TCC_BCHECK
4037 /* if bound checking, the referenced pointer must be checked */
4038 if (tcc_state->do_bounds_check)
4039 vtop->r |= VT_MUSTBOUND;
4040 #endif
4042 next();
4043 } else if (tok == '[') {
4044 next();
4045 gexpr();
4046 gen_op('+');
4047 indir();
4048 skip(']');
4049 } else if (tok == '(') {
4050 SValue ret;
4051 Sym *sa;
4052 int nb_args, ret_nregs, ret_align, variadic;
4054 /* function call */
4055 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4056 /* pointer test (no array accepted) */
4057 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4058 vtop->type = *pointed_type(&vtop->type);
4059 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4060 goto error_func;
4061 } else {
4062 error_func:
4063 expect("function pointer");
4065 } else {
4066 vtop->r &= ~VT_LVAL; /* no lvalue */
4068 /* get return type */
4069 s = vtop->type.ref;
4070 next();
4071 sa = s->next; /* first parameter */
4072 nb_args = 0;
4073 ret.r2 = VT_CONST;
4074 /* compute first implicit argument if a structure is returned */
4075 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4076 variadic = (s->c == FUNC_ELLIPSIS);
4077 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4078 &ret_align);
4079 if (!ret_nregs) {
4080 /* get some space for the returned structure */
4081 size = type_size(&s->type, &align);
4082 loc = (loc - size) & -align;
4083 ret.type = s->type;
4084 ret.r = VT_LOCAL | VT_LVAL;
4085 /* pass it as 'int' to avoid structure arg passing
4086 problems */
4087 vseti(VT_LOCAL, loc);
4088 ret.c = vtop->c;
4089 nb_args++;
4091 } else {
4092 ret_nregs = 1;
4093 ret.type = s->type;
4096 if (ret_nregs) {
4097 /* return in register */
4098 if (is_float(ret.type.t)) {
4099 ret.r = reg_fret(ret.type.t);
4100 #ifdef TCC_TARGET_X86_64
4101 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4102 ret.r2 = REG_QRET;
4103 #endif
4104 } else {
4105 #ifdef TCC_TARGET_X86_64
4106 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4107 #else
4108 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4109 #endif
4110 ret.r2 = REG_LRET;
4111 ret.r = REG_IRET;
4113 ret.c.i = 0;
4115 if (tok != ')') {
4116 for(;;) {
4117 expr_eq();
4118 gfunc_param_typed(s, sa);
4119 nb_args++;
4120 if (sa)
4121 sa = sa->next;
4122 if (tok == ')')
4123 break;
4124 skip(',');
4127 if (sa)
4128 tcc_error("too few arguments to function");
4129 skip(')');
4130 if (!nocode_wanted) {
4131 gfunc_call(nb_args);
4132 } else {
4133 vtop -= (nb_args + 1);
4136 /* return value */
4137 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4138 vsetc(&ret.type, r, &ret.c);
4139 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4142 /* handle packed struct return */
4143 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4144 int addr, offset;
4146 size = type_size(&s->type, &align);
4147 loc = (loc - size) & -align;
4148 addr = loc;
4149 offset = 0;
4150 for (;;) {
4151 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4152 vswap();
4153 vstore();
4154 vtop--;
4155 if (--ret_nregs == 0)
4156 break;
4157 /* XXX: compatible with arm only: ret_align == register_size */
4158 offset += ret_align;
4160 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4162 } else {
4163 break;
4168 ST_FUNC void expr_prod(void)
4170 int t;
4172 unary();
4173 while (tok == '*' || tok == '/' || tok == '%') {
4174 t = tok;
4175 next();
4176 unary();
4177 gen_op(t);
4181 ST_FUNC void expr_sum(void)
4183 int t;
4185 expr_prod();
4186 while (tok == '+' || tok == '-') {
4187 t = tok;
4188 next();
4189 expr_prod();
4190 gen_op(t);
4194 static void expr_shift(void)
4196 int t;
4198 expr_sum();
4199 while (tok == TOK_SHL || tok == TOK_SAR) {
4200 t = tok;
4201 next();
4202 expr_sum();
4203 gen_op(t);
4207 static void expr_cmp(void)
4209 int t;
4211 expr_shift();
4212 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4213 tok == TOK_ULT || tok == TOK_UGE) {
4214 t = tok;
4215 next();
4216 expr_shift();
4217 gen_op(t);
4221 static void expr_cmpeq(void)
4223 int t;
4225 expr_cmp();
4226 while (tok == TOK_EQ || tok == TOK_NE) {
4227 t = tok;
4228 next();
4229 expr_cmp();
4230 gen_op(t);
4234 static void expr_and(void)
4236 expr_cmpeq();
4237 while (tok == '&') {
4238 next();
4239 expr_cmpeq();
4240 gen_op('&');
4244 static void expr_xor(void)
4246 expr_and();
4247 while (tok == '^') {
4248 next();
4249 expr_and();
4250 gen_op('^');
4254 static void expr_or(void)
4256 expr_xor();
4257 while (tok == '|') {
4258 next();
4259 expr_xor();
4260 gen_op('|');
4264 /* XXX: fix this mess */
4265 static void expr_land_const(void)
4267 expr_or();
4268 while (tok == TOK_LAND) {
4269 next();
4270 expr_or();
4271 gen_op(TOK_LAND);
4275 /* XXX: fix this mess */
4276 static void expr_lor_const(void)
4278 expr_land_const();
4279 while (tok == TOK_LOR) {
4280 next();
4281 expr_land_const();
4282 gen_op(TOK_LOR);
4286 /* only used if non constant */
4287 static void expr_land(void)
4289 int t;
4291 expr_or();
4292 if (tok == TOK_LAND) {
4293 t = 0;
4294 save_regs(1);
4295 for(;;) {
4296 t = gvtst(1, t);
4297 if (tok != TOK_LAND) {
4298 vseti(VT_JMPI, t);
4299 break;
4301 next();
4302 expr_or();
4307 static void expr_lor(void)
4309 int t;
4311 expr_land();
4312 if (tok == TOK_LOR) {
4313 t = 0;
4314 save_regs(1);
4315 for(;;) {
4316 t = gvtst(0, t);
4317 if (tok != TOK_LOR) {
4318 vseti(VT_JMP, t);
4319 break;
4321 next();
4322 expr_land();
4327 /* XXX: better constant handling */
4328 static void expr_cond(void)
4330 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4331 SValue sv;
4332 CType type, type1, type2;
4334 if (const_wanted) {
4335 expr_lor_const();
4336 if (tok == '?') {
4337 CType boolean;
4338 int c;
4339 boolean.t = VT_BOOL;
4340 vdup();
4341 gen_cast(&boolean);
4342 c = vtop->c.i;
4343 vpop();
4344 next();
4345 if (tok != ':' || !gnu_ext) {
4346 vpop();
4347 gexpr();
4349 if (!c)
4350 vpop();
4351 skip(':');
4352 expr_cond();
4353 if (c)
4354 vpop();
4356 } else {
4357 expr_lor();
4358 if (tok == '?') {
4359 next();
4360 if (vtop != vstack) {
4361 /* needed to avoid having different registers saved in
4362 each branch */
4363 if (is_float(vtop->type.t)) {
4364 rc = RC_FLOAT;
4365 #ifdef TCC_TARGET_X86_64
4366 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4367 rc = RC_ST0;
4369 #endif
4371 else
4372 rc = RC_INT;
4373 gv(rc);
4374 save_regs(1);
4376 if (tok == ':' && gnu_ext) {
4377 gv_dup();
4378 tt = gvtst(1, 0);
4379 } else {
4380 tt = gvtst(1, 0);
4381 gexpr();
4383 type1 = vtop->type;
4384 sv = *vtop; /* save value to handle it later */
4385 vtop--; /* no vpop so that FP stack is not flushed */
4386 skip(':');
4387 u = gjmp(0);
4388 gsym(tt);
4389 expr_cond();
4390 type2 = vtop->type;
4392 t1 = type1.t;
4393 bt1 = t1 & VT_BTYPE;
4394 t2 = type2.t;
4395 bt2 = t2 & VT_BTYPE;
4396 /* cast operands to correct type according to ISOC rules */
4397 if (is_float(bt1) || is_float(bt2)) {
4398 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4399 type.t = VT_LDOUBLE;
4400 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4401 type.t = VT_DOUBLE;
4402 } else {
4403 type.t = VT_FLOAT;
4405 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4406 /* cast to biggest op */
4407 type.t = VT_LLONG;
4408 /* convert to unsigned if it does not fit in a long long */
4409 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4410 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4411 type.t |= VT_UNSIGNED;
4412 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4413 /* If one is a null ptr constant the result type
4414 is the other. */
4415 if (is_null_pointer (vtop))
4416 type = type1;
4417 else if (is_null_pointer (&sv))
4418 type = type2;
4419 /* XXX: test pointer compatibility, C99 has more elaborate
4420 rules here. */
4421 else
4422 type = type1;
4423 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4424 /* XXX: test function pointer compatibility */
4425 type = bt1 == VT_FUNC ? type1 : type2;
4426 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4427 /* XXX: test structure compatibility */
4428 type = bt1 == VT_STRUCT ? type1 : type2;
4429 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4430 /* NOTE: as an extension, we accept void on only one side */
4431 type.t = VT_VOID;
4432 } else {
4433 /* integer operations */
4434 type.t = VT_INT;
4435 /* convert to unsigned if it does not fit in an integer */
4436 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4437 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4438 type.t |= VT_UNSIGNED;
4441 /* now we convert second operand */
4442 gen_cast(&type);
4443 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4444 gaddrof();
4445 rc = RC_INT;
4446 if (is_float(type.t)) {
4447 rc = RC_FLOAT;
4448 #ifdef TCC_TARGET_X86_64
4449 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4450 rc = RC_ST0;
4452 #endif
4453 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4454 /* for long longs, we use fixed registers to avoid having
4455 to handle a complicated move */
4456 rc = RC_IRET;
4459 r2 = gv(rc);
4460 /* this is horrible, but we must also convert first
4461 operand */
4462 tt = gjmp(0);
4463 gsym(u);
4464 /* put again first value and cast it */
4465 *vtop = sv;
4466 gen_cast(&type);
4467 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4468 gaddrof();
4469 r1 = gv(rc);
4470 move_reg(r2, r1, type.t);
4471 vtop->r = r2;
4472 gsym(tt);
4477 static void expr_eq(void)
4479 int t;
4481 expr_cond();
4482 if (tok == '=' ||
4483 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4484 tok == TOK_A_XOR || tok == TOK_A_OR ||
4485 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4486 test_lvalue();
4487 t = tok;
4488 next();
4489 if (t == '=') {
4490 expr_eq();
4491 } else {
4492 vdup();
4493 expr_eq();
4494 gen_op(t & 0x7f);
4496 vstore();
4500 ST_FUNC void gexpr(void)
4502 while (1) {
4503 expr_eq();
4504 if (tok != ',')
4505 break;
4506 vpop();
4507 next();
4511 /* parse an expression and return its type without any side effect. */
4512 static void expr_type(CType *type)
4514 int saved_nocode_wanted;
4516 saved_nocode_wanted = nocode_wanted;
4517 nocode_wanted = 1;
4518 gexpr();
4519 *type = vtop->type;
4520 vpop();
4521 nocode_wanted = saved_nocode_wanted;
4524 /* parse a unary expression and return its type without any side
4525 effect. */
4526 static void unary_type(CType *type)
4528 int a;
4530 a = nocode_wanted;
4531 nocode_wanted = 1;
4532 unary();
4533 *type = vtop->type;
4534 vpop();
4535 nocode_wanted = a;
4538 /* parse a constant expression and return value in vtop. */
4539 static void expr_const1(void)
4541 int a;
4542 a = const_wanted;
4543 const_wanted = 1;
4544 expr_cond();
4545 const_wanted = a;
4548 /* parse an integer constant and return its value. */
4549 ST_FUNC int expr_const(void)
4551 int c;
4552 expr_const1();
4553 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4554 expect("constant expression");
4555 c = vtop->c.i;
4556 vpop();
4557 return c;
4560 /* return the label token if current token is a label, otherwise
4561 return zero */
4562 static int is_label(void)
4564 int last_tok;
4566 /* fast test first */
4567 if (tok < TOK_UIDENT)
4568 return 0;
4569 /* no need to save tokc because tok is an identifier */
4570 last_tok = tok;
4571 next();
4572 if (tok == ':') {
4573 next();
4574 return last_tok;
4575 } else {
4576 unget_tok(last_tok);
4577 return 0;
4581 static void label_or_decl(int l)
4583 int last_tok;
4585 /* fast test first */
4586 if (tok >= TOK_UIDENT)
4588 /* no need to save tokc because tok is an identifier */
4589 last_tok = tok;
4590 next();
4591 if (tok == ':') {
4592 unget_tok(last_tok);
4593 return;
4595 unget_tok(last_tok);
4597 decl(l);
4600 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4601 int case_reg, int is_expr)
4603 int a, b, c, d;
4604 Sym *s, *frame_bottom;
4606 /* generate line number info */
4607 if (tcc_state->do_debug &&
4608 (last_line_num != file->line_num || last_ind != ind)) {
4609 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4610 last_ind = ind;
4611 last_line_num = file->line_num;
4614 if (is_expr) {
4615 /* default return value is (void) */
4616 vpushi(0);
4617 vtop->type.t = VT_VOID;
4620 if (tok == TOK_IF) {
4621 /* if test */
4622 next();
4623 skip('(');
4624 gexpr();
4625 skip(')');
4626 a = gvtst(1, 0);
4627 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4628 c = tok;
4629 if (c == TOK_ELSE) {
4630 next();
4631 d = gjmp(0);
4632 gsym(a);
4633 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4634 gsym(d); /* patch else jmp */
4635 } else
4636 gsym(a);
4637 } else if (tok == TOK_WHILE) {
4638 next();
4639 d = ind;
4640 skip('(');
4641 gexpr();
4642 skip(')');
4643 a = gvtst(1, 0);
4644 b = 0;
4645 block(&a, &b, case_sym, def_sym, case_reg, 0);
4646 gjmp_addr(d);
4647 gsym(a);
4648 gsym_addr(b, d);
4649 } else if (tok == '{') {
4650 Sym *llabel;
4651 int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
4653 next();
4654 /* record local declaration stack position */
4655 s = local_stack;
4656 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4657 frame_bottom->next = scope_stack_bottom;
4658 scope_stack_bottom = frame_bottom;
4659 llabel = local_label_stack;
4661 /* save VLA state */
4662 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4663 if (saved_vla_sp_loc != &vla_sp_root_loc)
4664 vla_sp_loc = &block_vla_sp_loc;
4666 saved_vla_flags = vla_flags;
4667 vla_flags |= VLA_NEED_NEW_FRAME;
4669 /* handle local labels declarations */
4670 if (tok == TOK_LABEL) {
4671 next();
4672 for(;;) {
4673 if (tok < TOK_UIDENT)
4674 expect("label identifier");
4675 label_push(&local_label_stack, tok, LABEL_DECLARED);
4676 next();
4677 if (tok == ',') {
4678 next();
4679 } else {
4680 skip(';');
4681 break;
4685 while (tok != '}') {
4686 label_or_decl(VT_LOCAL);
4687 if (tok != '}') {
4688 if (is_expr)
4689 vpop();
4690 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4693 /* pop locally defined labels */
4694 label_pop(&local_label_stack, llabel);
4695 if(is_expr) {
4696 /* XXX: this solution makes only valgrind happy...
4697 triggered by gcc.c-torture/execute/20000917-1.c */
4698 Sym *p;
4699 switch(vtop->type.t & VT_BTYPE) {
4700 case VT_PTR:
4701 case VT_STRUCT:
4702 case VT_ENUM:
4703 case VT_FUNC:
4704 for(p=vtop->type.ref;p;p=p->prev)
4705 if(p->prev==s)
4706 tcc_error("unsupported expression type");
4709 /* pop locally defined symbols */
4710 scope_stack_bottom = scope_stack_bottom->next;
4711 sym_pop(&local_stack, s);
4713 /* Pop VLA frames and restore stack pointer if required */
4714 if (saved_vla_sp_loc != &vla_sp_root_loc)
4715 *saved_vla_sp_loc = block_vla_sp_loc;
4716 if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
4717 vla_sp_loc = saved_vla_sp_loc;
4718 gen_vla_sp_restore(*vla_sp_loc);
4720 vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
4722 next();
4723 } else if (tok == TOK_RETURN) {
4724 next();
4725 if (tok != ';') {
4726 gexpr();
4727 gen_assign_cast(&func_vt);
4728 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4729 CType type, ret_type;
4730 int ret_align, ret_nregs;
4731 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
4732 &ret_align);
4733 if (0 == ret_nregs) {
4734 /* if returning structure, must copy it to implicit
4735 first pointer arg location */
4736 type = func_vt;
4737 mk_pointer(&type);
4738 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4739 indir();
4740 vswap();
4741 /* copy structure value to pointer */
4742 vstore();
4743 } else {
4744 /* returning structure packed into registers */
4745 int r, size, addr, align;
4746 size = type_size(&func_vt,&align);
4747 if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))
4748 && (align & (ret_align-1))) {
4749 loc = (loc - size) & -align;
4750 addr = loc;
4751 type = func_vt;
4752 vset(&type, VT_LOCAL | VT_LVAL, addr);
4753 vswap();
4754 vstore();
4755 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
4757 vtop->type = ret_type;
4758 if (is_float(ret_type.t))
4759 r = rc_fret(ret_type.t);
4760 else
4761 r = RC_IRET;
4763 for (;;) {
4764 gv(r);
4765 if (--ret_nregs == 0)
4766 break;
4767 /* We assume that when a structure is returned in multiple
4768 registers, their classes are consecutive values of the
4769 suite s(n) = 2^n */
4770 r <<= 1;
4771 /* XXX: compatible with arm only: ret_align == register_size */
4772 vtop->c.i += ret_align;
4773 vtop->r = VT_LOCAL | VT_LVAL;
4776 } else if (is_float(func_vt.t)) {
4777 gv(rc_fret(func_vt.t));
4778 } else {
4779 gv(RC_IRET);
4781 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4783 skip(';');
4784 rsym = gjmp(rsym); /* jmp */
4785 } else if (tok == TOK_BREAK) {
4786 /* compute jump */
4787 if (!bsym)
4788 tcc_error("cannot break");
4789 *bsym = gjmp(*bsym);
4790 next();
4791 skip(';');
4792 } else if (tok == TOK_CONTINUE) {
4793 /* compute jump */
4794 if (!csym)
4795 tcc_error("cannot continue");
4796 *csym = gjmp(*csym);
4797 next();
4798 skip(';');
4799 } else if (tok == TOK_FOR) {
4800 int e;
4801 next();
4802 skip('(');
4803 s = local_stack;
4804 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4805 frame_bottom->next = scope_stack_bottom;
4806 scope_stack_bottom = frame_bottom;
4807 if (tok != ';') {
4808 /* c99 for-loop init decl? */
4809 if (!decl0(VT_LOCAL, 1)) {
4810 /* no, regular for-loop init expr */
4811 gexpr();
4812 vpop();
4815 skip(';');
4816 d = ind;
4817 c = ind;
4818 a = 0;
4819 b = 0;
4820 if (tok != ';') {
4821 gexpr();
4822 a = gvtst(1, 0);
4824 skip(';');
4825 if (tok != ')') {
4826 e = gjmp(0);
4827 c = ind;
4828 gexpr();
4829 vpop();
4830 gjmp_addr(d);
4831 gsym(e);
4833 skip(')');
4834 block(&a, &b, case_sym, def_sym, case_reg, 0);
4835 gjmp_addr(c);
4836 gsym(a);
4837 gsym_addr(b, c);
4838 scope_stack_bottom = scope_stack_bottom->next;
4839 sym_pop(&local_stack, s);
4840 } else
4841 if (tok == TOK_DO) {
4842 next();
4843 a = 0;
4844 b = 0;
4845 d = ind;
4846 block(&a, &b, case_sym, def_sym, case_reg, 0);
4847 skip(TOK_WHILE);
4848 skip('(');
4849 gsym(b);
4850 gexpr();
4851 c = gvtst(0, 0);
4852 gsym_addr(c, d);
4853 skip(')');
4854 gsym(a);
4855 skip(';');
4856 } else
4857 if (tok == TOK_SWITCH) {
4858 next();
4859 skip('(');
4860 gexpr();
4861 /* XXX: other types than integer */
4862 case_reg = gv(RC_INT);
4863 vpop();
4864 skip(')');
4865 a = 0;
4866 b = gjmp(0); /* jump to first case */
4867 c = 0;
4868 block(&a, csym, &b, &c, case_reg, 0);
4869 /* if no default, jmp after switch */
4870 if (c == 0)
4871 c = ind;
4872 /* default label */
4873 gsym_addr(b, c);
4874 /* break label */
4875 gsym(a);
4876 } else
4877 if (tok == TOK_CASE) {
4878 int v1, v2;
4879 if (!case_sym)
4880 expect("switch");
4881 next();
4882 v1 = expr_const();
4883 v2 = v1;
4884 if (gnu_ext && tok == TOK_DOTS) {
4885 next();
4886 v2 = expr_const();
4887 if (v2 < v1)
4888 tcc_warning("empty case range");
4890 /* since a case is like a label, we must skip it with a jmp */
4891 b = gjmp(0);
4892 gsym(*case_sym);
4893 vseti(case_reg, 0);
4894 vpushi(v1);
4895 if (v1 == v2) {
4896 gen_op(TOK_EQ);
4897 *case_sym = gtst(1, 0);
4898 } else {
4899 gen_op(TOK_GE);
4900 *case_sym = gtst(1, 0);
4901 vseti(case_reg, 0);
4902 vpushi(v2);
4903 gen_op(TOK_LE);
4904 *case_sym = gtst(1, *case_sym);
4906 gsym(b);
4907 skip(':');
4908 is_expr = 0;
4909 goto block_after_label;
4910 } else
4911 if (tok == TOK_DEFAULT) {
4912 next();
4913 skip(':');
4914 if (!def_sym)
4915 expect("switch");
4916 if (*def_sym)
4917 tcc_error("too many 'default'");
4918 *def_sym = ind;
4919 is_expr = 0;
4920 goto block_after_label;
4921 } else
4922 if (tok == TOK_GOTO) {
4923 next();
4924 if (tok == '*' && gnu_ext) {
4925 /* computed goto */
4926 next();
4927 gexpr();
4928 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4929 expect("pointer");
4930 ggoto();
4931 } else if (tok >= TOK_UIDENT) {
4932 s = label_find(tok);
4933 /* put forward definition if needed */
4934 if (!s) {
4935 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4936 } else {
4937 if (s->r == LABEL_DECLARED)
4938 s->r = LABEL_FORWARD;
4940 /* label already defined */
4941 if (vla_flags & VLA_IN_SCOPE) {
4942 /* If VLAs are in use, save the current stack pointer and
4943 reset the stack pointer to what it was at function entry
4944 (label will restore stack pointer in inner scopes) */
4945 vla_sp_save();
4946 gen_vla_sp_restore(vla_sp_root_loc);
4948 if (s->r & LABEL_FORWARD)
4949 s->jnext = gjmp(s->jnext);
4950 else
4951 gjmp_addr(s->jnext);
4952 next();
4953 } else {
4954 expect("label identifier");
4956 skip(';');
4957 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4958 asm_instr();
4959 } else {
4960 b = is_label();
4961 if (b) {
4962 /* label case */
4963 if (vla_flags & VLA_IN_SCOPE) {
4964 /* save/restore stack pointer across label
4965 this is a no-op when combined with the load immediately
4966 after the label unless we arrive via goto */
4967 vla_sp_save();
4969 s = label_find(b);
4970 if (s) {
4971 if (s->r == LABEL_DEFINED)
4972 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4973 gsym(s->jnext);
4974 s->r = LABEL_DEFINED;
4975 } else {
4976 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4978 s->jnext = ind;
4979 if (vla_flags & VLA_IN_SCOPE) {
4980 gen_vla_sp_restore(*vla_sp_loc);
4981 vla_flags |= VLA_NEED_NEW_FRAME;
4983 /* we accept this, but it is a mistake */
4984 block_after_label:
4985 if (tok == '}') {
4986 tcc_warning("deprecated use of label at end of compound statement");
4987 } else {
4988 if (is_expr)
4989 vpop();
4990 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4992 } else {
4993 /* expression case */
4994 if (tok != ';') {
4995 if (is_expr) {
4996 vpop();
4997 gexpr();
4998 } else {
4999 gexpr();
5000 vpop();
5003 skip(';');
5008 /* t is the array or struct type. c is the array or struct
5009 address. cur_index/cur_field is the pointer to the current
5010 value. 'size_only' is true if only size info is needed (only used
5011 in arrays) */
5012 static void decl_designator(CType *type, Section *sec, unsigned long c,
5013 int *cur_index, Sym **cur_field,
5014 int size_only)
5016 Sym *s, *f;
5017 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5018 CType type1;
5020 notfirst = 0;
5021 elem_size = 0;
5022 nb_elems = 1;
5023 if (gnu_ext && (l = is_label()) != 0)
5024 goto struct_field;
5025 while (tok == '[' || tok == '.') {
5026 if (tok == '[') {
5027 if (!(type->t & VT_ARRAY))
5028 expect("array type");
5029 s = type->ref;
5030 next();
5031 index = expr_const();
5032 if (index < 0 || (s->c >= 0 && index >= s->c))
5033 expect("invalid index");
5034 if (tok == TOK_DOTS && gnu_ext) {
5035 next();
5036 index_last = expr_const();
5037 if (index_last < 0 ||
5038 (s->c >= 0 && index_last >= s->c) ||
5039 index_last < index)
5040 expect("invalid index");
5041 } else {
5042 index_last = index;
5044 skip(']');
5045 if (!notfirst)
5046 *cur_index = index_last;
5047 type = pointed_type(type);
5048 elem_size = type_size(type, &align);
5049 c += index * elem_size;
5050 /* NOTE: we only support ranges for last designator */
5051 nb_elems = index_last - index + 1;
5052 if (nb_elems != 1) {
5053 notfirst = 1;
5054 break;
5056 } else {
5057 next();
5058 l = tok;
5059 next();
5060 struct_field:
5061 if ((type->t & VT_BTYPE) != VT_STRUCT)
5062 expect("struct/union type");
5063 s = type->ref;
5064 l |= SYM_FIELD;
5065 f = s->next;
5066 while (f) {
5067 if (f->v == l)
5068 break;
5069 f = f->next;
5071 if (!f)
5072 expect("field");
5073 if (!notfirst)
5074 *cur_field = f;
5075 /* XXX: fix this mess by using explicit storage field */
5076 type1 = f->type;
5077 type1.t |= (type->t & ~VT_TYPE);
5078 type = &type1;
5079 c += f->c;
5081 notfirst = 1;
5083 if (notfirst) {
5084 if (tok == '=') {
5085 next();
5086 } else {
5087 if (!gnu_ext)
5088 expect("=");
5090 } else {
5091 if (type->t & VT_ARRAY) {
5092 index = *cur_index;
5093 type = pointed_type(type);
5094 c += index * type_size(type, &align);
5095 } else {
5096 f = *cur_field;
5097 if (!f)
5098 tcc_error("too many field init");
5099 /* XXX: fix this mess by using explicit storage field */
5100 type1 = f->type;
5101 type1.t |= (type->t & ~VT_TYPE);
5102 type = &type1;
5103 c += f->c;
5106 decl_initializer(type, sec, c, 0, size_only);
5108 /* XXX: make it more general */
5109 if (!size_only && nb_elems > 1) {
5110 unsigned long c_end;
5111 uint8_t *src, *dst;
5112 int i;
5114 if (!sec)
5115 tcc_error("range init not supported yet for dynamic storage");
5116 c_end = c + nb_elems * elem_size;
5117 if (c_end > sec->data_allocated)
5118 section_realloc(sec, c_end);
5119 src = sec->data + c;
5120 dst = src;
5121 for(i = 1; i < nb_elems; i++) {
5122 dst += elem_size;
5123 memcpy(dst, src, elem_size);
5128 #define EXPR_VAL 0
5129 #define EXPR_CONST 1
5130 #define EXPR_ANY 2
5132 /* store a value or an expression directly in global data or in local array */
5133 static void init_putv(CType *type, Section *sec, unsigned long c,
5134 int v, int expr_type)
5136 int saved_global_expr, bt, bit_pos, bit_size;
5137 void *ptr;
5138 unsigned long long bit_mask;
5139 CType dtype;
5141 switch(expr_type) {
5142 case EXPR_VAL:
5143 vpushi(v);
5144 break;
5145 case EXPR_CONST:
5146 /* compound literals must be allocated globally in this case */
5147 saved_global_expr = global_expr;
5148 global_expr = 1;
5149 expr_const1();
5150 global_expr = saved_global_expr;
5151 /* NOTE: symbols are accepted */
5152 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5153 tcc_error("initializer element is not constant");
5154 break;
5155 case EXPR_ANY:
5156 expr_eq();
5157 break;
5160 dtype = *type;
5161 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5163 if (sec) {
5164 /* XXX: not portable */
5165 /* XXX: generate error if incorrect relocation */
5166 gen_assign_cast(&dtype);
5167 bt = type->t & VT_BTYPE;
5168 /* we'll write at most 12 bytes */
5169 if (c + 12 > sec->data_allocated) {
5170 section_realloc(sec, c + 12);
5172 ptr = sec->data + c;
5173 /* XXX: make code faster ? */
5174 if (!(type->t & VT_BITFIELD)) {
5175 bit_pos = 0;
5176 bit_size = 32;
5177 bit_mask = -1LL;
5178 } else {
5179 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5180 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5181 bit_mask = (1LL << bit_size) - 1;
5183 if ((vtop->r & VT_SYM) &&
5184 (bt == VT_BYTE ||
5185 bt == VT_SHORT ||
5186 bt == VT_DOUBLE ||
5187 bt == VT_LDOUBLE ||
5188 bt == VT_LLONG ||
5189 (bt == VT_INT && bit_size != 32)))
5190 tcc_error("initializer element is not computable at load time");
5191 switch(bt) {
5192 case VT_BOOL:
5193 vtop->c.i = (vtop->c.i != 0);
5194 case VT_BYTE:
5195 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5196 break;
5197 case VT_SHORT:
5198 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5199 break;
5200 case VT_DOUBLE:
5201 *(double *)ptr = vtop->c.d;
5202 break;
5203 case VT_LDOUBLE:
5204 *(long double *)ptr = vtop->c.ld;
5205 break;
5206 case VT_LLONG:
5207 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
5208 break;
5209 case VT_PTR:
5210 if (vtop->r & VT_SYM) {
5211 greloc(sec, vtop->sym, c, R_DATA_PTR);
5213 *(addr_t *)ptr |= (vtop->c.ptr_offset & bit_mask) << bit_pos;
5214 break;
5215 default:
5216 if (vtop->r & VT_SYM) {
5217 greloc(sec, vtop->sym, c, R_DATA_PTR);
5219 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5220 break;
5222 vtop--;
5223 } else {
5224 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5225 vswap();
5226 vstore();
5227 vpop();
5231 /* put zeros for variable based init */
5232 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5234 if (sec) {
5235 /* nothing to do because globals are already set to zero */
5236 } else {
5237 vpush_global_sym(&func_old_type, TOK_memset);
5238 vseti(VT_LOCAL, c);
5239 #ifdef TCC_TARGET_ARM
5240 vpushs(size);
5241 vpushi(0);
5242 #else
5243 vpushi(0);
5244 vpushs(size);
5245 #endif
5246 gfunc_call(3);
5250 /* 't' contains the type and storage info. 'c' is the offset of the
5251 object in section 'sec'. If 'sec' is NULL, it means stack based
5252 allocation. 'first' is true if array '{' must be read (multi
5253 dimension implicit array init handling). 'size_only' is true if
5254 size only evaluation is wanted (only for arrays). */
5255 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5256 int first, int size_only)
5258 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5259 int size1, align1, expr_type;
5260 Sym *s, *f;
5261 CType *t1;
5263 if (type->t & VT_VLA) {
5264 int a;
5266 /* save current stack pointer */
5267 if (vla_flags & VLA_NEED_NEW_FRAME) {
5268 vla_sp_save();
5269 vla_flags = VLA_IN_SCOPE;
5270 vla_sp_loc = &vla_sp_loc_tmp;
5273 vla_runtime_type_size(type, &a);
5274 gen_vla_alloc(type, a);
5275 vset(type, VT_LOCAL|VT_LVAL, c);
5276 vswap();
5277 vstore();
5278 vpop();
5279 } else if (type->t & VT_ARRAY) {
5280 s = type->ref;
5281 n = s->c;
5282 array_length = 0;
5283 t1 = pointed_type(type);
5284 size1 = type_size(t1, &align1);
5286 no_oblock = 1;
5287 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5288 tok == '{') {
5289 if (tok != '{')
5290 tcc_error("character array initializer must be a literal,"
5291 " optionally enclosed in braces");
5292 skip('{');
5293 no_oblock = 0;
5296 /* only parse strings here if correct type (otherwise: handle
5297 them as ((w)char *) expressions */
5298 if ((tok == TOK_LSTR &&
5299 #ifdef TCC_TARGET_PE
5300 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5301 #else
5302 (t1->t & VT_BTYPE) == VT_INT
5303 #endif
5304 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5305 while (tok == TOK_STR || tok == TOK_LSTR) {
5306 int cstr_len, ch;
5307 CString *cstr;
5309 cstr = tokc.cstr;
5310 /* compute maximum number of chars wanted */
5311 if (tok == TOK_STR)
5312 cstr_len = cstr->size;
5313 else
5314 cstr_len = cstr->size / sizeof(nwchar_t);
5315 cstr_len--;
5316 nb = cstr_len;
5317 if (n >= 0 && nb > (n - array_length))
5318 nb = n - array_length;
5319 if (!size_only) {
5320 if (cstr_len > nb)
5321 tcc_warning("initializer-string for array is too long");
5322 /* in order to go faster for common case (char
5323 string in global variable, we handle it
5324 specifically */
5325 if (sec && tok == TOK_STR && size1 == 1) {
5326 memcpy(sec->data + c + array_length, cstr->data, nb);
5327 } else {
5328 for(i=0;i<nb;i++) {
5329 if (tok == TOK_STR)
5330 ch = ((unsigned char *)cstr->data)[i];
5331 else
5332 ch = ((nwchar_t *)cstr->data)[i];
5333 init_putv(t1, sec, c + (array_length + i) * size1,
5334 ch, EXPR_VAL);
5338 array_length += nb;
5339 next();
5341 /* only add trailing zero if enough storage (no
5342 warning in this case since it is standard) */
5343 if (n < 0 || array_length < n) {
5344 if (!size_only) {
5345 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5347 array_length++;
5349 } else {
5350 index = 0;
5351 while (tok != '}') {
5352 decl_designator(type, sec, c, &index, NULL, size_only);
5353 if (n >= 0 && index >= n)
5354 tcc_error("index too large");
5355 /* must put zero in holes (note that doing it that way
5356 ensures that it even works with designators) */
5357 if (!size_only && array_length < index) {
5358 init_putz(t1, sec, c + array_length * size1,
5359 (index - array_length) * size1);
5361 index++;
5362 if (index > array_length)
5363 array_length = index;
5364 /* special test for multi dimensional arrays (may not
5365 be strictly correct if designators are used at the
5366 same time) */
5367 if (index >= n && no_oblock)
5368 break;
5369 if (tok == '}')
5370 break;
5371 skip(',');
5374 if (!no_oblock)
5375 skip('}');
5376 /* put zeros at the end */
5377 if (!size_only && n >= 0 && array_length < n) {
5378 init_putz(t1, sec, c + array_length * size1,
5379 (n - array_length) * size1);
5381 /* patch type size if needed */
5382 if (n < 0)
5383 s->c = array_length;
5384 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5385 (sec || !first || tok == '{')) {
5386 int par_count;
5388 /* NOTE: the previous test is a specific case for automatic
5389 struct/union init */
5390 /* XXX: union needs only one init */
5392 /* XXX: this test is incorrect for local initializers
5393 beginning with ( without {. It would be much more difficult
5394 to do it correctly (ideally, the expression parser should
5395 be used in all cases) */
5396 par_count = 0;
5397 if (tok == '(') {
5398 AttributeDef ad1;
5399 CType type1;
5400 next();
5401 while (tok == '(') {
5402 par_count++;
5403 next();
5405 if (!parse_btype(&type1, &ad1))
5406 expect("cast");
5407 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5408 #if 0
5409 if (!is_assignable_types(type, &type1))
5410 tcc_error("invalid type for cast");
5411 #endif
5412 skip(')');
5414 no_oblock = 1;
5415 if (first || tok == '{') {
5416 skip('{');
5417 no_oblock = 0;
5419 s = type->ref;
5420 f = s->next;
5421 array_length = 0;
5422 index = 0;
5423 n = s->c;
5424 while (tok != '}') {
5425 decl_designator(type, sec, c, NULL, &f, size_only);
5426 index = f->c;
5427 if (!size_only && array_length < index) {
5428 init_putz(type, sec, c + array_length,
5429 index - array_length);
5431 index = index + type_size(&f->type, &align1);
5432 if (index > array_length)
5433 array_length = index;
5435 /* gr: skip fields from same union - ugly. */
5436 while (f->next) {
5437 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5438 /* test for same offset */
5439 if (f->next->c != f->c)
5440 break;
5441 /* if yes, test for bitfield shift */
5442 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5443 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5444 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5445 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5446 if (bit_pos_1 != bit_pos_2)
5447 break;
5449 f = f->next;
5452 f = f->next;
5453 if (no_oblock && f == NULL)
5454 break;
5455 if (tok == '}')
5456 break;
5457 skip(',');
5459 /* put zeros at the end */
5460 if (!size_only && array_length < n) {
5461 init_putz(type, sec, c + array_length,
5462 n - array_length);
5464 if (!no_oblock)
5465 skip('}');
5466 while (par_count) {
5467 skip(')');
5468 par_count--;
5470 } else if (tok == '{') {
5471 next();
5472 decl_initializer(type, sec, c, first, size_only);
5473 skip('}');
5474 } else if (size_only) {
5475 /* just skip expression */
5476 parlevel = parlevel1 = 0;
5477 while ((parlevel > 0 || parlevel1 > 0 ||
5478 (tok != '}' && tok != ',')) && tok != -1) {
5479 if (tok == '(')
5480 parlevel++;
5481 else if (tok == ')')
5482 parlevel--;
5483 else if (tok == '{')
5484 parlevel1++;
5485 else if (tok == '}')
5486 parlevel1--;
5487 next();
5489 } else {
5490 /* currently, we always use constant expression for globals
5491 (may change for scripting case) */
5492 expr_type = EXPR_CONST;
5493 if (!sec)
5494 expr_type = EXPR_ANY;
5495 init_putv(type, sec, c, 0, expr_type);
5499 /* parse an initializer for type 't' if 'has_init' is non zero, and
5500 allocate space in local or global data space ('r' is either
5501 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5502 variable 'v' with an associated name represented by 'asm_label' of
5503 scope 'scope' is declared before initializers are parsed. If 'v' is
5504 zero, then a reference to the new object is put in the value stack.
5505 If 'has_init' is 2, a special parsing is done to handle string
5506 constants. */
5507 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5508 int has_init, int v, char *asm_label,
5509 int scope)
5511 int size, align, addr, data_offset;
5512 int level;
5513 ParseState saved_parse_state = {0};
5514 TokenString init_str;
5515 Section *sec;
5516 Sym *flexible_array;
5518 flexible_array = NULL;
5519 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5520 Sym *field = type->ref->next;
5521 if (field) {
5522 while (field->next)
5523 field = field->next;
5524 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5525 flexible_array = field;
5529 size = type_size(type, &align);
5530 /* If unknown size, we must evaluate it before
5531 evaluating initializers because
5532 initializers can generate global data too
5533 (e.g. string pointers or ISOC99 compound
5534 literals). It also simplifies local
5535 initializers handling */
5536 tok_str_new(&init_str);
5537 if (size < 0 || (flexible_array && has_init)) {
5538 if (!has_init)
5539 tcc_error("unknown type size");
5540 /* get all init string */
5541 if (has_init == 2) {
5542 /* only get strings */
5543 while (tok == TOK_STR || tok == TOK_LSTR) {
5544 tok_str_add_tok(&init_str);
5545 next();
5547 } else {
5548 level = 0;
5549 while (level > 0 || (tok != ',' && tok != ';')) {
5550 if (tok < 0)
5551 tcc_error("unexpected end of file in initializer");
5552 tok_str_add_tok(&init_str);
5553 if (tok == '{')
5554 level++;
5555 else if (tok == '}') {
5556 level--;
5557 if (level <= 0) {
5558 next();
5559 break;
5562 next();
5565 tok_str_add(&init_str, -1);
5566 tok_str_add(&init_str, 0);
5568 /* compute size */
5569 save_parse_state(&saved_parse_state);
5571 macro_ptr = init_str.str;
5572 next();
5573 decl_initializer(type, NULL, 0, 1, 1);
5574 /* prepare second initializer parsing */
5575 macro_ptr = init_str.str;
5576 next();
5578 /* if still unknown size, error */
5579 size = type_size(type, &align);
5580 if (size < 0)
5581 tcc_error("unknown type size");
5583 if (flexible_array)
5584 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5585 /* take into account specified alignment if bigger */
5586 if (ad->a.aligned) {
5587 if (ad->a.aligned > align)
5588 align = ad->a.aligned;
5589 } else if (ad->a.packed) {
5590 align = 1;
5592 if ((r & VT_VALMASK) == VT_LOCAL) {
5593 sec = NULL;
5594 #ifdef CONFIG_TCC_BCHECK
5595 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5596 loc--;
5598 #endif
5599 loc = (loc - size) & -align;
5600 addr = loc;
5601 #ifdef CONFIG_TCC_BCHECK
5602 /* handles bounds */
5603 /* XXX: currently, since we do only one pass, we cannot track
5604 '&' operators, so we add only arrays */
5605 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5606 unsigned long *bounds_ptr;
5607 /* add padding between regions */
5608 loc--;
5609 /* then add local bound info */
5610 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5611 bounds_ptr[0] = addr;
5612 bounds_ptr[1] = size;
5614 #endif
5615 if (v) {
5616 /* local variable */
5617 sym_push(v, type, r, addr);
5618 } else {
5619 /* push local reference */
5620 vset(type, r, addr);
5622 } else {
5623 Sym *sym;
5625 sym = NULL;
5626 if (v && scope == VT_CONST) {
5627 /* see if the symbol was already defined */
5628 sym = sym_find(v);
5629 if (sym) {
5630 if (!is_compatible_types(&sym->type, type))
5631 tcc_error("incompatible types for redefinition of '%s'",
5632 get_tok_str(v, NULL));
5633 if (sym->type.t & VT_EXTERN) {
5634 /* if the variable is extern, it was not allocated */
5635 sym->type.t &= ~VT_EXTERN;
5636 /* set array size if it was omitted in extern
5637 declaration */
5638 if ((sym->type.t & VT_ARRAY) &&
5639 sym->type.ref->c < 0 &&
5640 type->ref->c >= 0)
5641 sym->type.ref->c = type->ref->c;
5642 } else {
5643 /* we accept several definitions of the same
5644 global variable. this is tricky, because we
5645 must play with the SHN_COMMON type of the symbol */
5646 /* XXX: should check if the variable was already
5647 initialized. It is incorrect to initialized it
5648 twice */
5649 /* no init data, we won't add more to the symbol */
5650 if (!has_init)
5651 goto no_alloc;
5656 /* allocate symbol in corresponding section */
5657 sec = ad->section;
5658 if (!sec) {
5659 if (has_init)
5660 sec = data_section;
5661 else if (tcc_state->nocommon)
5662 sec = bss_section;
5664 if (sec) {
5665 data_offset = sec->data_offset;
5666 data_offset = (data_offset + align - 1) & -align;
5667 addr = data_offset;
5668 /* very important to increment global pointer at this time
5669 because initializers themselves can create new initializers */
5670 data_offset += size;
5671 #ifdef CONFIG_TCC_BCHECK
5672 /* add padding if bound check */
5673 if (tcc_state->do_bounds_check)
5674 data_offset++;
5675 #endif
5676 sec->data_offset = data_offset;
5677 /* allocate section space to put the data */
5678 if (sec->sh_type != SHT_NOBITS &&
5679 data_offset > sec->data_allocated)
5680 section_realloc(sec, data_offset);
5681 /* align section if needed */
5682 if (align > sec->sh_addralign)
5683 sec->sh_addralign = align;
5684 } else {
5685 addr = 0; /* avoid warning */
5688 if (v) {
5689 if (scope != VT_CONST || !sym) {
5690 sym = sym_push(v, type, r | VT_SYM, 0);
5691 sym->asm_label = asm_label;
5693 /* update symbol definition */
5694 if (sec) {
5695 put_extern_sym(sym, sec, addr, size);
5696 } else {
5697 ElfW(Sym) *esym;
5698 /* put a common area */
5699 put_extern_sym(sym, NULL, align, size);
5700 /* XXX: find a nicer way */
5701 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5702 esym->st_shndx = SHN_COMMON;
5704 } else {
5705 /* push global reference */
5706 sym = get_sym_ref(type, sec, addr, size);
5707 vpushsym(type, sym);
5709 /* patch symbol weakness */
5710 if (type->t & VT_WEAK)
5711 weaken_symbol(sym);
5712 apply_visibility(sym, type);
5713 #ifdef CONFIG_TCC_BCHECK
5714 /* handles bounds now because the symbol must be defined
5715 before for the relocation */
5716 if (tcc_state->do_bounds_check) {
5717 unsigned long *bounds_ptr;
5719 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5720 /* then add global bound info */
5721 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5722 bounds_ptr[0] = 0; /* relocated */
5723 bounds_ptr[1] = size;
5725 #endif
5727 if (has_init || (type->t & VT_VLA)) {
5728 decl_initializer(type, sec, addr, 1, 0);
5729 /* restore parse state if needed */
5730 if (init_str.str) {
5731 tok_str_free(init_str.str);
5732 restore_parse_state(&saved_parse_state);
5734 /* patch flexible array member size back to -1, */
5735 /* for possible subsequent similar declarations */
5736 if (flexible_array)
5737 flexible_array->type.ref->c = -1;
5739 no_alloc: ;
5742 static void put_func_debug(Sym *sym)
5744 char buf[512];
5746 /* stabs info */
5747 /* XXX: we put here a dummy type */
5748 snprintf(buf, sizeof(buf), "%s:%c1",
5749 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5750 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5751 cur_text_section, sym->c);
5752 /* //gr gdb wants a line at the function */
5753 put_stabn(N_SLINE, 0, file->line_num, 0);
5754 last_ind = 0;
5755 last_line_num = 0;
5758 /* parse an old style function declaration list */
5759 /* XXX: check multiple parameter */
5760 static void func_decl_list(Sym *func_sym)
5762 AttributeDef ad;
5763 int v;
5764 Sym *s;
5765 CType btype, type;
5767 /* parse each declaration */
5768 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5769 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5770 if (!parse_btype(&btype, &ad))
5771 expect("declaration list");
5772 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5773 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5774 tok == ';') {
5775 /* we accept no variable after */
5776 } else {
5777 for(;;) {
5778 type = btype;
5779 type_decl(&type, &ad, &v, TYPE_DIRECT);
5780 /* find parameter in function parameter list */
5781 s = func_sym->next;
5782 while (s != NULL) {
5783 if ((s->v & ~SYM_FIELD) == v)
5784 goto found;
5785 s = s->next;
5787 tcc_error("declaration for parameter '%s' but no such parameter",
5788 get_tok_str(v, NULL));
5789 found:
5790 /* check that no storage specifier except 'register' was given */
5791 if (type.t & VT_STORAGE)
5792 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5793 convert_parameter_type(&type);
5794 /* we can add the type (NOTE: it could be local to the function) */
5795 s->type = type;
5796 /* accept other parameters */
5797 if (tok == ',')
5798 next();
5799 else
5800 break;
5803 skip(';');
5807 /* parse a function defined by symbol 'sym' and generate its code in
5808 'cur_text_section' */
5809 static void gen_function(Sym *sym)
5811 int saved_nocode_wanted = nocode_wanted;
5812 nocode_wanted = 0;
5813 ind = cur_text_section->data_offset;
5814 /* NOTE: we patch the symbol size later */
5815 put_extern_sym(sym, cur_text_section, ind, 0);
5816 funcname = get_tok_str(sym->v, NULL);
5817 func_ind = ind;
5818 /* Initialize VLA state */
5819 vla_sp_loc = &vla_sp_root_loc;
5820 vla_flags = VLA_NEED_NEW_FRAME;
5821 /* put debug symbol */
5822 if (tcc_state->do_debug)
5823 put_func_debug(sym);
5824 /* push a dummy symbol to enable local sym storage */
5825 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5826 gfunc_prolog(&sym->type);
5827 #ifdef CONFIG_TCC_BCHECK
5828 if (tcc_state->do_bounds_check
5829 && !strcmp(get_tok_str(sym->v, NULL), "main")) {
5830 int i;
5832 sym = local_stack;
5833 for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) {
5834 if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD)
5835 break;
5836 vpush_global_sym(&func_old_type, TOK___bound_main_arg);
5837 vset(&sym->type, sym->r, sym->c);
5838 gfunc_call(1);
5841 #endif
5842 rsym = 0;
5843 block(NULL, NULL, NULL, NULL, 0, 0);
5844 gsym(rsym);
5845 gfunc_epilog();
5846 cur_text_section->data_offset = ind;
5847 label_pop(&global_label_stack, NULL);
5848 /* reset local stack */
5849 scope_stack_bottom = NULL;
5850 sym_pop(&local_stack, NULL);
5851 /* end of function */
5852 /* patch symbol size */
5853 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5854 ind - func_ind;
5855 /* patch symbol weakness (this definition overrules any prototype) */
5856 if (sym->type.t & VT_WEAK)
5857 weaken_symbol(sym);
5858 apply_visibility(sym, &sym->type);
5859 if (tcc_state->do_debug) {
5860 put_stabn(N_FUN, 0, 0, ind - func_ind);
5862 /* It's better to crash than to generate wrong code */
5863 cur_text_section = NULL;
5864 funcname = ""; /* for safety */
5865 func_vt.t = VT_VOID; /* for safety */
5866 func_var = 0; /* for safety */
5867 ind = 0; /* for safety */
5868 nocode_wanted = saved_nocode_wanted;
5871 ST_FUNC void gen_inline_functions(void)
5873 Sym *sym;
5874 int *str, inline_generated, i;
5875 struct InlineFunc *fn;
5877 /* iterate while inline function are referenced */
5878 for(;;) {
5879 inline_generated = 0;
5880 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5881 fn = tcc_state->inline_fns[i];
5882 sym = fn->sym;
5883 if (sym && sym->c) {
5884 /* the function was used: generate its code and
5885 convert it to a normal function */
5886 str = fn->token_str;
5887 fn->sym = NULL;
5888 if (file)
5889 pstrcpy(file->filename, sizeof file->filename, fn->filename);
5890 sym->r = VT_SYM | VT_CONST;
5891 sym->type.t &= ~VT_INLINE;
5893 macro_ptr = str;
5894 next();
5895 cur_text_section = text_section;
5896 gen_function(sym);
5897 macro_ptr = NULL; /* fail safe */
5899 inline_generated = 1;
5902 if (!inline_generated)
5903 break;
5905 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5906 fn = tcc_state->inline_fns[i];
5907 str = fn->token_str;
5908 tok_str_free(str);
5910 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5913 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5914 static int decl0(int l, int is_for_loop_init)
5916 int v, has_init, r;
5917 CType type, btype;
5918 Sym *sym;
5919 AttributeDef ad;
5921 while (1) {
5922 if (!parse_btype(&btype, &ad)) {
5923 if (is_for_loop_init)
5924 return 0;
5925 /* skip redundant ';' */
5926 /* XXX: find more elegant solution */
5927 if (tok == ';') {
5928 next();
5929 continue;
5931 if (l == VT_CONST &&
5932 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5933 /* global asm block */
5934 asm_global_instr();
5935 continue;
5937 /* special test for old K&R protos without explicit int
5938 type. Only accepted when defining global data */
5939 if (l == VT_LOCAL || tok < TOK_DEFINE)
5940 break;
5941 btype.t = VT_INT;
5943 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5944 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5945 tok == ';') {
5946 /* we accept no variable after */
5947 next();
5948 continue;
5950 while (1) { /* iterate thru each declaration */
5951 char *asm_label; // associated asm label
5952 type = btype;
5953 type_decl(&type, &ad, &v, TYPE_DIRECT);
5954 #if 0
5956 char buf[500];
5957 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5958 printf("type = '%s'\n", buf);
5960 #endif
5961 if ((type.t & VT_BTYPE) == VT_FUNC) {
5962 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5963 tcc_error("function without file scope cannot be static");
5965 /* if old style function prototype, we accept a
5966 declaration list */
5967 sym = type.ref;
5968 if (sym->c == FUNC_OLD)
5969 func_decl_list(sym);
5972 asm_label = NULL;
5973 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5974 CString astr;
5976 asm_label_instr(&astr);
5977 asm_label = tcc_strdup(astr.data);
5978 cstr_free(&astr);
5980 /* parse one last attribute list, after asm label */
5981 parse_attribute(&ad);
5984 if (ad.a.weak)
5985 type.t |= VT_WEAK;
5986 #ifdef TCC_TARGET_PE
5987 if (ad.a.func_import)
5988 type.t |= VT_IMPORT;
5989 if (ad.a.func_export)
5990 type.t |= VT_EXPORT;
5991 #endif
5992 type.t |= ad.a.visibility << VT_VIS_SHIFT;
5994 if (tok == '{') {
5995 if (l == VT_LOCAL)
5996 tcc_error("cannot use local functions");
5997 if ((type.t & VT_BTYPE) != VT_FUNC)
5998 expect("function definition");
6000 /* reject abstract declarators in function definition */
6001 sym = type.ref;
6002 while ((sym = sym->next) != NULL)
6003 if (!(sym->v & ~SYM_FIELD))
6004 expect("identifier");
6006 /* XXX: cannot do better now: convert extern line to static inline */
6007 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6008 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6010 sym = sym_find(v);
6011 if (sym) {
6012 Sym *ref;
6013 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6014 goto func_error1;
6016 ref = sym->type.ref;
6017 if (0 == ref->a.func_proto)
6018 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6020 /* use func_call from prototype if not defined */
6021 if (ref->a.func_call != FUNC_CDECL
6022 && type.ref->a.func_call == FUNC_CDECL)
6023 type.ref->a.func_call = ref->a.func_call;
6025 /* use export from prototype */
6026 if (ref->a.func_export)
6027 type.ref->a.func_export = 1;
6029 /* use static from prototype */
6030 if (sym->type.t & VT_STATIC)
6031 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6033 /* If the definition has no visibility use the
6034 one from prototype. */
6035 if (! (type.t & VT_VIS_MASK))
6036 type.t |= sym->type.t & VT_VIS_MASK;
6038 if (!is_compatible_types(&sym->type, &type)) {
6039 func_error1:
6040 tcc_error("incompatible types for redefinition of '%s'",
6041 get_tok_str(v, NULL));
6043 type.ref->a.func_proto = 0;
6044 /* if symbol is already defined, then put complete type */
6045 sym->type = type;
6046 } else {
6047 /* put function symbol */
6048 sym = global_identifier_push(v, type.t, 0);
6049 sym->type.ref = type.ref;
6052 /* static inline functions are just recorded as a kind
6053 of macro. Their code will be emitted at the end of
6054 the compilation unit only if they are used */
6055 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6056 (VT_INLINE | VT_STATIC)) {
6057 TokenString func_str;
6058 int block_level;
6059 struct InlineFunc *fn;
6060 const char *filename;
6062 tok_str_new(&func_str);
6064 block_level = 0;
6065 for(;;) {
6066 int t;
6067 if (tok == TOK_EOF)
6068 tcc_error("unexpected end of file");
6069 tok_str_add_tok(&func_str);
6070 t = tok;
6071 next();
6072 if (t == '{') {
6073 block_level++;
6074 } else if (t == '}') {
6075 block_level--;
6076 if (block_level == 0)
6077 break;
6080 tok_str_add(&func_str, -1);
6081 tok_str_add(&func_str, 0);
6082 filename = file ? file->filename : "";
6083 fn = tcc_malloc(sizeof *fn + strlen(filename));
6084 strcpy(fn->filename, filename);
6085 fn->sym = sym;
6086 fn->token_str = func_str.str;
6087 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6089 } else {
6090 /* compute text section */
6091 cur_text_section = ad.section;
6092 if (!cur_text_section)
6093 cur_text_section = text_section;
6094 sym->r = VT_SYM | VT_CONST;
6095 gen_function(sym);
6097 break;
6098 } else {
6099 if (btype.t & VT_TYPEDEF) {
6100 /* save typedefed type */
6101 /* XXX: test storage specifiers ? */
6102 sym = sym_push(v, &type, 0, 0);
6103 sym->a = ad.a;
6104 sym->type.t |= VT_TYPEDEF;
6105 } else {
6106 r = 0;
6107 if ((type.t & VT_BTYPE) == VT_FUNC) {
6108 /* external function definition */
6109 /* specific case for func_call attribute */
6110 ad.a.func_proto = 1;
6111 type.ref->a = ad.a;
6112 } else if (!(type.t & VT_ARRAY)) {
6113 /* not lvalue if array */
6114 r |= lvalue_type(type.t);
6116 has_init = (tok == '=');
6117 if (has_init && (type.t & VT_VLA))
6118 tcc_error("Variable length array cannot be initialized");
6119 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6120 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6121 !has_init && l == VT_CONST && type.ref->c < 0)) {
6122 /* external variable or function */
6123 /* NOTE: as GCC, uninitialized global static
6124 arrays of null size are considered as
6125 extern */
6126 sym = external_sym(v, &type, r, asm_label);
6128 if (ad.alias_target) {
6129 Section tsec;
6130 Elf32_Sym *esym;
6131 Sym *alias_target;
6133 alias_target = sym_find(ad.alias_target);
6134 if (!alias_target || !alias_target->c)
6135 tcc_error("unsupported forward __alias__ attribute");
6136 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6137 tsec.sh_num = esym->st_shndx;
6138 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6140 } else {
6141 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6142 if (type.t & VT_STATIC)
6143 r |= VT_CONST;
6144 else
6145 r |= l;
6146 if (has_init)
6147 next();
6148 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
6151 if (tok != ',') {
6152 if (is_for_loop_init)
6153 return 1;
6154 skip(';');
6155 break;
6157 next();
6159 ad.a.aligned = 0;
6162 return 0;
6165 ST_FUNC void decl(int l)
6167 decl0(l, 0);