VLA fix [2/3]: removed VT_ARRAY from VT_VLA types
[tinycc/miki.git] / tccgen.c
blobb55af88d0c7274d4fe46e58406d9be2d37a91063
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 ST_FUNC void test_lvalue(void)
95 if (!(vtop->r & VT_LVAL))
96 expect("lvalue");
99 /* ------------------------------------------------------------------------- */
100 /* symbol allocator */
101 static Sym *__sym_malloc(void)
103 Sym *sym_pool, *sym, *last_sym;
104 int i;
106 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
107 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
109 last_sym = sym_free_first;
110 sym = sym_pool;
111 for(i = 0; i < SYM_POOL_NB; i++) {
112 sym->next = last_sym;
113 last_sym = sym;
114 sym++;
116 sym_free_first = last_sym;
117 return last_sym;
120 static inline Sym *sym_malloc(void)
122 Sym *sym;
123 sym = sym_free_first;
124 if (!sym)
125 sym = __sym_malloc();
126 sym_free_first = sym->next;
127 return sym;
130 ST_INLN void sym_free(Sym *sym)
132 sym->next = sym_free_first;
133 tcc_free(sym->asm_label);
134 sym_free_first = sym;
137 /* push, without hashing */
138 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
140 Sym *s;
141 s = sym_malloc();
142 s->asm_label = NULL;
143 s->v = v;
144 s->type.t = t;
145 s->type.ref = NULL;
146 #ifdef _WIN64
147 s->d = NULL;
148 #endif
149 s->c = c;
150 s->next = NULL;
151 /* add in stack */
152 s->prev = *ps;
153 *ps = s;
154 return s;
157 /* find a symbol and return its associated structure. 's' is the top
158 of the symbol stack */
159 ST_FUNC Sym *sym_find2(Sym *s, int v)
161 while (s) {
162 if (s->v == v)
163 return s;
164 s = s->prev;
166 return NULL;
169 /* structure lookup */
170 ST_INLN Sym *struct_find(int v)
172 v -= TOK_IDENT;
173 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
174 return NULL;
175 return table_ident[v]->sym_struct;
178 /* find an identifier */
179 ST_INLN Sym *sym_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_identifier;
187 /* push a given symbol on the symbol stack */
188 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
190 Sym *s, **ps;
191 TokenSym *ts;
193 if (local_stack)
194 ps = &local_stack;
195 else
196 ps = &global_stack;
197 s = sym_push2(ps, v, type->t, c);
198 s->type.ref = type->ref;
199 s->r = r;
200 /* don't record fields or anonymous symbols */
201 /* XXX: simplify */
202 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
203 /* record symbol in token array */
204 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
205 if (v & SYM_STRUCT)
206 ps = &ts->sym_struct;
207 else
208 ps = &ts->sym_identifier;
209 s->prev_tok = *ps;
210 *ps = s;
212 return s;
215 /* push a global identifier */
216 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
218 Sym *s, **ps;
219 s = sym_push2(&global_stack, v, t, c);
220 /* don't record anonymous symbol */
221 if (v < SYM_FIRST_ANOM) {
222 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
223 /* modify the top most local identifier, so that
224 sym_identifier will point to 's' when popped */
225 while (*ps != NULL)
226 ps = &(*ps)->prev_tok;
227 s->prev_tok = NULL;
228 *ps = s;
230 return s;
233 /* pop symbols until top reaches 'b' */
234 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
236 Sym *s, *ss, **ps;
237 TokenSym *ts;
238 int v;
240 s = *ptop;
241 while(s != b) {
242 ss = s->prev;
243 v = s->v;
244 /* remove symbol in token array */
245 /* XXX: simplify */
246 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
247 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
248 if (v & SYM_STRUCT)
249 ps = &ts->sym_struct;
250 else
251 ps = &ts->sym_identifier;
252 *ps = s->prev_tok;
254 sym_free(s);
255 s = ss;
257 *ptop = b;
260 static void weaken_symbol(Sym *sym)
262 sym->type.t |= VT_WEAK;
263 if (sym->c > 0) {
264 int esym_type;
265 ElfW(Sym) *esym;
267 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
268 esym_type = ELFW(ST_TYPE)(esym->st_info);
269 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
273 /* ------------------------------------------------------------------------- */
275 ST_FUNC void swap(int *p, int *q)
277 int t;
278 t = *p;
279 *p = *q;
280 *q = t;
283 static void vsetc(CType *type, int r, CValue *vc)
285 int v;
287 if (vtop >= vstack + (VSTACK_SIZE - 1))
288 error("memory full");
289 /* cannot let cpu flags if other instruction are generated. Also
290 avoid leaving VT_JMP anywhere except on the top of the stack
291 because it would complicate the code generator. */
292 if (vtop >= vstack) {
293 v = vtop->r & VT_VALMASK;
294 if (v == VT_CMP || (v & ~1) == VT_JMP)
295 gv(RC_INT);
297 vtop++;
298 vtop->type = *type;
299 vtop->r = r;
300 vtop->r2 = VT_CONST;
301 vtop->c = *vc;
304 /* push constant of type "type" with useless value */
305 void vpush(CType *type)
307 CValue cval;
308 vsetc(type, VT_CONST, &cval);
311 /* push integer constant */
312 ST_FUNC void vpushi(int v)
314 CValue cval;
315 cval.i = v;
316 vsetc(&int_type, VT_CONST, &cval);
319 /* push long long constant */
320 static void vpushll(long long v)
322 CValue cval;
323 CType ctype;
324 ctype.t = VT_LLONG;
325 ctype.ref = 0;
326 cval.ull = v;
327 vsetc(&ctype, VT_CONST, &cval);
330 /* push arbitrary 64bit constant */
331 void vpush64(int ty, unsigned long long v)
333 CValue cval;
334 CType ctype;
335 ctype.t = ty;
336 cval.ull = v;
337 vsetc(&ctype, VT_CONST, &cval);
340 /* Return a static symbol pointing to a section */
341 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
343 int v;
344 Sym *sym;
346 v = anon_sym++;
347 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
348 sym->type.ref = type->ref;
349 sym->r = VT_CONST | VT_SYM;
350 put_extern_sym(sym, sec, offset, size);
351 return sym;
354 /* push a reference to a section offset by adding a dummy symbol */
355 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
357 CValue cval;
359 cval.ul = 0;
360 vsetc(type, VT_CONST | VT_SYM, &cval);
361 vtop->sym = get_sym_ref(type, sec, offset, size);
364 /* define a new external reference to a symbol 'v' of type 'u' */
365 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
367 Sym *s;
369 s = sym_find(v);
370 if (!s) {
371 /* push forward reference */
372 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
373 s->type.ref = type->ref;
374 s->r = r | VT_CONST | VT_SYM;
376 return s;
379 /* define a new external reference to a symbol 'v' with alternate asm
380 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
381 is no alternate name (most cases) */
382 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
384 Sym *s;
386 s = sym_find(v);
387 if (!s) {
388 /* push forward reference */
389 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
390 s->asm_label = asm_label;
391 s->type.t |= VT_EXTERN;
392 } else if (s->type.ref == func_old_type.ref) {
393 s->type.ref = type->ref;
394 s->r = r | VT_CONST | VT_SYM;
395 s->type.t |= VT_EXTERN;
396 } else if (!is_compatible_types(&s->type, type)) {
397 error("incompatible types for redefinition of '%s'",
398 get_tok_str(v, NULL));
400 return s;
403 /* push a reference to global symbol v */
404 ST_FUNC void vpush_global_sym(CType *type, int v)
406 Sym *sym;
407 CValue cval;
409 sym = external_global_sym(v, type, 0);
410 cval.ul = 0;
411 vsetc(type, VT_CONST | VT_SYM, &cval);
412 vtop->sym = sym;
415 ST_FUNC void vset(CType *type, int r, int v)
417 CValue cval;
419 cval.i = v;
420 vsetc(type, r, &cval);
423 static void vseti(int r, int v)
425 CType type;
426 type.t = VT_INT;
427 type.ref = 0;
428 vset(&type, r, v);
431 ST_FUNC void vswap(void)
433 SValue tmp;
435 tmp = vtop[0];
436 vtop[0] = vtop[-1];
437 vtop[-1] = tmp;
440 ST_FUNC void vpushv(SValue *v)
442 if (vtop >= vstack + (VSTACK_SIZE - 1))
443 error("memory full");
444 vtop++;
445 *vtop = *v;
448 static void vdup(void)
450 vpushv(vtop);
453 /* save r to the memory stack, and mark it as being free */
454 ST_FUNC void save_reg(int r)
456 int l, saved, size, align;
457 SValue *p, sv;
458 CType *type;
460 /* modify all stack values */
461 saved = 0;
462 l = 0;
463 for(p=vstack;p<=vtop;p++) {
464 if ((p->r & VT_VALMASK) == r ||
465 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
466 /* must save value on stack if not already done */
467 if (!saved) {
468 /* NOTE: must reload 'r' because r might be equal to r2 */
469 r = p->r & VT_VALMASK;
470 /* store register in the stack */
471 type = &p->type;
472 if ((p->r & VT_LVAL) ||
473 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
474 #ifdef TCC_TARGET_X86_64
475 type = &char_pointer_type;
476 #else
477 type = &int_type;
478 #endif
479 size = type_size(type, &align);
480 loc = (loc - size) & -align;
481 sv.type.t = type->t;
482 sv.r = VT_LOCAL | VT_LVAL;
483 sv.c.ul = loc;
484 store(r, &sv);
485 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
486 /* x86 specific: need to pop fp register ST0 if saved */
487 if (r == TREG_ST0) {
488 o(0xd8dd); /* fstp %st(0) */
490 #endif
491 #ifndef TCC_TARGET_X86_64
492 /* special long long case */
493 if ((type->t & VT_BTYPE) == VT_LLONG) {
494 sv.c.ul += 4;
495 store(p->r2, &sv);
497 #endif
498 l = loc;
499 saved = 1;
501 /* mark that stack entry as being saved on the stack */
502 if (p->r & VT_LVAL) {
503 /* also clear the bounded flag because the
504 relocation address of the function was stored in
505 p->c.ul */
506 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
507 } else {
508 p->r = lvalue_type(p->type.t) | VT_LOCAL;
510 p->r2 = VT_CONST;
511 p->c.ul = l;
516 #ifdef TCC_TARGET_ARM
517 /* find a register of class 'rc2' with at most one reference on stack.
518 * If none, call get_reg(rc) */
519 ST_FUNC int get_reg_ex(int rc, int rc2)
521 int r;
522 SValue *p;
524 for(r=0;r<NB_REGS;r++) {
525 if (reg_classes[r] & rc2) {
526 int n;
527 n=0;
528 for(p = vstack; p <= vtop; p++) {
529 if ((p->r & VT_VALMASK) == r ||
530 (p->r2 & VT_VALMASK) == r)
531 n++;
533 if (n <= 1)
534 return r;
537 return get_reg(rc);
539 #endif
541 /* find a free register of class 'rc'. If none, save one register */
542 ST_FUNC int get_reg(int rc)
544 int r;
545 SValue *p;
547 /* find a free register */
548 for(r=0;r<NB_REGS;r++) {
549 if (reg_classes[r] & rc) {
550 for(p=vstack;p<=vtop;p++) {
551 if ((p->r & VT_VALMASK) == r ||
552 (p->r2 & VT_VALMASK) == r)
553 goto notfound;
555 return r;
557 notfound: ;
560 /* no register left : free the first one on the stack (VERY
561 IMPORTANT to start from the bottom to ensure that we don't
562 spill registers used in gen_opi()) */
563 for(p=vstack;p<=vtop;p++) {
564 r = p->r & VT_VALMASK;
565 if (r < VT_CONST && (reg_classes[r] & rc))
566 goto save_found;
567 /* also look at second register (if long long) */
568 r = p->r2 & VT_VALMASK;
569 if (r < VT_CONST && (reg_classes[r] & rc)) {
570 save_found:
571 save_reg(r);
572 return r;
575 /* Should never comes here */
576 return -1;
579 /* save registers up to (vtop - n) stack entry */
580 ST_FUNC void save_regs(int n)
582 int r;
583 SValue *p, *p1;
584 p1 = vtop - n;
585 for(p = vstack;p <= p1; p++) {
586 r = p->r & VT_VALMASK;
587 if (r < VT_CONST) {
588 save_reg(r);
593 /* move register 's' to 'r', and flush previous value of r to memory
594 if needed */
595 static void move_reg(int r, int s)
597 SValue sv;
599 if (r != s) {
600 save_reg(r);
601 sv.type.t = VT_INT;
602 sv.r = s;
603 sv.c.ul = 0;
604 load(r, &sv);
608 /* get address of vtop (vtop MUST BE an lvalue) */
609 static void gaddrof(void)
611 vtop->r &= ~VT_LVAL;
612 /* tricky: if saved lvalue, then we can go back to lvalue */
613 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
614 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
617 #ifdef CONFIG_TCC_BCHECK
618 /* generate lvalue bound code */
619 static void gbound(void)
621 int lval_type;
622 CType type1;
624 vtop->r &= ~VT_MUSTBOUND;
625 /* if lvalue, then use checking code before dereferencing */
626 if (vtop->r & VT_LVAL) {
627 /* if not VT_BOUNDED value, then make one */
628 if (!(vtop->r & VT_BOUNDED)) {
629 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
630 /* must save type because we must set it to int to get pointer */
631 type1 = vtop->type;
632 vtop->type.t = VT_INT;
633 gaddrof();
634 vpushi(0);
635 gen_bounded_ptr_add();
636 vtop->r |= lval_type;
637 vtop->type = type1;
639 /* then check for dereferencing */
640 gen_bounded_ptr_deref();
643 #endif
645 /* store vtop a register belonging to class 'rc'. lvalues are
646 converted to values. Cannot be used if cannot be converted to
647 register value (such as structures). */
648 ST_FUNC int gv(int rc)
650 int r, rc2, bit_pos, bit_size, size, align, i;
652 /* NOTE: get_reg can modify vstack[] */
653 if (vtop->type.t & VT_BITFIELD) {
654 CType type;
655 int bits = 32;
656 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
657 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
658 /* remove bit field info to avoid loops */
659 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
660 /* cast to int to propagate signedness in following ops */
661 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
662 type.t = VT_LLONG;
663 bits = 64;
664 } else
665 type.t = VT_INT;
666 if((vtop->type.t & VT_UNSIGNED) ||
667 (vtop->type.t & VT_BTYPE) == VT_BOOL)
668 type.t |= VT_UNSIGNED;
669 gen_cast(&type);
670 /* generate shifts */
671 vpushi(bits - (bit_pos + bit_size));
672 gen_op(TOK_SHL);
673 vpushi(bits - bit_size);
674 /* NOTE: transformed to SHR if unsigned */
675 gen_op(TOK_SAR);
676 r = gv(rc);
677 } else {
678 if (is_float(vtop->type.t) &&
679 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
680 Sym *sym;
681 int *ptr;
682 unsigned long offset;
683 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
684 CValue check;
685 #endif
687 /* XXX: unify with initializers handling ? */
688 /* CPUs usually cannot use float constants, so we store them
689 generically in data segment */
690 size = type_size(&vtop->type, &align);
691 offset = (data_section->data_offset + align - 1) & -align;
692 data_section->data_offset = offset;
693 /* XXX: not portable yet */
694 #if defined(__i386__) || defined(__x86_64__)
695 /* Zero pad x87 tenbyte long doubles */
696 if (size == LDOUBLE_SIZE)
697 vtop->c.tab[2] &= 0xffff;
698 #endif
699 ptr = section_ptr_add(data_section, size);
700 size = size >> 2;
701 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
702 check.d = 1;
703 if(check.tab[0])
704 for(i=0;i<size;i++)
705 ptr[i] = vtop->c.tab[size-1-i];
706 else
707 #endif
708 for(i=0;i<size;i++)
709 ptr[i] = vtop->c.tab[i];
710 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
711 vtop->r |= VT_LVAL | VT_SYM;
712 vtop->sym = sym;
713 vtop->c.ul = 0;
715 #ifdef CONFIG_TCC_BCHECK
716 if (vtop->r & VT_MUSTBOUND)
717 gbound();
718 #endif
720 r = vtop->r & VT_VALMASK;
721 rc2 = RC_INT;
722 if (rc == RC_IRET)
723 rc2 = RC_LRET;
724 /* need to reload if:
725 - constant
726 - lvalue (need to dereference pointer)
727 - already a register, but not in the right class */
728 if (r >= VT_CONST
729 || (vtop->r & VT_LVAL)
730 || !(reg_classes[r] & rc)
731 #ifndef TCC_TARGET_X86_64
732 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
733 #endif
736 r = get_reg(rc);
737 #ifndef TCC_TARGET_X86_64
738 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
739 int r2;
740 unsigned long long ll;
741 /* two register type load : expand to two words
742 temporarily */
743 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
744 /* load constant */
745 ll = vtop->c.ull;
746 vtop->c.ui = ll; /* first word */
747 load(r, vtop);
748 vtop->r = r; /* save register value */
749 vpushi(ll >> 32); /* second word */
750 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
751 (vtop->r & VT_LVAL)) {
752 /* We do not want to modifier the long long
753 pointer here, so the safest (and less
754 efficient) is to save all the other registers
755 in the stack. XXX: totally inefficient. */
756 save_regs(1);
757 /* load from memory */
758 load(r, vtop);
759 vdup();
760 vtop[-1].r = r; /* save register value */
761 /* increment pointer to get second word */
762 vtop->type.t = VT_INT;
763 gaddrof();
764 vpushi(4);
765 gen_op('+');
766 vtop->r |= VT_LVAL;
767 } else {
768 /* move registers */
769 load(r, vtop);
770 vdup();
771 vtop[-1].r = r; /* save register value */
772 vtop->r = vtop[-1].r2;
774 /* allocate second register */
775 r2 = get_reg(rc2);
776 load(r2, vtop);
777 vpop();
778 /* write second register */
779 vtop->r2 = r2;
780 } else
781 #endif
782 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
783 int t1, t;
784 /* lvalue of scalar type : need to use lvalue type
785 because of possible cast */
786 t = vtop->type.t;
787 t1 = t;
788 /* compute memory access type */
789 if (vtop->r & VT_LVAL_BYTE)
790 t = VT_BYTE;
791 else if (vtop->r & VT_LVAL_SHORT)
792 t = VT_SHORT;
793 if (vtop->r & VT_LVAL_UNSIGNED)
794 t |= VT_UNSIGNED;
795 vtop->type.t = t;
796 load(r, vtop);
797 /* restore wanted type */
798 vtop->type.t = t1;
799 } else {
800 /* one register type load */
801 load(r, vtop);
804 vtop->r = r;
805 #ifdef TCC_TARGET_C67
806 /* uses register pairs for doubles */
807 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
808 vtop->r2 = r+1;
809 #endif
811 return r;
814 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
815 ST_FUNC void gv2(int rc1, int rc2)
817 int v;
819 /* generate more generic register first. But VT_JMP or VT_CMP
820 values must be generated first in all cases to avoid possible
821 reload errors */
822 v = vtop[0].r & VT_VALMASK;
823 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
824 vswap();
825 gv(rc1);
826 vswap();
827 gv(rc2);
828 /* test if reload is needed for first register */
829 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
830 vswap();
831 gv(rc1);
832 vswap();
834 } else {
835 gv(rc2);
836 vswap();
837 gv(rc1);
838 vswap();
839 /* test if reload is needed for first register */
840 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
841 gv(rc2);
846 /* wrapper around RC_FRET to return a register by type */
847 static int rc_fret(int t)
849 #ifdef TCC_TARGET_X86_64
850 if (t == VT_LDOUBLE) {
851 return RC_ST0;
853 #endif
854 return RC_FRET;
857 /* wrapper around REG_FRET to return a register by type */
858 static int reg_fret(int t)
860 #ifdef TCC_TARGET_X86_64
861 if (t == VT_LDOUBLE) {
862 return TREG_ST0;
864 #endif
865 return REG_FRET;
868 /* expand long long on stack in two int registers */
869 static void lexpand(void)
871 int u;
873 u = vtop->type.t & VT_UNSIGNED;
874 gv(RC_INT);
875 vdup();
876 vtop[0].r = vtop[-1].r2;
877 vtop[0].r2 = VT_CONST;
878 vtop[-1].r2 = VT_CONST;
879 vtop[0].type.t = VT_INT | u;
880 vtop[-1].type.t = VT_INT | u;
883 #ifdef TCC_TARGET_ARM
884 /* expand long long on stack */
885 ST_FUNC void lexpand_nr(void)
887 int u,v;
889 u = vtop->type.t & VT_UNSIGNED;
890 vdup();
891 vtop->r2 = VT_CONST;
892 vtop->type.t = VT_INT | u;
893 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
894 if (v == VT_CONST) {
895 vtop[-1].c.ui = vtop->c.ull;
896 vtop->c.ui = vtop->c.ull >> 32;
897 vtop->r = VT_CONST;
898 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
899 vtop->c.ui += 4;
900 vtop->r = vtop[-1].r;
901 } else if (v > VT_CONST) {
902 vtop--;
903 lexpand();
904 } else
905 vtop->r = vtop[-1].r2;
906 vtop[-1].r2 = VT_CONST;
907 vtop[-1].type.t = VT_INT | u;
909 #endif
911 /* build a long long from two ints */
912 static void lbuild(int t)
914 gv2(RC_INT, RC_INT);
915 vtop[-1].r2 = vtop[0].r;
916 vtop[-1].type.t = t;
917 vpop();
920 /* rotate n first stack elements to the bottom
921 I1 ... In -> I2 ... In I1 [top is right]
923 static void vrotb(int n)
925 int i;
926 SValue tmp;
928 tmp = vtop[-n + 1];
929 for(i=-n+1;i!=0;i++)
930 vtop[i] = vtop[i+1];
931 vtop[0] = tmp;
934 /* rotate n first stack elements to the top
935 I1 ... In -> In I1 ... I(n-1) [top is right]
937 ST_FUNC void vrott(int n)
939 int i;
940 SValue tmp;
942 tmp = vtop[0];
943 for(i = 0;i < n - 1; i++)
944 vtop[-i] = vtop[-i - 1];
945 vtop[-n + 1] = tmp;
948 #ifdef TCC_TARGET_ARM
949 /* like vrott but in other direction
950 In ... I1 -> I(n-1) ... I1 In [top is right]
952 ST_FUNC void vnrott(int n)
954 int i;
955 SValue tmp;
957 tmp = vtop[-n + 1];
958 for(i = n - 1; i > 0; i--)
959 vtop[-i] = vtop[-i + 1];
960 vtop[0] = tmp;
962 #endif
964 /* pop stack value */
965 ST_FUNC void vpop(void)
967 int v;
968 v = vtop->r & VT_VALMASK;
969 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
970 /* for x86, we need to pop the FP stack */
971 if (v == TREG_ST0 && !nocode_wanted) {
972 o(0xd8dd); /* fstp %st(0) */
973 } else
974 #endif
975 if (v == VT_JMP || v == VT_JMPI) {
976 /* need to put correct jump if && or || without test */
977 gsym(vtop->c.ul);
979 vtop--;
982 /* convert stack entry to register and duplicate its value in another
983 register */
984 static void gv_dup(void)
986 int rc, t, r, r1;
987 SValue sv;
989 t = vtop->type.t;
990 if ((t & VT_BTYPE) == VT_LLONG) {
991 lexpand();
992 gv_dup();
993 vswap();
994 vrotb(3);
995 gv_dup();
996 vrotb(4);
997 /* stack: H L L1 H1 */
998 lbuild(t);
999 vrotb(3);
1000 vrotb(3);
1001 vswap();
1002 lbuild(t);
1003 vswap();
1004 } else {
1005 /* duplicate value */
1006 rc = RC_INT;
1007 sv.type.t = VT_INT;
1008 if (is_float(t)) {
1009 rc = RC_FLOAT;
1010 #ifdef TCC_TARGET_X86_64
1011 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1012 rc = RC_ST0;
1014 #endif
1015 sv.type.t = t;
1017 r = gv(rc);
1018 r1 = get_reg(rc);
1019 sv.r = r;
1020 sv.c.ul = 0;
1021 load(r1, &sv); /* move r to r1 */
1022 vdup();
1023 /* duplicates value */
1024 if (r != r1)
1025 vtop->r = r1;
1029 #ifndef TCC_TARGET_X86_64
1030 /* generate CPU independent (unsigned) long long operations */
1031 static void gen_opl(int op)
1033 int t, a, b, op1, c, i;
1034 int func;
1035 unsigned short reg_iret = REG_IRET;
1036 unsigned short reg_lret = REG_LRET;
1037 SValue tmp;
1039 switch(op) {
1040 case '/':
1041 case TOK_PDIV:
1042 func = TOK___divdi3;
1043 goto gen_func;
1044 case TOK_UDIV:
1045 func = TOK___udivdi3;
1046 goto gen_func;
1047 case '%':
1048 func = TOK___moddi3;
1049 goto gen_mod_func;
1050 case TOK_UMOD:
1051 func = TOK___umoddi3;
1052 gen_mod_func:
1053 #ifdef TCC_ARM_EABI
1054 reg_iret = TREG_R2;
1055 reg_lret = TREG_R3;
1056 #endif
1057 gen_func:
1058 /* call generic long long function */
1059 vpush_global_sym(&func_old_type, func);
1060 vrott(3);
1061 gfunc_call(2);
1062 vpushi(0);
1063 vtop->r = reg_iret;
1064 vtop->r2 = reg_lret;
1065 break;
1066 case '^':
1067 case '&':
1068 case '|':
1069 case '*':
1070 case '+':
1071 case '-':
1072 t = vtop->type.t;
1073 vswap();
1074 lexpand();
1075 vrotb(3);
1076 lexpand();
1077 /* stack: L1 H1 L2 H2 */
1078 tmp = vtop[0];
1079 vtop[0] = vtop[-3];
1080 vtop[-3] = tmp;
1081 tmp = vtop[-2];
1082 vtop[-2] = vtop[-3];
1083 vtop[-3] = tmp;
1084 vswap();
1085 /* stack: H1 H2 L1 L2 */
1086 if (op == '*') {
1087 vpushv(vtop - 1);
1088 vpushv(vtop - 1);
1089 gen_op(TOK_UMULL);
1090 lexpand();
1091 /* stack: H1 H2 L1 L2 ML MH */
1092 for(i=0;i<4;i++)
1093 vrotb(6);
1094 /* stack: ML MH H1 H2 L1 L2 */
1095 tmp = vtop[0];
1096 vtop[0] = vtop[-2];
1097 vtop[-2] = tmp;
1098 /* stack: ML MH H1 L2 H2 L1 */
1099 gen_op('*');
1100 vrotb(3);
1101 vrotb(3);
1102 gen_op('*');
1103 /* stack: ML MH M1 M2 */
1104 gen_op('+');
1105 gen_op('+');
1106 } else if (op == '+' || op == '-') {
1107 /* XXX: add non carry method too (for MIPS or alpha) */
1108 if (op == '+')
1109 op1 = TOK_ADDC1;
1110 else
1111 op1 = TOK_SUBC1;
1112 gen_op(op1);
1113 /* stack: H1 H2 (L1 op L2) */
1114 vrotb(3);
1115 vrotb(3);
1116 gen_op(op1 + 1); /* TOK_xxxC2 */
1117 } else {
1118 gen_op(op);
1119 /* stack: H1 H2 (L1 op L2) */
1120 vrotb(3);
1121 vrotb(3);
1122 /* stack: (L1 op L2) H1 H2 */
1123 gen_op(op);
1124 /* stack: (L1 op L2) (H1 op H2) */
1126 /* stack: L H */
1127 lbuild(t);
1128 break;
1129 case TOK_SAR:
1130 case TOK_SHR:
1131 case TOK_SHL:
1132 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1133 t = vtop[-1].type.t;
1134 vswap();
1135 lexpand();
1136 vrotb(3);
1137 /* stack: L H shift */
1138 c = (int)vtop->c.i;
1139 /* constant: simpler */
1140 /* NOTE: all comments are for SHL. the other cases are
1141 done by swaping words */
1142 vpop();
1143 if (op != TOK_SHL)
1144 vswap();
1145 if (c >= 32) {
1146 /* stack: L H */
1147 vpop();
1148 if (c > 32) {
1149 vpushi(c - 32);
1150 gen_op(op);
1152 if (op != TOK_SAR) {
1153 vpushi(0);
1154 } else {
1155 gv_dup();
1156 vpushi(31);
1157 gen_op(TOK_SAR);
1159 vswap();
1160 } else {
1161 vswap();
1162 gv_dup();
1163 /* stack: H L L */
1164 vpushi(c);
1165 gen_op(op);
1166 vswap();
1167 vpushi(32 - c);
1168 if (op == TOK_SHL)
1169 gen_op(TOK_SHR);
1170 else
1171 gen_op(TOK_SHL);
1172 vrotb(3);
1173 /* stack: L L H */
1174 vpushi(c);
1175 if (op == TOK_SHL)
1176 gen_op(TOK_SHL);
1177 else
1178 gen_op(TOK_SHR);
1179 gen_op('|');
1181 if (op != TOK_SHL)
1182 vswap();
1183 lbuild(t);
1184 } else {
1185 /* XXX: should provide a faster fallback on x86 ? */
1186 switch(op) {
1187 case TOK_SAR:
1188 func = TOK___ashrdi3;
1189 goto gen_func;
1190 case TOK_SHR:
1191 func = TOK___lshrdi3;
1192 goto gen_func;
1193 case TOK_SHL:
1194 func = TOK___ashldi3;
1195 goto gen_func;
1198 break;
1199 default:
1200 /* compare operations */
1201 t = vtop->type.t;
1202 vswap();
1203 lexpand();
1204 vrotb(3);
1205 lexpand();
1206 /* stack: L1 H1 L2 H2 */
1207 tmp = vtop[-1];
1208 vtop[-1] = vtop[-2];
1209 vtop[-2] = tmp;
1210 /* stack: L1 L2 H1 H2 */
1211 /* compare high */
1212 op1 = op;
1213 /* when values are equal, we need to compare low words. since
1214 the jump is inverted, we invert the test too. */
1215 if (op1 == TOK_LT)
1216 op1 = TOK_LE;
1217 else if (op1 == TOK_GT)
1218 op1 = TOK_GE;
1219 else if (op1 == TOK_ULT)
1220 op1 = TOK_ULE;
1221 else if (op1 == TOK_UGT)
1222 op1 = TOK_UGE;
1223 a = 0;
1224 b = 0;
1225 gen_op(op1);
1226 if (op1 != TOK_NE) {
1227 a = gtst(1, 0);
1229 if (op != TOK_EQ) {
1230 /* generate non equal test */
1231 /* XXX: NOT PORTABLE yet */
1232 if (a == 0) {
1233 b = gtst(0, 0);
1234 } else {
1235 #if defined(TCC_TARGET_I386)
1236 b = psym(0x850f, 0);
1237 #elif defined(TCC_TARGET_ARM)
1238 b = ind;
1239 o(0x1A000000 | encbranch(ind, 0, 1));
1240 #elif defined(TCC_TARGET_C67)
1241 error("not implemented");
1242 #else
1243 #error not supported
1244 #endif
1247 /* compare low. Always unsigned */
1248 op1 = op;
1249 if (op1 == TOK_LT)
1250 op1 = TOK_ULT;
1251 else if (op1 == TOK_LE)
1252 op1 = TOK_ULE;
1253 else if (op1 == TOK_GT)
1254 op1 = TOK_UGT;
1255 else if (op1 == TOK_GE)
1256 op1 = TOK_UGE;
1257 gen_op(op1);
1258 a = gtst(1, a);
1259 gsym(b);
1260 vseti(VT_JMPI, a);
1261 break;
1264 #endif
1266 /* handle integer constant optimizations and various machine
1267 independent opt */
1268 static void gen_opic(int op)
1270 int c1, c2, t1, t2, n;
1271 SValue *v1, *v2;
1272 long long l1, l2;
1273 typedef unsigned long long U;
1275 v1 = vtop - 1;
1276 v2 = vtop;
1277 t1 = v1->type.t & VT_BTYPE;
1278 t2 = v2->type.t & VT_BTYPE;
1280 if (t1 == VT_LLONG)
1281 l1 = v1->c.ll;
1282 else if (v1->type.t & VT_UNSIGNED)
1283 l1 = v1->c.ui;
1284 else
1285 l1 = v1->c.i;
1287 if (t2 == VT_LLONG)
1288 l2 = v2->c.ll;
1289 else if (v2->type.t & VT_UNSIGNED)
1290 l2 = v2->c.ui;
1291 else
1292 l2 = v2->c.i;
1294 /* currently, we cannot do computations with forward symbols */
1295 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1296 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1297 if (c1 && c2) {
1298 switch(op) {
1299 case '+': l1 += l2; break;
1300 case '-': l1 -= l2; break;
1301 case '&': l1 &= l2; break;
1302 case '^': l1 ^= l2; break;
1303 case '|': l1 |= l2; break;
1304 case '*': l1 *= l2; break;
1306 case TOK_PDIV:
1307 case '/':
1308 case '%':
1309 case TOK_UDIV:
1310 case TOK_UMOD:
1311 /* if division by zero, generate explicit division */
1312 if (l2 == 0) {
1313 if (const_wanted)
1314 error("division by zero in constant");
1315 goto general_case;
1317 switch(op) {
1318 default: l1 /= l2; break;
1319 case '%': l1 %= l2; break;
1320 case TOK_UDIV: l1 = (U)l1 / l2; break;
1321 case TOK_UMOD: l1 = (U)l1 % l2; break;
1323 break;
1324 case TOK_SHL: l1 <<= l2; break;
1325 case TOK_SHR: l1 = (U)l1 >> l2; break;
1326 case TOK_SAR: l1 >>= l2; break;
1327 /* tests */
1328 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1329 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1330 case TOK_EQ: l1 = l1 == l2; break;
1331 case TOK_NE: l1 = l1 != l2; break;
1332 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1333 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1334 case TOK_LT: l1 = l1 < l2; break;
1335 case TOK_GE: l1 = l1 >= l2; break;
1336 case TOK_LE: l1 = l1 <= l2; break;
1337 case TOK_GT: l1 = l1 > l2; break;
1338 /* logical */
1339 case TOK_LAND: l1 = l1 && l2; break;
1340 case TOK_LOR: l1 = l1 || l2; break;
1341 default:
1342 goto general_case;
1344 v1->c.ll = l1;
1345 vtop--;
1346 } else {
1347 /* if commutative ops, put c2 as constant */
1348 if (c1 && (op == '+' || op == '&' || op == '^' ||
1349 op == '|' || op == '*')) {
1350 vswap();
1351 c2 = c1; //c = c1, c1 = c2, c2 = c;
1352 l2 = l1; //l = l1, l1 = l2, l2 = l;
1354 /* Filter out NOP operations like x*1, x-0, x&-1... */
1355 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1356 op == TOK_PDIV) &&
1357 l2 == 1) ||
1358 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1359 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1360 l2 == 0) ||
1361 (op == '&' &&
1362 l2 == -1))) {
1363 /* nothing to do */
1364 vtop--;
1365 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1366 /* try to use shifts instead of muls or divs */
1367 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1368 n = -1;
1369 while (l2) {
1370 l2 >>= 1;
1371 n++;
1373 vtop->c.ll = n;
1374 if (op == '*')
1375 op = TOK_SHL;
1376 else if (op == TOK_PDIV)
1377 op = TOK_SAR;
1378 else
1379 op = TOK_SHR;
1381 goto general_case;
1382 } else if (c2 && (op == '+' || op == '-') &&
1383 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1384 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1385 /* symbol + constant case */
1386 if (op == '-')
1387 l2 = -l2;
1388 vtop--;
1389 vtop->c.ll += l2;
1390 } else {
1391 general_case:
1392 if (!nocode_wanted) {
1393 /* call low level op generator */
1394 if (t1 == VT_LLONG || t2 == VT_LLONG)
1395 gen_opl(op);
1396 else
1397 gen_opi(op);
1398 } else {
1399 vtop--;
1405 /* generate a floating point operation with constant propagation */
1406 static void gen_opif(int op)
1408 int c1, c2;
1409 SValue *v1, *v2;
1410 long double f1, f2;
1412 v1 = vtop - 1;
1413 v2 = vtop;
1414 /* currently, we cannot do computations with forward symbols */
1415 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1416 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1417 if (c1 && c2) {
1418 if (v1->type.t == VT_FLOAT) {
1419 f1 = v1->c.f;
1420 f2 = v2->c.f;
1421 } else if (v1->type.t == VT_DOUBLE) {
1422 f1 = v1->c.d;
1423 f2 = v2->c.d;
1424 } else {
1425 f1 = v1->c.ld;
1426 f2 = v2->c.ld;
1429 /* NOTE: we only do constant propagation if finite number (not
1430 NaN or infinity) (ANSI spec) */
1431 if (!ieee_finite(f1) || !ieee_finite(f2))
1432 goto general_case;
1434 switch(op) {
1435 case '+': f1 += f2; break;
1436 case '-': f1 -= f2; break;
1437 case '*': f1 *= f2; break;
1438 case '/':
1439 if (f2 == 0.0) {
1440 if (const_wanted)
1441 error("division by zero in constant");
1442 goto general_case;
1444 f1 /= f2;
1445 break;
1446 /* XXX: also handles tests ? */
1447 default:
1448 goto general_case;
1450 /* XXX: overflow test ? */
1451 if (v1->type.t == VT_FLOAT) {
1452 v1->c.f = f1;
1453 } else if (v1->type.t == VT_DOUBLE) {
1454 v1->c.d = f1;
1455 } else {
1456 v1->c.ld = f1;
1458 vtop--;
1459 } else {
1460 general_case:
1461 if (!nocode_wanted) {
1462 gen_opf(op);
1463 } else {
1464 vtop--;
1469 static int pointed_size(CType *type)
1471 int align;
1472 return type_size(pointed_type(type), &align);
1475 static void vla_runtime_pointed_size(CType *type)
1477 int align;
1478 vla_runtime_type_size(pointed_type(type), &align);
1481 static inline int is_null_pointer(SValue *p)
1483 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1484 return 0;
1485 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1486 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1489 static inline int is_integer_btype(int bt)
1491 return (bt == VT_BYTE || bt == VT_SHORT ||
1492 bt == VT_INT || bt == VT_LLONG);
1495 /* check types for comparison or substraction of pointers */
1496 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1498 CType *type1, *type2, tmp_type1, tmp_type2;
1499 int bt1, bt2;
1501 /* null pointers are accepted for all comparisons as gcc */
1502 if (is_null_pointer(p1) || is_null_pointer(p2))
1503 return;
1504 type1 = &p1->type;
1505 type2 = &p2->type;
1506 bt1 = type1->t & VT_BTYPE;
1507 bt2 = type2->t & VT_BTYPE;
1508 /* accept comparison between pointer and integer with a warning */
1509 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1510 if (op != TOK_LOR && op != TOK_LAND )
1511 warning("comparison between pointer and integer");
1512 return;
1515 /* both must be pointers or implicit function pointers */
1516 if (bt1 == VT_PTR) {
1517 type1 = pointed_type(type1);
1518 } else if (bt1 != VT_FUNC)
1519 goto invalid_operands;
1521 if (bt2 == VT_PTR) {
1522 type2 = pointed_type(type2);
1523 } else if (bt2 != VT_FUNC) {
1524 invalid_operands:
1525 error("invalid operands to binary %s", get_tok_str(op, NULL));
1527 if ((type1->t & VT_BTYPE) == VT_VOID ||
1528 (type2->t & VT_BTYPE) == VT_VOID)
1529 return;
1530 tmp_type1 = *type1;
1531 tmp_type2 = *type2;
1532 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1533 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1534 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1535 /* gcc-like error if '-' is used */
1536 if (op == '-')
1537 goto invalid_operands;
1538 else
1539 warning("comparison of distinct pointer types lacks a cast");
1543 /* generic gen_op: handles types problems */
1544 ST_FUNC void gen_op(int op)
1546 int u, t1, t2, bt1, bt2, t;
1547 CType type1;
1549 t1 = vtop[-1].type.t;
1550 t2 = vtop[0].type.t;
1551 bt1 = t1 & VT_BTYPE;
1552 bt2 = t2 & VT_BTYPE;
1554 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1555 /* at least one operand is a pointer */
1556 /* relationnal op: must be both pointers */
1557 if (op >= TOK_ULT && op <= TOK_LOR) {
1558 check_comparison_pointer_types(vtop - 1, vtop, op);
1559 /* pointers are handled are unsigned */
1560 #ifdef TCC_TARGET_X86_64
1561 t = VT_LLONG | VT_UNSIGNED;
1562 #else
1563 t = VT_INT | VT_UNSIGNED;
1564 #endif
1565 goto std_op;
1567 /* if both pointers, then it must be the '-' op */
1568 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1569 int ptr1_is_vla;
1571 ptr1_is_vla = 0;
1572 if (op != '-')
1573 error("cannot use pointers here");
1574 check_comparison_pointer_types(vtop - 1, vtop, op);
1575 /* XXX: check that types are compatible */
1576 if (vtop[-1].type.t & VT_VLA) {
1577 vla_runtime_pointed_size(&vtop[-1].type);
1578 vrott(3);
1579 ptr1_is_vla = 1;
1580 } else {
1581 u = pointed_size(&vtop[-1].type);
1583 gen_opic(op);
1584 /* set to integer type */
1585 #ifdef TCC_TARGET_X86_64
1586 vtop->type.t = VT_LLONG;
1587 #else
1588 vtop->type.t = VT_INT;
1589 #endif
1590 if (ptr1_is_vla)
1591 vswap();
1592 else
1593 vpushi(u);
1594 gen_op(TOK_PDIV);
1595 } else {
1596 /* exactly one pointer : must be '+' or '-'. */
1597 if (op != '-' && op != '+')
1598 error("cannot use pointers here");
1599 /* Put pointer as first operand */
1600 if (bt2 == VT_PTR) {
1601 vswap();
1602 swap(&t1, &t2);
1604 type1 = vtop[-1].type;
1605 type1.t &= ~VT_ARRAY;
1606 if (vtop[-1].type.t & VT_VLA)
1607 vla_runtime_pointed_size(&vtop[-1].type);
1608 else {
1609 u = pointed_size(&vtop[-1].type);
1610 if (u < 0)
1611 error("unknown array element size");
1612 #ifdef TCC_TARGET_X86_64
1613 vpushll(u);
1614 #else
1615 /* XXX: cast to int ? (long long case) */
1616 vpushi(u);
1617 #endif
1619 gen_op('*');
1620 #ifdef CONFIG_TCC_BCHECK
1621 /* if evaluating constant expression, no code should be
1622 generated, so no bound check */
1623 if (tcc_state->do_bounds_check && !const_wanted) {
1624 /* if bounded pointers, we generate a special code to
1625 test bounds */
1626 if (op == '-') {
1627 vpushi(0);
1628 vswap();
1629 gen_op('-');
1631 gen_bounded_ptr_add();
1632 } else
1633 #endif
1635 gen_opic(op);
1637 /* put again type if gen_opic() swaped operands */
1638 vtop->type = type1;
1640 } else if (is_float(bt1) || is_float(bt2)) {
1641 /* compute bigger type and do implicit casts */
1642 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1643 t = VT_LDOUBLE;
1644 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1645 t = VT_DOUBLE;
1646 } else {
1647 t = VT_FLOAT;
1649 /* floats can only be used for a few operations */
1650 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1651 (op < TOK_ULT || op > TOK_GT))
1652 error("invalid operands for binary operation");
1653 goto std_op;
1654 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1655 /* cast to biggest op */
1656 t = VT_LLONG;
1657 /* convert to unsigned if it does not fit in a long long */
1658 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1659 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1660 t |= VT_UNSIGNED;
1661 goto std_op;
1662 } else {
1663 /* integer operations */
1664 t = VT_INT;
1665 /* convert to unsigned if it does not fit in an integer */
1666 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1667 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1668 t |= VT_UNSIGNED;
1669 std_op:
1670 /* XXX: currently, some unsigned operations are explicit, so
1671 we modify them here */
1672 if (t & VT_UNSIGNED) {
1673 if (op == TOK_SAR)
1674 op = TOK_SHR;
1675 else if (op == '/')
1676 op = TOK_UDIV;
1677 else if (op == '%')
1678 op = TOK_UMOD;
1679 else if (op == TOK_LT)
1680 op = TOK_ULT;
1681 else if (op == TOK_GT)
1682 op = TOK_UGT;
1683 else if (op == TOK_LE)
1684 op = TOK_ULE;
1685 else if (op == TOK_GE)
1686 op = TOK_UGE;
1688 vswap();
1689 type1.t = t;
1690 gen_cast(&type1);
1691 vswap();
1692 /* special case for shifts and long long: we keep the shift as
1693 an integer */
1694 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1695 type1.t = VT_INT;
1696 gen_cast(&type1);
1697 if (is_float(t))
1698 gen_opif(op);
1699 else
1700 gen_opic(op);
1701 if (op >= TOK_ULT && op <= TOK_GT) {
1702 /* relationnal op: the result is an int */
1703 vtop->type.t = VT_INT;
1704 } else {
1705 vtop->type.t = t;
1710 #ifndef TCC_TARGET_ARM
1711 /* generic itof for unsigned long long case */
1712 static void gen_cvt_itof1(int t)
1714 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1715 (VT_LLONG | VT_UNSIGNED)) {
1717 if (t == VT_FLOAT)
1718 vpush_global_sym(&func_old_type, TOK___floatundisf);
1719 #if LDOUBLE_SIZE != 8
1720 else if (t == VT_LDOUBLE)
1721 vpush_global_sym(&func_old_type, TOK___floatundixf);
1722 #endif
1723 else
1724 vpush_global_sym(&func_old_type, TOK___floatundidf);
1725 vrott(2);
1726 gfunc_call(1);
1727 vpushi(0);
1728 vtop->r = reg_fret(t);
1729 } else {
1730 gen_cvt_itof(t);
1733 #endif
1735 /* generic ftoi for unsigned long long case */
1736 static void gen_cvt_ftoi1(int t)
1738 int st;
1740 if (t == (VT_LLONG | VT_UNSIGNED)) {
1741 /* not handled natively */
1742 st = vtop->type.t & VT_BTYPE;
1743 if (st == VT_FLOAT)
1744 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1745 #if LDOUBLE_SIZE != 8
1746 else if (st == VT_LDOUBLE)
1747 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1748 #endif
1749 else
1750 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1751 vrott(2);
1752 gfunc_call(1);
1753 vpushi(0);
1754 vtop->r = REG_IRET;
1755 vtop->r2 = REG_LRET;
1756 } else {
1757 gen_cvt_ftoi(t);
1761 /* force char or short cast */
1762 static void force_charshort_cast(int t)
1764 int bits, dbt;
1765 dbt = t & VT_BTYPE;
1766 /* XXX: add optimization if lvalue : just change type and offset */
1767 if (dbt == VT_BYTE)
1768 bits = 8;
1769 else
1770 bits = 16;
1771 if (t & VT_UNSIGNED) {
1772 vpushi((1 << bits) - 1);
1773 gen_op('&');
1774 } else {
1775 bits = 32 - bits;
1776 vpushi(bits);
1777 gen_op(TOK_SHL);
1778 /* result must be signed or the SAR is converted to an SHL
1779 This was not the case when "t" was a signed short
1780 and the last value on the stack was an unsigned int */
1781 vtop->type.t &= ~VT_UNSIGNED;
1782 vpushi(bits);
1783 gen_op(TOK_SAR);
1787 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1788 static void gen_cast(CType *type)
1790 int sbt, dbt, sf, df, c, p;
1792 /* special delayed cast for char/short */
1793 /* XXX: in some cases (multiple cascaded casts), it may still
1794 be incorrect */
1795 if (vtop->r & VT_MUSTCAST) {
1796 vtop->r &= ~VT_MUSTCAST;
1797 force_charshort_cast(vtop->type.t);
1800 /* bitfields first get cast to ints */
1801 if (vtop->type.t & VT_BITFIELD) {
1802 gv(RC_INT);
1805 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1806 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1808 if (sbt != dbt) {
1809 sf = is_float(sbt);
1810 df = is_float(dbt);
1811 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1812 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1813 if (c) {
1814 /* constant case: we can do it now */
1815 /* XXX: in ISOC, cannot do it if error in convert */
1816 if (sbt == VT_FLOAT)
1817 vtop->c.ld = vtop->c.f;
1818 else if (sbt == VT_DOUBLE)
1819 vtop->c.ld = vtop->c.d;
1821 if (df) {
1822 if ((sbt & VT_BTYPE) == VT_LLONG) {
1823 if (sbt & VT_UNSIGNED)
1824 vtop->c.ld = vtop->c.ull;
1825 else
1826 vtop->c.ld = vtop->c.ll;
1827 } else if(!sf) {
1828 if (sbt & VT_UNSIGNED)
1829 vtop->c.ld = vtop->c.ui;
1830 else
1831 vtop->c.ld = vtop->c.i;
1834 if (dbt == VT_FLOAT)
1835 vtop->c.f = (float)vtop->c.ld;
1836 else if (dbt == VT_DOUBLE)
1837 vtop->c.d = (double)vtop->c.ld;
1838 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1839 vtop->c.ull = (unsigned long long)vtop->c.ld;
1840 } else if (sf && dbt == VT_BOOL) {
1841 vtop->c.i = (vtop->c.ld != 0);
1842 } else {
1843 if(sf)
1844 vtop->c.ll = (long long)vtop->c.ld;
1845 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1846 vtop->c.ll = vtop->c.ull;
1847 else if (sbt & VT_UNSIGNED)
1848 vtop->c.ll = vtop->c.ui;
1849 #ifdef TCC_TARGET_X86_64
1850 else if (sbt == VT_PTR)
1852 #endif
1853 else if (sbt != VT_LLONG)
1854 vtop->c.ll = vtop->c.i;
1856 if (dbt == (VT_LLONG|VT_UNSIGNED))
1857 vtop->c.ull = vtop->c.ll;
1858 else if (dbt == VT_BOOL)
1859 vtop->c.i = (vtop->c.ll != 0);
1860 else if (dbt != VT_LLONG) {
1861 int s = 0;
1862 if ((dbt & VT_BTYPE) == VT_BYTE)
1863 s = 24;
1864 else if ((dbt & VT_BTYPE) == VT_SHORT)
1865 s = 16;
1867 if(dbt & VT_UNSIGNED)
1868 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1869 else
1870 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1873 } else if (p && dbt == VT_BOOL) {
1874 vtop->r = VT_CONST;
1875 vtop->c.i = 1;
1876 } else if (!nocode_wanted) {
1877 /* non constant case: generate code */
1878 if (sf && df) {
1879 /* convert from fp to fp */
1880 gen_cvt_ftof(dbt);
1881 } else if (df) {
1882 /* convert int to fp */
1883 gen_cvt_itof1(dbt);
1884 } else if (sf) {
1885 /* convert fp to int */
1886 if (dbt == VT_BOOL) {
1887 vpushi(0);
1888 gen_op(TOK_NE);
1889 } else {
1890 /* we handle char/short/etc... with generic code */
1891 if (dbt != (VT_INT | VT_UNSIGNED) &&
1892 dbt != (VT_LLONG | VT_UNSIGNED) &&
1893 dbt != VT_LLONG)
1894 dbt = VT_INT;
1895 gen_cvt_ftoi1(dbt);
1896 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1897 /* additional cast for char/short... */
1898 vtop->type.t = dbt;
1899 gen_cast(type);
1902 #ifndef TCC_TARGET_X86_64
1903 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1904 if ((sbt & VT_BTYPE) != VT_LLONG) {
1905 /* scalar to long long */
1906 /* machine independent conversion */
1907 gv(RC_INT);
1908 /* generate high word */
1909 if (sbt == (VT_INT | VT_UNSIGNED)) {
1910 vpushi(0);
1911 gv(RC_INT);
1912 } else {
1913 if (sbt == VT_PTR) {
1914 /* cast from pointer to int before we apply
1915 shift operation, which pointers don't support*/
1916 gen_cast(&int_type);
1918 gv_dup();
1919 vpushi(31);
1920 gen_op(TOK_SAR);
1922 /* patch second register */
1923 vtop[-1].r2 = vtop->r;
1924 vpop();
1926 #else
1927 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1928 (dbt & VT_BTYPE) == VT_PTR ||
1929 (dbt & VT_BTYPE) == VT_FUNC) {
1930 if ((sbt & VT_BTYPE) != VT_LLONG &&
1931 (sbt & VT_BTYPE) != VT_PTR &&
1932 (sbt & VT_BTYPE) != VT_FUNC) {
1933 /* need to convert from 32bit to 64bit */
1934 int r = gv(RC_INT);
1935 if (sbt != (VT_INT | VT_UNSIGNED)) {
1936 /* x86_64 specific: movslq */
1937 o(0x6348);
1938 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1941 #endif
1942 } else if (dbt == VT_BOOL) {
1943 /* scalar to bool */
1944 vpushi(0);
1945 gen_op(TOK_NE);
1946 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1947 (dbt & VT_BTYPE) == VT_SHORT) {
1948 if (sbt == VT_PTR) {
1949 vtop->type.t = VT_INT;
1950 warning("nonportable conversion from pointer to char/short");
1952 force_charshort_cast(dbt);
1953 } else if ((dbt & VT_BTYPE) == VT_INT) {
1954 /* scalar to int */
1955 if (sbt == VT_LLONG) {
1956 /* from long long: just take low order word */
1957 lexpand();
1958 vpop();
1960 /* if lvalue and single word type, nothing to do because
1961 the lvalue already contains the real type size (see
1962 VT_LVAL_xxx constants) */
1965 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1966 /* if we are casting between pointer types,
1967 we must update the VT_LVAL_xxx size */
1968 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1969 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1971 vtop->type = *type;
1974 /* return type size as known at compile time. Put alignment at 'a' */
1975 ST_FUNC int type_size(CType *type, int *a)
1977 Sym *s;
1978 int bt;
1980 bt = type->t & VT_BTYPE;
1981 if (bt == VT_STRUCT) {
1982 /* struct/union */
1983 s = type->ref;
1984 *a = s->r;
1985 return s->c;
1986 } else if (bt == VT_PTR) {
1987 if (type->t & VT_ARRAY) {
1988 int ts;
1990 s = type->ref;
1991 ts = type_size(&s->type, a);
1993 if (ts < 0 && s->c < 0)
1994 ts = -ts;
1996 return ts * s->c;
1997 } else {
1998 *a = PTR_SIZE;
1999 return PTR_SIZE;
2001 } else if (bt == VT_LDOUBLE) {
2002 *a = LDOUBLE_ALIGN;
2003 return LDOUBLE_SIZE;
2004 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2005 #ifdef TCC_TARGET_I386
2006 #ifdef TCC_TARGET_PE
2007 *a = 8;
2008 #else
2009 *a = 4;
2010 #endif
2011 #elif defined(TCC_TARGET_ARM)
2012 #ifdef TCC_ARM_EABI
2013 *a = 8;
2014 #else
2015 *a = 4;
2016 #endif
2017 #else
2018 *a = 8;
2019 #endif
2020 return 8;
2021 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2022 *a = 4;
2023 return 4;
2024 } else if (bt == VT_SHORT) {
2025 *a = 2;
2026 return 2;
2027 } else {
2028 /* char, void, function, _Bool */
2029 *a = 1;
2030 return 1;
2034 /* push type size as known at runtime time on top of value stack. Put
2035 alignment at 'a' */
2036 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2038 if (type->t & VT_VLA) {
2039 Sym *s;
2041 s = type->ref;
2042 vla_runtime_type_size(&s->type, a);
2043 vpushv(s->s);
2044 if ((vtop->r & (VT_SYM|VT_LVAL|VT_VALMASK)) != VT_CONST) {
2045 gv_dup();
2046 vswap();
2047 vpop();
2049 gen_op('*');
2050 } else {
2051 int size;
2053 size = type_size(type, a);
2054 vpushi(size);
2058 /* return the pointed type of t */
2059 static inline CType *pointed_type(CType *type)
2061 return &type->ref->type;
2064 /* modify type so that its it is a pointer to type. */
2065 ST_FUNC void mk_pointer(CType *type)
2067 Sym *s;
2068 s = sym_push(SYM_FIELD, type, 0, -1);
2069 type->t = VT_PTR | (type->t & ~VT_TYPE);
2070 type->ref = s;
2073 /* compare function types. OLD functions match any new functions */
2074 static int is_compatible_func(CType *type1, CType *type2)
2076 Sym *s1, *s2;
2078 s1 = type1->ref;
2079 s2 = type2->ref;
2080 if (!is_compatible_types(&s1->type, &s2->type))
2081 return 0;
2082 /* check func_call */
2083 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2084 return 0;
2085 /* XXX: not complete */
2086 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2087 return 1;
2088 if (s1->c != s2->c)
2089 return 0;
2090 while (s1 != NULL) {
2091 if (s2 == NULL)
2092 return 0;
2093 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2094 return 0;
2095 s1 = s1->next;
2096 s2 = s2->next;
2098 if (s2)
2099 return 0;
2100 return 1;
2103 /* return true if type1 and type2 are the same. If unqualified is
2104 true, qualifiers on the types are ignored.
2106 - enums are not checked as gcc __builtin_types_compatible_p ()
2108 static int compare_types(CType *type1, CType *type2, int unqualified)
2110 int bt1, t1, t2;
2112 t1 = type1->t & VT_TYPE;
2113 t2 = type2->t & VT_TYPE;
2114 if (unqualified) {
2115 /* strip qualifiers before comparing */
2116 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2117 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2119 /* XXX: bitfields ? */
2120 if (t1 != t2)
2121 return 0;
2122 /* test more complicated cases */
2123 bt1 = t1 & VT_BTYPE;
2124 if (bt1 == VT_PTR) {
2125 type1 = pointed_type(type1);
2126 type2 = pointed_type(type2);
2127 return is_compatible_types(type1, type2);
2128 } else if (bt1 == VT_STRUCT) {
2129 return (type1->ref == type2->ref);
2130 } else if (bt1 == VT_FUNC) {
2131 return is_compatible_func(type1, type2);
2132 } else {
2133 return 1;
2137 /* return true if type1 and type2 are exactly the same (including
2138 qualifiers).
2140 static int is_compatible_types(CType *type1, CType *type2)
2142 return compare_types(type1,type2,0);
2145 /* return true if type1 and type2 are the same (ignoring qualifiers).
2147 static int is_compatible_parameter_types(CType *type1, CType *type2)
2149 return compare_types(type1,type2,1);
2152 /* print a type. If 'varstr' is not NULL, then the variable is also
2153 printed in the type */
2154 /* XXX: union */
2155 /* XXX: add array and function pointers */
2156 static void type_to_str(char *buf, int buf_size,
2157 CType *type, const char *varstr)
2159 int bt, v, t;
2160 Sym *s, *sa;
2161 char buf1[256];
2162 const char *tstr;
2164 t = type->t & VT_TYPE;
2165 bt = t & VT_BTYPE;
2166 buf[0] = '\0';
2167 if (t & VT_CONSTANT)
2168 pstrcat(buf, buf_size, "const ");
2169 if (t & VT_VOLATILE)
2170 pstrcat(buf, buf_size, "volatile ");
2171 if (t & VT_UNSIGNED)
2172 pstrcat(buf, buf_size, "unsigned ");
2173 switch(bt) {
2174 case VT_VOID:
2175 tstr = "void";
2176 goto add_tstr;
2177 case VT_BOOL:
2178 tstr = "_Bool";
2179 goto add_tstr;
2180 case VT_BYTE:
2181 tstr = "char";
2182 goto add_tstr;
2183 case VT_SHORT:
2184 tstr = "short";
2185 goto add_tstr;
2186 case VT_INT:
2187 tstr = "int";
2188 goto add_tstr;
2189 case VT_LONG:
2190 tstr = "long";
2191 goto add_tstr;
2192 case VT_LLONG:
2193 tstr = "long long";
2194 goto add_tstr;
2195 case VT_FLOAT:
2196 tstr = "float";
2197 goto add_tstr;
2198 case VT_DOUBLE:
2199 tstr = "double";
2200 goto add_tstr;
2201 case VT_LDOUBLE:
2202 tstr = "long double";
2203 add_tstr:
2204 pstrcat(buf, buf_size, tstr);
2205 break;
2206 case VT_ENUM:
2207 case VT_STRUCT:
2208 if (bt == VT_STRUCT)
2209 tstr = "struct ";
2210 else
2211 tstr = "enum ";
2212 pstrcat(buf, buf_size, tstr);
2213 v = type->ref->v & ~SYM_STRUCT;
2214 if (v >= SYM_FIRST_ANOM)
2215 pstrcat(buf, buf_size, "<anonymous>");
2216 else
2217 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2218 break;
2219 case VT_FUNC:
2220 s = type->ref;
2221 type_to_str(buf, buf_size, &s->type, varstr);
2222 pstrcat(buf, buf_size, "(");
2223 sa = s->next;
2224 while (sa != NULL) {
2225 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2226 pstrcat(buf, buf_size, buf1);
2227 sa = sa->next;
2228 if (sa)
2229 pstrcat(buf, buf_size, ", ");
2231 pstrcat(buf, buf_size, ")");
2232 goto no_var;
2233 case VT_PTR:
2234 s = type->ref;
2235 pstrcpy(buf1, sizeof(buf1), "*");
2236 if (varstr)
2237 pstrcat(buf1, sizeof(buf1), varstr);
2238 type_to_str(buf, buf_size, &s->type, buf1);
2239 goto no_var;
2241 if (varstr) {
2242 pstrcat(buf, buf_size, " ");
2243 pstrcat(buf, buf_size, varstr);
2245 no_var: ;
2248 /* verify type compatibility to store vtop in 'dt' type, and generate
2249 casts if needed. */
2250 static void gen_assign_cast(CType *dt)
2252 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2253 char buf1[256], buf2[256];
2254 int dbt, sbt;
2256 st = &vtop->type; /* source type */
2257 dbt = dt->t & VT_BTYPE;
2258 sbt = st->t & VT_BTYPE;
2259 if (dt->t & VT_CONSTANT)
2260 warning("assignment of read-only location");
2261 switch(dbt) {
2262 case VT_PTR:
2263 /* special cases for pointers */
2264 /* '0' can also be a pointer */
2265 if (is_null_pointer(vtop))
2266 goto type_ok;
2267 /* accept implicit pointer to integer cast with warning */
2268 if (is_integer_btype(sbt)) {
2269 warning("assignment makes pointer from integer without a cast");
2270 goto type_ok;
2272 type1 = pointed_type(dt);
2273 /* a function is implicitely a function pointer */
2274 if (sbt == VT_FUNC) {
2275 if ((type1->t & VT_BTYPE) != VT_VOID &&
2276 !is_compatible_types(pointed_type(dt), st))
2277 warning("assignment from incompatible pointer type");
2278 goto type_ok;
2280 if (sbt != VT_PTR)
2281 goto error;
2282 type2 = pointed_type(st);
2283 if ((type1->t & VT_BTYPE) == VT_VOID ||
2284 (type2->t & VT_BTYPE) == VT_VOID) {
2285 /* void * can match anything */
2286 } else {
2287 /* exact type match, except for unsigned */
2288 tmp_type1 = *type1;
2289 tmp_type2 = *type2;
2290 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2291 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2292 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2293 warning("assignment from incompatible pointer type");
2295 /* check const and volatile */
2296 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2297 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2298 warning("assignment discards qualifiers from pointer target type");
2299 break;
2300 case VT_BYTE:
2301 case VT_SHORT:
2302 case VT_INT:
2303 case VT_LLONG:
2304 if (sbt == VT_PTR || sbt == VT_FUNC) {
2305 warning("assignment makes integer from pointer without a cast");
2307 /* XXX: more tests */
2308 break;
2309 case VT_STRUCT:
2310 tmp_type1 = *dt;
2311 tmp_type2 = *st;
2312 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2313 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2314 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2315 error:
2316 type_to_str(buf1, sizeof(buf1), st, NULL);
2317 type_to_str(buf2, sizeof(buf2), dt, NULL);
2318 error("cannot cast '%s' to '%s'", buf1, buf2);
2320 break;
2322 type_ok:
2323 gen_cast(dt);
2326 /* store vtop in lvalue pushed on stack */
2327 ST_FUNC void vstore(void)
2329 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2331 ft = vtop[-1].type.t;
2332 sbt = vtop->type.t & VT_BTYPE;
2333 dbt = ft & VT_BTYPE;
2334 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2335 (sbt == VT_INT && dbt == VT_SHORT)) {
2336 /* optimize char/short casts */
2337 delayed_cast = VT_MUSTCAST;
2338 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2339 /* XXX: factorize */
2340 if (ft & VT_CONSTANT)
2341 warning("assignment of read-only location");
2342 } else {
2343 delayed_cast = 0;
2344 if (!(ft & VT_BITFIELD))
2345 gen_assign_cast(&vtop[-1].type);
2348 if (sbt == VT_STRUCT) {
2349 /* if structure, only generate pointer */
2350 /* structure assignment : generate memcpy */
2351 /* XXX: optimize if small size */
2352 if (!nocode_wanted) {
2353 size = type_size(&vtop->type, &align);
2355 /* destination */
2356 vswap();
2357 vtop->type.t = VT_PTR;
2358 gaddrof();
2360 /* address of memcpy() */
2361 #ifdef TCC_ARM_EABI
2362 if(!(align & 7))
2363 vpush_global_sym(&func_old_type, TOK_memcpy8);
2364 else if(!(align & 3))
2365 vpush_global_sym(&func_old_type, TOK_memcpy4);
2366 else
2367 #endif
2368 vpush_global_sym(&func_old_type, TOK_memcpy);
2370 vswap();
2371 /* source */
2372 vpushv(vtop - 2);
2373 vtop->type.t = VT_PTR;
2374 gaddrof();
2375 /* type size */
2376 vpushi(size);
2377 gfunc_call(3);
2378 } else {
2379 vswap();
2380 vpop();
2382 /* leave source on stack */
2383 } else if (ft & VT_BITFIELD) {
2384 /* bitfield store handling */
2385 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2386 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2387 /* remove bit field info to avoid loops */
2388 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2390 /* duplicate source into other register */
2391 gv_dup();
2392 vswap();
2393 vrott(3);
2395 if((ft & VT_BTYPE) == VT_BOOL) {
2396 gen_cast(&vtop[-1].type);
2397 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2400 /* duplicate destination */
2401 vdup();
2402 vtop[-1] = vtop[-2];
2404 /* mask and shift source */
2405 if((ft & VT_BTYPE) != VT_BOOL) {
2406 if((ft & VT_BTYPE) == VT_LLONG) {
2407 vpushll((1ULL << bit_size) - 1ULL);
2408 } else {
2409 vpushi((1 << bit_size) - 1);
2411 gen_op('&');
2413 vpushi(bit_pos);
2414 gen_op(TOK_SHL);
2415 /* load destination, mask and or with source */
2416 vswap();
2417 if((ft & VT_BTYPE) == VT_LLONG) {
2418 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2419 } else {
2420 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2422 gen_op('&');
2423 gen_op('|');
2424 /* store result */
2425 vstore();
2427 /* pop off shifted source from "duplicate source..." above */
2428 vpop();
2430 } else {
2431 #ifdef CONFIG_TCC_BCHECK
2432 /* bound check case */
2433 if (vtop[-1].r & VT_MUSTBOUND) {
2434 vswap();
2435 gbound();
2436 vswap();
2438 #endif
2439 if (!nocode_wanted) {
2440 rc = RC_INT;
2441 if (is_float(ft)) {
2442 rc = RC_FLOAT;
2443 #ifdef TCC_TARGET_X86_64
2444 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2445 rc = RC_ST0;
2447 #endif
2449 r = gv(rc); /* generate value */
2450 /* if lvalue was saved on stack, must read it */
2451 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2452 SValue sv;
2453 t = get_reg(RC_INT);
2454 #ifdef TCC_TARGET_X86_64
2455 sv.type.t = VT_PTR;
2456 #else
2457 sv.type.t = VT_INT;
2458 #endif
2459 sv.r = VT_LOCAL | VT_LVAL;
2460 sv.c.ul = vtop[-1].c.ul;
2461 load(t, &sv);
2462 vtop[-1].r = t | VT_LVAL;
2464 store(r, vtop - 1);
2465 #ifndef TCC_TARGET_X86_64
2466 /* two word case handling : store second register at word + 4 */
2467 if ((ft & VT_BTYPE) == VT_LLONG) {
2468 vswap();
2469 /* convert to int to increment easily */
2470 vtop->type.t = VT_INT;
2471 gaddrof();
2472 vpushi(4);
2473 gen_op('+');
2474 vtop->r |= VT_LVAL;
2475 vswap();
2476 /* XXX: it works because r2 is spilled last ! */
2477 store(vtop->r2, vtop - 1);
2479 #endif
2481 vswap();
2482 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2483 vtop->r |= delayed_cast;
2487 /* post defines POST/PRE add. c is the token ++ or -- */
2488 ST_FUNC void inc(int post, int c)
2490 test_lvalue();
2491 vdup(); /* save lvalue */
2492 if (post) {
2493 gv_dup(); /* duplicate value */
2494 vrotb(3);
2495 vrotb(3);
2497 /* add constant */
2498 vpushi(c - TOK_MID);
2499 gen_op('+');
2500 vstore(); /* store value */
2501 if (post)
2502 vpop(); /* if post op, return saved value */
2505 /* Parse GNUC __attribute__ extension. Currently, the following
2506 extensions are recognized:
2507 - aligned(n) : set data/function alignment.
2508 - packed : force data alignment to 1
2509 - section(x) : generate data/code in this section.
2510 - unused : currently ignored, but may be used someday.
2511 - regparm(n) : pass function parameters in registers (i386 only)
2513 static void parse_attribute(AttributeDef *ad)
2515 int t, n;
2517 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2518 next();
2519 skip('(');
2520 skip('(');
2521 while (tok != ')') {
2522 if (tok < TOK_IDENT)
2523 expect("attribute name");
2524 t = tok;
2525 next();
2526 switch(t) {
2527 case TOK_SECTION1:
2528 case TOK_SECTION2:
2529 skip('(');
2530 if (tok != TOK_STR)
2531 expect("section name");
2532 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2533 next();
2534 skip(')');
2535 break;
2536 case TOK_ALIAS1:
2537 case TOK_ALIAS2:
2538 skip('(');
2539 if (tok != TOK_STR)
2540 expect("alias(\"target\")");
2541 ad->alias_target = /* save string as token, for later */
2542 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2543 next();
2544 skip(')');
2545 break;
2546 case TOK_ALIGNED1:
2547 case TOK_ALIGNED2:
2548 if (tok == '(') {
2549 next();
2550 n = expr_const();
2551 if (n <= 0 || (n & (n - 1)) != 0)
2552 error("alignment must be a positive power of two");
2553 skip(')');
2554 } else {
2555 n = MAX_ALIGN;
2557 ad->aligned = n;
2558 break;
2559 case TOK_PACKED1:
2560 case TOK_PACKED2:
2561 ad->packed = 1;
2562 break;
2563 case TOK_WEAK1:
2564 case TOK_WEAK2:
2565 ad->weak = 1;
2566 break;
2567 case TOK_UNUSED1:
2568 case TOK_UNUSED2:
2569 /* currently, no need to handle it because tcc does not
2570 track unused objects */
2571 break;
2572 case TOK_NORETURN1:
2573 case TOK_NORETURN2:
2574 /* currently, no need to handle it because tcc does not
2575 track unused objects */
2576 break;
2577 case TOK_CDECL1:
2578 case TOK_CDECL2:
2579 case TOK_CDECL3:
2580 ad->func_call = FUNC_CDECL;
2581 break;
2582 case TOK_STDCALL1:
2583 case TOK_STDCALL2:
2584 case TOK_STDCALL3:
2585 ad->func_call = FUNC_STDCALL;
2586 break;
2587 #ifdef TCC_TARGET_I386
2588 case TOK_REGPARM1:
2589 case TOK_REGPARM2:
2590 skip('(');
2591 n = expr_const();
2592 if (n > 3)
2593 n = 3;
2594 else if (n < 0)
2595 n = 0;
2596 if (n > 0)
2597 ad->func_call = FUNC_FASTCALL1 + n - 1;
2598 skip(')');
2599 break;
2600 case TOK_FASTCALL1:
2601 case TOK_FASTCALL2:
2602 case TOK_FASTCALL3:
2603 ad->func_call = FUNC_FASTCALLW;
2604 break;
2605 #endif
2606 case TOK_MODE:
2607 skip('(');
2608 switch(tok) {
2609 case TOK_MODE_DI:
2610 ad->mode = VT_LLONG + 1;
2611 break;
2612 case TOK_MODE_HI:
2613 ad->mode = VT_SHORT + 1;
2614 break;
2615 case TOK_MODE_SI:
2616 ad->mode = VT_INT + 1;
2617 break;
2618 default:
2619 warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2620 break;
2622 next();
2623 skip(')');
2624 break;
2625 case TOK_DLLEXPORT:
2626 ad->func_export = 1;
2627 break;
2628 case TOK_DLLIMPORT:
2629 ad->func_import = 1;
2630 break;
2631 default:
2632 if (tcc_state->warn_unsupported)
2633 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2634 /* skip parameters */
2635 if (tok == '(') {
2636 int parenthesis = 0;
2637 do {
2638 if (tok == '(')
2639 parenthesis++;
2640 else if (tok == ')')
2641 parenthesis--;
2642 next();
2643 } while (parenthesis && tok != -1);
2645 break;
2647 if (tok != ',')
2648 break;
2649 next();
2651 skip(')');
2652 skip(')');
2656 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2657 static void struct_decl(CType *type, int u)
2659 int a, v, size, align, maxalign, c, offset;
2660 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2661 Sym *s, *ss, *ass, **ps;
2662 AttributeDef ad;
2663 CType type1, btype;
2665 a = tok; /* save decl type */
2666 next();
2667 if (tok != '{') {
2668 v = tok;
2669 next();
2670 /* struct already defined ? return it */
2671 if (v < TOK_IDENT)
2672 expect("struct/union/enum name");
2673 s = struct_find(v);
2674 if (s) {
2675 if (s->type.t != a)
2676 error("invalid type");
2677 goto do_decl;
2679 } else {
2680 v = anon_sym++;
2682 type1.t = a;
2683 /* we put an undefined size for struct/union */
2684 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2685 s->r = 0; /* default alignment is zero as gcc */
2686 /* put struct/union/enum name in type */
2687 do_decl:
2688 type->t = u;
2689 type->ref = s;
2691 if (tok == '{') {
2692 next();
2693 if (s->c != -1)
2694 error("struct/union/enum already defined");
2695 /* cannot be empty */
2696 c = 0;
2697 /* non empty enums are not allowed */
2698 if (a == TOK_ENUM) {
2699 for(;;) {
2700 v = tok;
2701 if (v < TOK_UIDENT)
2702 expect("identifier");
2703 next();
2704 if (tok == '=') {
2705 next();
2706 c = expr_const();
2708 /* enum symbols have static storage */
2709 ss = sym_push(v, &int_type, VT_CONST, c);
2710 ss->type.t |= VT_STATIC;
2711 if (tok != ',')
2712 break;
2713 next();
2714 c++;
2715 /* NOTE: we accept a trailing comma */
2716 if (tok == '}')
2717 break;
2719 skip('}');
2720 } else {
2721 maxalign = 1;
2722 ps = &s->next;
2723 prevbt = VT_INT;
2724 bit_pos = 0;
2725 offset = 0;
2726 while (tok != '}') {
2727 parse_btype(&btype, &ad);
2728 while (1) {
2729 bit_size = -1;
2730 v = 0;
2731 type1 = btype;
2732 if (tok != ':') {
2733 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2734 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2735 expect("identifier");
2736 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2737 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2738 error("invalid type for '%s'",
2739 get_tok_str(v, NULL));
2741 if (tok == ':') {
2742 next();
2743 bit_size = expr_const();
2744 /* XXX: handle v = 0 case for messages */
2745 if (bit_size < 0)
2746 error("negative width in bit-field '%s'",
2747 get_tok_str(v, NULL));
2748 if (v && bit_size == 0)
2749 error("zero width for bit-field '%s'",
2750 get_tok_str(v, NULL));
2752 size = type_size(&type1, &align);
2753 if (ad.aligned) {
2754 if (align < ad.aligned)
2755 align = ad.aligned;
2756 } else if (ad.packed) {
2757 align = 1;
2758 } else if (*tcc_state->pack_stack_ptr) {
2759 if (align > *tcc_state->pack_stack_ptr)
2760 align = *tcc_state->pack_stack_ptr;
2762 lbit_pos = 0;
2763 if (bit_size >= 0) {
2764 bt = type1.t & VT_BTYPE;
2765 if (bt != VT_INT &&
2766 bt != VT_BYTE &&
2767 bt != VT_SHORT &&
2768 bt != VT_BOOL &&
2769 bt != VT_ENUM &&
2770 bt != VT_LLONG)
2771 error("bitfields must have scalar type");
2772 bsize = size * 8;
2773 if (bit_size > bsize) {
2774 error("width of '%s' exceeds its type",
2775 get_tok_str(v, NULL));
2776 } else if (bit_size == bsize) {
2777 /* no need for bit fields */
2778 bit_pos = 0;
2779 } else if (bit_size == 0) {
2780 /* XXX: what to do if only padding in a
2781 structure ? */
2782 /* zero size: means to pad */
2783 bit_pos = 0;
2784 } else {
2785 /* we do not have enough room ?
2786 did the type change?
2787 is it a union? */
2788 if ((bit_pos + bit_size) > bsize ||
2789 bt != prevbt || a == TOK_UNION)
2790 bit_pos = 0;
2791 lbit_pos = bit_pos;
2792 /* XXX: handle LSB first */
2793 type1.t |= VT_BITFIELD |
2794 (bit_pos << VT_STRUCT_SHIFT) |
2795 (bit_size << (VT_STRUCT_SHIFT + 6));
2796 bit_pos += bit_size;
2798 prevbt = bt;
2799 } else {
2800 bit_pos = 0;
2802 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2803 /* add new memory data only if starting
2804 bit field */
2805 if (lbit_pos == 0) {
2806 if (a == TOK_STRUCT) {
2807 c = (c + align - 1) & -align;
2808 offset = c;
2809 if (size > 0)
2810 c += size;
2811 } else {
2812 offset = 0;
2813 if (size > c)
2814 c = size;
2816 if (align > maxalign)
2817 maxalign = align;
2819 #if 0
2820 printf("add field %s offset=%d",
2821 get_tok_str(v, NULL), offset);
2822 if (type1.t & VT_BITFIELD) {
2823 printf(" pos=%d size=%d",
2824 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2825 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2827 printf("\n");
2828 #endif
2830 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2831 ass = type1.ref;
2832 while ((ass = ass->next) != NULL) {
2833 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2834 *ps = ss;
2835 ps = &ss->next;
2837 } else if (v) {
2838 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2839 *ps = ss;
2840 ps = &ss->next;
2842 if (tok == ';' || tok == TOK_EOF)
2843 break;
2844 skip(',');
2846 skip(';');
2848 skip('}');
2849 /* store size and alignment */
2850 s->c = (c + maxalign - 1) & -maxalign;
2851 s->r = maxalign;
2856 /* return 0 if no type declaration. otherwise, return the basic type
2857 and skip it.
2859 static int parse_btype(CType *type, AttributeDef *ad)
2861 int t, u, type_found, typespec_found, typedef_found;
2862 Sym *s;
2863 CType type1;
2865 memset(ad, 0, sizeof(AttributeDef));
2866 type_found = 0;
2867 typespec_found = 0;
2868 typedef_found = 0;
2869 t = 0;
2870 while(1) {
2871 switch(tok) {
2872 case TOK_EXTENSION:
2873 /* currently, we really ignore extension */
2874 next();
2875 continue;
2877 /* basic types */
2878 case TOK_CHAR:
2879 u = VT_BYTE;
2880 basic_type:
2881 next();
2882 basic_type1:
2883 if ((t & VT_BTYPE) != 0)
2884 error("too many basic types");
2885 t |= u;
2886 typespec_found = 1;
2887 break;
2888 case TOK_VOID:
2889 u = VT_VOID;
2890 goto basic_type;
2891 case TOK_SHORT:
2892 u = VT_SHORT;
2893 goto basic_type;
2894 case TOK_INT:
2895 next();
2896 typespec_found = 1;
2897 break;
2898 case TOK_LONG:
2899 next();
2900 if ((t & VT_BTYPE) == VT_DOUBLE) {
2901 #ifndef TCC_TARGET_PE
2902 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2903 #endif
2904 } else if ((t & VT_BTYPE) == VT_LONG) {
2905 t = (t & ~VT_BTYPE) | VT_LLONG;
2906 } else {
2907 u = VT_LONG;
2908 goto basic_type1;
2910 break;
2911 case TOK_BOOL:
2912 u = VT_BOOL;
2913 goto basic_type;
2914 case TOK_FLOAT:
2915 u = VT_FLOAT;
2916 goto basic_type;
2917 case TOK_DOUBLE:
2918 next();
2919 if ((t & VT_BTYPE) == VT_LONG) {
2920 #ifdef TCC_TARGET_PE
2921 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2922 #else
2923 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2924 #endif
2925 } else {
2926 u = VT_DOUBLE;
2927 goto basic_type1;
2929 break;
2930 case TOK_ENUM:
2931 struct_decl(&type1, VT_ENUM);
2932 basic_type2:
2933 u = type1.t;
2934 type->ref = type1.ref;
2935 goto basic_type1;
2936 case TOK_STRUCT:
2937 case TOK_UNION:
2938 struct_decl(&type1, VT_STRUCT);
2939 goto basic_type2;
2941 /* type modifiers */
2942 case TOK_CONST1:
2943 case TOK_CONST2:
2944 case TOK_CONST3:
2945 t |= VT_CONSTANT;
2946 next();
2947 break;
2948 case TOK_VOLATILE1:
2949 case TOK_VOLATILE2:
2950 case TOK_VOLATILE3:
2951 t |= VT_VOLATILE;
2952 next();
2953 break;
2954 case TOK_SIGNED1:
2955 case TOK_SIGNED2:
2956 case TOK_SIGNED3:
2957 typespec_found = 1;
2958 t |= VT_SIGNED;
2959 next();
2960 break;
2961 case TOK_REGISTER:
2962 case TOK_AUTO:
2963 case TOK_RESTRICT1:
2964 case TOK_RESTRICT2:
2965 case TOK_RESTRICT3:
2966 next();
2967 break;
2968 case TOK_UNSIGNED:
2969 t |= VT_UNSIGNED;
2970 next();
2971 typespec_found = 1;
2972 break;
2974 /* storage */
2975 case TOK_EXTERN:
2976 t |= VT_EXTERN;
2977 next();
2978 break;
2979 case TOK_STATIC:
2980 t |= VT_STATIC;
2981 next();
2982 break;
2983 case TOK_TYPEDEF:
2984 t |= VT_TYPEDEF;
2985 next();
2986 break;
2987 case TOK_INLINE1:
2988 case TOK_INLINE2:
2989 case TOK_INLINE3:
2990 t |= VT_INLINE;
2991 next();
2992 break;
2994 /* GNUC attribute */
2995 case TOK_ATTRIBUTE1:
2996 case TOK_ATTRIBUTE2:
2997 parse_attribute(ad);
2998 if (ad->mode) {
2999 u = ad->mode -1;
3000 t = (t & ~VT_BTYPE) | u;
3002 break;
3003 /* GNUC typeof */
3004 case TOK_TYPEOF1:
3005 case TOK_TYPEOF2:
3006 case TOK_TYPEOF3:
3007 next();
3008 parse_expr_type(&type1);
3009 /* remove all storage modifiers except typedef */
3010 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3011 goto basic_type2;
3012 default:
3013 if (typespec_found || typedef_found)
3014 goto the_end;
3015 s = sym_find(tok);
3016 if (!s || !(s->type.t & VT_TYPEDEF))
3017 goto the_end;
3018 typedef_found = 1;
3019 t |= (s->type.t & ~VT_TYPEDEF);
3020 type->ref = s->type.ref;
3021 if (s->r) {
3022 /* get attributes from typedef */
3023 if (0 == ad->aligned)
3024 ad->aligned = FUNC_ALIGN(s->r);
3025 if (0 == ad->func_call)
3026 ad->func_call = FUNC_CALL(s->r);
3027 ad->packed |= FUNC_PACKED(s->r);
3029 next();
3030 typespec_found = 1;
3031 break;
3033 type_found = 1;
3035 the_end:
3036 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3037 error("signed and unsigned modifier");
3038 if (tcc_state->char_is_unsigned) {
3039 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3040 t |= VT_UNSIGNED;
3042 t &= ~VT_SIGNED;
3044 /* long is never used as type */
3045 if ((t & VT_BTYPE) == VT_LONG)
3046 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3047 t = (t & ~VT_BTYPE) | VT_INT;
3048 #else
3049 t = (t & ~VT_BTYPE) | VT_LLONG;
3050 #endif
3051 type->t = t;
3052 return type_found;
3055 /* convert a function parameter type (array to pointer and function to
3056 function pointer) */
3057 static inline void convert_parameter_type(CType *pt)
3059 /* remove const and volatile qualifiers (XXX: const could be used
3060 to indicate a const function parameter */
3061 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3062 /* array must be transformed to pointer according to ANSI C */
3063 pt->t &= ~VT_ARRAY;
3064 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3065 mk_pointer(pt);
3069 ST_FUNC void parse_asm_str(CString *astr)
3071 skip('(');
3072 /* read the string */
3073 if (tok != TOK_STR)
3074 expect("string constant");
3075 cstr_new(astr);
3076 while (tok == TOK_STR) {
3077 /* XXX: add \0 handling too ? */
3078 cstr_cat(astr, tokc.cstr->data);
3079 next();
3081 cstr_ccat(astr, '\0');
3084 /* Parse an asm label and return the label
3085 * Don't forget to free the CString in the caller! */
3086 static void asm_label_instr(CString *astr)
3088 next();
3089 parse_asm_str(astr);
3090 skip(')');
3091 #ifdef ASM_DEBUG
3092 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3093 #endif
3096 static void post_type(CType *type, AttributeDef *ad)
3098 int n, l, t1, arg_size, align;
3099 Sym **plast, *s, *first;
3100 AttributeDef ad1;
3101 CType pt;
3103 if (tok == '(') {
3104 /* function declaration */
3105 next();
3106 l = 0;
3107 first = NULL;
3108 plast = &first;
3109 arg_size = 0;
3110 if (tok != ')') {
3111 for(;;) {
3112 /* read param name and compute offset */
3113 if (l != FUNC_OLD) {
3114 if (!parse_btype(&pt, &ad1)) {
3115 if (l) {
3116 error("invalid type");
3117 } else {
3118 l = FUNC_OLD;
3119 goto old_proto;
3122 l = FUNC_NEW;
3123 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3124 break;
3125 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3126 if ((pt.t & VT_BTYPE) == VT_VOID)
3127 error("parameter declared as void");
3128 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3129 } else {
3130 old_proto:
3131 n = tok;
3132 if (n < TOK_UIDENT)
3133 expect("identifier");
3134 pt.t = VT_INT;
3135 next();
3137 convert_parameter_type(&pt);
3138 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3139 *plast = s;
3140 plast = &s->next;
3141 if (tok == ')')
3142 break;
3143 skip(',');
3144 if (l == FUNC_NEW && tok == TOK_DOTS) {
3145 l = FUNC_ELLIPSIS;
3146 next();
3147 break;
3151 /* if no parameters, then old type prototype */
3152 if (l == 0)
3153 l = FUNC_OLD;
3154 skip(')');
3155 /* NOTE: const is ignored in returned type as it has a special
3156 meaning in gcc / C++ */
3157 type->t &= ~VT_CONSTANT;
3158 /* some ancient pre-K&R C allows a function to return an array
3159 and the array brackets to be put after the arguments, such
3160 that "int c()[]" means something like "int[] c()" */
3161 if (tok == '[') {
3162 next();
3163 skip(']'); /* only handle simple "[]" */
3164 type->t |= VT_PTR;
3166 /* we push a anonymous symbol which will contain the function prototype */
3167 ad->func_args = arg_size;
3168 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3169 s->next = first;
3170 type->t = VT_FUNC;
3171 type->ref = s;
3172 } else if (tok == '[') {
3173 SValue *last_vtop = NULL;
3175 /* array definition */
3176 next();
3177 if (tok == TOK_RESTRICT1)
3178 next();
3179 n = -1;
3180 t1 = 0;
3181 if (tok != ']') {
3182 gexpr();
3183 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3184 n = vtop->c.i;
3185 last_vtop = vtop;
3186 if (n < 0)
3187 error("invalid array size");
3188 } else {
3189 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3190 error("size of variable length array should be an integer");
3191 t1 = VT_VLA;
3192 last_vtop = vtop;
3195 skip(']');
3196 /* parse next post type */
3197 post_type(type, ad);
3198 t1 |= type->t & VT_VLA;
3200 /* we push an anonymous symbol which will contain the array
3201 element type */
3202 s = sym_push(SYM_FIELD, type, 0, n);
3203 if (t1 & VT_VLA) {
3204 s->s = last_vtop; // That's ok, we don't need n with VLA
3205 } else {
3206 if (n >= 0)
3207 vpop();
3209 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3210 type->ref = s;
3214 /* Parse a type declaration (except basic type), and return the type
3215 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3216 expected. 'type' should contain the basic type. 'ad' is the
3217 attribute definition of the basic type. It can be modified by
3218 type_decl().
3220 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3222 Sym *s;
3223 CType type1, *type2;
3224 int qualifiers, storage;
3226 while (tok == '*') {
3227 qualifiers = 0;
3228 redo:
3229 next();
3230 switch(tok) {
3231 case TOK_CONST1:
3232 case TOK_CONST2:
3233 case TOK_CONST3:
3234 qualifiers |= VT_CONSTANT;
3235 goto redo;
3236 case TOK_VOLATILE1:
3237 case TOK_VOLATILE2:
3238 case TOK_VOLATILE3:
3239 qualifiers |= VT_VOLATILE;
3240 goto redo;
3241 case TOK_RESTRICT1:
3242 case TOK_RESTRICT2:
3243 case TOK_RESTRICT3:
3244 goto redo;
3246 mk_pointer(type);
3247 type->t |= qualifiers;
3250 /* XXX: clarify attribute handling */
3251 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3252 parse_attribute(ad);
3254 /* recursive type */
3255 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3256 type1.t = 0; /* XXX: same as int */
3257 if (tok == '(') {
3258 next();
3259 /* XXX: this is not correct to modify 'ad' at this point, but
3260 the syntax is not clear */
3261 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3262 parse_attribute(ad);
3263 type_decl(&type1, ad, v, td);
3264 skip(')');
3265 } else {
3266 /* type identifier */
3267 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3268 *v = tok;
3269 next();
3270 } else {
3271 if (!(td & TYPE_ABSTRACT))
3272 expect("identifier");
3273 *v = 0;
3276 storage = type->t & VT_STORAGE;
3277 type->t &= ~VT_STORAGE;
3278 post_type(type, ad);
3279 type->t |= storage;
3280 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3281 parse_attribute(ad);
3283 if (!type1.t)
3284 return;
3285 /* append type at the end of type1 */
3286 type2 = &type1;
3287 for(;;) {
3288 s = type2->ref;
3289 type2 = &s->type;
3290 if (!type2->t) {
3291 *type2 = *type;
3292 break;
3295 *type = type1;
3298 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3299 ST_FUNC int lvalue_type(int t)
3301 int bt, r;
3302 r = VT_LVAL;
3303 bt = t & VT_BTYPE;
3304 if (bt == VT_BYTE || bt == VT_BOOL)
3305 r |= VT_LVAL_BYTE;
3306 else if (bt == VT_SHORT)
3307 r |= VT_LVAL_SHORT;
3308 else
3309 return r;
3310 if (t & VT_UNSIGNED)
3311 r |= VT_LVAL_UNSIGNED;
3312 return r;
3315 /* indirection with full error checking and bound check */
3316 ST_FUNC void indir(void)
3318 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3319 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3320 return;
3321 expect("pointer");
3323 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3324 gv(RC_INT);
3325 vtop->type = *pointed_type(&vtop->type);
3326 /* Arrays and functions are never lvalues */
3327 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3328 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3329 vtop->r |= lvalue_type(vtop->type.t);
3330 /* if bound checking, the referenced pointer must be checked */
3331 #ifdef CONFIG_TCC_BCHECK
3332 if (tcc_state->do_bounds_check)
3333 vtop->r |= VT_MUSTBOUND;
3334 #endif
3338 /* pass a parameter to a function and do type checking and casting */
3339 static void gfunc_param_typed(Sym *func, Sym *arg)
3341 int func_type;
3342 CType type;
3344 func_type = func->c;
3345 if (func_type == FUNC_OLD ||
3346 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3347 /* default casting : only need to convert float to double */
3348 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3349 type.t = VT_DOUBLE;
3350 gen_cast(&type);
3352 } else if (arg == NULL) {
3353 error("too many arguments to function");
3354 } else {
3355 type = arg->type;
3356 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3357 gen_assign_cast(&type);
3361 /* parse an expression of the form '(type)' or '(expr)' and return its
3362 type */
3363 static void parse_expr_type(CType *type)
3365 int n;
3366 AttributeDef ad;
3368 skip('(');
3369 if (parse_btype(type, &ad)) {
3370 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3371 } else {
3372 expr_type(type);
3374 skip(')');
3377 static void parse_type(CType *type)
3379 AttributeDef ad;
3380 int n;
3382 if (!parse_btype(type, &ad)) {
3383 expect("type");
3385 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3388 static void vpush_tokc(int t)
3390 CType type;
3391 type.t = t;
3392 type.ref = 0;
3393 vsetc(&type, VT_CONST, &tokc);
3396 ST_FUNC void unary(void)
3398 int n, t, align, size, r, sizeof_caller;
3399 CType type;
3400 Sym *s;
3401 AttributeDef ad;
3402 static int in_sizeof = 0;
3404 sizeof_caller = in_sizeof;
3405 in_sizeof = 0;
3406 /* XXX: GCC 2.95.3 does not generate a table although it should be
3407 better here */
3408 tok_next:
3409 switch(tok) {
3410 case TOK_EXTENSION:
3411 next();
3412 goto tok_next;
3413 case TOK_CINT:
3414 case TOK_CCHAR:
3415 case TOK_LCHAR:
3416 vpushi(tokc.i);
3417 next();
3418 break;
3419 case TOK_CUINT:
3420 vpush_tokc(VT_INT | VT_UNSIGNED);
3421 next();
3422 break;
3423 case TOK_CLLONG:
3424 vpush_tokc(VT_LLONG);
3425 next();
3426 break;
3427 case TOK_CULLONG:
3428 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3429 next();
3430 break;
3431 case TOK_CFLOAT:
3432 vpush_tokc(VT_FLOAT);
3433 next();
3434 break;
3435 case TOK_CDOUBLE:
3436 vpush_tokc(VT_DOUBLE);
3437 next();
3438 break;
3439 case TOK_CLDOUBLE:
3440 vpush_tokc(VT_LDOUBLE);
3441 next();
3442 break;
3443 case TOK___FUNCTION__:
3444 if (!gnu_ext)
3445 goto tok_identifier;
3446 /* fall thru */
3447 case TOK___FUNC__:
3449 void *ptr;
3450 int len;
3451 /* special function name identifier */
3452 len = strlen(funcname) + 1;
3453 /* generate char[len] type */
3454 type.t = VT_BYTE;
3455 mk_pointer(&type);
3456 type.t |= VT_ARRAY;
3457 type.ref->c = len;
3458 vpush_ref(&type, data_section, data_section->data_offset, len);
3459 ptr = section_ptr_add(data_section, len);
3460 memcpy(ptr, funcname, len);
3461 next();
3463 break;
3464 case TOK_LSTR:
3465 #ifdef TCC_TARGET_PE
3466 t = VT_SHORT | VT_UNSIGNED;
3467 #else
3468 t = VT_INT;
3469 #endif
3470 goto str_init;
3471 case TOK_STR:
3472 /* string parsing */
3473 t = VT_BYTE;
3474 str_init:
3475 if (tcc_state->warn_write_strings)
3476 t |= VT_CONSTANT;
3477 type.t = t;
3478 mk_pointer(&type);
3479 type.t |= VT_ARRAY;
3480 memset(&ad, 0, sizeof(AttributeDef));
3481 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3482 break;
3483 case '(':
3484 next();
3485 /* cast ? */
3486 if (parse_btype(&type, &ad)) {
3487 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3488 skip(')');
3489 /* check ISOC99 compound literal */
3490 if (tok == '{') {
3491 /* data is allocated locally by default */
3492 if (global_expr)
3493 r = VT_CONST;
3494 else
3495 r = VT_LOCAL;
3496 /* all except arrays are lvalues */
3497 if (!(type.t & VT_ARRAY))
3498 r |= lvalue_type(type.t);
3499 memset(&ad, 0, sizeof(AttributeDef));
3500 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3501 } else {
3502 if (sizeof_caller) {
3503 vpush(&type);
3504 return;
3506 unary();
3507 gen_cast(&type);
3509 } else if (tok == '{') {
3510 /* save all registers */
3511 save_regs(0);
3512 /* statement expression : we do not accept break/continue
3513 inside as GCC does */
3514 block(NULL, NULL, NULL, NULL, 0, 1);
3515 skip(')');
3516 } else {
3517 gexpr();
3518 skip(')');
3520 break;
3521 case '*':
3522 next();
3523 unary();
3524 indir();
3525 break;
3526 case '&':
3527 next();
3528 unary();
3529 /* functions names must be treated as function pointers,
3530 except for unary '&' and sizeof. Since we consider that
3531 functions are not lvalues, we only have to handle it
3532 there and in function calls. */
3533 /* arrays can also be used although they are not lvalues */
3534 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3535 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3536 test_lvalue();
3537 mk_pointer(&vtop->type);
3538 gaddrof();
3539 break;
3540 case '!':
3541 next();
3542 unary();
3543 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3544 CType boolean;
3545 boolean.t = VT_BOOL;
3546 gen_cast(&boolean);
3547 vtop->c.i = !vtop->c.i;
3548 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3549 vtop->c.i = vtop->c.i ^ 1;
3550 else {
3551 save_regs(1);
3552 vseti(VT_JMP, gtst(1, 0));
3554 break;
3555 case '~':
3556 next();
3557 unary();
3558 vpushi(-1);
3559 gen_op('^');
3560 break;
3561 case '+':
3562 next();
3563 /* in order to force cast, we add zero */
3564 unary();
3565 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3566 error("pointer not accepted for unary plus");
3567 vpushi(0);
3568 gen_op('+');
3569 break;
3570 case TOK_SIZEOF:
3571 case TOK_ALIGNOF1:
3572 case TOK_ALIGNOF2:
3573 t = tok;
3574 next();
3575 in_sizeof++;
3576 unary_type(&type); // Perform a in_sizeof = 0;
3577 size = type_size(&type, &align);
3578 if (t == TOK_SIZEOF) {
3579 if (!(type.t & VT_VLA)) {
3580 if (size < 0)
3581 error("sizeof applied to an incomplete type");
3582 vpushi(size);
3583 } else {
3584 vla_runtime_type_size(&type, &align);
3586 } else {
3587 vpushi(align);
3589 vtop->type.t |= VT_UNSIGNED;
3590 break;
3592 case TOK_builtin_types_compatible_p:
3594 CType type1, type2;
3595 next();
3596 skip('(');
3597 parse_type(&type1);
3598 skip(',');
3599 parse_type(&type2);
3600 skip(')');
3601 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3602 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3603 vpushi(is_compatible_types(&type1, &type2));
3605 break;
3606 case TOK_builtin_constant_p:
3608 int saved_nocode_wanted, res;
3609 next();
3610 skip('(');
3611 saved_nocode_wanted = nocode_wanted;
3612 nocode_wanted = 1;
3613 gexpr();
3614 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3615 vpop();
3616 nocode_wanted = saved_nocode_wanted;
3617 skip(')');
3618 vpushi(res);
3620 break;
3621 case TOK_builtin_frame_address:
3623 CType type;
3624 next();
3625 skip('(');
3626 if (tok != TOK_CINT) {
3627 error("__builtin_frame_address only takes integers");
3629 if (tokc.i != 0) {
3630 error("TCC only supports __builtin_frame_address(0)");
3632 next();
3633 skip(')');
3634 type.t = VT_VOID;
3635 mk_pointer(&type);
3636 vset(&type, VT_LOCAL, 0);
3638 break;
3639 #ifdef TCC_TARGET_X86_64
3640 case TOK_builtin_va_arg_types:
3642 /* This definition must be synced with stdarg.h */
3643 enum __va_arg_type {
3644 __va_gen_reg, __va_float_reg, __va_stack
3646 CType type;
3647 int bt;
3648 next();
3649 skip('(');
3650 parse_type(&type);
3651 skip(')');
3652 bt = type.t & VT_BTYPE;
3653 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3654 vpushi(__va_stack);
3655 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3656 vpushi(__va_float_reg);
3657 } else {
3658 vpushi(__va_gen_reg);
3661 break;
3662 #endif
3663 case TOK_INC:
3664 case TOK_DEC:
3665 t = tok;
3666 next();
3667 unary();
3668 inc(0, t);
3669 break;
3670 case '-':
3671 next();
3672 vpushi(0);
3673 unary();
3674 gen_op('-');
3675 break;
3676 case TOK_LAND:
3677 if (!gnu_ext)
3678 goto tok_identifier;
3679 next();
3680 /* allow to take the address of a label */
3681 if (tok < TOK_UIDENT)
3682 expect("label identifier");
3683 s = label_find(tok);
3684 if (!s) {
3685 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3686 } else {
3687 if (s->r == LABEL_DECLARED)
3688 s->r = LABEL_FORWARD;
3690 if (!s->type.t) {
3691 s->type.t = VT_VOID;
3692 mk_pointer(&s->type);
3693 s->type.t |= VT_STATIC;
3695 vset(&s->type, VT_CONST | VT_SYM, 0);
3696 vtop->sym = s;
3697 next();
3698 break;
3700 // special qnan , snan and infinity values
3701 case TOK___NAN__:
3702 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3703 next();
3704 break;
3705 case TOK___SNAN__:
3706 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3707 next();
3708 break;
3709 case TOK___INF__:
3710 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3711 next();
3712 break;
3714 default:
3715 tok_identifier:
3716 t = tok;
3717 next();
3718 if (t < TOK_UIDENT)
3719 expect("identifier");
3720 s = sym_find(t);
3721 if (!s) {
3722 if (tok != '(')
3723 error("'%s' undeclared", get_tok_str(t, NULL));
3724 /* for simple function calls, we tolerate undeclared
3725 external reference to int() function */
3726 if (tcc_state->warn_implicit_function_declaration)
3727 warning("implicit declaration of function '%s'",
3728 get_tok_str(t, NULL));
3729 s = external_global_sym(t, &func_old_type, 0);
3731 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3732 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3733 /* if referencing an inline function, then we generate a
3734 symbol to it if not already done. It will have the
3735 effect to generate code for it at the end of the
3736 compilation unit. Inline function as always
3737 generated in the text section. */
3738 if (!s->c)
3739 put_extern_sym(s, text_section, 0, 0);
3740 r = VT_SYM | VT_CONST;
3741 } else {
3742 r = s->r;
3744 if (s->type.t & VT_VLA)
3745 vpushv(s->s);
3746 else
3747 vset(&s->type, r, s->c);
3748 /* if forward reference, we must point to s */
3749 if (vtop->r & VT_SYM) {
3750 vtop->sym = s;
3751 vtop->c.ul = 0;
3753 break;
3756 /* post operations */
3757 while (1) {
3758 if (tok == TOK_INC || tok == TOK_DEC) {
3759 inc(1, tok);
3760 next();
3761 } else if (tok == '.' || tok == TOK_ARROW) {
3762 int qualifiers;
3763 /* field */
3764 if (tok == TOK_ARROW)
3765 indir();
3766 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3767 test_lvalue();
3768 gaddrof();
3769 next();
3770 /* expect pointer on structure */
3771 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3772 expect("struct or union");
3773 s = vtop->type.ref;
3774 /* find field */
3775 tok |= SYM_FIELD;
3776 while ((s = s->next) != NULL) {
3777 if (s->v == tok)
3778 break;
3780 if (!s)
3781 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3782 /* add field offset to pointer */
3783 vtop->type = char_pointer_type; /* change type to 'char *' */
3784 vpushi(s->c);
3785 gen_op('+');
3786 /* change type to field type, and set to lvalue */
3787 vtop->type = s->type;
3788 vtop->type.t |= qualifiers;
3789 /* an array is never an lvalue */
3790 if (!(vtop->type.t & VT_ARRAY)) {
3791 vtop->r |= lvalue_type(vtop->type.t);
3792 #ifdef CONFIG_TCC_BCHECK
3793 /* if bound checking, the referenced pointer must be checked */
3794 if (tcc_state->do_bounds_check)
3795 vtop->r |= VT_MUSTBOUND;
3796 #endif
3798 next();
3799 } else if (tok == '[') {
3800 next();
3801 gexpr();
3802 gen_op('+');
3803 indir();
3804 skip(']');
3805 } else if (tok == '(') {
3806 SValue ret;
3807 Sym *sa;
3808 int nb_args;
3810 /* function call */
3811 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3812 /* pointer test (no array accepted) */
3813 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3814 vtop->type = *pointed_type(&vtop->type);
3815 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3816 goto error_func;
3817 } else {
3818 error_func:
3819 expect("function pointer");
3821 } else {
3822 vtop->r &= ~VT_LVAL; /* no lvalue */
3824 /* get return type */
3825 s = vtop->type.ref;
3826 next();
3827 sa = s->next; /* first parameter */
3828 nb_args = 0;
3829 ret.r2 = VT_CONST;
3830 /* compute first implicit argument if a structure is returned */
3831 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3832 /* get some space for the returned structure */
3833 size = type_size(&s->type, &align);
3834 loc = (loc - size) & -align;
3835 ret.type = s->type;
3836 ret.r = VT_LOCAL | VT_LVAL;
3837 /* pass it as 'int' to avoid structure arg passing
3838 problems */
3839 vseti(VT_LOCAL, loc);
3840 ret.c = vtop->c;
3841 nb_args++;
3842 } else {
3843 ret.type = s->type;
3844 /* return in register */
3845 if (is_float(ret.type.t)) {
3846 ret.r = reg_fret(ret.type.t);
3847 } else {
3848 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3849 ret.r2 = REG_LRET;
3850 ret.r = REG_IRET;
3852 ret.c.i = 0;
3854 if (tok != ')') {
3855 for(;;) {
3856 expr_eq();
3857 gfunc_param_typed(s, sa);
3858 nb_args++;
3859 if (sa)
3860 sa = sa->next;
3861 if (tok == ')')
3862 break;
3863 skip(',');
3866 if (sa)
3867 error("too few arguments to function");
3868 skip(')');
3869 if (!nocode_wanted) {
3870 gfunc_call(nb_args);
3871 } else {
3872 vtop -= (nb_args + 1);
3874 /* return value */
3875 vsetc(&ret.type, ret.r, &ret.c);
3876 vtop->r2 = ret.r2;
3877 } else {
3878 break;
3883 ST_FUNC void expr_prod(void)
3885 int t;
3887 unary();
3888 while (tok == '*' || tok == '/' || tok == '%') {
3889 t = tok;
3890 next();
3891 unary();
3892 gen_op(t);
3896 ST_FUNC void expr_sum(void)
3898 int t;
3900 expr_prod();
3901 while (tok == '+' || tok == '-') {
3902 t = tok;
3903 next();
3904 expr_prod();
3905 gen_op(t);
3909 static void expr_shift(void)
3911 int t;
3913 expr_sum();
3914 while (tok == TOK_SHL || tok == TOK_SAR) {
3915 t = tok;
3916 next();
3917 expr_sum();
3918 gen_op(t);
3922 static void expr_cmp(void)
3924 int t;
3926 expr_shift();
3927 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3928 tok == TOK_ULT || tok == TOK_UGE) {
3929 t = tok;
3930 next();
3931 expr_shift();
3932 gen_op(t);
3936 static void expr_cmpeq(void)
3938 int t;
3940 expr_cmp();
3941 while (tok == TOK_EQ || tok == TOK_NE) {
3942 t = tok;
3943 next();
3944 expr_cmp();
3945 gen_op(t);
3949 static void expr_and(void)
3951 expr_cmpeq();
3952 while (tok == '&') {
3953 next();
3954 expr_cmpeq();
3955 gen_op('&');
3959 static void expr_xor(void)
3961 expr_and();
3962 while (tok == '^') {
3963 next();
3964 expr_and();
3965 gen_op('^');
3969 static void expr_or(void)
3971 expr_xor();
3972 while (tok == '|') {
3973 next();
3974 expr_xor();
3975 gen_op('|');
3979 /* XXX: fix this mess */
3980 static void expr_land_const(void)
3982 expr_or();
3983 while (tok == TOK_LAND) {
3984 next();
3985 expr_or();
3986 gen_op(TOK_LAND);
3990 /* XXX: fix this mess */
3991 static void expr_lor_const(void)
3993 expr_land_const();
3994 while (tok == TOK_LOR) {
3995 next();
3996 expr_land_const();
3997 gen_op(TOK_LOR);
4001 /* only used if non constant */
4002 static void expr_land(void)
4004 int t;
4006 expr_or();
4007 if (tok == TOK_LAND) {
4008 t = 0;
4009 save_regs(1);
4010 for(;;) {
4011 t = gtst(1, t);
4012 if (tok != TOK_LAND) {
4013 vseti(VT_JMPI, t);
4014 break;
4016 next();
4017 expr_or();
4022 static void expr_lor(void)
4024 int t;
4026 expr_land();
4027 if (tok == TOK_LOR) {
4028 t = 0;
4029 save_regs(1);
4030 for(;;) {
4031 t = gtst(0, t);
4032 if (tok != TOK_LOR) {
4033 vseti(VT_JMP, t);
4034 break;
4036 next();
4037 expr_land();
4042 /* XXX: better constant handling */
4043 static void expr_cond(void)
4045 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4046 SValue sv;
4047 CType type, type1, type2;
4049 if (const_wanted) {
4050 expr_lor_const();
4051 if (tok == '?') {
4052 CType boolean;
4053 int c;
4054 boolean.t = VT_BOOL;
4055 vdup();
4056 gen_cast(&boolean);
4057 c = vtop->c.i;
4058 vpop();
4059 next();
4060 if (tok != ':' || !gnu_ext) {
4061 vpop();
4062 gexpr();
4064 if (!c)
4065 vpop();
4066 skip(':');
4067 expr_cond();
4068 if (c)
4069 vpop();
4071 } else {
4072 expr_lor();
4073 if (tok == '?') {
4074 next();
4075 if (vtop != vstack) {
4076 /* needed to avoid having different registers saved in
4077 each branch */
4078 if (is_float(vtop->type.t)) {
4079 rc = RC_FLOAT;
4080 #ifdef TCC_TARGET_X86_64
4081 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4082 rc = RC_ST0;
4084 #endif
4086 else
4087 rc = RC_INT;
4088 gv(rc);
4089 save_regs(1);
4091 if (tok == ':' && gnu_ext) {
4092 gv_dup();
4093 tt = gtst(1, 0);
4094 } else {
4095 tt = gtst(1, 0);
4096 gexpr();
4098 type1 = vtop->type;
4099 sv = *vtop; /* save value to handle it later */
4100 vtop--; /* no vpop so that FP stack is not flushed */
4101 skip(':');
4102 u = gjmp(0);
4103 gsym(tt);
4104 expr_cond();
4105 type2 = vtop->type;
4107 t1 = type1.t;
4108 bt1 = t1 & VT_BTYPE;
4109 t2 = type2.t;
4110 bt2 = t2 & VT_BTYPE;
4111 /* cast operands to correct type according to ISOC rules */
4112 if (is_float(bt1) || is_float(bt2)) {
4113 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4114 type.t = VT_LDOUBLE;
4115 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4116 type.t = VT_DOUBLE;
4117 } else {
4118 type.t = VT_FLOAT;
4120 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4121 /* cast to biggest op */
4122 type.t = VT_LLONG;
4123 /* convert to unsigned if it does not fit in a long long */
4124 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4125 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4126 type.t |= VT_UNSIGNED;
4127 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4128 /* XXX: test pointer compatibility */
4129 type = type1;
4130 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4131 /* XXX: test function pointer compatibility */
4132 type = type1;
4133 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4134 /* XXX: test structure compatibility */
4135 type = type1;
4136 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4137 /* NOTE: as an extension, we accept void on only one side */
4138 type.t = VT_VOID;
4139 } else {
4140 /* integer operations */
4141 type.t = VT_INT;
4142 /* convert to unsigned if it does not fit in an integer */
4143 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4144 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4145 type.t |= VT_UNSIGNED;
4148 /* now we convert second operand */
4149 gen_cast(&type);
4150 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4151 gaddrof();
4152 rc = RC_INT;
4153 if (is_float(type.t)) {
4154 rc = RC_FLOAT;
4155 #ifdef TCC_TARGET_X86_64
4156 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4157 rc = RC_ST0;
4159 #endif
4160 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4161 /* for long longs, we use fixed registers to avoid having
4162 to handle a complicated move */
4163 rc = RC_IRET;
4166 r2 = gv(rc);
4167 /* this is horrible, but we must also convert first
4168 operand */
4169 tt = gjmp(0);
4170 gsym(u);
4171 /* put again first value and cast it */
4172 *vtop = sv;
4173 gen_cast(&type);
4174 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4175 gaddrof();
4176 r1 = gv(rc);
4177 move_reg(r2, r1);
4178 vtop->r = r2;
4179 gsym(tt);
4184 static void expr_eq(void)
4186 int t;
4188 expr_cond();
4189 if (tok == '=' ||
4190 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4191 tok == TOK_A_XOR || tok == TOK_A_OR ||
4192 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4193 test_lvalue();
4194 t = tok;
4195 next();
4196 if (t == '=') {
4197 expr_eq();
4198 } else {
4199 vdup();
4200 expr_eq();
4201 gen_op(t & 0x7f);
4203 vstore();
4207 ST_FUNC void gexpr(void)
4209 while (1) {
4210 expr_eq();
4211 if (tok != ',')
4212 break;
4213 vpop();
4214 next();
4218 /* parse an expression and return its type without any side effect. */
4219 static void expr_type(CType *type)
4221 int saved_nocode_wanted;
4223 saved_nocode_wanted = nocode_wanted;
4224 nocode_wanted = 1;
4225 gexpr();
4226 *type = vtop->type;
4227 vpop();
4228 nocode_wanted = saved_nocode_wanted;
4231 /* parse a unary expression and return its type without any side
4232 effect. */
4233 static void unary_type(CType *type)
4235 int a;
4237 a = nocode_wanted;
4238 nocode_wanted = 1;
4239 unary();
4240 *type = vtop->type;
4241 vpop();
4242 nocode_wanted = a;
4245 /* parse a constant expression and return value in vtop. */
4246 static void expr_const1(void)
4248 int a;
4249 a = const_wanted;
4250 const_wanted = 1;
4251 expr_cond();
4252 const_wanted = a;
4255 /* parse an integer constant and return its value. */
4256 ST_FUNC int expr_const(void)
4258 int c;
4259 expr_const1();
4260 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4261 expect("constant expression");
4262 c = vtop->c.i;
4263 vpop();
4264 return c;
4267 /* return the label token if current token is a label, otherwise
4268 return zero */
4269 static int is_label(void)
4271 int last_tok;
4273 /* fast test first */
4274 if (tok < TOK_UIDENT)
4275 return 0;
4276 /* no need to save tokc because tok is an identifier */
4277 last_tok = tok;
4278 next();
4279 if (tok == ':') {
4280 next();
4281 return last_tok;
4282 } else {
4283 unget_tok(last_tok);
4284 return 0;
4288 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4289 int case_reg, int is_expr)
4291 int a, b, c, d;
4292 Sym *s;
4294 /* generate line number info */
4295 if (tcc_state->do_debug &&
4296 (last_line_num != file->line_num || last_ind != ind)) {
4297 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4298 last_ind = ind;
4299 last_line_num = file->line_num;
4302 if (is_expr) {
4303 /* default return value is (void) */
4304 vpushi(0);
4305 vtop->type.t = VT_VOID;
4308 if (tok == TOK_IF) {
4309 /* if test */
4310 next();
4311 skip('(');
4312 gexpr();
4313 skip(')');
4314 a = gtst(1, 0);
4315 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4316 c = tok;
4317 if (c == TOK_ELSE) {
4318 next();
4319 d = gjmp(0);
4320 gsym(a);
4321 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4322 gsym(d); /* patch else jmp */
4323 } else
4324 gsym(a);
4325 } else if (tok == TOK_WHILE) {
4326 next();
4327 d = ind;
4328 skip('(');
4329 gexpr();
4330 skip(')');
4331 a = gtst(1, 0);
4332 b = 0;
4333 block(&a, &b, case_sym, def_sym, case_reg, 0);
4334 gjmp_addr(d);
4335 gsym(a);
4336 gsym_addr(b, d);
4337 } else if (tok == '{') {
4338 Sym *llabel;
4339 SValue *pvtop;
4341 next();
4342 /* record local declaration stack position */
4343 s = local_stack;
4344 llabel = local_label_stack;
4345 /* record vstack position */
4346 pvtop = vtop;
4347 /* handle local labels declarations */
4348 if (tok == TOK_LABEL) {
4349 next();
4350 for(;;) {
4351 if (tok < TOK_UIDENT)
4352 expect("label identifier");
4353 label_push(&local_label_stack, tok, LABEL_DECLARED);
4354 next();
4355 if (tok == ',') {
4356 next();
4357 } else {
4358 skip(';');
4359 break;
4363 while (tok != '}') {
4364 decl(VT_LOCAL);
4365 if (tok != '}') {
4366 if (is_expr)
4367 vpop();
4368 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4371 /* pop locally defined labels */
4372 label_pop(&local_label_stack, llabel);
4373 /* pop left-over VLA size expressions */
4374 vtop = pvtop;
4375 if(is_expr) {
4376 /* XXX: this solution makes only valgrind happy...
4377 triggered by gcc.c-torture/execute/20000917-1.c */
4378 Sym *p;
4379 switch(vtop->type.t & VT_BTYPE) {
4380 case VT_PTR:
4381 case VT_STRUCT:
4382 case VT_ENUM:
4383 case VT_FUNC:
4384 for(p=vtop->type.ref;p;p=p->prev)
4385 if(p->prev==s)
4386 error("unsupported expression type");
4389 /* pop locally defined symbols */
4390 sym_pop(&local_stack, s);
4391 next();
4392 } else if (tok == TOK_RETURN) {
4393 next();
4394 if (tok != ';') {
4395 gexpr();
4396 gen_assign_cast(&func_vt);
4397 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4398 CType type;
4399 /* if returning structure, must copy it to implicit
4400 first pointer arg location */
4401 #ifdef TCC_ARM_EABI
4402 int align, size;
4403 size = type_size(&func_vt,&align);
4404 if(size <= 4)
4406 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4407 && (align & 3))
4409 int addr;
4410 loc = (loc - size) & -4;
4411 addr = loc;
4412 type = func_vt;
4413 vset(&type, VT_LOCAL | VT_LVAL, addr);
4414 vswap();
4415 vstore();
4416 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4418 vtop->type = int_type;
4419 gv(RC_IRET);
4420 } else {
4421 #endif
4422 type = func_vt;
4423 mk_pointer(&type);
4424 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4425 indir();
4426 vswap();
4427 /* copy structure value to pointer */
4428 vstore();
4429 #ifdef TCC_ARM_EABI
4431 #endif
4432 } else if (is_float(func_vt.t)) {
4433 gv(rc_fret(func_vt.t));
4434 } else {
4435 gv(RC_IRET);
4437 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4439 skip(';');
4440 rsym = gjmp(rsym); /* jmp */
4441 } else if (tok == TOK_BREAK) {
4442 /* compute jump */
4443 if (!bsym)
4444 error("cannot break");
4445 *bsym = gjmp(*bsym);
4446 next();
4447 skip(';');
4448 } else if (tok == TOK_CONTINUE) {
4449 /* compute jump */
4450 if (!csym)
4451 error("cannot continue");
4452 *csym = gjmp(*csym);
4453 next();
4454 skip(';');
4455 } else if (tok == TOK_FOR) {
4456 int e;
4457 next();
4458 skip('(');
4459 s = local_stack;
4460 if (tok != ';') {
4461 /* c99 for-loop init decl? */
4462 if (!decl0(VT_LOCAL, 1)) {
4463 /* no, regular for-loop init expr */
4464 gexpr();
4465 vpop();
4468 skip(';');
4469 d = ind;
4470 c = ind;
4471 a = 0;
4472 b = 0;
4473 if (tok != ';') {
4474 gexpr();
4475 a = gtst(1, 0);
4477 skip(';');
4478 if (tok != ')') {
4479 e = gjmp(0);
4480 c = ind;
4481 gexpr();
4482 vpop();
4483 gjmp_addr(d);
4484 gsym(e);
4486 skip(')');
4487 block(&a, &b, case_sym, def_sym, case_reg, 0);
4488 gjmp_addr(c);
4489 gsym(a);
4490 gsym_addr(b, c);
4491 sym_pop(&local_stack, s);
4492 } else
4493 if (tok == TOK_DO) {
4494 next();
4495 a = 0;
4496 b = 0;
4497 d = ind;
4498 block(&a, &b, case_sym, def_sym, case_reg, 0);
4499 skip(TOK_WHILE);
4500 skip('(');
4501 gsym(b);
4502 gexpr();
4503 c = gtst(0, 0);
4504 gsym_addr(c, d);
4505 skip(')');
4506 gsym(a);
4507 skip(';');
4508 } else
4509 if (tok == TOK_SWITCH) {
4510 next();
4511 skip('(');
4512 gexpr();
4513 /* XXX: other types than integer */
4514 case_reg = gv(RC_INT);
4515 vpop();
4516 skip(')');
4517 a = 0;
4518 b = gjmp(0); /* jump to first case */
4519 c = 0;
4520 block(&a, csym, &b, &c, case_reg, 0);
4521 /* if no default, jmp after switch */
4522 if (c == 0)
4523 c = ind;
4524 /* default label */
4525 gsym_addr(b, c);
4526 /* break label */
4527 gsym(a);
4528 } else
4529 if (tok == TOK_CASE) {
4530 int v1, v2;
4531 if (!case_sym)
4532 expect("switch");
4533 next();
4534 v1 = expr_const();
4535 v2 = v1;
4536 if (gnu_ext && tok == TOK_DOTS) {
4537 next();
4538 v2 = expr_const();
4539 if (v2 < v1)
4540 warning("empty case range");
4542 /* since a case is like a label, we must skip it with a jmp */
4543 b = gjmp(0);
4544 gsym(*case_sym);
4545 vseti(case_reg, 0);
4546 vpushi(v1);
4547 if (v1 == v2) {
4548 gen_op(TOK_EQ);
4549 *case_sym = gtst(1, 0);
4550 } else {
4551 gen_op(TOK_GE);
4552 *case_sym = gtst(1, 0);
4553 vseti(case_reg, 0);
4554 vpushi(v2);
4555 gen_op(TOK_LE);
4556 *case_sym = gtst(1, *case_sym);
4558 gsym(b);
4559 skip(':');
4560 is_expr = 0;
4561 goto block_after_label;
4562 } else
4563 if (tok == TOK_DEFAULT) {
4564 next();
4565 skip(':');
4566 if (!def_sym)
4567 expect("switch");
4568 if (*def_sym)
4569 error("too many 'default'");
4570 *def_sym = ind;
4571 is_expr = 0;
4572 goto block_after_label;
4573 } else
4574 if (tok == TOK_GOTO) {
4575 next();
4576 if (tok == '*' && gnu_ext) {
4577 /* computed goto */
4578 next();
4579 gexpr();
4580 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4581 expect("pointer");
4582 ggoto();
4583 } else if (tok >= TOK_UIDENT) {
4584 s = label_find(tok);
4585 /* put forward definition if needed */
4586 if (!s) {
4587 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4588 } else {
4589 if (s->r == LABEL_DECLARED)
4590 s->r = LABEL_FORWARD;
4592 /* label already defined */
4593 if (s->r & LABEL_FORWARD)
4594 s->jnext = gjmp(s->jnext);
4595 else
4596 gjmp_addr(s->jnext);
4597 next();
4598 } else {
4599 expect("label identifier");
4601 skip(';');
4602 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4603 asm_instr();
4604 } else {
4605 b = is_label();
4606 if (b) {
4607 /* label case */
4608 s = label_find(b);
4609 if (s) {
4610 if (s->r == LABEL_DEFINED)
4611 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4612 gsym(s->jnext);
4613 s->r = LABEL_DEFINED;
4614 } else {
4615 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4617 s->jnext = ind;
4618 /* we accept this, but it is a mistake */
4619 block_after_label:
4620 if (tok == '}') {
4621 warning("deprecated use of label at end of compound statement");
4622 } else {
4623 if (is_expr)
4624 vpop();
4625 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4627 } else {
4628 /* expression case */
4629 if (tok != ';') {
4630 if (is_expr) {
4631 vpop();
4632 gexpr();
4633 } else {
4634 gexpr();
4635 vpop();
4638 skip(';');
4643 /* t is the array or struct type. c is the array or struct
4644 address. cur_index/cur_field is the pointer to the current
4645 value. 'size_only' is true if only size info is needed (only used
4646 in arrays) */
4647 static void decl_designator(CType *type, Section *sec, unsigned long c,
4648 int *cur_index, Sym **cur_field,
4649 int size_only)
4651 Sym *s, *f;
4652 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4653 CType type1;
4655 notfirst = 0;
4656 elem_size = 0;
4657 nb_elems = 1;
4658 if (gnu_ext && (l = is_label()) != 0)
4659 goto struct_field;
4660 while (tok == '[' || tok == '.') {
4661 if (tok == '[') {
4662 if (!(type->t & VT_ARRAY))
4663 expect("array type");
4664 s = type->ref;
4665 next();
4666 index = expr_const();
4667 if (index < 0 || (s->c >= 0 && index >= s->c))
4668 expect("invalid index");
4669 if (tok == TOK_DOTS && gnu_ext) {
4670 next();
4671 index_last = expr_const();
4672 if (index_last < 0 ||
4673 (s->c >= 0 && index_last >= s->c) ||
4674 index_last < index)
4675 expect("invalid index");
4676 } else {
4677 index_last = index;
4679 skip(']');
4680 if (!notfirst)
4681 *cur_index = index_last;
4682 type = pointed_type(type);
4683 elem_size = type_size(type, &align);
4684 c += index * elem_size;
4685 /* NOTE: we only support ranges for last designator */
4686 nb_elems = index_last - index + 1;
4687 if (nb_elems != 1) {
4688 notfirst = 1;
4689 break;
4691 } else {
4692 next();
4693 l = tok;
4694 next();
4695 struct_field:
4696 if ((type->t & VT_BTYPE) != VT_STRUCT)
4697 expect("struct/union type");
4698 s = type->ref;
4699 l |= SYM_FIELD;
4700 f = s->next;
4701 while (f) {
4702 if (f->v == l)
4703 break;
4704 f = f->next;
4706 if (!f)
4707 expect("field");
4708 if (!notfirst)
4709 *cur_field = f;
4710 /* XXX: fix this mess by using explicit storage field */
4711 type1 = f->type;
4712 type1.t |= (type->t & ~VT_TYPE);
4713 type = &type1;
4714 c += f->c;
4716 notfirst = 1;
4718 if (notfirst) {
4719 if (tok == '=') {
4720 next();
4721 } else {
4722 if (!gnu_ext)
4723 expect("=");
4725 } else {
4726 if (type->t & VT_ARRAY) {
4727 index = *cur_index;
4728 type = pointed_type(type);
4729 c += index * type_size(type, &align);
4730 } else {
4731 f = *cur_field;
4732 if (!f)
4733 error("too many field init");
4734 /* XXX: fix this mess by using explicit storage field */
4735 type1 = f->type;
4736 type1.t |= (type->t & ~VT_TYPE);
4737 type = &type1;
4738 c += f->c;
4741 decl_initializer(type, sec, c, 0, size_only);
4743 /* XXX: make it more general */
4744 if (!size_only && nb_elems > 1) {
4745 unsigned long c_end;
4746 uint8_t *src, *dst;
4747 int i;
4749 if (!sec)
4750 error("range init not supported yet for dynamic storage");
4751 c_end = c + nb_elems * elem_size;
4752 if (c_end > sec->data_allocated)
4753 section_realloc(sec, c_end);
4754 src = sec->data + c;
4755 dst = src;
4756 for(i = 1; i < nb_elems; i++) {
4757 dst += elem_size;
4758 memcpy(dst, src, elem_size);
4763 #define EXPR_VAL 0
4764 #define EXPR_CONST 1
4765 #define EXPR_ANY 2
4767 /* store a value or an expression directly in global data or in local array */
4768 static void init_putv(CType *type, Section *sec, unsigned long c,
4769 int v, int expr_type)
4771 int saved_global_expr, bt, bit_pos, bit_size;
4772 void *ptr;
4773 unsigned long long bit_mask;
4774 CType dtype;
4776 switch(expr_type) {
4777 case EXPR_VAL:
4778 vpushi(v);
4779 break;
4780 case EXPR_CONST:
4781 /* compound literals must be allocated globally in this case */
4782 saved_global_expr = global_expr;
4783 global_expr = 1;
4784 expr_const1();
4785 global_expr = saved_global_expr;
4786 /* NOTE: symbols are accepted */
4787 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4788 error("initializer element is not constant");
4789 break;
4790 case EXPR_ANY:
4791 expr_eq();
4792 break;
4795 dtype = *type;
4796 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4798 if (sec) {
4799 /* XXX: not portable */
4800 /* XXX: generate error if incorrect relocation */
4801 gen_assign_cast(&dtype);
4802 bt = type->t & VT_BTYPE;
4803 /* we'll write at most 12 bytes */
4804 if (c + 12 > sec->data_allocated) {
4805 section_realloc(sec, c + 12);
4807 ptr = sec->data + c;
4808 /* XXX: make code faster ? */
4809 if (!(type->t & VT_BITFIELD)) {
4810 bit_pos = 0;
4811 bit_size = 32;
4812 bit_mask = -1LL;
4813 } else {
4814 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4815 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4816 bit_mask = (1LL << bit_size) - 1;
4818 if ((vtop->r & VT_SYM) &&
4819 (bt == VT_BYTE ||
4820 bt == VT_SHORT ||
4821 bt == VT_DOUBLE ||
4822 bt == VT_LDOUBLE ||
4823 bt == VT_LLONG ||
4824 (bt == VT_INT && bit_size != 32)))
4825 error("initializer element is not computable at load time");
4826 switch(bt) {
4827 case VT_BOOL:
4828 vtop->c.i = (vtop->c.i != 0);
4829 case VT_BYTE:
4830 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4831 break;
4832 case VT_SHORT:
4833 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4834 break;
4835 case VT_DOUBLE:
4836 *(double *)ptr = vtop->c.d;
4837 break;
4838 case VT_LDOUBLE:
4839 *(long double *)ptr = vtop->c.ld;
4840 break;
4841 case VT_LLONG:
4842 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4843 break;
4844 default:
4845 if (vtop->r & VT_SYM) {
4846 greloc(sec, vtop->sym, c, R_DATA_PTR);
4848 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4849 break;
4851 vtop--;
4852 } else {
4853 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4854 vswap();
4855 vstore();
4856 vpop();
4860 /* put zeros for variable based init */
4861 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4863 if (sec) {
4864 /* nothing to do because globals are already set to zero */
4865 } else {
4866 vpush_global_sym(&func_old_type, TOK_memset);
4867 vseti(VT_LOCAL, c);
4868 vpushi(0);
4869 vpushi(size);
4870 gfunc_call(3);
4874 /* 't' contains the type and storage info. 'c' is the offset of the
4875 object in section 'sec'. If 'sec' is NULL, it means stack based
4876 allocation. 'first' is true if array '{' must be read (multi
4877 dimension implicit array init handling). 'size_only' is true if
4878 size only evaluation is wanted (only for arrays). */
4879 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4880 int first, int size_only)
4882 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
4883 int size1, align1, expr_type;
4884 Sym *s, *f;
4885 CType *t1;
4887 if (type->t & VT_VLA) {
4888 int a;
4889 CValue retcval;
4891 vpush_global_sym(&func_old_type, TOK_alloca);
4892 vla_runtime_type_size(type, &a);
4893 gfunc_call(1);
4895 /* return value */
4896 retcval.i = 0;
4897 vsetc(type, REG_IRET, &retcval);
4898 } else if (type->t & VT_ARRAY) {
4899 s = type->ref;
4900 n = s->c;
4901 array_length = 0;
4902 t1 = pointed_type(type);
4903 size1 = type_size(t1, &align1);
4905 no_oblock = 1;
4906 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4907 tok == '{') {
4908 if (tok != '{')
4909 error("character array initializer must be a literal,"
4910 " optionally enclosed in braces");
4911 skip('{');
4912 no_oblock = 0;
4915 /* only parse strings here if correct type (otherwise: handle
4916 them as ((w)char *) expressions */
4917 if ((tok == TOK_LSTR &&
4918 #ifdef TCC_TARGET_PE
4919 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4920 #else
4921 (t1->t & VT_BTYPE) == VT_INT
4922 #endif
4923 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4924 while (tok == TOK_STR || tok == TOK_LSTR) {
4925 int cstr_len, ch;
4926 CString *cstr;
4928 cstr = tokc.cstr;
4929 /* compute maximum number of chars wanted */
4930 if (tok == TOK_STR)
4931 cstr_len = cstr->size;
4932 else
4933 cstr_len = cstr->size / sizeof(nwchar_t);
4934 cstr_len--;
4935 nb = cstr_len;
4936 if (n >= 0 && nb > (n - array_length))
4937 nb = n - array_length;
4938 if (!size_only) {
4939 if (cstr_len > nb)
4940 warning("initializer-string for array is too long");
4941 /* in order to go faster for common case (char
4942 string in global variable, we handle it
4943 specifically */
4944 if (sec && tok == TOK_STR && size1 == 1) {
4945 memcpy(sec->data + c + array_length, cstr->data, nb);
4946 } else {
4947 for(i=0;i<nb;i++) {
4948 if (tok == TOK_STR)
4949 ch = ((unsigned char *)cstr->data)[i];
4950 else
4951 ch = ((nwchar_t *)cstr->data)[i];
4952 init_putv(t1, sec, c + (array_length + i) * size1,
4953 ch, EXPR_VAL);
4957 array_length += nb;
4958 next();
4960 /* only add trailing zero if enough storage (no
4961 warning in this case since it is standard) */
4962 if (n < 0 || array_length < n) {
4963 if (!size_only) {
4964 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4966 array_length++;
4968 } else {
4969 index = 0;
4970 while (tok != '}') {
4971 decl_designator(type, sec, c, &index, NULL, size_only);
4972 if (n >= 0 && index >= n)
4973 error("index too large");
4974 /* must put zero in holes (note that doing it that way
4975 ensures that it even works with designators) */
4976 if (!size_only && array_length < index) {
4977 init_putz(t1, sec, c + array_length * size1,
4978 (index - array_length) * size1);
4980 index++;
4981 if (index > array_length)
4982 array_length = index;
4983 /* special test for multi dimensional arrays (may not
4984 be strictly correct if designators are used at the
4985 same time) */
4986 if (index >= n && no_oblock)
4987 break;
4988 if (tok == '}')
4989 break;
4990 skip(',');
4993 if (!no_oblock)
4994 skip('}');
4995 /* put zeros at the end */
4996 if (!size_only && n >= 0 && array_length < n) {
4997 init_putz(t1, sec, c + array_length * size1,
4998 (n - array_length) * size1);
5000 /* patch type size if needed */
5001 if (n < 0)
5002 s->c = array_length;
5003 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5004 (sec || !first || tok == '{')) {
5005 int par_count;
5007 /* NOTE: the previous test is a specific case for automatic
5008 struct/union init */
5009 /* XXX: union needs only one init */
5011 /* XXX: this test is incorrect for local initializers
5012 beginning with ( without {. It would be much more difficult
5013 to do it correctly (ideally, the expression parser should
5014 be used in all cases) */
5015 par_count = 0;
5016 if (tok == '(') {
5017 AttributeDef ad1;
5018 CType type1;
5019 next();
5020 while (tok == '(') {
5021 par_count++;
5022 next();
5024 if (!parse_btype(&type1, &ad1))
5025 expect("cast");
5026 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5027 #if 0
5028 if (!is_assignable_types(type, &type1))
5029 error("invalid type for cast");
5030 #endif
5031 skip(')');
5033 no_oblock = 1;
5034 if (first || tok == '{') {
5035 skip('{');
5036 no_oblock = 0;
5038 s = type->ref;
5039 f = s->next;
5040 array_length = 0;
5041 index = 0;
5042 n = s->c;
5043 while (tok != '}') {
5044 decl_designator(type, sec, c, NULL, &f, size_only);
5045 index = f->c;
5046 if (!size_only && array_length < index) {
5047 init_putz(type, sec, c + array_length,
5048 index - array_length);
5050 index = index + type_size(&f->type, &align1);
5051 if (index > array_length)
5052 array_length = index;
5054 /* gr: skip fields from same union - ugly. */
5055 while (f->next) {
5056 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5057 /* test for same offset */
5058 if (f->next->c != f->c)
5059 break;
5060 /* if yes, test for bitfield shift */
5061 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5062 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5063 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5064 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5065 if (bit_pos_1 != bit_pos_2)
5066 break;
5068 f = f->next;
5071 f = f->next;
5072 if (no_oblock && f == NULL)
5073 break;
5074 if (tok == '}')
5075 break;
5076 skip(',');
5078 /* put zeros at the end */
5079 if (!size_only && array_length < n) {
5080 init_putz(type, sec, c + array_length,
5081 n - array_length);
5083 if (!no_oblock)
5084 skip('}');
5085 while (par_count) {
5086 skip(')');
5087 par_count--;
5089 } else if (tok == '{') {
5090 next();
5091 decl_initializer(type, sec, c, first, size_only);
5092 skip('}');
5093 } else if (size_only) {
5094 /* just skip expression */
5095 parlevel = parlevel1 = 0;
5096 while ((parlevel > 0 || parlevel1 > 0 ||
5097 (tok != '}' && tok != ',')) && tok != -1) {
5098 if (tok == '(')
5099 parlevel++;
5100 else if (tok == ')')
5101 parlevel--;
5102 else if (tok == '{')
5103 parlevel1++;
5104 else if (tok == '}')
5105 parlevel1--;
5106 next();
5108 } else {
5109 /* currently, we always use constant expression for globals
5110 (may change for scripting case) */
5111 expr_type = EXPR_CONST;
5112 if (!sec)
5113 expr_type = EXPR_ANY;
5114 init_putv(type, sec, c, 0, expr_type);
5118 /* parse an initializer for type 't' if 'has_init' is non zero, and
5119 allocate space in local or global data space ('r' is either
5120 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5121 variable 'v' with an associated name represented by 'asm_label' of
5122 scope 'scope' is declared before initializers are parsed. If 'v' is
5123 zero, then a reference to the new object is put in the value stack.
5124 If 'has_init' is 2, a special parsing is done to handle string
5125 constants. */
5126 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5127 int has_init, int v, char *asm_label,
5128 int scope)
5130 int size, align, addr, data_offset;
5131 int level;
5132 ParseState saved_parse_state = {0};
5133 TokenString init_str;
5134 Section *sec;
5135 Sym *vla = NULL;
5136 Sym *flexible_array;
5138 flexible_array = NULL;
5139 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5140 Sym *field;
5141 field = type->ref;
5142 while (field && field->next)
5143 field = field->next;
5144 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5145 flexible_array = field;
5148 size = type_size(type, &align);
5149 /* If unknown size, we must evaluate it before
5150 evaluating initializers because
5151 initializers can generate global data too
5152 (e.g. string pointers or ISOC99 compound
5153 literals). It also simplifies local
5154 initializers handling */
5155 tok_str_new(&init_str);
5156 if (size < 0 || flexible_array) {
5157 if (!has_init)
5158 error("unknown type size");
5159 /* get all init string */
5160 if (has_init == 2) {
5161 /* only get strings */
5162 while (tok == TOK_STR || tok == TOK_LSTR) {
5163 tok_str_add_tok(&init_str);
5164 next();
5166 } else {
5167 level = 0;
5168 while (level > 0 || (tok != ',' && tok != ';')) {
5169 if (tok < 0)
5170 error("unexpected end of file in initializer");
5171 tok_str_add_tok(&init_str);
5172 if (tok == '{')
5173 level++;
5174 else if (tok == '}') {
5175 level--;
5176 if (level <= 0) {
5177 next();
5178 break;
5181 next();
5184 tok_str_add(&init_str, -1);
5185 tok_str_add(&init_str, 0);
5187 /* compute size */
5188 save_parse_state(&saved_parse_state);
5190 macro_ptr = init_str.str;
5191 next();
5192 decl_initializer(type, NULL, 0, 1, 1);
5193 /* prepare second initializer parsing */
5194 macro_ptr = init_str.str;
5195 next();
5197 /* if still unknown size, error */
5198 size = type_size(type, &align);
5199 if (size < 0)
5200 error("unknown type size");
5202 if (flexible_array)
5203 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5204 /* take into account specified alignment if bigger */
5205 if (ad->aligned) {
5206 if (ad->aligned > align)
5207 align = ad->aligned;
5208 } else if (ad->packed) {
5209 align = 1;
5211 if ((r & VT_VALMASK) == VT_LOCAL) {
5212 sec = NULL;
5213 #ifdef CONFIG_TCC_BCHECK
5214 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5215 loc--;
5217 #endif
5218 loc = (loc - size) & -align;
5219 addr = loc;
5220 #ifdef CONFIG_TCC_BCHECK
5221 /* handles bounds */
5222 /* XXX: currently, since we do only one pass, we cannot track
5223 '&' operators, so we add only arrays */
5224 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5225 unsigned long *bounds_ptr;
5226 /* add padding between regions */
5227 loc--;
5228 /* then add local bound info */
5229 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5230 bounds_ptr[0] = addr;
5231 bounds_ptr[1] = size;
5233 #endif
5234 if (v) {
5235 /* local variable */
5236 vla = sym_push(v, type, r, addr);
5237 } else {
5238 /* push local reference */
5239 vset(type, r, addr);
5241 } else {
5242 Sym *sym;
5244 sym = NULL;
5245 if (v && scope == VT_CONST) {
5246 /* see if the symbol was already defined */
5247 sym = sym_find(v);
5248 if (sym) {
5249 if (!is_compatible_types(&sym->type, type))
5250 error("incompatible types for redefinition of '%s'",
5251 get_tok_str(v, NULL));
5252 if (sym->type.t & VT_EXTERN) {
5253 /* if the variable is extern, it was not allocated */
5254 sym->type.t &= ~VT_EXTERN;
5255 /* set array size if it was ommited in extern
5256 declaration */
5257 if ((sym->type.t & VT_ARRAY) &&
5258 sym->type.ref->c < 0 &&
5259 type->ref->c >= 0)
5260 sym->type.ref->c = type->ref->c;
5261 } else {
5262 /* we accept several definitions of the same
5263 global variable. this is tricky, because we
5264 must play with the SHN_COMMON type of the symbol */
5265 /* XXX: should check if the variable was already
5266 initialized. It is incorrect to initialized it
5267 twice */
5268 /* no init data, we won't add more to the symbol */
5269 if (!has_init)
5270 goto no_alloc;
5275 /* allocate symbol in corresponding section */
5276 sec = ad->section;
5277 if (!sec) {
5278 if (has_init)
5279 sec = data_section;
5280 else if (tcc_state->nocommon)
5281 sec = bss_section;
5283 if (sec) {
5284 data_offset = sec->data_offset;
5285 data_offset = (data_offset + align - 1) & -align;
5286 addr = data_offset;
5287 /* very important to increment global pointer at this time
5288 because initializers themselves can create new initializers */
5289 data_offset += size;
5290 #ifdef CONFIG_TCC_BCHECK
5291 /* add padding if bound check */
5292 if (tcc_state->do_bounds_check)
5293 data_offset++;
5294 #endif
5295 sec->data_offset = data_offset;
5296 /* allocate section space to put the data */
5297 if (sec->sh_type != SHT_NOBITS &&
5298 data_offset > sec->data_allocated)
5299 section_realloc(sec, data_offset);
5300 /* align section if needed */
5301 if (align > sec->sh_addralign)
5302 sec->sh_addralign = align;
5303 } else {
5304 addr = 0; /* avoid warning */
5307 if (v) {
5308 if (scope != VT_CONST || !sym) {
5309 sym = sym_push(v, type, r | VT_SYM, 0);
5310 sym->asm_label = asm_label;
5312 /* update symbol definition */
5313 if (sec) {
5314 put_extern_sym(sym, sec, addr, size);
5315 } else {
5316 ElfW(Sym) *esym;
5317 /* put a common area */
5318 put_extern_sym(sym, NULL, align, size);
5319 /* XXX: find a nicer way */
5320 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5321 esym->st_shndx = SHN_COMMON;
5323 } else {
5324 CValue cval;
5326 /* push global reference */
5327 sym = get_sym_ref(type, sec, addr, size);
5328 cval.ul = 0;
5329 vsetc(type, VT_CONST | VT_SYM, &cval);
5330 vtop->sym = sym;
5332 /* patch symbol weakness */
5333 if (type->t & VT_WEAK)
5334 weaken_symbol(sym);
5335 #ifdef CONFIG_TCC_BCHECK
5336 /* handles bounds now because the symbol must be defined
5337 before for the relocation */
5338 if (tcc_state->do_bounds_check) {
5339 unsigned long *bounds_ptr;
5341 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5342 /* then add global bound info */
5343 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5344 bounds_ptr[0] = 0; /* relocated */
5345 bounds_ptr[1] = size;
5347 #endif
5349 if (has_init || (type->t & VT_VLA)) {
5350 decl_initializer(type, sec, addr, 1, 0);
5351 if (type->t & VT_VLA)
5352 vla->s = vtop;
5353 /* restore parse state if needed */
5354 if (init_str.str) {
5355 tok_str_free(init_str.str);
5356 restore_parse_state(&saved_parse_state);
5358 /* patch flexible array member size back to -1, */
5359 /* for possible subsequent similar declarations */
5360 if (flexible_array)
5361 flexible_array->type.ref->c = -1;
5363 no_alloc: ;
5366 static void put_func_debug(Sym *sym)
5368 char buf[512];
5370 /* stabs info */
5371 /* XXX: we put here a dummy type */
5372 snprintf(buf, sizeof(buf), "%s:%c1",
5373 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5374 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5375 cur_text_section, sym->c);
5376 /* //gr gdb wants a line at the function */
5377 put_stabn(N_SLINE, 0, file->line_num, 0);
5378 last_ind = 0;
5379 last_line_num = 0;
5382 /* parse an old style function declaration list */
5383 /* XXX: check multiple parameter */
5384 static void func_decl_list(Sym *func_sym)
5386 AttributeDef ad;
5387 int v;
5388 Sym *s;
5389 CType btype, type;
5391 /* parse each declaration */
5392 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5393 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5394 if (!parse_btype(&btype, &ad))
5395 expect("declaration list");
5396 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5397 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5398 tok == ';') {
5399 /* we accept no variable after */
5400 } else {
5401 for(;;) {
5402 type = btype;
5403 type_decl(&type, &ad, &v, TYPE_DIRECT);
5404 /* find parameter in function parameter list */
5405 s = func_sym->next;
5406 while (s != NULL) {
5407 if ((s->v & ~SYM_FIELD) == v)
5408 goto found;
5409 s = s->next;
5411 error("declaration for parameter '%s' but no such parameter",
5412 get_tok_str(v, NULL));
5413 found:
5414 /* check that no storage specifier except 'register' was given */
5415 if (type.t & VT_STORAGE)
5416 error("storage class specified for '%s'", get_tok_str(v, NULL));
5417 convert_parameter_type(&type);
5418 /* we can add the type (NOTE: it could be local to the function) */
5419 s->type = type;
5420 /* accept other parameters */
5421 if (tok == ',')
5422 next();
5423 else
5424 break;
5427 skip(';');
5431 /* parse a function defined by symbol 'sym' and generate its code in
5432 'cur_text_section' */
5433 static void gen_function(Sym *sym)
5435 int saved_nocode_wanted = nocode_wanted;
5436 nocode_wanted = 0;
5437 ind = cur_text_section->data_offset;
5438 /* NOTE: we patch the symbol size later */
5439 put_extern_sym(sym, cur_text_section, ind, 0);
5440 funcname = get_tok_str(sym->v, NULL);
5441 func_ind = ind;
5442 /* put debug symbol */
5443 if (tcc_state->do_debug)
5444 put_func_debug(sym);
5445 /* push a dummy symbol to enable local sym storage */
5446 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5447 gfunc_prolog(&sym->type);
5448 rsym = 0;
5449 block(NULL, NULL, NULL, NULL, 0, 0);
5450 gsym(rsym);
5451 gfunc_epilog();
5452 cur_text_section->data_offset = ind;
5453 label_pop(&global_label_stack, NULL);
5454 sym_pop(&local_stack, NULL); /* reset local stack */
5455 /* end of function */
5456 /* patch symbol size */
5457 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5458 ind - func_ind;
5459 /* patch symbol weakness (this definition overrules any prototype) */
5460 if (sym->type.t & VT_WEAK)
5461 weaken_symbol(sym);
5462 if (tcc_state->do_debug) {
5463 put_stabn(N_FUN, 0, 0, ind - func_ind);
5465 /* It's better to crash than to generate wrong code */
5466 cur_text_section = NULL;
5467 funcname = ""; /* for safety */
5468 func_vt.t = VT_VOID; /* for safety */
5469 ind = 0; /* for safety */
5470 nocode_wanted = saved_nocode_wanted;
5473 ST_FUNC void gen_inline_functions(void)
5475 Sym *sym;
5476 int *str, inline_generated, i;
5477 struct InlineFunc *fn;
5479 /* iterate while inline function are referenced */
5480 for(;;) {
5481 inline_generated = 0;
5482 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5483 fn = tcc_state->inline_fns[i];
5484 sym = fn->sym;
5485 if (sym && sym->c) {
5486 /* the function was used: generate its code and
5487 convert it to a normal function */
5488 str = fn->token_str;
5489 fn->sym = NULL;
5490 if (file)
5491 strcpy(file->filename, fn->filename);
5492 sym->r = VT_SYM | VT_CONST;
5493 sym->type.t &= ~VT_INLINE;
5495 macro_ptr = str;
5496 next();
5497 cur_text_section = text_section;
5498 gen_function(sym);
5499 macro_ptr = NULL; /* fail safe */
5501 inline_generated = 1;
5504 if (!inline_generated)
5505 break;
5507 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5508 fn = tcc_state->inline_fns[i];
5509 str = fn->token_str;
5510 tok_str_free(str);
5512 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5515 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5516 static int decl0(int l, int is_for_loop_init)
5518 int v, has_init, r;
5519 CType type, btype;
5520 Sym *sym;
5521 AttributeDef ad;
5523 while (1) {
5524 if (!parse_btype(&btype, &ad)) {
5525 if (is_for_loop_init)
5526 return 0;
5527 /* skip redundant ';' */
5528 /* XXX: find more elegant solution */
5529 if (tok == ';') {
5530 next();
5531 continue;
5533 if (l == VT_CONST &&
5534 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5535 /* global asm block */
5536 asm_global_instr();
5537 continue;
5539 /* special test for old K&R protos without explicit int
5540 type. Only accepted when defining global data */
5541 if (l == VT_LOCAL || tok < TOK_DEFINE)
5542 break;
5543 btype.t = VT_INT;
5545 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5546 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5547 tok == ';') {
5548 /* we accept no variable after */
5549 next();
5550 continue;
5552 while (1) { /* iterate thru each declaration */
5553 char *asm_label; // associated asm label
5554 type = btype;
5555 type_decl(&type, &ad, &v, TYPE_DIRECT);
5556 #if 0
5558 char buf[500];
5559 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5560 printf("type = '%s'\n", buf);
5562 #endif
5563 if ((type.t & VT_BTYPE) == VT_FUNC) {
5564 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5565 error("function without file scope cannot be static");
5567 /* if old style function prototype, we accept a
5568 declaration list */
5569 sym = type.ref;
5570 if (sym->c == FUNC_OLD)
5571 func_decl_list(sym);
5574 asm_label = NULL;
5575 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5576 CString astr;
5578 asm_label_instr(&astr);
5579 asm_label = tcc_strdup(astr.data);
5580 cstr_free(&astr);
5582 /* parse one last attribute list, after asm label */
5583 parse_attribute(&ad);
5586 if (ad.weak)
5587 type.t |= VT_WEAK;
5588 #ifdef TCC_TARGET_PE
5589 if (ad.func_import)
5590 type.t |= VT_IMPORT;
5591 if (ad.func_export)
5592 type.t |= VT_EXPORT;
5593 #endif
5594 if (tok == '{') {
5595 if (l == VT_LOCAL)
5596 error("cannot use local functions");
5597 if ((type.t & VT_BTYPE) != VT_FUNC)
5598 expect("function definition");
5600 /* reject abstract declarators in function definition */
5601 sym = type.ref;
5602 while ((sym = sym->next) != NULL)
5603 if (!(sym->v & ~SYM_FIELD))
5604 expect("identifier");
5606 /* XXX: cannot do better now: convert extern line to static inline */
5607 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5608 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5610 sym = sym_find(v);
5611 if (sym) {
5612 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5613 goto func_error1;
5615 r = sym->type.ref->r;
5616 /* use func_call from prototype if not defined */
5617 if (FUNC_CALL(r) != FUNC_CDECL
5618 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5619 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5621 /* use export from prototype */
5622 if (FUNC_EXPORT(r))
5623 FUNC_EXPORT(type.ref->r) = 1;
5625 /* use static from prototype */
5626 if (sym->type.t & VT_STATIC)
5627 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5629 if (!is_compatible_types(&sym->type, &type)) {
5630 func_error1:
5631 error("incompatible types for redefinition of '%s'",
5632 get_tok_str(v, NULL));
5634 /* if symbol is already defined, then put complete type */
5635 sym->type = type;
5636 } else {
5637 /* put function symbol */
5638 sym = global_identifier_push(v, type.t, 0);
5639 sym->type.ref = type.ref;
5642 /* static inline functions are just recorded as a kind
5643 of macro. Their code will be emitted at the end of
5644 the compilation unit only if they are used */
5645 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5646 (VT_INLINE | VT_STATIC)) {
5647 TokenString func_str;
5648 int block_level;
5649 struct InlineFunc *fn;
5650 const char *filename;
5652 tok_str_new(&func_str);
5654 block_level = 0;
5655 for(;;) {
5656 int t;
5657 if (tok == TOK_EOF)
5658 error("unexpected end of file");
5659 tok_str_add_tok(&func_str);
5660 t = tok;
5661 next();
5662 if (t == '{') {
5663 block_level++;
5664 } else if (t == '}') {
5665 block_level--;
5666 if (block_level == 0)
5667 break;
5670 tok_str_add(&func_str, -1);
5671 tok_str_add(&func_str, 0);
5672 filename = file ? file->filename : "";
5673 fn = tcc_malloc(sizeof *fn + strlen(filename));
5674 strcpy(fn->filename, filename);
5675 fn->sym = sym;
5676 fn->token_str = func_str.str;
5677 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5679 } else {
5680 /* compute text section */
5681 cur_text_section = ad.section;
5682 if (!cur_text_section)
5683 cur_text_section = text_section;
5684 sym->r = VT_SYM | VT_CONST;
5685 gen_function(sym);
5687 break;
5688 } else {
5689 if (btype.t & VT_TYPEDEF) {
5690 /* save typedefed type */
5691 /* XXX: test storage specifiers ? */
5692 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5693 sym->type.t |= VT_TYPEDEF;
5694 } else {
5695 r = 0;
5696 if ((type.t & VT_BTYPE) == VT_FUNC) {
5697 /* external function definition */
5698 /* specific case for func_call attribute */
5699 type.ref->r = INT_ATTR(&ad);
5700 } else if (!(type.t & VT_ARRAY)) {
5701 /* not lvalue if array */
5702 r |= lvalue_type(type.t);
5704 has_init = (tok == '=');
5705 if (has_init && (type.t & VT_VLA))
5706 error("Variable length array cannot be initialized");
5707 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5708 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5709 !has_init && l == VT_CONST && type.ref->c < 0)) {
5710 /* external variable or function */
5711 /* NOTE: as GCC, uninitialized global static
5712 arrays of null size are considered as
5713 extern */
5714 sym = external_sym(v, &type, r, asm_label);
5716 if (type.t & VT_WEAK)
5717 weaken_symbol(sym);
5719 if (ad.alias_target) {
5720 Section tsec;
5721 Elf32_Sym *esym;
5722 Sym *alias_target;
5724 alias_target = sym_find(ad.alias_target);
5725 if (!alias_target || !alias_target->c)
5726 error("unsupported forward __alias__ attribute");
5727 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
5728 tsec.sh_num = esym->st_shndx;
5729 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
5731 } else {
5732 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5733 if (type.t & VT_STATIC)
5734 r |= VT_CONST;
5735 else
5736 r |= l;
5737 if (has_init)
5738 next();
5739 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
5742 if (tok != ',') {
5743 if (is_for_loop_init)
5744 return 1;
5745 skip(';');
5746 break;
5748 next();
5752 return 0;
5755 ST_FUNC void decl(int l)
5757 decl0(l, 0);