Add predictability in CType initialization.
[tinycc.git] / tccgen.c
blob51ac0b15c6571d595aa36dbe598988ceaa8f5866
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 SValue __vstack[1+VSTACK_SIZE], *vtop;
60 ST_DATA int const_wanted; /* true if constant wanted */
61 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
62 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
63 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
64 ST_DATA int func_vc;
65 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
66 ST_DATA char *funcname;
68 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
70 /* ------------------------------------------------------------------------- */
71 static void gen_cast(CType *type);
72 static inline CType *pointed_type(CType *type);
73 static int is_compatible_types(CType *type1, CType *type2);
74 static int parse_btype(CType *type, AttributeDef *ad);
75 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
76 static void parse_expr_type(CType *type);
77 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
78 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
79 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
80 static int decl0(int l, int is_for_loop_init);
81 static void expr_eq(void);
82 static void unary_type(CType *type);
83 static void vla_runtime_type_size(CType *type, int *a);
84 static int is_compatible_parameter_types(CType *type1, CType *type2);
85 static void expr_type(CType *type);
87 ST_INLN int is_float(int t)
89 int bt;
90 bt = t & VT_BTYPE;
91 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
94 /* we use our own 'finite' function to avoid potential problems with
95 non standard math libs */
96 /* XXX: endianness dependent */
97 ST_FUNC int ieee_finite(double d)
99 int *p = (int *)&d;
100 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
103 ST_FUNC void test_lvalue(void)
105 if (!(vtop->r & VT_LVAL))
106 expect("lvalue");
109 /* ------------------------------------------------------------------------- */
110 /* symbol allocator */
111 static Sym *__sym_malloc(void)
113 Sym *sym_pool, *sym, *last_sym;
114 int i;
116 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
117 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
119 last_sym = sym_free_first;
120 sym = sym_pool;
121 for(i = 0; i < SYM_POOL_NB; i++) {
122 sym->next = last_sym;
123 last_sym = sym;
124 sym++;
126 sym_free_first = last_sym;
127 return last_sym;
130 static inline Sym *sym_malloc(void)
132 Sym *sym;
133 sym = sym_free_first;
134 if (!sym)
135 sym = __sym_malloc();
136 sym_free_first = sym->next;
137 return sym;
140 ST_INLN void sym_free(Sym *sym)
142 sym->next = sym_free_first;
143 tcc_free(sym->asm_label);
144 sym_free_first = sym;
147 /* push, without hashing */
148 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
150 Sym *s;
151 if (ps == &local_stack) {
152 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
153 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
154 tcc_error("incompatible types for redefinition of '%s'",
155 get_tok_str(v, NULL));
157 s = *ps;
158 s = sym_malloc();
159 s->asm_label = NULL;
160 s->v = v;
161 s->type.t = t;
162 s->type.ref = NULL;
163 #ifdef _WIN64
164 s->d = NULL;
165 #endif
166 s->c = c;
167 s->next = NULL;
168 /* add in stack */
169 s->prev = *ps;
170 *ps = s;
171 return s;
174 /* find a symbol and return its associated structure. 's' is the top
175 of the symbol stack */
176 ST_FUNC Sym *sym_find2(Sym *s, int v)
178 while (s) {
179 if (s->v == v)
180 return s;
181 s = s->prev;
183 return NULL;
186 /* structure lookup */
187 ST_INLN Sym *struct_find(int v)
189 v -= TOK_IDENT;
190 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
191 return NULL;
192 return table_ident[v]->sym_struct;
195 /* find an identifier */
196 ST_INLN Sym *sym_find(int v)
198 v -= TOK_IDENT;
199 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
200 return NULL;
201 return table_ident[v]->sym_identifier;
204 /* push a given symbol on the symbol stack */
205 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
207 Sym *s, **ps;
208 TokenSym *ts;
210 if (local_stack)
211 ps = &local_stack;
212 else
213 ps = &global_stack;
214 s = sym_push2(ps, v, type->t, c);
215 s->type.ref = type->ref;
216 s->r = r;
217 /* don't record fields or anonymous symbols */
218 /* XXX: simplify */
219 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
220 /* record symbol in token array */
221 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
222 if (v & SYM_STRUCT)
223 ps = &ts->sym_struct;
224 else
225 ps = &ts->sym_identifier;
226 s->prev_tok = *ps;
227 *ps = s;
229 return s;
232 /* push a global identifier */
233 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
235 Sym *s, **ps;
236 s = sym_push2(&global_stack, v, t, c);
237 /* don't record anonymous symbol */
238 if (v < SYM_FIRST_ANOM) {
239 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
240 /* modify the top most local identifier, so that
241 sym_identifier will point to 's' when popped */
242 while (*ps != NULL)
243 ps = &(*ps)->prev_tok;
244 s->prev_tok = NULL;
245 *ps = s;
247 return s;
250 /* pop symbols until top reaches 'b' */
251 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
253 Sym *s, *ss, **ps;
254 TokenSym *ts;
255 int v;
257 s = *ptop;
258 while(s != b) {
259 ss = s->prev;
260 v = s->v;
261 /* remove symbol in token array */
262 /* XXX: simplify */
263 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
264 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
265 if (v & SYM_STRUCT)
266 ps = &ts->sym_struct;
267 else
268 ps = &ts->sym_identifier;
269 *ps = s->prev_tok;
271 sym_free(s);
272 s = ss;
274 *ptop = b;
277 static void weaken_symbol(Sym *sym)
279 sym->type.t |= VT_WEAK;
280 if (sym->c > 0) {
281 int esym_type;
282 ElfW(Sym) *esym;
284 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
285 esym_type = ELFW(ST_TYPE)(esym->st_info);
286 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
290 /* ------------------------------------------------------------------------- */
292 ST_FUNC void swap(int *p, int *q)
294 int t;
295 t = *p;
296 *p = *q;
297 *q = t;
300 static void vsetc(CType *type, int r, CValue *vc)
302 int v;
304 if (vtop >= vstack + (VSTACK_SIZE - 1))
305 tcc_error("memory full");
306 /* cannot let cpu flags if other instruction are generated. Also
307 avoid leaving VT_JMP anywhere except on the top of the stack
308 because it would complicate the code generator. */
309 if (vtop >= vstack) {
310 v = vtop->r & VT_VALMASK;
311 if (v == VT_CMP || (v & ~1) == VT_JMP)
312 gv(RC_INT);
314 vtop++;
315 vtop->type = *type;
316 vtop->r = r;
317 vtop->r2 = VT_CONST;
318 vtop->c = *vc;
321 /* push constant of type "type" with useless value */
322 void vpush(CType *type)
324 CValue cval;
325 vsetc(type, VT_CONST, &cval);
328 /* push integer constant */
329 ST_FUNC void vpushi(int v)
331 CValue cval;
332 cval.i = v;
333 vsetc(&int_type, VT_CONST, &cval);
336 /* push a pointer sized constant */
337 static void vpushs(long long v)
339 CValue cval;
340 if (PTR_SIZE == 4)
341 cval.i = (int)v;
342 else
343 cval.ull = v;
344 vsetc(&size_type, VT_CONST, &cval);
347 /* push long long constant */
348 static void vpushll(long long v)
350 CValue cval;
351 CType ctype;
352 ctype.t = VT_LLONG;
353 ctype.ref = 0;
354 cval.ull = v;
355 vsetc(&ctype, VT_CONST, &cval);
358 /* push arbitrary 64bit constant */
359 void vpush64(int ty, unsigned long long v)
361 CValue cval;
362 CType ctype;
363 ctype.t = ty;
364 ctype.ref = 0;
365 cval.ull = v;
366 vsetc(&ctype, VT_CONST, &cval);
369 /* Return a static symbol pointing to a section */
370 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
372 int v;
373 Sym *sym;
375 v = anon_sym++;
376 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
377 sym->type.ref = type->ref;
378 sym->r = VT_CONST | VT_SYM;
379 put_extern_sym(sym, sec, offset, size);
380 return sym;
383 /* push a reference to a section offset by adding a dummy symbol */
384 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
386 CValue cval;
388 cval.ul = 0;
389 vsetc(type, VT_CONST | VT_SYM, &cval);
390 vtop->sym = get_sym_ref(type, sec, offset, size);
393 /* define a new external reference to a symbol 'v' of type 'u' */
394 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
396 Sym *s;
398 s = sym_find(v);
399 if (!s) {
400 /* push forward reference */
401 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
402 s->type.ref = type->ref;
403 s->r = r | VT_CONST | VT_SYM;
405 return s;
408 /* define a new external reference to a symbol 'v' with alternate asm
409 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
410 is no alternate name (most cases) */
411 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
413 Sym *s;
415 s = sym_find(v);
416 if (!s) {
417 /* push forward reference */
418 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
419 s->asm_label = asm_label;
420 s->type.t |= VT_EXTERN;
421 } else if (s->type.ref == func_old_type.ref) {
422 s->type.ref = type->ref;
423 s->r = r | VT_CONST | VT_SYM;
424 s->type.t |= VT_EXTERN;
425 } else if (!is_compatible_types(&s->type, type)) {
426 tcc_error("incompatible types for redefinition of '%s'",
427 get_tok_str(v, NULL));
429 return s;
432 /* push a reference to global symbol v */
433 ST_FUNC void vpush_global_sym(CType *type, int v)
435 Sym *sym;
436 CValue cval;
438 sym = external_global_sym(v, type, 0);
439 cval.ul = 0;
440 vsetc(type, VT_CONST | VT_SYM, &cval);
441 vtop->sym = sym;
444 ST_FUNC void vset(CType *type, int r, int v)
446 CValue cval;
448 cval.i = v;
449 vsetc(type, r, &cval);
452 static void vseti(int r, int v)
454 CType type;
455 type.t = VT_INT;
456 type.ref = 0;
457 vset(&type, r, v);
460 ST_FUNC void vswap(void)
462 SValue tmp;
463 /* cannot let cpu flags if other instruction are generated. Also
464 avoid leaving VT_JMP anywhere except on the top of the stack
465 because it would complicate the code generator. */
466 if (vtop >= vstack) {
467 int v = vtop->r & VT_VALMASK;
468 if (v == VT_CMP || (v & ~1) == VT_JMP)
469 gv(RC_INT);
471 tmp = vtop[0];
472 vtop[0] = vtop[-1];
473 vtop[-1] = tmp;
475 /* XXX: +2% overall speed possible with optimized memswap
477 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
481 ST_FUNC void vpushv(SValue *v)
483 if (vtop >= vstack + (VSTACK_SIZE - 1))
484 tcc_error("memory full");
485 vtop++;
486 *vtop = *v;
489 static void vdup(void)
491 vpushv(vtop);
494 /* save r to the memory stack, and mark it as being free */
495 ST_FUNC void save_reg(int r)
497 int l, saved, size, align;
498 SValue *p, sv;
499 CType *type;
501 /* modify all stack values */
502 saved = 0;
503 l = 0;
504 for(p=vstack;p<=vtop;p++) {
505 if ((p->r & VT_VALMASK) == r ||
506 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
507 /* must save value on stack if not already done */
508 if (!saved) {
509 /* NOTE: must reload 'r' because r might be equal to r2 */
510 r = p->r & VT_VALMASK;
511 /* store register in the stack */
512 type = &p->type;
513 if ((p->r & VT_LVAL) ||
514 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
515 #ifdef TCC_TARGET_X86_64
516 type = &char_pointer_type;
517 #else
518 type = &int_type;
519 #endif
520 size = type_size(type, &align);
521 loc = (loc - size) & -align;
522 sv.type.t = type->t;
523 sv.r = VT_LOCAL | VT_LVAL;
524 sv.c.ul = loc;
525 store(r, &sv);
526 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
527 /* x86 specific: need to pop fp register ST0 if saved */
528 if (r == TREG_ST0) {
529 o(0xd8dd); /* fstp %st(0) */
531 #endif
532 #ifndef TCC_TARGET_X86_64
533 /* special long long case */
534 if ((type->t & VT_BTYPE) == VT_LLONG) {
535 sv.c.ul += 4;
536 store(p->r2, &sv);
538 #endif
539 l = loc;
540 saved = 1;
542 /* mark that stack entry as being saved on the stack */
543 if (p->r & VT_LVAL) {
544 /* also clear the bounded flag because the
545 relocation address of the function was stored in
546 p->c.ul */
547 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
548 } else {
549 p->r = lvalue_type(p->type.t) | VT_LOCAL;
551 p->r2 = VT_CONST;
552 p->c.ul = l;
557 #ifdef TCC_TARGET_ARM
558 /* find a register of class 'rc2' with at most one reference on stack.
559 * If none, call get_reg(rc) */
560 ST_FUNC int get_reg_ex(int rc, int rc2)
562 int r;
563 SValue *p;
565 for(r=0;r<NB_REGS;r++) {
566 if (reg_classes[r] & rc2) {
567 int n;
568 n=0;
569 for(p = vstack; p <= vtop; p++) {
570 if ((p->r & VT_VALMASK) == r ||
571 (p->r2 & VT_VALMASK) == r)
572 n++;
574 if (n <= 1)
575 return r;
578 return get_reg(rc);
580 #endif
582 /* find a free register of class 'rc'. If none, save one register */
583 ST_FUNC int get_reg(int rc)
585 int r;
586 SValue *p;
588 /* find a free register */
589 for(r=0;r<NB_REGS;r++) {
590 if (reg_classes[r] & rc) {
591 for(p=vstack;p<=vtop;p++) {
592 if ((p->r & VT_VALMASK) == r ||
593 (p->r2 & VT_VALMASK) == r)
594 goto notfound;
596 return r;
598 notfound: ;
601 /* no register left : free the first one on the stack (VERY
602 IMPORTANT to start from the bottom to ensure that we don't
603 spill registers used in gen_opi()) */
604 for(p=vstack;p<=vtop;p++) {
605 /* look at second register (if long long) */
606 r = p->r2 & VT_VALMASK;
607 if (r < VT_CONST && (reg_classes[r] & rc))
608 goto save_found;
609 r = p->r & VT_VALMASK;
610 if (r < VT_CONST && (reg_classes[r] & rc)) {
611 save_found:
612 save_reg(r);
613 return r;
616 /* Should never comes here */
617 return -1;
620 /* save registers up to (vtop - n) stack entry */
621 ST_FUNC void save_regs(int n)
623 int r;
624 SValue *p, *p1;
625 p1 = vtop - n;
626 for(p = vstack;p <= p1; p++) {
627 r = p->r & VT_VALMASK;
628 if (r < VT_CONST) {
629 save_reg(r);
634 /* move register 's' to 'r', and flush previous value of r to memory
635 if needed */
636 static void move_reg(int r, int s)
638 SValue sv;
640 if (r != s) {
641 save_reg(r);
642 sv.type.t = VT_INT;
643 sv.r = s;
644 sv.c.ul = 0;
645 load(r, &sv);
649 /* get address of vtop (vtop MUST BE an lvalue) */
650 static void gaddrof(void)
652 if (vtop->r & VT_REF)
653 gv(RC_INT);
654 vtop->r &= ~VT_LVAL;
655 /* tricky: if saved lvalue, then we can go back to lvalue */
656 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
657 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
662 #ifdef CONFIG_TCC_BCHECK
663 /* generate lvalue bound code */
664 static void gbound(void)
666 int lval_type;
667 CType type1;
669 vtop->r &= ~VT_MUSTBOUND;
670 /* if lvalue, then use checking code before dereferencing */
671 if (vtop->r & VT_LVAL) {
672 /* if not VT_BOUNDED value, then make one */
673 if (!(vtop->r & VT_BOUNDED)) {
674 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
675 /* must save type because we must set it to int to get pointer */
676 type1 = vtop->type;
677 vtop->type.t = VT_INT;
678 gaddrof();
679 vpushi(0);
680 gen_bounded_ptr_add();
681 vtop->r |= lval_type;
682 vtop->type = type1;
684 /* then check for dereferencing */
685 gen_bounded_ptr_deref();
688 #endif
690 /* store vtop a register belonging to class 'rc'. lvalues are
691 converted to values. Cannot be used if cannot be converted to
692 register value (such as structures). */
693 ST_FUNC int gv(int rc)
695 int r, bit_pos, bit_size, size, align, i;
696 #ifndef TCC_TARGET_X86_64
697 int rc2;
698 #endif
700 /* NOTE: get_reg can modify vstack[] */
701 if (vtop->type.t & VT_BITFIELD) {
702 CType type;
703 int bits = 32;
704 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
705 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
706 /* remove bit field info to avoid loops */
707 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
708 /* cast to int to propagate signedness in following ops */
709 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
710 type.t = VT_LLONG;
711 bits = 64;
712 } else
713 type.t = VT_INT;
714 if((vtop->type.t & VT_UNSIGNED) ||
715 (vtop->type.t & VT_BTYPE) == VT_BOOL)
716 type.t |= VT_UNSIGNED;
717 gen_cast(&type);
718 /* generate shifts */
719 vpushi(bits - (bit_pos + bit_size));
720 gen_op(TOK_SHL);
721 vpushi(bits - bit_size);
722 /* NOTE: transformed to SHR if unsigned */
723 gen_op(TOK_SAR);
724 r = gv(rc);
725 } else {
726 if (is_float(vtop->type.t) &&
727 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
728 Sym *sym;
729 int *ptr;
730 unsigned long offset;
731 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
732 CValue check;
733 #endif
735 /* XXX: unify with initializers handling ? */
736 /* CPUs usually cannot use float constants, so we store them
737 generically in data segment */
738 size = type_size(&vtop->type, &align);
739 offset = (data_section->data_offset + align - 1) & -align;
740 data_section->data_offset = offset;
741 /* XXX: not portable yet */
742 #if defined(__i386__) || defined(__x86_64__)
743 /* Zero pad x87 tenbyte long doubles */
744 if (size == LDOUBLE_SIZE) {
745 vtop->c.tab[2] &= 0xffff;
746 #if LDOUBLE_SIZE == 16
747 vtop->c.tab[3] = 0;
748 #endif
750 #endif
751 ptr = section_ptr_add(data_section, size);
752 size = size >> 2;
753 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
754 check.d = 1;
755 if(check.tab[0])
756 for(i=0;i<size;i++)
757 ptr[i] = vtop->c.tab[size-1-i];
758 else
759 #endif
760 for(i=0;i<size;i++)
761 ptr[i] = vtop->c.tab[i];
762 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
763 vtop->r |= VT_LVAL | VT_SYM;
764 vtop->sym = sym;
765 vtop->c.ul = 0;
767 #ifdef CONFIG_TCC_BCHECK
768 if (vtop->r & VT_MUSTBOUND)
769 gbound();
770 #endif
772 r = vtop->r & VT_VALMASK;
773 #ifndef TCC_TARGET_X86_64
774 rc2 = RC_INT;
775 if (rc == RC_IRET)
776 rc2 = RC_LRET;
777 #endif
778 /* need to reload if:
779 - constant
780 - lvalue (need to dereference pointer)
781 - already a register, but not in the right class */
782 if (r >= VT_CONST
783 || (vtop->r & VT_LVAL)
784 || !(reg_classes[r] & rc)
785 #ifndef TCC_TARGET_X86_64
786 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
787 #endif
790 r = get_reg(rc);
791 #ifndef TCC_TARGET_X86_64
792 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
793 int r2;
794 unsigned long long ll;
795 /* two register type load : expand to two words
796 temporarily */
797 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
798 /* load constant */
799 ll = vtop->c.ull;
800 vtop->c.ui = ll; /* first word */
801 load(r, vtop);
802 vtop->r = r; /* save register value */
803 vpushi(ll >> 32); /* second word */
804 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
805 (vtop->r & VT_LVAL)) {
806 /* We do not want to modifier the long long
807 pointer here, so the safest (and less
808 efficient) is to save all the other registers
809 in the stack. XXX: totally inefficient. */
810 save_regs(1);
811 /* load from memory */
812 load(r, vtop);
813 vdup();
814 vtop[-1].r = r; /* save register value */
815 /* increment pointer to get second word */
816 vtop->type.t = VT_INT;
817 gaddrof();
818 vpushi(4);
819 gen_op('+');
820 vtop->r |= VT_LVAL;
821 } else {
822 /* move registers */
823 load(r, vtop);
824 vdup();
825 vtop[-1].r = r; /* save register value */
826 vtop->r = vtop[-1].r2;
828 /* Allocate second register. Here we rely on the fact that
829 get_reg() tries first to free r2 of an SValue. */
830 r2 = get_reg(rc2);
831 load(r2, vtop);
832 vpop();
833 /* write second register */
834 vtop->r2 = r2;
835 } else
836 #endif
837 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
838 int t1, t;
839 /* lvalue of scalar type : need to use lvalue type
840 because of possible cast */
841 t = vtop->type.t;
842 t1 = t;
843 /* compute memory access type */
844 if (vtop->r & VT_LVAL_BYTE)
845 t = VT_BYTE;
846 else if (vtop->r & VT_LVAL_SHORT)
847 t = VT_SHORT;
848 if (vtop->r & VT_LVAL_UNSIGNED)
849 t |= VT_UNSIGNED;
850 vtop->type.t = t;
851 load(r, vtop);
852 /* restore wanted type */
853 vtop->type.t = t1;
854 } else {
855 /* one register type load */
856 load(r, vtop);
859 vtop->r = r;
860 #ifdef TCC_TARGET_C67
861 /* uses register pairs for doubles */
862 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
863 vtop->r2 = r+1;
864 #endif
866 return r;
869 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
870 ST_FUNC void gv2(int rc1, int rc2)
872 int v;
874 /* generate more generic register first. But VT_JMP or VT_CMP
875 values must be generated first in all cases to avoid possible
876 reload errors */
877 v = vtop[0].r & VT_VALMASK;
878 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
879 vswap();
880 gv(rc1);
881 vswap();
882 gv(rc2);
883 /* test if reload is needed for first register */
884 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
885 vswap();
886 gv(rc1);
887 vswap();
889 } else {
890 gv(rc2);
891 vswap();
892 gv(rc1);
893 vswap();
894 /* test if reload is needed for first register */
895 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
896 gv(rc2);
901 /* wrapper around RC_FRET to return a register by type */
902 static int rc_fret(int t)
904 #ifdef TCC_TARGET_X86_64
905 if (t == VT_LDOUBLE) {
906 return RC_ST0;
908 #endif
909 return RC_FRET;
912 /* wrapper around REG_FRET to return a register by type */
913 static int reg_fret(int t)
915 #ifdef TCC_TARGET_X86_64
916 if (t == VT_LDOUBLE) {
917 return TREG_ST0;
919 #endif
920 return REG_FRET;
923 /* expand long long on stack in two int registers */
924 static void lexpand(void)
926 int u;
928 u = vtop->type.t & VT_UNSIGNED;
929 gv(RC_INT);
930 vdup();
931 vtop[0].r = vtop[-1].r2;
932 vtop[0].r2 = VT_CONST;
933 vtop[-1].r2 = VT_CONST;
934 vtop[0].type.t = VT_INT | u;
935 vtop[-1].type.t = VT_INT | u;
938 #ifdef TCC_TARGET_ARM
939 /* expand long long on stack */
940 ST_FUNC void lexpand_nr(void)
942 int u,v;
944 u = vtop->type.t & VT_UNSIGNED;
945 vdup();
946 vtop->r2 = VT_CONST;
947 vtop->type.t = VT_INT | u;
948 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
949 if (v == VT_CONST) {
950 vtop[-1].c.ui = vtop->c.ull;
951 vtop->c.ui = vtop->c.ull >> 32;
952 vtop->r = VT_CONST;
953 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
954 vtop->c.ui += 4;
955 vtop->r = vtop[-1].r;
956 } else if (v > VT_CONST) {
957 vtop--;
958 lexpand();
959 } else
960 vtop->r = vtop[-1].r2;
961 vtop[-1].r2 = VT_CONST;
962 vtop[-1].type.t = VT_INT | u;
964 #endif
966 /* build a long long from two ints */
967 static void lbuild(int t)
969 gv2(RC_INT, RC_INT);
970 vtop[-1].r2 = vtop[0].r;
971 vtop[-1].type.t = t;
972 vpop();
975 /* rotate n first stack elements to the bottom
976 I1 ... In -> I2 ... In I1 [top is right]
978 ST_FUNC void vrotb(int n)
980 int i;
981 SValue tmp;
983 tmp = vtop[-n + 1];
984 for(i=-n+1;i!=0;i++)
985 vtop[i] = vtop[i+1];
986 vtop[0] = tmp;
989 /* rotate the n elements before entry e towards the top
990 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
992 ST_FUNC void vrote(SValue *e, int n)
994 int i;
995 SValue tmp;
997 tmp = *e;
998 for(i = 0;i < n - 1; i++)
999 e[-i] = e[-i - 1];
1000 e[-n + 1] = tmp;
1003 /* rotate n first stack elements to the top
1004 I1 ... In -> In I1 ... I(n-1) [top is right]
1006 ST_FUNC void vrott(int n)
1008 vrote(vtop, n);
1011 /* pop stack value */
1012 ST_FUNC void vpop(void)
1014 int v;
1015 v = vtop->r & VT_VALMASK;
1016 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1017 /* for x86, we need to pop the FP stack */
1018 if (v == TREG_ST0 && !nocode_wanted) {
1019 o(0xd8dd); /* fstp %st(0) */
1020 } else
1021 #endif
1022 if (v == VT_JMP || v == VT_JMPI) {
1023 /* need to put correct jump if && or || without test */
1024 gsym(vtop->c.ul);
1026 vtop--;
1029 /* convert stack entry to register and duplicate its value in another
1030 register */
1031 static void gv_dup(void)
1033 int rc, t, r, r1;
1034 SValue sv;
1036 t = vtop->type.t;
1037 if ((t & VT_BTYPE) == VT_LLONG) {
1038 lexpand();
1039 gv_dup();
1040 vswap();
1041 vrotb(3);
1042 gv_dup();
1043 vrotb(4);
1044 /* stack: H L L1 H1 */
1045 lbuild(t);
1046 vrotb(3);
1047 vrotb(3);
1048 vswap();
1049 lbuild(t);
1050 vswap();
1051 } else {
1052 /* duplicate value */
1053 rc = RC_INT;
1054 sv.type.t = VT_INT;
1055 if (is_float(t)) {
1056 rc = RC_FLOAT;
1057 #ifdef TCC_TARGET_X86_64
1058 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1059 rc = RC_ST0;
1061 #endif
1062 sv.type.t = t;
1064 r = gv(rc);
1065 r1 = get_reg(rc);
1066 sv.r = r;
1067 sv.c.ul = 0;
1068 load(r1, &sv); /* move r to r1 */
1069 vdup();
1070 /* duplicates value */
1071 if (r != r1)
1072 vtop->r = r1;
1076 #ifndef TCC_TARGET_X86_64
1077 /* generate CPU independent (unsigned) long long operations */
1078 static void gen_opl(int op)
1080 int t, a, b, op1, c, i;
1081 int func;
1082 unsigned short reg_iret = REG_IRET;
1083 unsigned short reg_lret = REG_LRET;
1084 SValue tmp;
1086 switch(op) {
1087 case '/':
1088 case TOK_PDIV:
1089 func = TOK___divdi3;
1090 goto gen_func;
1091 case TOK_UDIV:
1092 func = TOK___udivdi3;
1093 goto gen_func;
1094 case '%':
1095 func = TOK___moddi3;
1096 goto gen_mod_func;
1097 case TOK_UMOD:
1098 func = TOK___umoddi3;
1099 gen_mod_func:
1100 #ifdef TCC_ARM_EABI
1101 reg_iret = TREG_R2;
1102 reg_lret = TREG_R3;
1103 #endif
1104 gen_func:
1105 /* call generic long long function */
1106 vpush_global_sym(&func_old_type, func);
1107 vrott(3);
1108 gfunc_call(2);
1109 vpushi(0);
1110 vtop->r = reg_iret;
1111 vtop->r2 = reg_lret;
1112 break;
1113 case '^':
1114 case '&':
1115 case '|':
1116 case '*':
1117 case '+':
1118 case '-':
1119 t = vtop->type.t;
1120 vswap();
1121 lexpand();
1122 vrotb(3);
1123 lexpand();
1124 /* stack: L1 H1 L2 H2 */
1125 tmp = vtop[0];
1126 vtop[0] = vtop[-3];
1127 vtop[-3] = tmp;
1128 tmp = vtop[-2];
1129 vtop[-2] = vtop[-3];
1130 vtop[-3] = tmp;
1131 vswap();
1132 /* stack: H1 H2 L1 L2 */
1133 if (op == '*') {
1134 vpushv(vtop - 1);
1135 vpushv(vtop - 1);
1136 gen_op(TOK_UMULL);
1137 lexpand();
1138 /* stack: H1 H2 L1 L2 ML MH */
1139 for(i=0;i<4;i++)
1140 vrotb(6);
1141 /* stack: ML MH H1 H2 L1 L2 */
1142 tmp = vtop[0];
1143 vtop[0] = vtop[-2];
1144 vtop[-2] = tmp;
1145 /* stack: ML MH H1 L2 H2 L1 */
1146 gen_op('*');
1147 vrotb(3);
1148 vrotb(3);
1149 gen_op('*');
1150 /* stack: ML MH M1 M2 */
1151 gen_op('+');
1152 gen_op('+');
1153 } else if (op == '+' || op == '-') {
1154 /* XXX: add non carry method too (for MIPS or alpha) */
1155 if (op == '+')
1156 op1 = TOK_ADDC1;
1157 else
1158 op1 = TOK_SUBC1;
1159 gen_op(op1);
1160 /* stack: H1 H2 (L1 op L2) */
1161 vrotb(3);
1162 vrotb(3);
1163 gen_op(op1 + 1); /* TOK_xxxC2 */
1164 } else {
1165 gen_op(op);
1166 /* stack: H1 H2 (L1 op L2) */
1167 vrotb(3);
1168 vrotb(3);
1169 /* stack: (L1 op L2) H1 H2 */
1170 gen_op(op);
1171 /* stack: (L1 op L2) (H1 op H2) */
1173 /* stack: L H */
1174 lbuild(t);
1175 break;
1176 case TOK_SAR:
1177 case TOK_SHR:
1178 case TOK_SHL:
1179 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1180 t = vtop[-1].type.t;
1181 vswap();
1182 lexpand();
1183 vrotb(3);
1184 /* stack: L H shift */
1185 c = (int)vtop->c.i;
1186 /* constant: simpler */
1187 /* NOTE: all comments are for SHL. the other cases are
1188 done by swaping words */
1189 vpop();
1190 if (op != TOK_SHL)
1191 vswap();
1192 if (c >= 32) {
1193 /* stack: L H */
1194 vpop();
1195 if (c > 32) {
1196 vpushi(c - 32);
1197 gen_op(op);
1199 if (op != TOK_SAR) {
1200 vpushi(0);
1201 } else {
1202 gv_dup();
1203 vpushi(31);
1204 gen_op(TOK_SAR);
1206 vswap();
1207 } else {
1208 vswap();
1209 gv_dup();
1210 /* stack: H L L */
1211 vpushi(c);
1212 gen_op(op);
1213 vswap();
1214 vpushi(32 - c);
1215 if (op == TOK_SHL)
1216 gen_op(TOK_SHR);
1217 else
1218 gen_op(TOK_SHL);
1219 vrotb(3);
1220 /* stack: L L H */
1221 vpushi(c);
1222 if (op == TOK_SHL)
1223 gen_op(TOK_SHL);
1224 else
1225 gen_op(TOK_SHR);
1226 gen_op('|');
1228 if (op != TOK_SHL)
1229 vswap();
1230 lbuild(t);
1231 } else {
1232 /* XXX: should provide a faster fallback on x86 ? */
1233 switch(op) {
1234 case TOK_SAR:
1235 func = TOK___ashrdi3;
1236 goto gen_func;
1237 case TOK_SHR:
1238 func = TOK___lshrdi3;
1239 goto gen_func;
1240 case TOK_SHL:
1241 func = TOK___ashldi3;
1242 goto gen_func;
1245 break;
1246 default:
1247 /* compare operations */
1248 t = vtop->type.t;
1249 vswap();
1250 lexpand();
1251 vrotb(3);
1252 lexpand();
1253 /* stack: L1 H1 L2 H2 */
1254 tmp = vtop[-1];
1255 vtop[-1] = vtop[-2];
1256 vtop[-2] = tmp;
1257 /* stack: L1 L2 H1 H2 */
1258 /* compare high */
1259 op1 = op;
1260 /* when values are equal, we need to compare low words. since
1261 the jump is inverted, we invert the test too. */
1262 if (op1 == TOK_LT)
1263 op1 = TOK_LE;
1264 else if (op1 == TOK_GT)
1265 op1 = TOK_GE;
1266 else if (op1 == TOK_ULT)
1267 op1 = TOK_ULE;
1268 else if (op1 == TOK_UGT)
1269 op1 = TOK_UGE;
1270 a = 0;
1271 b = 0;
1272 gen_op(op1);
1273 if (op1 != TOK_NE) {
1274 a = gtst(1, 0);
1276 if (op != TOK_EQ) {
1277 /* generate non equal test */
1278 /* XXX: NOT PORTABLE yet */
1279 if (a == 0) {
1280 b = gtst(0, 0);
1281 } else {
1282 #if defined(TCC_TARGET_I386)
1283 b = psym(0x850f, 0);
1284 #elif defined(TCC_TARGET_ARM)
1285 b = ind;
1286 o(0x1A000000 | encbranch(ind, 0, 1));
1287 #elif defined(TCC_TARGET_C67)
1288 tcc_error("not implemented");
1289 #else
1290 #error not supported
1291 #endif
1294 /* compare low. Always unsigned */
1295 op1 = op;
1296 if (op1 == TOK_LT)
1297 op1 = TOK_ULT;
1298 else if (op1 == TOK_LE)
1299 op1 = TOK_ULE;
1300 else if (op1 == TOK_GT)
1301 op1 = TOK_UGT;
1302 else if (op1 == TOK_GE)
1303 op1 = TOK_UGE;
1304 gen_op(op1);
1305 a = gtst(1, a);
1306 gsym(b);
1307 vseti(VT_JMPI, a);
1308 break;
1311 #endif
1313 /* handle integer constant optimizations and various machine
1314 independent opt */
1315 static void gen_opic(int op)
1317 int c1, c2, t1, t2, n;
1318 SValue *v1, *v2;
1319 long long l1, l2;
1320 typedef unsigned long long U;
1322 v1 = vtop - 1;
1323 v2 = vtop;
1324 t1 = v1->type.t & VT_BTYPE;
1325 t2 = v2->type.t & VT_BTYPE;
1327 if (t1 == VT_LLONG)
1328 l1 = v1->c.ll;
1329 else if (v1->type.t & VT_UNSIGNED)
1330 l1 = v1->c.ui;
1331 else
1332 l1 = v1->c.i;
1334 if (t2 == VT_LLONG)
1335 l2 = v2->c.ll;
1336 else if (v2->type.t & VT_UNSIGNED)
1337 l2 = v2->c.ui;
1338 else
1339 l2 = v2->c.i;
1341 /* currently, we cannot do computations with forward symbols */
1342 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1343 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1344 if (c1 && c2) {
1345 switch(op) {
1346 case '+': l1 += l2; break;
1347 case '-': l1 -= l2; break;
1348 case '&': l1 &= l2; break;
1349 case '^': l1 ^= l2; break;
1350 case '|': l1 |= l2; break;
1351 case '*': l1 *= l2; break;
1353 case TOK_PDIV:
1354 case '/':
1355 case '%':
1356 case TOK_UDIV:
1357 case TOK_UMOD:
1358 /* if division by zero, generate explicit division */
1359 if (l2 == 0) {
1360 if (const_wanted)
1361 tcc_error("division by zero in constant");
1362 goto general_case;
1364 switch(op) {
1365 default: l1 /= l2; break;
1366 case '%': l1 %= l2; break;
1367 case TOK_UDIV: l1 = (U)l1 / l2; break;
1368 case TOK_UMOD: l1 = (U)l1 % l2; break;
1370 break;
1371 case TOK_SHL: l1 <<= l2; break;
1372 case TOK_SHR: l1 = (U)l1 >> l2; break;
1373 case TOK_SAR: l1 >>= l2; break;
1374 /* tests */
1375 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1376 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1377 case TOK_EQ: l1 = l1 == l2; break;
1378 case TOK_NE: l1 = l1 != l2; break;
1379 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1380 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1381 case TOK_LT: l1 = l1 < l2; break;
1382 case TOK_GE: l1 = l1 >= l2; break;
1383 case TOK_LE: l1 = l1 <= l2; break;
1384 case TOK_GT: l1 = l1 > l2; break;
1385 /* logical */
1386 case TOK_LAND: l1 = l1 && l2; break;
1387 case TOK_LOR: l1 = l1 || l2; break;
1388 default:
1389 goto general_case;
1391 v1->c.ll = l1;
1392 vtop--;
1393 } else {
1394 /* if commutative ops, put c2 as constant */
1395 if (c1 && (op == '+' || op == '&' || op == '^' ||
1396 op == '|' || op == '*')) {
1397 vswap();
1398 c2 = c1; //c = c1, c1 = c2, c2 = c;
1399 l2 = l1; //l = l1, l1 = l2, l2 = l;
1401 /* Filter out NOP operations like x*1, x-0, x&-1... */
1402 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1403 op == TOK_PDIV) &&
1404 l2 == 1) ||
1405 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1406 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1407 l2 == 0) ||
1408 (op == '&' &&
1409 l2 == -1))) {
1410 /* nothing to do */
1411 vtop--;
1412 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1413 /* try to use shifts instead of muls or divs */
1414 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1415 n = -1;
1416 while (l2) {
1417 l2 >>= 1;
1418 n++;
1420 vtop->c.ll = n;
1421 if (op == '*')
1422 op = TOK_SHL;
1423 else if (op == TOK_PDIV)
1424 op = TOK_SAR;
1425 else
1426 op = TOK_SHR;
1428 goto general_case;
1429 } else if (c2 && (op == '+' || op == '-') &&
1430 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1431 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1432 /* symbol + constant case */
1433 if (op == '-')
1434 l2 = -l2;
1435 vtop--;
1436 vtop->c.ll += l2;
1437 } else {
1438 general_case:
1439 if (!nocode_wanted) {
1440 /* call low level op generator */
1441 if (t1 == VT_LLONG || t2 == VT_LLONG)
1442 gen_opl(op);
1443 else
1444 gen_opi(op);
1445 } else {
1446 vtop--;
1452 /* generate a floating point operation with constant propagation */
1453 static void gen_opif(int op)
1455 int c1, c2;
1456 SValue *v1, *v2;
1457 long double f1, f2;
1459 v1 = vtop - 1;
1460 v2 = vtop;
1461 /* currently, we cannot do computations with forward symbols */
1462 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1463 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1464 if (c1 && c2) {
1465 if (v1->type.t == VT_FLOAT) {
1466 f1 = v1->c.f;
1467 f2 = v2->c.f;
1468 } else if (v1->type.t == VT_DOUBLE) {
1469 f1 = v1->c.d;
1470 f2 = v2->c.d;
1471 } else {
1472 f1 = v1->c.ld;
1473 f2 = v2->c.ld;
1476 /* NOTE: we only do constant propagation if finite number (not
1477 NaN or infinity) (ANSI spec) */
1478 if (!ieee_finite(f1) || !ieee_finite(f2))
1479 goto general_case;
1481 switch(op) {
1482 case '+': f1 += f2; break;
1483 case '-': f1 -= f2; break;
1484 case '*': f1 *= f2; break;
1485 case '/':
1486 if (f2 == 0.0) {
1487 if (const_wanted)
1488 tcc_error("division by zero in constant");
1489 goto general_case;
1491 f1 /= f2;
1492 break;
1493 /* XXX: also handles tests ? */
1494 default:
1495 goto general_case;
1497 /* XXX: overflow test ? */
1498 if (v1->type.t == VT_FLOAT) {
1499 v1->c.f = f1;
1500 } else if (v1->type.t == VT_DOUBLE) {
1501 v1->c.d = f1;
1502 } else {
1503 v1->c.ld = f1;
1505 vtop--;
1506 } else {
1507 general_case:
1508 if (!nocode_wanted) {
1509 gen_opf(op);
1510 } else {
1511 vtop--;
1516 static int pointed_size(CType *type)
1518 int align;
1519 return type_size(pointed_type(type), &align);
1522 static void vla_runtime_pointed_size(CType *type)
1524 int align;
1525 vla_runtime_type_size(pointed_type(type), &align);
1528 static inline int is_null_pointer(SValue *p)
1530 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1531 return 0;
1532 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1533 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1534 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
1537 static inline int is_integer_btype(int bt)
1539 return (bt == VT_BYTE || bt == VT_SHORT ||
1540 bt == VT_INT || bt == VT_LLONG);
1543 /* check types for comparison or substraction of pointers */
1544 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1546 CType *type1, *type2, tmp_type1, tmp_type2;
1547 int bt1, bt2;
1549 /* null pointers are accepted for all comparisons as gcc */
1550 if (is_null_pointer(p1) || is_null_pointer(p2))
1551 return;
1552 type1 = &p1->type;
1553 type2 = &p2->type;
1554 bt1 = type1->t & VT_BTYPE;
1555 bt2 = type2->t & VT_BTYPE;
1556 /* accept comparison between pointer and integer with a warning */
1557 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1558 if (op != TOK_LOR && op != TOK_LAND )
1559 tcc_warning("comparison between pointer and integer");
1560 return;
1563 /* both must be pointers or implicit function pointers */
1564 if (bt1 == VT_PTR) {
1565 type1 = pointed_type(type1);
1566 } else if (bt1 != VT_FUNC)
1567 goto invalid_operands;
1569 if (bt2 == VT_PTR) {
1570 type2 = pointed_type(type2);
1571 } else if (bt2 != VT_FUNC) {
1572 invalid_operands:
1573 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1575 if ((type1->t & VT_BTYPE) == VT_VOID ||
1576 (type2->t & VT_BTYPE) == VT_VOID)
1577 return;
1578 tmp_type1 = *type1;
1579 tmp_type2 = *type2;
1580 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1581 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1582 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1583 /* gcc-like error if '-' is used */
1584 if (op == '-')
1585 goto invalid_operands;
1586 else
1587 tcc_warning("comparison of distinct pointer types lacks a cast");
1591 /* generic gen_op: handles types problems */
1592 ST_FUNC void gen_op(int op)
1594 int u, t1, t2, bt1, bt2, t;
1595 CType type1;
1597 t1 = vtop[-1].type.t;
1598 t2 = vtop[0].type.t;
1599 bt1 = t1 & VT_BTYPE;
1600 bt2 = t2 & VT_BTYPE;
1602 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1603 /* at least one operand is a pointer */
1604 /* relationnal op: must be both pointers */
1605 if (op >= TOK_ULT && op <= TOK_LOR) {
1606 check_comparison_pointer_types(vtop - 1, vtop, op);
1607 /* pointers are handled are unsigned */
1608 #ifdef TCC_TARGET_X86_64
1609 t = VT_LLONG | VT_UNSIGNED;
1610 #else
1611 t = VT_INT | VT_UNSIGNED;
1612 #endif
1613 goto std_op;
1615 /* if both pointers, then it must be the '-' op */
1616 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1617 if (op != '-')
1618 tcc_error("cannot use pointers here");
1619 check_comparison_pointer_types(vtop - 1, vtop, op);
1620 /* XXX: check that types are compatible */
1621 if (vtop[-1].type.t & VT_VLA) {
1622 vla_runtime_pointed_size(&vtop[-1].type);
1623 } else {
1624 vpushi(pointed_size(&vtop[-1].type));
1626 vrott(3);
1627 gen_opic(op);
1628 /* set to integer type */
1629 #ifdef TCC_TARGET_X86_64
1630 vtop->type.t = VT_LLONG;
1631 #else
1632 vtop->type.t = VT_INT;
1633 #endif
1634 vswap();
1635 gen_op(TOK_PDIV);
1636 } else {
1637 /* exactly one pointer : must be '+' or '-'. */
1638 if (op != '-' && op != '+')
1639 tcc_error("cannot use pointers here");
1640 /* Put pointer as first operand */
1641 if (bt2 == VT_PTR) {
1642 vswap();
1643 swap(&t1, &t2);
1645 type1 = vtop[-1].type;
1646 type1.t &= ~VT_ARRAY;
1647 if (vtop[-1].type.t & VT_VLA)
1648 vla_runtime_pointed_size(&vtop[-1].type);
1649 else {
1650 u = pointed_size(&vtop[-1].type);
1651 if (u < 0)
1652 tcc_error("unknown array element size");
1653 #ifdef TCC_TARGET_X86_64
1654 vpushll(u);
1655 #else
1656 /* XXX: cast to int ? (long long case) */
1657 vpushi(u);
1658 #endif
1660 gen_op('*');
1661 #ifdef CONFIG_TCC_BCHECK
1662 /* if evaluating constant expression, no code should be
1663 generated, so no bound check */
1664 if (tcc_state->do_bounds_check && !const_wanted) {
1665 /* if bounded pointers, we generate a special code to
1666 test bounds */
1667 if (op == '-') {
1668 vpushi(0);
1669 vswap();
1670 gen_op('-');
1672 gen_bounded_ptr_add();
1673 } else
1674 #endif
1676 gen_opic(op);
1678 /* put again type if gen_opic() swaped operands */
1679 vtop->type = type1;
1681 } else if (is_float(bt1) || is_float(bt2)) {
1682 /* compute bigger type and do implicit casts */
1683 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1684 t = VT_LDOUBLE;
1685 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1686 t = VT_DOUBLE;
1687 } else {
1688 t = VT_FLOAT;
1690 /* floats can only be used for a few operations */
1691 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1692 (op < TOK_ULT || op > TOK_GT))
1693 tcc_error("invalid operands for binary operation");
1694 goto std_op;
1695 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1696 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1697 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1698 t |= VT_UNSIGNED;
1699 goto std_op;
1700 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1701 /* cast to biggest op */
1702 t = VT_LLONG;
1703 /* convert to unsigned if it does not fit in a long long */
1704 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1705 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1706 t |= VT_UNSIGNED;
1707 goto std_op;
1708 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1709 tcc_error("comparison of struct");
1710 } else {
1711 /* integer operations */
1712 t = VT_INT;
1713 /* convert to unsigned if it does not fit in an integer */
1714 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1715 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1716 t |= VT_UNSIGNED;
1717 std_op:
1718 /* XXX: currently, some unsigned operations are explicit, so
1719 we modify them here */
1720 if (t & VT_UNSIGNED) {
1721 if (op == TOK_SAR)
1722 op = TOK_SHR;
1723 else if (op == '/')
1724 op = TOK_UDIV;
1725 else if (op == '%')
1726 op = TOK_UMOD;
1727 else if (op == TOK_LT)
1728 op = TOK_ULT;
1729 else if (op == TOK_GT)
1730 op = TOK_UGT;
1731 else if (op == TOK_LE)
1732 op = TOK_ULE;
1733 else if (op == TOK_GE)
1734 op = TOK_UGE;
1736 vswap();
1737 type1.t = t;
1738 type1.ref = 0;
1739 gen_cast(&type1);
1740 vswap();
1741 /* special case for shifts and long long: we keep the shift as
1742 an integer */
1743 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1744 type1.t = VT_INT;
1745 gen_cast(&type1);
1746 if (is_float(t))
1747 gen_opif(op);
1748 else
1749 gen_opic(op);
1750 if (op >= TOK_ULT && op <= TOK_GT) {
1751 /* relationnal op: the result is an int */
1752 vtop->type.t = VT_INT;
1753 } else {
1754 vtop->type.t = t;
1759 #ifndef TCC_TARGET_ARM
1760 /* generic itof for unsigned long long case */
1761 static void gen_cvt_itof1(int t)
1763 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1764 (VT_LLONG | VT_UNSIGNED)) {
1766 if (t == VT_FLOAT)
1767 vpush_global_sym(&func_old_type, TOK___floatundisf);
1768 #if LDOUBLE_SIZE != 8
1769 else if (t == VT_LDOUBLE)
1770 vpush_global_sym(&func_old_type, TOK___floatundixf);
1771 #endif
1772 else
1773 vpush_global_sym(&func_old_type, TOK___floatundidf);
1774 vrott(2);
1775 gfunc_call(1);
1776 vpushi(0);
1777 vtop->r = reg_fret(t);
1778 } else {
1779 gen_cvt_itof(t);
1782 #endif
1784 /* generic ftoi for unsigned long long case */
1785 static void gen_cvt_ftoi1(int t)
1787 int st;
1789 if (t == (VT_LLONG | VT_UNSIGNED)) {
1790 /* not handled natively */
1791 st = vtop->type.t & VT_BTYPE;
1792 if (st == VT_FLOAT)
1793 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1794 #if LDOUBLE_SIZE != 8
1795 else if (st == VT_LDOUBLE)
1796 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1797 #endif
1798 else
1799 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1800 vrott(2);
1801 gfunc_call(1);
1802 vpushi(0);
1803 vtop->r = REG_IRET;
1804 vtop->r2 = REG_LRET;
1805 } else {
1806 gen_cvt_ftoi(t);
1810 /* force char or short cast */
1811 static void force_charshort_cast(int t)
1813 int bits, dbt;
1814 dbt = t & VT_BTYPE;
1815 /* XXX: add optimization if lvalue : just change type and offset */
1816 if (dbt == VT_BYTE)
1817 bits = 8;
1818 else
1819 bits = 16;
1820 if (t & VT_UNSIGNED) {
1821 vpushi((1 << bits) - 1);
1822 gen_op('&');
1823 } else {
1824 bits = 32 - bits;
1825 vpushi(bits);
1826 gen_op(TOK_SHL);
1827 /* result must be signed or the SAR is converted to an SHL
1828 This was not the case when "t" was a signed short
1829 and the last value on the stack was an unsigned int */
1830 vtop->type.t &= ~VT_UNSIGNED;
1831 vpushi(bits);
1832 gen_op(TOK_SAR);
1836 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1837 static void gen_cast(CType *type)
1839 int sbt, dbt, sf, df, c, p;
1841 /* special delayed cast for char/short */
1842 /* XXX: in some cases (multiple cascaded casts), it may still
1843 be incorrect */
1844 if (vtop->r & VT_MUSTCAST) {
1845 vtop->r &= ~VT_MUSTCAST;
1846 force_charshort_cast(vtop->type.t);
1849 /* bitfields first get cast to ints */
1850 if (vtop->type.t & VT_BITFIELD) {
1851 gv(RC_INT);
1854 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1855 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1857 if (sbt != dbt) {
1858 sf = is_float(sbt);
1859 df = is_float(dbt);
1860 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1861 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1862 if (c) {
1863 /* constant case: we can do it now */
1864 /* XXX: in ISOC, cannot do it if error in convert */
1865 if (sbt == VT_FLOAT)
1866 vtop->c.ld = vtop->c.f;
1867 else if (sbt == VT_DOUBLE)
1868 vtop->c.ld = vtop->c.d;
1870 if (df) {
1871 if ((sbt & VT_BTYPE) == VT_LLONG) {
1872 if (sbt & VT_UNSIGNED)
1873 vtop->c.ld = vtop->c.ull;
1874 else
1875 vtop->c.ld = vtop->c.ll;
1876 } else if(!sf) {
1877 if (sbt & VT_UNSIGNED)
1878 vtop->c.ld = vtop->c.ui;
1879 else
1880 vtop->c.ld = vtop->c.i;
1883 if (dbt == VT_FLOAT)
1884 vtop->c.f = (float)vtop->c.ld;
1885 else if (dbt == VT_DOUBLE)
1886 vtop->c.d = (double)vtop->c.ld;
1887 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1888 vtop->c.ull = (unsigned long long)vtop->c.ld;
1889 } else if (sf && dbt == VT_BOOL) {
1890 vtop->c.i = (vtop->c.ld != 0);
1891 } else {
1892 if(sf)
1893 vtop->c.ll = (long long)vtop->c.ld;
1894 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1895 vtop->c.ll = vtop->c.ull;
1896 else if (sbt & VT_UNSIGNED)
1897 vtop->c.ll = vtop->c.ui;
1898 #ifdef TCC_TARGET_X86_64
1899 else if (sbt == VT_PTR)
1901 #endif
1902 else if (sbt != VT_LLONG)
1903 vtop->c.ll = vtop->c.i;
1905 if (dbt == (VT_LLONG|VT_UNSIGNED))
1906 vtop->c.ull = vtop->c.ll;
1907 else if (dbt == VT_BOOL)
1908 vtop->c.i = (vtop->c.ll != 0);
1909 else if (dbt != VT_LLONG) {
1910 int s = 0;
1911 if ((dbt & VT_BTYPE) == VT_BYTE)
1912 s = 24;
1913 else if ((dbt & VT_BTYPE) == VT_SHORT)
1914 s = 16;
1916 if(dbt & VT_UNSIGNED)
1917 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1918 else
1919 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1922 } else if (p && dbt == VT_BOOL) {
1923 vtop->r = VT_CONST;
1924 vtop->c.i = 1;
1925 } else if (!nocode_wanted) {
1926 /* non constant case: generate code */
1927 if (sf && df) {
1928 /* convert from fp to fp */
1929 gen_cvt_ftof(dbt);
1930 } else if (df) {
1931 /* convert int to fp */
1932 gen_cvt_itof1(dbt);
1933 } else if (sf) {
1934 /* convert fp to int */
1935 if (dbt == VT_BOOL) {
1936 vpushi(0);
1937 gen_op(TOK_NE);
1938 } else {
1939 /* we handle char/short/etc... with generic code */
1940 if (dbt != (VT_INT | VT_UNSIGNED) &&
1941 dbt != (VT_LLONG | VT_UNSIGNED) &&
1942 dbt != VT_LLONG)
1943 dbt = VT_INT;
1944 gen_cvt_ftoi1(dbt);
1945 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1946 /* additional cast for char/short... */
1947 vtop->type.t = dbt;
1948 gen_cast(type);
1951 #ifndef TCC_TARGET_X86_64
1952 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1953 if ((sbt & VT_BTYPE) != VT_LLONG) {
1954 /* scalar to long long */
1955 /* machine independent conversion */
1956 gv(RC_INT);
1957 /* generate high word */
1958 if (sbt == (VT_INT | VT_UNSIGNED)) {
1959 vpushi(0);
1960 gv(RC_INT);
1961 } else {
1962 if (sbt == VT_PTR) {
1963 /* cast from pointer to int before we apply
1964 shift operation, which pointers don't support*/
1965 gen_cast(&int_type);
1967 gv_dup();
1968 vpushi(31);
1969 gen_op(TOK_SAR);
1971 /* patch second register */
1972 vtop[-1].r2 = vtop->r;
1973 vpop();
1975 #else
1976 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1977 (dbt & VT_BTYPE) == VT_PTR ||
1978 (dbt & VT_BTYPE) == VT_FUNC) {
1979 if ((sbt & VT_BTYPE) != VT_LLONG &&
1980 (sbt & VT_BTYPE) != VT_PTR &&
1981 (sbt & VT_BTYPE) != VT_FUNC) {
1982 /* need to convert from 32bit to 64bit */
1983 int r = gv(RC_INT);
1984 if (sbt != (VT_INT | VT_UNSIGNED)) {
1985 /* x86_64 specific: movslq */
1986 o(0x6348);
1987 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1990 #endif
1991 } else if (dbt == VT_BOOL) {
1992 /* scalar to bool */
1993 vpushi(0);
1994 gen_op(TOK_NE);
1995 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1996 (dbt & VT_BTYPE) == VT_SHORT) {
1997 if (sbt == VT_PTR) {
1998 vtop->type.t = VT_INT;
1999 tcc_warning("nonportable conversion from pointer to char/short");
2001 force_charshort_cast(dbt);
2002 } else if ((dbt & VT_BTYPE) == VT_INT) {
2003 /* scalar to int */
2004 if (sbt == VT_LLONG) {
2005 /* from long long: just take low order word */
2006 lexpand();
2007 vpop();
2009 /* if lvalue and single word type, nothing to do because
2010 the lvalue already contains the real type size (see
2011 VT_LVAL_xxx constants) */
2014 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2015 /* if we are casting between pointer types,
2016 we must update the VT_LVAL_xxx size */
2017 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2018 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2020 vtop->type = *type;
2023 /* return type size as known at compile time. Put alignment at 'a' */
2024 ST_FUNC int type_size(CType *type, int *a)
2026 Sym *s;
2027 int bt;
2029 bt = type->t & VT_BTYPE;
2030 if (bt == VT_STRUCT) {
2031 /* struct/union */
2032 s = type->ref;
2033 *a = s->r;
2034 return s->c;
2035 } else if (bt == VT_PTR) {
2036 if (type->t & VT_ARRAY) {
2037 int ts;
2039 s = type->ref;
2040 ts = type_size(&s->type, a);
2042 if (ts < 0 && s->c < 0)
2043 ts = -ts;
2045 return ts * s->c;
2046 } else {
2047 *a = PTR_SIZE;
2048 return PTR_SIZE;
2050 } else if (bt == VT_LDOUBLE) {
2051 *a = LDOUBLE_ALIGN;
2052 return LDOUBLE_SIZE;
2053 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2054 #ifdef TCC_TARGET_I386
2055 #ifdef TCC_TARGET_PE
2056 *a = 8;
2057 #else
2058 *a = 4;
2059 #endif
2060 #elif defined(TCC_TARGET_ARM)
2061 #ifdef TCC_ARM_EABI
2062 *a = 8;
2063 #else
2064 *a = 4;
2065 #endif
2066 #else
2067 *a = 8;
2068 #endif
2069 return 8;
2070 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2071 *a = 4;
2072 return 4;
2073 } else if (bt == VT_SHORT) {
2074 *a = 2;
2075 return 2;
2076 } else {
2077 /* char, void, function, _Bool */
2078 *a = 1;
2079 return 1;
2083 /* push type size as known at runtime time on top of value stack. Put
2084 alignment at 'a' */
2085 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2087 if (type->t & VT_VLA) {
2088 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2089 } else {
2090 vpushi(type_size(type, a));
2094 /* return the pointed type of t */
2095 static inline CType *pointed_type(CType *type)
2097 return &type->ref->type;
2100 /* modify type so that its it is a pointer to type. */
2101 ST_FUNC void mk_pointer(CType *type)
2103 Sym *s;
2104 s = sym_push(SYM_FIELD, type, 0, -1);
2105 type->t = VT_PTR | (type->t & ~VT_TYPE);
2106 type->ref = s;
2109 /* compare function types. OLD functions match any new functions */
2110 static int is_compatible_func(CType *type1, CType *type2)
2112 Sym *s1, *s2;
2114 s1 = type1->ref;
2115 s2 = type2->ref;
2116 if (!is_compatible_types(&s1->type, &s2->type))
2117 return 0;
2118 /* check func_call */
2119 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2120 return 0;
2121 /* XXX: not complete */
2122 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2123 return 1;
2124 if (s1->c != s2->c)
2125 return 0;
2126 while (s1 != NULL) {
2127 if (s2 == NULL)
2128 return 0;
2129 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2130 return 0;
2131 s1 = s1->next;
2132 s2 = s2->next;
2134 if (s2)
2135 return 0;
2136 return 1;
2139 /* return true if type1 and type2 are the same. If unqualified is
2140 true, qualifiers on the types are ignored.
2142 - enums are not checked as gcc __builtin_types_compatible_p ()
2144 static int compare_types(CType *type1, CType *type2, int unqualified)
2146 int bt1, t1, t2;
2148 t1 = type1->t & VT_TYPE;
2149 t2 = type2->t & VT_TYPE;
2150 if (unqualified) {
2151 /* strip qualifiers before comparing */
2152 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2153 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2155 /* XXX: bitfields ? */
2156 if (t1 != t2)
2157 return 0;
2158 /* test more complicated cases */
2159 bt1 = t1 & VT_BTYPE;
2160 if (bt1 == VT_PTR) {
2161 type1 = pointed_type(type1);
2162 type2 = pointed_type(type2);
2163 return is_compatible_types(type1, type2);
2164 } else if (bt1 == VT_STRUCT) {
2165 return (type1->ref == type2->ref);
2166 } else if (bt1 == VT_FUNC) {
2167 return is_compatible_func(type1, type2);
2168 } else {
2169 return 1;
2173 /* return true if type1 and type2 are exactly the same (including
2174 qualifiers).
2176 static int is_compatible_types(CType *type1, CType *type2)
2178 return compare_types(type1,type2,0);
2181 /* return true if type1 and type2 are the same (ignoring qualifiers).
2183 static int is_compatible_parameter_types(CType *type1, CType *type2)
2185 return compare_types(type1,type2,1);
2188 /* print a type. If 'varstr' is not NULL, then the variable is also
2189 printed in the type */
2190 /* XXX: union */
2191 /* XXX: add array and function pointers */
2192 static void type_to_str(char *buf, int buf_size,
2193 CType *type, const char *varstr)
2195 int bt, v, t;
2196 Sym *s, *sa;
2197 char buf1[256];
2198 const char *tstr;
2200 t = type->t & VT_TYPE;
2201 bt = t & VT_BTYPE;
2202 buf[0] = '\0';
2203 if (t & VT_CONSTANT)
2204 pstrcat(buf, buf_size, "const ");
2205 if (t & VT_VOLATILE)
2206 pstrcat(buf, buf_size, "volatile ");
2207 if (t & VT_UNSIGNED)
2208 pstrcat(buf, buf_size, "unsigned ");
2209 switch(bt) {
2210 case VT_VOID:
2211 tstr = "void";
2212 goto add_tstr;
2213 case VT_BOOL:
2214 tstr = "_Bool";
2215 goto add_tstr;
2216 case VT_BYTE:
2217 tstr = "char";
2218 goto add_tstr;
2219 case VT_SHORT:
2220 tstr = "short";
2221 goto add_tstr;
2222 case VT_INT:
2223 tstr = "int";
2224 goto add_tstr;
2225 case VT_LONG:
2226 tstr = "long";
2227 goto add_tstr;
2228 case VT_LLONG:
2229 tstr = "long long";
2230 goto add_tstr;
2231 case VT_FLOAT:
2232 tstr = "float";
2233 goto add_tstr;
2234 case VT_DOUBLE:
2235 tstr = "double";
2236 goto add_tstr;
2237 case VT_LDOUBLE:
2238 tstr = "long double";
2239 add_tstr:
2240 pstrcat(buf, buf_size, tstr);
2241 break;
2242 case VT_ENUM:
2243 case VT_STRUCT:
2244 if (bt == VT_STRUCT)
2245 tstr = "struct ";
2246 else
2247 tstr = "enum ";
2248 pstrcat(buf, buf_size, tstr);
2249 v = type->ref->v & ~SYM_STRUCT;
2250 if (v >= SYM_FIRST_ANOM)
2251 pstrcat(buf, buf_size, "<anonymous>");
2252 else
2253 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2254 break;
2255 case VT_FUNC:
2256 s = type->ref;
2257 type_to_str(buf, buf_size, &s->type, varstr);
2258 pstrcat(buf, buf_size, "(");
2259 sa = s->next;
2260 while (sa != NULL) {
2261 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2262 pstrcat(buf, buf_size, buf1);
2263 sa = sa->next;
2264 if (sa)
2265 pstrcat(buf, buf_size, ", ");
2267 pstrcat(buf, buf_size, ")");
2268 goto no_var;
2269 case VT_PTR:
2270 s = type->ref;
2271 pstrcpy(buf1, sizeof(buf1), "*");
2272 if (varstr)
2273 pstrcat(buf1, sizeof(buf1), varstr);
2274 type_to_str(buf, buf_size, &s->type, buf1);
2275 goto no_var;
2277 if (varstr) {
2278 pstrcat(buf, buf_size, " ");
2279 pstrcat(buf, buf_size, varstr);
2281 no_var: ;
2284 /* verify type compatibility to store vtop in 'dt' type, and generate
2285 casts if needed. */
2286 static void gen_assign_cast(CType *dt)
2288 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2289 char buf1[256], buf2[256];
2290 int dbt, sbt;
2292 st = &vtop->type; /* source type */
2293 dbt = dt->t & VT_BTYPE;
2294 sbt = st->t & VT_BTYPE;
2295 if (sbt == VT_VOID)
2296 tcc_error("Cannot assign void value");
2297 if (dt->t & VT_CONSTANT)
2298 tcc_warning("assignment of read-only location");
2299 switch(dbt) {
2300 case VT_PTR:
2301 /* special cases for pointers */
2302 /* '0' can also be a pointer */
2303 if (is_null_pointer(vtop))
2304 goto type_ok;
2305 /* accept implicit pointer to integer cast with warning */
2306 if (is_integer_btype(sbt)) {
2307 tcc_warning("assignment makes pointer from integer without a cast");
2308 goto type_ok;
2310 type1 = pointed_type(dt);
2311 /* a function is implicitely a function pointer */
2312 if (sbt == VT_FUNC) {
2313 if ((type1->t & VT_BTYPE) != VT_VOID &&
2314 !is_compatible_types(pointed_type(dt), st))
2315 tcc_warning("assignment from incompatible pointer type");
2316 goto type_ok;
2318 if (sbt != VT_PTR)
2319 goto error;
2320 type2 = pointed_type(st);
2321 if ((type1->t & VT_BTYPE) == VT_VOID ||
2322 (type2->t & VT_BTYPE) == VT_VOID) {
2323 /* void * can match anything */
2324 } else {
2325 /* exact type match, except for unsigned */
2326 tmp_type1 = *type1;
2327 tmp_type2 = *type2;
2328 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2329 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2330 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2331 tcc_warning("assignment from incompatible pointer type");
2333 /* check const and volatile */
2334 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2335 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2336 tcc_warning("assignment discards qualifiers from pointer target type");
2337 break;
2338 case VT_BYTE:
2339 case VT_SHORT:
2340 case VT_INT:
2341 case VT_LLONG:
2342 if (sbt == VT_PTR || sbt == VT_FUNC) {
2343 tcc_warning("assignment makes integer from pointer without a cast");
2345 /* XXX: more tests */
2346 break;
2347 case VT_STRUCT:
2348 tmp_type1 = *dt;
2349 tmp_type2 = *st;
2350 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2351 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2352 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2353 error:
2354 type_to_str(buf1, sizeof(buf1), st, NULL);
2355 type_to_str(buf2, sizeof(buf2), dt, NULL);
2356 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2358 break;
2360 type_ok:
2361 gen_cast(dt);
2364 /* store vtop in lvalue pushed on stack */
2365 ST_FUNC void vstore(void)
2367 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2369 ft = vtop[-1].type.t;
2370 sbt = vtop->type.t & VT_BTYPE;
2371 dbt = ft & VT_BTYPE;
2372 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2373 (sbt == VT_INT && dbt == VT_SHORT))
2374 && !(vtop->type.t & VT_BITFIELD)) {
2375 /* optimize char/short casts */
2376 delayed_cast = VT_MUSTCAST;
2377 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2378 /* XXX: factorize */
2379 if (ft & VT_CONSTANT)
2380 tcc_warning("assignment of read-only location");
2381 } else {
2382 delayed_cast = 0;
2383 if (!(ft & VT_BITFIELD))
2384 gen_assign_cast(&vtop[-1].type);
2387 if (sbt == VT_STRUCT) {
2388 /* if structure, only generate pointer */
2389 /* structure assignment : generate memcpy */
2390 /* XXX: optimize if small size */
2391 if (!nocode_wanted) {
2392 size = type_size(&vtop->type, &align);
2394 /* destination */
2395 vswap();
2396 vtop->type.t = VT_PTR;
2397 gaddrof();
2399 /* address of memcpy() */
2400 #ifdef TCC_ARM_EABI
2401 if(!(align & 7))
2402 vpush_global_sym(&func_old_type, TOK_memcpy8);
2403 else if(!(align & 3))
2404 vpush_global_sym(&func_old_type, TOK_memcpy4);
2405 else
2406 #endif
2407 vpush_global_sym(&func_old_type, TOK_memcpy);
2409 vswap();
2410 /* source */
2411 vpushv(vtop - 2);
2412 vtop->type.t = VT_PTR;
2413 gaddrof();
2414 /* type size */
2415 vpushi(size);
2416 gfunc_call(3);
2417 } else {
2418 vswap();
2419 vpop();
2421 /* leave source on stack */
2422 } else if (ft & VT_BITFIELD) {
2423 /* bitfield store handling */
2424 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2425 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2426 /* remove bit field info to avoid loops */
2427 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2429 /* duplicate source into other register */
2430 gv_dup();
2431 vswap();
2432 vrott(3);
2434 if((ft & VT_BTYPE) == VT_BOOL) {
2435 gen_cast(&vtop[-1].type);
2436 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2439 /* duplicate destination */
2440 vdup();
2441 vtop[-1] = vtop[-2];
2443 /* mask and shift source */
2444 if((ft & VT_BTYPE) != VT_BOOL) {
2445 if((ft & VT_BTYPE) == VT_LLONG) {
2446 vpushll((1ULL << bit_size) - 1ULL);
2447 } else {
2448 vpushi((1 << bit_size) - 1);
2450 gen_op('&');
2452 vpushi(bit_pos);
2453 gen_op(TOK_SHL);
2454 /* load destination, mask and or with source */
2455 vswap();
2456 if((ft & VT_BTYPE) == VT_LLONG) {
2457 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2458 } else {
2459 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2461 gen_op('&');
2462 gen_op('|');
2463 /* store result */
2464 vstore();
2466 /* pop off shifted source from "duplicate source..." above */
2467 vpop();
2469 } else {
2470 #ifdef CONFIG_TCC_BCHECK
2471 /* bound check case */
2472 if (vtop[-1].r & VT_MUSTBOUND) {
2473 vswap();
2474 gbound();
2475 vswap();
2477 #endif
2478 if (!nocode_wanted) {
2479 rc = RC_INT;
2480 if (is_float(ft)) {
2481 rc = RC_FLOAT;
2482 #ifdef TCC_TARGET_X86_64
2483 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2484 rc = RC_ST0;
2486 #endif
2488 r = gv(rc); /* generate value */
2489 /* if lvalue was saved on stack, must read it */
2490 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2491 SValue sv;
2492 t = get_reg(RC_INT);
2493 #ifdef TCC_TARGET_X86_64
2494 sv.type.t = VT_PTR;
2495 #else
2496 sv.type.t = VT_INT;
2497 #endif
2498 sv.r = VT_LOCAL | VT_LVAL;
2499 sv.c.ul = vtop[-1].c.ul;
2500 load(t, &sv);
2501 vtop[-1].r = t | VT_LVAL;
2503 store(r, vtop - 1);
2504 #ifndef TCC_TARGET_X86_64
2505 /* two word case handling : store second register at word + 4 */
2506 if ((ft & VT_BTYPE) == VT_LLONG) {
2507 vswap();
2508 /* convert to int to increment easily */
2509 vtop->type.t = VT_INT;
2510 gaddrof();
2511 vpushi(4);
2512 gen_op('+');
2513 vtop->r |= VT_LVAL;
2514 vswap();
2515 /* XXX: it works because r2 is spilled last ! */
2516 store(vtop->r2, vtop - 1);
2518 #endif
2520 vswap();
2521 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2522 vtop->r |= delayed_cast;
2526 /* post defines POST/PRE add. c is the token ++ or -- */
2527 ST_FUNC void inc(int post, int c)
2529 test_lvalue();
2530 vdup(); /* save lvalue */
2531 if (post) {
2532 gv_dup(); /* duplicate value */
2533 vrotb(3);
2534 vrotb(3);
2536 /* add constant */
2537 vpushi(c - TOK_MID);
2538 gen_op('+');
2539 vstore(); /* store value */
2540 if (post)
2541 vpop(); /* if post op, return saved value */
2544 /* Parse GNUC __attribute__ extension. Currently, the following
2545 extensions are recognized:
2546 - aligned(n) : set data/function alignment.
2547 - packed : force data alignment to 1
2548 - section(x) : generate data/code in this section.
2549 - unused : currently ignored, but may be used someday.
2550 - regparm(n) : pass function parameters in registers (i386 only)
2552 static void parse_attribute(AttributeDef *ad)
2554 int t, n;
2556 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2557 next();
2558 skip('(');
2559 skip('(');
2560 while (tok != ')') {
2561 if (tok < TOK_IDENT)
2562 expect("attribute name");
2563 t = tok;
2564 next();
2565 switch(t) {
2566 case TOK_SECTION1:
2567 case TOK_SECTION2:
2568 skip('(');
2569 if (tok != TOK_STR)
2570 expect("section name");
2571 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2572 next();
2573 skip(')');
2574 break;
2575 case TOK_ALIAS1:
2576 case TOK_ALIAS2:
2577 skip('(');
2578 if (tok != TOK_STR)
2579 expect("alias(\"target\")");
2580 ad->alias_target = /* save string as token, for later */
2581 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2582 next();
2583 skip(')');
2584 break;
2585 case TOK_ALIGNED1:
2586 case TOK_ALIGNED2:
2587 if (tok == '(') {
2588 next();
2589 n = expr_const();
2590 if (n <= 0 || (n & (n - 1)) != 0)
2591 tcc_error("alignment must be a positive power of two");
2592 skip(')');
2593 } else {
2594 n = MAX_ALIGN;
2596 ad->aligned = n;
2597 break;
2598 case TOK_PACKED1:
2599 case TOK_PACKED2:
2600 ad->packed = 1;
2601 break;
2602 case TOK_WEAK1:
2603 case TOK_WEAK2:
2604 ad->weak = 1;
2605 break;
2606 case TOK_UNUSED1:
2607 case TOK_UNUSED2:
2608 /* currently, no need to handle it because tcc does not
2609 track unused objects */
2610 break;
2611 case TOK_NORETURN1:
2612 case TOK_NORETURN2:
2613 /* currently, no need to handle it because tcc does not
2614 track unused objects */
2615 break;
2616 case TOK_CDECL1:
2617 case TOK_CDECL2:
2618 case TOK_CDECL3:
2619 ad->func_call = FUNC_CDECL;
2620 break;
2621 case TOK_STDCALL1:
2622 case TOK_STDCALL2:
2623 case TOK_STDCALL3:
2624 ad->func_call = FUNC_STDCALL;
2625 break;
2626 #ifdef TCC_TARGET_I386
2627 case TOK_REGPARM1:
2628 case TOK_REGPARM2:
2629 skip('(');
2630 n = expr_const();
2631 if (n > 3)
2632 n = 3;
2633 else if (n < 0)
2634 n = 0;
2635 if (n > 0)
2636 ad->func_call = FUNC_FASTCALL1 + n - 1;
2637 skip(')');
2638 break;
2639 case TOK_FASTCALL1:
2640 case TOK_FASTCALL2:
2641 case TOK_FASTCALL3:
2642 ad->func_call = FUNC_FASTCALLW;
2643 break;
2644 #endif
2645 case TOK_MODE:
2646 skip('(');
2647 switch(tok) {
2648 case TOK_MODE_DI:
2649 ad->mode = VT_LLONG + 1;
2650 break;
2651 case TOK_MODE_HI:
2652 ad->mode = VT_SHORT + 1;
2653 break;
2654 case TOK_MODE_SI:
2655 ad->mode = VT_INT + 1;
2656 break;
2657 default:
2658 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2659 break;
2661 next();
2662 skip(')');
2663 break;
2664 case TOK_DLLEXPORT:
2665 ad->func_export = 1;
2666 break;
2667 case TOK_DLLIMPORT:
2668 ad->func_import = 1;
2669 break;
2670 default:
2671 if (tcc_state->warn_unsupported)
2672 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2673 /* skip parameters */
2674 if (tok == '(') {
2675 int parenthesis = 0;
2676 do {
2677 if (tok == '(')
2678 parenthesis++;
2679 else if (tok == ')')
2680 parenthesis--;
2681 next();
2682 } while (parenthesis && tok != -1);
2684 break;
2686 if (tok != ',')
2687 break;
2688 next();
2690 skip(')');
2691 skip(')');
2695 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2696 static void struct_decl(CType *type, int u)
2698 int a, v, size, align, maxalign, c, offset;
2699 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2700 Sym *s, *ss, *ass, **ps;
2701 AttributeDef ad;
2702 CType type1, btype;
2704 a = tok; /* save decl type */
2705 next();
2706 if (tok != '{') {
2707 v = tok;
2708 next();
2709 /* struct already defined ? return it */
2710 if (v < TOK_IDENT)
2711 expect("struct/union/enum name");
2712 s = struct_find(v);
2713 if (s) {
2714 if (s->type.t != a)
2715 tcc_error("invalid type");
2716 goto do_decl;
2718 } else {
2719 v = anon_sym++;
2721 type1.t = a;
2722 type1.ref = 0;
2723 /* we put an undefined size for struct/union */
2724 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2725 s->r = 0; /* default alignment is zero as gcc */
2726 /* put struct/union/enum name in type */
2727 do_decl:
2728 type->t = u;
2729 type->ref = s;
2731 if (tok == '{') {
2732 next();
2733 if (s->c != -1)
2734 tcc_error("struct/union/enum already defined");
2735 /* cannot be empty */
2736 c = 0;
2737 /* non empty enums are not allowed */
2738 if (a == TOK_ENUM) {
2739 for(;;) {
2740 v = tok;
2741 if (v < TOK_UIDENT)
2742 expect("identifier");
2743 next();
2744 if (tok == '=') {
2745 next();
2746 c = expr_const();
2748 /* enum symbols have static storage */
2749 ss = sym_push(v, &int_type, VT_CONST, c);
2750 ss->type.t |= VT_STATIC;
2751 if (tok != ',')
2752 break;
2753 next();
2754 c++;
2755 /* NOTE: we accept a trailing comma */
2756 if (tok == '}')
2757 break;
2759 skip('}');
2760 } else {
2761 maxalign = 1;
2762 ps = &s->next;
2763 prevbt = VT_INT;
2764 bit_pos = 0;
2765 offset = 0;
2766 while (tok != '}') {
2767 parse_btype(&btype, &ad);
2768 while (1) {
2769 bit_size = -1;
2770 v = 0;
2771 type1 = btype;
2772 if (tok != ':') {
2773 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2774 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2775 expect("identifier");
2776 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2777 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2778 tcc_error("invalid type for '%s'",
2779 get_tok_str(v, NULL));
2781 if (tok == ':') {
2782 next();
2783 bit_size = expr_const();
2784 /* XXX: handle v = 0 case for messages */
2785 if (bit_size < 0)
2786 tcc_error("negative width in bit-field '%s'",
2787 get_tok_str(v, NULL));
2788 if (v && bit_size == 0)
2789 tcc_error("zero width for bit-field '%s'",
2790 get_tok_str(v, NULL));
2792 size = type_size(&type1, &align);
2793 if (ad.aligned) {
2794 if (align < ad.aligned)
2795 align = ad.aligned;
2796 } else if (ad.packed) {
2797 align = 1;
2798 } else if (*tcc_state->pack_stack_ptr) {
2799 if (align > *tcc_state->pack_stack_ptr)
2800 align = *tcc_state->pack_stack_ptr;
2802 lbit_pos = 0;
2803 if (bit_size >= 0) {
2804 bt = type1.t & VT_BTYPE;
2805 if (bt != VT_INT &&
2806 bt != VT_BYTE &&
2807 bt != VT_SHORT &&
2808 bt != VT_BOOL &&
2809 bt != VT_ENUM &&
2810 bt != VT_LLONG)
2811 tcc_error("bitfields must have scalar type");
2812 bsize = size * 8;
2813 if (bit_size > bsize) {
2814 tcc_error("width of '%s' exceeds its type",
2815 get_tok_str(v, NULL));
2816 } else if (bit_size == bsize) {
2817 /* no need for bit fields */
2818 bit_pos = 0;
2819 } else if (bit_size == 0) {
2820 /* XXX: what to do if only padding in a
2821 structure ? */
2822 /* zero size: means to pad */
2823 bit_pos = 0;
2824 } else {
2825 /* we do not have enough room ?
2826 did the type change?
2827 is it a union? */
2828 if ((bit_pos + bit_size) > bsize ||
2829 bt != prevbt || a == TOK_UNION)
2830 bit_pos = 0;
2831 lbit_pos = bit_pos;
2832 /* XXX: handle LSB first */
2833 type1.t |= VT_BITFIELD |
2834 (bit_pos << VT_STRUCT_SHIFT) |
2835 (bit_size << (VT_STRUCT_SHIFT + 6));
2836 bit_pos += bit_size;
2838 prevbt = bt;
2839 } else {
2840 bit_pos = 0;
2842 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2843 /* add new memory data only if starting
2844 bit field */
2845 if (lbit_pos == 0) {
2846 if (a == TOK_STRUCT) {
2847 c = (c + align - 1) & -align;
2848 offset = c;
2849 if (size > 0)
2850 c += size;
2851 } else {
2852 offset = 0;
2853 if (size > c)
2854 c = size;
2856 if (align > maxalign)
2857 maxalign = align;
2859 #if 0
2860 printf("add field %s offset=%d",
2861 get_tok_str(v, NULL), offset);
2862 if (type1.t & VT_BITFIELD) {
2863 printf(" pos=%d size=%d",
2864 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2865 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2867 printf("\n");
2868 #endif
2870 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2871 ass = type1.ref;
2872 while ((ass = ass->next) != NULL) {
2873 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2874 *ps = ss;
2875 ps = &ss->next;
2877 } else if (v) {
2878 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2879 *ps = ss;
2880 ps = &ss->next;
2882 if (tok == ';' || tok == TOK_EOF)
2883 break;
2884 skip(',');
2886 skip(';');
2888 skip('}');
2889 /* store size and alignment */
2890 s->c = (c + maxalign - 1) & -maxalign;
2891 s->r = maxalign;
2896 /* return 0 if no type declaration. otherwise, return the basic type
2897 and skip it.
2899 static int parse_btype(CType *type, AttributeDef *ad)
2901 int t, u, type_found, typespec_found, typedef_found;
2902 Sym *s;
2903 CType type1;
2905 memset(ad, 0, sizeof(AttributeDef));
2906 type_found = 0;
2907 typespec_found = 0;
2908 typedef_found = 0;
2909 t = 0;
2910 while(1) {
2911 switch(tok) {
2912 case TOK_EXTENSION:
2913 /* currently, we really ignore extension */
2914 next();
2915 continue;
2917 /* basic types */
2918 case TOK_CHAR:
2919 u = VT_BYTE;
2920 basic_type:
2921 next();
2922 basic_type1:
2923 if ((t & VT_BTYPE) != 0)
2924 tcc_error("too many basic types");
2925 t |= u;
2926 typespec_found = 1;
2927 break;
2928 case TOK_VOID:
2929 u = VT_VOID;
2930 goto basic_type;
2931 case TOK_SHORT:
2932 u = VT_SHORT;
2933 goto basic_type;
2934 case TOK_INT:
2935 next();
2936 typespec_found = 1;
2937 break;
2938 case TOK_LONG:
2939 next();
2940 if ((t & VT_BTYPE) == VT_DOUBLE) {
2941 #ifndef TCC_TARGET_PE
2942 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2943 #endif
2944 } else if ((t & VT_BTYPE) == VT_LONG) {
2945 t = (t & ~VT_BTYPE) | VT_LLONG;
2946 } else {
2947 u = VT_LONG;
2948 goto basic_type1;
2950 break;
2951 case TOK_BOOL:
2952 u = VT_BOOL;
2953 goto basic_type;
2954 case TOK_FLOAT:
2955 u = VT_FLOAT;
2956 goto basic_type;
2957 case TOK_DOUBLE:
2958 next();
2959 if ((t & VT_BTYPE) == VT_LONG) {
2960 #ifdef TCC_TARGET_PE
2961 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2962 #else
2963 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2964 #endif
2965 } else {
2966 u = VT_DOUBLE;
2967 goto basic_type1;
2969 break;
2970 case TOK_ENUM:
2971 struct_decl(&type1, VT_ENUM);
2972 basic_type2:
2973 u = type1.t;
2974 type->ref = type1.ref;
2975 goto basic_type1;
2976 case TOK_STRUCT:
2977 case TOK_UNION:
2978 struct_decl(&type1, VT_STRUCT);
2979 goto basic_type2;
2981 /* type modifiers */
2982 case TOK_CONST1:
2983 case TOK_CONST2:
2984 case TOK_CONST3:
2985 t |= VT_CONSTANT;
2986 next();
2987 break;
2988 case TOK_VOLATILE1:
2989 case TOK_VOLATILE2:
2990 case TOK_VOLATILE3:
2991 t |= VT_VOLATILE;
2992 next();
2993 break;
2994 case TOK_SIGNED1:
2995 case TOK_SIGNED2:
2996 case TOK_SIGNED3:
2997 typespec_found = 1;
2998 t |= VT_SIGNED;
2999 next();
3000 break;
3001 case TOK_REGISTER:
3002 case TOK_AUTO:
3003 case TOK_RESTRICT1:
3004 case TOK_RESTRICT2:
3005 case TOK_RESTRICT3:
3006 next();
3007 break;
3008 case TOK_UNSIGNED:
3009 t |= VT_UNSIGNED;
3010 next();
3011 typespec_found = 1;
3012 break;
3014 /* storage */
3015 case TOK_EXTERN:
3016 t |= VT_EXTERN;
3017 next();
3018 break;
3019 case TOK_STATIC:
3020 t |= VT_STATIC;
3021 next();
3022 break;
3023 case TOK_TYPEDEF:
3024 t |= VT_TYPEDEF;
3025 next();
3026 break;
3027 case TOK_INLINE1:
3028 case TOK_INLINE2:
3029 case TOK_INLINE3:
3030 t |= VT_INLINE;
3031 next();
3032 break;
3034 /* GNUC attribute */
3035 case TOK_ATTRIBUTE1:
3036 case TOK_ATTRIBUTE2:
3037 parse_attribute(ad);
3038 if (ad->mode) {
3039 u = ad->mode -1;
3040 t = (t & ~VT_BTYPE) | u;
3042 break;
3043 /* GNUC typeof */
3044 case TOK_TYPEOF1:
3045 case TOK_TYPEOF2:
3046 case TOK_TYPEOF3:
3047 next();
3048 parse_expr_type(&type1);
3049 /* remove all storage modifiers except typedef */
3050 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3051 goto basic_type2;
3052 default:
3053 if (typespec_found || typedef_found)
3054 goto the_end;
3055 s = sym_find(tok);
3056 if (!s || !(s->type.t & VT_TYPEDEF))
3057 goto the_end;
3058 typedef_found = 1;
3059 t |= (s->type.t & ~VT_TYPEDEF);
3060 type->ref = s->type.ref;
3061 if (s->r) {
3062 /* get attributes from typedef */
3063 if (0 == ad->aligned)
3064 ad->aligned = FUNC_ALIGN(s->r);
3065 if (0 == ad->func_call)
3066 ad->func_call = FUNC_CALL(s->r);
3067 ad->packed |= FUNC_PACKED(s->r);
3069 next();
3070 typespec_found = 1;
3071 break;
3073 type_found = 1;
3075 the_end:
3076 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3077 tcc_error("signed and unsigned modifier");
3078 if (tcc_state->char_is_unsigned) {
3079 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3080 t |= VT_UNSIGNED;
3082 t &= ~VT_SIGNED;
3084 /* long is never used as type */
3085 if ((t & VT_BTYPE) == VT_LONG)
3086 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3087 t = (t & ~VT_BTYPE) | VT_INT;
3088 #else
3089 t = (t & ~VT_BTYPE) | VT_LLONG;
3090 #endif
3091 type->t = t;
3092 return type_found;
3095 /* convert a function parameter type (array to pointer and function to
3096 function pointer) */
3097 static inline void convert_parameter_type(CType *pt)
3099 /* remove const and volatile qualifiers (XXX: const could be used
3100 to indicate a const function parameter */
3101 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3102 /* array must be transformed to pointer according to ANSI C */
3103 pt->t &= ~VT_ARRAY;
3104 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3105 mk_pointer(pt);
3109 ST_FUNC void parse_asm_str(CString *astr)
3111 skip('(');
3112 /* read the string */
3113 if (tok != TOK_STR)
3114 expect("string constant");
3115 cstr_new(astr);
3116 while (tok == TOK_STR) {
3117 /* XXX: add \0 handling too ? */
3118 cstr_cat(astr, tokc.cstr->data);
3119 next();
3121 cstr_ccat(astr, '\0');
3124 /* Parse an asm label and return the label
3125 * Don't forget to free the CString in the caller! */
3126 static void asm_label_instr(CString *astr)
3128 next();
3129 parse_asm_str(astr);
3130 skip(')');
3131 #ifdef ASM_DEBUG
3132 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3133 #endif
3136 static void post_type(CType *type, AttributeDef *ad)
3138 int n, l, t1, arg_size, align;
3139 Sym **plast, *s, *first;
3140 AttributeDef ad1;
3141 CType pt;
3143 if (tok == '(') {
3144 /* function declaration */
3145 next();
3146 l = 0;
3147 first = NULL;
3148 plast = &first;
3149 arg_size = 0;
3150 if (tok != ')') {
3151 for(;;) {
3152 /* read param name and compute offset */
3153 if (l != FUNC_OLD) {
3154 if (!parse_btype(&pt, &ad1)) {
3155 if (l) {
3156 tcc_error("invalid type");
3157 } else {
3158 l = FUNC_OLD;
3159 goto old_proto;
3162 l = FUNC_NEW;
3163 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3164 break;
3165 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3166 if ((pt.t & VT_BTYPE) == VT_VOID)
3167 tcc_error("parameter declared as void");
3168 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3169 } else {
3170 old_proto:
3171 n = tok;
3172 if (n < TOK_UIDENT)
3173 expect("identifier");
3174 pt.t = VT_INT;
3175 next();
3177 convert_parameter_type(&pt);
3178 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3179 *plast = s;
3180 plast = &s->next;
3181 if (tok == ')')
3182 break;
3183 skip(',');
3184 if (l == FUNC_NEW && tok == TOK_DOTS) {
3185 l = FUNC_ELLIPSIS;
3186 next();
3187 break;
3191 /* if no parameters, then old type prototype */
3192 if (l == 0)
3193 l = FUNC_OLD;
3194 skip(')');
3195 /* NOTE: const is ignored in returned type as it has a special
3196 meaning in gcc / C++ */
3197 type->t &= ~VT_CONSTANT;
3198 /* some ancient pre-K&R C allows a function to return an array
3199 and the array brackets to be put after the arguments, such
3200 that "int c()[]" means something like "int[] c()" */
3201 if (tok == '[') {
3202 next();
3203 skip(']'); /* only handle simple "[]" */
3204 type->t |= VT_PTR;
3206 /* we push a anonymous symbol which will contain the function prototype */
3207 ad->func_args = arg_size;
3208 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3209 s->next = first;
3210 type->t = VT_FUNC;
3211 type->ref = s;
3212 } else if (tok == '[') {
3213 /* array definition */
3214 next();
3215 if (tok == TOK_RESTRICT1)
3216 next();
3217 n = -1;
3218 t1 = 0;
3219 if (tok != ']') {
3220 if (!local_stack || nocode_wanted)
3221 vpushi(expr_const());
3222 else gexpr();
3223 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3224 n = vtop->c.i;
3225 if (n < 0)
3226 tcc_error("invalid array size");
3227 } else {
3228 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3229 tcc_error("size of variable length array should be an integer");
3230 t1 = VT_VLA;
3233 skip(']');
3234 /* parse next post type */
3235 post_type(type, ad);
3236 t1 |= type->t & VT_VLA;
3238 if (t1 & VT_VLA) {
3239 loc -= type_size(&int_type, &align);
3240 loc &= -align;
3241 n = loc;
3243 vla_runtime_type_size(type, &align);
3244 gen_op('*');
3245 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3246 vswap();
3247 vstore();
3249 if (n != -1)
3250 vpop();
3252 /* we push an anonymous symbol which will contain the array
3253 element type */
3254 s = sym_push(SYM_FIELD, type, 0, n);
3255 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3256 type->ref = s;
3260 /* Parse a type declaration (except basic type), and return the type
3261 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3262 expected. 'type' should contain the basic type. 'ad' is the
3263 attribute definition of the basic type. It can be modified by
3264 type_decl().
3266 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3268 Sym *s;
3269 CType type1, *type2;
3270 int qualifiers, storage;
3272 while (tok == '*') {
3273 qualifiers = 0;
3274 redo:
3275 next();
3276 switch(tok) {
3277 case TOK_CONST1:
3278 case TOK_CONST2:
3279 case TOK_CONST3:
3280 qualifiers |= VT_CONSTANT;
3281 goto redo;
3282 case TOK_VOLATILE1:
3283 case TOK_VOLATILE2:
3284 case TOK_VOLATILE3:
3285 qualifiers |= VT_VOLATILE;
3286 goto redo;
3287 case TOK_RESTRICT1:
3288 case TOK_RESTRICT2:
3289 case TOK_RESTRICT3:
3290 goto redo;
3292 mk_pointer(type);
3293 type->t |= qualifiers;
3296 /* XXX: clarify attribute handling */
3297 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3298 parse_attribute(ad);
3300 /* recursive type */
3301 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3302 type1.t = 0; /* XXX: same as int */
3303 if (tok == '(') {
3304 next();
3305 /* XXX: this is not correct to modify 'ad' at this point, but
3306 the syntax is not clear */
3307 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3308 parse_attribute(ad);
3309 type_decl(&type1, ad, v, td);
3310 skip(')');
3311 } else {
3312 /* type identifier */
3313 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3314 *v = tok;
3315 next();
3316 } else {
3317 if (!(td & TYPE_ABSTRACT))
3318 expect("identifier");
3319 *v = 0;
3322 storage = type->t & VT_STORAGE;
3323 type->t &= ~VT_STORAGE;
3324 if (storage & VT_STATIC) {
3325 int saved_nocode_wanted = nocode_wanted;
3326 nocode_wanted = 1;
3327 post_type(type, ad);
3328 nocode_wanted = saved_nocode_wanted;
3329 } else
3330 post_type(type, ad);
3331 type->t |= storage;
3332 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3333 parse_attribute(ad);
3335 if (!type1.t)
3336 return;
3337 /* append type at the end of type1 */
3338 type2 = &type1;
3339 for(;;) {
3340 s = type2->ref;
3341 type2 = &s->type;
3342 if (!type2->t) {
3343 *type2 = *type;
3344 break;
3347 *type = type1;
3350 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3351 ST_FUNC int lvalue_type(int t)
3353 int bt, r;
3354 r = VT_LVAL;
3355 bt = t & VT_BTYPE;
3356 if (bt == VT_BYTE || bt == VT_BOOL)
3357 r |= VT_LVAL_BYTE;
3358 else if (bt == VT_SHORT)
3359 r |= VT_LVAL_SHORT;
3360 else
3361 return r;
3362 if (t & VT_UNSIGNED)
3363 r |= VT_LVAL_UNSIGNED;
3364 return r;
3367 /* indirection with full error checking and bound check */
3368 ST_FUNC void indir(void)
3370 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3371 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3372 return;
3373 expect("pointer");
3375 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3376 gv(RC_INT);
3377 vtop->type = *pointed_type(&vtop->type);
3378 /* Arrays and functions are never lvalues */
3379 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3380 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3381 vtop->r |= lvalue_type(vtop->type.t);
3382 /* if bound checking, the referenced pointer must be checked */
3383 #ifdef CONFIG_TCC_BCHECK
3384 if (tcc_state->do_bounds_check)
3385 vtop->r |= VT_MUSTBOUND;
3386 #endif
3390 /* pass a parameter to a function and do type checking and casting */
3391 static void gfunc_param_typed(Sym *func, Sym *arg)
3393 int func_type;
3394 CType type;
3396 func_type = func->c;
3397 if (func_type == FUNC_OLD ||
3398 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3399 /* default casting : only need to convert float to double */
3400 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3401 type.t = VT_DOUBLE;
3402 type.ref = 0;
3403 gen_cast(&type);
3405 } else if (arg == NULL) {
3406 tcc_error("too many arguments to function");
3407 } else {
3408 type = arg->type;
3409 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3410 gen_assign_cast(&type);
3414 /* parse an expression of the form '(type)' or '(expr)' and return its
3415 type */
3416 static void parse_expr_type(CType *type)
3418 int n;
3419 AttributeDef ad;
3421 skip('(');
3422 if (parse_btype(type, &ad)) {
3423 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3424 } else {
3425 expr_type(type);
3427 skip(')');
3430 static void parse_type(CType *type)
3432 AttributeDef ad;
3433 int n;
3435 if (!parse_btype(type, &ad)) {
3436 expect("type");
3438 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3441 static void vpush_tokc(int t)
3443 CType type;
3444 type.t = t;
3445 type.ref = 0;
3446 vsetc(&type, VT_CONST, &tokc);
3449 ST_FUNC void unary(void)
3451 int n, t, align, size, r, sizeof_caller;
3452 CType type;
3453 Sym *s;
3454 AttributeDef ad;
3455 static int in_sizeof = 0;
3457 sizeof_caller = in_sizeof;
3458 in_sizeof = 0;
3459 /* XXX: GCC 2.95.3 does not generate a table although it should be
3460 better here */
3461 tok_next:
3462 switch(tok) {
3463 case TOK_EXTENSION:
3464 next();
3465 goto tok_next;
3466 case TOK_CINT:
3467 case TOK_CCHAR:
3468 case TOK_LCHAR:
3469 vpushi(tokc.i);
3470 next();
3471 break;
3472 case TOK_CUINT:
3473 vpush_tokc(VT_INT | VT_UNSIGNED);
3474 next();
3475 break;
3476 case TOK_CLLONG:
3477 vpush_tokc(VT_LLONG);
3478 next();
3479 break;
3480 case TOK_CULLONG:
3481 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3482 next();
3483 break;
3484 case TOK_CFLOAT:
3485 vpush_tokc(VT_FLOAT);
3486 next();
3487 break;
3488 case TOK_CDOUBLE:
3489 vpush_tokc(VT_DOUBLE);
3490 next();
3491 break;
3492 case TOK_CLDOUBLE:
3493 vpush_tokc(VT_LDOUBLE);
3494 next();
3495 break;
3496 case TOK___FUNCTION__:
3497 if (!gnu_ext)
3498 goto tok_identifier;
3499 /* fall thru */
3500 case TOK___FUNC__:
3502 void *ptr;
3503 int len;
3504 /* special function name identifier */
3505 len = strlen(funcname) + 1;
3506 /* generate char[len] type */
3507 type.t = VT_BYTE;
3508 mk_pointer(&type);
3509 type.t |= VT_ARRAY;
3510 type.ref->c = len;
3511 vpush_ref(&type, data_section, data_section->data_offset, len);
3512 ptr = section_ptr_add(data_section, len);
3513 memcpy(ptr, funcname, len);
3514 next();
3516 break;
3517 case TOK_LSTR:
3518 #ifdef TCC_TARGET_PE
3519 t = VT_SHORT | VT_UNSIGNED;
3520 #else
3521 t = VT_INT;
3522 #endif
3523 goto str_init;
3524 case TOK_STR:
3525 /* string parsing */
3526 t = VT_BYTE;
3527 str_init:
3528 if (tcc_state->warn_write_strings)
3529 t |= VT_CONSTANT;
3530 type.t = t;
3531 mk_pointer(&type);
3532 type.t |= VT_ARRAY;
3533 memset(&ad, 0, sizeof(AttributeDef));
3534 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3535 break;
3536 case '(':
3537 next();
3538 /* cast ? */
3539 if (parse_btype(&type, &ad)) {
3540 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3541 skip(')');
3542 /* check ISOC99 compound literal */
3543 if (tok == '{') {
3544 /* data is allocated locally by default */
3545 if (global_expr)
3546 r = VT_CONST;
3547 else
3548 r = VT_LOCAL;
3549 /* all except arrays are lvalues */
3550 if (!(type.t & VT_ARRAY))
3551 r |= lvalue_type(type.t);
3552 memset(&ad, 0, sizeof(AttributeDef));
3553 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3554 } else {
3555 if (sizeof_caller) {
3556 vpush(&type);
3557 return;
3559 unary();
3560 gen_cast(&type);
3562 } else if (tok == '{') {
3563 /* save all registers */
3564 save_regs(0);
3565 /* statement expression : we do not accept break/continue
3566 inside as GCC does */
3567 block(NULL, NULL, NULL, NULL, 0, 1);
3568 skip(')');
3569 } else {
3570 gexpr();
3571 skip(')');
3573 break;
3574 case '*':
3575 next();
3576 unary();
3577 indir();
3578 break;
3579 case '&':
3580 next();
3581 unary();
3582 /* functions names must be treated as function pointers,
3583 except for unary '&' and sizeof. Since we consider that
3584 functions are not lvalues, we only have to handle it
3585 there and in function calls. */
3586 /* arrays can also be used although they are not lvalues */
3587 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3588 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3589 test_lvalue();
3590 mk_pointer(&vtop->type);
3591 gaddrof();
3592 break;
3593 case '!':
3594 next();
3595 unary();
3596 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3597 CType boolean;
3598 boolean.t = VT_BOOL;
3599 boolean.ref = 0;
3600 gen_cast(&boolean);
3601 vtop->c.i = !vtop->c.i;
3602 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3603 vtop->c.i = vtop->c.i ^ 1;
3604 else {
3605 save_regs(1);
3606 vseti(VT_JMP, gtst(1, 0));
3608 break;
3609 case '~':
3610 next();
3611 unary();
3612 vpushi(-1);
3613 gen_op('^');
3614 break;
3615 case '+':
3616 next();
3617 /* in order to force cast, we add zero */
3618 unary();
3619 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3620 tcc_error("pointer not accepted for unary plus");
3621 vpushi(0);
3622 gen_op('+');
3623 break;
3624 case TOK_SIZEOF:
3625 case TOK_ALIGNOF1:
3626 case TOK_ALIGNOF2:
3627 t = tok;
3628 next();
3629 in_sizeof++;
3630 unary_type(&type); // Perform a in_sizeof = 0;
3631 size = type_size(&type, &align);
3632 if (t == TOK_SIZEOF) {
3633 if (!(type.t & VT_VLA)) {
3634 if (size < 0)
3635 tcc_error("sizeof applied to an incomplete type");
3636 vpushs(size);
3637 } else {
3638 vla_runtime_type_size(&type, &align);
3640 } else {
3641 vpushs(align);
3643 vtop->type.t |= VT_UNSIGNED;
3644 break;
3646 case TOK_builtin_types_compatible_p:
3648 CType type1, type2;
3649 next();
3650 skip('(');
3651 parse_type(&type1);
3652 skip(',');
3653 parse_type(&type2);
3654 skip(')');
3655 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3656 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3657 vpushi(is_compatible_types(&type1, &type2));
3659 break;
3660 case TOK_builtin_constant_p:
3662 int saved_nocode_wanted, res;
3663 next();
3664 skip('(');
3665 saved_nocode_wanted = nocode_wanted;
3666 nocode_wanted = 1;
3667 gexpr();
3668 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3669 vpop();
3670 nocode_wanted = saved_nocode_wanted;
3671 skip(')');
3672 vpushi(res);
3674 break;
3675 case TOK_builtin_frame_address:
3677 int level;
3678 CType type;
3679 next();
3680 skip('(');
3681 if (tok != TOK_CINT || tokc.i < 0) {
3682 tcc_error("__builtin_frame_address only takes positive integers");
3684 level = tokc.i;
3685 next();
3686 skip(')');
3687 type.t = VT_VOID;
3688 mk_pointer(&type);
3689 vset(&type, VT_LOCAL, 0); /* local frame */
3690 while (level--) {
3691 mk_pointer(&vtop->type);
3692 indir(); /* -> parent frame */
3695 break;
3696 #ifdef TCC_TARGET_X86_64
3697 case TOK_builtin_va_arg_types:
3699 /* This definition must be synced with stdarg.h */
3700 enum __va_arg_type {
3701 __va_gen_reg, __va_float_reg, __va_stack
3703 CType type;
3704 int bt;
3705 next();
3706 skip('(');
3707 parse_type(&type);
3708 skip(')');
3709 bt = type.t & VT_BTYPE;
3710 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3711 vpushi(__va_stack);
3712 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3713 vpushi(__va_float_reg);
3714 } else {
3715 vpushi(__va_gen_reg);
3718 break;
3719 #endif
3720 case TOK_INC:
3721 case TOK_DEC:
3722 t = tok;
3723 next();
3724 unary();
3725 inc(0, t);
3726 break;
3727 case '-':
3728 next();
3729 vpushi(0);
3730 unary();
3731 gen_op('-');
3732 break;
3733 case TOK_LAND:
3734 if (!gnu_ext)
3735 goto tok_identifier;
3736 next();
3737 /* allow to take the address of a label */
3738 if (tok < TOK_UIDENT)
3739 expect("label identifier");
3740 s = label_find(tok);
3741 if (!s) {
3742 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3743 } else {
3744 if (s->r == LABEL_DECLARED)
3745 s->r = LABEL_FORWARD;
3747 if (!s->type.t) {
3748 s->type.t = VT_VOID;
3749 mk_pointer(&s->type);
3750 s->type.t |= VT_STATIC;
3752 vset(&s->type, VT_CONST | VT_SYM, 0);
3753 vtop->sym = s;
3754 next();
3755 break;
3757 // special qnan , snan and infinity values
3758 case TOK___NAN__:
3759 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3760 next();
3761 break;
3762 case TOK___SNAN__:
3763 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3764 next();
3765 break;
3766 case TOK___INF__:
3767 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3768 next();
3769 break;
3771 default:
3772 tok_identifier:
3773 t = tok;
3774 next();
3775 if (t < TOK_UIDENT)
3776 expect("identifier");
3777 s = sym_find(t);
3778 if (!s) {
3779 if (tok != '(')
3780 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
3781 /* for simple function calls, we tolerate undeclared
3782 external reference to int() function */
3783 if (tcc_state->warn_implicit_function_declaration)
3784 tcc_warning("implicit declaration of function '%s'",
3785 get_tok_str(t, NULL));
3786 s = external_global_sym(t, &func_old_type, 0);
3788 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3789 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3790 /* if referencing an inline function, then we generate a
3791 symbol to it if not already done. It will have the
3792 effect to generate code for it at the end of the
3793 compilation unit. Inline function as always
3794 generated in the text section. */
3795 if (!s->c)
3796 put_extern_sym(s, text_section, 0, 0);
3797 r = VT_SYM | VT_CONST;
3798 } else {
3799 r = s->r;
3801 vset(&s->type, r, s->c);
3802 /* if forward reference, we must point to s */
3803 if (vtop->r & VT_SYM) {
3804 vtop->sym = s;
3805 vtop->c.ul = 0;
3807 break;
3810 /* post operations */
3811 while (1) {
3812 if (tok == TOK_INC || tok == TOK_DEC) {
3813 inc(1, tok);
3814 next();
3815 } else if (tok == '.' || tok == TOK_ARROW) {
3816 int qualifiers;
3817 /* field */
3818 if (tok == TOK_ARROW)
3819 indir();
3820 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3821 test_lvalue();
3822 gaddrof();
3823 next();
3824 /* expect pointer on structure */
3825 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3826 expect("struct or union");
3827 s = vtop->type.ref;
3828 /* find field */
3829 tok |= SYM_FIELD;
3830 while ((s = s->next) != NULL) {
3831 if (s->v == tok)
3832 break;
3834 if (!s)
3835 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3836 /* add field offset to pointer */
3837 vtop->type = char_pointer_type; /* change type to 'char *' */
3838 vpushi(s->c);
3839 gen_op('+');
3840 /* change type to field type, and set to lvalue */
3841 vtop->type = s->type;
3842 vtop->type.t |= qualifiers;
3843 /* an array is never an lvalue */
3844 if (!(vtop->type.t & VT_ARRAY)) {
3845 vtop->r |= lvalue_type(vtop->type.t);
3846 #ifdef CONFIG_TCC_BCHECK
3847 /* if bound checking, the referenced pointer must be checked */
3848 if (tcc_state->do_bounds_check)
3849 vtop->r |= VT_MUSTBOUND;
3850 #endif
3852 next();
3853 } else if (tok == '[') {
3854 next();
3855 gexpr();
3856 gen_op('+');
3857 indir();
3858 skip(']');
3859 } else if (tok == '(') {
3860 SValue ret;
3861 Sym *sa;
3862 int nb_args;
3864 /* function call */
3865 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3866 /* pointer test (no array accepted) */
3867 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3868 vtop->type = *pointed_type(&vtop->type);
3869 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3870 goto error_func;
3871 } else {
3872 error_func:
3873 expect("function pointer");
3875 } else {
3876 vtop->r &= ~VT_LVAL; /* no lvalue */
3878 /* get return type */
3879 s = vtop->type.ref;
3880 next();
3881 sa = s->next; /* first parameter */
3882 nb_args = 0;
3883 ret.r2 = VT_CONST;
3884 /* compute first implicit argument if a structure is returned */
3885 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3886 /* get some space for the returned structure */
3887 size = type_size(&s->type, &align);
3888 loc = (loc - size) & -align;
3889 ret.type = s->type;
3890 ret.r = VT_LOCAL | VT_LVAL;
3891 /* pass it as 'int' to avoid structure arg passing
3892 problems */
3893 vseti(VT_LOCAL, loc);
3894 ret.c = vtop->c;
3895 nb_args++;
3896 } else {
3897 ret.type = s->type;
3898 /* return in register */
3899 if (is_float(ret.type.t)) {
3900 ret.r = reg_fret(ret.type.t);
3901 } else {
3902 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3903 ret.r2 = REG_LRET;
3904 ret.r = REG_IRET;
3906 ret.c.i = 0;
3908 if (tok != ')') {
3909 for(;;) {
3910 expr_eq();
3911 gfunc_param_typed(s, sa);
3912 nb_args++;
3913 if (sa)
3914 sa = sa->next;
3915 if (tok == ')')
3916 break;
3917 skip(',');
3920 if (sa)
3921 tcc_error("too few arguments to function");
3922 skip(')');
3923 if (!nocode_wanted) {
3924 gfunc_call(nb_args);
3925 } else {
3926 vtop -= (nb_args + 1);
3928 /* return value */
3929 vsetc(&ret.type, ret.r, &ret.c);
3930 vtop->r2 = ret.r2;
3931 } else {
3932 break;
3937 ST_FUNC void expr_prod(void)
3939 int t;
3941 unary();
3942 while (tok == '*' || tok == '/' || tok == '%') {
3943 t = tok;
3944 next();
3945 unary();
3946 gen_op(t);
3950 ST_FUNC void expr_sum(void)
3952 int t;
3954 expr_prod();
3955 while (tok == '+' || tok == '-') {
3956 t = tok;
3957 next();
3958 expr_prod();
3959 gen_op(t);
3963 static void expr_shift(void)
3965 int t;
3967 expr_sum();
3968 while (tok == TOK_SHL || tok == TOK_SAR) {
3969 t = tok;
3970 next();
3971 expr_sum();
3972 gen_op(t);
3976 static void expr_cmp(void)
3978 int t;
3980 expr_shift();
3981 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3982 tok == TOK_ULT || tok == TOK_UGE) {
3983 t = tok;
3984 next();
3985 expr_shift();
3986 gen_op(t);
3990 static void expr_cmpeq(void)
3992 int t;
3994 expr_cmp();
3995 while (tok == TOK_EQ || tok == TOK_NE) {
3996 t = tok;
3997 next();
3998 expr_cmp();
3999 gen_op(t);
4003 static void expr_and(void)
4005 expr_cmpeq();
4006 while (tok == '&') {
4007 next();
4008 expr_cmpeq();
4009 gen_op('&');
4013 static void expr_xor(void)
4015 expr_and();
4016 while (tok == '^') {
4017 next();
4018 expr_and();
4019 gen_op('^');
4023 static void expr_or(void)
4025 expr_xor();
4026 while (tok == '|') {
4027 next();
4028 expr_xor();
4029 gen_op('|');
4033 /* XXX: fix this mess */
4034 static void expr_land_const(void)
4036 expr_or();
4037 while (tok == TOK_LAND) {
4038 next();
4039 expr_or();
4040 gen_op(TOK_LAND);
4044 /* XXX: fix this mess */
4045 static void expr_lor_const(void)
4047 expr_land_const();
4048 while (tok == TOK_LOR) {
4049 next();
4050 expr_land_const();
4051 gen_op(TOK_LOR);
4055 /* only used if non constant */
4056 static void expr_land(void)
4058 int t;
4060 expr_or();
4061 if (tok == TOK_LAND) {
4062 t = 0;
4063 save_regs(1);
4064 for(;;) {
4065 t = gtst(1, t);
4066 if (tok != TOK_LAND) {
4067 vseti(VT_JMPI, t);
4068 break;
4070 next();
4071 expr_or();
4076 static void expr_lor(void)
4078 int t;
4080 expr_land();
4081 if (tok == TOK_LOR) {
4082 t = 0;
4083 save_regs(1);
4084 for(;;) {
4085 t = gtst(0, t);
4086 if (tok != TOK_LOR) {
4087 vseti(VT_JMP, t);
4088 break;
4090 next();
4091 expr_land();
4096 /* XXX: better constant handling */
4097 static void expr_cond(void)
4099 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4100 SValue sv;
4101 CType type, type1, type2;
4103 if (const_wanted) {
4104 expr_lor_const();
4105 if (tok == '?') {
4106 CType boolean;
4107 int c;
4108 boolean.t = VT_BOOL;
4109 boolean.ref = 0;
4110 vdup();
4111 gen_cast(&boolean);
4112 c = vtop->c.i;
4113 vpop();
4114 next();
4115 if (tok != ':' || !gnu_ext) {
4116 vpop();
4117 gexpr();
4119 if (!c)
4120 vpop();
4121 skip(':');
4122 expr_cond();
4123 if (c)
4124 vpop();
4126 } else {
4127 expr_lor();
4128 if (tok == '?') {
4129 next();
4130 if (vtop != vstack) {
4131 /* needed to avoid having different registers saved in
4132 each branch */
4133 if (is_float(vtop->type.t)) {
4134 rc = RC_FLOAT;
4135 #ifdef TCC_TARGET_X86_64
4136 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4137 rc = RC_ST0;
4139 #endif
4141 else
4142 rc = RC_INT;
4143 gv(rc);
4144 save_regs(1);
4146 if (tok == ':' && gnu_ext) {
4147 gv_dup();
4148 tt = gtst(1, 0);
4149 } else {
4150 tt = gtst(1, 0);
4151 gexpr();
4153 type1 = vtop->type;
4154 sv = *vtop; /* save value to handle it later */
4155 vtop--; /* no vpop so that FP stack is not flushed */
4156 skip(':');
4157 u = gjmp(0);
4158 gsym(tt);
4159 expr_cond();
4160 type2 = vtop->type;
4162 t1 = type1.t;
4163 bt1 = t1 & VT_BTYPE;
4164 t2 = type2.t;
4165 bt2 = t2 & VT_BTYPE;
4166 /* cast operands to correct type according to ISOC rules */
4167 if (is_float(bt1) || is_float(bt2)) {
4168 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4169 type.t = VT_LDOUBLE;
4170 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4171 type.t = VT_DOUBLE;
4172 } else {
4173 type.t = VT_FLOAT;
4175 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4176 /* cast to biggest op */
4177 type.t = VT_LLONG;
4178 /* convert to unsigned if it does not fit in a long long */
4179 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4180 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4181 type.t |= VT_UNSIGNED;
4182 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4183 /* If one is a null ptr constant the result type
4184 is the other. */
4185 if (is_null_pointer (vtop))
4186 type = type1;
4187 else if (is_null_pointer (&sv))
4188 type = type2;
4189 /* XXX: test pointer compatibility, C99 has more elaborate
4190 rules here. */
4191 else
4192 type = type1;
4193 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4194 /* XXX: test function pointer compatibility */
4195 type = bt1 == VT_FUNC ? type1 : type2;
4196 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4197 /* XXX: test structure compatibility */
4198 type = bt1 == VT_STRUCT ? type1 : type2;
4199 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4200 /* NOTE: as an extension, we accept void on only one side */
4201 type.t = VT_VOID;
4202 } else {
4203 /* integer operations */
4204 type.t = VT_INT;
4205 /* convert to unsigned if it does not fit in an integer */
4206 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4207 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4208 type.t |= VT_UNSIGNED;
4211 /* now we convert second operand */
4212 gen_cast(&type);
4213 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4214 gaddrof();
4215 rc = RC_INT;
4216 if (is_float(type.t)) {
4217 rc = RC_FLOAT;
4218 #ifdef TCC_TARGET_X86_64
4219 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4220 rc = RC_ST0;
4222 #endif
4223 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4224 /* for long longs, we use fixed registers to avoid having
4225 to handle a complicated move */
4226 rc = RC_IRET;
4229 r2 = gv(rc);
4230 /* this is horrible, but we must also convert first
4231 operand */
4232 tt = gjmp(0);
4233 gsym(u);
4234 /* put again first value and cast it */
4235 *vtop = sv;
4236 gen_cast(&type);
4237 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4238 gaddrof();
4239 r1 = gv(rc);
4240 move_reg(r2, r1);
4241 vtop->r = r2;
4242 gsym(tt);
4247 static void expr_eq(void)
4249 int t;
4251 expr_cond();
4252 if (tok == '=' ||
4253 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4254 tok == TOK_A_XOR || tok == TOK_A_OR ||
4255 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4256 test_lvalue();
4257 t = tok;
4258 next();
4259 if (t == '=') {
4260 expr_eq();
4261 } else {
4262 vdup();
4263 expr_eq();
4264 gen_op(t & 0x7f);
4266 vstore();
4270 ST_FUNC void gexpr(void)
4272 while (1) {
4273 expr_eq();
4274 if (tok != ',')
4275 break;
4276 vpop();
4277 next();
4281 /* parse an expression and return its type without any side effect. */
4282 static void expr_type(CType *type)
4284 int saved_nocode_wanted;
4286 saved_nocode_wanted = nocode_wanted;
4287 nocode_wanted = 1;
4288 gexpr();
4289 *type = vtop->type;
4290 vpop();
4291 nocode_wanted = saved_nocode_wanted;
4294 /* parse a unary expression and return its type without any side
4295 effect. */
4296 static void unary_type(CType *type)
4298 int a;
4300 a = nocode_wanted;
4301 nocode_wanted = 1;
4302 unary();
4303 *type = vtop->type;
4304 vpop();
4305 nocode_wanted = a;
4308 /* parse a constant expression and return value in vtop. */
4309 static void expr_const1(void)
4311 int a;
4312 a = const_wanted;
4313 const_wanted = 1;
4314 expr_cond();
4315 const_wanted = a;
4318 /* parse an integer constant and return its value. */
4319 ST_FUNC int expr_const(void)
4321 int c;
4322 expr_const1();
4323 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4324 expect("constant expression");
4325 c = vtop->c.i;
4326 vpop();
4327 return c;
4330 /* return the label token if current token is a label, otherwise
4331 return zero */
4332 static int is_label(void)
4334 int last_tok;
4336 /* fast test first */
4337 if (tok < TOK_UIDENT)
4338 return 0;
4339 /* no need to save tokc because tok is an identifier */
4340 last_tok = tok;
4341 next();
4342 if (tok == ':') {
4343 next();
4344 return last_tok;
4345 } else {
4346 unget_tok(last_tok);
4347 return 0;
4351 static void label_or_decl(int l)
4353 int last_tok;
4355 /* fast test first */
4356 if (tok >= TOK_UIDENT)
4358 /* no need to save tokc because tok is an identifier */
4359 last_tok = tok;
4360 next();
4361 if (tok == ':') {
4362 unget_tok(last_tok);
4363 return;
4365 unget_tok(last_tok);
4367 decl(l);
4370 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4371 int case_reg, int is_expr)
4373 int a, b, c, d;
4374 Sym *s, *frame_bottom;
4376 /* generate line number info */
4377 if (tcc_state->do_debug &&
4378 (last_line_num != file->line_num || last_ind != ind)) {
4379 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4380 last_ind = ind;
4381 last_line_num = file->line_num;
4384 if (is_expr) {
4385 /* default return value is (void) */
4386 vpushi(0);
4387 vtop->type.t = VT_VOID;
4390 if (tok == TOK_IF) {
4391 /* if test */
4392 next();
4393 skip('(');
4394 gexpr();
4395 skip(')');
4396 a = gtst(1, 0);
4397 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4398 c = tok;
4399 if (c == TOK_ELSE) {
4400 next();
4401 d = gjmp(0);
4402 gsym(a);
4403 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4404 gsym(d); /* patch else jmp */
4405 } else
4406 gsym(a);
4407 } else if (tok == TOK_WHILE) {
4408 next();
4409 d = ind;
4410 skip('(');
4411 gexpr();
4412 skip(')');
4413 a = gtst(1, 0);
4414 b = 0;
4415 block(&a, &b, case_sym, def_sym, case_reg, 0);
4416 gjmp_addr(d);
4417 gsym(a);
4418 gsym_addr(b, d);
4419 } else if (tok == '{') {
4420 Sym *llabel;
4422 next();
4423 /* record local declaration stack position */
4424 s = local_stack;
4425 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4426 frame_bottom->next = scope_stack_bottom;
4427 scope_stack_bottom = frame_bottom;
4428 llabel = local_label_stack;
4429 /* handle local labels declarations */
4430 if (tok == TOK_LABEL) {
4431 next();
4432 for(;;) {
4433 if (tok < TOK_UIDENT)
4434 expect("label identifier");
4435 label_push(&local_label_stack, tok, LABEL_DECLARED);
4436 next();
4437 if (tok == ',') {
4438 next();
4439 } else {
4440 skip(';');
4441 break;
4445 while (tok != '}') {
4446 label_or_decl(VT_LOCAL);
4447 if (tok != '}') {
4448 if (is_expr)
4449 vpop();
4450 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4453 /* pop locally defined labels */
4454 label_pop(&local_label_stack, llabel);
4455 if(is_expr) {
4456 /* XXX: this solution makes only valgrind happy...
4457 triggered by gcc.c-torture/execute/20000917-1.c */
4458 Sym *p;
4459 switch(vtop->type.t & VT_BTYPE) {
4460 case VT_PTR:
4461 case VT_STRUCT:
4462 case VT_ENUM:
4463 case VT_FUNC:
4464 for(p=vtop->type.ref;p;p=p->prev)
4465 if(p->prev==s)
4466 tcc_error("unsupported expression type");
4469 /* pop locally defined symbols */
4470 scope_stack_bottom = scope_stack_bottom->next;
4471 sym_pop(&local_stack, s);
4472 next();
4473 } else if (tok == TOK_RETURN) {
4474 next();
4475 if (tok != ';') {
4476 gexpr();
4477 gen_assign_cast(&func_vt);
4478 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4479 CType type;
4480 /* if returning structure, must copy it to implicit
4481 first pointer arg location */
4482 #ifdef TCC_ARM_EABI
4483 int align, size;
4484 size = type_size(&func_vt,&align);
4485 if(size <= 4)
4487 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4488 && (align & 3))
4490 int addr;
4491 loc = (loc - size) & -4;
4492 addr = loc;
4493 type = func_vt;
4494 vset(&type, VT_LOCAL | VT_LVAL, addr);
4495 vswap();
4496 vstore();
4497 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4499 vtop->type = int_type;
4500 gv(RC_IRET);
4501 } else {
4502 #endif
4503 type = func_vt;
4504 mk_pointer(&type);
4505 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4506 indir();
4507 vswap();
4508 /* copy structure value to pointer */
4509 vstore();
4510 #ifdef TCC_ARM_EABI
4512 #endif
4513 } else if (is_float(func_vt.t)) {
4514 gv(rc_fret(func_vt.t));
4515 } else {
4516 gv(RC_IRET);
4518 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4520 skip(';');
4521 rsym = gjmp(rsym); /* jmp */
4522 } else if (tok == TOK_BREAK) {
4523 /* compute jump */
4524 if (!bsym)
4525 tcc_error("cannot break");
4526 *bsym = gjmp(*bsym);
4527 next();
4528 skip(';');
4529 } else if (tok == TOK_CONTINUE) {
4530 /* compute jump */
4531 if (!csym)
4532 tcc_error("cannot continue");
4533 *csym = gjmp(*csym);
4534 next();
4535 skip(';');
4536 } else if (tok == TOK_FOR) {
4537 int e;
4538 next();
4539 skip('(');
4540 s = local_stack;
4541 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4542 frame_bottom->next = scope_stack_bottom;
4543 scope_stack_bottom = frame_bottom;
4544 if (tok != ';') {
4545 /* c99 for-loop init decl? */
4546 if (!decl0(VT_LOCAL, 1)) {
4547 /* no, regular for-loop init expr */
4548 gexpr();
4549 vpop();
4552 skip(';');
4553 d = ind;
4554 c = ind;
4555 a = 0;
4556 b = 0;
4557 if (tok != ';') {
4558 gexpr();
4559 a = gtst(1, 0);
4561 skip(';');
4562 if (tok != ')') {
4563 e = gjmp(0);
4564 c = ind;
4565 gexpr();
4566 vpop();
4567 gjmp_addr(d);
4568 gsym(e);
4570 skip(')');
4571 block(&a, &b, case_sym, def_sym, case_reg, 0);
4572 gjmp_addr(c);
4573 gsym(a);
4574 gsym_addr(b, c);
4575 scope_stack_bottom = scope_stack_bottom->next;
4576 sym_pop(&local_stack, s);
4577 } else
4578 if (tok == TOK_DO) {
4579 next();
4580 a = 0;
4581 b = 0;
4582 d = ind;
4583 block(&a, &b, case_sym, def_sym, case_reg, 0);
4584 skip(TOK_WHILE);
4585 skip('(');
4586 gsym(b);
4587 gexpr();
4588 c = gtst(0, 0);
4589 gsym_addr(c, d);
4590 skip(')');
4591 gsym(a);
4592 skip(';');
4593 } else
4594 if (tok == TOK_SWITCH) {
4595 next();
4596 skip('(');
4597 gexpr();
4598 /* XXX: other types than integer */
4599 case_reg = gv(RC_INT);
4600 vpop();
4601 skip(')');
4602 a = 0;
4603 b = gjmp(0); /* jump to first case */
4604 c = 0;
4605 block(&a, csym, &b, &c, case_reg, 0);
4606 /* if no default, jmp after switch */
4607 if (c == 0)
4608 c = ind;
4609 /* default label */
4610 gsym_addr(b, c);
4611 /* break label */
4612 gsym(a);
4613 } else
4614 if (tok == TOK_CASE) {
4615 int v1, v2;
4616 if (!case_sym)
4617 expect("switch");
4618 next();
4619 v1 = expr_const();
4620 v2 = v1;
4621 if (gnu_ext && tok == TOK_DOTS) {
4622 next();
4623 v2 = expr_const();
4624 if (v2 < v1)
4625 tcc_warning("empty case range");
4627 /* since a case is like a label, we must skip it with a jmp */
4628 b = gjmp(0);
4629 gsym(*case_sym);
4630 vseti(case_reg, 0);
4631 vpushi(v1);
4632 if (v1 == v2) {
4633 gen_op(TOK_EQ);
4634 *case_sym = gtst(1, 0);
4635 } else {
4636 gen_op(TOK_GE);
4637 *case_sym = gtst(1, 0);
4638 vseti(case_reg, 0);
4639 vpushi(v2);
4640 gen_op(TOK_LE);
4641 *case_sym = gtst(1, *case_sym);
4643 gsym(b);
4644 skip(':');
4645 is_expr = 0;
4646 goto block_after_label;
4647 } else
4648 if (tok == TOK_DEFAULT) {
4649 next();
4650 skip(':');
4651 if (!def_sym)
4652 expect("switch");
4653 if (*def_sym)
4654 tcc_error("too many 'default'");
4655 *def_sym = ind;
4656 is_expr = 0;
4657 goto block_after_label;
4658 } else
4659 if (tok == TOK_GOTO) {
4660 next();
4661 if (tok == '*' && gnu_ext) {
4662 /* computed goto */
4663 next();
4664 gexpr();
4665 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4666 expect("pointer");
4667 ggoto();
4668 } else if (tok >= TOK_UIDENT) {
4669 s = label_find(tok);
4670 /* put forward definition if needed */
4671 if (!s) {
4672 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4673 } else {
4674 if (s->r == LABEL_DECLARED)
4675 s->r = LABEL_FORWARD;
4677 /* label already defined */
4678 if (s->r & LABEL_FORWARD)
4679 s->jnext = gjmp(s->jnext);
4680 else
4681 gjmp_addr(s->jnext);
4682 next();
4683 } else {
4684 expect("label identifier");
4686 skip(';');
4687 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4688 asm_instr();
4689 } else {
4690 b = is_label();
4691 if (b) {
4692 /* label case */
4693 s = label_find(b);
4694 if (s) {
4695 if (s->r == LABEL_DEFINED)
4696 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4697 gsym(s->jnext);
4698 s->r = LABEL_DEFINED;
4699 } else {
4700 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4702 s->jnext = ind;
4703 /* we accept this, but it is a mistake */
4704 block_after_label:
4705 if (tok == '}') {
4706 tcc_warning("deprecated use of label at end of compound statement");
4707 } else {
4708 if (is_expr)
4709 vpop();
4710 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4712 } else {
4713 /* expression case */
4714 if (tok != ';') {
4715 if (is_expr) {
4716 vpop();
4717 gexpr();
4718 } else {
4719 gexpr();
4720 vpop();
4723 skip(';');
4728 /* t is the array or struct type. c is the array or struct
4729 address. cur_index/cur_field is the pointer to the current
4730 value. 'size_only' is true if only size info is needed (only used
4731 in arrays) */
4732 static void decl_designator(CType *type, Section *sec, unsigned long c,
4733 int *cur_index, Sym **cur_field,
4734 int size_only)
4736 Sym *s, *f;
4737 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4738 CType type1;
4740 notfirst = 0;
4741 elem_size = 0;
4742 nb_elems = 1;
4743 if (gnu_ext && (l = is_label()) != 0)
4744 goto struct_field;
4745 while (tok == '[' || tok == '.') {
4746 if (tok == '[') {
4747 if (!(type->t & VT_ARRAY))
4748 expect("array type");
4749 s = type->ref;
4750 next();
4751 index = expr_const();
4752 if (index < 0 || (s->c >= 0 && index >= s->c))
4753 expect("invalid index");
4754 if (tok == TOK_DOTS && gnu_ext) {
4755 next();
4756 index_last = expr_const();
4757 if (index_last < 0 ||
4758 (s->c >= 0 && index_last >= s->c) ||
4759 index_last < index)
4760 expect("invalid index");
4761 } else {
4762 index_last = index;
4764 skip(']');
4765 if (!notfirst)
4766 *cur_index = index_last;
4767 type = pointed_type(type);
4768 elem_size = type_size(type, &align);
4769 c += index * elem_size;
4770 /* NOTE: we only support ranges for last designator */
4771 nb_elems = index_last - index + 1;
4772 if (nb_elems != 1) {
4773 notfirst = 1;
4774 break;
4776 } else {
4777 next();
4778 l = tok;
4779 next();
4780 struct_field:
4781 if ((type->t & VT_BTYPE) != VT_STRUCT)
4782 expect("struct/union type");
4783 s = type->ref;
4784 l |= SYM_FIELD;
4785 f = s->next;
4786 while (f) {
4787 if (f->v == l)
4788 break;
4789 f = f->next;
4791 if (!f)
4792 expect("field");
4793 if (!notfirst)
4794 *cur_field = f;
4795 /* XXX: fix this mess by using explicit storage field */
4796 type1 = f->type;
4797 type1.t |= (type->t & ~VT_TYPE);
4798 type = &type1;
4799 c += f->c;
4801 notfirst = 1;
4803 if (notfirst) {
4804 if (tok == '=') {
4805 next();
4806 } else {
4807 if (!gnu_ext)
4808 expect("=");
4810 } else {
4811 if (type->t & VT_ARRAY) {
4812 index = *cur_index;
4813 type = pointed_type(type);
4814 c += index * type_size(type, &align);
4815 } else {
4816 f = *cur_field;
4817 if (!f)
4818 tcc_error("too many field init");
4819 /* XXX: fix this mess by using explicit storage field */
4820 type1 = f->type;
4821 type1.t |= (type->t & ~VT_TYPE);
4822 type = &type1;
4823 c += f->c;
4826 decl_initializer(type, sec, c, 0, size_only);
4828 /* XXX: make it more general */
4829 if (!size_only && nb_elems > 1) {
4830 unsigned long c_end;
4831 uint8_t *src, *dst;
4832 int i;
4834 if (!sec)
4835 tcc_error("range init not supported yet for dynamic storage");
4836 c_end = c + nb_elems * elem_size;
4837 if (c_end > sec->data_allocated)
4838 section_realloc(sec, c_end);
4839 src = sec->data + c;
4840 dst = src;
4841 for(i = 1; i < nb_elems; i++) {
4842 dst += elem_size;
4843 memcpy(dst, src, elem_size);
4848 #define EXPR_VAL 0
4849 #define EXPR_CONST 1
4850 #define EXPR_ANY 2
4852 /* store a value or an expression directly in global data or in local array */
4853 static void init_putv(CType *type, Section *sec, unsigned long c,
4854 int v, int expr_type)
4856 int saved_global_expr, bt, bit_pos, bit_size;
4857 void *ptr;
4858 unsigned long long bit_mask;
4859 CType dtype;
4861 switch(expr_type) {
4862 case EXPR_VAL:
4863 vpushi(v);
4864 break;
4865 case EXPR_CONST:
4866 /* compound literals must be allocated globally in this case */
4867 saved_global_expr = global_expr;
4868 global_expr = 1;
4869 expr_const1();
4870 global_expr = saved_global_expr;
4871 /* NOTE: symbols are accepted */
4872 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4873 tcc_error("initializer element is not constant");
4874 break;
4875 case EXPR_ANY:
4876 expr_eq();
4877 break;
4880 dtype = *type;
4881 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4883 if (sec) {
4884 /* XXX: not portable */
4885 /* XXX: generate error if incorrect relocation */
4886 gen_assign_cast(&dtype);
4887 bt = type->t & VT_BTYPE;
4888 /* we'll write at most 12 bytes */
4889 if (c + 12 > sec->data_allocated) {
4890 section_realloc(sec, c + 12);
4892 ptr = sec->data + c;
4893 /* XXX: make code faster ? */
4894 if (!(type->t & VT_BITFIELD)) {
4895 bit_pos = 0;
4896 bit_size = 32;
4897 bit_mask = -1LL;
4898 } else {
4899 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4900 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4901 bit_mask = (1LL << bit_size) - 1;
4903 if ((vtop->r & VT_SYM) &&
4904 (bt == VT_BYTE ||
4905 bt == VT_SHORT ||
4906 bt == VT_DOUBLE ||
4907 bt == VT_LDOUBLE ||
4908 bt == VT_LLONG ||
4909 (bt == VT_INT && bit_size != 32)))
4910 tcc_error("initializer element is not computable at load time");
4911 switch(bt) {
4912 case VT_BOOL:
4913 vtop->c.i = (vtop->c.i != 0);
4914 case VT_BYTE:
4915 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4916 break;
4917 case VT_SHORT:
4918 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4919 break;
4920 case VT_DOUBLE:
4921 *(double *)ptr = vtop->c.d;
4922 break;
4923 case VT_LDOUBLE:
4924 *(long double *)ptr = vtop->c.ld;
4925 break;
4926 case VT_LLONG:
4927 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4928 break;
4929 default:
4930 if (vtop->r & VT_SYM) {
4931 greloc(sec, vtop->sym, c, R_DATA_PTR);
4933 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4934 break;
4936 vtop--;
4937 } else {
4938 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4939 vswap();
4940 vstore();
4941 vpop();
4945 /* put zeros for variable based init */
4946 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4948 if (sec) {
4949 /* nothing to do because globals are already set to zero */
4950 } else {
4951 vpush_global_sym(&func_old_type, TOK_memset);
4952 vseti(VT_LOCAL, c);
4953 vpushi(0);
4954 vpushi(size);
4955 gfunc_call(3);
4959 /* 't' contains the type and storage info. 'c' is the offset of the
4960 object in section 'sec'. If 'sec' is NULL, it means stack based
4961 allocation. 'first' is true if array '{' must be read (multi
4962 dimension implicit array init handling). 'size_only' is true if
4963 size only evaluation is wanted (only for arrays). */
4964 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4965 int first, int size_only)
4967 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
4968 int size1, align1, expr_type;
4969 Sym *s, *f;
4970 CType *t1;
4972 if (type->t & VT_VLA) {
4973 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
4974 int a;
4975 CValue retcval;
4977 vpush_global_sym(&func_old_type, TOK_alloca);
4978 vla_runtime_type_size(type, &a);
4979 gfunc_call(1);
4981 /* return value */
4982 retcval.i = 0;
4983 vsetc(type, REG_IRET, &retcval);
4984 vset(type, VT_LOCAL|VT_LVAL, c);
4985 vswap();
4986 vstore();
4987 vpop();
4988 #else
4989 tcc_error("variable length arrays unsupported for this target");
4990 #endif
4991 } else if (type->t & VT_ARRAY) {
4992 s = type->ref;
4993 n = s->c;
4994 array_length = 0;
4995 t1 = pointed_type(type);
4996 size1 = type_size(t1, &align1);
4998 no_oblock = 1;
4999 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5000 tok == '{') {
5001 if (tok != '{')
5002 tcc_error("character array initializer must be a literal,"
5003 " optionally enclosed in braces");
5004 skip('{');
5005 no_oblock = 0;
5008 /* only parse strings here if correct type (otherwise: handle
5009 them as ((w)char *) expressions */
5010 if ((tok == TOK_LSTR &&
5011 #ifdef TCC_TARGET_PE
5012 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5013 #else
5014 (t1->t & VT_BTYPE) == VT_INT
5015 #endif
5016 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5017 while (tok == TOK_STR || tok == TOK_LSTR) {
5018 int cstr_len, ch;
5019 CString *cstr;
5021 cstr = tokc.cstr;
5022 /* compute maximum number of chars wanted */
5023 if (tok == TOK_STR)
5024 cstr_len = cstr->size;
5025 else
5026 cstr_len = cstr->size / sizeof(nwchar_t);
5027 cstr_len--;
5028 nb = cstr_len;
5029 if (n >= 0 && nb > (n - array_length))
5030 nb = n - array_length;
5031 if (!size_only) {
5032 if (cstr_len > nb)
5033 tcc_warning("initializer-string for array is too long");
5034 /* in order to go faster for common case (char
5035 string in global variable, we handle it
5036 specifically */
5037 if (sec && tok == TOK_STR && size1 == 1) {
5038 memcpy(sec->data + c + array_length, cstr->data, nb);
5039 } else {
5040 for(i=0;i<nb;i++) {
5041 if (tok == TOK_STR)
5042 ch = ((unsigned char *)cstr->data)[i];
5043 else
5044 ch = ((nwchar_t *)cstr->data)[i];
5045 init_putv(t1, sec, c + (array_length + i) * size1,
5046 ch, EXPR_VAL);
5050 array_length += nb;
5051 next();
5053 /* only add trailing zero if enough storage (no
5054 warning in this case since it is standard) */
5055 if (n < 0 || array_length < n) {
5056 if (!size_only) {
5057 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5059 array_length++;
5061 } else {
5062 index = 0;
5063 while (tok != '}') {
5064 decl_designator(type, sec, c, &index, NULL, size_only);
5065 if (n >= 0 && index >= n)
5066 tcc_error("index too large");
5067 /* must put zero in holes (note that doing it that way
5068 ensures that it even works with designators) */
5069 if (!size_only && array_length < index) {
5070 init_putz(t1, sec, c + array_length * size1,
5071 (index - array_length) * size1);
5073 index++;
5074 if (index > array_length)
5075 array_length = index;
5076 /* special test for multi dimensional arrays (may not
5077 be strictly correct if designators are used at the
5078 same time) */
5079 if (index >= n && no_oblock)
5080 break;
5081 if (tok == '}')
5082 break;
5083 skip(',');
5086 if (!no_oblock)
5087 skip('}');
5088 /* put zeros at the end */
5089 if (!size_only && n >= 0 && array_length < n) {
5090 init_putz(t1, sec, c + array_length * size1,
5091 (n - array_length) * size1);
5093 /* patch type size if needed */
5094 if (n < 0)
5095 s->c = array_length;
5096 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5097 (sec || !first || tok == '{')) {
5098 int par_count;
5100 /* NOTE: the previous test is a specific case for automatic
5101 struct/union init */
5102 /* XXX: union needs only one init */
5104 /* XXX: this test is incorrect for local initializers
5105 beginning with ( without {. It would be much more difficult
5106 to do it correctly (ideally, the expression parser should
5107 be used in all cases) */
5108 par_count = 0;
5109 if (tok == '(') {
5110 AttributeDef ad1;
5111 CType type1;
5112 next();
5113 while (tok == '(') {
5114 par_count++;
5115 next();
5117 if (!parse_btype(&type1, &ad1))
5118 expect("cast");
5119 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5120 #if 0
5121 if (!is_assignable_types(type, &type1))
5122 tcc_error("invalid type for cast");
5123 #endif
5124 skip(')');
5126 no_oblock = 1;
5127 if (first || tok == '{') {
5128 skip('{');
5129 no_oblock = 0;
5131 s = type->ref;
5132 f = s->next;
5133 array_length = 0;
5134 index = 0;
5135 n = s->c;
5136 while (tok != '}') {
5137 decl_designator(type, sec, c, NULL, &f, size_only);
5138 index = f->c;
5139 if (!size_only && array_length < index) {
5140 init_putz(type, sec, c + array_length,
5141 index - array_length);
5143 index = index + type_size(&f->type, &align1);
5144 if (index > array_length)
5145 array_length = index;
5147 /* gr: skip fields from same union - ugly. */
5148 while (f->next) {
5149 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5150 /* test for same offset */
5151 if (f->next->c != f->c)
5152 break;
5153 /* if yes, test for bitfield shift */
5154 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5155 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5156 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5157 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5158 if (bit_pos_1 != bit_pos_2)
5159 break;
5161 f = f->next;
5164 f = f->next;
5165 if (no_oblock && f == NULL)
5166 break;
5167 if (tok == '}')
5168 break;
5169 skip(',');
5171 /* put zeros at the end */
5172 if (!size_only && array_length < n) {
5173 init_putz(type, sec, c + array_length,
5174 n - array_length);
5176 if (!no_oblock)
5177 skip('}');
5178 while (par_count) {
5179 skip(')');
5180 par_count--;
5182 } else if (tok == '{') {
5183 next();
5184 decl_initializer(type, sec, c, first, size_only);
5185 skip('}');
5186 } else if (size_only) {
5187 /* just skip expression */
5188 parlevel = parlevel1 = 0;
5189 while ((parlevel > 0 || parlevel1 > 0 ||
5190 (tok != '}' && tok != ',')) && tok != -1) {
5191 if (tok == '(')
5192 parlevel++;
5193 else if (tok == ')')
5194 parlevel--;
5195 else if (tok == '{')
5196 parlevel1++;
5197 else if (tok == '}')
5198 parlevel1--;
5199 next();
5201 } else {
5202 /* currently, we always use constant expression for globals
5203 (may change for scripting case) */
5204 expr_type = EXPR_CONST;
5205 if (!sec)
5206 expr_type = EXPR_ANY;
5207 init_putv(type, sec, c, 0, expr_type);
5211 /* parse an initializer for type 't' if 'has_init' is non zero, and
5212 allocate space in local or global data space ('r' is either
5213 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5214 variable 'v' with an associated name represented by 'asm_label' of
5215 scope 'scope' is declared before initializers are parsed. If 'v' is
5216 zero, then a reference to the new object is put in the value stack.
5217 If 'has_init' is 2, a special parsing is done to handle string
5218 constants. */
5219 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5220 int has_init, int v, char *asm_label,
5221 int scope)
5223 int size, align, addr, data_offset;
5224 int level;
5225 ParseState saved_parse_state = {0};
5226 TokenString init_str;
5227 Section *sec;
5228 Sym *flexible_array;
5230 flexible_array = NULL;
5231 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5232 Sym *field;
5233 field = type->ref;
5234 while (field && field->next)
5235 field = field->next;
5236 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5237 flexible_array = field;
5240 size = type_size(type, &align);
5241 /* If unknown size, we must evaluate it before
5242 evaluating initializers because
5243 initializers can generate global data too
5244 (e.g. string pointers or ISOC99 compound
5245 literals). It also simplifies local
5246 initializers handling */
5247 tok_str_new(&init_str);
5248 if (size < 0 || (flexible_array && has_init)) {
5249 if (!has_init)
5250 tcc_error("unknown type size");
5251 /* get all init string */
5252 if (has_init == 2) {
5253 /* only get strings */
5254 while (tok == TOK_STR || tok == TOK_LSTR) {
5255 tok_str_add_tok(&init_str);
5256 next();
5258 } else {
5259 level = 0;
5260 while (level > 0 || (tok != ',' && tok != ';')) {
5261 if (tok < 0)
5262 tcc_error("unexpected end of file in initializer");
5263 tok_str_add_tok(&init_str);
5264 if (tok == '{')
5265 level++;
5266 else if (tok == '}') {
5267 level--;
5268 if (level <= 0) {
5269 next();
5270 break;
5273 next();
5276 tok_str_add(&init_str, -1);
5277 tok_str_add(&init_str, 0);
5279 /* compute size */
5280 save_parse_state(&saved_parse_state);
5282 macro_ptr = init_str.str;
5283 next();
5284 decl_initializer(type, NULL, 0, 1, 1);
5285 /* prepare second initializer parsing */
5286 macro_ptr = init_str.str;
5287 next();
5289 /* if still unknown size, error */
5290 size = type_size(type, &align);
5291 if (size < 0)
5292 tcc_error("unknown type size");
5294 if (flexible_array)
5295 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5296 /* take into account specified alignment if bigger */
5297 if (ad->aligned) {
5298 if (ad->aligned > align)
5299 align = ad->aligned;
5300 } else if (ad->packed) {
5301 align = 1;
5303 if ((r & VT_VALMASK) == VT_LOCAL) {
5304 sec = NULL;
5305 #ifdef CONFIG_TCC_BCHECK
5306 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5307 loc--;
5309 #endif
5310 loc = (loc - size) & -align;
5311 addr = loc;
5312 #ifdef CONFIG_TCC_BCHECK
5313 /* handles bounds */
5314 /* XXX: currently, since we do only one pass, we cannot track
5315 '&' operators, so we add only arrays */
5316 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5317 unsigned long *bounds_ptr;
5318 /* add padding between regions */
5319 loc--;
5320 /* then add local bound info */
5321 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5322 bounds_ptr[0] = addr;
5323 bounds_ptr[1] = size;
5325 #endif
5326 if (v) {
5327 /* local variable */
5328 sym_push(v, type, r, addr);
5329 } else {
5330 /* push local reference */
5331 vset(type, r, addr);
5333 } else {
5334 Sym *sym;
5336 sym = NULL;
5337 if (v && scope == VT_CONST) {
5338 /* see if the symbol was already defined */
5339 sym = sym_find(v);
5340 if (sym) {
5341 if (!is_compatible_types(&sym->type, type))
5342 tcc_error("incompatible types for redefinition of '%s'",
5343 get_tok_str(v, NULL));
5344 if (sym->type.t & VT_EXTERN) {
5345 /* if the variable is extern, it was not allocated */
5346 sym->type.t &= ~VT_EXTERN;
5347 /* set array size if it was ommited in extern
5348 declaration */
5349 if ((sym->type.t & VT_ARRAY) &&
5350 sym->type.ref->c < 0 &&
5351 type->ref->c >= 0)
5352 sym->type.ref->c = type->ref->c;
5353 } else {
5354 /* we accept several definitions of the same
5355 global variable. this is tricky, because we
5356 must play with the SHN_COMMON type of the symbol */
5357 /* XXX: should check if the variable was already
5358 initialized. It is incorrect to initialized it
5359 twice */
5360 /* no init data, we won't add more to the symbol */
5361 if (!has_init)
5362 goto no_alloc;
5367 /* allocate symbol in corresponding section */
5368 sec = ad->section;
5369 if (!sec) {
5370 if (has_init)
5371 sec = data_section;
5372 else if (tcc_state->nocommon)
5373 sec = bss_section;
5375 if (sec) {
5376 data_offset = sec->data_offset;
5377 data_offset = (data_offset + align - 1) & -align;
5378 addr = data_offset;
5379 /* very important to increment global pointer at this time
5380 because initializers themselves can create new initializers */
5381 data_offset += size;
5382 #ifdef CONFIG_TCC_BCHECK
5383 /* add padding if bound check */
5384 if (tcc_state->do_bounds_check)
5385 data_offset++;
5386 #endif
5387 sec->data_offset = data_offset;
5388 /* allocate section space to put the data */
5389 if (sec->sh_type != SHT_NOBITS &&
5390 data_offset > sec->data_allocated)
5391 section_realloc(sec, data_offset);
5392 /* align section if needed */
5393 if (align > sec->sh_addralign)
5394 sec->sh_addralign = align;
5395 } else {
5396 addr = 0; /* avoid warning */
5399 if (v) {
5400 if (scope != VT_CONST || !sym) {
5401 sym = sym_push(v, type, r | VT_SYM, 0);
5402 sym->asm_label = asm_label;
5404 /* update symbol definition */
5405 if (sec) {
5406 put_extern_sym(sym, sec, addr, size);
5407 } else {
5408 ElfW(Sym) *esym;
5409 /* put a common area */
5410 put_extern_sym(sym, NULL, align, size);
5411 /* XXX: find a nicer way */
5412 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5413 esym->st_shndx = SHN_COMMON;
5415 } else {
5416 CValue cval;
5418 /* push global reference */
5419 sym = get_sym_ref(type, sec, addr, size);
5420 cval.ul = 0;
5421 vsetc(type, VT_CONST | VT_SYM, &cval);
5422 vtop->sym = sym;
5424 /* patch symbol weakness */
5425 if (type->t & VT_WEAK)
5426 weaken_symbol(sym);
5427 #ifdef CONFIG_TCC_BCHECK
5428 /* handles bounds now because the symbol must be defined
5429 before for the relocation */
5430 if (tcc_state->do_bounds_check) {
5431 unsigned long *bounds_ptr;
5433 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5434 /* then add global bound info */
5435 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5436 bounds_ptr[0] = 0; /* relocated */
5437 bounds_ptr[1] = size;
5439 #endif
5441 if (has_init || (type->t & VT_VLA)) {
5442 decl_initializer(type, sec, addr, 1, 0);
5443 /* restore parse state if needed */
5444 if (init_str.str) {
5445 tok_str_free(init_str.str);
5446 restore_parse_state(&saved_parse_state);
5448 /* patch flexible array member size back to -1, */
5449 /* for possible subsequent similar declarations */
5450 if (flexible_array)
5451 flexible_array->type.ref->c = -1;
5453 no_alloc: ;
5456 static void put_func_debug(Sym *sym)
5458 char buf[512];
5460 /* stabs info */
5461 /* XXX: we put here a dummy type */
5462 snprintf(buf, sizeof(buf), "%s:%c1",
5463 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5464 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5465 cur_text_section, sym->c);
5466 /* //gr gdb wants a line at the function */
5467 put_stabn(N_SLINE, 0, file->line_num, 0);
5468 last_ind = 0;
5469 last_line_num = 0;
5472 /* parse an old style function declaration list */
5473 /* XXX: check multiple parameter */
5474 static void func_decl_list(Sym *func_sym)
5476 AttributeDef ad;
5477 int v;
5478 Sym *s;
5479 CType btype, type;
5481 /* parse each declaration */
5482 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5483 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5484 if (!parse_btype(&btype, &ad))
5485 expect("declaration list");
5486 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5487 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5488 tok == ';') {
5489 /* we accept no variable after */
5490 } else {
5491 for(;;) {
5492 type = btype;
5493 type_decl(&type, &ad, &v, TYPE_DIRECT);
5494 /* find parameter in function parameter list */
5495 s = func_sym->next;
5496 while (s != NULL) {
5497 if ((s->v & ~SYM_FIELD) == v)
5498 goto found;
5499 s = s->next;
5501 tcc_error("declaration for parameter '%s' but no such parameter",
5502 get_tok_str(v, NULL));
5503 found:
5504 /* check that no storage specifier except 'register' was given */
5505 if (type.t & VT_STORAGE)
5506 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5507 convert_parameter_type(&type);
5508 /* we can add the type (NOTE: it could be local to the function) */
5509 s->type = type;
5510 /* accept other parameters */
5511 if (tok == ',')
5512 next();
5513 else
5514 break;
5517 skip(';');
5521 /* parse a function defined by symbol 'sym' and generate its code in
5522 'cur_text_section' */
5523 static void gen_function(Sym *sym)
5525 int saved_nocode_wanted = nocode_wanted;
5526 nocode_wanted = 0;
5527 ind = cur_text_section->data_offset;
5528 /* NOTE: we patch the symbol size later */
5529 put_extern_sym(sym, cur_text_section, ind, 0);
5530 funcname = get_tok_str(sym->v, NULL);
5531 func_ind = ind;
5532 /* put debug symbol */
5533 if (tcc_state->do_debug)
5534 put_func_debug(sym);
5535 /* push a dummy symbol to enable local sym storage */
5536 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5537 gfunc_prolog(&sym->type);
5538 rsym = 0;
5539 block(NULL, NULL, NULL, NULL, 0, 0);
5540 gsym(rsym);
5541 gfunc_epilog();
5542 cur_text_section->data_offset = ind;
5543 label_pop(&global_label_stack, NULL);
5544 /* reset local stack */
5545 scope_stack_bottom = NULL;
5546 sym_pop(&local_stack, NULL);
5547 /* end of function */
5548 /* patch symbol size */
5549 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5550 ind - func_ind;
5551 /* patch symbol weakness (this definition overrules any prototype) */
5552 if (sym->type.t & VT_WEAK)
5553 weaken_symbol(sym);
5554 if (tcc_state->do_debug) {
5555 put_stabn(N_FUN, 0, 0, ind - func_ind);
5557 /* It's better to crash than to generate wrong code */
5558 cur_text_section = NULL;
5559 funcname = ""; /* for safety */
5560 func_vt.t = VT_VOID; /* for safety */
5561 ind = 0; /* for safety */
5562 nocode_wanted = saved_nocode_wanted;
5565 ST_FUNC void gen_inline_functions(void)
5567 Sym *sym;
5568 int *str, inline_generated, i;
5569 struct InlineFunc *fn;
5571 /* iterate while inline function are referenced */
5572 for(;;) {
5573 inline_generated = 0;
5574 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5575 fn = tcc_state->inline_fns[i];
5576 sym = fn->sym;
5577 if (sym && sym->c) {
5578 /* the function was used: generate its code and
5579 convert it to a normal function */
5580 str = fn->token_str;
5581 fn->sym = NULL;
5582 if (file)
5583 strcpy(file->filename, fn->filename);
5584 sym->r = VT_SYM | VT_CONST;
5585 sym->type.t &= ~VT_INLINE;
5587 macro_ptr = str;
5588 next();
5589 cur_text_section = text_section;
5590 gen_function(sym);
5591 macro_ptr = NULL; /* fail safe */
5593 inline_generated = 1;
5596 if (!inline_generated)
5597 break;
5599 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5600 fn = tcc_state->inline_fns[i];
5601 str = fn->token_str;
5602 tok_str_free(str);
5604 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5607 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5608 static int decl0(int l, int is_for_loop_init)
5610 int v, has_init, r;
5611 CType type, btype;
5612 Sym *sym;
5613 AttributeDef ad;
5615 while (1) {
5616 if (!parse_btype(&btype, &ad)) {
5617 if (is_for_loop_init)
5618 return 0;
5619 /* skip redundant ';' */
5620 /* XXX: find more elegant solution */
5621 if (tok == ';') {
5622 next();
5623 continue;
5625 if (l == VT_CONST &&
5626 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5627 /* global asm block */
5628 asm_global_instr();
5629 continue;
5631 /* special test for old K&R protos without explicit int
5632 type. Only accepted when defining global data */
5633 if (l == VT_LOCAL || tok < TOK_DEFINE)
5634 break;
5635 btype.t = VT_INT;
5637 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5638 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5639 tok == ';') {
5640 /* we accept no variable after */
5641 next();
5642 continue;
5644 while (1) { /* iterate thru each declaration */
5645 char *asm_label; // associated asm label
5646 type = btype;
5647 type_decl(&type, &ad, &v, TYPE_DIRECT);
5648 #if 0
5650 char buf[500];
5651 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5652 printf("type = '%s'\n", buf);
5654 #endif
5655 if ((type.t & VT_BTYPE) == VT_FUNC) {
5656 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5657 tcc_error("function without file scope cannot be static");
5659 /* if old style function prototype, we accept a
5660 declaration list */
5661 sym = type.ref;
5662 if (sym->c == FUNC_OLD)
5663 func_decl_list(sym);
5666 asm_label = NULL;
5667 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5668 CString astr;
5670 asm_label_instr(&astr);
5671 asm_label = tcc_strdup(astr.data);
5672 cstr_free(&astr);
5674 /* parse one last attribute list, after asm label */
5675 parse_attribute(&ad);
5678 if (ad.weak)
5679 type.t |= VT_WEAK;
5680 #ifdef TCC_TARGET_PE
5681 if (ad.func_import)
5682 type.t |= VT_IMPORT;
5683 if (ad.func_export)
5684 type.t |= VT_EXPORT;
5685 #endif
5686 if (tok == '{') {
5687 if (l == VT_LOCAL)
5688 tcc_error("cannot use local functions");
5689 if ((type.t & VT_BTYPE) != VT_FUNC)
5690 expect("function definition");
5692 /* reject abstract declarators in function definition */
5693 sym = type.ref;
5694 while ((sym = sym->next) != NULL)
5695 if (!(sym->v & ~SYM_FIELD))
5696 expect("identifier");
5698 /* XXX: cannot do better now: convert extern line to static inline */
5699 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5700 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5702 sym = sym_find(v);
5703 if (sym) {
5704 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5705 goto func_error1;
5707 r = sym->type.ref->r;
5708 /* use func_call from prototype if not defined */
5709 if (FUNC_CALL(r) != FUNC_CDECL
5710 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5711 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5713 /* use export from prototype */
5714 if (FUNC_EXPORT(r))
5715 FUNC_EXPORT(type.ref->r) = 1;
5717 /* use static from prototype */
5718 if (sym->type.t & VT_STATIC)
5719 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5721 if (!is_compatible_types(&sym->type, &type)) {
5722 func_error1:
5723 tcc_error("incompatible types for redefinition of '%s'",
5724 get_tok_str(v, NULL));
5726 /* if symbol is already defined, then put complete type */
5727 sym->type = type;
5728 } else {
5729 /* put function symbol */
5730 sym = global_identifier_push(v, type.t, 0);
5731 sym->type.ref = type.ref;
5734 /* static inline functions are just recorded as a kind
5735 of macro. Their code will be emitted at the end of
5736 the compilation unit only if they are used */
5737 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5738 (VT_INLINE | VT_STATIC)) {
5739 TokenString func_str;
5740 int block_level;
5741 struct InlineFunc *fn;
5742 const char *filename;
5744 tok_str_new(&func_str);
5746 block_level = 0;
5747 for(;;) {
5748 int t;
5749 if (tok == TOK_EOF)
5750 tcc_error("unexpected end of file");
5751 tok_str_add_tok(&func_str);
5752 t = tok;
5753 next();
5754 if (t == '{') {
5755 block_level++;
5756 } else if (t == '}') {
5757 block_level--;
5758 if (block_level == 0)
5759 break;
5762 tok_str_add(&func_str, -1);
5763 tok_str_add(&func_str, 0);
5764 filename = file ? file->filename : "";
5765 fn = tcc_malloc(sizeof *fn + strlen(filename));
5766 strcpy(fn->filename, filename);
5767 fn->sym = sym;
5768 fn->token_str = func_str.str;
5769 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5771 } else {
5772 /* compute text section */
5773 cur_text_section = ad.section;
5774 if (!cur_text_section)
5775 cur_text_section = text_section;
5776 sym->r = VT_SYM | VT_CONST;
5777 gen_function(sym);
5779 break;
5780 } else {
5781 if (btype.t & VT_TYPEDEF) {
5782 /* save typedefed type */
5783 /* XXX: test storage specifiers ? */
5784 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5785 sym->type.t |= VT_TYPEDEF;
5786 } else {
5787 r = 0;
5788 if ((type.t & VT_BTYPE) == VT_FUNC) {
5789 /* external function definition */
5790 /* specific case for func_call attribute */
5791 type.ref->r = INT_ATTR(&ad);
5792 } else if (!(type.t & VT_ARRAY)) {
5793 /* not lvalue if array */
5794 r |= lvalue_type(type.t);
5796 has_init = (tok == '=');
5797 if (has_init && (type.t & VT_VLA))
5798 tcc_error("Variable length array cannot be initialized");
5799 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5800 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5801 !has_init && l == VT_CONST && type.ref->c < 0)) {
5802 /* external variable or function */
5803 /* NOTE: as GCC, uninitialized global static
5804 arrays of null size are considered as
5805 extern */
5806 sym = external_sym(v, &type, r, asm_label);
5808 if (type.t & VT_WEAK)
5809 weaken_symbol(sym);
5811 if (ad.alias_target) {
5812 Section tsec;
5813 Elf32_Sym *esym;
5814 Sym *alias_target;
5816 alias_target = sym_find(ad.alias_target);
5817 if (!alias_target || !alias_target->c)
5818 tcc_error("unsupported forward __alias__ attribute");
5819 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
5820 tsec.sh_num = esym->st_shndx;
5821 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
5823 } else {
5824 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5825 if (type.t & VT_STATIC)
5826 r |= VT_CONST;
5827 else
5828 r |= l;
5829 if (has_init)
5830 next();
5831 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
5834 if (tok != ',') {
5835 if (is_for_loop_init)
5836 return 1;
5837 skip(';');
5838 break;
5840 next();
5842 ad.aligned = 0;
5845 return 0;
5848 ST_FUNC void decl(int l)
5850 decl0(l, 0);