VLA fix [3/3]: store VLA sizeofs in anonymous runtime stack vars
[tinycc.git] / tccgen.c
blobbc9b24fba346966fc736079382df2898a786d4cc
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 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2040 } else {
2041 vpushi(type_size(type, a));
2045 /* return the pointed type of t */
2046 static inline CType *pointed_type(CType *type)
2048 return &type->ref->type;
2051 /* modify type so that its it is a pointer to type. */
2052 ST_FUNC void mk_pointer(CType *type)
2054 Sym *s;
2055 s = sym_push(SYM_FIELD, type, 0, -1);
2056 type->t = VT_PTR | (type->t & ~VT_TYPE);
2057 type->ref = s;
2060 /* compare function types. OLD functions match any new functions */
2061 static int is_compatible_func(CType *type1, CType *type2)
2063 Sym *s1, *s2;
2065 s1 = type1->ref;
2066 s2 = type2->ref;
2067 if (!is_compatible_types(&s1->type, &s2->type))
2068 return 0;
2069 /* check func_call */
2070 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2071 return 0;
2072 /* XXX: not complete */
2073 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2074 return 1;
2075 if (s1->c != s2->c)
2076 return 0;
2077 while (s1 != NULL) {
2078 if (s2 == NULL)
2079 return 0;
2080 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2081 return 0;
2082 s1 = s1->next;
2083 s2 = s2->next;
2085 if (s2)
2086 return 0;
2087 return 1;
2090 /* return true if type1 and type2 are the same. If unqualified is
2091 true, qualifiers on the types are ignored.
2093 - enums are not checked as gcc __builtin_types_compatible_p ()
2095 static int compare_types(CType *type1, CType *type2, int unqualified)
2097 int bt1, t1, t2;
2099 t1 = type1->t & VT_TYPE;
2100 t2 = type2->t & VT_TYPE;
2101 if (unqualified) {
2102 /* strip qualifiers before comparing */
2103 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2104 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2106 /* XXX: bitfields ? */
2107 if (t1 != t2)
2108 return 0;
2109 /* test more complicated cases */
2110 bt1 = t1 & VT_BTYPE;
2111 if (bt1 == VT_PTR) {
2112 type1 = pointed_type(type1);
2113 type2 = pointed_type(type2);
2114 return is_compatible_types(type1, type2);
2115 } else if (bt1 == VT_STRUCT) {
2116 return (type1->ref == type2->ref);
2117 } else if (bt1 == VT_FUNC) {
2118 return is_compatible_func(type1, type2);
2119 } else {
2120 return 1;
2124 /* return true if type1 and type2 are exactly the same (including
2125 qualifiers).
2127 static int is_compatible_types(CType *type1, CType *type2)
2129 return compare_types(type1,type2,0);
2132 /* return true if type1 and type2 are the same (ignoring qualifiers).
2134 static int is_compatible_parameter_types(CType *type1, CType *type2)
2136 return compare_types(type1,type2,1);
2139 /* print a type. If 'varstr' is not NULL, then the variable is also
2140 printed in the type */
2141 /* XXX: union */
2142 /* XXX: add array and function pointers */
2143 static void type_to_str(char *buf, int buf_size,
2144 CType *type, const char *varstr)
2146 int bt, v, t;
2147 Sym *s, *sa;
2148 char buf1[256];
2149 const char *tstr;
2151 t = type->t & VT_TYPE;
2152 bt = t & VT_BTYPE;
2153 buf[0] = '\0';
2154 if (t & VT_CONSTANT)
2155 pstrcat(buf, buf_size, "const ");
2156 if (t & VT_VOLATILE)
2157 pstrcat(buf, buf_size, "volatile ");
2158 if (t & VT_UNSIGNED)
2159 pstrcat(buf, buf_size, "unsigned ");
2160 switch(bt) {
2161 case VT_VOID:
2162 tstr = "void";
2163 goto add_tstr;
2164 case VT_BOOL:
2165 tstr = "_Bool";
2166 goto add_tstr;
2167 case VT_BYTE:
2168 tstr = "char";
2169 goto add_tstr;
2170 case VT_SHORT:
2171 tstr = "short";
2172 goto add_tstr;
2173 case VT_INT:
2174 tstr = "int";
2175 goto add_tstr;
2176 case VT_LONG:
2177 tstr = "long";
2178 goto add_tstr;
2179 case VT_LLONG:
2180 tstr = "long long";
2181 goto add_tstr;
2182 case VT_FLOAT:
2183 tstr = "float";
2184 goto add_tstr;
2185 case VT_DOUBLE:
2186 tstr = "double";
2187 goto add_tstr;
2188 case VT_LDOUBLE:
2189 tstr = "long double";
2190 add_tstr:
2191 pstrcat(buf, buf_size, tstr);
2192 break;
2193 case VT_ENUM:
2194 case VT_STRUCT:
2195 if (bt == VT_STRUCT)
2196 tstr = "struct ";
2197 else
2198 tstr = "enum ";
2199 pstrcat(buf, buf_size, tstr);
2200 v = type->ref->v & ~SYM_STRUCT;
2201 if (v >= SYM_FIRST_ANOM)
2202 pstrcat(buf, buf_size, "<anonymous>");
2203 else
2204 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2205 break;
2206 case VT_FUNC:
2207 s = type->ref;
2208 type_to_str(buf, buf_size, &s->type, varstr);
2209 pstrcat(buf, buf_size, "(");
2210 sa = s->next;
2211 while (sa != NULL) {
2212 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2213 pstrcat(buf, buf_size, buf1);
2214 sa = sa->next;
2215 if (sa)
2216 pstrcat(buf, buf_size, ", ");
2218 pstrcat(buf, buf_size, ")");
2219 goto no_var;
2220 case VT_PTR:
2221 s = type->ref;
2222 pstrcpy(buf1, sizeof(buf1), "*");
2223 if (varstr)
2224 pstrcat(buf1, sizeof(buf1), varstr);
2225 type_to_str(buf, buf_size, &s->type, buf1);
2226 goto no_var;
2228 if (varstr) {
2229 pstrcat(buf, buf_size, " ");
2230 pstrcat(buf, buf_size, varstr);
2232 no_var: ;
2235 /* verify type compatibility to store vtop in 'dt' type, and generate
2236 casts if needed. */
2237 static void gen_assign_cast(CType *dt)
2239 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2240 char buf1[256], buf2[256];
2241 int dbt, sbt;
2243 st = &vtop->type; /* source type */
2244 dbt = dt->t & VT_BTYPE;
2245 sbt = st->t & VT_BTYPE;
2246 if (dt->t & VT_CONSTANT)
2247 warning("assignment of read-only location");
2248 switch(dbt) {
2249 case VT_PTR:
2250 /* special cases for pointers */
2251 /* '0' can also be a pointer */
2252 if (is_null_pointer(vtop))
2253 goto type_ok;
2254 /* accept implicit pointer to integer cast with warning */
2255 if (is_integer_btype(sbt)) {
2256 warning("assignment makes pointer from integer without a cast");
2257 goto type_ok;
2259 type1 = pointed_type(dt);
2260 /* a function is implicitely a function pointer */
2261 if (sbt == VT_FUNC) {
2262 if ((type1->t & VT_BTYPE) != VT_VOID &&
2263 !is_compatible_types(pointed_type(dt), st))
2264 warning("assignment from incompatible pointer type");
2265 goto type_ok;
2267 if (sbt != VT_PTR)
2268 goto error;
2269 type2 = pointed_type(st);
2270 if ((type1->t & VT_BTYPE) == VT_VOID ||
2271 (type2->t & VT_BTYPE) == VT_VOID) {
2272 /* void * can match anything */
2273 } else {
2274 /* exact type match, except for unsigned */
2275 tmp_type1 = *type1;
2276 tmp_type2 = *type2;
2277 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2278 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2279 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2280 warning("assignment from incompatible pointer type");
2282 /* check const and volatile */
2283 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2284 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2285 warning("assignment discards qualifiers from pointer target type");
2286 break;
2287 case VT_BYTE:
2288 case VT_SHORT:
2289 case VT_INT:
2290 case VT_LLONG:
2291 if (sbt == VT_PTR || sbt == VT_FUNC) {
2292 warning("assignment makes integer from pointer without a cast");
2294 /* XXX: more tests */
2295 break;
2296 case VT_STRUCT:
2297 tmp_type1 = *dt;
2298 tmp_type2 = *st;
2299 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2300 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2301 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2302 error:
2303 type_to_str(buf1, sizeof(buf1), st, NULL);
2304 type_to_str(buf2, sizeof(buf2), dt, NULL);
2305 error("cannot cast '%s' to '%s'", buf1, buf2);
2307 break;
2309 type_ok:
2310 gen_cast(dt);
2313 /* store vtop in lvalue pushed on stack */
2314 ST_FUNC void vstore(void)
2316 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2318 ft = vtop[-1].type.t;
2319 sbt = vtop->type.t & VT_BTYPE;
2320 dbt = ft & VT_BTYPE;
2321 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2322 (sbt == VT_INT && dbt == VT_SHORT)) {
2323 /* optimize char/short casts */
2324 delayed_cast = VT_MUSTCAST;
2325 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2326 /* XXX: factorize */
2327 if (ft & VT_CONSTANT)
2328 warning("assignment of read-only location");
2329 } else {
2330 delayed_cast = 0;
2331 if (!(ft & VT_BITFIELD))
2332 gen_assign_cast(&vtop[-1].type);
2335 if (sbt == VT_STRUCT) {
2336 /* if structure, only generate pointer */
2337 /* structure assignment : generate memcpy */
2338 /* XXX: optimize if small size */
2339 if (!nocode_wanted) {
2340 size = type_size(&vtop->type, &align);
2342 /* destination */
2343 vswap();
2344 vtop->type.t = VT_PTR;
2345 gaddrof();
2347 /* address of memcpy() */
2348 #ifdef TCC_ARM_EABI
2349 if(!(align & 7))
2350 vpush_global_sym(&func_old_type, TOK_memcpy8);
2351 else if(!(align & 3))
2352 vpush_global_sym(&func_old_type, TOK_memcpy4);
2353 else
2354 #endif
2355 vpush_global_sym(&func_old_type, TOK_memcpy);
2357 vswap();
2358 /* source */
2359 vpushv(vtop - 2);
2360 vtop->type.t = VT_PTR;
2361 gaddrof();
2362 /* type size */
2363 vpushi(size);
2364 gfunc_call(3);
2365 } else {
2366 vswap();
2367 vpop();
2369 /* leave source on stack */
2370 } else if (ft & VT_BITFIELD) {
2371 /* bitfield store handling */
2372 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2373 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2374 /* remove bit field info to avoid loops */
2375 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2377 /* duplicate source into other register */
2378 gv_dup();
2379 vswap();
2380 vrott(3);
2382 if((ft & VT_BTYPE) == VT_BOOL) {
2383 gen_cast(&vtop[-1].type);
2384 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2387 /* duplicate destination */
2388 vdup();
2389 vtop[-1] = vtop[-2];
2391 /* mask and shift source */
2392 if((ft & VT_BTYPE) != VT_BOOL) {
2393 if((ft & VT_BTYPE) == VT_LLONG) {
2394 vpushll((1ULL << bit_size) - 1ULL);
2395 } else {
2396 vpushi((1 << bit_size) - 1);
2398 gen_op('&');
2400 vpushi(bit_pos);
2401 gen_op(TOK_SHL);
2402 /* load destination, mask and or with source */
2403 vswap();
2404 if((ft & VT_BTYPE) == VT_LLONG) {
2405 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2406 } else {
2407 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2409 gen_op('&');
2410 gen_op('|');
2411 /* store result */
2412 vstore();
2414 /* pop off shifted source from "duplicate source..." above */
2415 vpop();
2417 } else {
2418 #ifdef CONFIG_TCC_BCHECK
2419 /* bound check case */
2420 if (vtop[-1].r & VT_MUSTBOUND) {
2421 vswap();
2422 gbound();
2423 vswap();
2425 #endif
2426 if (!nocode_wanted) {
2427 rc = RC_INT;
2428 if (is_float(ft)) {
2429 rc = RC_FLOAT;
2430 #ifdef TCC_TARGET_X86_64
2431 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2432 rc = RC_ST0;
2434 #endif
2436 r = gv(rc); /* generate value */
2437 /* if lvalue was saved on stack, must read it */
2438 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2439 SValue sv;
2440 t = get_reg(RC_INT);
2441 #ifdef TCC_TARGET_X86_64
2442 sv.type.t = VT_PTR;
2443 #else
2444 sv.type.t = VT_INT;
2445 #endif
2446 sv.r = VT_LOCAL | VT_LVAL;
2447 sv.c.ul = vtop[-1].c.ul;
2448 load(t, &sv);
2449 vtop[-1].r = t | VT_LVAL;
2451 store(r, vtop - 1);
2452 #ifndef TCC_TARGET_X86_64
2453 /* two word case handling : store second register at word + 4 */
2454 if ((ft & VT_BTYPE) == VT_LLONG) {
2455 vswap();
2456 /* convert to int to increment easily */
2457 vtop->type.t = VT_INT;
2458 gaddrof();
2459 vpushi(4);
2460 gen_op('+');
2461 vtop->r |= VT_LVAL;
2462 vswap();
2463 /* XXX: it works because r2 is spilled last ! */
2464 store(vtop->r2, vtop - 1);
2466 #endif
2468 vswap();
2469 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2470 vtop->r |= delayed_cast;
2474 /* post defines POST/PRE add. c is the token ++ or -- */
2475 ST_FUNC void inc(int post, int c)
2477 test_lvalue();
2478 vdup(); /* save lvalue */
2479 if (post) {
2480 gv_dup(); /* duplicate value */
2481 vrotb(3);
2482 vrotb(3);
2484 /* add constant */
2485 vpushi(c - TOK_MID);
2486 gen_op('+');
2487 vstore(); /* store value */
2488 if (post)
2489 vpop(); /* if post op, return saved value */
2492 /* Parse GNUC __attribute__ extension. Currently, the following
2493 extensions are recognized:
2494 - aligned(n) : set data/function alignment.
2495 - packed : force data alignment to 1
2496 - section(x) : generate data/code in this section.
2497 - unused : currently ignored, but may be used someday.
2498 - regparm(n) : pass function parameters in registers (i386 only)
2500 static void parse_attribute(AttributeDef *ad)
2502 int t, n;
2504 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2505 next();
2506 skip('(');
2507 skip('(');
2508 while (tok != ')') {
2509 if (tok < TOK_IDENT)
2510 expect("attribute name");
2511 t = tok;
2512 next();
2513 switch(t) {
2514 case TOK_SECTION1:
2515 case TOK_SECTION2:
2516 skip('(');
2517 if (tok != TOK_STR)
2518 expect("section name");
2519 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2520 next();
2521 skip(')');
2522 break;
2523 case TOK_ALIAS1:
2524 case TOK_ALIAS2:
2525 skip('(');
2526 if (tok != TOK_STR)
2527 expect("alias(\"target\")");
2528 ad->alias_target = /* save string as token, for later */
2529 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2530 next();
2531 skip(')');
2532 break;
2533 case TOK_ALIGNED1:
2534 case TOK_ALIGNED2:
2535 if (tok == '(') {
2536 next();
2537 n = expr_const();
2538 if (n <= 0 || (n & (n - 1)) != 0)
2539 error("alignment must be a positive power of two");
2540 skip(')');
2541 } else {
2542 n = MAX_ALIGN;
2544 ad->aligned = n;
2545 break;
2546 case TOK_PACKED1:
2547 case TOK_PACKED2:
2548 ad->packed = 1;
2549 break;
2550 case TOK_WEAK1:
2551 case TOK_WEAK2:
2552 ad->weak = 1;
2553 break;
2554 case TOK_UNUSED1:
2555 case TOK_UNUSED2:
2556 /* currently, no need to handle it because tcc does not
2557 track unused objects */
2558 break;
2559 case TOK_NORETURN1:
2560 case TOK_NORETURN2:
2561 /* currently, no need to handle it because tcc does not
2562 track unused objects */
2563 break;
2564 case TOK_CDECL1:
2565 case TOK_CDECL2:
2566 case TOK_CDECL3:
2567 ad->func_call = FUNC_CDECL;
2568 break;
2569 case TOK_STDCALL1:
2570 case TOK_STDCALL2:
2571 case TOK_STDCALL3:
2572 ad->func_call = FUNC_STDCALL;
2573 break;
2574 #ifdef TCC_TARGET_I386
2575 case TOK_REGPARM1:
2576 case TOK_REGPARM2:
2577 skip('(');
2578 n = expr_const();
2579 if (n > 3)
2580 n = 3;
2581 else if (n < 0)
2582 n = 0;
2583 if (n > 0)
2584 ad->func_call = FUNC_FASTCALL1 + n - 1;
2585 skip(')');
2586 break;
2587 case TOK_FASTCALL1:
2588 case TOK_FASTCALL2:
2589 case TOK_FASTCALL3:
2590 ad->func_call = FUNC_FASTCALLW;
2591 break;
2592 #endif
2593 case TOK_MODE:
2594 skip('(');
2595 switch(tok) {
2596 case TOK_MODE_DI:
2597 ad->mode = VT_LLONG + 1;
2598 break;
2599 case TOK_MODE_HI:
2600 ad->mode = VT_SHORT + 1;
2601 break;
2602 case TOK_MODE_SI:
2603 ad->mode = VT_INT + 1;
2604 break;
2605 default:
2606 warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2607 break;
2609 next();
2610 skip(')');
2611 break;
2612 case TOK_DLLEXPORT:
2613 ad->func_export = 1;
2614 break;
2615 case TOK_DLLIMPORT:
2616 ad->func_import = 1;
2617 break;
2618 default:
2619 if (tcc_state->warn_unsupported)
2620 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2621 /* skip parameters */
2622 if (tok == '(') {
2623 int parenthesis = 0;
2624 do {
2625 if (tok == '(')
2626 parenthesis++;
2627 else if (tok == ')')
2628 parenthesis--;
2629 next();
2630 } while (parenthesis && tok != -1);
2632 break;
2634 if (tok != ',')
2635 break;
2636 next();
2638 skip(')');
2639 skip(')');
2643 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2644 static void struct_decl(CType *type, int u)
2646 int a, v, size, align, maxalign, c, offset;
2647 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2648 Sym *s, *ss, *ass, **ps;
2649 AttributeDef ad;
2650 CType type1, btype;
2652 a = tok; /* save decl type */
2653 next();
2654 if (tok != '{') {
2655 v = tok;
2656 next();
2657 /* struct already defined ? return it */
2658 if (v < TOK_IDENT)
2659 expect("struct/union/enum name");
2660 s = struct_find(v);
2661 if (s) {
2662 if (s->type.t != a)
2663 error("invalid type");
2664 goto do_decl;
2666 } else {
2667 v = anon_sym++;
2669 type1.t = a;
2670 /* we put an undefined size for struct/union */
2671 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2672 s->r = 0; /* default alignment is zero as gcc */
2673 /* put struct/union/enum name in type */
2674 do_decl:
2675 type->t = u;
2676 type->ref = s;
2678 if (tok == '{') {
2679 next();
2680 if (s->c != -1)
2681 error("struct/union/enum already defined");
2682 /* cannot be empty */
2683 c = 0;
2684 /* non empty enums are not allowed */
2685 if (a == TOK_ENUM) {
2686 for(;;) {
2687 v = tok;
2688 if (v < TOK_UIDENT)
2689 expect("identifier");
2690 next();
2691 if (tok == '=') {
2692 next();
2693 c = expr_const();
2695 /* enum symbols have static storage */
2696 ss = sym_push(v, &int_type, VT_CONST, c);
2697 ss->type.t |= VT_STATIC;
2698 if (tok != ',')
2699 break;
2700 next();
2701 c++;
2702 /* NOTE: we accept a trailing comma */
2703 if (tok == '}')
2704 break;
2706 skip('}');
2707 } else {
2708 maxalign = 1;
2709 ps = &s->next;
2710 prevbt = VT_INT;
2711 bit_pos = 0;
2712 offset = 0;
2713 while (tok != '}') {
2714 parse_btype(&btype, &ad);
2715 while (1) {
2716 bit_size = -1;
2717 v = 0;
2718 type1 = btype;
2719 if (tok != ':') {
2720 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2721 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2722 expect("identifier");
2723 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2724 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2725 error("invalid type for '%s'",
2726 get_tok_str(v, NULL));
2728 if (tok == ':') {
2729 next();
2730 bit_size = expr_const();
2731 /* XXX: handle v = 0 case for messages */
2732 if (bit_size < 0)
2733 error("negative width in bit-field '%s'",
2734 get_tok_str(v, NULL));
2735 if (v && bit_size == 0)
2736 error("zero width for bit-field '%s'",
2737 get_tok_str(v, NULL));
2739 size = type_size(&type1, &align);
2740 if (ad.aligned) {
2741 if (align < ad.aligned)
2742 align = ad.aligned;
2743 } else if (ad.packed) {
2744 align = 1;
2745 } else if (*tcc_state->pack_stack_ptr) {
2746 if (align > *tcc_state->pack_stack_ptr)
2747 align = *tcc_state->pack_stack_ptr;
2749 lbit_pos = 0;
2750 if (bit_size >= 0) {
2751 bt = type1.t & VT_BTYPE;
2752 if (bt != VT_INT &&
2753 bt != VT_BYTE &&
2754 bt != VT_SHORT &&
2755 bt != VT_BOOL &&
2756 bt != VT_ENUM &&
2757 bt != VT_LLONG)
2758 error("bitfields must have scalar type");
2759 bsize = size * 8;
2760 if (bit_size > bsize) {
2761 error("width of '%s' exceeds its type",
2762 get_tok_str(v, NULL));
2763 } else if (bit_size == bsize) {
2764 /* no need for bit fields */
2765 bit_pos = 0;
2766 } else if (bit_size == 0) {
2767 /* XXX: what to do if only padding in a
2768 structure ? */
2769 /* zero size: means to pad */
2770 bit_pos = 0;
2771 } else {
2772 /* we do not have enough room ?
2773 did the type change?
2774 is it a union? */
2775 if ((bit_pos + bit_size) > bsize ||
2776 bt != prevbt || a == TOK_UNION)
2777 bit_pos = 0;
2778 lbit_pos = bit_pos;
2779 /* XXX: handle LSB first */
2780 type1.t |= VT_BITFIELD |
2781 (bit_pos << VT_STRUCT_SHIFT) |
2782 (bit_size << (VT_STRUCT_SHIFT + 6));
2783 bit_pos += bit_size;
2785 prevbt = bt;
2786 } else {
2787 bit_pos = 0;
2789 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2790 /* add new memory data only if starting
2791 bit field */
2792 if (lbit_pos == 0) {
2793 if (a == TOK_STRUCT) {
2794 c = (c + align - 1) & -align;
2795 offset = c;
2796 if (size > 0)
2797 c += size;
2798 } else {
2799 offset = 0;
2800 if (size > c)
2801 c = size;
2803 if (align > maxalign)
2804 maxalign = align;
2806 #if 0
2807 printf("add field %s offset=%d",
2808 get_tok_str(v, NULL), offset);
2809 if (type1.t & VT_BITFIELD) {
2810 printf(" pos=%d size=%d",
2811 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2812 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2814 printf("\n");
2815 #endif
2817 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2818 ass = type1.ref;
2819 while ((ass = ass->next) != NULL) {
2820 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2821 *ps = ss;
2822 ps = &ss->next;
2824 } else if (v) {
2825 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2826 *ps = ss;
2827 ps = &ss->next;
2829 if (tok == ';' || tok == TOK_EOF)
2830 break;
2831 skip(',');
2833 skip(';');
2835 skip('}');
2836 /* store size and alignment */
2837 s->c = (c + maxalign - 1) & -maxalign;
2838 s->r = maxalign;
2843 /* return 0 if no type declaration. otherwise, return the basic type
2844 and skip it.
2846 static int parse_btype(CType *type, AttributeDef *ad)
2848 int t, u, type_found, typespec_found, typedef_found;
2849 Sym *s;
2850 CType type1;
2852 memset(ad, 0, sizeof(AttributeDef));
2853 type_found = 0;
2854 typespec_found = 0;
2855 typedef_found = 0;
2856 t = 0;
2857 while(1) {
2858 switch(tok) {
2859 case TOK_EXTENSION:
2860 /* currently, we really ignore extension */
2861 next();
2862 continue;
2864 /* basic types */
2865 case TOK_CHAR:
2866 u = VT_BYTE;
2867 basic_type:
2868 next();
2869 basic_type1:
2870 if ((t & VT_BTYPE) != 0)
2871 error("too many basic types");
2872 t |= u;
2873 typespec_found = 1;
2874 break;
2875 case TOK_VOID:
2876 u = VT_VOID;
2877 goto basic_type;
2878 case TOK_SHORT:
2879 u = VT_SHORT;
2880 goto basic_type;
2881 case TOK_INT:
2882 next();
2883 typespec_found = 1;
2884 break;
2885 case TOK_LONG:
2886 next();
2887 if ((t & VT_BTYPE) == VT_DOUBLE) {
2888 #ifndef TCC_TARGET_PE
2889 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2890 #endif
2891 } else if ((t & VT_BTYPE) == VT_LONG) {
2892 t = (t & ~VT_BTYPE) | VT_LLONG;
2893 } else {
2894 u = VT_LONG;
2895 goto basic_type1;
2897 break;
2898 case TOK_BOOL:
2899 u = VT_BOOL;
2900 goto basic_type;
2901 case TOK_FLOAT:
2902 u = VT_FLOAT;
2903 goto basic_type;
2904 case TOK_DOUBLE:
2905 next();
2906 if ((t & VT_BTYPE) == VT_LONG) {
2907 #ifdef TCC_TARGET_PE
2908 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2909 #else
2910 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2911 #endif
2912 } else {
2913 u = VT_DOUBLE;
2914 goto basic_type1;
2916 break;
2917 case TOK_ENUM:
2918 struct_decl(&type1, VT_ENUM);
2919 basic_type2:
2920 u = type1.t;
2921 type->ref = type1.ref;
2922 goto basic_type1;
2923 case TOK_STRUCT:
2924 case TOK_UNION:
2925 struct_decl(&type1, VT_STRUCT);
2926 goto basic_type2;
2928 /* type modifiers */
2929 case TOK_CONST1:
2930 case TOK_CONST2:
2931 case TOK_CONST3:
2932 t |= VT_CONSTANT;
2933 next();
2934 break;
2935 case TOK_VOLATILE1:
2936 case TOK_VOLATILE2:
2937 case TOK_VOLATILE3:
2938 t |= VT_VOLATILE;
2939 next();
2940 break;
2941 case TOK_SIGNED1:
2942 case TOK_SIGNED2:
2943 case TOK_SIGNED3:
2944 typespec_found = 1;
2945 t |= VT_SIGNED;
2946 next();
2947 break;
2948 case TOK_REGISTER:
2949 case TOK_AUTO:
2950 case TOK_RESTRICT1:
2951 case TOK_RESTRICT2:
2952 case TOK_RESTRICT3:
2953 next();
2954 break;
2955 case TOK_UNSIGNED:
2956 t |= VT_UNSIGNED;
2957 next();
2958 typespec_found = 1;
2959 break;
2961 /* storage */
2962 case TOK_EXTERN:
2963 t |= VT_EXTERN;
2964 next();
2965 break;
2966 case TOK_STATIC:
2967 t |= VT_STATIC;
2968 next();
2969 break;
2970 case TOK_TYPEDEF:
2971 t |= VT_TYPEDEF;
2972 next();
2973 break;
2974 case TOK_INLINE1:
2975 case TOK_INLINE2:
2976 case TOK_INLINE3:
2977 t |= VT_INLINE;
2978 next();
2979 break;
2981 /* GNUC attribute */
2982 case TOK_ATTRIBUTE1:
2983 case TOK_ATTRIBUTE2:
2984 parse_attribute(ad);
2985 if (ad->mode) {
2986 u = ad->mode -1;
2987 t = (t & ~VT_BTYPE) | u;
2989 break;
2990 /* GNUC typeof */
2991 case TOK_TYPEOF1:
2992 case TOK_TYPEOF2:
2993 case TOK_TYPEOF3:
2994 next();
2995 parse_expr_type(&type1);
2996 /* remove all storage modifiers except typedef */
2997 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
2998 goto basic_type2;
2999 default:
3000 if (typespec_found || typedef_found)
3001 goto the_end;
3002 s = sym_find(tok);
3003 if (!s || !(s->type.t & VT_TYPEDEF))
3004 goto the_end;
3005 typedef_found = 1;
3006 t |= (s->type.t & ~VT_TYPEDEF);
3007 type->ref = s->type.ref;
3008 if (s->r) {
3009 /* get attributes from typedef */
3010 if (0 == ad->aligned)
3011 ad->aligned = FUNC_ALIGN(s->r);
3012 if (0 == ad->func_call)
3013 ad->func_call = FUNC_CALL(s->r);
3014 ad->packed |= FUNC_PACKED(s->r);
3016 next();
3017 typespec_found = 1;
3018 break;
3020 type_found = 1;
3022 the_end:
3023 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3024 error("signed and unsigned modifier");
3025 if (tcc_state->char_is_unsigned) {
3026 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3027 t |= VT_UNSIGNED;
3029 t &= ~VT_SIGNED;
3031 /* long is never used as type */
3032 if ((t & VT_BTYPE) == VT_LONG)
3033 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3034 t = (t & ~VT_BTYPE) | VT_INT;
3035 #else
3036 t = (t & ~VT_BTYPE) | VT_LLONG;
3037 #endif
3038 type->t = t;
3039 return type_found;
3042 /* convert a function parameter type (array to pointer and function to
3043 function pointer) */
3044 static inline void convert_parameter_type(CType *pt)
3046 /* remove const and volatile qualifiers (XXX: const could be used
3047 to indicate a const function parameter */
3048 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3049 /* array must be transformed to pointer according to ANSI C */
3050 pt->t &= ~VT_ARRAY;
3051 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3052 mk_pointer(pt);
3056 ST_FUNC void parse_asm_str(CString *astr)
3058 skip('(');
3059 /* read the string */
3060 if (tok != TOK_STR)
3061 expect("string constant");
3062 cstr_new(astr);
3063 while (tok == TOK_STR) {
3064 /* XXX: add \0 handling too ? */
3065 cstr_cat(astr, tokc.cstr->data);
3066 next();
3068 cstr_ccat(astr, '\0');
3071 /* Parse an asm label and return the label
3072 * Don't forget to free the CString in the caller! */
3073 static void asm_label_instr(CString *astr)
3075 next();
3076 parse_asm_str(astr);
3077 skip(')');
3078 #ifdef ASM_DEBUG
3079 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3080 #endif
3083 static void post_type(CType *type, AttributeDef *ad)
3085 int n, l, t1, arg_size, align;
3086 Sym **plast, *s, *first;
3087 AttributeDef ad1;
3088 CType pt;
3090 if (tok == '(') {
3091 /* function declaration */
3092 next();
3093 l = 0;
3094 first = NULL;
3095 plast = &first;
3096 arg_size = 0;
3097 if (tok != ')') {
3098 for(;;) {
3099 /* read param name and compute offset */
3100 if (l != FUNC_OLD) {
3101 if (!parse_btype(&pt, &ad1)) {
3102 if (l) {
3103 error("invalid type");
3104 } else {
3105 l = FUNC_OLD;
3106 goto old_proto;
3109 l = FUNC_NEW;
3110 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3111 break;
3112 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3113 if ((pt.t & VT_BTYPE) == VT_VOID)
3114 error("parameter declared as void");
3115 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3116 } else {
3117 old_proto:
3118 n = tok;
3119 if (n < TOK_UIDENT)
3120 expect("identifier");
3121 pt.t = VT_INT;
3122 next();
3124 convert_parameter_type(&pt);
3125 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3126 *plast = s;
3127 plast = &s->next;
3128 if (tok == ')')
3129 break;
3130 skip(',');
3131 if (l == FUNC_NEW && tok == TOK_DOTS) {
3132 l = FUNC_ELLIPSIS;
3133 next();
3134 break;
3138 /* if no parameters, then old type prototype */
3139 if (l == 0)
3140 l = FUNC_OLD;
3141 skip(')');
3142 /* NOTE: const is ignored in returned type as it has a special
3143 meaning in gcc / C++ */
3144 type->t &= ~VT_CONSTANT;
3145 /* some ancient pre-K&R C allows a function to return an array
3146 and the array brackets to be put after the arguments, such
3147 that "int c()[]" means something like "int[] c()" */
3148 if (tok == '[') {
3149 next();
3150 skip(']'); /* only handle simple "[]" */
3151 type->t |= VT_PTR;
3153 /* we push a anonymous symbol which will contain the function prototype */
3154 ad->func_args = arg_size;
3155 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3156 s->next = first;
3157 type->t = VT_FUNC;
3158 type->ref = s;
3159 } else if (tok == '[') {
3160 /* array definition */
3161 next();
3162 if (tok == TOK_RESTRICT1)
3163 next();
3164 n = -1;
3165 t1 = 0;
3166 if (tok != ']') {
3167 gexpr();
3168 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3169 n = vtop->c.i;
3170 if (n < 0)
3171 error("invalid array size");
3172 } else {
3173 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3174 error("size of variable length array should be an integer");
3175 t1 = VT_VLA;
3178 skip(']');
3179 /* parse next post type */
3180 post_type(type, ad);
3181 t1 |= type->t & VT_VLA;
3183 if (t1 & VT_VLA) {
3184 loc -= type_size(&int_type, &align);
3185 loc &= -align;
3186 n = loc;
3188 vla_runtime_type_size(type, &align);
3189 gen_op('*');
3190 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3191 vswap();
3192 vstore();
3194 if (n != -1)
3195 vpop();
3197 /* we push an anonymous symbol which will contain the array
3198 element type */
3199 s = sym_push(SYM_FIELD, type, 0, n);
3200 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3201 type->ref = s;
3205 /* Parse a type declaration (except basic type), and return the type
3206 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3207 expected. 'type' should contain the basic type. 'ad' is the
3208 attribute definition of the basic type. It can be modified by
3209 type_decl().
3211 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3213 Sym *s;
3214 CType type1, *type2;
3215 int qualifiers, storage;
3217 while (tok == '*') {
3218 qualifiers = 0;
3219 redo:
3220 next();
3221 switch(tok) {
3222 case TOK_CONST1:
3223 case TOK_CONST2:
3224 case TOK_CONST3:
3225 qualifiers |= VT_CONSTANT;
3226 goto redo;
3227 case TOK_VOLATILE1:
3228 case TOK_VOLATILE2:
3229 case TOK_VOLATILE3:
3230 qualifiers |= VT_VOLATILE;
3231 goto redo;
3232 case TOK_RESTRICT1:
3233 case TOK_RESTRICT2:
3234 case TOK_RESTRICT3:
3235 goto redo;
3237 mk_pointer(type);
3238 type->t |= qualifiers;
3241 /* XXX: clarify attribute handling */
3242 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3243 parse_attribute(ad);
3245 /* recursive type */
3246 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3247 type1.t = 0; /* XXX: same as int */
3248 if (tok == '(') {
3249 next();
3250 /* XXX: this is not correct to modify 'ad' at this point, but
3251 the syntax is not clear */
3252 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3253 parse_attribute(ad);
3254 type_decl(&type1, ad, v, td);
3255 skip(')');
3256 } else {
3257 /* type identifier */
3258 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3259 *v = tok;
3260 next();
3261 } else {
3262 if (!(td & TYPE_ABSTRACT))
3263 expect("identifier");
3264 *v = 0;
3267 storage = type->t & VT_STORAGE;
3268 type->t &= ~VT_STORAGE;
3269 post_type(type, ad);
3270 type->t |= storage;
3271 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3272 parse_attribute(ad);
3274 if (!type1.t)
3275 return;
3276 /* append type at the end of type1 */
3277 type2 = &type1;
3278 for(;;) {
3279 s = type2->ref;
3280 type2 = &s->type;
3281 if (!type2->t) {
3282 *type2 = *type;
3283 break;
3286 *type = type1;
3289 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3290 ST_FUNC int lvalue_type(int t)
3292 int bt, r;
3293 r = VT_LVAL;
3294 bt = t & VT_BTYPE;
3295 if (bt == VT_BYTE || bt == VT_BOOL)
3296 r |= VT_LVAL_BYTE;
3297 else if (bt == VT_SHORT)
3298 r |= VT_LVAL_SHORT;
3299 else
3300 return r;
3301 if (t & VT_UNSIGNED)
3302 r |= VT_LVAL_UNSIGNED;
3303 return r;
3306 /* indirection with full error checking and bound check */
3307 ST_FUNC void indir(void)
3309 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3310 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3311 return;
3312 expect("pointer");
3314 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3315 gv(RC_INT);
3316 vtop->type = *pointed_type(&vtop->type);
3317 /* Arrays and functions are never lvalues */
3318 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3319 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3320 vtop->r |= lvalue_type(vtop->type.t);
3321 /* if bound checking, the referenced pointer must be checked */
3322 #ifdef CONFIG_TCC_BCHECK
3323 if (tcc_state->do_bounds_check)
3324 vtop->r |= VT_MUSTBOUND;
3325 #endif
3329 /* pass a parameter to a function and do type checking and casting */
3330 static void gfunc_param_typed(Sym *func, Sym *arg)
3332 int func_type;
3333 CType type;
3335 func_type = func->c;
3336 if (func_type == FUNC_OLD ||
3337 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3338 /* default casting : only need to convert float to double */
3339 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3340 type.t = VT_DOUBLE;
3341 gen_cast(&type);
3343 } else if (arg == NULL) {
3344 error("too many arguments to function");
3345 } else {
3346 type = arg->type;
3347 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3348 gen_assign_cast(&type);
3352 /* parse an expression of the form '(type)' or '(expr)' and return its
3353 type */
3354 static void parse_expr_type(CType *type)
3356 int n;
3357 AttributeDef ad;
3359 skip('(');
3360 if (parse_btype(type, &ad)) {
3361 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3362 } else {
3363 expr_type(type);
3365 skip(')');
3368 static void parse_type(CType *type)
3370 AttributeDef ad;
3371 int n;
3373 if (!parse_btype(type, &ad)) {
3374 expect("type");
3376 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3379 static void vpush_tokc(int t)
3381 CType type;
3382 type.t = t;
3383 type.ref = 0;
3384 vsetc(&type, VT_CONST, &tokc);
3387 ST_FUNC void unary(void)
3389 int n, t, align, size, r, sizeof_caller;
3390 CType type;
3391 Sym *s;
3392 AttributeDef ad;
3393 static int in_sizeof = 0;
3395 sizeof_caller = in_sizeof;
3396 in_sizeof = 0;
3397 /* XXX: GCC 2.95.3 does not generate a table although it should be
3398 better here */
3399 tok_next:
3400 switch(tok) {
3401 case TOK_EXTENSION:
3402 next();
3403 goto tok_next;
3404 case TOK_CINT:
3405 case TOK_CCHAR:
3406 case TOK_LCHAR:
3407 vpushi(tokc.i);
3408 next();
3409 break;
3410 case TOK_CUINT:
3411 vpush_tokc(VT_INT | VT_UNSIGNED);
3412 next();
3413 break;
3414 case TOK_CLLONG:
3415 vpush_tokc(VT_LLONG);
3416 next();
3417 break;
3418 case TOK_CULLONG:
3419 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3420 next();
3421 break;
3422 case TOK_CFLOAT:
3423 vpush_tokc(VT_FLOAT);
3424 next();
3425 break;
3426 case TOK_CDOUBLE:
3427 vpush_tokc(VT_DOUBLE);
3428 next();
3429 break;
3430 case TOK_CLDOUBLE:
3431 vpush_tokc(VT_LDOUBLE);
3432 next();
3433 break;
3434 case TOK___FUNCTION__:
3435 if (!gnu_ext)
3436 goto tok_identifier;
3437 /* fall thru */
3438 case TOK___FUNC__:
3440 void *ptr;
3441 int len;
3442 /* special function name identifier */
3443 len = strlen(funcname) + 1;
3444 /* generate char[len] type */
3445 type.t = VT_BYTE;
3446 mk_pointer(&type);
3447 type.t |= VT_ARRAY;
3448 type.ref->c = len;
3449 vpush_ref(&type, data_section, data_section->data_offset, len);
3450 ptr = section_ptr_add(data_section, len);
3451 memcpy(ptr, funcname, len);
3452 next();
3454 break;
3455 case TOK_LSTR:
3456 #ifdef TCC_TARGET_PE
3457 t = VT_SHORT | VT_UNSIGNED;
3458 #else
3459 t = VT_INT;
3460 #endif
3461 goto str_init;
3462 case TOK_STR:
3463 /* string parsing */
3464 t = VT_BYTE;
3465 str_init:
3466 if (tcc_state->warn_write_strings)
3467 t |= VT_CONSTANT;
3468 type.t = t;
3469 mk_pointer(&type);
3470 type.t |= VT_ARRAY;
3471 memset(&ad, 0, sizeof(AttributeDef));
3472 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3473 break;
3474 case '(':
3475 next();
3476 /* cast ? */
3477 if (parse_btype(&type, &ad)) {
3478 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3479 skip(')');
3480 /* check ISOC99 compound literal */
3481 if (tok == '{') {
3482 /* data is allocated locally by default */
3483 if (global_expr)
3484 r = VT_CONST;
3485 else
3486 r = VT_LOCAL;
3487 /* all except arrays are lvalues */
3488 if (!(type.t & VT_ARRAY))
3489 r |= lvalue_type(type.t);
3490 memset(&ad, 0, sizeof(AttributeDef));
3491 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3492 } else {
3493 if (sizeof_caller) {
3494 vpush(&type);
3495 return;
3497 unary();
3498 gen_cast(&type);
3500 } else if (tok == '{') {
3501 /* save all registers */
3502 save_regs(0);
3503 /* statement expression : we do not accept break/continue
3504 inside as GCC does */
3505 block(NULL, NULL, NULL, NULL, 0, 1);
3506 skip(')');
3507 } else {
3508 gexpr();
3509 skip(')');
3511 break;
3512 case '*':
3513 next();
3514 unary();
3515 indir();
3516 break;
3517 case '&':
3518 next();
3519 unary();
3520 /* functions names must be treated as function pointers,
3521 except for unary '&' and sizeof. Since we consider that
3522 functions are not lvalues, we only have to handle it
3523 there and in function calls. */
3524 /* arrays can also be used although they are not lvalues */
3525 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3526 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3527 test_lvalue();
3528 mk_pointer(&vtop->type);
3529 gaddrof();
3530 break;
3531 case '!':
3532 next();
3533 unary();
3534 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3535 CType boolean;
3536 boolean.t = VT_BOOL;
3537 gen_cast(&boolean);
3538 vtop->c.i = !vtop->c.i;
3539 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3540 vtop->c.i = vtop->c.i ^ 1;
3541 else {
3542 save_regs(1);
3543 vseti(VT_JMP, gtst(1, 0));
3545 break;
3546 case '~':
3547 next();
3548 unary();
3549 vpushi(-1);
3550 gen_op('^');
3551 break;
3552 case '+':
3553 next();
3554 /* in order to force cast, we add zero */
3555 unary();
3556 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3557 error("pointer not accepted for unary plus");
3558 vpushi(0);
3559 gen_op('+');
3560 break;
3561 case TOK_SIZEOF:
3562 case TOK_ALIGNOF1:
3563 case TOK_ALIGNOF2:
3564 t = tok;
3565 next();
3566 in_sizeof++;
3567 unary_type(&type); // Perform a in_sizeof = 0;
3568 size = type_size(&type, &align);
3569 if (t == TOK_SIZEOF) {
3570 if (!(type.t & VT_VLA)) {
3571 if (size < 0)
3572 error("sizeof applied to an incomplete type");
3573 vpushi(size);
3574 } else {
3575 vla_runtime_type_size(&type, &align);
3577 } else {
3578 vpushi(align);
3580 vtop->type.t |= VT_UNSIGNED;
3581 break;
3583 case TOK_builtin_types_compatible_p:
3585 CType type1, type2;
3586 next();
3587 skip('(');
3588 parse_type(&type1);
3589 skip(',');
3590 parse_type(&type2);
3591 skip(')');
3592 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3593 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3594 vpushi(is_compatible_types(&type1, &type2));
3596 break;
3597 case TOK_builtin_constant_p:
3599 int saved_nocode_wanted, res;
3600 next();
3601 skip('(');
3602 saved_nocode_wanted = nocode_wanted;
3603 nocode_wanted = 1;
3604 gexpr();
3605 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3606 vpop();
3607 nocode_wanted = saved_nocode_wanted;
3608 skip(')');
3609 vpushi(res);
3611 break;
3612 case TOK_builtin_frame_address:
3614 CType type;
3615 next();
3616 skip('(');
3617 if (tok != TOK_CINT) {
3618 error("__builtin_frame_address only takes integers");
3620 if (tokc.i != 0) {
3621 error("TCC only supports __builtin_frame_address(0)");
3623 next();
3624 skip(')');
3625 type.t = VT_VOID;
3626 mk_pointer(&type);
3627 vset(&type, VT_LOCAL, 0);
3629 break;
3630 #ifdef TCC_TARGET_X86_64
3631 case TOK_builtin_va_arg_types:
3633 /* This definition must be synced with stdarg.h */
3634 enum __va_arg_type {
3635 __va_gen_reg, __va_float_reg, __va_stack
3637 CType type;
3638 int bt;
3639 next();
3640 skip('(');
3641 parse_type(&type);
3642 skip(')');
3643 bt = type.t & VT_BTYPE;
3644 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3645 vpushi(__va_stack);
3646 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3647 vpushi(__va_float_reg);
3648 } else {
3649 vpushi(__va_gen_reg);
3652 break;
3653 #endif
3654 case TOK_INC:
3655 case TOK_DEC:
3656 t = tok;
3657 next();
3658 unary();
3659 inc(0, t);
3660 break;
3661 case '-':
3662 next();
3663 vpushi(0);
3664 unary();
3665 gen_op('-');
3666 break;
3667 case TOK_LAND:
3668 if (!gnu_ext)
3669 goto tok_identifier;
3670 next();
3671 /* allow to take the address of a label */
3672 if (tok < TOK_UIDENT)
3673 expect("label identifier");
3674 s = label_find(tok);
3675 if (!s) {
3676 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3677 } else {
3678 if (s->r == LABEL_DECLARED)
3679 s->r = LABEL_FORWARD;
3681 if (!s->type.t) {
3682 s->type.t = VT_VOID;
3683 mk_pointer(&s->type);
3684 s->type.t |= VT_STATIC;
3686 vset(&s->type, VT_CONST | VT_SYM, 0);
3687 vtop->sym = s;
3688 next();
3689 break;
3691 // special qnan , snan and infinity values
3692 case TOK___NAN__:
3693 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3694 next();
3695 break;
3696 case TOK___SNAN__:
3697 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3698 next();
3699 break;
3700 case TOK___INF__:
3701 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3702 next();
3703 break;
3705 default:
3706 tok_identifier:
3707 t = tok;
3708 next();
3709 if (t < TOK_UIDENT)
3710 expect("identifier");
3711 s = sym_find(t);
3712 if (!s) {
3713 if (tok != '(')
3714 error("'%s' undeclared", get_tok_str(t, NULL));
3715 /* for simple function calls, we tolerate undeclared
3716 external reference to int() function */
3717 if (tcc_state->warn_implicit_function_declaration)
3718 warning("implicit declaration of function '%s'",
3719 get_tok_str(t, NULL));
3720 s = external_global_sym(t, &func_old_type, 0);
3722 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3723 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3724 /* if referencing an inline function, then we generate a
3725 symbol to it if not already done. It will have the
3726 effect to generate code for it at the end of the
3727 compilation unit. Inline function as always
3728 generated in the text section. */
3729 if (!s->c)
3730 put_extern_sym(s, text_section, 0, 0);
3731 r = VT_SYM | VT_CONST;
3732 } else {
3733 r = s->r;
3735 vset(&s->type, r, s->c);
3736 /* if forward reference, we must point to s */
3737 if (vtop->r & VT_SYM) {
3738 vtop->sym = s;
3739 vtop->c.ul = 0;
3741 break;
3744 /* post operations */
3745 while (1) {
3746 if (tok == TOK_INC || tok == TOK_DEC) {
3747 inc(1, tok);
3748 next();
3749 } else if (tok == '.' || tok == TOK_ARROW) {
3750 int qualifiers;
3751 /* field */
3752 if (tok == TOK_ARROW)
3753 indir();
3754 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3755 test_lvalue();
3756 gaddrof();
3757 next();
3758 /* expect pointer on structure */
3759 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3760 expect("struct or union");
3761 s = vtop->type.ref;
3762 /* find field */
3763 tok |= SYM_FIELD;
3764 while ((s = s->next) != NULL) {
3765 if (s->v == tok)
3766 break;
3768 if (!s)
3769 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3770 /* add field offset to pointer */
3771 vtop->type = char_pointer_type; /* change type to 'char *' */
3772 vpushi(s->c);
3773 gen_op('+');
3774 /* change type to field type, and set to lvalue */
3775 vtop->type = s->type;
3776 vtop->type.t |= qualifiers;
3777 /* an array is never an lvalue */
3778 if (!(vtop->type.t & VT_ARRAY)) {
3779 vtop->r |= lvalue_type(vtop->type.t);
3780 #ifdef CONFIG_TCC_BCHECK
3781 /* if bound checking, the referenced pointer must be checked */
3782 if (tcc_state->do_bounds_check)
3783 vtop->r |= VT_MUSTBOUND;
3784 #endif
3786 next();
3787 } else if (tok == '[') {
3788 next();
3789 gexpr();
3790 gen_op('+');
3791 indir();
3792 skip(']');
3793 } else if (tok == '(') {
3794 SValue ret;
3795 Sym *sa;
3796 int nb_args;
3798 /* function call */
3799 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3800 /* pointer test (no array accepted) */
3801 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3802 vtop->type = *pointed_type(&vtop->type);
3803 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3804 goto error_func;
3805 } else {
3806 error_func:
3807 expect("function pointer");
3809 } else {
3810 vtop->r &= ~VT_LVAL; /* no lvalue */
3812 /* get return type */
3813 s = vtop->type.ref;
3814 next();
3815 sa = s->next; /* first parameter */
3816 nb_args = 0;
3817 ret.r2 = VT_CONST;
3818 /* compute first implicit argument if a structure is returned */
3819 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3820 /* get some space for the returned structure */
3821 size = type_size(&s->type, &align);
3822 loc = (loc - size) & -align;
3823 ret.type = s->type;
3824 ret.r = VT_LOCAL | VT_LVAL;
3825 /* pass it as 'int' to avoid structure arg passing
3826 problems */
3827 vseti(VT_LOCAL, loc);
3828 ret.c = vtop->c;
3829 nb_args++;
3830 } else {
3831 ret.type = s->type;
3832 /* return in register */
3833 if (is_float(ret.type.t)) {
3834 ret.r = reg_fret(ret.type.t);
3835 } else {
3836 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3837 ret.r2 = REG_LRET;
3838 ret.r = REG_IRET;
3840 ret.c.i = 0;
3842 if (tok != ')') {
3843 for(;;) {
3844 expr_eq();
3845 gfunc_param_typed(s, sa);
3846 nb_args++;
3847 if (sa)
3848 sa = sa->next;
3849 if (tok == ')')
3850 break;
3851 skip(',');
3854 if (sa)
3855 error("too few arguments to function");
3856 skip(')');
3857 if (!nocode_wanted) {
3858 gfunc_call(nb_args);
3859 } else {
3860 vtop -= (nb_args + 1);
3862 /* return value */
3863 vsetc(&ret.type, ret.r, &ret.c);
3864 vtop->r2 = ret.r2;
3865 } else {
3866 break;
3871 ST_FUNC void expr_prod(void)
3873 int t;
3875 unary();
3876 while (tok == '*' || tok == '/' || tok == '%') {
3877 t = tok;
3878 next();
3879 unary();
3880 gen_op(t);
3884 ST_FUNC void expr_sum(void)
3886 int t;
3888 expr_prod();
3889 while (tok == '+' || tok == '-') {
3890 t = tok;
3891 next();
3892 expr_prod();
3893 gen_op(t);
3897 static void expr_shift(void)
3899 int t;
3901 expr_sum();
3902 while (tok == TOK_SHL || tok == TOK_SAR) {
3903 t = tok;
3904 next();
3905 expr_sum();
3906 gen_op(t);
3910 static void expr_cmp(void)
3912 int t;
3914 expr_shift();
3915 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3916 tok == TOK_ULT || tok == TOK_UGE) {
3917 t = tok;
3918 next();
3919 expr_shift();
3920 gen_op(t);
3924 static void expr_cmpeq(void)
3926 int t;
3928 expr_cmp();
3929 while (tok == TOK_EQ || tok == TOK_NE) {
3930 t = tok;
3931 next();
3932 expr_cmp();
3933 gen_op(t);
3937 static void expr_and(void)
3939 expr_cmpeq();
3940 while (tok == '&') {
3941 next();
3942 expr_cmpeq();
3943 gen_op('&');
3947 static void expr_xor(void)
3949 expr_and();
3950 while (tok == '^') {
3951 next();
3952 expr_and();
3953 gen_op('^');
3957 static void expr_or(void)
3959 expr_xor();
3960 while (tok == '|') {
3961 next();
3962 expr_xor();
3963 gen_op('|');
3967 /* XXX: fix this mess */
3968 static void expr_land_const(void)
3970 expr_or();
3971 while (tok == TOK_LAND) {
3972 next();
3973 expr_or();
3974 gen_op(TOK_LAND);
3978 /* XXX: fix this mess */
3979 static void expr_lor_const(void)
3981 expr_land_const();
3982 while (tok == TOK_LOR) {
3983 next();
3984 expr_land_const();
3985 gen_op(TOK_LOR);
3989 /* only used if non constant */
3990 static void expr_land(void)
3992 int t;
3994 expr_or();
3995 if (tok == TOK_LAND) {
3996 t = 0;
3997 save_regs(1);
3998 for(;;) {
3999 t = gtst(1, t);
4000 if (tok != TOK_LAND) {
4001 vseti(VT_JMPI, t);
4002 break;
4004 next();
4005 expr_or();
4010 static void expr_lor(void)
4012 int t;
4014 expr_land();
4015 if (tok == TOK_LOR) {
4016 t = 0;
4017 save_regs(1);
4018 for(;;) {
4019 t = gtst(0, t);
4020 if (tok != TOK_LOR) {
4021 vseti(VT_JMP, t);
4022 break;
4024 next();
4025 expr_land();
4030 /* XXX: better constant handling */
4031 static void expr_cond(void)
4033 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4034 SValue sv;
4035 CType type, type1, type2;
4037 if (const_wanted) {
4038 expr_lor_const();
4039 if (tok == '?') {
4040 CType boolean;
4041 int c;
4042 boolean.t = VT_BOOL;
4043 vdup();
4044 gen_cast(&boolean);
4045 c = vtop->c.i;
4046 vpop();
4047 next();
4048 if (tok != ':' || !gnu_ext) {
4049 vpop();
4050 gexpr();
4052 if (!c)
4053 vpop();
4054 skip(':');
4055 expr_cond();
4056 if (c)
4057 vpop();
4059 } else {
4060 expr_lor();
4061 if (tok == '?') {
4062 next();
4063 if (vtop != vstack) {
4064 /* needed to avoid having different registers saved in
4065 each branch */
4066 if (is_float(vtop->type.t)) {
4067 rc = RC_FLOAT;
4068 #ifdef TCC_TARGET_X86_64
4069 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4070 rc = RC_ST0;
4072 #endif
4074 else
4075 rc = RC_INT;
4076 gv(rc);
4077 save_regs(1);
4079 if (tok == ':' && gnu_ext) {
4080 gv_dup();
4081 tt = gtst(1, 0);
4082 } else {
4083 tt = gtst(1, 0);
4084 gexpr();
4086 type1 = vtop->type;
4087 sv = *vtop; /* save value to handle it later */
4088 vtop--; /* no vpop so that FP stack is not flushed */
4089 skip(':');
4090 u = gjmp(0);
4091 gsym(tt);
4092 expr_cond();
4093 type2 = vtop->type;
4095 t1 = type1.t;
4096 bt1 = t1 & VT_BTYPE;
4097 t2 = type2.t;
4098 bt2 = t2 & VT_BTYPE;
4099 /* cast operands to correct type according to ISOC rules */
4100 if (is_float(bt1) || is_float(bt2)) {
4101 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4102 type.t = VT_LDOUBLE;
4103 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4104 type.t = VT_DOUBLE;
4105 } else {
4106 type.t = VT_FLOAT;
4108 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4109 /* cast to biggest op */
4110 type.t = VT_LLONG;
4111 /* convert to unsigned if it does not fit in a long long */
4112 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4113 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4114 type.t |= VT_UNSIGNED;
4115 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4116 /* XXX: test pointer compatibility */
4117 type = type1;
4118 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4119 /* XXX: test function pointer compatibility */
4120 type = type1;
4121 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4122 /* XXX: test structure compatibility */
4123 type = type1;
4124 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4125 /* NOTE: as an extension, we accept void on only one side */
4126 type.t = VT_VOID;
4127 } else {
4128 /* integer operations */
4129 type.t = VT_INT;
4130 /* convert to unsigned if it does not fit in an integer */
4131 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4132 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4133 type.t |= VT_UNSIGNED;
4136 /* now we convert second operand */
4137 gen_cast(&type);
4138 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4139 gaddrof();
4140 rc = RC_INT;
4141 if (is_float(type.t)) {
4142 rc = RC_FLOAT;
4143 #ifdef TCC_TARGET_X86_64
4144 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4145 rc = RC_ST0;
4147 #endif
4148 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4149 /* for long longs, we use fixed registers to avoid having
4150 to handle a complicated move */
4151 rc = RC_IRET;
4154 r2 = gv(rc);
4155 /* this is horrible, but we must also convert first
4156 operand */
4157 tt = gjmp(0);
4158 gsym(u);
4159 /* put again first value and cast it */
4160 *vtop = sv;
4161 gen_cast(&type);
4162 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4163 gaddrof();
4164 r1 = gv(rc);
4165 move_reg(r2, r1);
4166 vtop->r = r2;
4167 gsym(tt);
4172 static void expr_eq(void)
4174 int t;
4176 expr_cond();
4177 if (tok == '=' ||
4178 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4179 tok == TOK_A_XOR || tok == TOK_A_OR ||
4180 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4181 test_lvalue();
4182 t = tok;
4183 next();
4184 if (t == '=') {
4185 expr_eq();
4186 } else {
4187 vdup();
4188 expr_eq();
4189 gen_op(t & 0x7f);
4191 vstore();
4195 ST_FUNC void gexpr(void)
4197 while (1) {
4198 expr_eq();
4199 if (tok != ',')
4200 break;
4201 vpop();
4202 next();
4206 /* parse an expression and return its type without any side effect. */
4207 static void expr_type(CType *type)
4209 int saved_nocode_wanted;
4211 saved_nocode_wanted = nocode_wanted;
4212 nocode_wanted = 1;
4213 gexpr();
4214 *type = vtop->type;
4215 vpop();
4216 nocode_wanted = saved_nocode_wanted;
4219 /* parse a unary expression and return its type without any side
4220 effect. */
4221 static void unary_type(CType *type)
4223 int a;
4225 a = nocode_wanted;
4226 nocode_wanted = 1;
4227 unary();
4228 *type = vtop->type;
4229 vpop();
4230 nocode_wanted = a;
4233 /* parse a constant expression and return value in vtop. */
4234 static void expr_const1(void)
4236 int a;
4237 a = const_wanted;
4238 const_wanted = 1;
4239 expr_cond();
4240 const_wanted = a;
4243 /* parse an integer constant and return its value. */
4244 ST_FUNC int expr_const(void)
4246 int c;
4247 expr_const1();
4248 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4249 expect("constant expression");
4250 c = vtop->c.i;
4251 vpop();
4252 return c;
4255 /* return the label token if current token is a label, otherwise
4256 return zero */
4257 static int is_label(void)
4259 int last_tok;
4261 /* fast test first */
4262 if (tok < TOK_UIDENT)
4263 return 0;
4264 /* no need to save tokc because tok is an identifier */
4265 last_tok = tok;
4266 next();
4267 if (tok == ':') {
4268 next();
4269 return last_tok;
4270 } else {
4271 unget_tok(last_tok);
4272 return 0;
4276 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4277 int case_reg, int is_expr)
4279 int a, b, c, d;
4280 Sym *s;
4282 /* generate line number info */
4283 if (tcc_state->do_debug &&
4284 (last_line_num != file->line_num || last_ind != ind)) {
4285 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4286 last_ind = ind;
4287 last_line_num = file->line_num;
4290 if (is_expr) {
4291 /* default return value is (void) */
4292 vpushi(0);
4293 vtop->type.t = VT_VOID;
4296 if (tok == TOK_IF) {
4297 /* if test */
4298 next();
4299 skip('(');
4300 gexpr();
4301 skip(')');
4302 a = gtst(1, 0);
4303 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4304 c = tok;
4305 if (c == TOK_ELSE) {
4306 next();
4307 d = gjmp(0);
4308 gsym(a);
4309 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4310 gsym(d); /* patch else jmp */
4311 } else
4312 gsym(a);
4313 } else if (tok == TOK_WHILE) {
4314 next();
4315 d = ind;
4316 skip('(');
4317 gexpr();
4318 skip(')');
4319 a = gtst(1, 0);
4320 b = 0;
4321 block(&a, &b, case_sym, def_sym, case_reg, 0);
4322 gjmp_addr(d);
4323 gsym(a);
4324 gsym_addr(b, d);
4325 } else if (tok == '{') {
4326 Sym *llabel;
4327 SValue *pvtop;
4329 next();
4330 /* record local declaration stack position */
4331 s = local_stack;
4332 llabel = local_label_stack;
4333 /* record vstack position */
4334 pvtop = vtop;
4335 /* handle local labels declarations */
4336 if (tok == TOK_LABEL) {
4337 next();
4338 for(;;) {
4339 if (tok < TOK_UIDENT)
4340 expect("label identifier");
4341 label_push(&local_label_stack, tok, LABEL_DECLARED);
4342 next();
4343 if (tok == ',') {
4344 next();
4345 } else {
4346 skip(';');
4347 break;
4351 while (tok != '}') {
4352 decl(VT_LOCAL);
4353 if (tok != '}') {
4354 if (is_expr)
4355 vpop();
4356 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4359 /* pop locally defined labels */
4360 label_pop(&local_label_stack, llabel);
4361 /* pop left-over VLA size expressions */
4362 vtop = pvtop;
4363 if(is_expr) {
4364 /* XXX: this solution makes only valgrind happy...
4365 triggered by gcc.c-torture/execute/20000917-1.c */
4366 Sym *p;
4367 switch(vtop->type.t & VT_BTYPE) {
4368 case VT_PTR:
4369 case VT_STRUCT:
4370 case VT_ENUM:
4371 case VT_FUNC:
4372 for(p=vtop->type.ref;p;p=p->prev)
4373 if(p->prev==s)
4374 error("unsupported expression type");
4377 /* pop locally defined symbols */
4378 sym_pop(&local_stack, s);
4379 next();
4380 } else if (tok == TOK_RETURN) {
4381 next();
4382 if (tok != ';') {
4383 gexpr();
4384 gen_assign_cast(&func_vt);
4385 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4386 CType type;
4387 /* if returning structure, must copy it to implicit
4388 first pointer arg location */
4389 #ifdef TCC_ARM_EABI
4390 int align, size;
4391 size = type_size(&func_vt,&align);
4392 if(size <= 4)
4394 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4395 && (align & 3))
4397 int addr;
4398 loc = (loc - size) & -4;
4399 addr = loc;
4400 type = func_vt;
4401 vset(&type, VT_LOCAL | VT_LVAL, addr);
4402 vswap();
4403 vstore();
4404 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4406 vtop->type = int_type;
4407 gv(RC_IRET);
4408 } else {
4409 #endif
4410 type = func_vt;
4411 mk_pointer(&type);
4412 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4413 indir();
4414 vswap();
4415 /* copy structure value to pointer */
4416 vstore();
4417 #ifdef TCC_ARM_EABI
4419 #endif
4420 } else if (is_float(func_vt.t)) {
4421 gv(rc_fret(func_vt.t));
4422 } else {
4423 gv(RC_IRET);
4425 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4427 skip(';');
4428 rsym = gjmp(rsym); /* jmp */
4429 } else if (tok == TOK_BREAK) {
4430 /* compute jump */
4431 if (!bsym)
4432 error("cannot break");
4433 *bsym = gjmp(*bsym);
4434 next();
4435 skip(';');
4436 } else if (tok == TOK_CONTINUE) {
4437 /* compute jump */
4438 if (!csym)
4439 error("cannot continue");
4440 *csym = gjmp(*csym);
4441 next();
4442 skip(';');
4443 } else if (tok == TOK_FOR) {
4444 int e;
4445 next();
4446 skip('(');
4447 s = local_stack;
4448 if (tok != ';') {
4449 /* c99 for-loop init decl? */
4450 if (!decl0(VT_LOCAL, 1)) {
4451 /* no, regular for-loop init expr */
4452 gexpr();
4453 vpop();
4456 skip(';');
4457 d = ind;
4458 c = ind;
4459 a = 0;
4460 b = 0;
4461 if (tok != ';') {
4462 gexpr();
4463 a = gtst(1, 0);
4465 skip(';');
4466 if (tok != ')') {
4467 e = gjmp(0);
4468 c = ind;
4469 gexpr();
4470 vpop();
4471 gjmp_addr(d);
4472 gsym(e);
4474 skip(')');
4475 block(&a, &b, case_sym, def_sym, case_reg, 0);
4476 gjmp_addr(c);
4477 gsym(a);
4478 gsym_addr(b, c);
4479 sym_pop(&local_stack, s);
4480 } else
4481 if (tok == TOK_DO) {
4482 next();
4483 a = 0;
4484 b = 0;
4485 d = ind;
4486 block(&a, &b, case_sym, def_sym, case_reg, 0);
4487 skip(TOK_WHILE);
4488 skip('(');
4489 gsym(b);
4490 gexpr();
4491 c = gtst(0, 0);
4492 gsym_addr(c, d);
4493 skip(')');
4494 gsym(a);
4495 skip(';');
4496 } else
4497 if (tok == TOK_SWITCH) {
4498 next();
4499 skip('(');
4500 gexpr();
4501 /* XXX: other types than integer */
4502 case_reg = gv(RC_INT);
4503 vpop();
4504 skip(')');
4505 a = 0;
4506 b = gjmp(0); /* jump to first case */
4507 c = 0;
4508 block(&a, csym, &b, &c, case_reg, 0);
4509 /* if no default, jmp after switch */
4510 if (c == 0)
4511 c = ind;
4512 /* default label */
4513 gsym_addr(b, c);
4514 /* break label */
4515 gsym(a);
4516 } else
4517 if (tok == TOK_CASE) {
4518 int v1, v2;
4519 if (!case_sym)
4520 expect("switch");
4521 next();
4522 v1 = expr_const();
4523 v2 = v1;
4524 if (gnu_ext && tok == TOK_DOTS) {
4525 next();
4526 v2 = expr_const();
4527 if (v2 < v1)
4528 warning("empty case range");
4530 /* since a case is like a label, we must skip it with a jmp */
4531 b = gjmp(0);
4532 gsym(*case_sym);
4533 vseti(case_reg, 0);
4534 vpushi(v1);
4535 if (v1 == v2) {
4536 gen_op(TOK_EQ);
4537 *case_sym = gtst(1, 0);
4538 } else {
4539 gen_op(TOK_GE);
4540 *case_sym = gtst(1, 0);
4541 vseti(case_reg, 0);
4542 vpushi(v2);
4543 gen_op(TOK_LE);
4544 *case_sym = gtst(1, *case_sym);
4546 gsym(b);
4547 skip(':');
4548 is_expr = 0;
4549 goto block_after_label;
4550 } else
4551 if (tok == TOK_DEFAULT) {
4552 next();
4553 skip(':');
4554 if (!def_sym)
4555 expect("switch");
4556 if (*def_sym)
4557 error("too many 'default'");
4558 *def_sym = ind;
4559 is_expr = 0;
4560 goto block_after_label;
4561 } else
4562 if (tok == TOK_GOTO) {
4563 next();
4564 if (tok == '*' && gnu_ext) {
4565 /* computed goto */
4566 next();
4567 gexpr();
4568 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4569 expect("pointer");
4570 ggoto();
4571 } else if (tok >= TOK_UIDENT) {
4572 s = label_find(tok);
4573 /* put forward definition if needed */
4574 if (!s) {
4575 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4576 } else {
4577 if (s->r == LABEL_DECLARED)
4578 s->r = LABEL_FORWARD;
4580 /* label already defined */
4581 if (s->r & LABEL_FORWARD)
4582 s->jnext = gjmp(s->jnext);
4583 else
4584 gjmp_addr(s->jnext);
4585 next();
4586 } else {
4587 expect("label identifier");
4589 skip(';');
4590 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4591 asm_instr();
4592 } else {
4593 b = is_label();
4594 if (b) {
4595 /* label case */
4596 s = label_find(b);
4597 if (s) {
4598 if (s->r == LABEL_DEFINED)
4599 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4600 gsym(s->jnext);
4601 s->r = LABEL_DEFINED;
4602 } else {
4603 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4605 s->jnext = ind;
4606 /* we accept this, but it is a mistake */
4607 block_after_label:
4608 if (tok == '}') {
4609 warning("deprecated use of label at end of compound statement");
4610 } else {
4611 if (is_expr)
4612 vpop();
4613 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4615 } else {
4616 /* expression case */
4617 if (tok != ';') {
4618 if (is_expr) {
4619 vpop();
4620 gexpr();
4621 } else {
4622 gexpr();
4623 vpop();
4626 skip(';');
4631 /* t is the array or struct type. c is the array or struct
4632 address. cur_index/cur_field is the pointer to the current
4633 value. 'size_only' is true if only size info is needed (only used
4634 in arrays) */
4635 static void decl_designator(CType *type, Section *sec, unsigned long c,
4636 int *cur_index, Sym **cur_field,
4637 int size_only)
4639 Sym *s, *f;
4640 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4641 CType type1;
4643 notfirst = 0;
4644 elem_size = 0;
4645 nb_elems = 1;
4646 if (gnu_ext && (l = is_label()) != 0)
4647 goto struct_field;
4648 while (tok == '[' || tok == '.') {
4649 if (tok == '[') {
4650 if (!(type->t & VT_ARRAY))
4651 expect("array type");
4652 s = type->ref;
4653 next();
4654 index = expr_const();
4655 if (index < 0 || (s->c >= 0 && index >= s->c))
4656 expect("invalid index");
4657 if (tok == TOK_DOTS && gnu_ext) {
4658 next();
4659 index_last = expr_const();
4660 if (index_last < 0 ||
4661 (s->c >= 0 && index_last >= s->c) ||
4662 index_last < index)
4663 expect("invalid index");
4664 } else {
4665 index_last = index;
4667 skip(']');
4668 if (!notfirst)
4669 *cur_index = index_last;
4670 type = pointed_type(type);
4671 elem_size = type_size(type, &align);
4672 c += index * elem_size;
4673 /* NOTE: we only support ranges for last designator */
4674 nb_elems = index_last - index + 1;
4675 if (nb_elems != 1) {
4676 notfirst = 1;
4677 break;
4679 } else {
4680 next();
4681 l = tok;
4682 next();
4683 struct_field:
4684 if ((type->t & VT_BTYPE) != VT_STRUCT)
4685 expect("struct/union type");
4686 s = type->ref;
4687 l |= SYM_FIELD;
4688 f = s->next;
4689 while (f) {
4690 if (f->v == l)
4691 break;
4692 f = f->next;
4694 if (!f)
4695 expect("field");
4696 if (!notfirst)
4697 *cur_field = f;
4698 /* XXX: fix this mess by using explicit storage field */
4699 type1 = f->type;
4700 type1.t |= (type->t & ~VT_TYPE);
4701 type = &type1;
4702 c += f->c;
4704 notfirst = 1;
4706 if (notfirst) {
4707 if (tok == '=') {
4708 next();
4709 } else {
4710 if (!gnu_ext)
4711 expect("=");
4713 } else {
4714 if (type->t & VT_ARRAY) {
4715 index = *cur_index;
4716 type = pointed_type(type);
4717 c += index * type_size(type, &align);
4718 } else {
4719 f = *cur_field;
4720 if (!f)
4721 error("too many field init");
4722 /* XXX: fix this mess by using explicit storage field */
4723 type1 = f->type;
4724 type1.t |= (type->t & ~VT_TYPE);
4725 type = &type1;
4726 c += f->c;
4729 decl_initializer(type, sec, c, 0, size_only);
4731 /* XXX: make it more general */
4732 if (!size_only && nb_elems > 1) {
4733 unsigned long c_end;
4734 uint8_t *src, *dst;
4735 int i;
4737 if (!sec)
4738 error("range init not supported yet for dynamic storage");
4739 c_end = c + nb_elems * elem_size;
4740 if (c_end > sec->data_allocated)
4741 section_realloc(sec, c_end);
4742 src = sec->data + c;
4743 dst = src;
4744 for(i = 1; i < nb_elems; i++) {
4745 dst += elem_size;
4746 memcpy(dst, src, elem_size);
4751 #define EXPR_VAL 0
4752 #define EXPR_CONST 1
4753 #define EXPR_ANY 2
4755 /* store a value or an expression directly in global data or in local array */
4756 static void init_putv(CType *type, Section *sec, unsigned long c,
4757 int v, int expr_type)
4759 int saved_global_expr, bt, bit_pos, bit_size;
4760 void *ptr;
4761 unsigned long long bit_mask;
4762 CType dtype;
4764 switch(expr_type) {
4765 case EXPR_VAL:
4766 vpushi(v);
4767 break;
4768 case EXPR_CONST:
4769 /* compound literals must be allocated globally in this case */
4770 saved_global_expr = global_expr;
4771 global_expr = 1;
4772 expr_const1();
4773 global_expr = saved_global_expr;
4774 /* NOTE: symbols are accepted */
4775 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4776 error("initializer element is not constant");
4777 break;
4778 case EXPR_ANY:
4779 expr_eq();
4780 break;
4783 dtype = *type;
4784 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4786 if (sec) {
4787 /* XXX: not portable */
4788 /* XXX: generate error if incorrect relocation */
4789 gen_assign_cast(&dtype);
4790 bt = type->t & VT_BTYPE;
4791 /* we'll write at most 12 bytes */
4792 if (c + 12 > sec->data_allocated) {
4793 section_realloc(sec, c + 12);
4795 ptr = sec->data + c;
4796 /* XXX: make code faster ? */
4797 if (!(type->t & VT_BITFIELD)) {
4798 bit_pos = 0;
4799 bit_size = 32;
4800 bit_mask = -1LL;
4801 } else {
4802 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4803 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4804 bit_mask = (1LL << bit_size) - 1;
4806 if ((vtop->r & VT_SYM) &&
4807 (bt == VT_BYTE ||
4808 bt == VT_SHORT ||
4809 bt == VT_DOUBLE ||
4810 bt == VT_LDOUBLE ||
4811 bt == VT_LLONG ||
4812 (bt == VT_INT && bit_size != 32)))
4813 error("initializer element is not computable at load time");
4814 switch(bt) {
4815 case VT_BOOL:
4816 vtop->c.i = (vtop->c.i != 0);
4817 case VT_BYTE:
4818 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4819 break;
4820 case VT_SHORT:
4821 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4822 break;
4823 case VT_DOUBLE:
4824 *(double *)ptr = vtop->c.d;
4825 break;
4826 case VT_LDOUBLE:
4827 *(long double *)ptr = vtop->c.ld;
4828 break;
4829 case VT_LLONG:
4830 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4831 break;
4832 default:
4833 if (vtop->r & VT_SYM) {
4834 greloc(sec, vtop->sym, c, R_DATA_PTR);
4836 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4837 break;
4839 vtop--;
4840 } else {
4841 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4842 vswap();
4843 vstore();
4844 vpop();
4848 /* put zeros for variable based init */
4849 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4851 if (sec) {
4852 /* nothing to do because globals are already set to zero */
4853 } else {
4854 vpush_global_sym(&func_old_type, TOK_memset);
4855 vseti(VT_LOCAL, c);
4856 vpushi(0);
4857 vpushi(size);
4858 gfunc_call(3);
4862 /* 't' contains the type and storage info. 'c' is the offset of the
4863 object in section 'sec'. If 'sec' is NULL, it means stack based
4864 allocation. 'first' is true if array '{' must be read (multi
4865 dimension implicit array init handling). 'size_only' is true if
4866 size only evaluation is wanted (only for arrays). */
4867 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4868 int first, int size_only)
4870 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
4871 int size1, align1, expr_type;
4872 Sym *s, *f;
4873 CType *t1;
4875 if (type->t & VT_VLA) {
4876 int a;
4877 CValue retcval;
4879 vpush_global_sym(&func_old_type, TOK_alloca);
4880 vla_runtime_type_size(type, &a);
4881 gfunc_call(1);
4883 /* return value */
4884 retcval.i = 0;
4885 vsetc(type, REG_IRET, &retcval);
4886 vset(type, VT_LOCAL|VT_LVAL, c);
4887 vswap();
4888 vstore();
4889 vpop();
4890 } else if (type->t & VT_ARRAY) {
4891 s = type->ref;
4892 n = s->c;
4893 array_length = 0;
4894 t1 = pointed_type(type);
4895 size1 = type_size(t1, &align1);
4897 no_oblock = 1;
4898 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4899 tok == '{') {
4900 if (tok != '{')
4901 error("character array initializer must be a literal,"
4902 " optionally enclosed in braces");
4903 skip('{');
4904 no_oblock = 0;
4907 /* only parse strings here if correct type (otherwise: handle
4908 them as ((w)char *) expressions */
4909 if ((tok == TOK_LSTR &&
4910 #ifdef TCC_TARGET_PE
4911 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4912 #else
4913 (t1->t & VT_BTYPE) == VT_INT
4914 #endif
4915 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4916 while (tok == TOK_STR || tok == TOK_LSTR) {
4917 int cstr_len, ch;
4918 CString *cstr;
4920 cstr = tokc.cstr;
4921 /* compute maximum number of chars wanted */
4922 if (tok == TOK_STR)
4923 cstr_len = cstr->size;
4924 else
4925 cstr_len = cstr->size / sizeof(nwchar_t);
4926 cstr_len--;
4927 nb = cstr_len;
4928 if (n >= 0 && nb > (n - array_length))
4929 nb = n - array_length;
4930 if (!size_only) {
4931 if (cstr_len > nb)
4932 warning("initializer-string for array is too long");
4933 /* in order to go faster for common case (char
4934 string in global variable, we handle it
4935 specifically */
4936 if (sec && tok == TOK_STR && size1 == 1) {
4937 memcpy(sec->data + c + array_length, cstr->data, nb);
4938 } else {
4939 for(i=0;i<nb;i++) {
4940 if (tok == TOK_STR)
4941 ch = ((unsigned char *)cstr->data)[i];
4942 else
4943 ch = ((nwchar_t *)cstr->data)[i];
4944 init_putv(t1, sec, c + (array_length + i) * size1,
4945 ch, EXPR_VAL);
4949 array_length += nb;
4950 next();
4952 /* only add trailing zero if enough storage (no
4953 warning in this case since it is standard) */
4954 if (n < 0 || array_length < n) {
4955 if (!size_only) {
4956 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4958 array_length++;
4960 } else {
4961 index = 0;
4962 while (tok != '}') {
4963 decl_designator(type, sec, c, &index, NULL, size_only);
4964 if (n >= 0 && index >= n)
4965 error("index too large");
4966 /* must put zero in holes (note that doing it that way
4967 ensures that it even works with designators) */
4968 if (!size_only && array_length < index) {
4969 init_putz(t1, sec, c + array_length * size1,
4970 (index - array_length) * size1);
4972 index++;
4973 if (index > array_length)
4974 array_length = index;
4975 /* special test for multi dimensional arrays (may not
4976 be strictly correct if designators are used at the
4977 same time) */
4978 if (index >= n && no_oblock)
4979 break;
4980 if (tok == '}')
4981 break;
4982 skip(',');
4985 if (!no_oblock)
4986 skip('}');
4987 /* put zeros at the end */
4988 if (!size_only && n >= 0 && array_length < n) {
4989 init_putz(t1, sec, c + array_length * size1,
4990 (n - array_length) * size1);
4992 /* patch type size if needed */
4993 if (n < 0)
4994 s->c = array_length;
4995 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4996 (sec || !first || tok == '{')) {
4997 int par_count;
4999 /* NOTE: the previous test is a specific case for automatic
5000 struct/union init */
5001 /* XXX: union needs only one init */
5003 /* XXX: this test is incorrect for local initializers
5004 beginning with ( without {. It would be much more difficult
5005 to do it correctly (ideally, the expression parser should
5006 be used in all cases) */
5007 par_count = 0;
5008 if (tok == '(') {
5009 AttributeDef ad1;
5010 CType type1;
5011 next();
5012 while (tok == '(') {
5013 par_count++;
5014 next();
5016 if (!parse_btype(&type1, &ad1))
5017 expect("cast");
5018 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5019 #if 0
5020 if (!is_assignable_types(type, &type1))
5021 error("invalid type for cast");
5022 #endif
5023 skip(')');
5025 no_oblock = 1;
5026 if (first || tok == '{') {
5027 skip('{');
5028 no_oblock = 0;
5030 s = type->ref;
5031 f = s->next;
5032 array_length = 0;
5033 index = 0;
5034 n = s->c;
5035 while (tok != '}') {
5036 decl_designator(type, sec, c, NULL, &f, size_only);
5037 index = f->c;
5038 if (!size_only && array_length < index) {
5039 init_putz(type, sec, c + array_length,
5040 index - array_length);
5042 index = index + type_size(&f->type, &align1);
5043 if (index > array_length)
5044 array_length = index;
5046 /* gr: skip fields from same union - ugly. */
5047 while (f->next) {
5048 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5049 /* test for same offset */
5050 if (f->next->c != f->c)
5051 break;
5052 /* if yes, test for bitfield shift */
5053 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5054 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5055 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5056 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5057 if (bit_pos_1 != bit_pos_2)
5058 break;
5060 f = f->next;
5063 f = f->next;
5064 if (no_oblock && f == NULL)
5065 break;
5066 if (tok == '}')
5067 break;
5068 skip(',');
5070 /* put zeros at the end */
5071 if (!size_only && array_length < n) {
5072 init_putz(type, sec, c + array_length,
5073 n - array_length);
5075 if (!no_oblock)
5076 skip('}');
5077 while (par_count) {
5078 skip(')');
5079 par_count--;
5081 } else if (tok == '{') {
5082 next();
5083 decl_initializer(type, sec, c, first, size_only);
5084 skip('}');
5085 } else if (size_only) {
5086 /* just skip expression */
5087 parlevel = parlevel1 = 0;
5088 while ((parlevel > 0 || parlevel1 > 0 ||
5089 (tok != '}' && tok != ',')) && tok != -1) {
5090 if (tok == '(')
5091 parlevel++;
5092 else if (tok == ')')
5093 parlevel--;
5094 else if (tok == '{')
5095 parlevel1++;
5096 else if (tok == '}')
5097 parlevel1--;
5098 next();
5100 } else {
5101 /* currently, we always use constant expression for globals
5102 (may change for scripting case) */
5103 expr_type = EXPR_CONST;
5104 if (!sec)
5105 expr_type = EXPR_ANY;
5106 init_putv(type, sec, c, 0, expr_type);
5110 /* parse an initializer for type 't' if 'has_init' is non zero, and
5111 allocate space in local or global data space ('r' is either
5112 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5113 variable 'v' with an associated name represented by 'asm_label' of
5114 scope 'scope' is declared before initializers are parsed. If 'v' is
5115 zero, then a reference to the new object is put in the value stack.
5116 If 'has_init' is 2, a special parsing is done to handle string
5117 constants. */
5118 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5119 int has_init, int v, char *asm_label,
5120 int scope)
5122 int size, align, addr, data_offset;
5123 int level;
5124 ParseState saved_parse_state = {0};
5125 TokenString init_str;
5126 Section *sec;
5127 Sym *flexible_array;
5129 flexible_array = NULL;
5130 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5131 Sym *field;
5132 field = type->ref;
5133 while (field && field->next)
5134 field = field->next;
5135 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5136 flexible_array = field;
5139 size = type_size(type, &align);
5140 /* If unknown size, we must evaluate it before
5141 evaluating initializers because
5142 initializers can generate global data too
5143 (e.g. string pointers or ISOC99 compound
5144 literals). It also simplifies local
5145 initializers handling */
5146 tok_str_new(&init_str);
5147 if (size < 0 || flexible_array) {
5148 if (!has_init)
5149 error("unknown type size");
5150 /* get all init string */
5151 if (has_init == 2) {
5152 /* only get strings */
5153 while (tok == TOK_STR || tok == TOK_LSTR) {
5154 tok_str_add_tok(&init_str);
5155 next();
5157 } else {
5158 level = 0;
5159 while (level > 0 || (tok != ',' && tok != ';')) {
5160 if (tok < 0)
5161 error("unexpected end of file in initializer");
5162 tok_str_add_tok(&init_str);
5163 if (tok == '{')
5164 level++;
5165 else if (tok == '}') {
5166 level--;
5167 if (level <= 0) {
5168 next();
5169 break;
5172 next();
5175 tok_str_add(&init_str, -1);
5176 tok_str_add(&init_str, 0);
5178 /* compute size */
5179 save_parse_state(&saved_parse_state);
5181 macro_ptr = init_str.str;
5182 next();
5183 decl_initializer(type, NULL, 0, 1, 1);
5184 /* prepare second initializer parsing */
5185 macro_ptr = init_str.str;
5186 next();
5188 /* if still unknown size, error */
5189 size = type_size(type, &align);
5190 if (size < 0)
5191 error("unknown type size");
5193 if (flexible_array)
5194 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5195 /* take into account specified alignment if bigger */
5196 if (ad->aligned) {
5197 if (ad->aligned > align)
5198 align = ad->aligned;
5199 } else if (ad->packed) {
5200 align = 1;
5202 if ((r & VT_VALMASK) == VT_LOCAL) {
5203 sec = NULL;
5204 #ifdef CONFIG_TCC_BCHECK
5205 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5206 loc--;
5208 #endif
5209 loc = (loc - size) & -align;
5210 addr = loc;
5211 #ifdef CONFIG_TCC_BCHECK
5212 /* handles bounds */
5213 /* XXX: currently, since we do only one pass, we cannot track
5214 '&' operators, so we add only arrays */
5215 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5216 unsigned long *bounds_ptr;
5217 /* add padding between regions */
5218 loc--;
5219 /* then add local bound info */
5220 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5221 bounds_ptr[0] = addr;
5222 bounds_ptr[1] = size;
5224 #endif
5225 if (v) {
5226 /* local variable */
5227 sym_push(v, type, r, addr);
5228 } else {
5229 /* push local reference */
5230 vset(type, r, addr);
5232 } else {
5233 Sym *sym;
5235 sym = NULL;
5236 if (v && scope == VT_CONST) {
5237 /* see if the symbol was already defined */
5238 sym = sym_find(v);
5239 if (sym) {
5240 if (!is_compatible_types(&sym->type, type))
5241 error("incompatible types for redefinition of '%s'",
5242 get_tok_str(v, NULL));
5243 if (sym->type.t & VT_EXTERN) {
5244 /* if the variable is extern, it was not allocated */
5245 sym->type.t &= ~VT_EXTERN;
5246 /* set array size if it was ommited in extern
5247 declaration */
5248 if ((sym->type.t & VT_ARRAY) &&
5249 sym->type.ref->c < 0 &&
5250 type->ref->c >= 0)
5251 sym->type.ref->c = type->ref->c;
5252 } else {
5253 /* we accept several definitions of the same
5254 global variable. this is tricky, because we
5255 must play with the SHN_COMMON type of the symbol */
5256 /* XXX: should check if the variable was already
5257 initialized. It is incorrect to initialized it
5258 twice */
5259 /* no init data, we won't add more to the symbol */
5260 if (!has_init)
5261 goto no_alloc;
5266 /* allocate symbol in corresponding section */
5267 sec = ad->section;
5268 if (!sec) {
5269 if (has_init)
5270 sec = data_section;
5271 else if (tcc_state->nocommon)
5272 sec = bss_section;
5274 if (sec) {
5275 data_offset = sec->data_offset;
5276 data_offset = (data_offset + align - 1) & -align;
5277 addr = data_offset;
5278 /* very important to increment global pointer at this time
5279 because initializers themselves can create new initializers */
5280 data_offset += size;
5281 #ifdef CONFIG_TCC_BCHECK
5282 /* add padding if bound check */
5283 if (tcc_state->do_bounds_check)
5284 data_offset++;
5285 #endif
5286 sec->data_offset = data_offset;
5287 /* allocate section space to put the data */
5288 if (sec->sh_type != SHT_NOBITS &&
5289 data_offset > sec->data_allocated)
5290 section_realloc(sec, data_offset);
5291 /* align section if needed */
5292 if (align > sec->sh_addralign)
5293 sec->sh_addralign = align;
5294 } else {
5295 addr = 0; /* avoid warning */
5298 if (v) {
5299 if (scope != VT_CONST || !sym) {
5300 sym = sym_push(v, type, r | VT_SYM, 0);
5301 sym->asm_label = asm_label;
5303 /* update symbol definition */
5304 if (sec) {
5305 put_extern_sym(sym, sec, addr, size);
5306 } else {
5307 ElfW(Sym) *esym;
5308 /* put a common area */
5309 put_extern_sym(sym, NULL, align, size);
5310 /* XXX: find a nicer way */
5311 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5312 esym->st_shndx = SHN_COMMON;
5314 } else {
5315 CValue cval;
5317 /* push global reference */
5318 sym = get_sym_ref(type, sec, addr, size);
5319 cval.ul = 0;
5320 vsetc(type, VT_CONST | VT_SYM, &cval);
5321 vtop->sym = sym;
5323 /* patch symbol weakness */
5324 if (type->t & VT_WEAK)
5325 weaken_symbol(sym);
5326 #ifdef CONFIG_TCC_BCHECK
5327 /* handles bounds now because the symbol must be defined
5328 before for the relocation */
5329 if (tcc_state->do_bounds_check) {
5330 unsigned long *bounds_ptr;
5332 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5333 /* then add global bound info */
5334 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5335 bounds_ptr[0] = 0; /* relocated */
5336 bounds_ptr[1] = size;
5338 #endif
5340 if (has_init || (type->t & VT_VLA)) {
5341 decl_initializer(type, sec, addr, 1, 0);
5342 /* restore parse state if needed */
5343 if (init_str.str) {
5344 tok_str_free(init_str.str);
5345 restore_parse_state(&saved_parse_state);
5347 /* patch flexible array member size back to -1, */
5348 /* for possible subsequent similar declarations */
5349 if (flexible_array)
5350 flexible_array->type.ref->c = -1;
5352 no_alloc: ;
5355 static void put_func_debug(Sym *sym)
5357 char buf[512];
5359 /* stabs info */
5360 /* XXX: we put here a dummy type */
5361 snprintf(buf, sizeof(buf), "%s:%c1",
5362 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5363 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5364 cur_text_section, sym->c);
5365 /* //gr gdb wants a line at the function */
5366 put_stabn(N_SLINE, 0, file->line_num, 0);
5367 last_ind = 0;
5368 last_line_num = 0;
5371 /* parse an old style function declaration list */
5372 /* XXX: check multiple parameter */
5373 static void func_decl_list(Sym *func_sym)
5375 AttributeDef ad;
5376 int v;
5377 Sym *s;
5378 CType btype, type;
5380 /* parse each declaration */
5381 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5382 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5383 if (!parse_btype(&btype, &ad))
5384 expect("declaration list");
5385 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5386 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5387 tok == ';') {
5388 /* we accept no variable after */
5389 } else {
5390 for(;;) {
5391 type = btype;
5392 type_decl(&type, &ad, &v, TYPE_DIRECT);
5393 /* find parameter in function parameter list */
5394 s = func_sym->next;
5395 while (s != NULL) {
5396 if ((s->v & ~SYM_FIELD) == v)
5397 goto found;
5398 s = s->next;
5400 error("declaration for parameter '%s' but no such parameter",
5401 get_tok_str(v, NULL));
5402 found:
5403 /* check that no storage specifier except 'register' was given */
5404 if (type.t & VT_STORAGE)
5405 error("storage class specified for '%s'", get_tok_str(v, NULL));
5406 convert_parameter_type(&type);
5407 /* we can add the type (NOTE: it could be local to the function) */
5408 s->type = type;
5409 /* accept other parameters */
5410 if (tok == ',')
5411 next();
5412 else
5413 break;
5416 skip(';');
5420 /* parse a function defined by symbol 'sym' and generate its code in
5421 'cur_text_section' */
5422 static void gen_function(Sym *sym)
5424 int saved_nocode_wanted = nocode_wanted;
5425 nocode_wanted = 0;
5426 ind = cur_text_section->data_offset;
5427 /* NOTE: we patch the symbol size later */
5428 put_extern_sym(sym, cur_text_section, ind, 0);
5429 funcname = get_tok_str(sym->v, NULL);
5430 func_ind = ind;
5431 /* put debug symbol */
5432 if (tcc_state->do_debug)
5433 put_func_debug(sym);
5434 /* push a dummy symbol to enable local sym storage */
5435 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5436 gfunc_prolog(&sym->type);
5437 rsym = 0;
5438 block(NULL, NULL, NULL, NULL, 0, 0);
5439 gsym(rsym);
5440 gfunc_epilog();
5441 cur_text_section->data_offset = ind;
5442 label_pop(&global_label_stack, NULL);
5443 sym_pop(&local_stack, NULL); /* reset local stack */
5444 /* end of function */
5445 /* patch symbol size */
5446 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5447 ind - func_ind;
5448 /* patch symbol weakness (this definition overrules any prototype) */
5449 if (sym->type.t & VT_WEAK)
5450 weaken_symbol(sym);
5451 if (tcc_state->do_debug) {
5452 put_stabn(N_FUN, 0, 0, ind - func_ind);
5454 /* It's better to crash than to generate wrong code */
5455 cur_text_section = NULL;
5456 funcname = ""; /* for safety */
5457 func_vt.t = VT_VOID; /* for safety */
5458 ind = 0; /* for safety */
5459 nocode_wanted = saved_nocode_wanted;
5462 ST_FUNC void gen_inline_functions(void)
5464 Sym *sym;
5465 int *str, inline_generated, i;
5466 struct InlineFunc *fn;
5468 /* iterate while inline function are referenced */
5469 for(;;) {
5470 inline_generated = 0;
5471 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5472 fn = tcc_state->inline_fns[i];
5473 sym = fn->sym;
5474 if (sym && sym->c) {
5475 /* the function was used: generate its code and
5476 convert it to a normal function */
5477 str = fn->token_str;
5478 fn->sym = NULL;
5479 if (file)
5480 strcpy(file->filename, fn->filename);
5481 sym->r = VT_SYM | VT_CONST;
5482 sym->type.t &= ~VT_INLINE;
5484 macro_ptr = str;
5485 next();
5486 cur_text_section = text_section;
5487 gen_function(sym);
5488 macro_ptr = NULL; /* fail safe */
5490 inline_generated = 1;
5493 if (!inline_generated)
5494 break;
5496 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5497 fn = tcc_state->inline_fns[i];
5498 str = fn->token_str;
5499 tok_str_free(str);
5501 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5504 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5505 static int decl0(int l, int is_for_loop_init)
5507 int v, has_init, r;
5508 CType type, btype;
5509 Sym *sym;
5510 AttributeDef ad;
5512 while (1) {
5513 if (!parse_btype(&btype, &ad)) {
5514 if (is_for_loop_init)
5515 return 0;
5516 /* skip redundant ';' */
5517 /* XXX: find more elegant solution */
5518 if (tok == ';') {
5519 next();
5520 continue;
5522 if (l == VT_CONST &&
5523 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5524 /* global asm block */
5525 asm_global_instr();
5526 continue;
5528 /* special test for old K&R protos without explicit int
5529 type. Only accepted when defining global data */
5530 if (l == VT_LOCAL || tok < TOK_DEFINE)
5531 break;
5532 btype.t = VT_INT;
5534 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5535 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5536 tok == ';') {
5537 /* we accept no variable after */
5538 next();
5539 continue;
5541 while (1) { /* iterate thru each declaration */
5542 char *asm_label; // associated asm label
5543 type = btype;
5544 type_decl(&type, &ad, &v, TYPE_DIRECT);
5545 #if 0
5547 char buf[500];
5548 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5549 printf("type = '%s'\n", buf);
5551 #endif
5552 if ((type.t & VT_BTYPE) == VT_FUNC) {
5553 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5554 error("function without file scope cannot be static");
5556 /* if old style function prototype, we accept a
5557 declaration list */
5558 sym = type.ref;
5559 if (sym->c == FUNC_OLD)
5560 func_decl_list(sym);
5563 asm_label = NULL;
5564 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5565 CString astr;
5567 asm_label_instr(&astr);
5568 asm_label = tcc_strdup(astr.data);
5569 cstr_free(&astr);
5571 /* parse one last attribute list, after asm label */
5572 parse_attribute(&ad);
5575 if (ad.weak)
5576 type.t |= VT_WEAK;
5577 #ifdef TCC_TARGET_PE
5578 if (ad.func_import)
5579 type.t |= VT_IMPORT;
5580 if (ad.func_export)
5581 type.t |= VT_EXPORT;
5582 #endif
5583 if (tok == '{') {
5584 if (l == VT_LOCAL)
5585 error("cannot use local functions");
5586 if ((type.t & VT_BTYPE) != VT_FUNC)
5587 expect("function definition");
5589 /* reject abstract declarators in function definition */
5590 sym = type.ref;
5591 while ((sym = sym->next) != NULL)
5592 if (!(sym->v & ~SYM_FIELD))
5593 expect("identifier");
5595 /* XXX: cannot do better now: convert extern line to static inline */
5596 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5597 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5599 sym = sym_find(v);
5600 if (sym) {
5601 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5602 goto func_error1;
5604 r = sym->type.ref->r;
5605 /* use func_call from prototype if not defined */
5606 if (FUNC_CALL(r) != FUNC_CDECL
5607 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5608 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5610 /* use export from prototype */
5611 if (FUNC_EXPORT(r))
5612 FUNC_EXPORT(type.ref->r) = 1;
5614 /* use static from prototype */
5615 if (sym->type.t & VT_STATIC)
5616 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5618 if (!is_compatible_types(&sym->type, &type)) {
5619 func_error1:
5620 error("incompatible types for redefinition of '%s'",
5621 get_tok_str(v, NULL));
5623 /* if symbol is already defined, then put complete type */
5624 sym->type = type;
5625 } else {
5626 /* put function symbol */
5627 sym = global_identifier_push(v, type.t, 0);
5628 sym->type.ref = type.ref;
5631 /* static inline functions are just recorded as a kind
5632 of macro. Their code will be emitted at the end of
5633 the compilation unit only if they are used */
5634 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5635 (VT_INLINE | VT_STATIC)) {
5636 TokenString func_str;
5637 int block_level;
5638 struct InlineFunc *fn;
5639 const char *filename;
5641 tok_str_new(&func_str);
5643 block_level = 0;
5644 for(;;) {
5645 int t;
5646 if (tok == TOK_EOF)
5647 error("unexpected end of file");
5648 tok_str_add_tok(&func_str);
5649 t = tok;
5650 next();
5651 if (t == '{') {
5652 block_level++;
5653 } else if (t == '}') {
5654 block_level--;
5655 if (block_level == 0)
5656 break;
5659 tok_str_add(&func_str, -1);
5660 tok_str_add(&func_str, 0);
5661 filename = file ? file->filename : "";
5662 fn = tcc_malloc(sizeof *fn + strlen(filename));
5663 strcpy(fn->filename, filename);
5664 fn->sym = sym;
5665 fn->token_str = func_str.str;
5666 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5668 } else {
5669 /* compute text section */
5670 cur_text_section = ad.section;
5671 if (!cur_text_section)
5672 cur_text_section = text_section;
5673 sym->r = VT_SYM | VT_CONST;
5674 gen_function(sym);
5676 break;
5677 } else {
5678 if (btype.t & VT_TYPEDEF) {
5679 /* save typedefed type */
5680 /* XXX: test storage specifiers ? */
5681 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5682 sym->type.t |= VT_TYPEDEF;
5683 } else {
5684 r = 0;
5685 if ((type.t & VT_BTYPE) == VT_FUNC) {
5686 /* external function definition */
5687 /* specific case for func_call attribute */
5688 type.ref->r = INT_ATTR(&ad);
5689 } else if (!(type.t & VT_ARRAY)) {
5690 /* not lvalue if array */
5691 r |= lvalue_type(type.t);
5693 has_init = (tok == '=');
5694 if (has_init && (type.t & VT_VLA))
5695 error("Variable length array cannot be initialized");
5696 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5697 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5698 !has_init && l == VT_CONST && type.ref->c < 0)) {
5699 /* external variable or function */
5700 /* NOTE: as GCC, uninitialized global static
5701 arrays of null size are considered as
5702 extern */
5703 sym = external_sym(v, &type, r, asm_label);
5705 if (type.t & VT_WEAK)
5706 weaken_symbol(sym);
5708 if (ad.alias_target) {
5709 Section tsec;
5710 Elf32_Sym *esym;
5711 Sym *alias_target;
5713 alias_target = sym_find(ad.alias_target);
5714 if (!alias_target || !alias_target->c)
5715 error("unsupported forward __alias__ attribute");
5716 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
5717 tsec.sh_num = esym->st_shndx;
5718 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
5720 } else {
5721 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5722 if (type.t & VT_STATIC)
5723 r |= VT_CONST;
5724 else
5725 r |= l;
5726 if (has_init)
5727 next();
5728 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
5731 if (tok != ',') {
5732 if (is_for_loop_init)
5733 return 1;
5734 skip(';');
5735 break;
5737 next();
5741 return 0;
5744 ST_FUNC void decl(int l)
5746 decl0(l, 0);