arm: fix conversion from float/double to signed integer with VFP
[tinycc.git] / tccgen.c
blob9602d66b19b9e31d3173e9ab140bfbd7f998bf7f
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 cval.ull = v;
365 vsetc(&ctype, VT_CONST, &cval);
368 /* Return a static symbol pointing to a section */
369 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
371 int v;
372 Sym *sym;
374 v = anon_sym++;
375 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
376 sym->type.ref = type->ref;
377 sym->r = VT_CONST | VT_SYM;
378 put_extern_sym(sym, sec, offset, size);
379 return sym;
382 /* push a reference to a section offset by adding a dummy symbol */
383 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
385 CValue cval;
387 cval.ul = 0;
388 vsetc(type, VT_CONST | VT_SYM, &cval);
389 vtop->sym = get_sym_ref(type, sec, offset, size);
392 /* define a new external reference to a symbol 'v' of type 'u' */
393 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
395 Sym *s;
397 s = sym_find(v);
398 if (!s) {
399 /* push forward reference */
400 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
401 s->type.ref = type->ref;
402 s->r = r | VT_CONST | VT_SYM;
404 return s;
407 /* define a new external reference to a symbol 'v' with alternate asm
408 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
409 is no alternate name (most cases) */
410 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
412 Sym *s;
414 s = sym_find(v);
415 if (!s) {
416 /* push forward reference */
417 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
418 s->asm_label = asm_label;
419 s->type.t |= VT_EXTERN;
420 } else if (s->type.ref == func_old_type.ref) {
421 s->type.ref = type->ref;
422 s->r = r | VT_CONST | VT_SYM;
423 s->type.t |= VT_EXTERN;
424 } else if (!is_compatible_types(&s->type, type)) {
425 tcc_error("incompatible types for redefinition of '%s'",
426 get_tok_str(v, NULL));
428 return s;
431 /* push a reference to global symbol v */
432 ST_FUNC void vpush_global_sym(CType *type, int v)
434 Sym *sym;
435 CValue cval;
437 sym = external_global_sym(v, type, 0);
438 cval.ul = 0;
439 vsetc(type, VT_CONST | VT_SYM, &cval);
440 vtop->sym = sym;
443 ST_FUNC void vset(CType *type, int r, int v)
445 CValue cval;
447 cval.i = v;
448 vsetc(type, r, &cval);
451 static void vseti(int r, int v)
453 CType type;
454 type.t = VT_INT;
455 type.ref = 0;
456 vset(&type, r, v);
459 ST_FUNC void vswap(void)
461 SValue tmp;
462 /* cannot let cpu flags if other instruction are generated. Also
463 avoid leaving VT_JMP anywhere except on the top of the stack
464 because it would complicate the code generator. */
465 if (vtop >= vstack) {
466 int v = vtop->r & VT_VALMASK;
467 if (v == VT_CMP || (v & ~1) == VT_JMP)
468 gv(RC_INT);
470 tmp = vtop[0];
471 vtop[0] = vtop[-1];
472 vtop[-1] = tmp;
474 /* XXX: +2% overall speed possible with optimized memswap
476 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
480 ST_FUNC void vpushv(SValue *v)
482 if (vtop >= vstack + (VSTACK_SIZE - 1))
483 tcc_error("memory full");
484 vtop++;
485 *vtop = *v;
488 static void vdup(void)
490 vpushv(vtop);
493 /* save r to the memory stack, and mark it as being free */
494 ST_FUNC void save_reg(int r)
496 int l, saved, size, align;
497 SValue *p, sv;
498 CType *type;
500 /* modify all stack values */
501 saved = 0;
502 l = 0;
503 for(p=vstack;p<=vtop;p++) {
504 if ((p->r & VT_VALMASK) == r ||
505 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
506 /* must save value on stack if not already done */
507 if (!saved) {
508 /* NOTE: must reload 'r' because r might be equal to r2 */
509 r = p->r & VT_VALMASK;
510 /* store register in the stack */
511 type = &p->type;
512 if ((p->r & VT_LVAL) ||
513 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
514 #ifdef TCC_TARGET_X86_64
515 type = &char_pointer_type;
516 #else
517 type = &int_type;
518 #endif
519 size = type_size(type, &align);
520 loc = (loc - size) & -align;
521 sv.type.t = type->t;
522 sv.r = VT_LOCAL | VT_LVAL;
523 sv.c.ul = loc;
524 store(r, &sv);
525 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
526 /* x86 specific: need to pop fp register ST0 if saved */
527 if (r == TREG_ST0) {
528 o(0xd8dd); /* fstp %st(0) */
530 #endif
531 #ifndef TCC_TARGET_X86_64
532 /* special long long case */
533 if ((type->t & VT_BTYPE) == VT_LLONG) {
534 sv.c.ul += 4;
535 store(p->r2, &sv);
537 #endif
538 l = loc;
539 saved = 1;
541 /* mark that stack entry as being saved on the stack */
542 if (p->r & VT_LVAL) {
543 /* also clear the bounded flag because the
544 relocation address of the function was stored in
545 p->c.ul */
546 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
547 } else {
548 p->r = lvalue_type(p->type.t) | VT_LOCAL;
550 p->r2 = VT_CONST;
551 p->c.ul = l;
556 #ifdef TCC_TARGET_ARM
557 /* find a register of class 'rc2' with at most one reference on stack.
558 * If none, call get_reg(rc) */
559 ST_FUNC int get_reg_ex(int rc, int rc2)
561 int r;
562 SValue *p;
564 for(r=0;r<NB_REGS;r++) {
565 if (reg_classes[r] & rc2) {
566 int n;
567 n=0;
568 for(p = vstack; p <= vtop; p++) {
569 if ((p->r & VT_VALMASK) == r ||
570 (p->r2 & VT_VALMASK) == r)
571 n++;
573 if (n <= 1)
574 return r;
577 return get_reg(rc);
579 #endif
581 /* find a free register of class 'rc'. If none, save one register */
582 ST_FUNC int get_reg(int rc)
584 int r;
585 SValue *p;
587 /* find a free register */
588 for(r=0;r<NB_REGS;r++) {
589 if (reg_classes[r] & rc) {
590 for(p=vstack;p<=vtop;p++) {
591 if ((p->r & VT_VALMASK) == r ||
592 (p->r2 & VT_VALMASK) == r)
593 goto notfound;
595 return r;
597 notfound: ;
600 /* no register left : free the first one on the stack (VERY
601 IMPORTANT to start from the bottom to ensure that we don't
602 spill registers used in gen_opi()) */
603 for(p=vstack;p<=vtop;p++) {
604 /* look at second register (if long long) */
605 r = p->r2 & VT_VALMASK;
606 if (r < VT_CONST && (reg_classes[r] & rc))
607 goto save_found;
608 r = p->r & VT_VALMASK;
609 if (r < VT_CONST && (reg_classes[r] & rc)) {
610 save_found:
611 save_reg(r);
612 return r;
615 /* Should never comes here */
616 return -1;
619 /* save registers up to (vtop - n) stack entry */
620 ST_FUNC void save_regs(int n)
622 int r;
623 SValue *p, *p1;
624 p1 = vtop - n;
625 for(p = vstack;p <= p1; p++) {
626 r = p->r & VT_VALMASK;
627 if (r < VT_CONST) {
628 save_reg(r);
633 /* move register 's' to 'r', and flush previous value of r to memory
634 if needed */
635 static void move_reg(int r, int s)
637 SValue sv;
639 if (r != s) {
640 save_reg(r);
641 sv.type.t = VT_INT;
642 sv.r = s;
643 sv.c.ul = 0;
644 load(r, &sv);
648 /* get address of vtop (vtop MUST BE an lvalue) */
649 static void gaddrof(void)
651 if (vtop->r & VT_REF)
652 gv(RC_INT);
653 vtop->r &= ~VT_LVAL;
654 /* tricky: if saved lvalue, then we can go back to lvalue */
655 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
656 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
661 #ifdef CONFIG_TCC_BCHECK
662 /* generate lvalue bound code */
663 static void gbound(void)
665 int lval_type;
666 CType type1;
668 vtop->r &= ~VT_MUSTBOUND;
669 /* if lvalue, then use checking code before dereferencing */
670 if (vtop->r & VT_LVAL) {
671 /* if not VT_BOUNDED value, then make one */
672 if (!(vtop->r & VT_BOUNDED)) {
673 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
674 /* must save type because we must set it to int to get pointer */
675 type1 = vtop->type;
676 vtop->type.t = VT_INT;
677 gaddrof();
678 vpushi(0);
679 gen_bounded_ptr_add();
680 vtop->r |= lval_type;
681 vtop->type = type1;
683 /* then check for dereferencing */
684 gen_bounded_ptr_deref();
687 #endif
689 /* store vtop a register belonging to class 'rc'. lvalues are
690 converted to values. Cannot be used if cannot be converted to
691 register value (such as structures). */
692 ST_FUNC int gv(int rc)
694 int r, bit_pos, bit_size, size, align, i;
695 #ifndef TCC_TARGET_X86_64
696 int rc2;
697 #endif
699 /* NOTE: get_reg can modify vstack[] */
700 if (vtop->type.t & VT_BITFIELD) {
701 CType type;
702 int bits = 32;
703 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
704 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
705 /* remove bit field info to avoid loops */
706 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
707 /* cast to int to propagate signedness in following ops */
708 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
709 type.t = VT_LLONG;
710 bits = 64;
711 } else
712 type.t = VT_INT;
713 if((vtop->type.t & VT_UNSIGNED) ||
714 (vtop->type.t & VT_BTYPE) == VT_BOOL)
715 type.t |= VT_UNSIGNED;
716 gen_cast(&type);
717 /* generate shifts */
718 vpushi(bits - (bit_pos + bit_size));
719 gen_op(TOK_SHL);
720 vpushi(bits - bit_size);
721 /* NOTE: transformed to SHR if unsigned */
722 gen_op(TOK_SAR);
723 r = gv(rc);
724 } else {
725 if (is_float(vtop->type.t) &&
726 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
727 Sym *sym;
728 int *ptr;
729 unsigned long offset;
730 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
731 CValue check;
732 #endif
734 /* XXX: unify with initializers handling ? */
735 /* CPUs usually cannot use float constants, so we store them
736 generically in data segment */
737 size = type_size(&vtop->type, &align);
738 offset = (data_section->data_offset + align - 1) & -align;
739 data_section->data_offset = offset;
740 /* XXX: not portable yet */
741 #if defined(__i386__) || defined(__x86_64__)
742 /* Zero pad x87 tenbyte long doubles */
743 if (size == LDOUBLE_SIZE) {
744 vtop->c.tab[2] &= 0xffff;
745 #if LDOUBLE_SIZE == 16
746 vtop->c.tab[3] = 0;
747 #endif
749 #endif
750 ptr = section_ptr_add(data_section, size);
751 size = size >> 2;
752 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
753 check.d = 1;
754 if(check.tab[0])
755 for(i=0;i<size;i++)
756 ptr[i] = vtop->c.tab[size-1-i];
757 else
758 #endif
759 for(i=0;i<size;i++)
760 ptr[i] = vtop->c.tab[i];
761 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
762 vtop->r |= VT_LVAL | VT_SYM;
763 vtop->sym = sym;
764 vtop->c.ul = 0;
766 #ifdef CONFIG_TCC_BCHECK
767 if (vtop->r & VT_MUSTBOUND)
768 gbound();
769 #endif
771 r = vtop->r & VT_VALMASK;
772 #ifndef TCC_TARGET_X86_64
773 rc2 = RC_INT;
774 if (rc == RC_IRET)
775 rc2 = RC_LRET;
776 #endif
777 /* need to reload if:
778 - constant
779 - lvalue (need to dereference pointer)
780 - already a register, but not in the right class */
781 if (r >= VT_CONST
782 || (vtop->r & VT_LVAL)
783 || !(reg_classes[r] & rc)
784 #ifndef TCC_TARGET_X86_64
785 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
786 #endif
789 r = get_reg(rc);
790 #ifndef TCC_TARGET_X86_64
791 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
792 int r2;
793 unsigned long long ll;
794 /* two register type load : expand to two words
795 temporarily */
796 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
797 /* load constant */
798 ll = vtop->c.ull;
799 vtop->c.ui = ll; /* first word */
800 load(r, vtop);
801 vtop->r = r; /* save register value */
802 vpushi(ll >> 32); /* second word */
803 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
804 (vtop->r & VT_LVAL)) {
805 /* We do not want to modifier the long long
806 pointer here, so the safest (and less
807 efficient) is to save all the other registers
808 in the stack. XXX: totally inefficient. */
809 save_regs(1);
810 /* load from memory */
811 load(r, vtop);
812 vdup();
813 vtop[-1].r = r; /* save register value */
814 /* increment pointer to get second word */
815 vtop->type.t = VT_INT;
816 gaddrof();
817 vpushi(4);
818 gen_op('+');
819 vtop->r |= VT_LVAL;
820 } else {
821 /* move registers */
822 load(r, vtop);
823 vdup();
824 vtop[-1].r = r; /* save register value */
825 vtop->r = vtop[-1].r2;
827 /* Allocate second register. Here we rely on the fact that
828 get_reg() tries first to free r2 of an SValue. */
829 r2 = get_reg(rc2);
830 load(r2, vtop);
831 vpop();
832 /* write second register */
833 vtop->r2 = r2;
834 } else
835 #endif
836 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
837 int t1, t;
838 /* lvalue of scalar type : need to use lvalue type
839 because of possible cast */
840 t = vtop->type.t;
841 t1 = t;
842 /* compute memory access type */
843 if (vtop->r & VT_LVAL_BYTE)
844 t = VT_BYTE;
845 else if (vtop->r & VT_LVAL_SHORT)
846 t = VT_SHORT;
847 if (vtop->r & VT_LVAL_UNSIGNED)
848 t |= VT_UNSIGNED;
849 vtop->type.t = t;
850 load(r, vtop);
851 /* restore wanted type */
852 vtop->type.t = t1;
853 } else {
854 /* one register type load */
855 load(r, vtop);
858 vtop->r = r;
859 #ifdef TCC_TARGET_C67
860 /* uses register pairs for doubles */
861 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
862 vtop->r2 = r+1;
863 #endif
865 return r;
868 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
869 ST_FUNC void gv2(int rc1, int rc2)
871 int v;
873 /* generate more generic register first. But VT_JMP or VT_CMP
874 values must be generated first in all cases to avoid possible
875 reload errors */
876 v = vtop[0].r & VT_VALMASK;
877 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
878 vswap();
879 gv(rc1);
880 vswap();
881 gv(rc2);
882 /* test if reload is needed for first register */
883 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
884 vswap();
885 gv(rc1);
886 vswap();
888 } else {
889 gv(rc2);
890 vswap();
891 gv(rc1);
892 vswap();
893 /* test if reload is needed for first register */
894 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
895 gv(rc2);
900 /* wrapper around RC_FRET to return a register by type */
901 static int rc_fret(int t)
903 #ifdef TCC_TARGET_X86_64
904 if (t == VT_LDOUBLE) {
905 return RC_ST0;
907 #endif
908 return RC_FRET;
911 /* wrapper around REG_FRET to return a register by type */
912 static int reg_fret(int t)
914 #ifdef TCC_TARGET_X86_64
915 if (t == VT_LDOUBLE) {
916 return TREG_ST0;
918 #endif
919 return REG_FRET;
922 /* expand long long on stack in two int registers */
923 static void lexpand(void)
925 int u;
927 u = vtop->type.t & VT_UNSIGNED;
928 gv(RC_INT);
929 vdup();
930 vtop[0].r = vtop[-1].r2;
931 vtop[0].r2 = VT_CONST;
932 vtop[-1].r2 = VT_CONST;
933 vtop[0].type.t = VT_INT | u;
934 vtop[-1].type.t = VT_INT | u;
937 #ifdef TCC_TARGET_ARM
938 /* expand long long on stack */
939 ST_FUNC void lexpand_nr(void)
941 int u,v;
943 u = vtop->type.t & VT_UNSIGNED;
944 vdup();
945 vtop->r2 = VT_CONST;
946 vtop->type.t = VT_INT | u;
947 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
948 if (v == VT_CONST) {
949 vtop[-1].c.ui = vtop->c.ull;
950 vtop->c.ui = vtop->c.ull >> 32;
951 vtop->r = VT_CONST;
952 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
953 vtop->c.ui += 4;
954 vtop->r = vtop[-1].r;
955 } else if (v > VT_CONST) {
956 vtop--;
957 lexpand();
958 } else
959 vtop->r = vtop[-1].r2;
960 vtop[-1].r2 = VT_CONST;
961 vtop[-1].type.t = VT_INT | u;
963 #endif
965 /* build a long long from two ints */
966 static void lbuild(int t)
968 gv2(RC_INT, RC_INT);
969 vtop[-1].r2 = vtop[0].r;
970 vtop[-1].type.t = t;
971 vpop();
974 /* rotate n first stack elements to the bottom
975 I1 ... In -> I2 ... In I1 [top is right]
977 ST_FUNC void vrotb(int n)
979 int i;
980 SValue tmp;
982 tmp = vtop[-n + 1];
983 for(i=-n+1;i!=0;i++)
984 vtop[i] = vtop[i+1];
985 vtop[0] = tmp;
988 /* rotate the n elements before entry e towards the top
989 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
991 ST_FUNC void vrote(SValue *e, int n)
993 int i;
994 SValue tmp;
996 tmp = *e;
997 for(i = 0;i < n - 1; i++)
998 e[-i] = e[-i - 1];
999 e[-n + 1] = tmp;
1002 /* rotate n first stack elements to the top
1003 I1 ... In -> In I1 ... I(n-1) [top is right]
1005 ST_FUNC void vrott(int n)
1007 vrote(vtop, n);
1010 /* pop stack value */
1011 ST_FUNC void vpop(void)
1013 int v;
1014 v = vtop->r & VT_VALMASK;
1015 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1016 /* for x86, we need to pop the FP stack */
1017 if (v == TREG_ST0 && !nocode_wanted) {
1018 o(0xd8dd); /* fstp %st(0) */
1019 } else
1020 #endif
1021 if (v == VT_JMP || v == VT_JMPI) {
1022 /* need to put correct jump if && or || without test */
1023 gsym(vtop->c.ul);
1025 vtop--;
1028 /* convert stack entry to register and duplicate its value in another
1029 register */
1030 static void gv_dup(void)
1032 int rc, t, r, r1;
1033 SValue sv;
1035 t = vtop->type.t;
1036 if ((t & VT_BTYPE) == VT_LLONG) {
1037 lexpand();
1038 gv_dup();
1039 vswap();
1040 vrotb(3);
1041 gv_dup();
1042 vrotb(4);
1043 /* stack: H L L1 H1 */
1044 lbuild(t);
1045 vrotb(3);
1046 vrotb(3);
1047 vswap();
1048 lbuild(t);
1049 vswap();
1050 } else {
1051 /* duplicate value */
1052 rc = RC_INT;
1053 sv.type.t = VT_INT;
1054 if (is_float(t)) {
1055 rc = RC_FLOAT;
1056 #ifdef TCC_TARGET_X86_64
1057 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1058 rc = RC_ST0;
1060 #endif
1061 sv.type.t = t;
1063 r = gv(rc);
1064 r1 = get_reg(rc);
1065 sv.r = r;
1066 sv.c.ul = 0;
1067 load(r1, &sv); /* move r to r1 */
1068 vdup();
1069 /* duplicates value */
1070 if (r != r1)
1071 vtop->r = r1;
1075 #ifndef TCC_TARGET_X86_64
1076 /* generate CPU independent (unsigned) long long operations */
1077 static void gen_opl(int op)
1079 int t, a, b, op1, c, i;
1080 int func;
1081 unsigned short reg_iret = REG_IRET;
1082 unsigned short reg_lret = REG_LRET;
1083 SValue tmp;
1085 switch(op) {
1086 case '/':
1087 case TOK_PDIV:
1088 func = TOK___divdi3;
1089 goto gen_func;
1090 case TOK_UDIV:
1091 func = TOK___udivdi3;
1092 goto gen_func;
1093 case '%':
1094 func = TOK___moddi3;
1095 goto gen_mod_func;
1096 case TOK_UMOD:
1097 func = TOK___umoddi3;
1098 gen_mod_func:
1099 #ifdef TCC_ARM_EABI
1100 reg_iret = TREG_R2;
1101 reg_lret = TREG_R3;
1102 #endif
1103 gen_func:
1104 /* call generic long long function */
1105 vpush_global_sym(&func_old_type, func);
1106 vrott(3);
1107 gfunc_call(2);
1108 vpushi(0);
1109 vtop->r = reg_iret;
1110 vtop->r2 = reg_lret;
1111 break;
1112 case '^':
1113 case '&':
1114 case '|':
1115 case '*':
1116 case '+':
1117 case '-':
1118 t = vtop->type.t;
1119 vswap();
1120 lexpand();
1121 vrotb(3);
1122 lexpand();
1123 /* stack: L1 H1 L2 H2 */
1124 tmp = vtop[0];
1125 vtop[0] = vtop[-3];
1126 vtop[-3] = tmp;
1127 tmp = vtop[-2];
1128 vtop[-2] = vtop[-3];
1129 vtop[-3] = tmp;
1130 vswap();
1131 /* stack: H1 H2 L1 L2 */
1132 if (op == '*') {
1133 vpushv(vtop - 1);
1134 vpushv(vtop - 1);
1135 gen_op(TOK_UMULL);
1136 lexpand();
1137 /* stack: H1 H2 L1 L2 ML MH */
1138 for(i=0;i<4;i++)
1139 vrotb(6);
1140 /* stack: ML MH H1 H2 L1 L2 */
1141 tmp = vtop[0];
1142 vtop[0] = vtop[-2];
1143 vtop[-2] = tmp;
1144 /* stack: ML MH H1 L2 H2 L1 */
1145 gen_op('*');
1146 vrotb(3);
1147 vrotb(3);
1148 gen_op('*');
1149 /* stack: ML MH M1 M2 */
1150 gen_op('+');
1151 gen_op('+');
1152 } else if (op == '+' || op == '-') {
1153 /* XXX: add non carry method too (for MIPS or alpha) */
1154 if (op == '+')
1155 op1 = TOK_ADDC1;
1156 else
1157 op1 = TOK_SUBC1;
1158 gen_op(op1);
1159 /* stack: H1 H2 (L1 op L2) */
1160 vrotb(3);
1161 vrotb(3);
1162 gen_op(op1 + 1); /* TOK_xxxC2 */
1163 } else {
1164 gen_op(op);
1165 /* stack: H1 H2 (L1 op L2) */
1166 vrotb(3);
1167 vrotb(3);
1168 /* stack: (L1 op L2) H1 H2 */
1169 gen_op(op);
1170 /* stack: (L1 op L2) (H1 op H2) */
1172 /* stack: L H */
1173 lbuild(t);
1174 break;
1175 case TOK_SAR:
1176 case TOK_SHR:
1177 case TOK_SHL:
1178 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1179 t = vtop[-1].type.t;
1180 vswap();
1181 lexpand();
1182 vrotb(3);
1183 /* stack: L H shift */
1184 c = (int)vtop->c.i;
1185 /* constant: simpler */
1186 /* NOTE: all comments are for SHL. the other cases are
1187 done by swaping words */
1188 vpop();
1189 if (op != TOK_SHL)
1190 vswap();
1191 if (c >= 32) {
1192 /* stack: L H */
1193 vpop();
1194 if (c > 32) {
1195 vpushi(c - 32);
1196 gen_op(op);
1198 if (op != TOK_SAR) {
1199 vpushi(0);
1200 } else {
1201 gv_dup();
1202 vpushi(31);
1203 gen_op(TOK_SAR);
1205 vswap();
1206 } else {
1207 vswap();
1208 gv_dup();
1209 /* stack: H L L */
1210 vpushi(c);
1211 gen_op(op);
1212 vswap();
1213 vpushi(32 - c);
1214 if (op == TOK_SHL)
1215 gen_op(TOK_SHR);
1216 else
1217 gen_op(TOK_SHL);
1218 vrotb(3);
1219 /* stack: L L H */
1220 vpushi(c);
1221 if (op == TOK_SHL)
1222 gen_op(TOK_SHL);
1223 else
1224 gen_op(TOK_SHR);
1225 gen_op('|');
1227 if (op != TOK_SHL)
1228 vswap();
1229 lbuild(t);
1230 } else {
1231 /* XXX: should provide a faster fallback on x86 ? */
1232 switch(op) {
1233 case TOK_SAR:
1234 func = TOK___ashrdi3;
1235 goto gen_func;
1236 case TOK_SHR:
1237 func = TOK___lshrdi3;
1238 goto gen_func;
1239 case TOK_SHL:
1240 func = TOK___ashldi3;
1241 goto gen_func;
1244 break;
1245 default:
1246 /* compare operations */
1247 t = vtop->type.t;
1248 vswap();
1249 lexpand();
1250 vrotb(3);
1251 lexpand();
1252 /* stack: L1 H1 L2 H2 */
1253 tmp = vtop[-1];
1254 vtop[-1] = vtop[-2];
1255 vtop[-2] = tmp;
1256 /* stack: L1 L2 H1 H2 */
1257 /* compare high */
1258 op1 = op;
1259 /* when values are equal, we need to compare low words. since
1260 the jump is inverted, we invert the test too. */
1261 if (op1 == TOK_LT)
1262 op1 = TOK_LE;
1263 else if (op1 == TOK_GT)
1264 op1 = TOK_GE;
1265 else if (op1 == TOK_ULT)
1266 op1 = TOK_ULE;
1267 else if (op1 == TOK_UGT)
1268 op1 = TOK_UGE;
1269 a = 0;
1270 b = 0;
1271 gen_op(op1);
1272 if (op1 != TOK_NE) {
1273 a = gtst(1, 0);
1275 if (op != TOK_EQ) {
1276 /* generate non equal test */
1277 /* XXX: NOT PORTABLE yet */
1278 if (a == 0) {
1279 b = gtst(0, 0);
1280 } else {
1281 #if defined(TCC_TARGET_I386)
1282 b = psym(0x850f, 0);
1283 #elif defined(TCC_TARGET_ARM)
1284 b = ind;
1285 o(0x1A000000 | encbranch(ind, 0, 1));
1286 #elif defined(TCC_TARGET_C67)
1287 tcc_error("not implemented");
1288 #else
1289 #error not supported
1290 #endif
1293 /* compare low. Always unsigned */
1294 op1 = op;
1295 if (op1 == TOK_LT)
1296 op1 = TOK_ULT;
1297 else if (op1 == TOK_LE)
1298 op1 = TOK_ULE;
1299 else if (op1 == TOK_GT)
1300 op1 = TOK_UGT;
1301 else if (op1 == TOK_GE)
1302 op1 = TOK_UGE;
1303 gen_op(op1);
1304 a = gtst(1, a);
1305 gsym(b);
1306 vseti(VT_JMPI, a);
1307 break;
1310 #endif
1312 /* handle integer constant optimizations and various machine
1313 independent opt */
1314 static void gen_opic(int op)
1316 int c1, c2, t1, t2, n;
1317 SValue *v1, *v2;
1318 long long l1, l2;
1319 typedef unsigned long long U;
1321 v1 = vtop - 1;
1322 v2 = vtop;
1323 t1 = v1->type.t & VT_BTYPE;
1324 t2 = v2->type.t & VT_BTYPE;
1326 if (t1 == VT_LLONG)
1327 l1 = v1->c.ll;
1328 else if (v1->type.t & VT_UNSIGNED)
1329 l1 = v1->c.ui;
1330 else
1331 l1 = v1->c.i;
1333 if (t2 == VT_LLONG)
1334 l2 = v2->c.ll;
1335 else if (v2->type.t & VT_UNSIGNED)
1336 l2 = v2->c.ui;
1337 else
1338 l2 = v2->c.i;
1340 /* currently, we cannot do computations with forward symbols */
1341 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1342 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1343 if (c1 && c2) {
1344 switch(op) {
1345 case '+': l1 += l2; break;
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;
1352 case TOK_PDIV:
1353 case '/':
1354 case '%':
1355 case TOK_UDIV:
1356 case TOK_UMOD:
1357 /* if division by zero, generate explicit division */
1358 if (l2 == 0) {
1359 if (const_wanted)
1360 tcc_error("division by zero in constant");
1361 goto general_case;
1363 switch(op) {
1364 default: l1 /= l2; break;
1365 case '%': l1 %= l2; break;
1366 case TOK_UDIV: l1 = (U)l1 / l2; break;
1367 case TOK_UMOD: l1 = (U)l1 % l2; break;
1369 break;
1370 case TOK_SHL: l1 <<= l2; break;
1371 case TOK_SHR: l1 = (U)l1 >> l2; break;
1372 case TOK_SAR: l1 >>= l2; break;
1373 /* tests */
1374 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1375 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1376 case TOK_EQ: l1 = l1 == l2; break;
1377 case TOK_NE: l1 = l1 != l2; break;
1378 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1379 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1380 case TOK_LT: l1 = l1 < l2; break;
1381 case TOK_GE: l1 = l1 >= l2; break;
1382 case TOK_LE: l1 = l1 <= l2; break;
1383 case TOK_GT: l1 = l1 > l2; break;
1384 /* logical */
1385 case TOK_LAND: l1 = l1 && l2; break;
1386 case TOK_LOR: l1 = l1 || l2; break;
1387 default:
1388 goto general_case;
1390 v1->c.ll = l1;
1391 vtop--;
1392 } else {
1393 /* if commutative ops, put c2 as constant */
1394 if (c1 && (op == '+' || op == '&' || op == '^' ||
1395 op == '|' || op == '*')) {
1396 vswap();
1397 c2 = c1; //c = c1, c1 = c2, c2 = c;
1398 l2 = l1; //l = l1, l1 = l2, l2 = l;
1400 /* Filter out NOP operations like x*1, x-0, x&-1... */
1401 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1402 op == TOK_PDIV) &&
1403 l2 == 1) ||
1404 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1405 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1406 l2 == 0) ||
1407 (op == '&' &&
1408 l2 == -1))) {
1409 /* nothing to do */
1410 vtop--;
1411 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1412 /* try to use shifts instead of muls or divs */
1413 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1414 n = -1;
1415 while (l2) {
1416 l2 >>= 1;
1417 n++;
1419 vtop->c.ll = n;
1420 if (op == '*')
1421 op = TOK_SHL;
1422 else if (op == TOK_PDIV)
1423 op = TOK_SAR;
1424 else
1425 op = TOK_SHR;
1427 goto general_case;
1428 } else if (c2 && (op == '+' || op == '-') &&
1429 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1430 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1431 /* symbol + constant case */
1432 if (op == '-')
1433 l2 = -l2;
1434 vtop--;
1435 vtop->c.ll += l2;
1436 } else {
1437 general_case:
1438 if (!nocode_wanted) {
1439 /* call low level op generator */
1440 if (t1 == VT_LLONG || t2 == VT_LLONG)
1441 gen_opl(op);
1442 else
1443 gen_opi(op);
1444 } else {
1445 vtop--;
1451 /* generate a floating point operation with constant propagation */
1452 static void gen_opif(int op)
1454 int c1, c2;
1455 SValue *v1, *v2;
1456 long double f1, f2;
1458 v1 = vtop - 1;
1459 v2 = vtop;
1460 /* currently, we cannot do computations with forward symbols */
1461 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1462 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1463 if (c1 && c2) {
1464 if (v1->type.t == VT_FLOAT) {
1465 f1 = v1->c.f;
1466 f2 = v2->c.f;
1467 } else if (v1->type.t == VT_DOUBLE) {
1468 f1 = v1->c.d;
1469 f2 = v2->c.d;
1470 } else {
1471 f1 = v1->c.ld;
1472 f2 = v2->c.ld;
1475 /* NOTE: we only do constant propagation if finite number (not
1476 NaN or infinity) (ANSI spec) */
1477 if (!ieee_finite(f1) || !ieee_finite(f2))
1478 goto general_case;
1480 switch(op) {
1481 case '+': f1 += f2; break;
1482 case '-': f1 -= f2; break;
1483 case '*': f1 *= f2; break;
1484 case '/':
1485 if (f2 == 0.0) {
1486 if (const_wanted)
1487 tcc_error("division by zero in constant");
1488 goto general_case;
1490 f1 /= f2;
1491 break;
1492 /* XXX: also handles tests ? */
1493 default:
1494 goto general_case;
1496 /* XXX: overflow test ? */
1497 if (v1->type.t == VT_FLOAT) {
1498 v1->c.f = f1;
1499 } else if (v1->type.t == VT_DOUBLE) {
1500 v1->c.d = f1;
1501 } else {
1502 v1->c.ld = f1;
1504 vtop--;
1505 } else {
1506 general_case:
1507 if (!nocode_wanted) {
1508 gen_opf(op);
1509 } else {
1510 vtop--;
1515 static int pointed_size(CType *type)
1517 int align;
1518 return type_size(pointed_type(type), &align);
1521 static void vla_runtime_pointed_size(CType *type)
1523 int align;
1524 vla_runtime_type_size(pointed_type(type), &align);
1527 static inline int is_null_pointer(SValue *p)
1529 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1530 return 0;
1531 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1532 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1533 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
1536 static inline int is_integer_btype(int bt)
1538 return (bt == VT_BYTE || bt == VT_SHORT ||
1539 bt == VT_INT || bt == VT_LLONG);
1542 /* check types for comparison or substraction of pointers */
1543 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1545 CType *type1, *type2, tmp_type1, tmp_type2;
1546 int bt1, bt2;
1548 /* null pointers are accepted for all comparisons as gcc */
1549 if (is_null_pointer(p1) || is_null_pointer(p2))
1550 return;
1551 type1 = &p1->type;
1552 type2 = &p2->type;
1553 bt1 = type1->t & VT_BTYPE;
1554 bt2 = type2->t & VT_BTYPE;
1555 /* accept comparison between pointer and integer with a warning */
1556 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1557 if (op != TOK_LOR && op != TOK_LAND )
1558 tcc_warning("comparison between pointer and integer");
1559 return;
1562 /* both must be pointers or implicit function pointers */
1563 if (bt1 == VT_PTR) {
1564 type1 = pointed_type(type1);
1565 } else if (bt1 != VT_FUNC)
1566 goto invalid_operands;
1568 if (bt2 == VT_PTR) {
1569 type2 = pointed_type(type2);
1570 } else if (bt2 != VT_FUNC) {
1571 invalid_operands:
1572 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1574 if ((type1->t & VT_BTYPE) == VT_VOID ||
1575 (type2->t & VT_BTYPE) == VT_VOID)
1576 return;
1577 tmp_type1 = *type1;
1578 tmp_type2 = *type2;
1579 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1580 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1581 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1582 /* gcc-like error if '-' is used */
1583 if (op == '-')
1584 goto invalid_operands;
1585 else
1586 tcc_warning("comparison of distinct pointer types lacks a cast");
1590 /* generic gen_op: handles types problems */
1591 ST_FUNC void gen_op(int op)
1593 int u, t1, t2, bt1, bt2, t;
1594 CType type1;
1596 t1 = vtop[-1].type.t;
1597 t2 = vtop[0].type.t;
1598 bt1 = t1 & VT_BTYPE;
1599 bt2 = t2 & VT_BTYPE;
1601 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1602 /* at least one operand is a pointer */
1603 /* relationnal op: must be both pointers */
1604 if (op >= TOK_ULT && op <= TOK_LOR) {
1605 check_comparison_pointer_types(vtop - 1, vtop, op);
1606 /* pointers are handled are unsigned */
1607 #ifdef TCC_TARGET_X86_64
1608 t = VT_LLONG | VT_UNSIGNED;
1609 #else
1610 t = VT_INT | VT_UNSIGNED;
1611 #endif
1612 goto std_op;
1614 /* if both pointers, then it must be the '-' op */
1615 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1616 if (op != '-')
1617 tcc_error("cannot use pointers here");
1618 check_comparison_pointer_types(vtop - 1, vtop, op);
1619 /* XXX: check that types are compatible */
1620 if (vtop[-1].type.t & VT_VLA) {
1621 vla_runtime_pointed_size(&vtop[-1].type);
1622 } else {
1623 vpushi(pointed_size(&vtop[-1].type));
1625 vrott(3);
1626 gen_opic(op);
1627 /* set to integer type */
1628 #ifdef TCC_TARGET_X86_64
1629 vtop->type.t = VT_LLONG;
1630 #else
1631 vtop->type.t = VT_INT;
1632 #endif
1633 vswap();
1634 gen_op(TOK_PDIV);
1635 } else {
1636 /* exactly one pointer : must be '+' or '-'. */
1637 if (op != '-' && op != '+')
1638 tcc_error("cannot use pointers here");
1639 /* Put pointer as first operand */
1640 if (bt2 == VT_PTR) {
1641 vswap();
1642 swap(&t1, &t2);
1644 type1 = vtop[-1].type;
1645 type1.t &= ~VT_ARRAY;
1646 if (vtop[-1].type.t & VT_VLA)
1647 vla_runtime_pointed_size(&vtop[-1].type);
1648 else {
1649 u = pointed_size(&vtop[-1].type);
1650 if (u < 0)
1651 tcc_error("unknown array element size");
1652 #ifdef TCC_TARGET_X86_64
1653 vpushll(u);
1654 #else
1655 /* XXX: cast to int ? (long long case) */
1656 vpushi(u);
1657 #endif
1659 gen_op('*');
1660 #ifdef CONFIG_TCC_BCHECK
1661 /* if evaluating constant expression, no code should be
1662 generated, so no bound check */
1663 if (tcc_state->do_bounds_check && !const_wanted) {
1664 /* if bounded pointers, we generate a special code to
1665 test bounds */
1666 if (op == '-') {
1667 vpushi(0);
1668 vswap();
1669 gen_op('-');
1671 gen_bounded_ptr_add();
1672 } else
1673 #endif
1675 gen_opic(op);
1677 /* put again type if gen_opic() swaped operands */
1678 vtop->type = type1;
1680 } else if (is_float(bt1) || is_float(bt2)) {
1681 /* compute bigger type and do implicit casts */
1682 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1683 t = VT_LDOUBLE;
1684 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1685 t = VT_DOUBLE;
1686 } else {
1687 t = VT_FLOAT;
1689 /* floats can only be used for a few operations */
1690 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1691 (op < TOK_ULT || op > TOK_GT))
1692 tcc_error("invalid operands for binary operation");
1693 goto std_op;
1694 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1695 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1696 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1697 t |= VT_UNSIGNED;
1698 goto std_op;
1699 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1700 /* cast to biggest op */
1701 t = VT_LLONG;
1702 /* convert to unsigned if it does not fit in a long long */
1703 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1704 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1705 t |= VT_UNSIGNED;
1706 goto std_op;
1707 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1708 tcc_error("comparison of struct");
1709 } else {
1710 /* integer operations */
1711 t = VT_INT;
1712 /* convert to unsigned if it does not fit in an integer */
1713 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1714 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1715 t |= VT_UNSIGNED;
1716 std_op:
1717 /* XXX: currently, some unsigned operations are explicit, so
1718 we modify them here */
1719 if (t & VT_UNSIGNED) {
1720 if (op == TOK_SAR)
1721 op = TOK_SHR;
1722 else if (op == '/')
1723 op = TOK_UDIV;
1724 else if (op == '%')
1725 op = TOK_UMOD;
1726 else if (op == TOK_LT)
1727 op = TOK_ULT;
1728 else if (op == TOK_GT)
1729 op = TOK_UGT;
1730 else if (op == TOK_LE)
1731 op = TOK_ULE;
1732 else if (op == TOK_GE)
1733 op = TOK_UGE;
1735 vswap();
1736 type1.t = t;
1737 gen_cast(&type1);
1738 vswap();
1739 /* special case for shifts and long long: we keep the shift as
1740 an integer */
1741 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1742 type1.t = VT_INT;
1743 gen_cast(&type1);
1744 if (is_float(t))
1745 gen_opif(op);
1746 else
1747 gen_opic(op);
1748 if (op >= TOK_ULT && op <= TOK_GT) {
1749 /* relationnal op: the result is an int */
1750 vtop->type.t = VT_INT;
1751 } else {
1752 vtop->type.t = t;
1757 #ifndef TCC_TARGET_ARM
1758 /* generic itof for unsigned long long case */
1759 static void gen_cvt_itof1(int t)
1761 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1762 (VT_LLONG | VT_UNSIGNED)) {
1764 if (t == VT_FLOAT)
1765 vpush_global_sym(&func_old_type, TOK___floatundisf);
1766 #if LDOUBLE_SIZE != 8
1767 else if (t == VT_LDOUBLE)
1768 vpush_global_sym(&func_old_type, TOK___floatundixf);
1769 #endif
1770 else
1771 vpush_global_sym(&func_old_type, TOK___floatundidf);
1772 vrott(2);
1773 gfunc_call(1);
1774 vpushi(0);
1775 vtop->r = reg_fret(t);
1776 } else {
1777 gen_cvt_itof(t);
1780 #endif
1782 /* generic ftoi for unsigned long long case */
1783 static void gen_cvt_ftoi1(int t)
1785 int st;
1787 if (t == (VT_LLONG | VT_UNSIGNED)) {
1788 /* not handled natively */
1789 st = vtop->type.t & VT_BTYPE;
1790 if (st == VT_FLOAT)
1791 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1792 #if LDOUBLE_SIZE != 8
1793 else if (st == VT_LDOUBLE)
1794 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1795 #endif
1796 else
1797 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1798 vrott(2);
1799 gfunc_call(1);
1800 vpushi(0);
1801 vtop->r = REG_IRET;
1802 vtop->r2 = REG_LRET;
1803 } else {
1804 gen_cvt_ftoi(t);
1808 /* force char or short cast */
1809 static void force_charshort_cast(int t)
1811 int bits, dbt;
1812 dbt = t & VT_BTYPE;
1813 /* XXX: add optimization if lvalue : just change type and offset */
1814 if (dbt == VT_BYTE)
1815 bits = 8;
1816 else
1817 bits = 16;
1818 if (t & VT_UNSIGNED) {
1819 vpushi((1 << bits) - 1);
1820 gen_op('&');
1821 } else {
1822 bits = 32 - bits;
1823 vpushi(bits);
1824 gen_op(TOK_SHL);
1825 /* result must be signed or the SAR is converted to an SHL
1826 This was not the case when "t" was a signed short
1827 and the last value on the stack was an unsigned int */
1828 vtop->type.t &= ~VT_UNSIGNED;
1829 vpushi(bits);
1830 gen_op(TOK_SAR);
1834 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1835 static void gen_cast(CType *type)
1837 int sbt, dbt, sf, df, c, p;
1839 /* special delayed cast for char/short */
1840 /* XXX: in some cases (multiple cascaded casts), it may still
1841 be incorrect */
1842 if (vtop->r & VT_MUSTCAST) {
1843 vtop->r &= ~VT_MUSTCAST;
1844 force_charshort_cast(vtop->type.t);
1847 /* bitfields first get cast to ints */
1848 if (vtop->type.t & VT_BITFIELD) {
1849 gv(RC_INT);
1852 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1853 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1855 if (sbt != dbt) {
1856 sf = is_float(sbt);
1857 df = is_float(dbt);
1858 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1859 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1860 if (c) {
1861 /* constant case: we can do it now */
1862 /* XXX: in ISOC, cannot do it if error in convert */
1863 if (sbt == VT_FLOAT)
1864 vtop->c.ld = vtop->c.f;
1865 else if (sbt == VT_DOUBLE)
1866 vtop->c.ld = vtop->c.d;
1868 if (df) {
1869 if ((sbt & VT_BTYPE) == VT_LLONG) {
1870 if (sbt & VT_UNSIGNED)
1871 vtop->c.ld = vtop->c.ull;
1872 else
1873 vtop->c.ld = vtop->c.ll;
1874 } else if(!sf) {
1875 if (sbt & VT_UNSIGNED)
1876 vtop->c.ld = vtop->c.ui;
1877 else
1878 vtop->c.ld = vtop->c.i;
1881 if (dbt == VT_FLOAT)
1882 vtop->c.f = (float)vtop->c.ld;
1883 else if (dbt == VT_DOUBLE)
1884 vtop->c.d = (double)vtop->c.ld;
1885 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1886 vtop->c.ull = (unsigned long long)vtop->c.ld;
1887 } else if (sf && dbt == VT_BOOL) {
1888 vtop->c.i = (vtop->c.ld != 0);
1889 } else {
1890 if(sf)
1891 vtop->c.ll = (long long)vtop->c.ld;
1892 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1893 vtop->c.ll = vtop->c.ull;
1894 else if (sbt & VT_UNSIGNED)
1895 vtop->c.ll = vtop->c.ui;
1896 #ifdef TCC_TARGET_X86_64
1897 else if (sbt == VT_PTR)
1899 #endif
1900 else if (sbt != VT_LLONG)
1901 vtop->c.ll = vtop->c.i;
1903 if (dbt == (VT_LLONG|VT_UNSIGNED))
1904 vtop->c.ull = vtop->c.ll;
1905 else if (dbt == VT_BOOL)
1906 vtop->c.i = (vtop->c.ll != 0);
1907 else if (dbt != VT_LLONG) {
1908 int s = 0;
1909 if ((dbt & VT_BTYPE) == VT_BYTE)
1910 s = 24;
1911 else if ((dbt & VT_BTYPE) == VT_SHORT)
1912 s = 16;
1914 if(dbt & VT_UNSIGNED)
1915 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1916 else
1917 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1920 } else if (p && dbt == VT_BOOL) {
1921 vtop->r = VT_CONST;
1922 vtop->c.i = 1;
1923 } else if (!nocode_wanted) {
1924 /* non constant case: generate code */
1925 if (sf && df) {
1926 /* convert from fp to fp */
1927 gen_cvt_ftof(dbt);
1928 } else if (df) {
1929 /* convert int to fp */
1930 gen_cvt_itof1(dbt);
1931 } else if (sf) {
1932 /* convert fp to int */
1933 if (dbt == VT_BOOL) {
1934 vpushi(0);
1935 gen_op(TOK_NE);
1936 } else {
1937 /* we handle char/short/etc... with generic code */
1938 if (dbt != (VT_INT | VT_UNSIGNED) &&
1939 dbt != (VT_LLONG | VT_UNSIGNED) &&
1940 dbt != VT_LLONG)
1941 dbt = VT_INT;
1942 gen_cvt_ftoi1(dbt);
1943 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1944 /* additional cast for char/short... */
1945 vtop->type.t = dbt;
1946 gen_cast(type);
1949 #ifndef TCC_TARGET_X86_64
1950 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1951 if ((sbt & VT_BTYPE) != VT_LLONG) {
1952 /* scalar to long long */
1953 /* machine independent conversion */
1954 gv(RC_INT);
1955 /* generate high word */
1956 if (sbt == (VT_INT | VT_UNSIGNED)) {
1957 vpushi(0);
1958 gv(RC_INT);
1959 } else {
1960 if (sbt == VT_PTR) {
1961 /* cast from pointer to int before we apply
1962 shift operation, which pointers don't support*/
1963 gen_cast(&int_type);
1965 gv_dup();
1966 vpushi(31);
1967 gen_op(TOK_SAR);
1969 /* patch second register */
1970 vtop[-1].r2 = vtop->r;
1971 vpop();
1973 #else
1974 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1975 (dbt & VT_BTYPE) == VT_PTR ||
1976 (dbt & VT_BTYPE) == VT_FUNC) {
1977 if ((sbt & VT_BTYPE) != VT_LLONG &&
1978 (sbt & VT_BTYPE) != VT_PTR &&
1979 (sbt & VT_BTYPE) != VT_FUNC) {
1980 /* need to convert from 32bit to 64bit */
1981 int r = gv(RC_INT);
1982 if (sbt != (VT_INT | VT_UNSIGNED)) {
1983 /* x86_64 specific: movslq */
1984 o(0x6348);
1985 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1988 #endif
1989 } else if (dbt == VT_BOOL) {
1990 /* scalar to bool */
1991 vpushi(0);
1992 gen_op(TOK_NE);
1993 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1994 (dbt & VT_BTYPE) == VT_SHORT) {
1995 if (sbt == VT_PTR) {
1996 vtop->type.t = VT_INT;
1997 tcc_warning("nonportable conversion from pointer to char/short");
1999 force_charshort_cast(dbt);
2000 } else if ((dbt & VT_BTYPE) == VT_INT) {
2001 /* scalar to int */
2002 if (sbt == VT_LLONG) {
2003 /* from long long: just take low order word */
2004 lexpand();
2005 vpop();
2007 /* if lvalue and single word type, nothing to do because
2008 the lvalue already contains the real type size (see
2009 VT_LVAL_xxx constants) */
2012 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2013 /* if we are casting between pointer types,
2014 we must update the VT_LVAL_xxx size */
2015 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2016 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2018 vtop->type = *type;
2021 /* return type size as known at compile time. Put alignment at 'a' */
2022 ST_FUNC int type_size(CType *type, int *a)
2024 Sym *s;
2025 int bt;
2027 bt = type->t & VT_BTYPE;
2028 if (bt == VT_STRUCT) {
2029 /* struct/union */
2030 s = type->ref;
2031 *a = s->r;
2032 return s->c;
2033 } else if (bt == VT_PTR) {
2034 if (type->t & VT_ARRAY) {
2035 int ts;
2037 s = type->ref;
2038 ts = type_size(&s->type, a);
2040 if (ts < 0 && s->c < 0)
2041 ts = -ts;
2043 return ts * s->c;
2044 } else {
2045 *a = PTR_SIZE;
2046 return PTR_SIZE;
2048 } else if (bt == VT_LDOUBLE) {
2049 *a = LDOUBLE_ALIGN;
2050 return LDOUBLE_SIZE;
2051 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2052 #ifdef TCC_TARGET_I386
2053 #ifdef TCC_TARGET_PE
2054 *a = 8;
2055 #else
2056 *a = 4;
2057 #endif
2058 #elif defined(TCC_TARGET_ARM)
2059 #ifdef TCC_ARM_EABI
2060 *a = 8;
2061 #else
2062 *a = 4;
2063 #endif
2064 #else
2065 *a = 8;
2066 #endif
2067 return 8;
2068 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2069 *a = 4;
2070 return 4;
2071 } else if (bt == VT_SHORT) {
2072 *a = 2;
2073 return 2;
2074 } else {
2075 /* char, void, function, _Bool */
2076 *a = 1;
2077 return 1;
2081 /* push type size as known at runtime time on top of value stack. Put
2082 alignment at 'a' */
2083 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2085 if (type->t & VT_VLA) {
2086 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2087 } else {
2088 vpushi(type_size(type, a));
2092 /* return the pointed type of t */
2093 static inline CType *pointed_type(CType *type)
2095 return &type->ref->type;
2098 /* modify type so that its it is a pointer to type. */
2099 ST_FUNC void mk_pointer(CType *type)
2101 Sym *s;
2102 s = sym_push(SYM_FIELD, type, 0, -1);
2103 type->t = VT_PTR | (type->t & ~VT_TYPE);
2104 type->ref = s;
2107 /* compare function types. OLD functions match any new functions */
2108 static int is_compatible_func(CType *type1, CType *type2)
2110 Sym *s1, *s2;
2112 s1 = type1->ref;
2113 s2 = type2->ref;
2114 if (!is_compatible_types(&s1->type, &s2->type))
2115 return 0;
2116 /* check func_call */
2117 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2118 return 0;
2119 /* XXX: not complete */
2120 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2121 return 1;
2122 if (s1->c != s2->c)
2123 return 0;
2124 while (s1 != NULL) {
2125 if (s2 == NULL)
2126 return 0;
2127 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2128 return 0;
2129 s1 = s1->next;
2130 s2 = s2->next;
2132 if (s2)
2133 return 0;
2134 return 1;
2137 /* return true if type1 and type2 are the same. If unqualified is
2138 true, qualifiers on the types are ignored.
2140 - enums are not checked as gcc __builtin_types_compatible_p ()
2142 static int compare_types(CType *type1, CType *type2, int unqualified)
2144 int bt1, t1, t2;
2146 t1 = type1->t & VT_TYPE;
2147 t2 = type2->t & VT_TYPE;
2148 if (unqualified) {
2149 /* strip qualifiers before comparing */
2150 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2151 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2153 /* XXX: bitfields ? */
2154 if (t1 != t2)
2155 return 0;
2156 /* test more complicated cases */
2157 bt1 = t1 & VT_BTYPE;
2158 if (bt1 == VT_PTR) {
2159 type1 = pointed_type(type1);
2160 type2 = pointed_type(type2);
2161 return is_compatible_types(type1, type2);
2162 } else if (bt1 == VT_STRUCT) {
2163 return (type1->ref == type2->ref);
2164 } else if (bt1 == VT_FUNC) {
2165 return is_compatible_func(type1, type2);
2166 } else {
2167 return 1;
2171 /* return true if type1 and type2 are exactly the same (including
2172 qualifiers).
2174 static int is_compatible_types(CType *type1, CType *type2)
2176 return compare_types(type1,type2,0);
2179 /* return true if type1 and type2 are the same (ignoring qualifiers).
2181 static int is_compatible_parameter_types(CType *type1, CType *type2)
2183 return compare_types(type1,type2,1);
2186 /* print a type. If 'varstr' is not NULL, then the variable is also
2187 printed in the type */
2188 /* XXX: union */
2189 /* XXX: add array and function pointers */
2190 static void type_to_str(char *buf, int buf_size,
2191 CType *type, const char *varstr)
2193 int bt, v, t;
2194 Sym *s, *sa;
2195 char buf1[256];
2196 const char *tstr;
2198 t = type->t & VT_TYPE;
2199 bt = t & VT_BTYPE;
2200 buf[0] = '\0';
2201 if (t & VT_CONSTANT)
2202 pstrcat(buf, buf_size, "const ");
2203 if (t & VT_VOLATILE)
2204 pstrcat(buf, buf_size, "volatile ");
2205 if (t & VT_UNSIGNED)
2206 pstrcat(buf, buf_size, "unsigned ");
2207 switch(bt) {
2208 case VT_VOID:
2209 tstr = "void";
2210 goto add_tstr;
2211 case VT_BOOL:
2212 tstr = "_Bool";
2213 goto add_tstr;
2214 case VT_BYTE:
2215 tstr = "char";
2216 goto add_tstr;
2217 case VT_SHORT:
2218 tstr = "short";
2219 goto add_tstr;
2220 case VT_INT:
2221 tstr = "int";
2222 goto add_tstr;
2223 case VT_LONG:
2224 tstr = "long";
2225 goto add_tstr;
2226 case VT_LLONG:
2227 tstr = "long long";
2228 goto add_tstr;
2229 case VT_FLOAT:
2230 tstr = "float";
2231 goto add_tstr;
2232 case VT_DOUBLE:
2233 tstr = "double";
2234 goto add_tstr;
2235 case VT_LDOUBLE:
2236 tstr = "long double";
2237 add_tstr:
2238 pstrcat(buf, buf_size, tstr);
2239 break;
2240 case VT_ENUM:
2241 case VT_STRUCT:
2242 if (bt == VT_STRUCT)
2243 tstr = "struct ";
2244 else
2245 tstr = "enum ";
2246 pstrcat(buf, buf_size, tstr);
2247 v = type->ref->v & ~SYM_STRUCT;
2248 if (v >= SYM_FIRST_ANOM)
2249 pstrcat(buf, buf_size, "<anonymous>");
2250 else
2251 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2252 break;
2253 case VT_FUNC:
2254 s = type->ref;
2255 type_to_str(buf, buf_size, &s->type, varstr);
2256 pstrcat(buf, buf_size, "(");
2257 sa = s->next;
2258 while (sa != NULL) {
2259 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2260 pstrcat(buf, buf_size, buf1);
2261 sa = sa->next;
2262 if (sa)
2263 pstrcat(buf, buf_size, ", ");
2265 pstrcat(buf, buf_size, ")");
2266 goto no_var;
2267 case VT_PTR:
2268 s = type->ref;
2269 pstrcpy(buf1, sizeof(buf1), "*");
2270 if (varstr)
2271 pstrcat(buf1, sizeof(buf1), varstr);
2272 type_to_str(buf, buf_size, &s->type, buf1);
2273 goto no_var;
2275 if (varstr) {
2276 pstrcat(buf, buf_size, " ");
2277 pstrcat(buf, buf_size, varstr);
2279 no_var: ;
2282 /* verify type compatibility to store vtop in 'dt' type, and generate
2283 casts if needed. */
2284 static void gen_assign_cast(CType *dt)
2286 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2287 char buf1[256], buf2[256];
2288 int dbt, sbt;
2290 st = &vtop->type; /* source type */
2291 dbt = dt->t & VT_BTYPE;
2292 sbt = st->t & VT_BTYPE;
2293 if (sbt == VT_VOID)
2294 tcc_error("Cannot assign void value");
2295 if (dt->t & VT_CONSTANT)
2296 tcc_warning("assignment of read-only location");
2297 switch(dbt) {
2298 case VT_PTR:
2299 /* special cases for pointers */
2300 /* '0' can also be a pointer */
2301 if (is_null_pointer(vtop))
2302 goto type_ok;
2303 /* accept implicit pointer to integer cast with warning */
2304 if (is_integer_btype(sbt)) {
2305 tcc_warning("assignment makes pointer from integer without a cast");
2306 goto type_ok;
2308 type1 = pointed_type(dt);
2309 /* a function is implicitely a function pointer */
2310 if (sbt == VT_FUNC) {
2311 if ((type1->t & VT_BTYPE) != VT_VOID &&
2312 !is_compatible_types(pointed_type(dt), st))
2313 tcc_warning("assignment from incompatible pointer type");
2314 goto type_ok;
2316 if (sbt != VT_PTR)
2317 goto error;
2318 type2 = pointed_type(st);
2319 if ((type1->t & VT_BTYPE) == VT_VOID ||
2320 (type2->t & VT_BTYPE) == VT_VOID) {
2321 /* void * can match anything */
2322 } else {
2323 /* exact type match, except for unsigned */
2324 tmp_type1 = *type1;
2325 tmp_type2 = *type2;
2326 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2327 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2328 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2329 tcc_warning("assignment from incompatible pointer type");
2331 /* check const and volatile */
2332 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2333 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2334 tcc_warning("assignment discards qualifiers from pointer target type");
2335 break;
2336 case VT_BYTE:
2337 case VT_SHORT:
2338 case VT_INT:
2339 case VT_LLONG:
2340 if (sbt == VT_PTR || sbt == VT_FUNC) {
2341 tcc_warning("assignment makes integer from pointer without a cast");
2343 /* XXX: more tests */
2344 break;
2345 case VT_STRUCT:
2346 tmp_type1 = *dt;
2347 tmp_type2 = *st;
2348 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2349 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2350 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2351 error:
2352 type_to_str(buf1, sizeof(buf1), st, NULL);
2353 type_to_str(buf2, sizeof(buf2), dt, NULL);
2354 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2356 break;
2358 type_ok:
2359 gen_cast(dt);
2362 /* store vtop in lvalue pushed on stack */
2363 ST_FUNC void vstore(void)
2365 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2367 ft = vtop[-1].type.t;
2368 sbt = vtop->type.t & VT_BTYPE;
2369 dbt = ft & VT_BTYPE;
2370 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2371 (sbt == VT_INT && dbt == VT_SHORT))
2372 && !(vtop->type.t & VT_BITFIELD)) {
2373 /* optimize char/short casts */
2374 delayed_cast = VT_MUSTCAST;
2375 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2376 /* XXX: factorize */
2377 if (ft & VT_CONSTANT)
2378 tcc_warning("assignment of read-only location");
2379 } else {
2380 delayed_cast = 0;
2381 if (!(ft & VT_BITFIELD))
2382 gen_assign_cast(&vtop[-1].type);
2385 if (sbt == VT_STRUCT) {
2386 /* if structure, only generate pointer */
2387 /* structure assignment : generate memcpy */
2388 /* XXX: optimize if small size */
2389 if (!nocode_wanted) {
2390 size = type_size(&vtop->type, &align);
2392 /* destination */
2393 vswap();
2394 vtop->type.t = VT_PTR;
2395 gaddrof();
2397 /* address of memcpy() */
2398 #ifdef TCC_ARM_EABI
2399 if(!(align & 7))
2400 vpush_global_sym(&func_old_type, TOK_memcpy8);
2401 else if(!(align & 3))
2402 vpush_global_sym(&func_old_type, TOK_memcpy4);
2403 else
2404 #endif
2405 vpush_global_sym(&func_old_type, TOK_memcpy);
2407 vswap();
2408 /* source */
2409 vpushv(vtop - 2);
2410 vtop->type.t = VT_PTR;
2411 gaddrof();
2412 /* type size */
2413 vpushi(size);
2414 gfunc_call(3);
2415 } else {
2416 vswap();
2417 vpop();
2419 /* leave source on stack */
2420 } else if (ft & VT_BITFIELD) {
2421 /* bitfield store handling */
2422 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2423 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2424 /* remove bit field info to avoid loops */
2425 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2427 /* duplicate source into other register */
2428 gv_dup();
2429 vswap();
2430 vrott(3);
2432 if((ft & VT_BTYPE) == VT_BOOL) {
2433 gen_cast(&vtop[-1].type);
2434 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2437 /* duplicate destination */
2438 vdup();
2439 vtop[-1] = vtop[-2];
2441 /* mask and shift source */
2442 if((ft & VT_BTYPE) != VT_BOOL) {
2443 if((ft & VT_BTYPE) == VT_LLONG) {
2444 vpushll((1ULL << bit_size) - 1ULL);
2445 } else {
2446 vpushi((1 << bit_size) - 1);
2448 gen_op('&');
2450 vpushi(bit_pos);
2451 gen_op(TOK_SHL);
2452 /* load destination, mask and or with source */
2453 vswap();
2454 if((ft & VT_BTYPE) == VT_LLONG) {
2455 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2456 } else {
2457 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2459 gen_op('&');
2460 gen_op('|');
2461 /* store result */
2462 vstore();
2464 /* pop off shifted source from "duplicate source..." above */
2465 vpop();
2467 } else {
2468 #ifdef CONFIG_TCC_BCHECK
2469 /* bound check case */
2470 if (vtop[-1].r & VT_MUSTBOUND) {
2471 vswap();
2472 gbound();
2473 vswap();
2475 #endif
2476 if (!nocode_wanted) {
2477 rc = RC_INT;
2478 if (is_float(ft)) {
2479 rc = RC_FLOAT;
2480 #ifdef TCC_TARGET_X86_64
2481 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2482 rc = RC_ST0;
2484 #endif
2486 r = gv(rc); /* generate value */
2487 /* if lvalue was saved on stack, must read it */
2488 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2489 SValue sv;
2490 t = get_reg(RC_INT);
2491 #ifdef TCC_TARGET_X86_64
2492 sv.type.t = VT_PTR;
2493 #else
2494 sv.type.t = VT_INT;
2495 #endif
2496 sv.r = VT_LOCAL | VT_LVAL;
2497 sv.c.ul = vtop[-1].c.ul;
2498 load(t, &sv);
2499 vtop[-1].r = t | VT_LVAL;
2501 store(r, vtop - 1);
2502 #ifndef TCC_TARGET_X86_64
2503 /* two word case handling : store second register at word + 4 */
2504 if ((ft & VT_BTYPE) == VT_LLONG) {
2505 vswap();
2506 /* convert to int to increment easily */
2507 vtop->type.t = VT_INT;
2508 gaddrof();
2509 vpushi(4);
2510 gen_op('+');
2511 vtop->r |= VT_LVAL;
2512 vswap();
2513 /* XXX: it works because r2 is spilled last ! */
2514 store(vtop->r2, vtop - 1);
2516 #endif
2518 vswap();
2519 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2520 vtop->r |= delayed_cast;
2524 /* post defines POST/PRE add. c is the token ++ or -- */
2525 ST_FUNC void inc(int post, int c)
2527 test_lvalue();
2528 vdup(); /* save lvalue */
2529 if (post) {
2530 gv_dup(); /* duplicate value */
2531 vrotb(3);
2532 vrotb(3);
2534 /* add constant */
2535 vpushi(c - TOK_MID);
2536 gen_op('+');
2537 vstore(); /* store value */
2538 if (post)
2539 vpop(); /* if post op, return saved value */
2542 /* Parse GNUC __attribute__ extension. Currently, the following
2543 extensions are recognized:
2544 - aligned(n) : set data/function alignment.
2545 - packed : force data alignment to 1
2546 - section(x) : generate data/code in this section.
2547 - unused : currently ignored, but may be used someday.
2548 - regparm(n) : pass function parameters in registers (i386 only)
2550 static void parse_attribute(AttributeDef *ad)
2552 int t, n;
2554 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2555 next();
2556 skip('(');
2557 skip('(');
2558 while (tok != ')') {
2559 if (tok < TOK_IDENT)
2560 expect("attribute name");
2561 t = tok;
2562 next();
2563 switch(t) {
2564 case TOK_SECTION1:
2565 case TOK_SECTION2:
2566 skip('(');
2567 if (tok != TOK_STR)
2568 expect("section name");
2569 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2570 next();
2571 skip(')');
2572 break;
2573 case TOK_ALIAS1:
2574 case TOK_ALIAS2:
2575 skip('(');
2576 if (tok != TOK_STR)
2577 expect("alias(\"target\")");
2578 ad->alias_target = /* save string as token, for later */
2579 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2580 next();
2581 skip(')');
2582 break;
2583 case TOK_ALIGNED1:
2584 case TOK_ALIGNED2:
2585 if (tok == '(') {
2586 next();
2587 n = expr_const();
2588 if (n <= 0 || (n & (n - 1)) != 0)
2589 tcc_error("alignment must be a positive power of two");
2590 skip(')');
2591 } else {
2592 n = MAX_ALIGN;
2594 ad->aligned = n;
2595 break;
2596 case TOK_PACKED1:
2597 case TOK_PACKED2:
2598 ad->packed = 1;
2599 break;
2600 case TOK_WEAK1:
2601 case TOK_WEAK2:
2602 ad->weak = 1;
2603 break;
2604 case TOK_UNUSED1:
2605 case TOK_UNUSED2:
2606 /* currently, no need to handle it because tcc does not
2607 track unused objects */
2608 break;
2609 case TOK_NORETURN1:
2610 case TOK_NORETURN2:
2611 /* currently, no need to handle it because tcc does not
2612 track unused objects */
2613 break;
2614 case TOK_CDECL1:
2615 case TOK_CDECL2:
2616 case TOK_CDECL3:
2617 ad->func_call = FUNC_CDECL;
2618 break;
2619 case TOK_STDCALL1:
2620 case TOK_STDCALL2:
2621 case TOK_STDCALL3:
2622 ad->func_call = FUNC_STDCALL;
2623 break;
2624 #ifdef TCC_TARGET_I386
2625 case TOK_REGPARM1:
2626 case TOK_REGPARM2:
2627 skip('(');
2628 n = expr_const();
2629 if (n > 3)
2630 n = 3;
2631 else if (n < 0)
2632 n = 0;
2633 if (n > 0)
2634 ad->func_call = FUNC_FASTCALL1 + n - 1;
2635 skip(')');
2636 break;
2637 case TOK_FASTCALL1:
2638 case TOK_FASTCALL2:
2639 case TOK_FASTCALL3:
2640 ad->func_call = FUNC_FASTCALLW;
2641 break;
2642 #endif
2643 case TOK_MODE:
2644 skip('(');
2645 switch(tok) {
2646 case TOK_MODE_DI:
2647 ad->mode = VT_LLONG + 1;
2648 break;
2649 case TOK_MODE_HI:
2650 ad->mode = VT_SHORT + 1;
2651 break;
2652 case TOK_MODE_SI:
2653 ad->mode = VT_INT + 1;
2654 break;
2655 default:
2656 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2657 break;
2659 next();
2660 skip(')');
2661 break;
2662 case TOK_DLLEXPORT:
2663 ad->func_export = 1;
2664 break;
2665 case TOK_DLLIMPORT:
2666 ad->func_import = 1;
2667 break;
2668 default:
2669 if (tcc_state->warn_unsupported)
2670 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2671 /* skip parameters */
2672 if (tok == '(') {
2673 int parenthesis = 0;
2674 do {
2675 if (tok == '(')
2676 parenthesis++;
2677 else if (tok == ')')
2678 parenthesis--;
2679 next();
2680 } while (parenthesis && tok != -1);
2682 break;
2684 if (tok != ',')
2685 break;
2686 next();
2688 skip(')');
2689 skip(')');
2693 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2694 static void struct_decl(CType *type, int u)
2696 int a, v, size, align, maxalign, c, offset;
2697 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2698 Sym *s, *ss, *ass, **ps;
2699 AttributeDef ad;
2700 CType type1, btype;
2702 a = tok; /* save decl type */
2703 next();
2704 if (tok != '{') {
2705 v = tok;
2706 next();
2707 /* struct already defined ? return it */
2708 if (v < TOK_IDENT)
2709 expect("struct/union/enum name");
2710 s = struct_find(v);
2711 if (s) {
2712 if (s->type.t != a)
2713 tcc_error("invalid type");
2714 goto do_decl;
2716 } else {
2717 v = anon_sym++;
2719 type1.t = a;
2720 /* we put an undefined size for struct/union */
2721 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2722 s->r = 0; /* default alignment is zero as gcc */
2723 /* put struct/union/enum name in type */
2724 do_decl:
2725 type->t = u;
2726 type->ref = s;
2728 if (tok == '{') {
2729 next();
2730 if (s->c != -1)
2731 tcc_error("struct/union/enum already defined");
2732 /* cannot be empty */
2733 c = 0;
2734 /* non empty enums are not allowed */
2735 if (a == TOK_ENUM) {
2736 for(;;) {
2737 v = tok;
2738 if (v < TOK_UIDENT)
2739 expect("identifier");
2740 next();
2741 if (tok == '=') {
2742 next();
2743 c = expr_const();
2745 /* enum symbols have static storage */
2746 ss = sym_push(v, &int_type, VT_CONST, c);
2747 ss->type.t |= VT_STATIC;
2748 if (tok != ',')
2749 break;
2750 next();
2751 c++;
2752 /* NOTE: we accept a trailing comma */
2753 if (tok == '}')
2754 break;
2756 skip('}');
2757 } else {
2758 maxalign = 1;
2759 ps = &s->next;
2760 prevbt = VT_INT;
2761 bit_pos = 0;
2762 offset = 0;
2763 while (tok != '}') {
2764 parse_btype(&btype, &ad);
2765 while (1) {
2766 bit_size = -1;
2767 v = 0;
2768 type1 = btype;
2769 if (tok != ':') {
2770 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2771 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2772 expect("identifier");
2773 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2774 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2775 tcc_error("invalid type for '%s'",
2776 get_tok_str(v, NULL));
2778 if (tok == ':') {
2779 next();
2780 bit_size = expr_const();
2781 /* XXX: handle v = 0 case for messages */
2782 if (bit_size < 0)
2783 tcc_error("negative width in bit-field '%s'",
2784 get_tok_str(v, NULL));
2785 if (v && bit_size == 0)
2786 tcc_error("zero width for bit-field '%s'",
2787 get_tok_str(v, NULL));
2789 size = type_size(&type1, &align);
2790 if (ad.aligned) {
2791 if (align < ad.aligned)
2792 align = ad.aligned;
2793 } else if (ad.packed) {
2794 align = 1;
2795 } else if (*tcc_state->pack_stack_ptr) {
2796 if (align > *tcc_state->pack_stack_ptr)
2797 align = *tcc_state->pack_stack_ptr;
2799 lbit_pos = 0;
2800 if (bit_size >= 0) {
2801 bt = type1.t & VT_BTYPE;
2802 if (bt != VT_INT &&
2803 bt != VT_BYTE &&
2804 bt != VT_SHORT &&
2805 bt != VT_BOOL &&
2806 bt != VT_ENUM &&
2807 bt != VT_LLONG)
2808 tcc_error("bitfields must have scalar type");
2809 bsize = size * 8;
2810 if (bit_size > bsize) {
2811 tcc_error("width of '%s' exceeds its type",
2812 get_tok_str(v, NULL));
2813 } else if (bit_size == bsize) {
2814 /* no need for bit fields */
2815 bit_pos = 0;
2816 } else if (bit_size == 0) {
2817 /* XXX: what to do if only padding in a
2818 structure ? */
2819 /* zero size: means to pad */
2820 bit_pos = 0;
2821 } else {
2822 /* we do not have enough room ?
2823 did the type change?
2824 is it a union? */
2825 if ((bit_pos + bit_size) > bsize ||
2826 bt != prevbt || a == TOK_UNION)
2827 bit_pos = 0;
2828 lbit_pos = bit_pos;
2829 /* XXX: handle LSB first */
2830 type1.t |= VT_BITFIELD |
2831 (bit_pos << VT_STRUCT_SHIFT) |
2832 (bit_size << (VT_STRUCT_SHIFT + 6));
2833 bit_pos += bit_size;
2835 prevbt = bt;
2836 } else {
2837 bit_pos = 0;
2839 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2840 /* add new memory data only if starting
2841 bit field */
2842 if (lbit_pos == 0) {
2843 if (a == TOK_STRUCT) {
2844 c = (c + align - 1) & -align;
2845 offset = c;
2846 if (size > 0)
2847 c += size;
2848 } else {
2849 offset = 0;
2850 if (size > c)
2851 c = size;
2853 if (align > maxalign)
2854 maxalign = align;
2856 #if 0
2857 printf("add field %s offset=%d",
2858 get_tok_str(v, NULL), offset);
2859 if (type1.t & VT_BITFIELD) {
2860 printf(" pos=%d size=%d",
2861 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2862 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2864 printf("\n");
2865 #endif
2867 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2868 ass = type1.ref;
2869 while ((ass = ass->next) != NULL) {
2870 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2871 *ps = ss;
2872 ps = &ss->next;
2874 } else if (v) {
2875 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2876 *ps = ss;
2877 ps = &ss->next;
2879 if (tok == ';' || tok == TOK_EOF)
2880 break;
2881 skip(',');
2883 skip(';');
2885 skip('}');
2886 /* store size and alignment */
2887 s->c = (c + maxalign - 1) & -maxalign;
2888 s->r = maxalign;
2893 /* return 0 if no type declaration. otherwise, return the basic type
2894 and skip it.
2896 static int parse_btype(CType *type, AttributeDef *ad)
2898 int t, u, type_found, typespec_found, typedef_found;
2899 Sym *s;
2900 CType type1;
2902 memset(ad, 0, sizeof(AttributeDef));
2903 type_found = 0;
2904 typespec_found = 0;
2905 typedef_found = 0;
2906 t = 0;
2907 while(1) {
2908 switch(tok) {
2909 case TOK_EXTENSION:
2910 /* currently, we really ignore extension */
2911 next();
2912 continue;
2914 /* basic types */
2915 case TOK_CHAR:
2916 u = VT_BYTE;
2917 basic_type:
2918 next();
2919 basic_type1:
2920 if ((t & VT_BTYPE) != 0)
2921 tcc_error("too many basic types");
2922 t |= u;
2923 typespec_found = 1;
2924 break;
2925 case TOK_VOID:
2926 u = VT_VOID;
2927 goto basic_type;
2928 case TOK_SHORT:
2929 u = VT_SHORT;
2930 goto basic_type;
2931 case TOK_INT:
2932 next();
2933 typespec_found = 1;
2934 break;
2935 case TOK_LONG:
2936 next();
2937 if ((t & VT_BTYPE) == VT_DOUBLE) {
2938 #ifndef TCC_TARGET_PE
2939 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2940 #endif
2941 } else if ((t & VT_BTYPE) == VT_LONG) {
2942 t = (t & ~VT_BTYPE) | VT_LLONG;
2943 } else {
2944 u = VT_LONG;
2945 goto basic_type1;
2947 break;
2948 case TOK_BOOL:
2949 u = VT_BOOL;
2950 goto basic_type;
2951 case TOK_FLOAT:
2952 u = VT_FLOAT;
2953 goto basic_type;
2954 case TOK_DOUBLE:
2955 next();
2956 if ((t & VT_BTYPE) == VT_LONG) {
2957 #ifdef TCC_TARGET_PE
2958 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2959 #else
2960 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2961 #endif
2962 } else {
2963 u = VT_DOUBLE;
2964 goto basic_type1;
2966 break;
2967 case TOK_ENUM:
2968 struct_decl(&type1, VT_ENUM);
2969 basic_type2:
2970 u = type1.t;
2971 type->ref = type1.ref;
2972 goto basic_type1;
2973 case TOK_STRUCT:
2974 case TOK_UNION:
2975 struct_decl(&type1, VT_STRUCT);
2976 goto basic_type2;
2978 /* type modifiers */
2979 case TOK_CONST1:
2980 case TOK_CONST2:
2981 case TOK_CONST3:
2982 t |= VT_CONSTANT;
2983 next();
2984 break;
2985 case TOK_VOLATILE1:
2986 case TOK_VOLATILE2:
2987 case TOK_VOLATILE3:
2988 t |= VT_VOLATILE;
2989 next();
2990 break;
2991 case TOK_SIGNED1:
2992 case TOK_SIGNED2:
2993 case TOK_SIGNED3:
2994 typespec_found = 1;
2995 t |= VT_SIGNED;
2996 next();
2997 break;
2998 case TOK_REGISTER:
2999 case TOK_AUTO:
3000 case TOK_RESTRICT1:
3001 case TOK_RESTRICT2:
3002 case TOK_RESTRICT3:
3003 next();
3004 break;
3005 case TOK_UNSIGNED:
3006 t |= VT_UNSIGNED;
3007 next();
3008 typespec_found = 1;
3009 break;
3011 /* storage */
3012 case TOK_EXTERN:
3013 t |= VT_EXTERN;
3014 next();
3015 break;
3016 case TOK_STATIC:
3017 t |= VT_STATIC;
3018 next();
3019 break;
3020 case TOK_TYPEDEF:
3021 t |= VT_TYPEDEF;
3022 next();
3023 break;
3024 case TOK_INLINE1:
3025 case TOK_INLINE2:
3026 case TOK_INLINE3:
3027 t |= VT_INLINE;
3028 next();
3029 break;
3031 /* GNUC attribute */
3032 case TOK_ATTRIBUTE1:
3033 case TOK_ATTRIBUTE2:
3034 parse_attribute(ad);
3035 if (ad->mode) {
3036 u = ad->mode -1;
3037 t = (t & ~VT_BTYPE) | u;
3039 break;
3040 /* GNUC typeof */
3041 case TOK_TYPEOF1:
3042 case TOK_TYPEOF2:
3043 case TOK_TYPEOF3:
3044 next();
3045 parse_expr_type(&type1);
3046 /* remove all storage modifiers except typedef */
3047 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3048 goto basic_type2;
3049 default:
3050 if (typespec_found || typedef_found)
3051 goto the_end;
3052 s = sym_find(tok);
3053 if (!s || !(s->type.t & VT_TYPEDEF))
3054 goto the_end;
3055 typedef_found = 1;
3056 t |= (s->type.t & ~VT_TYPEDEF);
3057 type->ref = s->type.ref;
3058 if (s->r) {
3059 /* get attributes from typedef */
3060 if (0 == ad->aligned)
3061 ad->aligned = FUNC_ALIGN(s->r);
3062 if (0 == ad->func_call)
3063 ad->func_call = FUNC_CALL(s->r);
3064 ad->packed |= FUNC_PACKED(s->r);
3066 next();
3067 typespec_found = 1;
3068 break;
3070 type_found = 1;
3072 the_end:
3073 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3074 tcc_error("signed and unsigned modifier");
3075 if (tcc_state->char_is_unsigned) {
3076 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3077 t |= VT_UNSIGNED;
3079 t &= ~VT_SIGNED;
3081 /* long is never used as type */
3082 if ((t & VT_BTYPE) == VT_LONG)
3083 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3084 t = (t & ~VT_BTYPE) | VT_INT;
3085 #else
3086 t = (t & ~VT_BTYPE) | VT_LLONG;
3087 #endif
3088 type->t = t;
3089 return type_found;
3092 /* convert a function parameter type (array to pointer and function to
3093 function pointer) */
3094 static inline void convert_parameter_type(CType *pt)
3096 /* remove const and volatile qualifiers (XXX: const could be used
3097 to indicate a const function parameter */
3098 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3099 /* array must be transformed to pointer according to ANSI C */
3100 pt->t &= ~VT_ARRAY;
3101 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3102 mk_pointer(pt);
3106 ST_FUNC void parse_asm_str(CString *astr)
3108 skip('(');
3109 /* read the string */
3110 if (tok != TOK_STR)
3111 expect("string constant");
3112 cstr_new(astr);
3113 while (tok == TOK_STR) {
3114 /* XXX: add \0 handling too ? */
3115 cstr_cat(astr, tokc.cstr->data);
3116 next();
3118 cstr_ccat(astr, '\0');
3121 /* Parse an asm label and return the label
3122 * Don't forget to free the CString in the caller! */
3123 static void asm_label_instr(CString *astr)
3125 next();
3126 parse_asm_str(astr);
3127 skip(')');
3128 #ifdef ASM_DEBUG
3129 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3130 #endif
3133 static void post_type(CType *type, AttributeDef *ad)
3135 int n, l, t1, arg_size, align;
3136 Sym **plast, *s, *first;
3137 AttributeDef ad1;
3138 CType pt;
3140 if (tok == '(') {
3141 /* function declaration */
3142 next();
3143 l = 0;
3144 first = NULL;
3145 plast = &first;
3146 arg_size = 0;
3147 if (tok != ')') {
3148 for(;;) {
3149 /* read param name and compute offset */
3150 if (l != FUNC_OLD) {
3151 if (!parse_btype(&pt, &ad1)) {
3152 if (l) {
3153 tcc_error("invalid type");
3154 } else {
3155 l = FUNC_OLD;
3156 goto old_proto;
3159 l = FUNC_NEW;
3160 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3161 break;
3162 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3163 if ((pt.t & VT_BTYPE) == VT_VOID)
3164 tcc_error("parameter declared as void");
3165 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3166 } else {
3167 old_proto:
3168 n = tok;
3169 if (n < TOK_UIDENT)
3170 expect("identifier");
3171 pt.t = VT_INT;
3172 next();
3174 convert_parameter_type(&pt);
3175 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3176 *plast = s;
3177 plast = &s->next;
3178 if (tok == ')')
3179 break;
3180 skip(',');
3181 if (l == FUNC_NEW && tok == TOK_DOTS) {
3182 l = FUNC_ELLIPSIS;
3183 next();
3184 break;
3188 /* if no parameters, then old type prototype */
3189 if (l == 0)
3190 l = FUNC_OLD;
3191 skip(')');
3192 /* NOTE: const is ignored in returned type as it has a special
3193 meaning in gcc / C++ */
3194 type->t &= ~VT_CONSTANT;
3195 /* some ancient pre-K&R C allows a function to return an array
3196 and the array brackets to be put after the arguments, such
3197 that "int c()[]" means something like "int[] c()" */
3198 if (tok == '[') {
3199 next();
3200 skip(']'); /* only handle simple "[]" */
3201 type->t |= VT_PTR;
3203 /* we push a anonymous symbol which will contain the function prototype */
3204 ad->func_args = arg_size;
3205 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3206 s->next = first;
3207 type->t = VT_FUNC;
3208 type->ref = s;
3209 } else if (tok == '[') {
3210 /* array definition */
3211 next();
3212 if (tok == TOK_RESTRICT1)
3213 next();
3214 n = -1;
3215 t1 = 0;
3216 if (tok != ']') {
3217 if (!local_stack || nocode_wanted)
3218 vpushi(expr_const());
3219 else gexpr();
3220 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3221 n = vtop->c.i;
3222 if (n < 0)
3223 tcc_error("invalid array size");
3224 } else {
3225 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3226 tcc_error("size of variable length array should be an integer");
3227 t1 = VT_VLA;
3230 skip(']');
3231 /* parse next post type */
3232 post_type(type, ad);
3233 t1 |= type->t & VT_VLA;
3235 if (t1 & VT_VLA) {
3236 loc -= type_size(&int_type, &align);
3237 loc &= -align;
3238 n = loc;
3240 vla_runtime_type_size(type, &align);
3241 gen_op('*');
3242 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3243 vswap();
3244 vstore();
3246 if (n != -1)
3247 vpop();
3249 /* we push an anonymous symbol which will contain the array
3250 element type */
3251 s = sym_push(SYM_FIELD, type, 0, n);
3252 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3253 type->ref = s;
3257 /* Parse a type declaration (except basic type), and return the type
3258 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3259 expected. 'type' should contain the basic type. 'ad' is the
3260 attribute definition of the basic type. It can be modified by
3261 type_decl().
3263 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3265 Sym *s;
3266 CType type1, *type2;
3267 int qualifiers, storage;
3269 while (tok == '*') {
3270 qualifiers = 0;
3271 redo:
3272 next();
3273 switch(tok) {
3274 case TOK_CONST1:
3275 case TOK_CONST2:
3276 case TOK_CONST3:
3277 qualifiers |= VT_CONSTANT;
3278 goto redo;
3279 case TOK_VOLATILE1:
3280 case TOK_VOLATILE2:
3281 case TOK_VOLATILE3:
3282 qualifiers |= VT_VOLATILE;
3283 goto redo;
3284 case TOK_RESTRICT1:
3285 case TOK_RESTRICT2:
3286 case TOK_RESTRICT3:
3287 goto redo;
3289 mk_pointer(type);
3290 type->t |= qualifiers;
3293 /* XXX: clarify attribute handling */
3294 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3295 parse_attribute(ad);
3297 /* recursive type */
3298 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3299 type1.t = 0; /* XXX: same as int */
3300 if (tok == '(') {
3301 next();
3302 /* XXX: this is not correct to modify 'ad' at this point, but
3303 the syntax is not clear */
3304 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3305 parse_attribute(ad);
3306 type_decl(&type1, ad, v, td);
3307 skip(')');
3308 } else {
3309 /* type identifier */
3310 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3311 *v = tok;
3312 next();
3313 } else {
3314 if (!(td & TYPE_ABSTRACT))
3315 expect("identifier");
3316 *v = 0;
3319 storage = type->t & VT_STORAGE;
3320 type->t &= ~VT_STORAGE;
3321 if (storage & VT_STATIC) {
3322 int saved_nocode_wanted = nocode_wanted;
3323 nocode_wanted = 1;
3324 post_type(type, ad);
3325 nocode_wanted = saved_nocode_wanted;
3326 } else
3327 post_type(type, ad);
3328 type->t |= storage;
3329 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3330 parse_attribute(ad);
3332 if (!type1.t)
3333 return;
3334 /* append type at the end of type1 */
3335 type2 = &type1;
3336 for(;;) {
3337 s = type2->ref;
3338 type2 = &s->type;
3339 if (!type2->t) {
3340 *type2 = *type;
3341 break;
3344 *type = type1;
3347 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3348 ST_FUNC int lvalue_type(int t)
3350 int bt, r;
3351 r = VT_LVAL;
3352 bt = t & VT_BTYPE;
3353 if (bt == VT_BYTE || bt == VT_BOOL)
3354 r |= VT_LVAL_BYTE;
3355 else if (bt == VT_SHORT)
3356 r |= VT_LVAL_SHORT;
3357 else
3358 return r;
3359 if (t & VT_UNSIGNED)
3360 r |= VT_LVAL_UNSIGNED;
3361 return r;
3364 /* indirection with full error checking and bound check */
3365 ST_FUNC void indir(void)
3367 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3368 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3369 return;
3370 expect("pointer");
3372 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3373 gv(RC_INT);
3374 vtop->type = *pointed_type(&vtop->type);
3375 /* Arrays and functions are never lvalues */
3376 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3377 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3378 vtop->r |= lvalue_type(vtop->type.t);
3379 /* if bound checking, the referenced pointer must be checked */
3380 #ifdef CONFIG_TCC_BCHECK
3381 if (tcc_state->do_bounds_check)
3382 vtop->r |= VT_MUSTBOUND;
3383 #endif
3387 /* pass a parameter to a function and do type checking and casting */
3388 static void gfunc_param_typed(Sym *func, Sym *arg)
3390 int func_type;
3391 CType type;
3393 func_type = func->c;
3394 if (func_type == FUNC_OLD ||
3395 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3396 /* default casting : only need to convert float to double */
3397 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3398 type.t = VT_DOUBLE;
3399 gen_cast(&type);
3401 } else if (arg == NULL) {
3402 tcc_error("too many arguments to function");
3403 } else {
3404 type = arg->type;
3405 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3406 gen_assign_cast(&type);
3410 /* parse an expression of the form '(type)' or '(expr)' and return its
3411 type */
3412 static void parse_expr_type(CType *type)
3414 int n;
3415 AttributeDef ad;
3417 skip('(');
3418 if (parse_btype(type, &ad)) {
3419 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3420 } else {
3421 expr_type(type);
3423 skip(')');
3426 static void parse_type(CType *type)
3428 AttributeDef ad;
3429 int n;
3431 if (!parse_btype(type, &ad)) {
3432 expect("type");
3434 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3437 static void vpush_tokc(int t)
3439 CType type;
3440 type.t = t;
3441 type.ref = 0;
3442 vsetc(&type, VT_CONST, &tokc);
3445 ST_FUNC void unary(void)
3447 int n, t, align, size, r, sizeof_caller;
3448 CType type;
3449 Sym *s;
3450 AttributeDef ad;
3451 static int in_sizeof = 0;
3453 sizeof_caller = in_sizeof;
3454 in_sizeof = 0;
3455 /* XXX: GCC 2.95.3 does not generate a table although it should be
3456 better here */
3457 tok_next:
3458 switch(tok) {
3459 case TOK_EXTENSION:
3460 next();
3461 goto tok_next;
3462 case TOK_CINT:
3463 case TOK_CCHAR:
3464 case TOK_LCHAR:
3465 vpushi(tokc.i);
3466 next();
3467 break;
3468 case TOK_CUINT:
3469 vpush_tokc(VT_INT | VT_UNSIGNED);
3470 next();
3471 break;
3472 case TOK_CLLONG:
3473 vpush_tokc(VT_LLONG);
3474 next();
3475 break;
3476 case TOK_CULLONG:
3477 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3478 next();
3479 break;
3480 case TOK_CFLOAT:
3481 vpush_tokc(VT_FLOAT);
3482 next();
3483 break;
3484 case TOK_CDOUBLE:
3485 vpush_tokc(VT_DOUBLE);
3486 next();
3487 break;
3488 case TOK_CLDOUBLE:
3489 vpush_tokc(VT_LDOUBLE);
3490 next();
3491 break;
3492 case TOK___FUNCTION__:
3493 if (!gnu_ext)
3494 goto tok_identifier;
3495 /* fall thru */
3496 case TOK___FUNC__:
3498 void *ptr;
3499 int len;
3500 /* special function name identifier */
3501 len = strlen(funcname) + 1;
3502 /* generate char[len] type */
3503 type.t = VT_BYTE;
3504 mk_pointer(&type);
3505 type.t |= VT_ARRAY;
3506 type.ref->c = len;
3507 vpush_ref(&type, data_section, data_section->data_offset, len);
3508 ptr = section_ptr_add(data_section, len);
3509 memcpy(ptr, funcname, len);
3510 next();
3512 break;
3513 case TOK_LSTR:
3514 #ifdef TCC_TARGET_PE
3515 t = VT_SHORT | VT_UNSIGNED;
3516 #else
3517 t = VT_INT;
3518 #endif
3519 goto str_init;
3520 case TOK_STR:
3521 /* string parsing */
3522 t = VT_BYTE;
3523 str_init:
3524 if (tcc_state->warn_write_strings)
3525 t |= VT_CONSTANT;
3526 type.t = t;
3527 mk_pointer(&type);
3528 type.t |= VT_ARRAY;
3529 memset(&ad, 0, sizeof(AttributeDef));
3530 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3531 break;
3532 case '(':
3533 next();
3534 /* cast ? */
3535 if (parse_btype(&type, &ad)) {
3536 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3537 skip(')');
3538 /* check ISOC99 compound literal */
3539 if (tok == '{') {
3540 /* data is allocated locally by default */
3541 if (global_expr)
3542 r = VT_CONST;
3543 else
3544 r = VT_LOCAL;
3545 /* all except arrays are lvalues */
3546 if (!(type.t & VT_ARRAY))
3547 r |= lvalue_type(type.t);
3548 memset(&ad, 0, sizeof(AttributeDef));
3549 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3550 } else {
3551 if (sizeof_caller) {
3552 vpush(&type);
3553 return;
3555 unary();
3556 gen_cast(&type);
3558 } else if (tok == '{') {
3559 /* save all registers */
3560 save_regs(0);
3561 /* statement expression : we do not accept break/continue
3562 inside as GCC does */
3563 block(NULL, NULL, NULL, NULL, 0, 1);
3564 skip(')');
3565 } else {
3566 gexpr();
3567 skip(')');
3569 break;
3570 case '*':
3571 next();
3572 unary();
3573 indir();
3574 break;
3575 case '&':
3576 next();
3577 unary();
3578 /* functions names must be treated as function pointers,
3579 except for unary '&' and sizeof. Since we consider that
3580 functions are not lvalues, we only have to handle it
3581 there and in function calls. */
3582 /* arrays can also be used although they are not lvalues */
3583 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3584 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3585 test_lvalue();
3586 mk_pointer(&vtop->type);
3587 gaddrof();
3588 break;
3589 case '!':
3590 next();
3591 unary();
3592 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3593 CType boolean;
3594 boolean.t = VT_BOOL;
3595 gen_cast(&boolean);
3596 vtop->c.i = !vtop->c.i;
3597 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3598 vtop->c.i = vtop->c.i ^ 1;
3599 else {
3600 save_regs(1);
3601 vseti(VT_JMP, gtst(1, 0));
3603 break;
3604 case '~':
3605 next();
3606 unary();
3607 vpushi(-1);
3608 gen_op('^');
3609 break;
3610 case '+':
3611 next();
3612 /* in order to force cast, we add zero */
3613 unary();
3614 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3615 tcc_error("pointer not accepted for unary plus");
3616 vpushi(0);
3617 gen_op('+');
3618 break;
3619 case TOK_SIZEOF:
3620 case TOK_ALIGNOF1:
3621 case TOK_ALIGNOF2:
3622 t = tok;
3623 next();
3624 in_sizeof++;
3625 unary_type(&type); // Perform a in_sizeof = 0;
3626 size = type_size(&type, &align);
3627 if (t == TOK_SIZEOF) {
3628 if (!(type.t & VT_VLA)) {
3629 if (size < 0)
3630 tcc_error("sizeof applied to an incomplete type");
3631 vpushs(size);
3632 } else {
3633 vla_runtime_type_size(&type, &align);
3635 } else {
3636 vpushs(align);
3638 vtop->type.t |= VT_UNSIGNED;
3639 break;
3641 case TOK_builtin_types_compatible_p:
3643 CType type1, type2;
3644 next();
3645 skip('(');
3646 parse_type(&type1);
3647 skip(',');
3648 parse_type(&type2);
3649 skip(')');
3650 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3651 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3652 vpushi(is_compatible_types(&type1, &type2));
3654 break;
3655 case TOK_builtin_constant_p:
3657 int saved_nocode_wanted, res;
3658 next();
3659 skip('(');
3660 saved_nocode_wanted = nocode_wanted;
3661 nocode_wanted = 1;
3662 gexpr();
3663 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3664 vpop();
3665 nocode_wanted = saved_nocode_wanted;
3666 skip(')');
3667 vpushi(res);
3669 break;
3670 case TOK_builtin_frame_address:
3672 int level;
3673 CType type;
3674 next();
3675 skip('(');
3676 if (tok != TOK_CINT || tokc.i < 0) {
3677 tcc_error("__builtin_frame_address only takes positive integers");
3679 level = tokc.i;
3680 next();
3681 skip(')');
3682 type.t = VT_VOID;
3683 mk_pointer(&type);
3684 vset(&type, VT_LOCAL, 0); /* local frame */
3685 while (level--) {
3686 mk_pointer(&vtop->type);
3687 indir(); /* -> parent frame */
3690 break;
3691 #ifdef TCC_TARGET_X86_64
3692 case TOK_builtin_va_arg_types:
3694 /* This definition must be synced with stdarg.h */
3695 enum __va_arg_type {
3696 __va_gen_reg, __va_float_reg, __va_stack
3698 CType type;
3699 int bt;
3700 next();
3701 skip('(');
3702 parse_type(&type);
3703 skip(')');
3704 bt = type.t & VT_BTYPE;
3705 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3706 vpushi(__va_stack);
3707 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3708 vpushi(__va_float_reg);
3709 } else {
3710 vpushi(__va_gen_reg);
3713 break;
3714 #endif
3715 case TOK_INC:
3716 case TOK_DEC:
3717 t = tok;
3718 next();
3719 unary();
3720 inc(0, t);
3721 break;
3722 case '-':
3723 next();
3724 vpushi(0);
3725 unary();
3726 gen_op('-');
3727 break;
3728 case TOK_LAND:
3729 if (!gnu_ext)
3730 goto tok_identifier;
3731 next();
3732 /* allow to take the address of a label */
3733 if (tok < TOK_UIDENT)
3734 expect("label identifier");
3735 s = label_find(tok);
3736 if (!s) {
3737 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3738 } else {
3739 if (s->r == LABEL_DECLARED)
3740 s->r = LABEL_FORWARD;
3742 if (!s->type.t) {
3743 s->type.t = VT_VOID;
3744 mk_pointer(&s->type);
3745 s->type.t |= VT_STATIC;
3747 vset(&s->type, VT_CONST | VT_SYM, 0);
3748 vtop->sym = s;
3749 next();
3750 break;
3752 // special qnan , snan and infinity values
3753 case TOK___NAN__:
3754 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3755 next();
3756 break;
3757 case TOK___SNAN__:
3758 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3759 next();
3760 break;
3761 case TOK___INF__:
3762 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3763 next();
3764 break;
3766 default:
3767 tok_identifier:
3768 t = tok;
3769 next();
3770 if (t < TOK_UIDENT)
3771 expect("identifier");
3772 s = sym_find(t);
3773 if (!s) {
3774 if (tok != '(')
3775 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
3776 /* for simple function calls, we tolerate undeclared
3777 external reference to int() function */
3778 if (tcc_state->warn_implicit_function_declaration)
3779 tcc_warning("implicit declaration of function '%s'",
3780 get_tok_str(t, NULL));
3781 s = external_global_sym(t, &func_old_type, 0);
3783 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3784 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3785 /* if referencing an inline function, then we generate a
3786 symbol to it if not already done. It will have the
3787 effect to generate code for it at the end of the
3788 compilation unit. Inline function as always
3789 generated in the text section. */
3790 if (!s->c)
3791 put_extern_sym(s, text_section, 0, 0);
3792 r = VT_SYM | VT_CONST;
3793 } else {
3794 r = s->r;
3796 vset(&s->type, r, s->c);
3797 /* if forward reference, we must point to s */
3798 if (vtop->r & VT_SYM) {
3799 vtop->sym = s;
3800 vtop->c.ul = 0;
3802 break;
3805 /* post operations */
3806 while (1) {
3807 if (tok == TOK_INC || tok == TOK_DEC) {
3808 inc(1, tok);
3809 next();
3810 } else if (tok == '.' || tok == TOK_ARROW) {
3811 int qualifiers;
3812 /* field */
3813 if (tok == TOK_ARROW)
3814 indir();
3815 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3816 test_lvalue();
3817 gaddrof();
3818 next();
3819 /* expect pointer on structure */
3820 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3821 expect("struct or union");
3822 s = vtop->type.ref;
3823 /* find field */
3824 tok |= SYM_FIELD;
3825 while ((s = s->next) != NULL) {
3826 if (s->v == tok)
3827 break;
3829 if (!s)
3830 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3831 /* add field offset to pointer */
3832 vtop->type = char_pointer_type; /* change type to 'char *' */
3833 vpushi(s->c);
3834 gen_op('+');
3835 /* change type to field type, and set to lvalue */
3836 vtop->type = s->type;
3837 vtop->type.t |= qualifiers;
3838 /* an array is never an lvalue */
3839 if (!(vtop->type.t & VT_ARRAY)) {
3840 vtop->r |= lvalue_type(vtop->type.t);
3841 #ifdef CONFIG_TCC_BCHECK
3842 /* if bound checking, the referenced pointer must be checked */
3843 if (tcc_state->do_bounds_check)
3844 vtop->r |= VT_MUSTBOUND;
3845 #endif
3847 next();
3848 } else if (tok == '[') {
3849 next();
3850 gexpr();
3851 gen_op('+');
3852 indir();
3853 skip(']');
3854 } else if (tok == '(') {
3855 SValue ret;
3856 Sym *sa;
3857 int nb_args;
3859 /* function call */
3860 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3861 /* pointer test (no array accepted) */
3862 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3863 vtop->type = *pointed_type(&vtop->type);
3864 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3865 goto error_func;
3866 } else {
3867 error_func:
3868 expect("function pointer");
3870 } else {
3871 vtop->r &= ~VT_LVAL; /* no lvalue */
3873 /* get return type */
3874 s = vtop->type.ref;
3875 next();
3876 sa = s->next; /* first parameter */
3877 nb_args = 0;
3878 ret.r2 = VT_CONST;
3879 /* compute first implicit argument if a structure is returned */
3880 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3881 /* get some space for the returned structure */
3882 size = type_size(&s->type, &align);
3883 loc = (loc - size) & -align;
3884 ret.type = s->type;
3885 ret.r = VT_LOCAL | VT_LVAL;
3886 /* pass it as 'int' to avoid structure arg passing
3887 problems */
3888 vseti(VT_LOCAL, loc);
3889 ret.c = vtop->c;
3890 nb_args++;
3891 } else {
3892 ret.type = s->type;
3893 /* return in register */
3894 if (is_float(ret.type.t)) {
3895 ret.r = reg_fret(ret.type.t);
3896 } else {
3897 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3898 ret.r2 = REG_LRET;
3899 ret.r = REG_IRET;
3901 ret.c.i = 0;
3903 if (tok != ')') {
3904 for(;;) {
3905 expr_eq();
3906 gfunc_param_typed(s, sa);
3907 nb_args++;
3908 if (sa)
3909 sa = sa->next;
3910 if (tok == ')')
3911 break;
3912 skip(',');
3915 if (sa)
3916 tcc_error("too few arguments to function");
3917 skip(')');
3918 if (!nocode_wanted) {
3919 gfunc_call(nb_args);
3920 } else {
3921 vtop -= (nb_args + 1);
3923 /* return value */
3924 vsetc(&ret.type, ret.r, &ret.c);
3925 vtop->r2 = ret.r2;
3926 } else {
3927 break;
3932 ST_FUNC void expr_prod(void)
3934 int t;
3936 unary();
3937 while (tok == '*' || tok == '/' || tok == '%') {
3938 t = tok;
3939 next();
3940 unary();
3941 gen_op(t);
3945 ST_FUNC void expr_sum(void)
3947 int t;
3949 expr_prod();
3950 while (tok == '+' || tok == '-') {
3951 t = tok;
3952 next();
3953 expr_prod();
3954 gen_op(t);
3958 static void expr_shift(void)
3960 int t;
3962 expr_sum();
3963 while (tok == TOK_SHL || tok == TOK_SAR) {
3964 t = tok;
3965 next();
3966 expr_sum();
3967 gen_op(t);
3971 static void expr_cmp(void)
3973 int t;
3975 expr_shift();
3976 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3977 tok == TOK_ULT || tok == TOK_UGE) {
3978 t = tok;
3979 next();
3980 expr_shift();
3981 gen_op(t);
3985 static void expr_cmpeq(void)
3987 int t;
3989 expr_cmp();
3990 while (tok == TOK_EQ || tok == TOK_NE) {
3991 t = tok;
3992 next();
3993 expr_cmp();
3994 gen_op(t);
3998 static void expr_and(void)
4000 expr_cmpeq();
4001 while (tok == '&') {
4002 next();
4003 expr_cmpeq();
4004 gen_op('&');
4008 static void expr_xor(void)
4010 expr_and();
4011 while (tok == '^') {
4012 next();
4013 expr_and();
4014 gen_op('^');
4018 static void expr_or(void)
4020 expr_xor();
4021 while (tok == '|') {
4022 next();
4023 expr_xor();
4024 gen_op('|');
4028 /* XXX: fix this mess */
4029 static void expr_land_const(void)
4031 expr_or();
4032 while (tok == TOK_LAND) {
4033 next();
4034 expr_or();
4035 gen_op(TOK_LAND);
4039 /* XXX: fix this mess */
4040 static void expr_lor_const(void)
4042 expr_land_const();
4043 while (tok == TOK_LOR) {
4044 next();
4045 expr_land_const();
4046 gen_op(TOK_LOR);
4050 /* only used if non constant */
4051 static void expr_land(void)
4053 int t;
4055 expr_or();
4056 if (tok == TOK_LAND) {
4057 t = 0;
4058 save_regs(1);
4059 for(;;) {
4060 t = gtst(1, t);
4061 if (tok != TOK_LAND) {
4062 vseti(VT_JMPI, t);
4063 break;
4065 next();
4066 expr_or();
4071 static void expr_lor(void)
4073 int t;
4075 expr_land();
4076 if (tok == TOK_LOR) {
4077 t = 0;
4078 save_regs(1);
4079 for(;;) {
4080 t = gtst(0, t);
4081 if (tok != TOK_LOR) {
4082 vseti(VT_JMP, t);
4083 break;
4085 next();
4086 expr_land();
4091 /* XXX: better constant handling */
4092 static void expr_cond(void)
4094 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4095 SValue sv;
4096 CType type, type1, type2;
4098 if (const_wanted) {
4099 expr_lor_const();
4100 if (tok == '?') {
4101 CType boolean;
4102 int c;
4103 boolean.t = VT_BOOL;
4104 vdup();
4105 gen_cast(&boolean);
4106 c = vtop->c.i;
4107 vpop();
4108 next();
4109 if (tok != ':' || !gnu_ext) {
4110 vpop();
4111 gexpr();
4113 if (!c)
4114 vpop();
4115 skip(':');
4116 expr_cond();
4117 if (c)
4118 vpop();
4120 } else {
4121 expr_lor();
4122 if (tok == '?') {
4123 next();
4124 if (vtop != vstack) {
4125 /* needed to avoid having different registers saved in
4126 each branch */
4127 if (is_float(vtop->type.t)) {
4128 rc = RC_FLOAT;
4129 #ifdef TCC_TARGET_X86_64
4130 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4131 rc = RC_ST0;
4133 #endif
4135 else
4136 rc = RC_INT;
4137 gv(rc);
4138 save_regs(1);
4140 if (tok == ':' && gnu_ext) {
4141 gv_dup();
4142 tt = gtst(1, 0);
4143 } else {
4144 tt = gtst(1, 0);
4145 gexpr();
4147 type1 = vtop->type;
4148 sv = *vtop; /* save value to handle it later */
4149 vtop--; /* no vpop so that FP stack is not flushed */
4150 skip(':');
4151 u = gjmp(0);
4152 gsym(tt);
4153 expr_cond();
4154 type2 = vtop->type;
4156 t1 = type1.t;
4157 bt1 = t1 & VT_BTYPE;
4158 t2 = type2.t;
4159 bt2 = t2 & VT_BTYPE;
4160 /* cast operands to correct type according to ISOC rules */
4161 if (is_float(bt1) || is_float(bt2)) {
4162 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4163 type.t = VT_LDOUBLE;
4164 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4165 type.t = VT_DOUBLE;
4166 } else {
4167 type.t = VT_FLOAT;
4169 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4170 /* cast to biggest op */
4171 type.t = VT_LLONG;
4172 /* convert to unsigned if it does not fit in a long long */
4173 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4174 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4175 type.t |= VT_UNSIGNED;
4176 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4177 /* If one is a null ptr constant the result type
4178 is the other. */
4179 if (is_null_pointer (vtop))
4180 type = type1;
4181 else if (is_null_pointer (&sv))
4182 type = type2;
4183 /* XXX: test pointer compatibility, C99 has more elaborate
4184 rules here. */
4185 else
4186 type = type1;
4187 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4188 /* XXX: test function pointer compatibility */
4189 type = bt1 == VT_FUNC ? type1 : type2;
4190 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4191 /* XXX: test structure compatibility */
4192 type = bt1 == VT_STRUCT ? type1 : type2;
4193 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4194 /* NOTE: as an extension, we accept void on only one side */
4195 type.t = VT_VOID;
4196 } else {
4197 /* integer operations */
4198 type.t = VT_INT;
4199 /* convert to unsigned if it does not fit in an integer */
4200 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4201 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4202 type.t |= VT_UNSIGNED;
4205 /* now we convert second operand */
4206 gen_cast(&type);
4207 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4208 gaddrof();
4209 rc = RC_INT;
4210 if (is_float(type.t)) {
4211 rc = RC_FLOAT;
4212 #ifdef TCC_TARGET_X86_64
4213 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4214 rc = RC_ST0;
4216 #endif
4217 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4218 /* for long longs, we use fixed registers to avoid having
4219 to handle a complicated move */
4220 rc = RC_IRET;
4223 r2 = gv(rc);
4224 /* this is horrible, but we must also convert first
4225 operand */
4226 tt = gjmp(0);
4227 gsym(u);
4228 /* put again first value and cast it */
4229 *vtop = sv;
4230 gen_cast(&type);
4231 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4232 gaddrof();
4233 r1 = gv(rc);
4234 move_reg(r2, r1);
4235 vtop->r = r2;
4236 gsym(tt);
4241 static void expr_eq(void)
4243 int t;
4245 expr_cond();
4246 if (tok == '=' ||
4247 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4248 tok == TOK_A_XOR || tok == TOK_A_OR ||
4249 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4250 test_lvalue();
4251 t = tok;
4252 next();
4253 if (t == '=') {
4254 expr_eq();
4255 } else {
4256 vdup();
4257 expr_eq();
4258 gen_op(t & 0x7f);
4260 vstore();
4264 ST_FUNC void gexpr(void)
4266 while (1) {
4267 expr_eq();
4268 if (tok != ',')
4269 break;
4270 vpop();
4271 next();
4275 /* parse an expression and return its type without any side effect. */
4276 static void expr_type(CType *type)
4278 int saved_nocode_wanted;
4280 saved_nocode_wanted = nocode_wanted;
4281 nocode_wanted = 1;
4282 gexpr();
4283 *type = vtop->type;
4284 vpop();
4285 nocode_wanted = saved_nocode_wanted;
4288 /* parse a unary expression and return its type without any side
4289 effect. */
4290 static void unary_type(CType *type)
4292 int a;
4294 a = nocode_wanted;
4295 nocode_wanted = 1;
4296 unary();
4297 *type = vtop->type;
4298 vpop();
4299 nocode_wanted = a;
4302 /* parse a constant expression and return value in vtop. */
4303 static void expr_const1(void)
4305 int a;
4306 a = const_wanted;
4307 const_wanted = 1;
4308 expr_cond();
4309 const_wanted = a;
4312 /* parse an integer constant and return its value. */
4313 ST_FUNC int expr_const(void)
4315 int c;
4316 expr_const1();
4317 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4318 expect("constant expression");
4319 c = vtop->c.i;
4320 vpop();
4321 return c;
4324 /* return the label token if current token is a label, otherwise
4325 return zero */
4326 static int is_label(void)
4328 int last_tok;
4330 /* fast test first */
4331 if (tok < TOK_UIDENT)
4332 return 0;
4333 /* no need to save tokc because tok is an identifier */
4334 last_tok = tok;
4335 next();
4336 if (tok == ':') {
4337 next();
4338 return last_tok;
4339 } else {
4340 unget_tok(last_tok);
4341 return 0;
4345 static void label_or_decl(int l)
4347 int last_tok;
4349 /* fast test first */
4350 if (tok >= TOK_UIDENT)
4352 /* no need to save tokc because tok is an identifier */
4353 last_tok = tok;
4354 next();
4355 if (tok == ':') {
4356 unget_tok(last_tok);
4357 return;
4359 unget_tok(last_tok);
4361 decl(l);
4364 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4365 int case_reg, int is_expr)
4367 int a, b, c, d;
4368 Sym *s, *frame_bottom;
4370 /* generate line number info */
4371 if (tcc_state->do_debug &&
4372 (last_line_num != file->line_num || last_ind != ind)) {
4373 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4374 last_ind = ind;
4375 last_line_num = file->line_num;
4378 if (is_expr) {
4379 /* default return value is (void) */
4380 vpushi(0);
4381 vtop->type.t = VT_VOID;
4384 if (tok == TOK_IF) {
4385 /* if test */
4386 next();
4387 skip('(');
4388 gexpr();
4389 skip(')');
4390 a = gtst(1, 0);
4391 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4392 c = tok;
4393 if (c == TOK_ELSE) {
4394 next();
4395 d = gjmp(0);
4396 gsym(a);
4397 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4398 gsym(d); /* patch else jmp */
4399 } else
4400 gsym(a);
4401 } else if (tok == TOK_WHILE) {
4402 next();
4403 d = ind;
4404 skip('(');
4405 gexpr();
4406 skip(')');
4407 a = gtst(1, 0);
4408 b = 0;
4409 block(&a, &b, case_sym, def_sym, case_reg, 0);
4410 gjmp_addr(d);
4411 gsym(a);
4412 gsym_addr(b, d);
4413 } else if (tok == '{') {
4414 Sym *llabel;
4416 next();
4417 /* record local declaration stack position */
4418 s = local_stack;
4419 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4420 frame_bottom->next = scope_stack_bottom;
4421 scope_stack_bottom = frame_bottom;
4422 llabel = local_label_stack;
4423 /* handle local labels declarations */
4424 if (tok == TOK_LABEL) {
4425 next();
4426 for(;;) {
4427 if (tok < TOK_UIDENT)
4428 expect("label identifier");
4429 label_push(&local_label_stack, tok, LABEL_DECLARED);
4430 next();
4431 if (tok == ',') {
4432 next();
4433 } else {
4434 skip(';');
4435 break;
4439 while (tok != '}') {
4440 label_or_decl(VT_LOCAL);
4441 if (tok != '}') {
4442 if (is_expr)
4443 vpop();
4444 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4447 /* pop locally defined labels */
4448 label_pop(&local_label_stack, llabel);
4449 if(is_expr) {
4450 /* XXX: this solution makes only valgrind happy...
4451 triggered by gcc.c-torture/execute/20000917-1.c */
4452 Sym *p;
4453 switch(vtop->type.t & VT_BTYPE) {
4454 case VT_PTR:
4455 case VT_STRUCT:
4456 case VT_ENUM:
4457 case VT_FUNC:
4458 for(p=vtop->type.ref;p;p=p->prev)
4459 if(p->prev==s)
4460 tcc_error("unsupported expression type");
4463 /* pop locally defined symbols */
4464 scope_stack_bottom = scope_stack_bottom->next;
4465 sym_pop(&local_stack, s);
4466 next();
4467 } else if (tok == TOK_RETURN) {
4468 next();
4469 if (tok != ';') {
4470 gexpr();
4471 gen_assign_cast(&func_vt);
4472 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4473 CType type;
4474 /* if returning structure, must copy it to implicit
4475 first pointer arg location */
4476 #ifdef TCC_ARM_EABI
4477 int align, size;
4478 size = type_size(&func_vt,&align);
4479 if(size <= 4)
4481 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4482 && (align & 3))
4484 int addr;
4485 loc = (loc - size) & -4;
4486 addr = loc;
4487 type = func_vt;
4488 vset(&type, VT_LOCAL | VT_LVAL, addr);
4489 vswap();
4490 vstore();
4491 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4493 vtop->type = int_type;
4494 gv(RC_IRET);
4495 } else {
4496 #endif
4497 type = func_vt;
4498 mk_pointer(&type);
4499 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4500 indir();
4501 vswap();
4502 /* copy structure value to pointer */
4503 vstore();
4504 #ifdef TCC_ARM_EABI
4506 #endif
4507 } else if (is_float(func_vt.t)) {
4508 gv(rc_fret(func_vt.t));
4509 } else {
4510 gv(RC_IRET);
4512 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4514 skip(';');
4515 rsym = gjmp(rsym); /* jmp */
4516 } else if (tok == TOK_BREAK) {
4517 /* compute jump */
4518 if (!bsym)
4519 tcc_error("cannot break");
4520 *bsym = gjmp(*bsym);
4521 next();
4522 skip(';');
4523 } else if (tok == TOK_CONTINUE) {
4524 /* compute jump */
4525 if (!csym)
4526 tcc_error("cannot continue");
4527 *csym = gjmp(*csym);
4528 next();
4529 skip(';');
4530 } else if (tok == TOK_FOR) {
4531 int e;
4532 next();
4533 skip('(');
4534 s = local_stack;
4535 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4536 frame_bottom->next = scope_stack_bottom;
4537 scope_stack_bottom = frame_bottom;
4538 if (tok != ';') {
4539 /* c99 for-loop init decl? */
4540 if (!decl0(VT_LOCAL, 1)) {
4541 /* no, regular for-loop init expr */
4542 gexpr();
4543 vpop();
4546 skip(';');
4547 d = ind;
4548 c = ind;
4549 a = 0;
4550 b = 0;
4551 if (tok != ';') {
4552 gexpr();
4553 a = gtst(1, 0);
4555 skip(';');
4556 if (tok != ')') {
4557 e = gjmp(0);
4558 c = ind;
4559 gexpr();
4560 vpop();
4561 gjmp_addr(d);
4562 gsym(e);
4564 skip(')');
4565 block(&a, &b, case_sym, def_sym, case_reg, 0);
4566 gjmp_addr(c);
4567 gsym(a);
4568 gsym_addr(b, c);
4569 scope_stack_bottom = scope_stack_bottom->next;
4570 sym_pop(&local_stack, s);
4571 } else
4572 if (tok == TOK_DO) {
4573 next();
4574 a = 0;
4575 b = 0;
4576 d = ind;
4577 block(&a, &b, case_sym, def_sym, case_reg, 0);
4578 skip(TOK_WHILE);
4579 skip('(');
4580 gsym(b);
4581 gexpr();
4582 c = gtst(0, 0);
4583 gsym_addr(c, d);
4584 skip(')');
4585 gsym(a);
4586 skip(';');
4587 } else
4588 if (tok == TOK_SWITCH) {
4589 next();
4590 skip('(');
4591 gexpr();
4592 /* XXX: other types than integer */
4593 case_reg = gv(RC_INT);
4594 vpop();
4595 skip(')');
4596 a = 0;
4597 b = gjmp(0); /* jump to first case */
4598 c = 0;
4599 block(&a, csym, &b, &c, case_reg, 0);
4600 /* if no default, jmp after switch */
4601 if (c == 0)
4602 c = ind;
4603 /* default label */
4604 gsym_addr(b, c);
4605 /* break label */
4606 gsym(a);
4607 } else
4608 if (tok == TOK_CASE) {
4609 int v1, v2;
4610 if (!case_sym)
4611 expect("switch");
4612 next();
4613 v1 = expr_const();
4614 v2 = v1;
4615 if (gnu_ext && tok == TOK_DOTS) {
4616 next();
4617 v2 = expr_const();
4618 if (v2 < v1)
4619 tcc_warning("empty case range");
4621 /* since a case is like a label, we must skip it with a jmp */
4622 b = gjmp(0);
4623 gsym(*case_sym);
4624 vseti(case_reg, 0);
4625 vpushi(v1);
4626 if (v1 == v2) {
4627 gen_op(TOK_EQ);
4628 *case_sym = gtst(1, 0);
4629 } else {
4630 gen_op(TOK_GE);
4631 *case_sym = gtst(1, 0);
4632 vseti(case_reg, 0);
4633 vpushi(v2);
4634 gen_op(TOK_LE);
4635 *case_sym = gtst(1, *case_sym);
4637 gsym(b);
4638 skip(':');
4639 is_expr = 0;
4640 goto block_after_label;
4641 } else
4642 if (tok == TOK_DEFAULT) {
4643 next();
4644 skip(':');
4645 if (!def_sym)
4646 expect("switch");
4647 if (*def_sym)
4648 tcc_error("too many 'default'");
4649 *def_sym = ind;
4650 is_expr = 0;
4651 goto block_after_label;
4652 } else
4653 if (tok == TOK_GOTO) {
4654 next();
4655 if (tok == '*' && gnu_ext) {
4656 /* computed goto */
4657 next();
4658 gexpr();
4659 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4660 expect("pointer");
4661 ggoto();
4662 } else if (tok >= TOK_UIDENT) {
4663 s = label_find(tok);
4664 /* put forward definition if needed */
4665 if (!s) {
4666 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4667 } else {
4668 if (s->r == LABEL_DECLARED)
4669 s->r = LABEL_FORWARD;
4671 /* label already defined */
4672 if (s->r & LABEL_FORWARD)
4673 s->jnext = gjmp(s->jnext);
4674 else
4675 gjmp_addr(s->jnext);
4676 next();
4677 } else {
4678 expect("label identifier");
4680 skip(';');
4681 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4682 asm_instr();
4683 } else {
4684 b = is_label();
4685 if (b) {
4686 /* label case */
4687 s = label_find(b);
4688 if (s) {
4689 if (s->r == LABEL_DEFINED)
4690 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4691 gsym(s->jnext);
4692 s->r = LABEL_DEFINED;
4693 } else {
4694 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4696 s->jnext = ind;
4697 /* we accept this, but it is a mistake */
4698 block_after_label:
4699 if (tok == '}') {
4700 tcc_warning("deprecated use of label at end of compound statement");
4701 } else {
4702 if (is_expr)
4703 vpop();
4704 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4706 } else {
4707 /* expression case */
4708 if (tok != ';') {
4709 if (is_expr) {
4710 vpop();
4711 gexpr();
4712 } else {
4713 gexpr();
4714 vpop();
4717 skip(';');
4722 /* t is the array or struct type. c is the array or struct
4723 address. cur_index/cur_field is the pointer to the current
4724 value. 'size_only' is true if only size info is needed (only used
4725 in arrays) */
4726 static void decl_designator(CType *type, Section *sec, unsigned long c,
4727 int *cur_index, Sym **cur_field,
4728 int size_only)
4730 Sym *s, *f;
4731 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4732 CType type1;
4734 notfirst = 0;
4735 elem_size = 0;
4736 nb_elems = 1;
4737 if (gnu_ext && (l = is_label()) != 0)
4738 goto struct_field;
4739 while (tok == '[' || tok == '.') {
4740 if (tok == '[') {
4741 if (!(type->t & VT_ARRAY))
4742 expect("array type");
4743 s = type->ref;
4744 next();
4745 index = expr_const();
4746 if (index < 0 || (s->c >= 0 && index >= s->c))
4747 expect("invalid index");
4748 if (tok == TOK_DOTS && gnu_ext) {
4749 next();
4750 index_last = expr_const();
4751 if (index_last < 0 ||
4752 (s->c >= 0 && index_last >= s->c) ||
4753 index_last < index)
4754 expect("invalid index");
4755 } else {
4756 index_last = index;
4758 skip(']');
4759 if (!notfirst)
4760 *cur_index = index_last;
4761 type = pointed_type(type);
4762 elem_size = type_size(type, &align);
4763 c += index * elem_size;
4764 /* NOTE: we only support ranges for last designator */
4765 nb_elems = index_last - index + 1;
4766 if (nb_elems != 1) {
4767 notfirst = 1;
4768 break;
4770 } else {
4771 next();
4772 l = tok;
4773 next();
4774 struct_field:
4775 if ((type->t & VT_BTYPE) != VT_STRUCT)
4776 expect("struct/union type");
4777 s = type->ref;
4778 l |= SYM_FIELD;
4779 f = s->next;
4780 while (f) {
4781 if (f->v == l)
4782 break;
4783 f = f->next;
4785 if (!f)
4786 expect("field");
4787 if (!notfirst)
4788 *cur_field = f;
4789 /* XXX: fix this mess by using explicit storage field */
4790 type1 = f->type;
4791 type1.t |= (type->t & ~VT_TYPE);
4792 type = &type1;
4793 c += f->c;
4795 notfirst = 1;
4797 if (notfirst) {
4798 if (tok == '=') {
4799 next();
4800 } else {
4801 if (!gnu_ext)
4802 expect("=");
4804 } else {
4805 if (type->t & VT_ARRAY) {
4806 index = *cur_index;
4807 type = pointed_type(type);
4808 c += index * type_size(type, &align);
4809 } else {
4810 f = *cur_field;
4811 if (!f)
4812 tcc_error("too many field init");
4813 /* XXX: fix this mess by using explicit storage field */
4814 type1 = f->type;
4815 type1.t |= (type->t & ~VT_TYPE);
4816 type = &type1;
4817 c += f->c;
4820 decl_initializer(type, sec, c, 0, size_only);
4822 /* XXX: make it more general */
4823 if (!size_only && nb_elems > 1) {
4824 unsigned long c_end;
4825 uint8_t *src, *dst;
4826 int i;
4828 if (!sec)
4829 tcc_error("range init not supported yet for dynamic storage");
4830 c_end = c + nb_elems * elem_size;
4831 if (c_end > sec->data_allocated)
4832 section_realloc(sec, c_end);
4833 src = sec->data + c;
4834 dst = src;
4835 for(i = 1; i < nb_elems; i++) {
4836 dst += elem_size;
4837 memcpy(dst, src, elem_size);
4842 #define EXPR_VAL 0
4843 #define EXPR_CONST 1
4844 #define EXPR_ANY 2
4846 /* store a value or an expression directly in global data or in local array */
4847 static void init_putv(CType *type, Section *sec, unsigned long c,
4848 int v, int expr_type)
4850 int saved_global_expr, bt, bit_pos, bit_size;
4851 void *ptr;
4852 unsigned long long bit_mask;
4853 CType dtype;
4855 switch(expr_type) {
4856 case EXPR_VAL:
4857 vpushi(v);
4858 break;
4859 case EXPR_CONST:
4860 /* compound literals must be allocated globally in this case */
4861 saved_global_expr = global_expr;
4862 global_expr = 1;
4863 expr_const1();
4864 global_expr = saved_global_expr;
4865 /* NOTE: symbols are accepted */
4866 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4867 tcc_error("initializer element is not constant");
4868 break;
4869 case EXPR_ANY:
4870 expr_eq();
4871 break;
4874 dtype = *type;
4875 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4877 if (sec) {
4878 /* XXX: not portable */
4879 /* XXX: generate error if incorrect relocation */
4880 gen_assign_cast(&dtype);
4881 bt = type->t & VT_BTYPE;
4882 /* we'll write at most 12 bytes */
4883 if (c + 12 > sec->data_allocated) {
4884 section_realloc(sec, c + 12);
4886 ptr = sec->data + c;
4887 /* XXX: make code faster ? */
4888 if (!(type->t & VT_BITFIELD)) {
4889 bit_pos = 0;
4890 bit_size = 32;
4891 bit_mask = -1LL;
4892 } else {
4893 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4894 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4895 bit_mask = (1LL << bit_size) - 1;
4897 if ((vtop->r & VT_SYM) &&
4898 (bt == VT_BYTE ||
4899 bt == VT_SHORT ||
4900 bt == VT_DOUBLE ||
4901 bt == VT_LDOUBLE ||
4902 bt == VT_LLONG ||
4903 (bt == VT_INT && bit_size != 32)))
4904 tcc_error("initializer element is not computable at load time");
4905 switch(bt) {
4906 case VT_BOOL:
4907 vtop->c.i = (vtop->c.i != 0);
4908 case VT_BYTE:
4909 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4910 break;
4911 case VT_SHORT:
4912 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4913 break;
4914 case VT_DOUBLE:
4915 *(double *)ptr = vtop->c.d;
4916 break;
4917 case VT_LDOUBLE:
4918 *(long double *)ptr = vtop->c.ld;
4919 break;
4920 case VT_LLONG:
4921 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4922 break;
4923 default:
4924 if (vtop->r & VT_SYM) {
4925 greloc(sec, vtop->sym, c, R_DATA_PTR);
4927 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4928 break;
4930 vtop--;
4931 } else {
4932 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4933 vswap();
4934 vstore();
4935 vpop();
4939 /* put zeros for variable based init */
4940 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4942 if (sec) {
4943 /* nothing to do because globals are already set to zero */
4944 } else {
4945 vpush_global_sym(&func_old_type, TOK_memset);
4946 vseti(VT_LOCAL, c);
4947 vpushi(0);
4948 vpushi(size);
4949 gfunc_call(3);
4953 /* 't' contains the type and storage info. 'c' is the offset of the
4954 object in section 'sec'. If 'sec' is NULL, it means stack based
4955 allocation. 'first' is true if array '{' must be read (multi
4956 dimension implicit array init handling). 'size_only' is true if
4957 size only evaluation is wanted (only for arrays). */
4958 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4959 int first, int size_only)
4961 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
4962 int size1, align1, expr_type;
4963 Sym *s, *f;
4964 CType *t1;
4966 if (type->t & VT_VLA) {
4967 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
4968 int a;
4969 CValue retcval;
4971 vpush_global_sym(&func_old_type, TOK_alloca);
4972 vla_runtime_type_size(type, &a);
4973 gfunc_call(1);
4975 /* return value */
4976 retcval.i = 0;
4977 vsetc(type, REG_IRET, &retcval);
4978 vset(type, VT_LOCAL|VT_LVAL, c);
4979 vswap();
4980 vstore();
4981 vpop();
4982 #else
4983 tcc_error("variable length arrays unsupported for this target");
4984 #endif
4985 } else if (type->t & VT_ARRAY) {
4986 s = type->ref;
4987 n = s->c;
4988 array_length = 0;
4989 t1 = pointed_type(type);
4990 size1 = type_size(t1, &align1);
4992 no_oblock = 1;
4993 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4994 tok == '{') {
4995 if (tok != '{')
4996 tcc_error("character array initializer must be a literal,"
4997 " optionally enclosed in braces");
4998 skip('{');
4999 no_oblock = 0;
5002 /* only parse strings here if correct type (otherwise: handle
5003 them as ((w)char *) expressions */
5004 if ((tok == TOK_LSTR &&
5005 #ifdef TCC_TARGET_PE
5006 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5007 #else
5008 (t1->t & VT_BTYPE) == VT_INT
5009 #endif
5010 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5011 while (tok == TOK_STR || tok == TOK_LSTR) {
5012 int cstr_len, ch;
5013 CString *cstr;
5015 cstr = tokc.cstr;
5016 /* compute maximum number of chars wanted */
5017 if (tok == TOK_STR)
5018 cstr_len = cstr->size;
5019 else
5020 cstr_len = cstr->size / sizeof(nwchar_t);
5021 cstr_len--;
5022 nb = cstr_len;
5023 if (n >= 0 && nb > (n - array_length))
5024 nb = n - array_length;
5025 if (!size_only) {
5026 if (cstr_len > nb)
5027 tcc_warning("initializer-string for array is too long");
5028 /* in order to go faster for common case (char
5029 string in global variable, we handle it
5030 specifically */
5031 if (sec && tok == TOK_STR && size1 == 1) {
5032 memcpy(sec->data + c + array_length, cstr->data, nb);
5033 } else {
5034 for(i=0;i<nb;i++) {
5035 if (tok == TOK_STR)
5036 ch = ((unsigned char *)cstr->data)[i];
5037 else
5038 ch = ((nwchar_t *)cstr->data)[i];
5039 init_putv(t1, sec, c + (array_length + i) * size1,
5040 ch, EXPR_VAL);
5044 array_length += nb;
5045 next();
5047 /* only add trailing zero if enough storage (no
5048 warning in this case since it is standard) */
5049 if (n < 0 || array_length < n) {
5050 if (!size_only) {
5051 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5053 array_length++;
5055 } else {
5056 index = 0;
5057 while (tok != '}') {
5058 decl_designator(type, sec, c, &index, NULL, size_only);
5059 if (n >= 0 && index >= n)
5060 tcc_error("index too large");
5061 /* must put zero in holes (note that doing it that way
5062 ensures that it even works with designators) */
5063 if (!size_only && array_length < index) {
5064 init_putz(t1, sec, c + array_length * size1,
5065 (index - array_length) * size1);
5067 index++;
5068 if (index > array_length)
5069 array_length = index;
5070 /* special test for multi dimensional arrays (may not
5071 be strictly correct if designators are used at the
5072 same time) */
5073 if (index >= n && no_oblock)
5074 break;
5075 if (tok == '}')
5076 break;
5077 skip(',');
5080 if (!no_oblock)
5081 skip('}');
5082 /* put zeros at the end */
5083 if (!size_only && n >= 0 && array_length < n) {
5084 init_putz(t1, sec, c + array_length * size1,
5085 (n - array_length) * size1);
5087 /* patch type size if needed */
5088 if (n < 0)
5089 s->c = array_length;
5090 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5091 (sec || !first || tok == '{')) {
5092 int par_count;
5094 /* NOTE: the previous test is a specific case for automatic
5095 struct/union init */
5096 /* XXX: union needs only one init */
5098 /* XXX: this test is incorrect for local initializers
5099 beginning with ( without {. It would be much more difficult
5100 to do it correctly (ideally, the expression parser should
5101 be used in all cases) */
5102 par_count = 0;
5103 if (tok == '(') {
5104 AttributeDef ad1;
5105 CType type1;
5106 next();
5107 while (tok == '(') {
5108 par_count++;
5109 next();
5111 if (!parse_btype(&type1, &ad1))
5112 expect("cast");
5113 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5114 #if 0
5115 if (!is_assignable_types(type, &type1))
5116 tcc_error("invalid type for cast");
5117 #endif
5118 skip(')');
5120 no_oblock = 1;
5121 if (first || tok == '{') {
5122 skip('{');
5123 no_oblock = 0;
5125 s = type->ref;
5126 f = s->next;
5127 array_length = 0;
5128 index = 0;
5129 n = s->c;
5130 while (tok != '}') {
5131 decl_designator(type, sec, c, NULL, &f, size_only);
5132 index = f->c;
5133 if (!size_only && array_length < index) {
5134 init_putz(type, sec, c + array_length,
5135 index - array_length);
5137 index = index + type_size(&f->type, &align1);
5138 if (index > array_length)
5139 array_length = index;
5141 /* gr: skip fields from same union - ugly. */
5142 while (f->next) {
5143 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5144 /* test for same offset */
5145 if (f->next->c != f->c)
5146 break;
5147 /* if yes, test for bitfield shift */
5148 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5149 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5150 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5151 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5152 if (bit_pos_1 != bit_pos_2)
5153 break;
5155 f = f->next;
5158 f = f->next;
5159 if (no_oblock && f == NULL)
5160 break;
5161 if (tok == '}')
5162 break;
5163 skip(',');
5165 /* put zeros at the end */
5166 if (!size_only && array_length < n) {
5167 init_putz(type, sec, c + array_length,
5168 n - array_length);
5170 if (!no_oblock)
5171 skip('}');
5172 while (par_count) {
5173 skip(')');
5174 par_count--;
5176 } else if (tok == '{') {
5177 next();
5178 decl_initializer(type, sec, c, first, size_only);
5179 skip('}');
5180 } else if (size_only) {
5181 /* just skip expression */
5182 parlevel = parlevel1 = 0;
5183 while ((parlevel > 0 || parlevel1 > 0 ||
5184 (tok != '}' && tok != ',')) && tok != -1) {
5185 if (tok == '(')
5186 parlevel++;
5187 else if (tok == ')')
5188 parlevel--;
5189 else if (tok == '{')
5190 parlevel1++;
5191 else if (tok == '}')
5192 parlevel1--;
5193 next();
5195 } else {
5196 /* currently, we always use constant expression for globals
5197 (may change for scripting case) */
5198 expr_type = EXPR_CONST;
5199 if (!sec)
5200 expr_type = EXPR_ANY;
5201 init_putv(type, sec, c, 0, expr_type);
5205 /* parse an initializer for type 't' if 'has_init' is non zero, and
5206 allocate space in local or global data space ('r' is either
5207 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5208 variable 'v' with an associated name represented by 'asm_label' of
5209 scope 'scope' is declared before initializers are parsed. If 'v' is
5210 zero, then a reference to the new object is put in the value stack.
5211 If 'has_init' is 2, a special parsing is done to handle string
5212 constants. */
5213 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5214 int has_init, int v, char *asm_label,
5215 int scope)
5217 int size, align, addr, data_offset;
5218 int level;
5219 ParseState saved_parse_state = {0};
5220 TokenString init_str;
5221 Section *sec;
5222 Sym *flexible_array;
5224 flexible_array = NULL;
5225 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5226 Sym *field;
5227 field = type->ref;
5228 while (field && field->next)
5229 field = field->next;
5230 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5231 flexible_array = field;
5234 size = type_size(type, &align);
5235 /* If unknown size, we must evaluate it before
5236 evaluating initializers because
5237 initializers can generate global data too
5238 (e.g. string pointers or ISOC99 compound
5239 literals). It also simplifies local
5240 initializers handling */
5241 tok_str_new(&init_str);
5242 if (size < 0 || (flexible_array && has_init)) {
5243 if (!has_init)
5244 tcc_error("unknown type size");
5245 /* get all init string */
5246 if (has_init == 2) {
5247 /* only get strings */
5248 while (tok == TOK_STR || tok == TOK_LSTR) {
5249 tok_str_add_tok(&init_str);
5250 next();
5252 } else {
5253 level = 0;
5254 while (level > 0 || (tok != ',' && tok != ';')) {
5255 if (tok < 0)
5256 tcc_error("unexpected end of file in initializer");
5257 tok_str_add_tok(&init_str);
5258 if (tok == '{')
5259 level++;
5260 else if (tok == '}') {
5261 level--;
5262 if (level <= 0) {
5263 next();
5264 break;
5267 next();
5270 tok_str_add(&init_str, -1);
5271 tok_str_add(&init_str, 0);
5273 /* compute size */
5274 save_parse_state(&saved_parse_state);
5276 macro_ptr = init_str.str;
5277 next();
5278 decl_initializer(type, NULL, 0, 1, 1);
5279 /* prepare second initializer parsing */
5280 macro_ptr = init_str.str;
5281 next();
5283 /* if still unknown size, error */
5284 size = type_size(type, &align);
5285 if (size < 0)
5286 tcc_error("unknown type size");
5288 if (flexible_array)
5289 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5290 /* take into account specified alignment if bigger */
5291 if (ad->aligned) {
5292 if (ad->aligned > align)
5293 align = ad->aligned;
5294 } else if (ad->packed) {
5295 align = 1;
5297 if ((r & VT_VALMASK) == VT_LOCAL) {
5298 sec = NULL;
5299 #ifdef CONFIG_TCC_BCHECK
5300 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5301 loc--;
5303 #endif
5304 loc = (loc - size) & -align;
5305 addr = loc;
5306 #ifdef CONFIG_TCC_BCHECK
5307 /* handles bounds */
5308 /* XXX: currently, since we do only one pass, we cannot track
5309 '&' operators, so we add only arrays */
5310 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5311 unsigned long *bounds_ptr;
5312 /* add padding between regions */
5313 loc--;
5314 /* then add local bound info */
5315 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5316 bounds_ptr[0] = addr;
5317 bounds_ptr[1] = size;
5319 #endif
5320 if (v) {
5321 /* local variable */
5322 sym_push(v, type, r, addr);
5323 } else {
5324 /* push local reference */
5325 vset(type, r, addr);
5327 } else {
5328 Sym *sym;
5330 sym = NULL;
5331 if (v && scope == VT_CONST) {
5332 /* see if the symbol was already defined */
5333 sym = sym_find(v);
5334 if (sym) {
5335 if (!is_compatible_types(&sym->type, type))
5336 tcc_error("incompatible types for redefinition of '%s'",
5337 get_tok_str(v, NULL));
5338 if (sym->type.t & VT_EXTERN) {
5339 /* if the variable is extern, it was not allocated */
5340 sym->type.t &= ~VT_EXTERN;
5341 /* set array size if it was ommited in extern
5342 declaration */
5343 if ((sym->type.t & VT_ARRAY) &&
5344 sym->type.ref->c < 0 &&
5345 type->ref->c >= 0)
5346 sym->type.ref->c = type->ref->c;
5347 } else {
5348 /* we accept several definitions of the same
5349 global variable. this is tricky, because we
5350 must play with the SHN_COMMON type of the symbol */
5351 /* XXX: should check if the variable was already
5352 initialized. It is incorrect to initialized it
5353 twice */
5354 /* no init data, we won't add more to the symbol */
5355 if (!has_init)
5356 goto no_alloc;
5361 /* allocate symbol in corresponding section */
5362 sec = ad->section;
5363 if (!sec) {
5364 if (has_init)
5365 sec = data_section;
5366 else if (tcc_state->nocommon)
5367 sec = bss_section;
5369 if (sec) {
5370 data_offset = sec->data_offset;
5371 data_offset = (data_offset + align - 1) & -align;
5372 addr = data_offset;
5373 /* very important to increment global pointer at this time
5374 because initializers themselves can create new initializers */
5375 data_offset += size;
5376 #ifdef CONFIG_TCC_BCHECK
5377 /* add padding if bound check */
5378 if (tcc_state->do_bounds_check)
5379 data_offset++;
5380 #endif
5381 sec->data_offset = data_offset;
5382 /* allocate section space to put the data */
5383 if (sec->sh_type != SHT_NOBITS &&
5384 data_offset > sec->data_allocated)
5385 section_realloc(sec, data_offset);
5386 /* align section if needed */
5387 if (align > sec->sh_addralign)
5388 sec->sh_addralign = align;
5389 } else {
5390 addr = 0; /* avoid warning */
5393 if (v) {
5394 if (scope != VT_CONST || !sym) {
5395 sym = sym_push(v, type, r | VT_SYM, 0);
5396 sym->asm_label = asm_label;
5398 /* update symbol definition */
5399 if (sec) {
5400 put_extern_sym(sym, sec, addr, size);
5401 } else {
5402 ElfW(Sym) *esym;
5403 /* put a common area */
5404 put_extern_sym(sym, NULL, align, size);
5405 /* XXX: find a nicer way */
5406 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5407 esym->st_shndx = SHN_COMMON;
5409 } else {
5410 CValue cval;
5412 /* push global reference */
5413 sym = get_sym_ref(type, sec, addr, size);
5414 cval.ul = 0;
5415 vsetc(type, VT_CONST | VT_SYM, &cval);
5416 vtop->sym = sym;
5418 /* patch symbol weakness */
5419 if (type->t & VT_WEAK)
5420 weaken_symbol(sym);
5421 #ifdef CONFIG_TCC_BCHECK
5422 /* handles bounds now because the symbol must be defined
5423 before for the relocation */
5424 if (tcc_state->do_bounds_check) {
5425 unsigned long *bounds_ptr;
5427 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5428 /* then add global bound info */
5429 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5430 bounds_ptr[0] = 0; /* relocated */
5431 bounds_ptr[1] = size;
5433 #endif
5435 if (has_init || (type->t & VT_VLA)) {
5436 decl_initializer(type, sec, addr, 1, 0);
5437 /* restore parse state if needed */
5438 if (init_str.str) {
5439 tok_str_free(init_str.str);
5440 restore_parse_state(&saved_parse_state);
5442 /* patch flexible array member size back to -1, */
5443 /* for possible subsequent similar declarations */
5444 if (flexible_array)
5445 flexible_array->type.ref->c = -1;
5447 no_alloc: ;
5450 static void put_func_debug(Sym *sym)
5452 char buf[512];
5454 /* stabs info */
5455 /* XXX: we put here a dummy type */
5456 snprintf(buf, sizeof(buf), "%s:%c1",
5457 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5458 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5459 cur_text_section, sym->c);
5460 /* //gr gdb wants a line at the function */
5461 put_stabn(N_SLINE, 0, file->line_num, 0);
5462 last_ind = 0;
5463 last_line_num = 0;
5466 /* parse an old style function declaration list */
5467 /* XXX: check multiple parameter */
5468 static void func_decl_list(Sym *func_sym)
5470 AttributeDef ad;
5471 int v;
5472 Sym *s;
5473 CType btype, type;
5475 /* parse each declaration */
5476 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5477 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5478 if (!parse_btype(&btype, &ad))
5479 expect("declaration list");
5480 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5481 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5482 tok == ';') {
5483 /* we accept no variable after */
5484 } else {
5485 for(;;) {
5486 type = btype;
5487 type_decl(&type, &ad, &v, TYPE_DIRECT);
5488 /* find parameter in function parameter list */
5489 s = func_sym->next;
5490 while (s != NULL) {
5491 if ((s->v & ~SYM_FIELD) == v)
5492 goto found;
5493 s = s->next;
5495 tcc_error("declaration for parameter '%s' but no such parameter",
5496 get_tok_str(v, NULL));
5497 found:
5498 /* check that no storage specifier except 'register' was given */
5499 if (type.t & VT_STORAGE)
5500 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5501 convert_parameter_type(&type);
5502 /* we can add the type (NOTE: it could be local to the function) */
5503 s->type = type;
5504 /* accept other parameters */
5505 if (tok == ',')
5506 next();
5507 else
5508 break;
5511 skip(';');
5515 /* parse a function defined by symbol 'sym' and generate its code in
5516 'cur_text_section' */
5517 static void gen_function(Sym *sym)
5519 int saved_nocode_wanted = nocode_wanted;
5520 nocode_wanted = 0;
5521 ind = cur_text_section->data_offset;
5522 /* NOTE: we patch the symbol size later */
5523 put_extern_sym(sym, cur_text_section, ind, 0);
5524 funcname = get_tok_str(sym->v, NULL);
5525 func_ind = ind;
5526 /* put debug symbol */
5527 if (tcc_state->do_debug)
5528 put_func_debug(sym);
5529 /* push a dummy symbol to enable local sym storage */
5530 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5531 gfunc_prolog(&sym->type);
5532 rsym = 0;
5533 block(NULL, NULL, NULL, NULL, 0, 0);
5534 gsym(rsym);
5535 gfunc_epilog();
5536 cur_text_section->data_offset = ind;
5537 label_pop(&global_label_stack, NULL);
5538 /* reset local stack */
5539 scope_stack_bottom = NULL;
5540 sym_pop(&local_stack, NULL);
5541 /* end of function */
5542 /* patch symbol size */
5543 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5544 ind - func_ind;
5545 /* patch symbol weakness (this definition overrules any prototype) */
5546 if (sym->type.t & VT_WEAK)
5547 weaken_symbol(sym);
5548 if (tcc_state->do_debug) {
5549 put_stabn(N_FUN, 0, 0, ind - func_ind);
5551 /* It's better to crash than to generate wrong code */
5552 cur_text_section = NULL;
5553 funcname = ""; /* for safety */
5554 func_vt.t = VT_VOID; /* for safety */
5555 ind = 0; /* for safety */
5556 nocode_wanted = saved_nocode_wanted;
5559 ST_FUNC void gen_inline_functions(void)
5561 Sym *sym;
5562 int *str, inline_generated, i;
5563 struct InlineFunc *fn;
5565 /* iterate while inline function are referenced */
5566 for(;;) {
5567 inline_generated = 0;
5568 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5569 fn = tcc_state->inline_fns[i];
5570 sym = fn->sym;
5571 if (sym && sym->c) {
5572 /* the function was used: generate its code and
5573 convert it to a normal function */
5574 str = fn->token_str;
5575 fn->sym = NULL;
5576 if (file)
5577 pstrcpy(file->filename, sizeof file->filename, fn->filename);
5578 sym->r = VT_SYM | VT_CONST;
5579 sym->type.t &= ~VT_INLINE;
5581 macro_ptr = str;
5582 next();
5583 cur_text_section = text_section;
5584 gen_function(sym);
5585 macro_ptr = NULL; /* fail safe */
5587 inline_generated = 1;
5590 if (!inline_generated)
5591 break;
5593 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5594 fn = tcc_state->inline_fns[i];
5595 str = fn->token_str;
5596 tok_str_free(str);
5598 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5601 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5602 static int decl0(int l, int is_for_loop_init)
5604 int v, has_init, r;
5605 CType type, btype;
5606 Sym *sym;
5607 AttributeDef ad;
5609 while (1) {
5610 if (!parse_btype(&btype, &ad)) {
5611 if (is_for_loop_init)
5612 return 0;
5613 /* skip redundant ';' */
5614 /* XXX: find more elegant solution */
5615 if (tok == ';') {
5616 next();
5617 continue;
5619 if (l == VT_CONST &&
5620 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5621 /* global asm block */
5622 asm_global_instr();
5623 continue;
5625 /* special test for old K&R protos without explicit int
5626 type. Only accepted when defining global data */
5627 if (l == VT_LOCAL || tok < TOK_DEFINE)
5628 break;
5629 btype.t = VT_INT;
5631 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5632 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5633 tok == ';') {
5634 /* we accept no variable after */
5635 next();
5636 continue;
5638 while (1) { /* iterate thru each declaration */
5639 char *asm_label; // associated asm label
5640 type = btype;
5641 type_decl(&type, &ad, &v, TYPE_DIRECT);
5642 #if 0
5644 char buf[500];
5645 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5646 printf("type = '%s'\n", buf);
5648 #endif
5649 if ((type.t & VT_BTYPE) == VT_FUNC) {
5650 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5651 tcc_error("function without file scope cannot be static");
5653 /* if old style function prototype, we accept a
5654 declaration list */
5655 sym = type.ref;
5656 if (sym->c == FUNC_OLD)
5657 func_decl_list(sym);
5660 asm_label = NULL;
5661 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5662 CString astr;
5664 asm_label_instr(&astr);
5665 asm_label = tcc_strdup(astr.data);
5666 cstr_free(&astr);
5668 /* parse one last attribute list, after asm label */
5669 parse_attribute(&ad);
5672 if (ad.weak)
5673 type.t |= VT_WEAK;
5674 #ifdef TCC_TARGET_PE
5675 if (ad.func_import)
5676 type.t |= VT_IMPORT;
5677 if (ad.func_export)
5678 type.t |= VT_EXPORT;
5679 #endif
5680 if (tok == '{') {
5681 if (l == VT_LOCAL)
5682 tcc_error("cannot use local functions");
5683 if ((type.t & VT_BTYPE) != VT_FUNC)
5684 expect("function definition");
5686 /* reject abstract declarators in function definition */
5687 sym = type.ref;
5688 while ((sym = sym->next) != NULL)
5689 if (!(sym->v & ~SYM_FIELD))
5690 expect("identifier");
5692 /* XXX: cannot do better now: convert extern line to static inline */
5693 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5694 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5696 sym = sym_find(v);
5697 if (sym) {
5698 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5699 goto func_error1;
5701 r = sym->type.ref->r;
5702 /* use func_call from prototype if not defined */
5703 if (FUNC_CALL(r) != FUNC_CDECL
5704 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5705 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5707 /* use export from prototype */
5708 if (FUNC_EXPORT(r))
5709 FUNC_EXPORT(type.ref->r) = 1;
5711 /* use static from prototype */
5712 if (sym->type.t & VT_STATIC)
5713 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5715 if (!is_compatible_types(&sym->type, &type)) {
5716 func_error1:
5717 tcc_error("incompatible types for redefinition of '%s'",
5718 get_tok_str(v, NULL));
5720 /* if symbol is already defined, then put complete type */
5721 sym->type = type;
5722 } else {
5723 /* put function symbol */
5724 sym = global_identifier_push(v, type.t, 0);
5725 sym->type.ref = type.ref;
5728 /* static inline functions are just recorded as a kind
5729 of macro. Their code will be emitted at the end of
5730 the compilation unit only if they are used */
5731 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5732 (VT_INLINE | VT_STATIC)) {
5733 TokenString func_str;
5734 int block_level;
5735 struct InlineFunc *fn;
5736 const char *filename;
5738 tok_str_new(&func_str);
5740 block_level = 0;
5741 for(;;) {
5742 int t;
5743 if (tok == TOK_EOF)
5744 tcc_error("unexpected end of file");
5745 tok_str_add_tok(&func_str);
5746 t = tok;
5747 next();
5748 if (t == '{') {
5749 block_level++;
5750 } else if (t == '}') {
5751 block_level--;
5752 if (block_level == 0)
5753 break;
5756 tok_str_add(&func_str, -1);
5757 tok_str_add(&func_str, 0);
5758 filename = file ? file->filename : "";
5759 fn = tcc_malloc(sizeof *fn + strlen(filename));
5760 strcpy(fn->filename, filename);
5761 fn->sym = sym;
5762 fn->token_str = func_str.str;
5763 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5765 } else {
5766 /* compute text section */
5767 cur_text_section = ad.section;
5768 if (!cur_text_section)
5769 cur_text_section = text_section;
5770 sym->r = VT_SYM | VT_CONST;
5771 gen_function(sym);
5773 break;
5774 } else {
5775 if (btype.t & VT_TYPEDEF) {
5776 /* save typedefed type */
5777 /* XXX: test storage specifiers ? */
5778 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5779 sym->type.t |= VT_TYPEDEF;
5780 } else {
5781 r = 0;
5782 if ((type.t & VT_BTYPE) == VT_FUNC) {
5783 /* external function definition */
5784 /* specific case for func_call attribute */
5785 type.ref->r = INT_ATTR(&ad);
5786 } else if (!(type.t & VT_ARRAY)) {
5787 /* not lvalue if array */
5788 r |= lvalue_type(type.t);
5790 has_init = (tok == '=');
5791 if (has_init && (type.t & VT_VLA))
5792 tcc_error("Variable length array cannot be initialized");
5793 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5794 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5795 !has_init && l == VT_CONST && type.ref->c < 0)) {
5796 /* external variable or function */
5797 /* NOTE: as GCC, uninitialized global static
5798 arrays of null size are considered as
5799 extern */
5800 sym = external_sym(v, &type, r, asm_label);
5802 if (type.t & VT_WEAK)
5803 weaken_symbol(sym);
5805 if (ad.alias_target) {
5806 Section tsec;
5807 Elf32_Sym *esym;
5808 Sym *alias_target;
5810 alias_target = sym_find(ad.alias_target);
5811 if (!alias_target || !alias_target->c)
5812 tcc_error("unsupported forward __alias__ attribute");
5813 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
5814 tsec.sh_num = esym->st_shndx;
5815 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
5817 } else {
5818 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5819 if (type.t & VT_STATIC)
5820 r |= VT_CONST;
5821 else
5822 r |= l;
5823 if (has_init)
5824 next();
5825 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
5828 if (tok != ',') {
5829 if (is_for_loop_init)
5830 return 1;
5831 skip(';');
5832 break;
5834 next();
5836 ad.aligned = 0;
5839 return 0;
5842 ST_FUNC void decl(int l)
5844 decl0(l, 0);