support "x86_64-linux-gnu" subdirs with lib & include
[tinycc.git] / tccgen.c
blob5aa21c614bd224806d30cd4e885199714b08b440
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 *define_stack;
54 ST_DATA Sym *global_label_stack;
55 ST_DATA Sym *local_label_stack;
57 ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
59 ST_DATA int const_wanted; /* true if constant wanted */
60 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
61 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
62 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
63 ST_DATA int func_vc;
64 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
65 ST_DATA char *funcname;
67 ST_DATA CType char_pointer_type, func_old_type, int_type;
69 /* ------------------------------------------------------------------------- */
70 static void gen_cast(CType *type);
71 static inline CType *pointed_type(CType *type);
72 static int is_compatible_types(CType *type1, CType *type2);
73 static int parse_btype(CType *type, AttributeDef *ad);
74 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
75 static void parse_expr_type(CType *type);
76 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
77 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
78 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
79 static int decl0(int l, int is_for_loop_init);
80 static void expr_eq(void);
81 static void unary_type(CType *type);
82 static void vla_runtime_type_size(CType *type, int *a);
83 static int is_compatible_parameter_types(CType *type1, CType *type2);
84 static void expr_type(CType *type);
86 ST_INLN int is_float(int t)
88 int bt;
89 bt = t & VT_BTYPE;
90 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
93 /* we use our own 'finite' function to avoid potential problems with
94 non standard math libs */
95 /* XXX: endianness dependent */
96 ST_FUNC int ieee_finite(double d)
98 int *p = (int *)&d;
99 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
102 ST_FUNC void test_lvalue(void)
104 if (!(vtop->r & VT_LVAL))
105 expect("lvalue");
108 /* ------------------------------------------------------------------------- */
109 /* symbol allocator */
110 static Sym *__sym_malloc(void)
112 Sym *sym_pool, *sym, *last_sym;
113 int i;
115 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
116 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
118 last_sym = sym_free_first;
119 sym = sym_pool;
120 for(i = 0; i < SYM_POOL_NB; i++) {
121 sym->next = last_sym;
122 last_sym = sym;
123 sym++;
125 sym_free_first = last_sym;
126 return last_sym;
129 static inline Sym *sym_malloc(void)
131 Sym *sym;
132 sym = sym_free_first;
133 if (!sym)
134 sym = __sym_malloc();
135 sym_free_first = sym->next;
136 return sym;
139 ST_INLN void sym_free(Sym *sym)
141 sym->next = sym_free_first;
142 tcc_free(sym->asm_label);
143 sym_free_first = sym;
146 /* push, without hashing */
147 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
149 Sym *s;
150 s = sym_malloc();
151 s->asm_label = NULL;
152 s->v = v;
153 s->type.t = t;
154 s->type.ref = NULL;
155 #ifdef _WIN64
156 s->d = NULL;
157 #endif
158 s->c = c;
159 s->next = NULL;
160 /* add in stack */
161 s->prev = *ps;
162 *ps = s;
163 return s;
166 /* find a symbol and return its associated structure. 's' is the top
167 of the symbol stack */
168 ST_FUNC Sym *sym_find2(Sym *s, int v)
170 while (s) {
171 if (s->v == v)
172 return s;
173 s = s->prev;
175 return NULL;
178 /* structure lookup */
179 ST_INLN Sym *struct_find(int v)
181 v -= TOK_IDENT;
182 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
183 return NULL;
184 return table_ident[v]->sym_struct;
187 /* find an identifier */
188 ST_INLN Sym *sym_find(int v)
190 v -= TOK_IDENT;
191 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
192 return NULL;
193 return table_ident[v]->sym_identifier;
196 /* push a given symbol on the symbol stack */
197 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
199 Sym *s, **ps;
200 TokenSym *ts;
202 if (local_stack)
203 ps = &local_stack;
204 else
205 ps = &global_stack;
206 s = sym_push2(ps, v, type->t, c);
207 s->type.ref = type->ref;
208 s->r = r;
209 /* don't record fields or anonymous symbols */
210 /* XXX: simplify */
211 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
212 /* record symbol in token array */
213 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
214 if (v & SYM_STRUCT)
215 ps = &ts->sym_struct;
216 else
217 ps = &ts->sym_identifier;
218 s->prev_tok = *ps;
219 *ps = s;
221 return s;
224 /* push a global identifier */
225 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
227 Sym *s, **ps;
228 s = sym_push2(&global_stack, v, t, c);
229 /* don't record anonymous symbol */
230 if (v < SYM_FIRST_ANOM) {
231 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
232 /* modify the top most local identifier, so that
233 sym_identifier will point to 's' when popped */
234 while (*ps != NULL)
235 ps = &(*ps)->prev_tok;
236 s->prev_tok = NULL;
237 *ps = s;
239 return s;
242 /* pop symbols until top reaches 'b' */
243 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
245 Sym *s, *ss, **ps;
246 TokenSym *ts;
247 int v;
249 s = *ptop;
250 while(s != b) {
251 ss = s->prev;
252 v = s->v;
253 /* remove symbol in token array */
254 /* XXX: simplify */
255 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
256 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
257 if (v & SYM_STRUCT)
258 ps = &ts->sym_struct;
259 else
260 ps = &ts->sym_identifier;
261 *ps = s->prev_tok;
263 sym_free(s);
264 s = ss;
266 *ptop = b;
269 static void weaken_symbol(Sym *sym)
271 sym->type.t |= VT_WEAK;
272 if (sym->c > 0) {
273 int esym_type;
274 ElfW(Sym) *esym;
276 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
277 esym_type = ELFW(ST_TYPE)(esym->st_info);
278 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
282 /* ------------------------------------------------------------------------- */
284 ST_FUNC void swap(int *p, int *q)
286 int t;
287 t = *p;
288 *p = *q;
289 *q = t;
292 static void vsetc(CType *type, int r, CValue *vc)
294 int v;
296 if (vtop >= vstack + (VSTACK_SIZE - 1))
297 tcc_error("memory full");
298 /* cannot let cpu flags if other instruction are generated. Also
299 avoid leaving VT_JMP anywhere except on the top of the stack
300 because it would complicate the code generator. */
301 if (vtop >= vstack) {
302 v = vtop->r & VT_VALMASK;
303 if (v == VT_CMP || (v & ~1) == VT_JMP)
304 gv(RC_INT);
306 vtop++;
307 vtop->type = *type;
308 vtop->r = r;
309 vtop->r2 = VT_CONST;
310 vtop->c = *vc;
313 /* push constant of type "type" with useless value */
314 void vpush(CType *type)
316 CValue cval;
317 vsetc(type, VT_CONST, &cval);
320 /* push integer constant */
321 ST_FUNC void vpushi(int v)
323 CValue cval;
324 cval.i = v;
325 vsetc(&int_type, VT_CONST, &cval);
328 /* push long long constant */
329 static void vpushll(long long v)
331 CValue cval;
332 CType ctype;
333 ctype.t = VT_LLONG;
334 ctype.ref = 0;
335 cval.ull = v;
336 vsetc(&ctype, VT_CONST, &cval);
339 /* push arbitrary 64bit constant */
340 void vpush64(int ty, unsigned long long v)
342 CValue cval;
343 CType ctype;
344 ctype.t = ty;
345 cval.ull = v;
346 vsetc(&ctype, VT_CONST, &cval);
349 /* Return a static symbol pointing to a section */
350 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
352 int v;
353 Sym *sym;
355 v = anon_sym++;
356 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
357 sym->type.ref = type->ref;
358 sym->r = VT_CONST | VT_SYM;
359 put_extern_sym(sym, sec, offset, size);
360 return sym;
363 /* push a reference to a section offset by adding a dummy symbol */
364 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
366 CValue cval;
368 cval.ul = 0;
369 vsetc(type, VT_CONST | VT_SYM, &cval);
370 vtop->sym = get_sym_ref(type, sec, offset, size);
373 /* define a new external reference to a symbol 'v' of type 'u' */
374 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
376 Sym *s;
378 s = sym_find(v);
379 if (!s) {
380 /* push forward reference */
381 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
382 s->type.ref = type->ref;
383 s->r = r | VT_CONST | VT_SYM;
385 return s;
388 /* define a new external reference to a symbol 'v' with alternate asm
389 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
390 is no alternate name (most cases) */
391 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
393 Sym *s;
395 s = sym_find(v);
396 if (!s) {
397 /* push forward reference */
398 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
399 s->asm_label = asm_label;
400 s->type.t |= VT_EXTERN;
401 } else if (s->type.ref == func_old_type.ref) {
402 s->type.ref = type->ref;
403 s->r = r | VT_CONST | VT_SYM;
404 s->type.t |= VT_EXTERN;
405 } else if (!is_compatible_types(&s->type, type)) {
406 tcc_error("incompatible types for redefinition of '%s'",
407 get_tok_str(v, NULL));
409 return s;
412 /* push a reference to global symbol v */
413 ST_FUNC void vpush_global_sym(CType *type, int v)
415 Sym *sym;
416 CValue cval;
418 sym = external_global_sym(v, type, 0);
419 cval.ul = 0;
420 vsetc(type, VT_CONST | VT_SYM, &cval);
421 vtop->sym = sym;
424 ST_FUNC void vset(CType *type, int r, int v)
426 CValue cval;
428 cval.i = v;
429 vsetc(type, r, &cval);
432 static void vseti(int r, int v)
434 CType type;
435 type.t = VT_INT;
436 type.ref = 0;
437 vset(&type, r, v);
440 ST_FUNC void vswap(void)
442 SValue tmp;
444 tmp = vtop[0];
445 vtop[0] = vtop[-1];
446 vtop[-1] = tmp;
449 ST_FUNC void vpushv(SValue *v)
451 if (vtop >= vstack + (VSTACK_SIZE - 1))
452 tcc_error("memory full");
453 vtop++;
454 *vtop = *v;
457 static void vdup(void)
459 vpushv(vtop);
462 /* save r to the memory stack, and mark it as being free */
463 ST_FUNC void save_reg(int r)
465 int l, saved, size, align;
466 SValue *p, sv;
467 CType *type;
469 /* modify all stack values */
470 saved = 0;
471 l = 0;
472 for(p=vstack;p<=vtop;p++) {
473 if ((p->r & VT_VALMASK) == r ||
474 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
475 /* must save value on stack if not already done */
476 if (!saved) {
477 /* NOTE: must reload 'r' because r might be equal to r2 */
478 r = p->r & VT_VALMASK;
479 /* store register in the stack */
480 type = &p->type;
481 if ((p->r & VT_LVAL) ||
482 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
483 #ifdef TCC_TARGET_X86_64
484 type = &char_pointer_type;
485 #else
486 type = &int_type;
487 #endif
488 size = type_size(type, &align);
489 loc = (loc - size) & -align;
490 sv.type.t = type->t;
491 sv.r = VT_LOCAL | VT_LVAL;
492 sv.c.ul = loc;
493 store(r, &sv);
494 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
495 /* x86 specific: need to pop fp register ST0 if saved */
496 if (r == TREG_ST0) {
497 o(0xd8dd); /* fstp %st(0) */
499 #endif
500 #ifndef TCC_TARGET_X86_64
501 /* special long long case */
502 if ((type->t & VT_BTYPE) == VT_LLONG) {
503 sv.c.ul += 4;
504 store(p->r2, &sv);
506 #endif
507 l = loc;
508 saved = 1;
510 /* mark that stack entry as being saved on the stack */
511 if (p->r & VT_LVAL) {
512 /* also clear the bounded flag because the
513 relocation address of the function was stored in
514 p->c.ul */
515 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
516 } else {
517 p->r = lvalue_type(p->type.t) | VT_LOCAL;
519 p->r2 = VT_CONST;
520 p->c.ul = l;
525 #ifdef TCC_TARGET_ARM
526 /* find a register of class 'rc2' with at most one reference on stack.
527 * If none, call get_reg(rc) */
528 ST_FUNC int get_reg_ex(int rc, int rc2)
530 int r;
531 SValue *p;
533 for(r=0;r<NB_REGS;r++) {
534 if (reg_classes[r] & rc2) {
535 int n;
536 n=0;
537 for(p = vstack; p <= vtop; p++) {
538 if ((p->r & VT_VALMASK) == r ||
539 (p->r2 & VT_VALMASK) == r)
540 n++;
542 if (n <= 1)
543 return r;
546 return get_reg(rc);
548 #endif
550 /* find a free register of class 'rc'. If none, save one register */
551 ST_FUNC int get_reg(int rc)
553 int r;
554 SValue *p;
556 /* find a free register */
557 for(r=0;r<NB_REGS;r++) {
558 if (reg_classes[r] & rc) {
559 for(p=vstack;p<=vtop;p++) {
560 if ((p->r & VT_VALMASK) == r ||
561 (p->r2 & VT_VALMASK) == r)
562 goto notfound;
564 return r;
566 notfound: ;
569 /* no register left : free the first one on the stack (VERY
570 IMPORTANT to start from the bottom to ensure that we don't
571 spill registers used in gen_opi()) */
572 for(p=vstack;p<=vtop;p++) {
573 r = p->r & VT_VALMASK;
574 if (r < VT_CONST && (reg_classes[r] & rc))
575 goto save_found;
576 /* also look at second register (if long long) */
577 r = p->r2 & VT_VALMASK;
578 if (r < VT_CONST && (reg_classes[r] & rc)) {
579 save_found:
580 save_reg(r);
581 return r;
584 /* Should never comes here */
585 return -1;
588 /* save registers up to (vtop - n) stack entry */
589 ST_FUNC void save_regs(int n)
591 int r;
592 SValue *p, *p1;
593 p1 = vtop - n;
594 for(p = vstack;p <= p1; p++) {
595 r = p->r & VT_VALMASK;
596 if (r < VT_CONST) {
597 save_reg(r);
602 /* move register 's' to 'r', and flush previous value of r to memory
603 if needed */
604 static void move_reg(int r, int s)
606 SValue sv;
608 if (r != s) {
609 save_reg(r);
610 sv.type.t = VT_INT;
611 sv.r = s;
612 sv.c.ul = 0;
613 load(r, &sv);
617 /* get address of vtop (vtop MUST BE an lvalue) */
618 static void gaddrof(void)
620 if (vtop->r & VT_REF)
621 gv(RC_INT);
622 vtop->r &= ~VT_LVAL;
623 /* tricky: if saved lvalue, then we can go back to lvalue */
624 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
625 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
630 #ifdef CONFIG_TCC_BCHECK
631 /* generate lvalue bound code */
632 static void gbound(void)
634 int lval_type;
635 CType type1;
637 vtop->r &= ~VT_MUSTBOUND;
638 /* if lvalue, then use checking code before dereferencing */
639 if (vtop->r & VT_LVAL) {
640 /* if not VT_BOUNDED value, then make one */
641 if (!(vtop->r & VT_BOUNDED)) {
642 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
643 /* must save type because we must set it to int to get pointer */
644 type1 = vtop->type;
645 vtop->type.t = VT_INT;
646 gaddrof();
647 vpushi(0);
648 gen_bounded_ptr_add();
649 vtop->r |= lval_type;
650 vtop->type = type1;
652 /* then check for dereferencing */
653 gen_bounded_ptr_deref();
656 #endif
658 /* store vtop a register belonging to class 'rc'. lvalues are
659 converted to values. Cannot be used if cannot be converted to
660 register value (such as structures). */
661 ST_FUNC int gv(int rc)
663 int r, bit_pos, bit_size, size, align, i;
664 #ifndef TCC_TARGET_X86_64
665 int rc2;
666 #endif
668 /* NOTE: get_reg can modify vstack[] */
669 if (vtop->type.t & VT_BITFIELD) {
670 CType type;
671 int bits = 32;
672 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
673 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
674 /* remove bit field info to avoid loops */
675 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
676 /* cast to int to propagate signedness in following ops */
677 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
678 type.t = VT_LLONG;
679 bits = 64;
680 } else
681 type.t = VT_INT;
682 if((vtop->type.t & VT_UNSIGNED) ||
683 (vtop->type.t & VT_BTYPE) == VT_BOOL)
684 type.t |= VT_UNSIGNED;
685 gen_cast(&type);
686 /* generate shifts */
687 vpushi(bits - (bit_pos + bit_size));
688 gen_op(TOK_SHL);
689 vpushi(bits - bit_size);
690 /* NOTE: transformed to SHR if unsigned */
691 gen_op(TOK_SAR);
692 r = gv(rc);
693 } else {
694 if (is_float(vtop->type.t) &&
695 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
696 Sym *sym;
697 int *ptr;
698 unsigned long offset;
699 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
700 CValue check;
701 #endif
703 /* XXX: unify with initializers handling ? */
704 /* CPUs usually cannot use float constants, so we store them
705 generically in data segment */
706 size = type_size(&vtop->type, &align);
707 offset = (data_section->data_offset + align - 1) & -align;
708 data_section->data_offset = offset;
709 /* XXX: not portable yet */
710 #if defined(__i386__) || defined(__x86_64__)
711 /* Zero pad x87 tenbyte long doubles */
712 if (size == LDOUBLE_SIZE) {
713 vtop->c.tab[2] &= 0xffff;
714 #if LDOUBLE_SIZE == 16
715 vtop->c.tab[3] = 0;
716 #endif
718 #endif
719 ptr = section_ptr_add(data_section, size);
720 size = size >> 2;
721 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
722 check.d = 1;
723 if(check.tab[0])
724 for(i=0;i<size;i++)
725 ptr[i] = vtop->c.tab[size-1-i];
726 else
727 #endif
728 for(i=0;i<size;i++)
729 ptr[i] = vtop->c.tab[i];
730 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
731 vtop->r |= VT_LVAL | VT_SYM;
732 vtop->sym = sym;
733 vtop->c.ul = 0;
735 #ifdef CONFIG_TCC_BCHECK
736 if (vtop->r & VT_MUSTBOUND)
737 gbound();
738 #endif
740 r = vtop->r & VT_VALMASK;
741 #ifndef TCC_TARGET_X86_64
742 rc2 = RC_INT;
743 if (rc == RC_IRET)
744 rc2 = RC_LRET;
745 #endif
746 /* need to reload if:
747 - constant
748 - lvalue (need to dereference pointer)
749 - already a register, but not in the right class */
750 if (r >= VT_CONST
751 || (vtop->r & VT_LVAL)
752 || !(reg_classes[r] & rc)
753 #ifndef TCC_TARGET_X86_64
754 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
755 #endif
758 r = get_reg(rc);
759 #ifndef TCC_TARGET_X86_64
760 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
761 int r2;
762 unsigned long long ll;
763 /* two register type load : expand to two words
764 temporarily */
765 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
766 /* load constant */
767 ll = vtop->c.ull;
768 vtop->c.ui = ll; /* first word */
769 load(r, vtop);
770 vtop->r = r; /* save register value */
771 vpushi(ll >> 32); /* second word */
772 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
773 (vtop->r & VT_LVAL)) {
774 /* We do not want to modifier the long long
775 pointer here, so the safest (and less
776 efficient) is to save all the other registers
777 in the stack. XXX: totally inefficient. */
778 save_regs(1);
779 /* load from memory */
780 load(r, vtop);
781 vdup();
782 vtop[-1].r = r; /* save register value */
783 /* increment pointer to get second word */
784 vtop->type.t = VT_INT;
785 gaddrof();
786 vpushi(4);
787 gen_op('+');
788 vtop->r |= VT_LVAL;
789 } else {
790 /* move registers */
791 load(r, vtop);
792 vdup();
793 vtop[-1].r = r; /* save register value */
794 vtop->r = vtop[-1].r2;
796 /* allocate second register */
797 r2 = get_reg(rc2);
798 load(r2, vtop);
799 vpop();
800 /* write second register */
801 vtop->r2 = r2;
802 } else
803 #endif
804 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
805 int t1, t;
806 /* lvalue of scalar type : need to use lvalue type
807 because of possible cast */
808 t = vtop->type.t;
809 t1 = t;
810 /* compute memory access type */
811 if (vtop->r & VT_LVAL_BYTE)
812 t = VT_BYTE;
813 else if (vtop->r & VT_LVAL_SHORT)
814 t = VT_SHORT;
815 if (vtop->r & VT_LVAL_UNSIGNED)
816 t |= VT_UNSIGNED;
817 vtop->type.t = t;
818 load(r, vtop);
819 /* restore wanted type */
820 vtop->type.t = t1;
821 } else {
822 /* one register type load */
823 load(r, vtop);
826 vtop->r = r;
827 #ifdef TCC_TARGET_C67
828 /* uses register pairs for doubles */
829 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
830 vtop->r2 = r+1;
831 #endif
833 return r;
836 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
837 ST_FUNC void gv2(int rc1, int rc2)
839 int v;
841 /* generate more generic register first. But VT_JMP or VT_CMP
842 values must be generated first in all cases to avoid possible
843 reload errors */
844 v = vtop[0].r & VT_VALMASK;
845 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
846 vswap();
847 gv(rc1);
848 vswap();
849 gv(rc2);
850 /* test if reload is needed for first register */
851 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
852 vswap();
853 gv(rc1);
854 vswap();
856 } else {
857 gv(rc2);
858 vswap();
859 gv(rc1);
860 vswap();
861 /* test if reload is needed for first register */
862 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
863 gv(rc2);
868 /* wrapper around RC_FRET to return a register by type */
869 static int rc_fret(int t)
871 #ifdef TCC_TARGET_X86_64
872 if (t == VT_LDOUBLE) {
873 return RC_ST0;
875 #endif
876 return RC_FRET;
879 /* wrapper around REG_FRET to return a register by type */
880 static int reg_fret(int t)
882 #ifdef TCC_TARGET_X86_64
883 if (t == VT_LDOUBLE) {
884 return TREG_ST0;
886 #endif
887 return REG_FRET;
890 /* expand long long on stack in two int registers */
891 static void lexpand(void)
893 int u;
895 u = vtop->type.t & VT_UNSIGNED;
896 gv(RC_INT);
897 vdup();
898 vtop[0].r = vtop[-1].r2;
899 vtop[0].r2 = VT_CONST;
900 vtop[-1].r2 = VT_CONST;
901 vtop[0].type.t = VT_INT | u;
902 vtop[-1].type.t = VT_INT | u;
905 #ifdef TCC_TARGET_ARM
906 /* expand long long on stack */
907 ST_FUNC void lexpand_nr(void)
909 int u,v;
911 u = vtop->type.t & VT_UNSIGNED;
912 vdup();
913 vtop->r2 = VT_CONST;
914 vtop->type.t = VT_INT | u;
915 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
916 if (v == VT_CONST) {
917 vtop[-1].c.ui = vtop->c.ull;
918 vtop->c.ui = vtop->c.ull >> 32;
919 vtop->r = VT_CONST;
920 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
921 vtop->c.ui += 4;
922 vtop->r = vtop[-1].r;
923 } else if (v > VT_CONST) {
924 vtop--;
925 lexpand();
926 } else
927 vtop->r = vtop[-1].r2;
928 vtop[-1].r2 = VT_CONST;
929 vtop[-1].type.t = VT_INT | u;
931 #endif
933 /* build a long long from two ints */
934 static void lbuild(int t)
936 gv2(RC_INT, RC_INT);
937 vtop[-1].r2 = vtop[0].r;
938 vtop[-1].type.t = t;
939 vpop();
942 /* rotate n first stack elements to the bottom
943 I1 ... In -> I2 ... In I1 [top is right]
945 static void vrotb(int n)
947 int i;
948 SValue tmp;
950 tmp = vtop[-n + 1];
951 for(i=-n+1;i!=0;i++)
952 vtop[i] = vtop[i+1];
953 vtop[0] = tmp;
956 /* rotate n first stack elements to the top
957 I1 ... In -> In I1 ... I(n-1) [top is right]
959 ST_FUNC void vrott(int n)
961 int i;
962 SValue tmp;
964 tmp = vtop[0];
965 for(i = 0;i < n - 1; i++)
966 vtop[-i] = vtop[-i - 1];
967 vtop[-n + 1] = tmp;
970 /* pop stack value */
971 ST_FUNC void vpop(void)
973 int v;
974 v = vtop->r & VT_VALMASK;
975 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
976 /* for x86, we need to pop the FP stack */
977 if (v == TREG_ST0 && !nocode_wanted) {
978 o(0xd8dd); /* fstp %st(0) */
979 } else
980 #endif
981 if (v == VT_JMP || v == VT_JMPI) {
982 /* need to put correct jump if && or || without test */
983 gsym(vtop->c.ul);
985 vtop--;
988 /* convert stack entry to register and duplicate its value in another
989 register */
990 static void gv_dup(void)
992 int rc, t, r, r1;
993 SValue sv;
995 t = vtop->type.t;
996 if ((t & VT_BTYPE) == VT_LLONG) {
997 lexpand();
998 gv_dup();
999 vswap();
1000 vrotb(3);
1001 gv_dup();
1002 vrotb(4);
1003 /* stack: H L L1 H1 */
1004 lbuild(t);
1005 vrotb(3);
1006 vrotb(3);
1007 vswap();
1008 lbuild(t);
1009 vswap();
1010 } else {
1011 /* duplicate value */
1012 rc = RC_INT;
1013 sv.type.t = VT_INT;
1014 if (is_float(t)) {
1015 rc = RC_FLOAT;
1016 #ifdef TCC_TARGET_X86_64
1017 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1018 rc = RC_ST0;
1020 #endif
1021 sv.type.t = t;
1023 r = gv(rc);
1024 r1 = get_reg(rc);
1025 sv.r = r;
1026 sv.c.ul = 0;
1027 load(r1, &sv); /* move r to r1 */
1028 vdup();
1029 /* duplicates value */
1030 if (r != r1)
1031 vtop->r = r1;
1035 #ifndef TCC_TARGET_X86_64
1036 /* generate CPU independent (unsigned) long long operations */
1037 static void gen_opl(int op)
1039 int t, a, b, op1, c, i;
1040 int func;
1041 unsigned short reg_iret = REG_IRET;
1042 unsigned short reg_lret = REG_LRET;
1043 SValue tmp;
1045 switch(op) {
1046 case '/':
1047 case TOK_PDIV:
1048 func = TOK___divdi3;
1049 goto gen_func;
1050 case TOK_UDIV:
1051 func = TOK___udivdi3;
1052 goto gen_func;
1053 case '%':
1054 func = TOK___moddi3;
1055 goto gen_mod_func;
1056 case TOK_UMOD:
1057 func = TOK___umoddi3;
1058 gen_mod_func:
1059 #ifdef TCC_ARM_EABI
1060 reg_iret = TREG_R2;
1061 reg_lret = TREG_R3;
1062 #endif
1063 gen_func:
1064 /* call generic long long function */
1065 vpush_global_sym(&func_old_type, func);
1066 vrott(3);
1067 gfunc_call(2);
1068 vpushi(0);
1069 vtop->r = reg_iret;
1070 vtop->r2 = reg_lret;
1071 break;
1072 case '^':
1073 case '&':
1074 case '|':
1075 case '*':
1076 case '+':
1077 case '-':
1078 t = vtop->type.t;
1079 vswap();
1080 lexpand();
1081 vrotb(3);
1082 lexpand();
1083 /* stack: L1 H1 L2 H2 */
1084 tmp = vtop[0];
1085 vtop[0] = vtop[-3];
1086 vtop[-3] = tmp;
1087 tmp = vtop[-2];
1088 vtop[-2] = vtop[-3];
1089 vtop[-3] = tmp;
1090 vswap();
1091 /* stack: H1 H2 L1 L2 */
1092 if (op == '*') {
1093 vpushv(vtop - 1);
1094 vpushv(vtop - 1);
1095 gen_op(TOK_UMULL);
1096 lexpand();
1097 /* stack: H1 H2 L1 L2 ML MH */
1098 for(i=0;i<4;i++)
1099 vrotb(6);
1100 /* stack: ML MH H1 H2 L1 L2 */
1101 tmp = vtop[0];
1102 vtop[0] = vtop[-2];
1103 vtop[-2] = tmp;
1104 /* stack: ML MH H1 L2 H2 L1 */
1105 gen_op('*');
1106 vrotb(3);
1107 vrotb(3);
1108 gen_op('*');
1109 /* stack: ML MH M1 M2 */
1110 gen_op('+');
1111 gen_op('+');
1112 } else if (op == '+' || op == '-') {
1113 /* XXX: add non carry method too (for MIPS or alpha) */
1114 if (op == '+')
1115 op1 = TOK_ADDC1;
1116 else
1117 op1 = TOK_SUBC1;
1118 gen_op(op1);
1119 /* stack: H1 H2 (L1 op L2) */
1120 vrotb(3);
1121 vrotb(3);
1122 gen_op(op1 + 1); /* TOK_xxxC2 */
1123 } else {
1124 gen_op(op);
1125 /* stack: H1 H2 (L1 op L2) */
1126 vrotb(3);
1127 vrotb(3);
1128 /* stack: (L1 op L2) H1 H2 */
1129 gen_op(op);
1130 /* stack: (L1 op L2) (H1 op H2) */
1132 /* stack: L H */
1133 lbuild(t);
1134 break;
1135 case TOK_SAR:
1136 case TOK_SHR:
1137 case TOK_SHL:
1138 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1139 t = vtop[-1].type.t;
1140 vswap();
1141 lexpand();
1142 vrotb(3);
1143 /* stack: L H shift */
1144 c = (int)vtop->c.i;
1145 /* constant: simpler */
1146 /* NOTE: all comments are for SHL. the other cases are
1147 done by swaping words */
1148 vpop();
1149 if (op != TOK_SHL)
1150 vswap();
1151 if (c >= 32) {
1152 /* stack: L H */
1153 vpop();
1154 if (c > 32) {
1155 vpushi(c - 32);
1156 gen_op(op);
1158 if (op != TOK_SAR) {
1159 vpushi(0);
1160 } else {
1161 gv_dup();
1162 vpushi(31);
1163 gen_op(TOK_SAR);
1165 vswap();
1166 } else {
1167 vswap();
1168 gv_dup();
1169 /* stack: H L L */
1170 vpushi(c);
1171 gen_op(op);
1172 vswap();
1173 vpushi(32 - c);
1174 if (op == TOK_SHL)
1175 gen_op(TOK_SHR);
1176 else
1177 gen_op(TOK_SHL);
1178 vrotb(3);
1179 /* stack: L L H */
1180 vpushi(c);
1181 if (op == TOK_SHL)
1182 gen_op(TOK_SHL);
1183 else
1184 gen_op(TOK_SHR);
1185 gen_op('|');
1187 if (op != TOK_SHL)
1188 vswap();
1189 lbuild(t);
1190 } else {
1191 /* XXX: should provide a faster fallback on x86 ? */
1192 switch(op) {
1193 case TOK_SAR:
1194 func = TOK___ashrdi3;
1195 goto gen_func;
1196 case TOK_SHR:
1197 func = TOK___lshrdi3;
1198 goto gen_func;
1199 case TOK_SHL:
1200 func = TOK___ashldi3;
1201 goto gen_func;
1204 break;
1205 default:
1206 /* compare operations */
1207 t = vtop->type.t;
1208 vswap();
1209 lexpand();
1210 vrotb(3);
1211 lexpand();
1212 /* stack: L1 H1 L2 H2 */
1213 tmp = vtop[-1];
1214 vtop[-1] = vtop[-2];
1215 vtop[-2] = tmp;
1216 /* stack: L1 L2 H1 H2 */
1217 /* compare high */
1218 op1 = op;
1219 /* when values are equal, we need to compare low words. since
1220 the jump is inverted, we invert the test too. */
1221 if (op1 == TOK_LT)
1222 op1 = TOK_LE;
1223 else if (op1 == TOK_GT)
1224 op1 = TOK_GE;
1225 else if (op1 == TOK_ULT)
1226 op1 = TOK_ULE;
1227 else if (op1 == TOK_UGT)
1228 op1 = TOK_UGE;
1229 a = 0;
1230 b = 0;
1231 gen_op(op1);
1232 if (op1 != TOK_NE) {
1233 a = gtst(1, 0);
1235 if (op != TOK_EQ) {
1236 /* generate non equal test */
1237 /* XXX: NOT PORTABLE yet */
1238 if (a == 0) {
1239 b = gtst(0, 0);
1240 } else {
1241 #if defined(TCC_TARGET_I386)
1242 b = psym(0x850f, 0);
1243 #elif defined(TCC_TARGET_ARM)
1244 b = ind;
1245 o(0x1A000000 | encbranch(ind, 0, 1));
1246 #elif defined(TCC_TARGET_C67)
1247 tcc_error("not implemented");
1248 #else
1249 #error not supported
1250 #endif
1253 /* compare low. Always unsigned */
1254 op1 = op;
1255 if (op1 == TOK_LT)
1256 op1 = TOK_ULT;
1257 else if (op1 == TOK_LE)
1258 op1 = TOK_ULE;
1259 else if (op1 == TOK_GT)
1260 op1 = TOK_UGT;
1261 else if (op1 == TOK_GE)
1262 op1 = TOK_UGE;
1263 gen_op(op1);
1264 a = gtst(1, a);
1265 gsym(b);
1266 vseti(VT_JMPI, a);
1267 break;
1270 #endif
1272 /* handle integer constant optimizations and various machine
1273 independent opt */
1274 static void gen_opic(int op)
1276 int c1, c2, t1, t2, n;
1277 SValue *v1, *v2;
1278 long long l1, l2;
1279 typedef unsigned long long U;
1281 v1 = vtop - 1;
1282 v2 = vtop;
1283 t1 = v1->type.t & VT_BTYPE;
1284 t2 = v2->type.t & VT_BTYPE;
1286 if (t1 == VT_LLONG)
1287 l1 = v1->c.ll;
1288 else if (v1->type.t & VT_UNSIGNED)
1289 l1 = v1->c.ui;
1290 else
1291 l1 = v1->c.i;
1293 if (t2 == VT_LLONG)
1294 l2 = v2->c.ll;
1295 else if (v2->type.t & VT_UNSIGNED)
1296 l2 = v2->c.ui;
1297 else
1298 l2 = v2->c.i;
1300 /* currently, we cannot do computations with forward symbols */
1301 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1302 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1303 if (c1 && c2) {
1304 switch(op) {
1305 case '+': l1 += l2; break;
1306 case '-': l1 -= l2; break;
1307 case '&': l1 &= l2; break;
1308 case '^': l1 ^= l2; break;
1309 case '|': l1 |= l2; break;
1310 case '*': l1 *= l2; break;
1312 case TOK_PDIV:
1313 case '/':
1314 case '%':
1315 case TOK_UDIV:
1316 case TOK_UMOD:
1317 /* if division by zero, generate explicit division */
1318 if (l2 == 0) {
1319 if (const_wanted)
1320 tcc_error("division by zero in constant");
1321 goto general_case;
1323 switch(op) {
1324 default: l1 /= l2; break;
1325 case '%': l1 %= l2; break;
1326 case TOK_UDIV: l1 = (U)l1 / l2; break;
1327 case TOK_UMOD: l1 = (U)l1 % l2; break;
1329 break;
1330 case TOK_SHL: l1 <<= l2; break;
1331 case TOK_SHR: l1 = (U)l1 >> l2; break;
1332 case TOK_SAR: l1 >>= l2; break;
1333 /* tests */
1334 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1335 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1336 case TOK_EQ: l1 = l1 == l2; break;
1337 case TOK_NE: l1 = l1 != l2; break;
1338 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1339 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1340 case TOK_LT: l1 = l1 < l2; break;
1341 case TOK_GE: l1 = l1 >= l2; break;
1342 case TOK_LE: l1 = l1 <= l2; break;
1343 case TOK_GT: l1 = l1 > l2; break;
1344 /* logical */
1345 case TOK_LAND: l1 = l1 && l2; break;
1346 case TOK_LOR: l1 = l1 || l2; break;
1347 default:
1348 goto general_case;
1350 v1->c.ll = l1;
1351 vtop--;
1352 } else {
1353 /* if commutative ops, put c2 as constant */
1354 if (c1 && (op == '+' || op == '&' || op == '^' ||
1355 op == '|' || op == '*')) {
1356 vswap();
1357 c2 = c1; //c = c1, c1 = c2, c2 = c;
1358 l2 = l1; //l = l1, l1 = l2, l2 = l;
1360 /* Filter out NOP operations like x*1, x-0, x&-1... */
1361 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1362 op == TOK_PDIV) &&
1363 l2 == 1) ||
1364 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1365 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1366 l2 == 0) ||
1367 (op == '&' &&
1368 l2 == -1))) {
1369 /* nothing to do */
1370 vtop--;
1371 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1372 /* try to use shifts instead of muls or divs */
1373 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1374 n = -1;
1375 while (l2) {
1376 l2 >>= 1;
1377 n++;
1379 vtop->c.ll = n;
1380 if (op == '*')
1381 op = TOK_SHL;
1382 else if (op == TOK_PDIV)
1383 op = TOK_SAR;
1384 else
1385 op = TOK_SHR;
1387 goto general_case;
1388 } else if (c2 && (op == '+' || op == '-') &&
1389 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1390 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1391 /* symbol + constant case */
1392 if (op == '-')
1393 l2 = -l2;
1394 vtop--;
1395 vtop->c.ll += l2;
1396 } else {
1397 general_case:
1398 if (!nocode_wanted) {
1399 /* call low level op generator */
1400 if (t1 == VT_LLONG || t2 == VT_LLONG)
1401 gen_opl(op);
1402 else
1403 gen_opi(op);
1404 } else {
1405 vtop--;
1411 /* generate a floating point operation with constant propagation */
1412 static void gen_opif(int op)
1414 int c1, c2;
1415 SValue *v1, *v2;
1416 long double f1, f2;
1418 v1 = vtop - 1;
1419 v2 = vtop;
1420 /* currently, we cannot do computations with forward symbols */
1421 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1422 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1423 if (c1 && c2) {
1424 if (v1->type.t == VT_FLOAT) {
1425 f1 = v1->c.f;
1426 f2 = v2->c.f;
1427 } else if (v1->type.t == VT_DOUBLE) {
1428 f1 = v1->c.d;
1429 f2 = v2->c.d;
1430 } else {
1431 f1 = v1->c.ld;
1432 f2 = v2->c.ld;
1435 /* NOTE: we only do constant propagation if finite number (not
1436 NaN or infinity) (ANSI spec) */
1437 if (!ieee_finite(f1) || !ieee_finite(f2))
1438 goto general_case;
1440 switch(op) {
1441 case '+': f1 += f2; break;
1442 case '-': f1 -= f2; break;
1443 case '*': f1 *= f2; break;
1444 case '/':
1445 if (f2 == 0.0) {
1446 if (const_wanted)
1447 tcc_error("division by zero in constant");
1448 goto general_case;
1450 f1 /= f2;
1451 break;
1452 /* XXX: also handles tests ? */
1453 default:
1454 goto general_case;
1456 /* XXX: overflow test ? */
1457 if (v1->type.t == VT_FLOAT) {
1458 v1->c.f = f1;
1459 } else if (v1->type.t == VT_DOUBLE) {
1460 v1->c.d = f1;
1461 } else {
1462 v1->c.ld = f1;
1464 vtop--;
1465 } else {
1466 general_case:
1467 if (!nocode_wanted) {
1468 gen_opf(op);
1469 } else {
1470 vtop--;
1475 static int pointed_size(CType *type)
1477 int align;
1478 return type_size(pointed_type(type), &align);
1481 static void vla_runtime_pointed_size(CType *type)
1483 int align;
1484 vla_runtime_type_size(pointed_type(type), &align);
1487 static inline int is_null_pointer(SValue *p)
1489 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1490 return 0;
1491 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1492 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1495 static inline int is_integer_btype(int bt)
1497 return (bt == VT_BYTE || bt == VT_SHORT ||
1498 bt == VT_INT || bt == VT_LLONG);
1501 /* check types for comparison or substraction of pointers */
1502 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1504 CType *type1, *type2, tmp_type1, tmp_type2;
1505 int bt1, bt2;
1507 /* null pointers are accepted for all comparisons as gcc */
1508 if (is_null_pointer(p1) || is_null_pointer(p2))
1509 return;
1510 type1 = &p1->type;
1511 type2 = &p2->type;
1512 bt1 = type1->t & VT_BTYPE;
1513 bt2 = type2->t & VT_BTYPE;
1514 /* accept comparison between pointer and integer with a warning */
1515 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1516 if (op != TOK_LOR && op != TOK_LAND )
1517 tcc_warning("comparison between pointer and integer");
1518 return;
1521 /* both must be pointers or implicit function pointers */
1522 if (bt1 == VT_PTR) {
1523 type1 = pointed_type(type1);
1524 } else if (bt1 != VT_FUNC)
1525 goto invalid_operands;
1527 if (bt2 == VT_PTR) {
1528 type2 = pointed_type(type2);
1529 } else if (bt2 != VT_FUNC) {
1530 invalid_operands:
1531 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1533 if ((type1->t & VT_BTYPE) == VT_VOID ||
1534 (type2->t & VT_BTYPE) == VT_VOID)
1535 return;
1536 tmp_type1 = *type1;
1537 tmp_type2 = *type2;
1538 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1539 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1540 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1541 /* gcc-like error if '-' is used */
1542 if (op == '-')
1543 goto invalid_operands;
1544 else
1545 tcc_warning("comparison of distinct pointer types lacks a cast");
1549 /* generic gen_op: handles types problems */
1550 ST_FUNC void gen_op(int op)
1552 int u, t1, t2, bt1, bt2, t;
1553 CType type1;
1555 t1 = vtop[-1].type.t;
1556 t2 = vtop[0].type.t;
1557 bt1 = t1 & VT_BTYPE;
1558 bt2 = t2 & VT_BTYPE;
1560 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1561 /* at least one operand is a pointer */
1562 /* relationnal op: must be both pointers */
1563 if (op >= TOK_ULT && op <= TOK_LOR) {
1564 check_comparison_pointer_types(vtop - 1, vtop, op);
1565 /* pointers are handled are unsigned */
1566 #ifdef TCC_TARGET_X86_64
1567 t = VT_LLONG | VT_UNSIGNED;
1568 #else
1569 t = VT_INT | VT_UNSIGNED;
1570 #endif
1571 goto std_op;
1573 /* if both pointers, then it must be the '-' op */
1574 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1575 if (op != '-')
1576 tcc_error("cannot use pointers here");
1577 check_comparison_pointer_types(vtop - 1, vtop, op);
1578 /* XXX: check that types are compatible */
1579 if (vtop[-1].type.t & VT_VLA) {
1580 vla_runtime_pointed_size(&vtop[-1].type);
1581 } else {
1582 vpushi(pointed_size(&vtop[-1].type));
1584 vrott(3);
1585 gen_opic(op);
1586 /* set to integer type */
1587 #ifdef TCC_TARGET_X86_64
1588 vtop->type.t = VT_LLONG;
1589 #else
1590 vtop->type.t = VT_INT;
1591 #endif
1592 vswap();
1593 gen_op(TOK_PDIV);
1594 } else {
1595 /* exactly one pointer : must be '+' or '-'. */
1596 if (op != '-' && op != '+')
1597 tcc_error("cannot use pointers here");
1598 /* Put pointer as first operand */
1599 if (bt2 == VT_PTR) {
1600 vswap();
1601 swap(&t1, &t2);
1603 type1 = vtop[-1].type;
1604 type1.t &= ~VT_ARRAY;
1605 if (vtop[-1].type.t & VT_VLA)
1606 vla_runtime_pointed_size(&vtop[-1].type);
1607 else {
1608 u = pointed_size(&vtop[-1].type);
1609 if (u < 0)
1610 tcc_error("unknown array element size");
1611 #ifdef TCC_TARGET_X86_64
1612 vpushll(u);
1613 #else
1614 /* XXX: cast to int ? (long long case) */
1615 vpushi(u);
1616 #endif
1618 gen_op('*');
1619 #ifdef CONFIG_TCC_BCHECK
1620 /* if evaluating constant expression, no code should be
1621 generated, so no bound check */
1622 if (tcc_state->do_bounds_check && !const_wanted) {
1623 /* if bounded pointers, we generate a special code to
1624 test bounds */
1625 if (op == '-') {
1626 vpushi(0);
1627 vswap();
1628 gen_op('-');
1630 gen_bounded_ptr_add();
1631 } else
1632 #endif
1634 gen_opic(op);
1636 /* put again type if gen_opic() swaped operands */
1637 vtop->type = type1;
1639 } else if (is_float(bt1) || is_float(bt2)) {
1640 /* compute bigger type and do implicit casts */
1641 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1642 t = VT_LDOUBLE;
1643 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1644 t = VT_DOUBLE;
1645 } else {
1646 t = VT_FLOAT;
1648 /* floats can only be used for a few operations */
1649 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1650 (op < TOK_ULT || op > TOK_GT))
1651 tcc_error("invalid operands for binary operation");
1652 goto std_op;
1653 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1654 /* cast to biggest op */
1655 t = VT_LLONG;
1656 /* convert to unsigned if it does not fit in a long long */
1657 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1658 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1659 t |= VT_UNSIGNED;
1660 goto std_op;
1661 } else {
1662 /* integer operations */
1663 t = VT_INT;
1664 /* convert to unsigned if it does not fit in an integer */
1665 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1666 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1667 t |= VT_UNSIGNED;
1668 std_op:
1669 /* XXX: currently, some unsigned operations are explicit, so
1670 we modify them here */
1671 if (t & VT_UNSIGNED) {
1672 if (op == TOK_SAR)
1673 op = TOK_SHR;
1674 else if (op == '/')
1675 op = TOK_UDIV;
1676 else if (op == '%')
1677 op = TOK_UMOD;
1678 else if (op == TOK_LT)
1679 op = TOK_ULT;
1680 else if (op == TOK_GT)
1681 op = TOK_UGT;
1682 else if (op == TOK_LE)
1683 op = TOK_ULE;
1684 else if (op == TOK_GE)
1685 op = TOK_UGE;
1687 vswap();
1688 type1.t = t;
1689 gen_cast(&type1);
1690 vswap();
1691 /* special case for shifts and long long: we keep the shift as
1692 an integer */
1693 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1694 type1.t = VT_INT;
1695 gen_cast(&type1);
1696 if (is_float(t))
1697 gen_opif(op);
1698 else
1699 gen_opic(op);
1700 if (op >= TOK_ULT && op <= TOK_GT) {
1701 /* relationnal op: the result is an int */
1702 vtop->type.t = VT_INT;
1703 } else {
1704 vtop->type.t = t;
1709 #ifndef TCC_TARGET_ARM
1710 /* generic itof for unsigned long long case */
1711 static void gen_cvt_itof1(int t)
1713 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1714 (VT_LLONG | VT_UNSIGNED)) {
1716 if (t == VT_FLOAT)
1717 vpush_global_sym(&func_old_type, TOK___floatundisf);
1718 #if LDOUBLE_SIZE != 8
1719 else if (t == VT_LDOUBLE)
1720 vpush_global_sym(&func_old_type, TOK___floatundixf);
1721 #endif
1722 else
1723 vpush_global_sym(&func_old_type, TOK___floatundidf);
1724 vrott(2);
1725 gfunc_call(1);
1726 vpushi(0);
1727 vtop->r = reg_fret(t);
1728 } else {
1729 gen_cvt_itof(t);
1732 #endif
1734 /* generic ftoi for unsigned long long case */
1735 static void gen_cvt_ftoi1(int t)
1737 int st;
1739 if (t == (VT_LLONG | VT_UNSIGNED)) {
1740 /* not handled natively */
1741 st = vtop->type.t & VT_BTYPE;
1742 if (st == VT_FLOAT)
1743 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1744 #if LDOUBLE_SIZE != 8
1745 else if (st == VT_LDOUBLE)
1746 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1747 #endif
1748 else
1749 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1750 vrott(2);
1751 gfunc_call(1);
1752 vpushi(0);
1753 vtop->r = REG_IRET;
1754 vtop->r2 = REG_LRET;
1755 } else {
1756 gen_cvt_ftoi(t);
1760 /* force char or short cast */
1761 static void force_charshort_cast(int t)
1763 int bits, dbt;
1764 dbt = t & VT_BTYPE;
1765 /* XXX: add optimization if lvalue : just change type and offset */
1766 if (dbt == VT_BYTE)
1767 bits = 8;
1768 else
1769 bits = 16;
1770 if (t & VT_UNSIGNED) {
1771 vpushi((1 << bits) - 1);
1772 gen_op('&');
1773 } else {
1774 bits = 32 - bits;
1775 vpushi(bits);
1776 gen_op(TOK_SHL);
1777 /* result must be signed or the SAR is converted to an SHL
1778 This was not the case when "t" was a signed short
1779 and the last value on the stack was an unsigned int */
1780 vtop->type.t &= ~VT_UNSIGNED;
1781 vpushi(bits);
1782 gen_op(TOK_SAR);
1786 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1787 static void gen_cast(CType *type)
1789 int sbt, dbt, sf, df, c, p;
1791 /* special delayed cast for char/short */
1792 /* XXX: in some cases (multiple cascaded casts), it may still
1793 be incorrect */
1794 if (vtop->r & VT_MUSTCAST) {
1795 vtop->r &= ~VT_MUSTCAST;
1796 force_charshort_cast(vtop->type.t);
1799 /* bitfields first get cast to ints */
1800 if (vtop->type.t & VT_BITFIELD) {
1801 gv(RC_INT);
1804 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1805 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1807 if (sbt != dbt) {
1808 sf = is_float(sbt);
1809 df = is_float(dbt);
1810 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1811 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1812 if (c) {
1813 /* constant case: we can do it now */
1814 /* XXX: in ISOC, cannot do it if error in convert */
1815 if (sbt == VT_FLOAT)
1816 vtop->c.ld = vtop->c.f;
1817 else if (sbt == VT_DOUBLE)
1818 vtop->c.ld = vtop->c.d;
1820 if (df) {
1821 if ((sbt & VT_BTYPE) == VT_LLONG) {
1822 if (sbt & VT_UNSIGNED)
1823 vtop->c.ld = vtop->c.ull;
1824 else
1825 vtop->c.ld = vtop->c.ll;
1826 } else if(!sf) {
1827 if (sbt & VT_UNSIGNED)
1828 vtop->c.ld = vtop->c.ui;
1829 else
1830 vtop->c.ld = vtop->c.i;
1833 if (dbt == VT_FLOAT)
1834 vtop->c.f = (float)vtop->c.ld;
1835 else if (dbt == VT_DOUBLE)
1836 vtop->c.d = (double)vtop->c.ld;
1837 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1838 vtop->c.ull = (unsigned long long)vtop->c.ld;
1839 } else if (sf && dbt == VT_BOOL) {
1840 vtop->c.i = (vtop->c.ld != 0);
1841 } else {
1842 if(sf)
1843 vtop->c.ll = (long long)vtop->c.ld;
1844 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1845 vtop->c.ll = vtop->c.ull;
1846 else if (sbt & VT_UNSIGNED)
1847 vtop->c.ll = vtop->c.ui;
1848 #ifdef TCC_TARGET_X86_64
1849 else if (sbt == VT_PTR)
1851 #endif
1852 else if (sbt != VT_LLONG)
1853 vtop->c.ll = vtop->c.i;
1855 if (dbt == (VT_LLONG|VT_UNSIGNED))
1856 vtop->c.ull = vtop->c.ll;
1857 else if (dbt == VT_BOOL)
1858 vtop->c.i = (vtop->c.ll != 0);
1859 else if (dbt != VT_LLONG) {
1860 int s = 0;
1861 if ((dbt & VT_BTYPE) == VT_BYTE)
1862 s = 24;
1863 else if ((dbt & VT_BTYPE) == VT_SHORT)
1864 s = 16;
1866 if(dbt & VT_UNSIGNED)
1867 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1868 else
1869 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1872 } else if (p && dbt == VT_BOOL) {
1873 vtop->r = VT_CONST;
1874 vtop->c.i = 1;
1875 } else if (!nocode_wanted) {
1876 /* non constant case: generate code */
1877 if (sf && df) {
1878 /* convert from fp to fp */
1879 gen_cvt_ftof(dbt);
1880 } else if (df) {
1881 /* convert int to fp */
1882 gen_cvt_itof1(dbt);
1883 } else if (sf) {
1884 /* convert fp to int */
1885 if (dbt == VT_BOOL) {
1886 vpushi(0);
1887 gen_op(TOK_NE);
1888 } else {
1889 /* we handle char/short/etc... with generic code */
1890 if (dbt != (VT_INT | VT_UNSIGNED) &&
1891 dbt != (VT_LLONG | VT_UNSIGNED) &&
1892 dbt != VT_LLONG)
1893 dbt = VT_INT;
1894 gen_cvt_ftoi1(dbt);
1895 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1896 /* additional cast for char/short... */
1897 vtop->type.t = dbt;
1898 gen_cast(type);
1901 #ifndef TCC_TARGET_X86_64
1902 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1903 if ((sbt & VT_BTYPE) != VT_LLONG) {
1904 /* scalar to long long */
1905 /* machine independent conversion */
1906 gv(RC_INT);
1907 /* generate high word */
1908 if (sbt == (VT_INT | VT_UNSIGNED)) {
1909 vpushi(0);
1910 gv(RC_INT);
1911 } else {
1912 if (sbt == VT_PTR) {
1913 /* cast from pointer to int before we apply
1914 shift operation, which pointers don't support*/
1915 gen_cast(&int_type);
1917 gv_dup();
1918 vpushi(31);
1919 gen_op(TOK_SAR);
1921 /* patch second register */
1922 vtop[-1].r2 = vtop->r;
1923 vpop();
1925 #else
1926 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1927 (dbt & VT_BTYPE) == VT_PTR ||
1928 (dbt & VT_BTYPE) == VT_FUNC) {
1929 if ((sbt & VT_BTYPE) != VT_LLONG &&
1930 (sbt & VT_BTYPE) != VT_PTR &&
1931 (sbt & VT_BTYPE) != VT_FUNC) {
1932 /* need to convert from 32bit to 64bit */
1933 int r = gv(RC_INT);
1934 if (sbt != (VT_INT | VT_UNSIGNED)) {
1935 /* x86_64 specific: movslq */
1936 o(0x6348);
1937 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1940 #endif
1941 } else if (dbt == VT_BOOL) {
1942 /* scalar to bool */
1943 vpushi(0);
1944 gen_op(TOK_NE);
1945 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1946 (dbt & VT_BTYPE) == VT_SHORT) {
1947 if (sbt == VT_PTR) {
1948 vtop->type.t = VT_INT;
1949 tcc_warning("nonportable conversion from pointer to char/short");
1951 force_charshort_cast(dbt);
1952 } else if ((dbt & VT_BTYPE) == VT_INT) {
1953 /* scalar to int */
1954 if (sbt == VT_LLONG) {
1955 /* from long long: just take low order word */
1956 lexpand();
1957 vpop();
1959 /* if lvalue and single word type, nothing to do because
1960 the lvalue already contains the real type size (see
1961 VT_LVAL_xxx constants) */
1964 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1965 /* if we are casting between pointer types,
1966 we must update the VT_LVAL_xxx size */
1967 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1968 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1970 vtop->type = *type;
1973 /* return type size as known at compile time. Put alignment at 'a' */
1974 ST_FUNC int type_size(CType *type, int *a)
1976 Sym *s;
1977 int bt;
1979 bt = type->t & VT_BTYPE;
1980 if (bt == VT_STRUCT) {
1981 /* struct/union */
1982 s = type->ref;
1983 *a = s->r;
1984 return s->c;
1985 } else if (bt == VT_PTR) {
1986 if (type->t & VT_ARRAY) {
1987 int ts;
1989 s = type->ref;
1990 ts = type_size(&s->type, a);
1992 if (ts < 0 && s->c < 0)
1993 ts = -ts;
1995 return ts * s->c;
1996 } else {
1997 *a = PTR_SIZE;
1998 return PTR_SIZE;
2000 } else if (bt == VT_LDOUBLE) {
2001 *a = LDOUBLE_ALIGN;
2002 return LDOUBLE_SIZE;
2003 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2004 #ifdef TCC_TARGET_I386
2005 #ifdef TCC_TARGET_PE
2006 *a = 8;
2007 #else
2008 *a = 4;
2009 #endif
2010 #elif defined(TCC_TARGET_ARM)
2011 #ifdef TCC_ARM_EABI
2012 *a = 8;
2013 #else
2014 *a = 4;
2015 #endif
2016 #else
2017 *a = 8;
2018 #endif
2019 return 8;
2020 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2021 *a = 4;
2022 return 4;
2023 } else if (bt == VT_SHORT) {
2024 *a = 2;
2025 return 2;
2026 } else {
2027 /* char, void, function, _Bool */
2028 *a = 1;
2029 return 1;
2033 /* push type size as known at runtime time on top of value stack. Put
2034 alignment at 'a' */
2035 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2037 if (type->t & VT_VLA) {
2038 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2039 } else {
2040 vpushi(type_size(type, a));
2044 /* return the pointed type of t */
2045 static inline CType *pointed_type(CType *type)
2047 return &type->ref->type;
2050 /* modify type so that its it is a pointer to type. */
2051 ST_FUNC void mk_pointer(CType *type)
2053 Sym *s;
2054 s = sym_push(SYM_FIELD, type, 0, -1);
2055 type->t = VT_PTR | (type->t & ~VT_TYPE);
2056 type->ref = s;
2059 /* compare function types. OLD functions match any new functions */
2060 static int is_compatible_func(CType *type1, CType *type2)
2062 Sym *s1, *s2;
2064 s1 = type1->ref;
2065 s2 = type2->ref;
2066 if (!is_compatible_types(&s1->type, &s2->type))
2067 return 0;
2068 /* check func_call */
2069 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2070 return 0;
2071 /* XXX: not complete */
2072 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2073 return 1;
2074 if (s1->c != s2->c)
2075 return 0;
2076 while (s1 != NULL) {
2077 if (s2 == NULL)
2078 return 0;
2079 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2080 return 0;
2081 s1 = s1->next;
2082 s2 = s2->next;
2084 if (s2)
2085 return 0;
2086 return 1;
2089 /* return true if type1 and type2 are the same. If unqualified is
2090 true, qualifiers on the types are ignored.
2092 - enums are not checked as gcc __builtin_types_compatible_p ()
2094 static int compare_types(CType *type1, CType *type2, int unqualified)
2096 int bt1, t1, t2;
2098 t1 = type1->t & VT_TYPE;
2099 t2 = type2->t & VT_TYPE;
2100 if (unqualified) {
2101 /* strip qualifiers before comparing */
2102 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2103 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2105 /* XXX: bitfields ? */
2106 if (t1 != t2)
2107 return 0;
2108 /* test more complicated cases */
2109 bt1 = t1 & VT_BTYPE;
2110 if (bt1 == VT_PTR) {
2111 type1 = pointed_type(type1);
2112 type2 = pointed_type(type2);
2113 return is_compatible_types(type1, type2);
2114 } else if (bt1 == VT_STRUCT) {
2115 return (type1->ref == type2->ref);
2116 } else if (bt1 == VT_FUNC) {
2117 return is_compatible_func(type1, type2);
2118 } else {
2119 return 1;
2123 /* return true if type1 and type2 are exactly the same (including
2124 qualifiers).
2126 static int is_compatible_types(CType *type1, CType *type2)
2128 return compare_types(type1,type2,0);
2131 /* return true if type1 and type2 are the same (ignoring qualifiers).
2133 static int is_compatible_parameter_types(CType *type1, CType *type2)
2135 return compare_types(type1,type2,1);
2138 /* print a type. If 'varstr' is not NULL, then the variable is also
2139 printed in the type */
2140 /* XXX: union */
2141 /* XXX: add array and function pointers */
2142 static void type_to_str(char *buf, int buf_size,
2143 CType *type, const char *varstr)
2145 int bt, v, t;
2146 Sym *s, *sa;
2147 char buf1[256];
2148 const char *tstr;
2150 t = type->t & VT_TYPE;
2151 bt = t & VT_BTYPE;
2152 buf[0] = '\0';
2153 if (t & VT_CONSTANT)
2154 pstrcat(buf, buf_size, "const ");
2155 if (t & VT_VOLATILE)
2156 pstrcat(buf, buf_size, "volatile ");
2157 if (t & VT_UNSIGNED)
2158 pstrcat(buf, buf_size, "unsigned ");
2159 switch(bt) {
2160 case VT_VOID:
2161 tstr = "void";
2162 goto add_tstr;
2163 case VT_BOOL:
2164 tstr = "_Bool";
2165 goto add_tstr;
2166 case VT_BYTE:
2167 tstr = "char";
2168 goto add_tstr;
2169 case VT_SHORT:
2170 tstr = "short";
2171 goto add_tstr;
2172 case VT_INT:
2173 tstr = "int";
2174 goto add_tstr;
2175 case VT_LONG:
2176 tstr = "long";
2177 goto add_tstr;
2178 case VT_LLONG:
2179 tstr = "long long";
2180 goto add_tstr;
2181 case VT_FLOAT:
2182 tstr = "float";
2183 goto add_tstr;
2184 case VT_DOUBLE:
2185 tstr = "double";
2186 goto add_tstr;
2187 case VT_LDOUBLE:
2188 tstr = "long double";
2189 add_tstr:
2190 pstrcat(buf, buf_size, tstr);
2191 break;
2192 case VT_ENUM:
2193 case VT_STRUCT:
2194 if (bt == VT_STRUCT)
2195 tstr = "struct ";
2196 else
2197 tstr = "enum ";
2198 pstrcat(buf, buf_size, tstr);
2199 v = type->ref->v & ~SYM_STRUCT;
2200 if (v >= SYM_FIRST_ANOM)
2201 pstrcat(buf, buf_size, "<anonymous>");
2202 else
2203 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2204 break;
2205 case VT_FUNC:
2206 s = type->ref;
2207 type_to_str(buf, buf_size, &s->type, varstr);
2208 pstrcat(buf, buf_size, "(");
2209 sa = s->next;
2210 while (sa != NULL) {
2211 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2212 pstrcat(buf, buf_size, buf1);
2213 sa = sa->next;
2214 if (sa)
2215 pstrcat(buf, buf_size, ", ");
2217 pstrcat(buf, buf_size, ")");
2218 goto no_var;
2219 case VT_PTR:
2220 s = type->ref;
2221 pstrcpy(buf1, sizeof(buf1), "*");
2222 if (varstr)
2223 pstrcat(buf1, sizeof(buf1), varstr);
2224 type_to_str(buf, buf_size, &s->type, buf1);
2225 goto no_var;
2227 if (varstr) {
2228 pstrcat(buf, buf_size, " ");
2229 pstrcat(buf, buf_size, varstr);
2231 no_var: ;
2234 /* verify type compatibility to store vtop in 'dt' type, and generate
2235 casts if needed. */
2236 static void gen_assign_cast(CType *dt)
2238 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2239 char buf1[256], buf2[256];
2240 int dbt, sbt;
2242 st = &vtop->type; /* source type */
2243 dbt = dt->t & VT_BTYPE;
2244 sbt = st->t & VT_BTYPE;
2245 if (sbt == VT_VOID)
2246 tcc_error("Cannot assign void value");
2247 if (dt->t & VT_CONSTANT)
2248 tcc_warning("assignment of read-only location");
2249 switch(dbt) {
2250 case VT_PTR:
2251 /* special cases for pointers */
2252 /* '0' can also be a pointer */
2253 if (is_null_pointer(vtop))
2254 goto type_ok;
2255 /* accept implicit pointer to integer cast with warning */
2256 if (is_integer_btype(sbt)) {
2257 tcc_warning("assignment makes pointer from integer without a cast");
2258 goto type_ok;
2260 type1 = pointed_type(dt);
2261 /* a function is implicitely a function pointer */
2262 if (sbt == VT_FUNC) {
2263 if ((type1->t & VT_BTYPE) != VT_VOID &&
2264 !is_compatible_types(pointed_type(dt), st))
2265 tcc_warning("assignment from incompatible pointer type");
2266 goto type_ok;
2268 if (sbt != VT_PTR)
2269 goto error;
2270 type2 = pointed_type(st);
2271 if ((type1->t & VT_BTYPE) == VT_VOID ||
2272 (type2->t & VT_BTYPE) == VT_VOID) {
2273 /* void * can match anything */
2274 } else {
2275 /* exact type match, except for unsigned */
2276 tmp_type1 = *type1;
2277 tmp_type2 = *type2;
2278 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2279 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2280 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2281 tcc_warning("assignment from incompatible pointer type");
2283 /* check const and volatile */
2284 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2285 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2286 tcc_warning("assignment discards qualifiers from pointer target type");
2287 break;
2288 case VT_BYTE:
2289 case VT_SHORT:
2290 case VT_INT:
2291 case VT_LLONG:
2292 if (sbt == VT_PTR || sbt == VT_FUNC) {
2293 tcc_warning("assignment makes integer from pointer without a cast");
2295 /* XXX: more tests */
2296 break;
2297 case VT_STRUCT:
2298 tmp_type1 = *dt;
2299 tmp_type2 = *st;
2300 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2301 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2302 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2303 error:
2304 type_to_str(buf1, sizeof(buf1), st, NULL);
2305 type_to_str(buf2, sizeof(buf2), dt, NULL);
2306 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2308 break;
2310 type_ok:
2311 gen_cast(dt);
2314 /* store vtop in lvalue pushed on stack */
2315 ST_FUNC void vstore(void)
2317 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2319 ft = vtop[-1].type.t;
2320 sbt = vtop->type.t & VT_BTYPE;
2321 dbt = ft & VT_BTYPE;
2322 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2323 (sbt == VT_INT && dbt == VT_SHORT)) {
2324 /* optimize char/short casts */
2325 delayed_cast = VT_MUSTCAST;
2326 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2327 /* XXX: factorize */
2328 if (ft & VT_CONSTANT)
2329 tcc_warning("assignment of read-only location");
2330 } else {
2331 delayed_cast = 0;
2332 if (!(ft & VT_BITFIELD))
2333 gen_assign_cast(&vtop[-1].type);
2336 if (sbt == VT_STRUCT) {
2337 /* if structure, only generate pointer */
2338 /* structure assignment : generate memcpy */
2339 /* XXX: optimize if small size */
2340 if (!nocode_wanted) {
2341 size = type_size(&vtop->type, &align);
2343 /* destination */
2344 vswap();
2345 vtop->type.t = VT_PTR;
2346 gaddrof();
2348 /* address of memcpy() */
2349 #ifdef TCC_ARM_EABI
2350 if(!(align & 7))
2351 vpush_global_sym(&func_old_type, TOK_memcpy8);
2352 else if(!(align & 3))
2353 vpush_global_sym(&func_old_type, TOK_memcpy4);
2354 else
2355 #endif
2356 vpush_global_sym(&func_old_type, TOK_memcpy);
2358 vswap();
2359 /* source */
2360 vpushv(vtop - 2);
2361 vtop->type.t = VT_PTR;
2362 gaddrof();
2363 /* type size */
2364 vpushi(size);
2365 gfunc_call(3);
2366 } else {
2367 vswap();
2368 vpop();
2370 /* leave source on stack */
2371 } else if (ft & VT_BITFIELD) {
2372 /* bitfield store handling */
2373 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2374 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2375 /* remove bit field info to avoid loops */
2376 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2378 /* duplicate source into other register */
2379 gv_dup();
2380 vswap();
2381 vrott(3);
2383 if((ft & VT_BTYPE) == VT_BOOL) {
2384 gen_cast(&vtop[-1].type);
2385 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2388 /* duplicate destination */
2389 vdup();
2390 vtop[-1] = vtop[-2];
2392 /* mask and shift source */
2393 if((ft & VT_BTYPE) != VT_BOOL) {
2394 if((ft & VT_BTYPE) == VT_LLONG) {
2395 vpushll((1ULL << bit_size) - 1ULL);
2396 } else {
2397 vpushi((1 << bit_size) - 1);
2399 gen_op('&');
2401 vpushi(bit_pos);
2402 gen_op(TOK_SHL);
2403 /* load destination, mask and or with source */
2404 vswap();
2405 if((ft & VT_BTYPE) == VT_LLONG) {
2406 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2407 } else {
2408 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2410 gen_op('&');
2411 gen_op('|');
2412 /* store result */
2413 vstore();
2415 /* pop off shifted source from "duplicate source..." above */
2416 vpop();
2418 } else {
2419 #ifdef CONFIG_TCC_BCHECK
2420 /* bound check case */
2421 if (vtop[-1].r & VT_MUSTBOUND) {
2422 vswap();
2423 gbound();
2424 vswap();
2426 #endif
2427 if (!nocode_wanted) {
2428 rc = RC_INT;
2429 if (is_float(ft)) {
2430 rc = RC_FLOAT;
2431 #ifdef TCC_TARGET_X86_64
2432 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2433 rc = RC_ST0;
2435 #endif
2437 r = gv(rc); /* generate value */
2438 /* if lvalue was saved on stack, must read it */
2439 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2440 SValue sv;
2441 t = get_reg(RC_INT);
2442 #ifdef TCC_TARGET_X86_64
2443 sv.type.t = VT_PTR;
2444 #else
2445 sv.type.t = VT_INT;
2446 #endif
2447 sv.r = VT_LOCAL | VT_LVAL;
2448 sv.c.ul = vtop[-1].c.ul;
2449 load(t, &sv);
2450 vtop[-1].r = t | VT_LVAL;
2452 store(r, vtop - 1);
2453 #ifndef TCC_TARGET_X86_64
2454 /* two word case handling : store second register at word + 4 */
2455 if ((ft & VT_BTYPE) == VT_LLONG) {
2456 vswap();
2457 /* convert to int to increment easily */
2458 vtop->type.t = VT_INT;
2459 gaddrof();
2460 vpushi(4);
2461 gen_op('+');
2462 vtop->r |= VT_LVAL;
2463 vswap();
2464 /* XXX: it works because r2 is spilled last ! */
2465 store(vtop->r2, vtop - 1);
2467 #endif
2469 vswap();
2470 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2471 vtop->r |= delayed_cast;
2475 /* post defines POST/PRE add. c is the token ++ or -- */
2476 ST_FUNC void inc(int post, int c)
2478 test_lvalue();
2479 vdup(); /* save lvalue */
2480 if (post) {
2481 gv_dup(); /* duplicate value */
2482 vrotb(3);
2483 vrotb(3);
2485 /* add constant */
2486 vpushi(c - TOK_MID);
2487 gen_op('+');
2488 vstore(); /* store value */
2489 if (post)
2490 vpop(); /* if post op, return saved value */
2493 /* Parse GNUC __attribute__ extension. Currently, the following
2494 extensions are recognized:
2495 - aligned(n) : set data/function alignment.
2496 - packed : force data alignment to 1
2497 - section(x) : generate data/code in this section.
2498 - unused : currently ignored, but may be used someday.
2499 - regparm(n) : pass function parameters in registers (i386 only)
2501 static void parse_attribute(AttributeDef *ad)
2503 int t, n;
2505 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2506 next();
2507 skip('(');
2508 skip('(');
2509 while (tok != ')') {
2510 if (tok < TOK_IDENT)
2511 expect("attribute name");
2512 t = tok;
2513 next();
2514 switch(t) {
2515 case TOK_SECTION1:
2516 case TOK_SECTION2:
2517 skip('(');
2518 if (tok != TOK_STR)
2519 expect("section name");
2520 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2521 next();
2522 skip(')');
2523 break;
2524 case TOK_ALIAS1:
2525 case TOK_ALIAS2:
2526 skip('(');
2527 if (tok != TOK_STR)
2528 expect("alias(\"target\")");
2529 ad->alias_target = /* save string as token, for later */
2530 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2531 next();
2532 skip(')');
2533 break;
2534 case TOK_ALIGNED1:
2535 case TOK_ALIGNED2:
2536 if (tok == '(') {
2537 next();
2538 n = expr_const();
2539 if (n <= 0 || (n & (n - 1)) != 0)
2540 tcc_error("alignment must be a positive power of two");
2541 skip(')');
2542 } else {
2543 n = MAX_ALIGN;
2545 ad->aligned = n;
2546 break;
2547 case TOK_PACKED1:
2548 case TOK_PACKED2:
2549 ad->packed = 1;
2550 break;
2551 case TOK_WEAK1:
2552 case TOK_WEAK2:
2553 ad->weak = 1;
2554 break;
2555 case TOK_UNUSED1:
2556 case TOK_UNUSED2:
2557 /* currently, no need to handle it because tcc does not
2558 track unused objects */
2559 break;
2560 case TOK_NORETURN1:
2561 case TOK_NORETURN2:
2562 /* currently, no need to handle it because tcc does not
2563 track unused objects */
2564 break;
2565 case TOK_CDECL1:
2566 case TOK_CDECL2:
2567 case TOK_CDECL3:
2568 ad->func_call = FUNC_CDECL;
2569 break;
2570 case TOK_STDCALL1:
2571 case TOK_STDCALL2:
2572 case TOK_STDCALL3:
2573 ad->func_call = FUNC_STDCALL;
2574 break;
2575 #ifdef TCC_TARGET_I386
2576 case TOK_REGPARM1:
2577 case TOK_REGPARM2:
2578 skip('(');
2579 n = expr_const();
2580 if (n > 3)
2581 n = 3;
2582 else if (n < 0)
2583 n = 0;
2584 if (n > 0)
2585 ad->func_call = FUNC_FASTCALL1 + n - 1;
2586 skip(')');
2587 break;
2588 case TOK_FASTCALL1:
2589 case TOK_FASTCALL2:
2590 case TOK_FASTCALL3:
2591 ad->func_call = FUNC_FASTCALLW;
2592 break;
2593 #endif
2594 case TOK_MODE:
2595 skip('(');
2596 switch(tok) {
2597 case TOK_MODE_DI:
2598 ad->mode = VT_LLONG + 1;
2599 break;
2600 case TOK_MODE_HI:
2601 ad->mode = VT_SHORT + 1;
2602 break;
2603 case TOK_MODE_SI:
2604 ad->mode = VT_INT + 1;
2605 break;
2606 default:
2607 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2608 break;
2610 next();
2611 skip(')');
2612 break;
2613 case TOK_DLLEXPORT:
2614 ad->func_export = 1;
2615 break;
2616 case TOK_DLLIMPORT:
2617 ad->func_import = 1;
2618 break;
2619 default:
2620 if (tcc_state->warn_unsupported)
2621 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2622 /* skip parameters */
2623 if (tok == '(') {
2624 int parenthesis = 0;
2625 do {
2626 if (tok == '(')
2627 parenthesis++;
2628 else if (tok == ')')
2629 parenthesis--;
2630 next();
2631 } while (parenthesis && tok != -1);
2633 break;
2635 if (tok != ',')
2636 break;
2637 next();
2639 skip(')');
2640 skip(')');
2644 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2645 static void struct_decl(CType *type, int u)
2647 int a, v, size, align, maxalign, c, offset;
2648 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2649 Sym *s, *ss, *ass, **ps;
2650 AttributeDef ad;
2651 CType type1, btype;
2653 a = tok; /* save decl type */
2654 next();
2655 if (tok != '{') {
2656 v = tok;
2657 next();
2658 /* struct already defined ? return it */
2659 if (v < TOK_IDENT)
2660 expect("struct/union/enum name");
2661 s = struct_find(v);
2662 if (s) {
2663 if (s->type.t != a)
2664 tcc_error("invalid type");
2665 goto do_decl;
2667 } else {
2668 v = anon_sym++;
2670 type1.t = a;
2671 /* we put an undefined size for struct/union */
2672 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2673 s->r = 0; /* default alignment is zero as gcc */
2674 /* put struct/union/enum name in type */
2675 do_decl:
2676 type->t = u;
2677 type->ref = s;
2679 if (tok == '{') {
2680 next();
2681 if (s->c != -1)
2682 tcc_error("struct/union/enum already defined");
2683 /* cannot be empty */
2684 c = 0;
2685 /* non empty enums are not allowed */
2686 if (a == TOK_ENUM) {
2687 for(;;) {
2688 v = tok;
2689 if (v < TOK_UIDENT)
2690 expect("identifier");
2691 next();
2692 if (tok == '=') {
2693 next();
2694 c = expr_const();
2696 /* enum symbols have static storage */
2697 ss = sym_push(v, &int_type, VT_CONST, c);
2698 ss->type.t |= VT_STATIC;
2699 if (tok != ',')
2700 break;
2701 next();
2702 c++;
2703 /* NOTE: we accept a trailing comma */
2704 if (tok == '}')
2705 break;
2707 skip('}');
2708 } else {
2709 maxalign = 1;
2710 ps = &s->next;
2711 prevbt = VT_INT;
2712 bit_pos = 0;
2713 offset = 0;
2714 while (tok != '}') {
2715 parse_btype(&btype, &ad);
2716 while (1) {
2717 bit_size = -1;
2718 v = 0;
2719 type1 = btype;
2720 if (tok != ':') {
2721 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2722 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2723 expect("identifier");
2724 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2725 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2726 tcc_error("invalid type for '%s'",
2727 get_tok_str(v, NULL));
2729 if (tok == ':') {
2730 next();
2731 bit_size = expr_const();
2732 /* XXX: handle v = 0 case for messages */
2733 if (bit_size < 0)
2734 tcc_error("negative width in bit-field '%s'",
2735 get_tok_str(v, NULL));
2736 if (v && bit_size == 0)
2737 tcc_error("zero width for bit-field '%s'",
2738 get_tok_str(v, NULL));
2740 size = type_size(&type1, &align);
2741 if (ad.aligned) {
2742 if (align < ad.aligned)
2743 align = ad.aligned;
2744 } else if (ad.packed) {
2745 align = 1;
2746 } else if (*tcc_state->pack_stack_ptr) {
2747 if (align > *tcc_state->pack_stack_ptr)
2748 align = *tcc_state->pack_stack_ptr;
2750 lbit_pos = 0;
2751 if (bit_size >= 0) {
2752 bt = type1.t & VT_BTYPE;
2753 if (bt != VT_INT &&
2754 bt != VT_BYTE &&
2755 bt != VT_SHORT &&
2756 bt != VT_BOOL &&
2757 bt != VT_ENUM &&
2758 bt != VT_LLONG)
2759 tcc_error("bitfields must have scalar type");
2760 bsize = size * 8;
2761 if (bit_size > bsize) {
2762 tcc_error("width of '%s' exceeds its type",
2763 get_tok_str(v, NULL));
2764 } else if (bit_size == bsize) {
2765 /* no need for bit fields */
2766 bit_pos = 0;
2767 } else if (bit_size == 0) {
2768 /* XXX: what to do if only padding in a
2769 structure ? */
2770 /* zero size: means to pad */
2771 bit_pos = 0;
2772 } else {
2773 /* we do not have enough room ?
2774 did the type change?
2775 is it a union? */
2776 if ((bit_pos + bit_size) > bsize ||
2777 bt != prevbt || a == TOK_UNION)
2778 bit_pos = 0;
2779 lbit_pos = bit_pos;
2780 /* XXX: handle LSB first */
2781 type1.t |= VT_BITFIELD |
2782 (bit_pos << VT_STRUCT_SHIFT) |
2783 (bit_size << (VT_STRUCT_SHIFT + 6));
2784 bit_pos += bit_size;
2786 prevbt = bt;
2787 } else {
2788 bit_pos = 0;
2790 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2791 /* add new memory data only if starting
2792 bit field */
2793 if (lbit_pos == 0) {
2794 if (a == TOK_STRUCT) {
2795 c = (c + align - 1) & -align;
2796 offset = c;
2797 if (size > 0)
2798 c += size;
2799 } else {
2800 offset = 0;
2801 if (size > c)
2802 c = size;
2804 if (align > maxalign)
2805 maxalign = align;
2807 #if 0
2808 printf("add field %s offset=%d",
2809 get_tok_str(v, NULL), offset);
2810 if (type1.t & VT_BITFIELD) {
2811 printf(" pos=%d size=%d",
2812 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2813 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2815 printf("\n");
2816 #endif
2818 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2819 ass = type1.ref;
2820 while ((ass = ass->next) != NULL) {
2821 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2822 *ps = ss;
2823 ps = &ss->next;
2825 } else if (v) {
2826 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2827 *ps = ss;
2828 ps = &ss->next;
2830 if (tok == ';' || tok == TOK_EOF)
2831 break;
2832 skip(',');
2834 skip(';');
2836 skip('}');
2837 /* store size and alignment */
2838 s->c = (c + maxalign - 1) & -maxalign;
2839 s->r = maxalign;
2844 /* return 0 if no type declaration. otherwise, return the basic type
2845 and skip it.
2847 static int parse_btype(CType *type, AttributeDef *ad)
2849 int t, u, type_found, typespec_found, typedef_found;
2850 Sym *s;
2851 CType type1;
2853 memset(ad, 0, sizeof(AttributeDef));
2854 type_found = 0;
2855 typespec_found = 0;
2856 typedef_found = 0;
2857 t = 0;
2858 while(1) {
2859 switch(tok) {
2860 case TOK_EXTENSION:
2861 /* currently, we really ignore extension */
2862 next();
2863 continue;
2865 /* basic types */
2866 case TOK_CHAR:
2867 u = VT_BYTE;
2868 basic_type:
2869 next();
2870 basic_type1:
2871 if ((t & VT_BTYPE) != 0)
2872 tcc_error("too many basic types");
2873 t |= u;
2874 typespec_found = 1;
2875 break;
2876 case TOK_VOID:
2877 u = VT_VOID;
2878 goto basic_type;
2879 case TOK_SHORT:
2880 u = VT_SHORT;
2881 goto basic_type;
2882 case TOK_INT:
2883 next();
2884 typespec_found = 1;
2885 break;
2886 case TOK_LONG:
2887 next();
2888 if ((t & VT_BTYPE) == VT_DOUBLE) {
2889 #ifndef TCC_TARGET_PE
2890 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2891 #endif
2892 } else if ((t & VT_BTYPE) == VT_LONG) {
2893 t = (t & ~VT_BTYPE) | VT_LLONG;
2894 } else {
2895 u = VT_LONG;
2896 goto basic_type1;
2898 break;
2899 case TOK_BOOL:
2900 u = VT_BOOL;
2901 goto basic_type;
2902 case TOK_FLOAT:
2903 u = VT_FLOAT;
2904 goto basic_type;
2905 case TOK_DOUBLE:
2906 next();
2907 if ((t & VT_BTYPE) == VT_LONG) {
2908 #ifdef TCC_TARGET_PE
2909 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2910 #else
2911 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2912 #endif
2913 } else {
2914 u = VT_DOUBLE;
2915 goto basic_type1;
2917 break;
2918 case TOK_ENUM:
2919 struct_decl(&type1, VT_ENUM);
2920 basic_type2:
2921 u = type1.t;
2922 type->ref = type1.ref;
2923 goto basic_type1;
2924 case TOK_STRUCT:
2925 case TOK_UNION:
2926 struct_decl(&type1, VT_STRUCT);
2927 goto basic_type2;
2929 /* type modifiers */
2930 case TOK_CONST1:
2931 case TOK_CONST2:
2932 case TOK_CONST3:
2933 t |= VT_CONSTANT;
2934 next();
2935 break;
2936 case TOK_VOLATILE1:
2937 case TOK_VOLATILE2:
2938 case TOK_VOLATILE3:
2939 t |= VT_VOLATILE;
2940 next();
2941 break;
2942 case TOK_SIGNED1:
2943 case TOK_SIGNED2:
2944 case TOK_SIGNED3:
2945 typespec_found = 1;
2946 t |= VT_SIGNED;
2947 next();
2948 break;
2949 case TOK_REGISTER:
2950 case TOK_AUTO:
2951 case TOK_RESTRICT1:
2952 case TOK_RESTRICT2:
2953 case TOK_RESTRICT3:
2954 next();
2955 break;
2956 case TOK_UNSIGNED:
2957 t |= VT_UNSIGNED;
2958 next();
2959 typespec_found = 1;
2960 break;
2962 /* storage */
2963 case TOK_EXTERN:
2964 t |= VT_EXTERN;
2965 next();
2966 break;
2967 case TOK_STATIC:
2968 t |= VT_STATIC;
2969 next();
2970 break;
2971 case TOK_TYPEDEF:
2972 t |= VT_TYPEDEF;
2973 next();
2974 break;
2975 case TOK_INLINE1:
2976 case TOK_INLINE2:
2977 case TOK_INLINE3:
2978 t |= VT_INLINE;
2979 next();
2980 break;
2982 /* GNUC attribute */
2983 case TOK_ATTRIBUTE1:
2984 case TOK_ATTRIBUTE2:
2985 parse_attribute(ad);
2986 if (ad->mode) {
2987 u = ad->mode -1;
2988 t = (t & ~VT_BTYPE) | u;
2990 break;
2991 /* GNUC typeof */
2992 case TOK_TYPEOF1:
2993 case TOK_TYPEOF2:
2994 case TOK_TYPEOF3:
2995 next();
2996 parse_expr_type(&type1);
2997 /* remove all storage modifiers except typedef */
2998 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
2999 goto basic_type2;
3000 default:
3001 if (typespec_found || typedef_found)
3002 goto the_end;
3003 s = sym_find(tok);
3004 if (!s || !(s->type.t & VT_TYPEDEF))
3005 goto the_end;
3006 typedef_found = 1;
3007 t |= (s->type.t & ~VT_TYPEDEF);
3008 type->ref = s->type.ref;
3009 if (s->r) {
3010 /* get attributes from typedef */
3011 if (0 == ad->aligned)
3012 ad->aligned = FUNC_ALIGN(s->r);
3013 if (0 == ad->func_call)
3014 ad->func_call = FUNC_CALL(s->r);
3015 ad->packed |= FUNC_PACKED(s->r);
3017 next();
3018 typespec_found = 1;
3019 break;
3021 type_found = 1;
3023 the_end:
3024 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3025 tcc_error("signed and unsigned modifier");
3026 if (tcc_state->char_is_unsigned) {
3027 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3028 t |= VT_UNSIGNED;
3030 t &= ~VT_SIGNED;
3032 /* long is never used as type */
3033 if ((t & VT_BTYPE) == VT_LONG)
3034 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3035 t = (t & ~VT_BTYPE) | VT_INT;
3036 #else
3037 t = (t & ~VT_BTYPE) | VT_LLONG;
3038 #endif
3039 type->t = t;
3040 return type_found;
3043 /* convert a function parameter type (array to pointer and function to
3044 function pointer) */
3045 static inline void convert_parameter_type(CType *pt)
3047 /* remove const and volatile qualifiers (XXX: const could be used
3048 to indicate a const function parameter */
3049 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3050 /* array must be transformed to pointer according to ANSI C */
3051 pt->t &= ~VT_ARRAY;
3052 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3053 mk_pointer(pt);
3057 ST_FUNC void parse_asm_str(CString *astr)
3059 skip('(');
3060 /* read the string */
3061 if (tok != TOK_STR)
3062 expect("string constant");
3063 cstr_new(astr);
3064 while (tok == TOK_STR) {
3065 /* XXX: add \0 handling too ? */
3066 cstr_cat(astr, tokc.cstr->data);
3067 next();
3069 cstr_ccat(astr, '\0');
3072 /* Parse an asm label and return the label
3073 * Don't forget to free the CString in the caller! */
3074 static void asm_label_instr(CString *astr)
3076 next();
3077 parse_asm_str(astr);
3078 skip(')');
3079 #ifdef ASM_DEBUG
3080 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3081 #endif
3084 static void post_type(CType *type, AttributeDef *ad)
3086 int n, l, t1, arg_size, align;
3087 Sym **plast, *s, *first;
3088 AttributeDef ad1;
3089 CType pt;
3091 if (tok == '(') {
3092 /* function declaration */
3093 next();
3094 l = 0;
3095 first = NULL;
3096 plast = &first;
3097 arg_size = 0;
3098 if (tok != ')') {
3099 for(;;) {
3100 /* read param name and compute offset */
3101 if (l != FUNC_OLD) {
3102 if (!parse_btype(&pt, &ad1)) {
3103 if (l) {
3104 tcc_error("invalid type");
3105 } else {
3106 l = FUNC_OLD;
3107 goto old_proto;
3110 l = FUNC_NEW;
3111 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3112 break;
3113 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3114 if ((pt.t & VT_BTYPE) == VT_VOID)
3115 tcc_error("parameter declared as void");
3116 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3117 } else {
3118 old_proto:
3119 n = tok;
3120 if (n < TOK_UIDENT)
3121 expect("identifier");
3122 pt.t = VT_INT;
3123 next();
3125 convert_parameter_type(&pt);
3126 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3127 *plast = s;
3128 plast = &s->next;
3129 if (tok == ')')
3130 break;
3131 skip(',');
3132 if (l == FUNC_NEW && tok == TOK_DOTS) {
3133 l = FUNC_ELLIPSIS;
3134 next();
3135 break;
3139 /* if no parameters, then old type prototype */
3140 if (l == 0)
3141 l = FUNC_OLD;
3142 skip(')');
3143 /* NOTE: const is ignored in returned type as it has a special
3144 meaning in gcc / C++ */
3145 type->t &= ~VT_CONSTANT;
3146 /* some ancient pre-K&R C allows a function to return an array
3147 and the array brackets to be put after the arguments, such
3148 that "int c()[]" means something like "int[] c()" */
3149 if (tok == '[') {
3150 next();
3151 skip(']'); /* only handle simple "[]" */
3152 type->t |= VT_PTR;
3154 /* we push a anonymous symbol which will contain the function prototype */
3155 ad->func_args = arg_size;
3156 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3157 s->next = first;
3158 type->t = VT_FUNC;
3159 type->ref = s;
3160 } else if (tok == '[') {
3161 /* array definition */
3162 next();
3163 if (tok == TOK_RESTRICT1)
3164 next();
3165 n = -1;
3166 t1 = 0;
3167 if (tok != ']') {
3168 if (!local_stack || nocode_wanted)
3169 vpushi(expr_const());
3170 else gexpr();
3171 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3172 n = vtop->c.i;
3173 if (n < 0)
3174 tcc_error("invalid array size");
3175 } else {
3176 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3177 tcc_error("size of variable length array should be an integer");
3178 t1 = VT_VLA;
3181 skip(']');
3182 /* parse next post type */
3183 post_type(type, ad);
3184 t1 |= type->t & VT_VLA;
3186 if (t1 & VT_VLA) {
3187 loc -= type_size(&int_type, &align);
3188 loc &= -align;
3189 n = loc;
3191 vla_runtime_type_size(type, &align);
3192 gen_op('*');
3193 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3194 vswap();
3195 vstore();
3197 if (n != -1)
3198 vpop();
3200 /* we push an anonymous symbol which will contain the array
3201 element type */
3202 s = sym_push(SYM_FIELD, type, 0, n);
3203 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3204 type->ref = s;
3208 /* Parse a type declaration (except basic type), and return the type
3209 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3210 expected. 'type' should contain the basic type. 'ad' is the
3211 attribute definition of the basic type. It can be modified by
3212 type_decl().
3214 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3216 Sym *s;
3217 CType type1, *type2;
3218 int qualifiers, storage;
3220 while (tok == '*') {
3221 qualifiers = 0;
3222 redo:
3223 next();
3224 switch(tok) {
3225 case TOK_CONST1:
3226 case TOK_CONST2:
3227 case TOK_CONST3:
3228 qualifiers |= VT_CONSTANT;
3229 goto redo;
3230 case TOK_VOLATILE1:
3231 case TOK_VOLATILE2:
3232 case TOK_VOLATILE3:
3233 qualifiers |= VT_VOLATILE;
3234 goto redo;
3235 case TOK_RESTRICT1:
3236 case TOK_RESTRICT2:
3237 case TOK_RESTRICT3:
3238 goto redo;
3240 mk_pointer(type);
3241 type->t |= qualifiers;
3244 /* XXX: clarify attribute handling */
3245 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3246 parse_attribute(ad);
3248 /* recursive type */
3249 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3250 type1.t = 0; /* XXX: same as int */
3251 if (tok == '(') {
3252 next();
3253 /* XXX: this is not correct to modify 'ad' at this point, but
3254 the syntax is not clear */
3255 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3256 parse_attribute(ad);
3257 type_decl(&type1, ad, v, td);
3258 skip(')');
3259 } else {
3260 /* type identifier */
3261 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3262 *v = tok;
3263 next();
3264 } else {
3265 if (!(td & TYPE_ABSTRACT))
3266 expect("identifier");
3267 *v = 0;
3270 storage = type->t & VT_STORAGE;
3271 type->t &= ~VT_STORAGE;
3272 post_type(type, ad);
3273 type->t |= storage;
3274 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3275 parse_attribute(ad);
3277 if (!type1.t)
3278 return;
3279 /* append type at the end of type1 */
3280 type2 = &type1;
3281 for(;;) {
3282 s = type2->ref;
3283 type2 = &s->type;
3284 if (!type2->t) {
3285 *type2 = *type;
3286 break;
3289 *type = type1;
3292 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3293 ST_FUNC int lvalue_type(int t)
3295 int bt, r;
3296 r = VT_LVAL;
3297 bt = t & VT_BTYPE;
3298 if (bt == VT_BYTE || bt == VT_BOOL)
3299 r |= VT_LVAL_BYTE;
3300 else if (bt == VT_SHORT)
3301 r |= VT_LVAL_SHORT;
3302 else
3303 return r;
3304 if (t & VT_UNSIGNED)
3305 r |= VT_LVAL_UNSIGNED;
3306 return r;
3309 /* indirection with full error checking and bound check */
3310 ST_FUNC void indir(void)
3312 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3313 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3314 return;
3315 expect("pointer");
3317 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3318 gv(RC_INT);
3319 vtop->type = *pointed_type(&vtop->type);
3320 /* Arrays and functions are never lvalues */
3321 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3322 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3323 vtop->r |= lvalue_type(vtop->type.t);
3324 /* if bound checking, the referenced pointer must be checked */
3325 #ifdef CONFIG_TCC_BCHECK
3326 if (tcc_state->do_bounds_check)
3327 vtop->r |= VT_MUSTBOUND;
3328 #endif
3332 /* pass a parameter to a function and do type checking and casting */
3333 static void gfunc_param_typed(Sym *func, Sym *arg)
3335 int func_type;
3336 CType type;
3338 func_type = func->c;
3339 if (func_type == FUNC_OLD ||
3340 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3341 /* default casting : only need to convert float to double */
3342 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3343 type.t = VT_DOUBLE;
3344 gen_cast(&type);
3346 } else if (arg == NULL) {
3347 tcc_error("too many arguments to function");
3348 } else {
3349 type = arg->type;
3350 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3351 gen_assign_cast(&type);
3355 /* parse an expression of the form '(type)' or '(expr)' and return its
3356 type */
3357 static void parse_expr_type(CType *type)
3359 int n;
3360 AttributeDef ad;
3362 skip('(');
3363 if (parse_btype(type, &ad)) {
3364 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3365 } else {
3366 expr_type(type);
3368 skip(')');
3371 static void parse_type(CType *type)
3373 AttributeDef ad;
3374 int n;
3376 if (!parse_btype(type, &ad)) {
3377 expect("type");
3379 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3382 static void vpush_tokc(int t)
3384 CType type;
3385 type.t = t;
3386 type.ref = 0;
3387 vsetc(&type, VT_CONST, &tokc);
3390 ST_FUNC void unary(void)
3392 int n, t, align, size, r, sizeof_caller;
3393 CType type;
3394 Sym *s;
3395 AttributeDef ad;
3396 static int in_sizeof = 0;
3398 sizeof_caller = in_sizeof;
3399 in_sizeof = 0;
3400 /* XXX: GCC 2.95.3 does not generate a table although it should be
3401 better here */
3402 tok_next:
3403 switch(tok) {
3404 case TOK_EXTENSION:
3405 next();
3406 goto tok_next;
3407 case TOK_CINT:
3408 case TOK_CCHAR:
3409 case TOK_LCHAR:
3410 vpushi(tokc.i);
3411 next();
3412 break;
3413 case TOK_CUINT:
3414 vpush_tokc(VT_INT | VT_UNSIGNED);
3415 next();
3416 break;
3417 case TOK_CLLONG:
3418 vpush_tokc(VT_LLONG);
3419 next();
3420 break;
3421 case TOK_CULLONG:
3422 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3423 next();
3424 break;
3425 case TOK_CFLOAT:
3426 vpush_tokc(VT_FLOAT);
3427 next();
3428 break;
3429 case TOK_CDOUBLE:
3430 vpush_tokc(VT_DOUBLE);
3431 next();
3432 break;
3433 case TOK_CLDOUBLE:
3434 vpush_tokc(VT_LDOUBLE);
3435 next();
3436 break;
3437 case TOK___FUNCTION__:
3438 if (!gnu_ext)
3439 goto tok_identifier;
3440 /* fall thru */
3441 case TOK___FUNC__:
3443 void *ptr;
3444 int len;
3445 /* special function name identifier */
3446 len = strlen(funcname) + 1;
3447 /* generate char[len] type */
3448 type.t = VT_BYTE;
3449 mk_pointer(&type);
3450 type.t |= VT_ARRAY;
3451 type.ref->c = len;
3452 vpush_ref(&type, data_section, data_section->data_offset, len);
3453 ptr = section_ptr_add(data_section, len);
3454 memcpy(ptr, funcname, len);
3455 next();
3457 break;
3458 case TOK_LSTR:
3459 #ifdef TCC_TARGET_PE
3460 t = VT_SHORT | VT_UNSIGNED;
3461 #else
3462 t = VT_INT;
3463 #endif
3464 goto str_init;
3465 case TOK_STR:
3466 /* string parsing */
3467 t = VT_BYTE;
3468 str_init:
3469 if (tcc_state->warn_write_strings)
3470 t |= VT_CONSTANT;
3471 type.t = t;
3472 mk_pointer(&type);
3473 type.t |= VT_ARRAY;
3474 memset(&ad, 0, sizeof(AttributeDef));
3475 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3476 break;
3477 case '(':
3478 next();
3479 /* cast ? */
3480 if (parse_btype(&type, &ad)) {
3481 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3482 skip(')');
3483 /* check ISOC99 compound literal */
3484 if (tok == '{') {
3485 /* data is allocated locally by default */
3486 if (global_expr)
3487 r = VT_CONST;
3488 else
3489 r = VT_LOCAL;
3490 /* all except arrays are lvalues */
3491 if (!(type.t & VT_ARRAY))
3492 r |= lvalue_type(type.t);
3493 memset(&ad, 0, sizeof(AttributeDef));
3494 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3495 } else {
3496 if (sizeof_caller) {
3497 vpush(&type);
3498 return;
3500 unary();
3501 gen_cast(&type);
3503 } else if (tok == '{') {
3504 /* save all registers */
3505 save_regs(0);
3506 /* statement expression : we do not accept break/continue
3507 inside as GCC does */
3508 block(NULL, NULL, NULL, NULL, 0, 1);
3509 skip(')');
3510 } else {
3511 gexpr();
3512 skip(')');
3514 break;
3515 case '*':
3516 next();
3517 unary();
3518 indir();
3519 break;
3520 case '&':
3521 next();
3522 unary();
3523 /* functions names must be treated as function pointers,
3524 except for unary '&' and sizeof. Since we consider that
3525 functions are not lvalues, we only have to handle it
3526 there and in function calls. */
3527 /* arrays can also be used although they are not lvalues */
3528 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3529 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3530 test_lvalue();
3531 mk_pointer(&vtop->type);
3532 gaddrof();
3533 break;
3534 case '!':
3535 next();
3536 unary();
3537 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3538 CType boolean;
3539 boolean.t = VT_BOOL;
3540 gen_cast(&boolean);
3541 vtop->c.i = !vtop->c.i;
3542 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3543 vtop->c.i = vtop->c.i ^ 1;
3544 else {
3545 save_regs(1);
3546 vseti(VT_JMP, gtst(1, 0));
3548 break;
3549 case '~':
3550 next();
3551 unary();
3552 vpushi(-1);
3553 gen_op('^');
3554 break;
3555 case '+':
3556 next();
3557 /* in order to force cast, we add zero */
3558 unary();
3559 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3560 tcc_error("pointer not accepted for unary plus");
3561 vpushi(0);
3562 gen_op('+');
3563 break;
3564 case TOK_SIZEOF:
3565 case TOK_ALIGNOF1:
3566 case TOK_ALIGNOF2:
3567 t = tok;
3568 next();
3569 in_sizeof++;
3570 unary_type(&type); // Perform a in_sizeof = 0;
3571 size = type_size(&type, &align);
3572 if (t == TOK_SIZEOF) {
3573 if (!(type.t & VT_VLA)) {
3574 if (size < 0)
3575 tcc_error("sizeof applied to an incomplete type");
3576 vpushi(size);
3577 } else {
3578 vla_runtime_type_size(&type, &align);
3580 } else {
3581 vpushi(align);
3583 vtop->type.t |= VT_UNSIGNED;
3584 break;
3586 case TOK_builtin_types_compatible_p:
3588 CType type1, type2;
3589 next();
3590 skip('(');
3591 parse_type(&type1);
3592 skip(',');
3593 parse_type(&type2);
3594 skip(')');
3595 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3596 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3597 vpushi(is_compatible_types(&type1, &type2));
3599 break;
3600 case TOK_builtin_constant_p:
3602 int saved_nocode_wanted, res;
3603 next();
3604 skip('(');
3605 saved_nocode_wanted = nocode_wanted;
3606 nocode_wanted = 1;
3607 gexpr();
3608 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3609 vpop();
3610 nocode_wanted = saved_nocode_wanted;
3611 skip(')');
3612 vpushi(res);
3614 break;
3615 case TOK_builtin_frame_address:
3617 CType type;
3618 next();
3619 skip('(');
3620 if (tok != TOK_CINT) {
3621 tcc_error("__builtin_frame_address only takes integers");
3623 if (tokc.i != 0) {
3624 tcc_error("TCC only supports __builtin_frame_address(0)");
3626 next();
3627 skip(')');
3628 type.t = VT_VOID;
3629 mk_pointer(&type);
3630 vset(&type, VT_LOCAL, 0);
3632 break;
3633 #ifdef TCC_TARGET_X86_64
3634 case TOK_builtin_va_arg_types:
3636 /* This definition must be synced with stdarg.h */
3637 enum __va_arg_type {
3638 __va_gen_reg, __va_float_reg, __va_stack
3640 CType type;
3641 int bt;
3642 next();
3643 skip('(');
3644 parse_type(&type);
3645 skip(')');
3646 bt = type.t & VT_BTYPE;
3647 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3648 vpushi(__va_stack);
3649 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3650 vpushi(__va_float_reg);
3651 } else {
3652 vpushi(__va_gen_reg);
3655 break;
3656 #endif
3657 case TOK_INC:
3658 case TOK_DEC:
3659 t = tok;
3660 next();
3661 unary();
3662 inc(0, t);
3663 break;
3664 case '-':
3665 next();
3666 vpushi(0);
3667 unary();
3668 gen_op('-');
3669 break;
3670 case TOK_LAND:
3671 if (!gnu_ext)
3672 goto tok_identifier;
3673 next();
3674 /* allow to take the address of a label */
3675 if (tok < TOK_UIDENT)
3676 expect("label identifier");
3677 s = label_find(tok);
3678 if (!s) {
3679 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3680 } else {
3681 if (s->r == LABEL_DECLARED)
3682 s->r = LABEL_FORWARD;
3684 if (!s->type.t) {
3685 s->type.t = VT_VOID;
3686 mk_pointer(&s->type);
3687 s->type.t |= VT_STATIC;
3689 vset(&s->type, VT_CONST | VT_SYM, 0);
3690 vtop->sym = s;
3691 next();
3692 break;
3694 // special qnan , snan and infinity values
3695 case TOK___NAN__:
3696 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3697 next();
3698 break;
3699 case TOK___SNAN__:
3700 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3701 next();
3702 break;
3703 case TOK___INF__:
3704 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3705 next();
3706 break;
3708 default:
3709 tok_identifier:
3710 t = tok;
3711 next();
3712 if (t < TOK_UIDENT)
3713 expect("identifier");
3714 s = sym_find(t);
3715 if (!s) {
3716 if (tok != '(')
3717 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
3718 /* for simple function calls, we tolerate undeclared
3719 external reference to int() function */
3720 if (tcc_state->warn_implicit_function_declaration)
3721 tcc_warning("implicit declaration of function '%s'",
3722 get_tok_str(t, NULL));
3723 s = external_global_sym(t, &func_old_type, 0);
3725 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3726 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3727 /* if referencing an inline function, then we generate a
3728 symbol to it if not already done. It will have the
3729 effect to generate code for it at the end of the
3730 compilation unit. Inline function as always
3731 generated in the text section. */
3732 if (!s->c)
3733 put_extern_sym(s, text_section, 0, 0);
3734 r = VT_SYM | VT_CONST;
3735 } else {
3736 r = s->r;
3738 vset(&s->type, r, s->c);
3739 /* if forward reference, we must point to s */
3740 if (vtop->r & VT_SYM) {
3741 vtop->sym = s;
3742 vtop->c.ul = 0;
3744 break;
3747 /* post operations */
3748 while (1) {
3749 if (tok == TOK_INC || tok == TOK_DEC) {
3750 inc(1, tok);
3751 next();
3752 } else if (tok == '.' || tok == TOK_ARROW) {
3753 int qualifiers;
3754 /* field */
3755 if (tok == TOK_ARROW)
3756 indir();
3757 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3758 test_lvalue();
3759 gaddrof();
3760 next();
3761 /* expect pointer on structure */
3762 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3763 expect("struct or union");
3764 s = vtop->type.ref;
3765 /* find field */
3766 tok |= SYM_FIELD;
3767 while ((s = s->next) != NULL) {
3768 if (s->v == tok)
3769 break;
3771 if (!s)
3772 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3773 /* add field offset to pointer */
3774 vtop->type = char_pointer_type; /* change type to 'char *' */
3775 vpushi(s->c);
3776 gen_op('+');
3777 /* change type to field type, and set to lvalue */
3778 vtop->type = s->type;
3779 vtop->type.t |= qualifiers;
3780 /* an array is never an lvalue */
3781 if (!(vtop->type.t & VT_ARRAY)) {
3782 vtop->r |= lvalue_type(vtop->type.t);
3783 #ifdef CONFIG_TCC_BCHECK
3784 /* if bound checking, the referenced pointer must be checked */
3785 if (tcc_state->do_bounds_check)
3786 vtop->r |= VT_MUSTBOUND;
3787 #endif
3789 next();
3790 } else if (tok == '[') {
3791 next();
3792 gexpr();
3793 gen_op('+');
3794 indir();
3795 skip(']');
3796 } else if (tok == '(') {
3797 SValue ret;
3798 Sym *sa;
3799 int nb_args;
3801 /* function call */
3802 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3803 /* pointer test (no array accepted) */
3804 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3805 vtop->type = *pointed_type(&vtop->type);
3806 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3807 goto error_func;
3808 } else {
3809 error_func:
3810 expect("function pointer");
3812 } else {
3813 vtop->r &= ~VT_LVAL; /* no lvalue */
3815 /* get return type */
3816 s = vtop->type.ref;
3817 next();
3818 sa = s->next; /* first parameter */
3819 nb_args = 0;
3820 ret.r2 = VT_CONST;
3821 /* compute first implicit argument if a structure is returned */
3822 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3823 /* get some space for the returned structure */
3824 size = type_size(&s->type, &align);
3825 loc = (loc - size) & -align;
3826 ret.type = s->type;
3827 ret.r = VT_LOCAL | VT_LVAL;
3828 /* pass it as 'int' to avoid structure arg passing
3829 problems */
3830 vseti(VT_LOCAL, loc);
3831 ret.c = vtop->c;
3832 nb_args++;
3833 } else {
3834 ret.type = s->type;
3835 /* return in register */
3836 if (is_float(ret.type.t)) {
3837 ret.r = reg_fret(ret.type.t);
3838 } else {
3839 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3840 ret.r2 = REG_LRET;
3841 ret.r = REG_IRET;
3843 ret.c.i = 0;
3845 if (tok != ')') {
3846 for(;;) {
3847 expr_eq();
3848 gfunc_param_typed(s, sa);
3849 nb_args++;
3850 if (sa)
3851 sa = sa->next;
3852 if (tok == ')')
3853 break;
3854 skip(',');
3857 if (sa)
3858 tcc_error("too few arguments to function");
3859 skip(')');
3860 if (!nocode_wanted) {
3861 gfunc_call(nb_args);
3862 } else {
3863 vtop -= (nb_args + 1);
3865 /* return value */
3866 vsetc(&ret.type, ret.r, &ret.c);
3867 vtop->r2 = ret.r2;
3868 } else {
3869 break;
3874 ST_FUNC void expr_prod(void)
3876 int t;
3878 unary();
3879 while (tok == '*' || tok == '/' || tok == '%') {
3880 t = tok;
3881 next();
3882 unary();
3883 gen_op(t);
3887 ST_FUNC void expr_sum(void)
3889 int t;
3891 expr_prod();
3892 while (tok == '+' || tok == '-') {
3893 t = tok;
3894 next();
3895 expr_prod();
3896 gen_op(t);
3900 static void expr_shift(void)
3902 int t;
3904 expr_sum();
3905 while (tok == TOK_SHL || tok == TOK_SAR) {
3906 t = tok;
3907 next();
3908 expr_sum();
3909 gen_op(t);
3913 static void expr_cmp(void)
3915 int t;
3917 expr_shift();
3918 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3919 tok == TOK_ULT || tok == TOK_UGE) {
3920 t = tok;
3921 next();
3922 expr_shift();
3923 gen_op(t);
3927 static void expr_cmpeq(void)
3929 int t;
3931 expr_cmp();
3932 while (tok == TOK_EQ || tok == TOK_NE) {
3933 t = tok;
3934 next();
3935 expr_cmp();
3936 gen_op(t);
3940 static void expr_and(void)
3942 expr_cmpeq();
3943 while (tok == '&') {
3944 next();
3945 expr_cmpeq();
3946 gen_op('&');
3950 static void expr_xor(void)
3952 expr_and();
3953 while (tok == '^') {
3954 next();
3955 expr_and();
3956 gen_op('^');
3960 static void expr_or(void)
3962 expr_xor();
3963 while (tok == '|') {
3964 next();
3965 expr_xor();
3966 gen_op('|');
3970 /* XXX: fix this mess */
3971 static void expr_land_const(void)
3973 expr_or();
3974 while (tok == TOK_LAND) {
3975 next();
3976 expr_or();
3977 gen_op(TOK_LAND);
3981 /* XXX: fix this mess */
3982 static void expr_lor_const(void)
3984 expr_land_const();
3985 while (tok == TOK_LOR) {
3986 next();
3987 expr_land_const();
3988 gen_op(TOK_LOR);
3992 /* only used if non constant */
3993 static void expr_land(void)
3995 int t;
3997 expr_or();
3998 if (tok == TOK_LAND) {
3999 t = 0;
4000 save_regs(1);
4001 for(;;) {
4002 t = gtst(1, t);
4003 if (tok != TOK_LAND) {
4004 vseti(VT_JMPI, t);
4005 break;
4007 next();
4008 expr_or();
4013 static void expr_lor(void)
4015 int t;
4017 expr_land();
4018 if (tok == TOK_LOR) {
4019 t = 0;
4020 save_regs(1);
4021 for(;;) {
4022 t = gtst(0, t);
4023 if (tok != TOK_LOR) {
4024 vseti(VT_JMP, t);
4025 break;
4027 next();
4028 expr_land();
4033 /* XXX: better constant handling */
4034 static void expr_cond(void)
4036 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4037 SValue sv;
4038 CType type, type1, type2;
4040 if (const_wanted) {
4041 expr_lor_const();
4042 if (tok == '?') {
4043 CType boolean;
4044 int c;
4045 boolean.t = VT_BOOL;
4046 vdup();
4047 gen_cast(&boolean);
4048 c = vtop->c.i;
4049 vpop();
4050 next();
4051 if (tok != ':' || !gnu_ext) {
4052 vpop();
4053 gexpr();
4055 if (!c)
4056 vpop();
4057 skip(':');
4058 expr_cond();
4059 if (c)
4060 vpop();
4062 } else {
4063 expr_lor();
4064 if (tok == '?') {
4065 next();
4066 if (vtop != vstack) {
4067 /* needed to avoid having different registers saved in
4068 each branch */
4069 if (is_float(vtop->type.t)) {
4070 rc = RC_FLOAT;
4071 #ifdef TCC_TARGET_X86_64
4072 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4073 rc = RC_ST0;
4075 #endif
4077 else
4078 rc = RC_INT;
4079 gv(rc);
4080 save_regs(1);
4082 if (tok == ':' && gnu_ext) {
4083 gv_dup();
4084 tt = gtst(1, 0);
4085 } else {
4086 tt = gtst(1, 0);
4087 gexpr();
4089 type1 = vtop->type;
4090 sv = *vtop; /* save value to handle it later */
4091 vtop--; /* no vpop so that FP stack is not flushed */
4092 skip(':');
4093 u = gjmp(0);
4094 gsym(tt);
4095 expr_cond();
4096 type2 = vtop->type;
4098 t1 = type1.t;
4099 bt1 = t1 & VT_BTYPE;
4100 t2 = type2.t;
4101 bt2 = t2 & VT_BTYPE;
4102 /* cast operands to correct type according to ISOC rules */
4103 if (is_float(bt1) || is_float(bt2)) {
4104 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4105 type.t = VT_LDOUBLE;
4106 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4107 type.t = VT_DOUBLE;
4108 } else {
4109 type.t = VT_FLOAT;
4111 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4112 /* cast to biggest op */
4113 type.t = VT_LLONG;
4114 /* convert to unsigned if it does not fit in a long long */
4115 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4116 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4117 type.t |= VT_UNSIGNED;
4118 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4119 /* XXX: test pointer compatibility */
4120 type = type1;
4121 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4122 /* XXX: test function pointer compatibility */
4123 type = type1;
4124 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4125 /* XXX: test structure compatibility */
4126 type = type1;
4127 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4128 /* NOTE: as an extension, we accept void on only one side */
4129 type.t = VT_VOID;
4130 } else {
4131 /* integer operations */
4132 type.t = VT_INT;
4133 /* convert to unsigned if it does not fit in an integer */
4134 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4135 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4136 type.t |= VT_UNSIGNED;
4139 /* now we convert second operand */
4140 gen_cast(&type);
4141 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4142 gaddrof();
4143 rc = RC_INT;
4144 if (is_float(type.t)) {
4145 rc = RC_FLOAT;
4146 #ifdef TCC_TARGET_X86_64
4147 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4148 rc = RC_ST0;
4150 #endif
4151 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4152 /* for long longs, we use fixed registers to avoid having
4153 to handle a complicated move */
4154 rc = RC_IRET;
4157 r2 = gv(rc);
4158 /* this is horrible, but we must also convert first
4159 operand */
4160 tt = gjmp(0);
4161 gsym(u);
4162 /* put again first value and cast it */
4163 *vtop = sv;
4164 gen_cast(&type);
4165 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4166 gaddrof();
4167 r1 = gv(rc);
4168 move_reg(r2, r1);
4169 vtop->r = r2;
4170 gsym(tt);
4175 static void expr_eq(void)
4177 int t;
4179 expr_cond();
4180 if (tok == '=' ||
4181 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4182 tok == TOK_A_XOR || tok == TOK_A_OR ||
4183 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4184 test_lvalue();
4185 t = tok;
4186 next();
4187 if (t == '=') {
4188 expr_eq();
4189 } else {
4190 vdup();
4191 expr_eq();
4192 gen_op(t & 0x7f);
4194 vstore();
4198 ST_FUNC void gexpr(void)
4200 while (1) {
4201 expr_eq();
4202 if (tok != ',')
4203 break;
4204 vpop();
4205 next();
4209 /* parse an expression and return its type without any side effect. */
4210 static void expr_type(CType *type)
4212 int saved_nocode_wanted;
4214 saved_nocode_wanted = nocode_wanted;
4215 nocode_wanted = 1;
4216 gexpr();
4217 *type = vtop->type;
4218 vpop();
4219 nocode_wanted = saved_nocode_wanted;
4222 /* parse a unary expression and return its type without any side
4223 effect. */
4224 static void unary_type(CType *type)
4226 int a;
4228 a = nocode_wanted;
4229 nocode_wanted = 1;
4230 unary();
4231 *type = vtop->type;
4232 vpop();
4233 nocode_wanted = a;
4236 /* parse a constant expression and return value in vtop. */
4237 static void expr_const1(void)
4239 int a;
4240 a = const_wanted;
4241 const_wanted = 1;
4242 expr_cond();
4243 const_wanted = a;
4246 /* parse an integer constant and return its value. */
4247 ST_FUNC int expr_const(void)
4249 int c;
4250 expr_const1();
4251 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4252 expect("constant expression");
4253 c = vtop->c.i;
4254 vpop();
4255 return c;
4258 /* return the label token if current token is a label, otherwise
4259 return zero */
4260 static int is_label(void)
4262 int last_tok;
4264 /* fast test first */
4265 if (tok < TOK_UIDENT)
4266 return 0;
4267 /* no need to save tokc because tok is an identifier */
4268 last_tok = tok;
4269 next();
4270 if (tok == ':') {
4271 next();
4272 return last_tok;
4273 } else {
4274 unget_tok(last_tok);
4275 return 0;
4279 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4280 int case_reg, int is_expr)
4282 int a, b, c, d;
4283 Sym *s;
4285 /* generate line number info */
4286 if (tcc_state->do_debug &&
4287 (last_line_num != file->line_num || last_ind != ind)) {
4288 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4289 last_ind = ind;
4290 last_line_num = file->line_num;
4293 if (is_expr) {
4294 /* default return value is (void) */
4295 vpushi(0);
4296 vtop->type.t = VT_VOID;
4299 if (tok == TOK_IF) {
4300 /* if test */
4301 next();
4302 skip('(');
4303 gexpr();
4304 skip(')');
4305 a = gtst(1, 0);
4306 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4307 c = tok;
4308 if (c == TOK_ELSE) {
4309 next();
4310 d = gjmp(0);
4311 gsym(a);
4312 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4313 gsym(d); /* patch else jmp */
4314 } else
4315 gsym(a);
4316 } else if (tok == TOK_WHILE) {
4317 next();
4318 d = ind;
4319 skip('(');
4320 gexpr();
4321 skip(')');
4322 a = gtst(1, 0);
4323 b = 0;
4324 block(&a, &b, case_sym, def_sym, case_reg, 0);
4325 gjmp_addr(d);
4326 gsym(a);
4327 gsym_addr(b, d);
4328 } else if (tok == '{') {
4329 Sym *llabel;
4331 next();
4332 /* record local declaration stack position */
4333 s = local_stack;
4334 llabel = local_label_stack;
4335 /* handle local labels declarations */
4336 if (tok == TOK_LABEL) {
4337 next();
4338 for(;;) {
4339 if (tok < TOK_UIDENT)
4340 expect("label identifier");
4341 label_push(&local_label_stack, tok, LABEL_DECLARED);
4342 next();
4343 if (tok == ',') {
4344 next();
4345 } else {
4346 skip(';');
4347 break;
4351 while (tok != '}') {
4352 decl(VT_LOCAL);
4353 if (tok != '}') {
4354 if (is_expr)
4355 vpop();
4356 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4359 /* pop locally defined labels */
4360 label_pop(&local_label_stack, llabel);
4361 if(is_expr) {
4362 /* XXX: this solution makes only valgrind happy...
4363 triggered by gcc.c-torture/execute/20000917-1.c */
4364 Sym *p;
4365 switch(vtop->type.t & VT_BTYPE) {
4366 case VT_PTR:
4367 case VT_STRUCT:
4368 case VT_ENUM:
4369 case VT_FUNC:
4370 for(p=vtop->type.ref;p;p=p->prev)
4371 if(p->prev==s)
4372 tcc_error("unsupported expression type");
4375 /* pop locally defined symbols */
4376 sym_pop(&local_stack, s);
4377 next();
4378 } else if (tok == TOK_RETURN) {
4379 next();
4380 if (tok != ';') {
4381 gexpr();
4382 gen_assign_cast(&func_vt);
4383 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4384 CType type;
4385 /* if returning structure, must copy it to implicit
4386 first pointer arg location */
4387 #ifdef TCC_ARM_EABI
4388 int align, size;
4389 size = type_size(&func_vt,&align);
4390 if(size <= 4)
4392 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4393 && (align & 3))
4395 int addr;
4396 loc = (loc - size) & -4;
4397 addr = loc;
4398 type = func_vt;
4399 vset(&type, VT_LOCAL | VT_LVAL, addr);
4400 vswap();
4401 vstore();
4402 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4404 vtop->type = int_type;
4405 gv(RC_IRET);
4406 } else {
4407 #endif
4408 type = func_vt;
4409 mk_pointer(&type);
4410 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4411 indir();
4412 vswap();
4413 /* copy structure value to pointer */
4414 vstore();
4415 #ifdef TCC_ARM_EABI
4417 #endif
4418 } else if (is_float(func_vt.t)) {
4419 gv(rc_fret(func_vt.t));
4420 } else {
4421 gv(RC_IRET);
4423 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4425 skip(';');
4426 rsym = gjmp(rsym); /* jmp */
4427 } else if (tok == TOK_BREAK) {
4428 /* compute jump */
4429 if (!bsym)
4430 tcc_error("cannot break");
4431 *bsym = gjmp(*bsym);
4432 next();
4433 skip(';');
4434 } else if (tok == TOK_CONTINUE) {
4435 /* compute jump */
4436 if (!csym)
4437 tcc_error("cannot continue");
4438 *csym = gjmp(*csym);
4439 next();
4440 skip(';');
4441 } else if (tok == TOK_FOR) {
4442 int e;
4443 next();
4444 skip('(');
4445 s = local_stack;
4446 if (tok != ';') {
4447 /* c99 for-loop init decl? */
4448 if (!decl0(VT_LOCAL, 1)) {
4449 /* no, regular for-loop init expr */
4450 gexpr();
4451 vpop();
4454 skip(';');
4455 d = ind;
4456 c = ind;
4457 a = 0;
4458 b = 0;
4459 if (tok != ';') {
4460 gexpr();
4461 a = gtst(1, 0);
4463 skip(';');
4464 if (tok != ')') {
4465 e = gjmp(0);
4466 c = ind;
4467 gexpr();
4468 vpop();
4469 gjmp_addr(d);
4470 gsym(e);
4472 skip(')');
4473 block(&a, &b, case_sym, def_sym, case_reg, 0);
4474 gjmp_addr(c);
4475 gsym(a);
4476 gsym_addr(b, c);
4477 sym_pop(&local_stack, s);
4478 } else
4479 if (tok == TOK_DO) {
4480 next();
4481 a = 0;
4482 b = 0;
4483 d = ind;
4484 block(&a, &b, case_sym, def_sym, case_reg, 0);
4485 skip(TOK_WHILE);
4486 skip('(');
4487 gsym(b);
4488 gexpr();
4489 c = gtst(0, 0);
4490 gsym_addr(c, d);
4491 skip(')');
4492 gsym(a);
4493 skip(';');
4494 } else
4495 if (tok == TOK_SWITCH) {
4496 next();
4497 skip('(');
4498 gexpr();
4499 /* XXX: other types than integer */
4500 case_reg = gv(RC_INT);
4501 vpop();
4502 skip(')');
4503 a = 0;
4504 b = gjmp(0); /* jump to first case */
4505 c = 0;
4506 block(&a, csym, &b, &c, case_reg, 0);
4507 /* if no default, jmp after switch */
4508 if (c == 0)
4509 c = ind;
4510 /* default label */
4511 gsym_addr(b, c);
4512 /* break label */
4513 gsym(a);
4514 } else
4515 if (tok == TOK_CASE) {
4516 int v1, v2;
4517 if (!case_sym)
4518 expect("switch");
4519 next();
4520 v1 = expr_const();
4521 v2 = v1;
4522 if (gnu_ext && tok == TOK_DOTS) {
4523 next();
4524 v2 = expr_const();
4525 if (v2 < v1)
4526 tcc_warning("empty case range");
4528 /* since a case is like a label, we must skip it with a jmp */
4529 b = gjmp(0);
4530 gsym(*case_sym);
4531 vseti(case_reg, 0);
4532 vpushi(v1);
4533 if (v1 == v2) {
4534 gen_op(TOK_EQ);
4535 *case_sym = gtst(1, 0);
4536 } else {
4537 gen_op(TOK_GE);
4538 *case_sym = gtst(1, 0);
4539 vseti(case_reg, 0);
4540 vpushi(v2);
4541 gen_op(TOK_LE);
4542 *case_sym = gtst(1, *case_sym);
4544 gsym(b);
4545 skip(':');
4546 is_expr = 0;
4547 goto block_after_label;
4548 } else
4549 if (tok == TOK_DEFAULT) {
4550 next();
4551 skip(':');
4552 if (!def_sym)
4553 expect("switch");
4554 if (*def_sym)
4555 tcc_error("too many 'default'");
4556 *def_sym = ind;
4557 is_expr = 0;
4558 goto block_after_label;
4559 } else
4560 if (tok == TOK_GOTO) {
4561 next();
4562 if (tok == '*' && gnu_ext) {
4563 /* computed goto */
4564 next();
4565 gexpr();
4566 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4567 expect("pointer");
4568 ggoto();
4569 } else if (tok >= TOK_UIDENT) {
4570 s = label_find(tok);
4571 /* put forward definition if needed */
4572 if (!s) {
4573 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4574 } else {
4575 if (s->r == LABEL_DECLARED)
4576 s->r = LABEL_FORWARD;
4578 /* label already defined */
4579 if (s->r & LABEL_FORWARD)
4580 s->jnext = gjmp(s->jnext);
4581 else
4582 gjmp_addr(s->jnext);
4583 next();
4584 } else {
4585 expect("label identifier");
4587 skip(';');
4588 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4589 asm_instr();
4590 } else {
4591 b = is_label();
4592 if (b) {
4593 /* label case */
4594 s = label_find(b);
4595 if (s) {
4596 if (s->r == LABEL_DEFINED)
4597 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4598 gsym(s->jnext);
4599 s->r = LABEL_DEFINED;
4600 } else {
4601 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4603 s->jnext = ind;
4604 /* we accept this, but it is a mistake */
4605 block_after_label:
4606 if (tok == '}') {
4607 tcc_warning("deprecated use of label at end of compound statement");
4608 } else {
4609 if (is_expr)
4610 vpop();
4611 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4613 } else {
4614 /* expression case */
4615 if (tok != ';') {
4616 if (is_expr) {
4617 vpop();
4618 gexpr();
4619 } else {
4620 gexpr();
4621 vpop();
4624 skip(';');
4629 /* t is the array or struct type. c is the array or struct
4630 address. cur_index/cur_field is the pointer to the current
4631 value. 'size_only' is true if only size info is needed (only used
4632 in arrays) */
4633 static void decl_designator(CType *type, Section *sec, unsigned long c,
4634 int *cur_index, Sym **cur_field,
4635 int size_only)
4637 Sym *s, *f;
4638 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4639 CType type1;
4641 notfirst = 0;
4642 elem_size = 0;
4643 nb_elems = 1;
4644 if (gnu_ext && (l = is_label()) != 0)
4645 goto struct_field;
4646 while (tok == '[' || tok == '.') {
4647 if (tok == '[') {
4648 if (!(type->t & VT_ARRAY))
4649 expect("array type");
4650 s = type->ref;
4651 next();
4652 index = expr_const();
4653 if (index < 0 || (s->c >= 0 && index >= s->c))
4654 expect("invalid index");
4655 if (tok == TOK_DOTS && gnu_ext) {
4656 next();
4657 index_last = expr_const();
4658 if (index_last < 0 ||
4659 (s->c >= 0 && index_last >= s->c) ||
4660 index_last < index)
4661 expect("invalid index");
4662 } else {
4663 index_last = index;
4665 skip(']');
4666 if (!notfirst)
4667 *cur_index = index_last;
4668 type = pointed_type(type);
4669 elem_size = type_size(type, &align);
4670 c += index * elem_size;
4671 /* NOTE: we only support ranges for last designator */
4672 nb_elems = index_last - index + 1;
4673 if (nb_elems != 1) {
4674 notfirst = 1;
4675 break;
4677 } else {
4678 next();
4679 l = tok;
4680 next();
4681 struct_field:
4682 if ((type->t & VT_BTYPE) != VT_STRUCT)
4683 expect("struct/union type");
4684 s = type->ref;
4685 l |= SYM_FIELD;
4686 f = s->next;
4687 while (f) {
4688 if (f->v == l)
4689 break;
4690 f = f->next;
4692 if (!f)
4693 expect("field");
4694 if (!notfirst)
4695 *cur_field = f;
4696 /* XXX: fix this mess by using explicit storage field */
4697 type1 = f->type;
4698 type1.t |= (type->t & ~VT_TYPE);
4699 type = &type1;
4700 c += f->c;
4702 notfirst = 1;
4704 if (notfirst) {
4705 if (tok == '=') {
4706 next();
4707 } else {
4708 if (!gnu_ext)
4709 expect("=");
4711 } else {
4712 if (type->t & VT_ARRAY) {
4713 index = *cur_index;
4714 type = pointed_type(type);
4715 c += index * type_size(type, &align);
4716 } else {
4717 f = *cur_field;
4718 if (!f)
4719 tcc_error("too many field init");
4720 /* XXX: fix this mess by using explicit storage field */
4721 type1 = f->type;
4722 type1.t |= (type->t & ~VT_TYPE);
4723 type = &type1;
4724 c += f->c;
4727 decl_initializer(type, sec, c, 0, size_only);
4729 /* XXX: make it more general */
4730 if (!size_only && nb_elems > 1) {
4731 unsigned long c_end;
4732 uint8_t *src, *dst;
4733 int i;
4735 if (!sec)
4736 tcc_error("range init not supported yet for dynamic storage");
4737 c_end = c + nb_elems * elem_size;
4738 if (c_end > sec->data_allocated)
4739 section_realloc(sec, c_end);
4740 src = sec->data + c;
4741 dst = src;
4742 for(i = 1; i < nb_elems; i++) {
4743 dst += elem_size;
4744 memcpy(dst, src, elem_size);
4749 #define EXPR_VAL 0
4750 #define EXPR_CONST 1
4751 #define EXPR_ANY 2
4753 /* store a value or an expression directly in global data or in local array */
4754 static void init_putv(CType *type, Section *sec, unsigned long c,
4755 int v, int expr_type)
4757 int saved_global_expr, bt, bit_pos, bit_size;
4758 void *ptr;
4759 unsigned long long bit_mask;
4760 CType dtype;
4762 switch(expr_type) {
4763 case EXPR_VAL:
4764 vpushi(v);
4765 break;
4766 case EXPR_CONST:
4767 /* compound literals must be allocated globally in this case */
4768 saved_global_expr = global_expr;
4769 global_expr = 1;
4770 expr_const1();
4771 global_expr = saved_global_expr;
4772 /* NOTE: symbols are accepted */
4773 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4774 tcc_error("initializer element is not constant");
4775 break;
4776 case EXPR_ANY:
4777 expr_eq();
4778 break;
4781 dtype = *type;
4782 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4784 if (sec) {
4785 /* XXX: not portable */
4786 /* XXX: generate error if incorrect relocation */
4787 gen_assign_cast(&dtype);
4788 bt = type->t & VT_BTYPE;
4789 /* we'll write at most 12 bytes */
4790 if (c + 12 > sec->data_allocated) {
4791 section_realloc(sec, c + 12);
4793 ptr = sec->data + c;
4794 /* XXX: make code faster ? */
4795 if (!(type->t & VT_BITFIELD)) {
4796 bit_pos = 0;
4797 bit_size = 32;
4798 bit_mask = -1LL;
4799 } else {
4800 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4801 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4802 bit_mask = (1LL << bit_size) - 1;
4804 if ((vtop->r & VT_SYM) &&
4805 (bt == VT_BYTE ||
4806 bt == VT_SHORT ||
4807 bt == VT_DOUBLE ||
4808 bt == VT_LDOUBLE ||
4809 bt == VT_LLONG ||
4810 (bt == VT_INT && bit_size != 32)))
4811 tcc_error("initializer element is not computable at load time");
4812 switch(bt) {
4813 case VT_BOOL:
4814 vtop->c.i = (vtop->c.i != 0);
4815 case VT_BYTE:
4816 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4817 break;
4818 case VT_SHORT:
4819 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4820 break;
4821 case VT_DOUBLE:
4822 *(double *)ptr = vtop->c.d;
4823 break;
4824 case VT_LDOUBLE:
4825 *(long double *)ptr = vtop->c.ld;
4826 break;
4827 case VT_LLONG:
4828 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4829 break;
4830 default:
4831 if (vtop->r & VT_SYM) {
4832 greloc(sec, vtop->sym, c, R_DATA_PTR);
4834 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4835 break;
4837 vtop--;
4838 } else {
4839 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4840 vswap();
4841 vstore();
4842 vpop();
4846 /* put zeros for variable based init */
4847 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4849 if (sec) {
4850 /* nothing to do because globals are already set to zero */
4851 } else {
4852 vpush_global_sym(&func_old_type, TOK_memset);
4853 vseti(VT_LOCAL, c);
4854 vpushi(0);
4855 vpushi(size);
4856 gfunc_call(3);
4860 /* 't' contains the type and storage info. 'c' is the offset of the
4861 object in section 'sec'. If 'sec' is NULL, it means stack based
4862 allocation. 'first' is true if array '{' must be read (multi
4863 dimension implicit array init handling). 'size_only' is true if
4864 size only evaluation is wanted (only for arrays). */
4865 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4866 int first, int size_only)
4868 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
4869 int size1, align1, expr_type;
4870 Sym *s, *f;
4871 CType *t1;
4873 if (type->t & VT_VLA) {
4874 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
4875 int a;
4876 CValue retcval;
4878 vpush_global_sym(&func_old_type, TOK_alloca);
4879 vla_runtime_type_size(type, &a);
4880 gfunc_call(1);
4882 /* return value */
4883 retcval.i = 0;
4884 vsetc(type, REG_IRET, &retcval);
4885 vset(type, VT_LOCAL|VT_LVAL, c);
4886 vswap();
4887 vstore();
4888 vpop();
4889 #else
4890 tcc_error("variable length arrays unsupported for this target");
4891 #endif
4892 } else if (type->t & VT_ARRAY) {
4893 s = type->ref;
4894 n = s->c;
4895 array_length = 0;
4896 t1 = pointed_type(type);
4897 size1 = type_size(t1, &align1);
4899 no_oblock = 1;
4900 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4901 tok == '{') {
4902 if (tok != '{')
4903 tcc_error("character array initializer must be a literal,"
4904 " optionally enclosed in braces");
4905 skip('{');
4906 no_oblock = 0;
4909 /* only parse strings here if correct type (otherwise: handle
4910 them as ((w)char *) expressions */
4911 if ((tok == TOK_LSTR &&
4912 #ifdef TCC_TARGET_PE
4913 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4914 #else
4915 (t1->t & VT_BTYPE) == VT_INT
4916 #endif
4917 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4918 while (tok == TOK_STR || tok == TOK_LSTR) {
4919 int cstr_len, ch;
4920 CString *cstr;
4922 cstr = tokc.cstr;
4923 /* compute maximum number of chars wanted */
4924 if (tok == TOK_STR)
4925 cstr_len = cstr->size;
4926 else
4927 cstr_len = cstr->size / sizeof(nwchar_t);
4928 cstr_len--;
4929 nb = cstr_len;
4930 if (n >= 0 && nb > (n - array_length))
4931 nb = n - array_length;
4932 if (!size_only) {
4933 if (cstr_len > nb)
4934 tcc_warning("initializer-string for array is too long");
4935 /* in order to go faster for common case (char
4936 string in global variable, we handle it
4937 specifically */
4938 if (sec && tok == TOK_STR && size1 == 1) {
4939 memcpy(sec->data + c + array_length, cstr->data, nb);
4940 } else {
4941 for(i=0;i<nb;i++) {
4942 if (tok == TOK_STR)
4943 ch = ((unsigned char *)cstr->data)[i];
4944 else
4945 ch = ((nwchar_t *)cstr->data)[i];
4946 init_putv(t1, sec, c + (array_length + i) * size1,
4947 ch, EXPR_VAL);
4951 array_length += nb;
4952 next();
4954 /* only add trailing zero if enough storage (no
4955 warning in this case since it is standard) */
4956 if (n < 0 || array_length < n) {
4957 if (!size_only) {
4958 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4960 array_length++;
4962 } else {
4963 index = 0;
4964 while (tok != '}') {
4965 decl_designator(type, sec, c, &index, NULL, size_only);
4966 if (n >= 0 && index >= n)
4967 tcc_error("index too large");
4968 /* must put zero in holes (note that doing it that way
4969 ensures that it even works with designators) */
4970 if (!size_only && array_length < index) {
4971 init_putz(t1, sec, c + array_length * size1,
4972 (index - array_length) * size1);
4974 index++;
4975 if (index > array_length)
4976 array_length = index;
4977 /* special test for multi dimensional arrays (may not
4978 be strictly correct if designators are used at the
4979 same time) */
4980 if (index >= n && no_oblock)
4981 break;
4982 if (tok == '}')
4983 break;
4984 skip(',');
4987 if (!no_oblock)
4988 skip('}');
4989 /* put zeros at the end */
4990 if (!size_only && n >= 0 && array_length < n) {
4991 init_putz(t1, sec, c + array_length * size1,
4992 (n - array_length) * size1);
4994 /* patch type size if needed */
4995 if (n < 0)
4996 s->c = array_length;
4997 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4998 (sec || !first || tok == '{')) {
4999 int par_count;
5001 /* NOTE: the previous test is a specific case for automatic
5002 struct/union init */
5003 /* XXX: union needs only one init */
5005 /* XXX: this test is incorrect for local initializers
5006 beginning with ( without {. It would be much more difficult
5007 to do it correctly (ideally, the expression parser should
5008 be used in all cases) */
5009 par_count = 0;
5010 if (tok == '(') {
5011 AttributeDef ad1;
5012 CType type1;
5013 next();
5014 while (tok == '(') {
5015 par_count++;
5016 next();
5018 if (!parse_btype(&type1, &ad1))
5019 expect("cast");
5020 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5021 #if 0
5022 if (!is_assignable_types(type, &type1))
5023 tcc_error("invalid type for cast");
5024 #endif
5025 skip(')');
5027 no_oblock = 1;
5028 if (first || tok == '{') {
5029 skip('{');
5030 no_oblock = 0;
5032 s = type->ref;
5033 f = s->next;
5034 array_length = 0;
5035 index = 0;
5036 n = s->c;
5037 while (tok != '}') {
5038 decl_designator(type, sec, c, NULL, &f, size_only);
5039 index = f->c;
5040 if (!size_only && array_length < index) {
5041 init_putz(type, sec, c + array_length,
5042 index - array_length);
5044 index = index + type_size(&f->type, &align1);
5045 if (index > array_length)
5046 array_length = index;
5048 /* gr: skip fields from same union - ugly. */
5049 while (f->next) {
5050 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5051 /* test for same offset */
5052 if (f->next->c != f->c)
5053 break;
5054 /* if yes, test for bitfield shift */
5055 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5056 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5057 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5058 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5059 if (bit_pos_1 != bit_pos_2)
5060 break;
5062 f = f->next;
5065 f = f->next;
5066 if (no_oblock && f == NULL)
5067 break;
5068 if (tok == '}')
5069 break;
5070 skip(',');
5072 /* put zeros at the end */
5073 if (!size_only && array_length < n) {
5074 init_putz(type, sec, c + array_length,
5075 n - array_length);
5077 if (!no_oblock)
5078 skip('}');
5079 while (par_count) {
5080 skip(')');
5081 par_count--;
5083 } else if (tok == '{') {
5084 next();
5085 decl_initializer(type, sec, c, first, size_only);
5086 skip('}');
5087 } else if (size_only) {
5088 /* just skip expression */
5089 parlevel = parlevel1 = 0;
5090 while ((parlevel > 0 || parlevel1 > 0 ||
5091 (tok != '}' && tok != ',')) && tok != -1) {
5092 if (tok == '(')
5093 parlevel++;
5094 else if (tok == ')')
5095 parlevel--;
5096 else if (tok == '{')
5097 parlevel1++;
5098 else if (tok == '}')
5099 parlevel1--;
5100 next();
5102 } else {
5103 /* currently, we always use constant expression for globals
5104 (may change for scripting case) */
5105 expr_type = EXPR_CONST;
5106 if (!sec)
5107 expr_type = EXPR_ANY;
5108 init_putv(type, sec, c, 0, expr_type);
5112 /* parse an initializer for type 't' if 'has_init' is non zero, and
5113 allocate space in local or global data space ('r' is either
5114 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5115 variable 'v' with an associated name represented by 'asm_label' of
5116 scope 'scope' is declared before initializers are parsed. If 'v' is
5117 zero, then a reference to the new object is put in the value stack.
5118 If 'has_init' is 2, a special parsing is done to handle string
5119 constants. */
5120 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5121 int has_init, int v, char *asm_label,
5122 int scope)
5124 int size, align, addr, data_offset;
5125 int level;
5126 ParseState saved_parse_state = {0};
5127 TokenString init_str;
5128 Section *sec;
5129 Sym *flexible_array;
5131 flexible_array = NULL;
5132 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5133 Sym *field;
5134 field = type->ref;
5135 while (field && field->next)
5136 field = field->next;
5137 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5138 flexible_array = field;
5141 size = type_size(type, &align);
5142 /* If unknown size, we must evaluate it before
5143 evaluating initializers because
5144 initializers can generate global data too
5145 (e.g. string pointers or ISOC99 compound
5146 literals). It also simplifies local
5147 initializers handling */
5148 tok_str_new(&init_str);
5149 if (size < 0 || (flexible_array && has_init)) {
5150 if (!has_init)
5151 tcc_error("unknown type size");
5152 /* get all init string */
5153 if (has_init == 2) {
5154 /* only get strings */
5155 while (tok == TOK_STR || tok == TOK_LSTR) {
5156 tok_str_add_tok(&init_str);
5157 next();
5159 } else {
5160 level = 0;
5161 while (level > 0 || (tok != ',' && tok != ';')) {
5162 if (tok < 0)
5163 tcc_error("unexpected end of file in initializer");
5164 tok_str_add_tok(&init_str);
5165 if (tok == '{')
5166 level++;
5167 else if (tok == '}') {
5168 level--;
5169 if (level <= 0) {
5170 next();
5171 break;
5174 next();
5177 tok_str_add(&init_str, -1);
5178 tok_str_add(&init_str, 0);
5180 /* compute size */
5181 save_parse_state(&saved_parse_state);
5183 macro_ptr = init_str.str;
5184 next();
5185 decl_initializer(type, NULL, 0, 1, 1);
5186 /* prepare second initializer parsing */
5187 macro_ptr = init_str.str;
5188 next();
5190 /* if still unknown size, error */
5191 size = type_size(type, &align);
5192 if (size < 0)
5193 tcc_error("unknown type size");
5195 if (flexible_array)
5196 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5197 /* take into account specified alignment if bigger */
5198 if (ad->aligned) {
5199 if (ad->aligned > align)
5200 align = ad->aligned;
5201 } else if (ad->packed) {
5202 align = 1;
5204 if ((r & VT_VALMASK) == VT_LOCAL) {
5205 sec = NULL;
5206 #ifdef CONFIG_TCC_BCHECK
5207 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5208 loc--;
5210 #endif
5211 loc = (loc - size) & -align;
5212 addr = loc;
5213 #ifdef CONFIG_TCC_BCHECK
5214 /* handles bounds */
5215 /* XXX: currently, since we do only one pass, we cannot track
5216 '&' operators, so we add only arrays */
5217 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5218 unsigned long *bounds_ptr;
5219 /* add padding between regions */
5220 loc--;
5221 /* then add local bound info */
5222 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5223 bounds_ptr[0] = addr;
5224 bounds_ptr[1] = size;
5226 #endif
5227 if (v) {
5228 /* local variable */
5229 sym_push(v, type, r, addr);
5230 } else {
5231 /* push local reference */
5232 vset(type, r, addr);
5234 } else {
5235 Sym *sym;
5237 sym = NULL;
5238 if (v && scope == VT_CONST) {
5239 /* see if the symbol was already defined */
5240 sym = sym_find(v);
5241 if (sym) {
5242 if (!is_compatible_types(&sym->type, type))
5243 tcc_error("incompatible types for redefinition of '%s'",
5244 get_tok_str(v, NULL));
5245 if (sym->type.t & VT_EXTERN) {
5246 /* if the variable is extern, it was not allocated */
5247 sym->type.t &= ~VT_EXTERN;
5248 /* set array size if it was ommited in extern
5249 declaration */
5250 if ((sym->type.t & VT_ARRAY) &&
5251 sym->type.ref->c < 0 &&
5252 type->ref->c >= 0)
5253 sym->type.ref->c = type->ref->c;
5254 } else {
5255 /* we accept several definitions of the same
5256 global variable. this is tricky, because we
5257 must play with the SHN_COMMON type of the symbol */
5258 /* XXX: should check if the variable was already
5259 initialized. It is incorrect to initialized it
5260 twice */
5261 /* no init data, we won't add more to the symbol */
5262 if (!has_init)
5263 goto no_alloc;
5268 /* allocate symbol in corresponding section */
5269 sec = ad->section;
5270 if (!sec) {
5271 if (has_init)
5272 sec = data_section;
5273 else if (tcc_state->nocommon)
5274 sec = bss_section;
5276 if (sec) {
5277 data_offset = sec->data_offset;
5278 data_offset = (data_offset + align - 1) & -align;
5279 addr = data_offset;
5280 /* very important to increment global pointer at this time
5281 because initializers themselves can create new initializers */
5282 data_offset += size;
5283 #ifdef CONFIG_TCC_BCHECK
5284 /* add padding if bound check */
5285 if (tcc_state->do_bounds_check)
5286 data_offset++;
5287 #endif
5288 sec->data_offset = data_offset;
5289 /* allocate section space to put the data */
5290 if (sec->sh_type != SHT_NOBITS &&
5291 data_offset > sec->data_allocated)
5292 section_realloc(sec, data_offset);
5293 /* align section if needed */
5294 if (align > sec->sh_addralign)
5295 sec->sh_addralign = align;
5296 } else {
5297 addr = 0; /* avoid warning */
5300 if (v) {
5301 if (scope != VT_CONST || !sym) {
5302 sym = sym_push(v, type, r | VT_SYM, 0);
5303 sym->asm_label = asm_label;
5305 /* update symbol definition */
5306 if (sec) {
5307 put_extern_sym(sym, sec, addr, size);
5308 } else {
5309 ElfW(Sym) *esym;
5310 /* put a common area */
5311 put_extern_sym(sym, NULL, align, size);
5312 /* XXX: find a nicer way */
5313 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5314 esym->st_shndx = SHN_COMMON;
5316 } else {
5317 CValue cval;
5319 /* push global reference */
5320 sym = get_sym_ref(type, sec, addr, size);
5321 cval.ul = 0;
5322 vsetc(type, VT_CONST | VT_SYM, &cval);
5323 vtop->sym = sym;
5325 /* patch symbol weakness */
5326 if (type->t & VT_WEAK)
5327 weaken_symbol(sym);
5328 #ifdef CONFIG_TCC_BCHECK
5329 /* handles bounds now because the symbol must be defined
5330 before for the relocation */
5331 if (tcc_state->do_bounds_check) {
5332 unsigned long *bounds_ptr;
5334 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5335 /* then add global bound info */
5336 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5337 bounds_ptr[0] = 0; /* relocated */
5338 bounds_ptr[1] = size;
5340 #endif
5342 if (has_init || (type->t & VT_VLA)) {
5343 decl_initializer(type, sec, addr, 1, 0);
5344 /* restore parse state if needed */
5345 if (init_str.str) {
5346 tok_str_free(init_str.str);
5347 restore_parse_state(&saved_parse_state);
5349 /* patch flexible array member size back to -1, */
5350 /* for possible subsequent similar declarations */
5351 if (flexible_array)
5352 flexible_array->type.ref->c = -1;
5354 no_alloc: ;
5357 static void put_func_debug(Sym *sym)
5359 char buf[512];
5361 /* stabs info */
5362 /* XXX: we put here a dummy type */
5363 snprintf(buf, sizeof(buf), "%s:%c1",
5364 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5365 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5366 cur_text_section, sym->c);
5367 /* //gr gdb wants a line at the function */
5368 put_stabn(N_SLINE, 0, file->line_num, 0);
5369 last_ind = 0;
5370 last_line_num = 0;
5373 /* parse an old style function declaration list */
5374 /* XXX: check multiple parameter */
5375 static void func_decl_list(Sym *func_sym)
5377 AttributeDef ad;
5378 int v;
5379 Sym *s;
5380 CType btype, type;
5382 /* parse each declaration */
5383 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5384 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5385 if (!parse_btype(&btype, &ad))
5386 expect("declaration list");
5387 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5388 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5389 tok == ';') {
5390 /* we accept no variable after */
5391 } else {
5392 for(;;) {
5393 type = btype;
5394 type_decl(&type, &ad, &v, TYPE_DIRECT);
5395 /* find parameter in function parameter list */
5396 s = func_sym->next;
5397 while (s != NULL) {
5398 if ((s->v & ~SYM_FIELD) == v)
5399 goto found;
5400 s = s->next;
5402 tcc_error("declaration for parameter '%s' but no such parameter",
5403 get_tok_str(v, NULL));
5404 found:
5405 /* check that no storage specifier except 'register' was given */
5406 if (type.t & VT_STORAGE)
5407 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5408 convert_parameter_type(&type);
5409 /* we can add the type (NOTE: it could be local to the function) */
5410 s->type = type;
5411 /* accept other parameters */
5412 if (tok == ',')
5413 next();
5414 else
5415 break;
5418 skip(';');
5422 /* parse a function defined by symbol 'sym' and generate its code in
5423 'cur_text_section' */
5424 static void gen_function(Sym *sym)
5426 int saved_nocode_wanted = nocode_wanted;
5427 nocode_wanted = 0;
5428 ind = cur_text_section->data_offset;
5429 /* NOTE: we patch the symbol size later */
5430 put_extern_sym(sym, cur_text_section, ind, 0);
5431 funcname = get_tok_str(sym->v, NULL);
5432 func_ind = ind;
5433 /* put debug symbol */
5434 if (tcc_state->do_debug)
5435 put_func_debug(sym);
5436 /* push a dummy symbol to enable local sym storage */
5437 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5438 gfunc_prolog(&sym->type);
5439 rsym = 0;
5440 block(NULL, NULL, NULL, NULL, 0, 0);
5441 gsym(rsym);
5442 gfunc_epilog();
5443 cur_text_section->data_offset = ind;
5444 label_pop(&global_label_stack, NULL);
5445 sym_pop(&local_stack, NULL); /* reset local stack */
5446 /* end of function */
5447 /* patch symbol size */
5448 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5449 ind - func_ind;
5450 /* patch symbol weakness (this definition overrules any prototype) */
5451 if (sym->type.t & VT_WEAK)
5452 weaken_symbol(sym);
5453 if (tcc_state->do_debug) {
5454 put_stabn(N_FUN, 0, 0, ind - func_ind);
5456 /* It's better to crash than to generate wrong code */
5457 cur_text_section = NULL;
5458 funcname = ""; /* for safety */
5459 func_vt.t = VT_VOID; /* for safety */
5460 ind = 0; /* for safety */
5461 nocode_wanted = saved_nocode_wanted;
5464 ST_FUNC void gen_inline_functions(void)
5466 Sym *sym;
5467 int *str, inline_generated, i;
5468 struct InlineFunc *fn;
5470 /* iterate while inline function are referenced */
5471 for(;;) {
5472 inline_generated = 0;
5473 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5474 fn = tcc_state->inline_fns[i];
5475 sym = fn->sym;
5476 if (sym && sym->c) {
5477 /* the function was used: generate its code and
5478 convert it to a normal function */
5479 str = fn->token_str;
5480 fn->sym = NULL;
5481 if (file)
5482 strcpy(file->filename, fn->filename);
5483 sym->r = VT_SYM | VT_CONST;
5484 sym->type.t &= ~VT_INLINE;
5486 macro_ptr = str;
5487 next();
5488 cur_text_section = text_section;
5489 gen_function(sym);
5490 macro_ptr = NULL; /* fail safe */
5492 inline_generated = 1;
5495 if (!inline_generated)
5496 break;
5498 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5499 fn = tcc_state->inline_fns[i];
5500 str = fn->token_str;
5501 tok_str_free(str);
5503 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5506 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5507 static int decl0(int l, int is_for_loop_init)
5509 int v, has_init, r;
5510 CType type, btype;
5511 Sym *sym;
5512 AttributeDef ad;
5514 while (1) {
5515 if (!parse_btype(&btype, &ad)) {
5516 if (is_for_loop_init)
5517 return 0;
5518 /* skip redundant ';' */
5519 /* XXX: find more elegant solution */
5520 if (tok == ';') {
5521 next();
5522 continue;
5524 if (l == VT_CONST &&
5525 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5526 /* global asm block */
5527 asm_global_instr();
5528 continue;
5530 /* special test for old K&R protos without explicit int
5531 type. Only accepted when defining global data */
5532 if (l == VT_LOCAL || tok < TOK_DEFINE)
5533 break;
5534 btype.t = VT_INT;
5536 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5537 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5538 tok == ';') {
5539 /* we accept no variable after */
5540 next();
5541 continue;
5543 while (1) { /* iterate thru each declaration */
5544 char *asm_label; // associated asm label
5545 type = btype;
5546 type_decl(&type, &ad, &v, TYPE_DIRECT);
5547 #if 0
5549 char buf[500];
5550 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5551 printf("type = '%s'\n", buf);
5553 #endif
5554 if ((type.t & VT_BTYPE) == VT_FUNC) {
5555 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5556 tcc_error("function without file scope cannot be static");
5558 /* if old style function prototype, we accept a
5559 declaration list */
5560 sym = type.ref;
5561 if (sym->c == FUNC_OLD)
5562 func_decl_list(sym);
5565 asm_label = NULL;
5566 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5567 CString astr;
5569 asm_label_instr(&astr);
5570 asm_label = tcc_strdup(astr.data);
5571 cstr_free(&astr);
5573 /* parse one last attribute list, after asm label */
5574 parse_attribute(&ad);
5577 if (ad.weak)
5578 type.t |= VT_WEAK;
5579 #ifdef TCC_TARGET_PE
5580 if (ad.func_import)
5581 type.t |= VT_IMPORT;
5582 if (ad.func_export)
5583 type.t |= VT_EXPORT;
5584 #endif
5585 if (tok == '{') {
5586 if (l == VT_LOCAL)
5587 tcc_error("cannot use local functions");
5588 if ((type.t & VT_BTYPE) != VT_FUNC)
5589 expect("function definition");
5591 /* reject abstract declarators in function definition */
5592 sym = type.ref;
5593 while ((sym = sym->next) != NULL)
5594 if (!(sym->v & ~SYM_FIELD))
5595 expect("identifier");
5597 /* XXX: cannot do better now: convert extern line to static inline */
5598 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5599 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5601 sym = sym_find(v);
5602 if (sym) {
5603 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5604 goto func_error1;
5606 r = sym->type.ref->r;
5607 /* use func_call from prototype if not defined */
5608 if (FUNC_CALL(r) != FUNC_CDECL
5609 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5610 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5612 /* use export from prototype */
5613 if (FUNC_EXPORT(r))
5614 FUNC_EXPORT(type.ref->r) = 1;
5616 /* use static from prototype */
5617 if (sym->type.t & VT_STATIC)
5618 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5620 if (!is_compatible_types(&sym->type, &type)) {
5621 func_error1:
5622 tcc_error("incompatible types for redefinition of '%s'",
5623 get_tok_str(v, NULL));
5625 /* if symbol is already defined, then put complete type */
5626 sym->type = type;
5627 } else {
5628 /* put function symbol */
5629 sym = global_identifier_push(v, type.t, 0);
5630 sym->type.ref = type.ref;
5633 /* static inline functions are just recorded as a kind
5634 of macro. Their code will be emitted at the end of
5635 the compilation unit only if they are used */
5636 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5637 (VT_INLINE | VT_STATIC)) {
5638 TokenString func_str;
5639 int block_level;
5640 struct InlineFunc *fn;
5641 const char *filename;
5643 tok_str_new(&func_str);
5645 block_level = 0;
5646 for(;;) {
5647 int t;
5648 if (tok == TOK_EOF)
5649 tcc_error("unexpected end of file");
5650 tok_str_add_tok(&func_str);
5651 t = tok;
5652 next();
5653 if (t == '{') {
5654 block_level++;
5655 } else if (t == '}') {
5656 block_level--;
5657 if (block_level == 0)
5658 break;
5661 tok_str_add(&func_str, -1);
5662 tok_str_add(&func_str, 0);
5663 filename = file ? file->filename : "";
5664 fn = tcc_malloc(sizeof *fn + strlen(filename));
5665 strcpy(fn->filename, filename);
5666 fn->sym = sym;
5667 fn->token_str = func_str.str;
5668 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5670 } else {
5671 /* compute text section */
5672 cur_text_section = ad.section;
5673 if (!cur_text_section)
5674 cur_text_section = text_section;
5675 sym->r = VT_SYM | VT_CONST;
5676 gen_function(sym);
5678 break;
5679 } else {
5680 if (btype.t & VT_TYPEDEF) {
5681 /* save typedefed type */
5682 /* XXX: test storage specifiers ? */
5683 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5684 sym->type.t |= VT_TYPEDEF;
5685 } else {
5686 r = 0;
5687 if ((type.t & VT_BTYPE) == VT_FUNC) {
5688 /* external function definition */
5689 /* specific case for func_call attribute */
5690 type.ref->r = INT_ATTR(&ad);
5691 } else if (!(type.t & VT_ARRAY)) {
5692 /* not lvalue if array */
5693 r |= lvalue_type(type.t);
5695 has_init = (tok == '=');
5696 if (has_init && (type.t & VT_VLA))
5697 tcc_error("Variable length array cannot be initialized");
5698 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5699 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5700 !has_init && l == VT_CONST && type.ref->c < 0)) {
5701 /* external variable or function */
5702 /* NOTE: as GCC, uninitialized global static
5703 arrays of null size are considered as
5704 extern */
5705 sym = external_sym(v, &type, r, asm_label);
5707 if (type.t & VT_WEAK)
5708 weaken_symbol(sym);
5710 if (ad.alias_target) {
5711 Section tsec;
5712 Elf32_Sym *esym;
5713 Sym *alias_target;
5715 alias_target = sym_find(ad.alias_target);
5716 if (!alias_target || !alias_target->c)
5717 tcc_error("unsupported forward __alias__ attribute");
5718 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
5719 tsec.sh_num = esym->st_shndx;
5720 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
5722 } else {
5723 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5724 if (type.t & VT_STATIC)
5725 r |= VT_CONST;
5726 else
5727 r |= l;
5728 if (has_init)
5729 next();
5730 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
5733 if (tok != ',') {
5734 if (is_for_loop_init)
5735 return 1;
5736 skip(';');
5737 break;
5739 next();
5741 ad.aligned = 0;
5744 return 0;
5747 ST_FUNC void decl(int l)
5749 decl0(l, 0);