clarify support for functions returning an array (try#2)
[tinycc.git] / tccgen.c
blobfbeb782444f57f56768cbb04a8c03ea83e08d947
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 int is_compatible_parameter_types(CType *type1, CType *type2);
83 static void expr_type(CType *type);
85 ST_INLN int is_float(int t)
87 int bt;
88 bt = t & VT_BTYPE;
89 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
92 ST_FUNC void test_lvalue(void)
94 if (!(vtop->r & VT_LVAL))
95 expect("lvalue");
98 /* ------------------------------------------------------------------------- */
99 /* symbol allocator */
100 static Sym *__sym_malloc(void)
102 Sym *sym_pool, *sym, *last_sym;
103 int i;
105 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
106 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
108 last_sym = sym_free_first;
109 sym = sym_pool;
110 for(i = 0; i < SYM_POOL_NB; i++) {
111 sym->next = last_sym;
112 last_sym = sym;
113 sym++;
115 sym_free_first = last_sym;
116 return last_sym;
119 static inline Sym *sym_malloc(void)
121 Sym *sym;
122 sym = sym_free_first;
123 if (!sym)
124 sym = __sym_malloc();
125 sym_free_first = sym->next;
126 return sym;
129 ST_INLN void sym_free(Sym *sym)
131 sym->next = sym_free_first;
132 tcc_free(sym->asm_label);
133 sym_free_first = sym;
136 /* push, without hashing */
137 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
139 Sym *s;
140 s = sym_malloc();
141 s->asm_label = NULL;
142 s->v = v;
143 s->type.t = t;
144 s->type.ref = NULL;
145 #ifdef _WIN64
146 s->d = NULL;
147 #endif
148 s->c = c;
149 s->next = NULL;
150 /* add in stack */
151 s->prev = *ps;
152 *ps = s;
153 return s;
156 /* find a symbol and return its associated structure. 's' is the top
157 of the symbol stack */
158 ST_FUNC Sym *sym_find2(Sym *s, int v)
160 while (s) {
161 if (s->v == v)
162 return s;
163 s = s->prev;
165 return NULL;
168 /* structure lookup */
169 ST_INLN Sym *struct_find(int v)
171 v -= TOK_IDENT;
172 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
173 return NULL;
174 return table_ident[v]->sym_struct;
177 /* find an identifier */
178 ST_INLN Sym *sym_find(int v)
180 v -= TOK_IDENT;
181 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
182 return NULL;
183 return table_ident[v]->sym_identifier;
186 /* push a given symbol on the symbol stack */
187 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
189 Sym *s, **ps;
190 TokenSym *ts;
192 if (local_stack)
193 ps = &local_stack;
194 else
195 ps = &global_stack;
196 s = sym_push2(ps, v, type->t, c);
197 s->type.ref = type->ref;
198 s->r = r;
199 /* don't record fields or anonymous symbols */
200 /* XXX: simplify */
201 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
202 /* record symbol in token array */
203 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
204 if (v & SYM_STRUCT)
205 ps = &ts->sym_struct;
206 else
207 ps = &ts->sym_identifier;
208 s->prev_tok = *ps;
209 *ps = s;
211 return s;
214 /* push a global identifier */
215 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
217 Sym *s, **ps;
218 s = sym_push2(&global_stack, v, t, c);
219 /* don't record anonymous symbol */
220 if (v < SYM_FIRST_ANOM) {
221 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
222 /* modify the top most local identifier, so that
223 sym_identifier will point to 's' when popped */
224 while (*ps != NULL)
225 ps = &(*ps)->prev_tok;
226 s->prev_tok = NULL;
227 *ps = s;
229 return s;
232 /* pop symbols until top reaches 'b' */
233 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
235 Sym *s, *ss, **ps;
236 TokenSym *ts;
237 int v;
239 s = *ptop;
240 while(s != b) {
241 ss = s->prev;
242 v = s->v;
243 /* remove symbol in token array */
244 /* XXX: simplify */
245 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
246 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
247 if (v & SYM_STRUCT)
248 ps = &ts->sym_struct;
249 else
250 ps = &ts->sym_identifier;
251 *ps = s->prev_tok;
253 sym_free(s);
254 s = ss;
256 *ptop = b;
259 static void weaken_symbol(Sym *sym)
261 sym->type.t |= VT_WEAK;
262 if (sym->c > 0) {
263 int esym_type;
264 ElfW(Sym) *esym;
266 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
267 esym_type = ELFW(ST_TYPE)(esym->st_info);
268 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
272 /* ------------------------------------------------------------------------- */
274 ST_FUNC void swap(int *p, int *q)
276 int t;
277 t = *p;
278 *p = *q;
279 *q = t;
282 static void vsetc(CType *type, int r, CValue *vc)
284 int v;
286 if (vtop >= vstack + (VSTACK_SIZE - 1))
287 error("memory full");
288 /* cannot let cpu flags if other instruction are generated. Also
289 avoid leaving VT_JMP anywhere except on the top of the stack
290 because it would complicate the code generator. */
291 if (vtop >= vstack) {
292 v = vtop->r & VT_VALMASK;
293 if (v == VT_CMP || (v & ~1) == VT_JMP)
294 gv(RC_INT);
296 vtop++;
297 vtop->type = *type;
298 vtop->r = r;
299 vtop->r2 = VT_CONST;
300 vtop->c = *vc;
303 /* push constant of type "type" with useless value */
304 void vpush(CType *type)
306 CValue cval;
307 vsetc(type, VT_CONST, &cval);
310 /* push integer constant */
311 ST_FUNC void vpushi(int v)
313 CValue cval;
314 cval.i = v;
315 vsetc(&int_type, VT_CONST, &cval);
318 /* push long long constant */
319 static void vpushll(long long v)
321 CValue cval;
322 CType ctype;
323 ctype.t = VT_LLONG;
324 ctype.ref = 0;
325 cval.ull = v;
326 vsetc(&ctype, VT_CONST, &cval);
329 /* push arbitrary 64bit constant */
330 void vpush64(int ty, unsigned long long v)
332 CValue cval;
333 CType ctype;
334 ctype.t = ty;
335 cval.ull = v;
336 vsetc(&ctype, VT_CONST, &cval);
339 /* Return a static symbol pointing to a section */
340 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
342 int v;
343 Sym *sym;
345 v = anon_sym++;
346 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
347 sym->type.ref = type->ref;
348 sym->r = VT_CONST | VT_SYM;
349 put_extern_sym(sym, sec, offset, size);
350 return sym;
353 /* push a reference to a section offset by adding a dummy symbol */
354 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
356 CValue cval;
358 cval.ul = 0;
359 vsetc(type, VT_CONST | VT_SYM, &cval);
360 vtop->sym = get_sym_ref(type, sec, offset, size);
363 /* define a new external reference to a symbol 'v' of type 'u' */
364 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
366 Sym *s;
368 s = sym_find(v);
369 if (!s) {
370 /* push forward reference */
371 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
372 s->type.ref = type->ref;
373 s->r = r | VT_CONST | VT_SYM;
375 return s;
378 /* define a new external reference to a symbol 'v' with alternate asm
379 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
380 is no alternate name (most cases) */
381 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
383 Sym *s;
385 s = sym_find(v);
386 if (!s) {
387 /* push forward reference */
388 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
389 s->asm_label = asm_label;
390 s->type.t |= VT_EXTERN;
391 } else if (s->type.ref == func_old_type.ref) {
392 s->type.ref = type->ref;
393 s->r = r | VT_CONST | VT_SYM;
394 s->type.t |= VT_EXTERN;
395 } else if (!is_compatible_types(&s->type, type)) {
396 error("incompatible types for redefinition of '%s'",
397 get_tok_str(v, NULL));
399 return s;
402 /* push a reference to global symbol v */
403 ST_FUNC void vpush_global_sym(CType *type, int v)
405 Sym *sym;
406 CValue cval;
408 sym = external_global_sym(v, type, 0);
409 cval.ul = 0;
410 vsetc(type, VT_CONST | VT_SYM, &cval);
411 vtop->sym = sym;
414 ST_FUNC void vset(CType *type, int r, int v)
416 CValue cval;
418 cval.i = v;
419 vsetc(type, r, &cval);
422 static void vseti(int r, int v)
424 CType type;
425 type.t = VT_INT;
426 type.ref = 0;
427 vset(&type, r, v);
430 ST_FUNC void vswap(void)
432 SValue tmp;
434 tmp = vtop[0];
435 vtop[0] = vtop[-1];
436 vtop[-1] = tmp;
439 ST_FUNC void vpushv(SValue *v)
441 if (vtop >= vstack + (VSTACK_SIZE - 1))
442 error("memory full");
443 vtop++;
444 *vtop = *v;
447 static void vdup(void)
449 vpushv(vtop);
452 /* save r to the memory stack, and mark it as being free */
453 ST_FUNC void save_reg(int r)
455 int l, saved, size, align;
456 SValue *p, sv;
457 CType *type;
459 /* modify all stack values */
460 saved = 0;
461 l = 0;
462 for(p=vstack;p<=vtop;p++) {
463 if ((p->r & VT_VALMASK) == r ||
464 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
465 /* must save value on stack if not already done */
466 if (!saved) {
467 /* NOTE: must reload 'r' because r might be equal to r2 */
468 r = p->r & VT_VALMASK;
469 /* store register in the stack */
470 type = &p->type;
471 if ((p->r & VT_LVAL) ||
472 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
473 #ifdef TCC_TARGET_X86_64
474 type = &char_pointer_type;
475 #else
476 type = &int_type;
477 #endif
478 size = type_size(type, &align);
479 loc = (loc - size) & -align;
480 sv.type.t = type->t;
481 sv.r = VT_LOCAL | VT_LVAL;
482 sv.c.ul = loc;
483 store(r, &sv);
484 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
485 /* x86 specific: need to pop fp register ST0 if saved */
486 if (r == TREG_ST0) {
487 o(0xd8dd); /* fstp %st(0) */
489 #endif
490 #ifndef TCC_TARGET_X86_64
491 /* special long long case */
492 if ((type->t & VT_BTYPE) == VT_LLONG) {
493 sv.c.ul += 4;
494 store(p->r2, &sv);
496 #endif
497 l = loc;
498 saved = 1;
500 /* mark that stack entry as being saved on the stack */
501 if (p->r & VT_LVAL) {
502 /* also clear the bounded flag because the
503 relocation address of the function was stored in
504 p->c.ul */
505 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
506 } else {
507 p->r = lvalue_type(p->type.t) | VT_LOCAL;
509 p->r2 = VT_CONST;
510 p->c.ul = l;
515 #ifdef TCC_TARGET_ARM
516 /* find a register of class 'rc2' with at most one reference on stack.
517 * If none, call get_reg(rc) */
518 ST_FUNC int get_reg_ex(int rc, int rc2)
520 int r;
521 SValue *p;
523 for(r=0;r<NB_REGS;r++) {
524 if (reg_classes[r] & rc2) {
525 int n;
526 n=0;
527 for(p = vstack; p <= vtop; p++) {
528 if ((p->r & VT_VALMASK) == r ||
529 (p->r2 & VT_VALMASK) == r)
530 n++;
532 if (n <= 1)
533 return r;
536 return get_reg(rc);
538 #endif
540 /* find a free register of class 'rc'. If none, save one register */
541 ST_FUNC int get_reg(int rc)
543 int r;
544 SValue *p;
546 /* find a free register */
547 for(r=0;r<NB_REGS;r++) {
548 if (reg_classes[r] & rc) {
549 for(p=vstack;p<=vtop;p++) {
550 if ((p->r & VT_VALMASK) == r ||
551 (p->r2 & VT_VALMASK) == r)
552 goto notfound;
554 return r;
556 notfound: ;
559 /* no register left : free the first one on the stack (VERY
560 IMPORTANT to start from the bottom to ensure that we don't
561 spill registers used in gen_opi()) */
562 for(p=vstack;p<=vtop;p++) {
563 r = p->r & VT_VALMASK;
564 if (r < VT_CONST && (reg_classes[r] & rc))
565 goto save_found;
566 /* also look at second register (if long long) */
567 r = p->r2 & VT_VALMASK;
568 if (r < VT_CONST && (reg_classes[r] & rc)) {
569 save_found:
570 save_reg(r);
571 return r;
574 /* Should never comes here */
575 return -1;
578 /* save registers up to (vtop - n) stack entry */
579 ST_FUNC void save_regs(int n)
581 int r;
582 SValue *p, *p1;
583 p1 = vtop - n;
584 for(p = vstack;p <= p1; p++) {
585 r = p->r & VT_VALMASK;
586 if (r < VT_CONST) {
587 save_reg(r);
592 /* move register 's' to 'r', and flush previous value of r to memory
593 if needed */
594 static void move_reg(int r, int s)
596 SValue sv;
598 if (r != s) {
599 save_reg(r);
600 sv.type.t = VT_INT;
601 sv.r = s;
602 sv.c.ul = 0;
603 load(r, &sv);
607 /* get address of vtop (vtop MUST BE an lvalue) */
608 static void gaddrof(void)
610 vtop->r &= ~VT_LVAL;
611 /* tricky: if saved lvalue, then we can go back to lvalue */
612 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
613 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
616 #ifdef CONFIG_TCC_BCHECK
617 /* generate lvalue bound code */
618 static void gbound(void)
620 int lval_type;
621 CType type1;
623 vtop->r &= ~VT_MUSTBOUND;
624 /* if lvalue, then use checking code before dereferencing */
625 if (vtop->r & VT_LVAL) {
626 /* if not VT_BOUNDED value, then make one */
627 if (!(vtop->r & VT_BOUNDED)) {
628 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
629 /* must save type because we must set it to int to get pointer */
630 type1 = vtop->type;
631 vtop->type.t = VT_INT;
632 gaddrof();
633 vpushi(0);
634 gen_bounded_ptr_add();
635 vtop->r |= lval_type;
636 vtop->type = type1;
638 /* then check for dereferencing */
639 gen_bounded_ptr_deref();
642 #endif
644 /* store vtop a register belonging to class 'rc'. lvalues are
645 converted to values. Cannot be used if cannot be converted to
646 register value (such as structures). */
647 ST_FUNC int gv(int rc)
649 int r, rc2, bit_pos, bit_size, size, align, i;
651 /* NOTE: get_reg can modify vstack[] */
652 if (vtop->type.t & VT_BITFIELD) {
653 CType type;
654 int bits = 32;
655 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
656 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
657 /* remove bit field info to avoid loops */
658 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
659 /* cast to int to propagate signedness in following ops */
660 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
661 type.t = VT_LLONG;
662 bits = 64;
663 } else
664 type.t = VT_INT;
665 if((vtop->type.t & VT_UNSIGNED) ||
666 (vtop->type.t & VT_BTYPE) == VT_BOOL)
667 type.t |= VT_UNSIGNED;
668 gen_cast(&type);
669 /* generate shifts */
670 vpushi(bits - (bit_pos + bit_size));
671 gen_op(TOK_SHL);
672 vpushi(bits - bit_size);
673 /* NOTE: transformed to SHR if unsigned */
674 gen_op(TOK_SAR);
675 r = gv(rc);
676 } else {
677 if (is_float(vtop->type.t) &&
678 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
679 Sym *sym;
680 int *ptr;
681 unsigned long offset;
682 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
683 CValue check;
684 #endif
686 /* XXX: unify with initializers handling ? */
687 /* CPUs usually cannot use float constants, so we store them
688 generically in data segment */
689 size = type_size(&vtop->type, &align);
690 offset = (data_section->data_offset + align - 1) & -align;
691 data_section->data_offset = offset;
692 /* XXX: not portable yet */
693 #if defined(__i386__) || defined(__x86_64__)
694 /* Zero pad x87 tenbyte long doubles */
695 if (size == LDOUBLE_SIZE)
696 vtop->c.tab[2] &= 0xffff;
697 #endif
698 ptr = section_ptr_add(data_section, size);
699 size = size >> 2;
700 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
701 check.d = 1;
702 if(check.tab[0])
703 for(i=0;i<size;i++)
704 ptr[i] = vtop->c.tab[size-1-i];
705 else
706 #endif
707 for(i=0;i<size;i++)
708 ptr[i] = vtop->c.tab[i];
709 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
710 vtop->r |= VT_LVAL | VT_SYM;
711 vtop->sym = sym;
712 vtop->c.ul = 0;
714 #ifdef CONFIG_TCC_BCHECK
715 if (vtop->r & VT_MUSTBOUND)
716 gbound();
717 #endif
719 r = vtop->r & VT_VALMASK;
720 rc2 = RC_INT;
721 if (rc == RC_IRET)
722 rc2 = RC_LRET;
723 /* need to reload if:
724 - constant
725 - lvalue (need to dereference pointer)
726 - already a register, but not in the right class */
727 if (r >= VT_CONST
728 || (vtop->r & VT_LVAL)
729 || !(reg_classes[r] & rc)
730 #ifndef TCC_TARGET_X86_64
731 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
732 #endif
735 r = get_reg(rc);
736 #ifndef TCC_TARGET_X86_64
737 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
738 int r2;
739 unsigned long long ll;
740 /* two register type load : expand to two words
741 temporarily */
742 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
743 /* load constant */
744 ll = vtop->c.ull;
745 vtop->c.ui = ll; /* first word */
746 load(r, vtop);
747 vtop->r = r; /* save register value */
748 vpushi(ll >> 32); /* second word */
749 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
750 (vtop->r & VT_LVAL)) {
751 /* We do not want to modifier the long long
752 pointer here, so the safest (and less
753 efficient) is to save all the other registers
754 in the stack. XXX: totally inefficient. */
755 save_regs(1);
756 /* load from memory */
757 load(r, vtop);
758 vdup();
759 vtop[-1].r = r; /* save register value */
760 /* increment pointer to get second word */
761 vtop->type.t = VT_INT;
762 gaddrof();
763 vpushi(4);
764 gen_op('+');
765 vtop->r |= VT_LVAL;
766 } else {
767 /* move registers */
768 load(r, vtop);
769 vdup();
770 vtop[-1].r = r; /* save register value */
771 vtop->r = vtop[-1].r2;
773 /* allocate second register */
774 r2 = get_reg(rc2);
775 load(r2, vtop);
776 vpop();
777 /* write second register */
778 vtop->r2 = r2;
779 } else
780 #endif
781 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
782 int t1, t;
783 /* lvalue of scalar type : need to use lvalue type
784 because of possible cast */
785 t = vtop->type.t;
786 t1 = t;
787 /* compute memory access type */
788 if (vtop->r & VT_LVAL_BYTE)
789 t = VT_BYTE;
790 else if (vtop->r & VT_LVAL_SHORT)
791 t = VT_SHORT;
792 if (vtop->r & VT_LVAL_UNSIGNED)
793 t |= VT_UNSIGNED;
794 vtop->type.t = t;
795 load(r, vtop);
796 /* restore wanted type */
797 vtop->type.t = t1;
798 } else {
799 /* one register type load */
800 load(r, vtop);
803 vtop->r = r;
804 #ifdef TCC_TARGET_C67
805 /* uses register pairs for doubles */
806 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
807 vtop->r2 = r+1;
808 #endif
810 return r;
813 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
814 ST_FUNC void gv2(int rc1, int rc2)
816 int v;
818 /* generate more generic register first. But VT_JMP or VT_CMP
819 values must be generated first in all cases to avoid possible
820 reload errors */
821 v = vtop[0].r & VT_VALMASK;
822 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
823 vswap();
824 gv(rc1);
825 vswap();
826 gv(rc2);
827 /* test if reload is needed for first register */
828 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
829 vswap();
830 gv(rc1);
831 vswap();
833 } else {
834 gv(rc2);
835 vswap();
836 gv(rc1);
837 vswap();
838 /* test if reload is needed for first register */
839 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
840 gv(rc2);
845 /* wrapper around RC_FRET to return a register by type */
846 static int rc_fret(int t)
848 #ifdef TCC_TARGET_X86_64
849 if (t == VT_LDOUBLE) {
850 return RC_ST0;
852 #endif
853 return RC_FRET;
856 /* wrapper around REG_FRET to return a register by type */
857 static int reg_fret(int t)
859 #ifdef TCC_TARGET_X86_64
860 if (t == VT_LDOUBLE) {
861 return TREG_ST0;
863 #endif
864 return REG_FRET;
867 /* expand long long on stack in two int registers */
868 static void lexpand(void)
870 int u;
872 u = vtop->type.t & VT_UNSIGNED;
873 gv(RC_INT);
874 vdup();
875 vtop[0].r = vtop[-1].r2;
876 vtop[0].r2 = VT_CONST;
877 vtop[-1].r2 = VT_CONST;
878 vtop[0].type.t = VT_INT | u;
879 vtop[-1].type.t = VT_INT | u;
882 #ifdef TCC_TARGET_ARM
883 /* expand long long on stack */
884 ST_FUNC void lexpand_nr(void)
886 int u,v;
888 u = vtop->type.t & VT_UNSIGNED;
889 vdup();
890 vtop->r2 = VT_CONST;
891 vtop->type.t = VT_INT | u;
892 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
893 if (v == VT_CONST) {
894 vtop[-1].c.ui = vtop->c.ull;
895 vtop->c.ui = vtop->c.ull >> 32;
896 vtop->r = VT_CONST;
897 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
898 vtop->c.ui += 4;
899 vtop->r = vtop[-1].r;
900 } else if (v > VT_CONST) {
901 vtop--;
902 lexpand();
903 } else
904 vtop->r = vtop[-1].r2;
905 vtop[-1].r2 = VT_CONST;
906 vtop[-1].type.t = VT_INT | u;
908 #endif
910 /* build a long long from two ints */
911 static void lbuild(int t)
913 gv2(RC_INT, RC_INT);
914 vtop[-1].r2 = vtop[0].r;
915 vtop[-1].type.t = t;
916 vpop();
919 /* rotate n first stack elements to the bottom
920 I1 ... In -> I2 ... In I1 [top is right]
922 static void vrotb(int n)
924 int i;
925 SValue tmp;
927 tmp = vtop[-n + 1];
928 for(i=-n+1;i!=0;i++)
929 vtop[i] = vtop[i+1];
930 vtop[0] = tmp;
933 /* rotate n first stack elements to the top
934 I1 ... In -> In I1 ... I(n-1) [top is right]
936 ST_FUNC void vrott(int n)
938 int i;
939 SValue tmp;
941 tmp = vtop[0];
942 for(i = 0;i < n - 1; i++)
943 vtop[-i] = vtop[-i - 1];
944 vtop[-n + 1] = tmp;
947 #ifdef TCC_TARGET_ARM
948 /* like vrott but in other direction
949 In ... I1 -> I(n-1) ... I1 In [top is right]
951 ST_FUNC void vnrott(int n)
953 int i;
954 SValue tmp;
956 tmp = vtop[-n + 1];
957 for(i = n - 1; i > 0; i--)
958 vtop[-i] = vtop[-i + 1];
959 vtop[0] = tmp;
961 #endif
963 /* pop stack value */
964 ST_FUNC void vpop(void)
966 int v;
967 v = vtop->r & VT_VALMASK;
968 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
969 /* for x86, we need to pop the FP stack */
970 if (v == TREG_ST0 && !nocode_wanted) {
971 o(0xd8dd); /* fstp %st(0) */
972 } else
973 #endif
974 if (v == VT_JMP || v == VT_JMPI) {
975 /* need to put correct jump if && or || without test */
976 gsym(vtop->c.ul);
978 vtop--;
981 /* convert stack entry to register and duplicate its value in another
982 register */
983 static void gv_dup(void)
985 int rc, t, r, r1;
986 SValue sv;
988 t = vtop->type.t;
989 if ((t & VT_BTYPE) == VT_LLONG) {
990 lexpand();
991 gv_dup();
992 vswap();
993 vrotb(3);
994 gv_dup();
995 vrotb(4);
996 /* stack: H L L1 H1 */
997 lbuild(t);
998 vrotb(3);
999 vrotb(3);
1000 vswap();
1001 lbuild(t);
1002 vswap();
1003 } else {
1004 /* duplicate value */
1005 rc = RC_INT;
1006 sv.type.t = VT_INT;
1007 if (is_float(t)) {
1008 rc = RC_FLOAT;
1009 #ifdef TCC_TARGET_X86_64
1010 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1011 rc = RC_ST0;
1013 #endif
1014 sv.type.t = t;
1016 r = gv(rc);
1017 r1 = get_reg(rc);
1018 sv.r = r;
1019 sv.c.ul = 0;
1020 load(r1, &sv); /* move r to r1 */
1021 vdup();
1022 /* duplicates value */
1023 if (r != r1)
1024 vtop->r = r1;
1028 #ifndef TCC_TARGET_X86_64
1029 /* generate CPU independent (unsigned) long long operations */
1030 static void gen_opl(int op)
1032 int t, a, b, op1, c, i;
1033 int func;
1034 unsigned short reg_iret = REG_IRET;
1035 unsigned short reg_lret = REG_LRET;
1036 SValue tmp;
1038 switch(op) {
1039 case '/':
1040 case TOK_PDIV:
1041 func = TOK___divdi3;
1042 goto gen_func;
1043 case TOK_UDIV:
1044 func = TOK___udivdi3;
1045 goto gen_func;
1046 case '%':
1047 func = TOK___moddi3;
1048 goto gen_mod_func;
1049 case TOK_UMOD:
1050 func = TOK___umoddi3;
1051 gen_mod_func:
1052 #ifdef TCC_ARM_EABI
1053 reg_iret = TREG_R2;
1054 reg_lret = TREG_R3;
1055 #endif
1056 gen_func:
1057 /* call generic long long function */
1058 vpush_global_sym(&func_old_type, func);
1059 vrott(3);
1060 gfunc_call(2);
1061 vpushi(0);
1062 vtop->r = reg_iret;
1063 vtop->r2 = reg_lret;
1064 break;
1065 case '^':
1066 case '&':
1067 case '|':
1068 case '*':
1069 case '+':
1070 case '-':
1071 t = vtop->type.t;
1072 vswap();
1073 lexpand();
1074 vrotb(3);
1075 lexpand();
1076 /* stack: L1 H1 L2 H2 */
1077 tmp = vtop[0];
1078 vtop[0] = vtop[-3];
1079 vtop[-3] = tmp;
1080 tmp = vtop[-2];
1081 vtop[-2] = vtop[-3];
1082 vtop[-3] = tmp;
1083 vswap();
1084 /* stack: H1 H2 L1 L2 */
1085 if (op == '*') {
1086 vpushv(vtop - 1);
1087 vpushv(vtop - 1);
1088 gen_op(TOK_UMULL);
1089 lexpand();
1090 /* stack: H1 H2 L1 L2 ML MH */
1091 for(i=0;i<4;i++)
1092 vrotb(6);
1093 /* stack: ML MH H1 H2 L1 L2 */
1094 tmp = vtop[0];
1095 vtop[0] = vtop[-2];
1096 vtop[-2] = tmp;
1097 /* stack: ML MH H1 L2 H2 L1 */
1098 gen_op('*');
1099 vrotb(3);
1100 vrotb(3);
1101 gen_op('*');
1102 /* stack: ML MH M1 M2 */
1103 gen_op('+');
1104 gen_op('+');
1105 } else if (op == '+' || op == '-') {
1106 /* XXX: add non carry method too (for MIPS or alpha) */
1107 if (op == '+')
1108 op1 = TOK_ADDC1;
1109 else
1110 op1 = TOK_SUBC1;
1111 gen_op(op1);
1112 /* stack: H1 H2 (L1 op L2) */
1113 vrotb(3);
1114 vrotb(3);
1115 gen_op(op1 + 1); /* TOK_xxxC2 */
1116 } else {
1117 gen_op(op);
1118 /* stack: H1 H2 (L1 op L2) */
1119 vrotb(3);
1120 vrotb(3);
1121 /* stack: (L1 op L2) H1 H2 */
1122 gen_op(op);
1123 /* stack: (L1 op L2) (H1 op H2) */
1125 /* stack: L H */
1126 lbuild(t);
1127 break;
1128 case TOK_SAR:
1129 case TOK_SHR:
1130 case TOK_SHL:
1131 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1132 t = vtop[-1].type.t;
1133 vswap();
1134 lexpand();
1135 vrotb(3);
1136 /* stack: L H shift */
1137 c = (int)vtop->c.i;
1138 /* constant: simpler */
1139 /* NOTE: all comments are for SHL. the other cases are
1140 done by swaping words */
1141 vpop();
1142 if (op != TOK_SHL)
1143 vswap();
1144 if (c >= 32) {
1145 /* stack: L H */
1146 vpop();
1147 if (c > 32) {
1148 vpushi(c - 32);
1149 gen_op(op);
1151 if (op != TOK_SAR) {
1152 vpushi(0);
1153 } else {
1154 gv_dup();
1155 vpushi(31);
1156 gen_op(TOK_SAR);
1158 vswap();
1159 } else {
1160 vswap();
1161 gv_dup();
1162 /* stack: H L L */
1163 vpushi(c);
1164 gen_op(op);
1165 vswap();
1166 vpushi(32 - c);
1167 if (op == TOK_SHL)
1168 gen_op(TOK_SHR);
1169 else
1170 gen_op(TOK_SHL);
1171 vrotb(3);
1172 /* stack: L L H */
1173 vpushi(c);
1174 if (op == TOK_SHL)
1175 gen_op(TOK_SHL);
1176 else
1177 gen_op(TOK_SHR);
1178 gen_op('|');
1180 if (op != TOK_SHL)
1181 vswap();
1182 lbuild(t);
1183 } else {
1184 /* XXX: should provide a faster fallback on x86 ? */
1185 switch(op) {
1186 case TOK_SAR:
1187 func = TOK___ashrdi3;
1188 goto gen_func;
1189 case TOK_SHR:
1190 func = TOK___lshrdi3;
1191 goto gen_func;
1192 case TOK_SHL:
1193 func = TOK___ashldi3;
1194 goto gen_func;
1197 break;
1198 default:
1199 /* compare operations */
1200 t = vtop->type.t;
1201 vswap();
1202 lexpand();
1203 vrotb(3);
1204 lexpand();
1205 /* stack: L1 H1 L2 H2 */
1206 tmp = vtop[-1];
1207 vtop[-1] = vtop[-2];
1208 vtop[-2] = tmp;
1209 /* stack: L1 L2 H1 H2 */
1210 /* compare high */
1211 op1 = op;
1212 /* when values are equal, we need to compare low words. since
1213 the jump is inverted, we invert the test too. */
1214 if (op1 == TOK_LT)
1215 op1 = TOK_LE;
1216 else if (op1 == TOK_GT)
1217 op1 = TOK_GE;
1218 else if (op1 == TOK_ULT)
1219 op1 = TOK_ULE;
1220 else if (op1 == TOK_UGT)
1221 op1 = TOK_UGE;
1222 a = 0;
1223 b = 0;
1224 gen_op(op1);
1225 if (op1 != TOK_NE) {
1226 a = gtst(1, 0);
1228 if (op != TOK_EQ) {
1229 /* generate non equal test */
1230 /* XXX: NOT PORTABLE yet */
1231 if (a == 0) {
1232 b = gtst(0, 0);
1233 } else {
1234 #if defined(TCC_TARGET_I386)
1235 b = psym(0x850f, 0);
1236 #elif defined(TCC_TARGET_ARM)
1237 b = ind;
1238 o(0x1A000000 | encbranch(ind, 0, 1));
1239 #elif defined(TCC_TARGET_C67)
1240 error("not implemented");
1241 #else
1242 #error not supported
1243 #endif
1246 /* compare low. Always unsigned */
1247 op1 = op;
1248 if (op1 == TOK_LT)
1249 op1 = TOK_ULT;
1250 else if (op1 == TOK_LE)
1251 op1 = TOK_ULE;
1252 else if (op1 == TOK_GT)
1253 op1 = TOK_UGT;
1254 else if (op1 == TOK_GE)
1255 op1 = TOK_UGE;
1256 gen_op(op1);
1257 a = gtst(1, a);
1258 gsym(b);
1259 vseti(VT_JMPI, a);
1260 break;
1263 #endif
1265 /* handle integer constant optimizations and various machine
1266 independent opt */
1267 static void gen_opic(int op)
1269 int c1, c2, t1, t2, n;
1270 SValue *v1, *v2;
1271 long long l1, l2;
1272 typedef unsigned long long U;
1274 v1 = vtop - 1;
1275 v2 = vtop;
1276 t1 = v1->type.t & VT_BTYPE;
1277 t2 = v2->type.t & VT_BTYPE;
1279 if (t1 == VT_LLONG)
1280 l1 = v1->c.ll;
1281 else if (v1->type.t & VT_UNSIGNED)
1282 l1 = v1->c.ui;
1283 else
1284 l1 = v1->c.i;
1286 if (t2 == VT_LLONG)
1287 l2 = v2->c.ll;
1288 else if (v2->type.t & VT_UNSIGNED)
1289 l2 = v2->c.ui;
1290 else
1291 l2 = v2->c.i;
1293 /* currently, we cannot do computations with forward symbols */
1294 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1295 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1296 if (c1 && c2) {
1297 switch(op) {
1298 case '+': l1 += l2; break;
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;
1305 case TOK_PDIV:
1306 case '/':
1307 case '%':
1308 case TOK_UDIV:
1309 case TOK_UMOD:
1310 /* if division by zero, generate explicit division */
1311 if (l2 == 0) {
1312 if (const_wanted)
1313 error("division by zero in constant");
1314 goto general_case;
1316 switch(op) {
1317 default: l1 /= l2; break;
1318 case '%': l1 %= l2; break;
1319 case TOK_UDIV: l1 = (U)l1 / l2; break;
1320 case TOK_UMOD: l1 = (U)l1 % l2; break;
1322 break;
1323 case TOK_SHL: l1 <<= l2; break;
1324 case TOK_SHR: l1 = (U)l1 >> l2; break;
1325 case TOK_SAR: l1 >>= l2; break;
1326 /* tests */
1327 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1328 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1329 case TOK_EQ: l1 = l1 == l2; break;
1330 case TOK_NE: l1 = l1 != l2; break;
1331 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1332 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1333 case TOK_LT: l1 = l1 < l2; break;
1334 case TOK_GE: l1 = l1 >= l2; break;
1335 case TOK_LE: l1 = l1 <= l2; break;
1336 case TOK_GT: l1 = l1 > l2; break;
1337 /* logical */
1338 case TOK_LAND: l1 = l1 && l2; break;
1339 case TOK_LOR: l1 = l1 || l2; break;
1340 default:
1341 goto general_case;
1343 v1->c.ll = l1;
1344 vtop--;
1345 } else {
1346 /* if commutative ops, put c2 as constant */
1347 if (c1 && (op == '+' || op == '&' || op == '^' ||
1348 op == '|' || op == '*')) {
1349 vswap();
1350 c2 = c1; //c = c1, c1 = c2, c2 = c;
1351 l2 = l1; //l = l1, l1 = l2, l2 = l;
1353 /* Filter out NOP operations like x*1, x-0, x&-1... */
1354 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1355 op == TOK_PDIV) &&
1356 l2 == 1) ||
1357 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1358 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1359 l2 == 0) ||
1360 (op == '&' &&
1361 l2 == -1))) {
1362 /* nothing to do */
1363 vtop--;
1364 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1365 /* try to use shifts instead of muls or divs */
1366 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1367 n = -1;
1368 while (l2) {
1369 l2 >>= 1;
1370 n++;
1372 vtop->c.ll = n;
1373 if (op == '*')
1374 op = TOK_SHL;
1375 else if (op == TOK_PDIV)
1376 op = TOK_SAR;
1377 else
1378 op = TOK_SHR;
1380 goto general_case;
1381 } else if (c2 && (op == '+' || op == '-') &&
1382 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1383 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1384 /* symbol + constant case */
1385 if (op == '-')
1386 l2 = -l2;
1387 vtop--;
1388 vtop->c.ll += l2;
1389 } else {
1390 general_case:
1391 if (!nocode_wanted) {
1392 /* call low level op generator */
1393 if (t1 == VT_LLONG || t2 == VT_LLONG)
1394 gen_opl(op);
1395 else
1396 gen_opi(op);
1397 } else {
1398 vtop--;
1404 /* generate a floating point operation with constant propagation */
1405 static void gen_opif(int op)
1407 int c1, c2;
1408 SValue *v1, *v2;
1409 long double f1, f2;
1411 v1 = vtop - 1;
1412 v2 = vtop;
1413 /* currently, we cannot do computations with forward symbols */
1414 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1415 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1416 if (c1 && c2) {
1417 if (v1->type.t == VT_FLOAT) {
1418 f1 = v1->c.f;
1419 f2 = v2->c.f;
1420 } else if (v1->type.t == VT_DOUBLE) {
1421 f1 = v1->c.d;
1422 f2 = v2->c.d;
1423 } else {
1424 f1 = v1->c.ld;
1425 f2 = v2->c.ld;
1428 /* NOTE: we only do constant propagation if finite number (not
1429 NaN or infinity) (ANSI spec) */
1430 if (!ieee_finite(f1) || !ieee_finite(f2))
1431 goto general_case;
1433 switch(op) {
1434 case '+': f1 += f2; break;
1435 case '-': f1 -= f2; break;
1436 case '*': f1 *= f2; break;
1437 case '/':
1438 if (f2 == 0.0) {
1439 if (const_wanted)
1440 error("division by zero in constant");
1441 goto general_case;
1443 f1 /= f2;
1444 break;
1445 /* XXX: also handles tests ? */
1446 default:
1447 goto general_case;
1449 /* XXX: overflow test ? */
1450 if (v1->type.t == VT_FLOAT) {
1451 v1->c.f = f1;
1452 } else if (v1->type.t == VT_DOUBLE) {
1453 v1->c.d = f1;
1454 } else {
1455 v1->c.ld = f1;
1457 vtop--;
1458 } else {
1459 general_case:
1460 if (!nocode_wanted) {
1461 gen_opf(op);
1462 } else {
1463 vtop--;
1468 static int pointed_size(CType *type)
1470 int align;
1471 return type_size(pointed_type(type), &align);
1474 static inline int is_null_pointer(SValue *p)
1476 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1477 return 0;
1478 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1479 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1482 static inline int is_integer_btype(int bt)
1484 return (bt == VT_BYTE || bt == VT_SHORT ||
1485 bt == VT_INT || bt == VT_LLONG);
1488 /* check types for comparison or substraction of pointers */
1489 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1491 CType *type1, *type2, tmp_type1, tmp_type2;
1492 int bt1, bt2;
1494 /* null pointers are accepted for all comparisons as gcc */
1495 if (is_null_pointer(p1) || is_null_pointer(p2))
1496 return;
1497 type1 = &p1->type;
1498 type2 = &p2->type;
1499 bt1 = type1->t & VT_BTYPE;
1500 bt2 = type2->t & VT_BTYPE;
1501 /* accept comparison between pointer and integer with a warning */
1502 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1503 if (op != TOK_LOR && op != TOK_LAND )
1504 warning("comparison between pointer and integer");
1505 return;
1508 /* both must be pointers or implicit function pointers */
1509 if (bt1 == VT_PTR) {
1510 type1 = pointed_type(type1);
1511 } else if (bt1 != VT_FUNC)
1512 goto invalid_operands;
1514 if (bt2 == VT_PTR) {
1515 type2 = pointed_type(type2);
1516 } else if (bt2 != VT_FUNC) {
1517 invalid_operands:
1518 error("invalid operands to binary %s", get_tok_str(op, NULL));
1520 if ((type1->t & VT_BTYPE) == VT_VOID ||
1521 (type2->t & VT_BTYPE) == VT_VOID)
1522 return;
1523 tmp_type1 = *type1;
1524 tmp_type2 = *type2;
1525 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1526 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1527 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1528 /* gcc-like error if '-' is used */
1529 if (op == '-')
1530 goto invalid_operands;
1531 else
1532 warning("comparison of distinct pointer types lacks a cast");
1536 /* generic gen_op: handles types problems */
1537 ST_FUNC void gen_op(int op)
1539 int u, t1, t2, bt1, bt2, t;
1540 CType type1;
1542 t1 = vtop[-1].type.t;
1543 t2 = vtop[0].type.t;
1544 bt1 = t1 & VT_BTYPE;
1545 bt2 = t2 & VT_BTYPE;
1547 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1548 /* at least one operand is a pointer */
1549 /* relationnal op: must be both pointers */
1550 if (op >= TOK_ULT && op <= TOK_LOR) {
1551 check_comparison_pointer_types(vtop - 1, vtop, op);
1552 /* pointers are handled are unsigned */
1553 #ifdef TCC_TARGET_X86_64
1554 t = VT_LLONG | VT_UNSIGNED;
1555 #else
1556 t = VT_INT | VT_UNSIGNED;
1557 #endif
1558 goto std_op;
1560 /* if both pointers, then it must be the '-' op */
1561 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1562 if (op != '-')
1563 error("cannot use pointers here");
1564 check_comparison_pointer_types(vtop - 1, vtop, op);
1565 /* XXX: check that types are compatible */
1566 u = pointed_size(&vtop[-1].type);
1567 gen_opic(op);
1568 /* set to integer type */
1569 #ifdef TCC_TARGET_X86_64
1570 vtop->type.t = VT_LLONG;
1571 #else
1572 vtop->type.t = VT_INT;
1573 #endif
1574 vpushi(u);
1575 gen_op(TOK_PDIV);
1576 } else {
1577 /* exactly one pointer : must be '+' or '-'. */
1578 if (op != '-' && op != '+')
1579 error("cannot use pointers here");
1580 /* Put pointer as first operand */
1581 if (bt2 == VT_PTR) {
1582 vswap();
1583 swap(&t1, &t2);
1585 type1 = vtop[-1].type;
1586 type1.t &= ~VT_ARRAY;
1587 u = pointed_size(&vtop[-1].type);
1588 if (u < 0)
1589 error("unknown array element size");
1590 #ifdef TCC_TARGET_X86_64
1591 vpushll(u);
1592 #else
1593 /* XXX: cast to int ? (long long case) */
1594 vpushi(u);
1595 #endif
1596 gen_op('*');
1597 #ifdef CONFIG_TCC_BCHECK
1598 /* if evaluating constant expression, no code should be
1599 generated, so no bound check */
1600 if (tcc_state->do_bounds_check && !const_wanted) {
1601 /* if bounded pointers, we generate a special code to
1602 test bounds */
1603 if (op == '-') {
1604 vpushi(0);
1605 vswap();
1606 gen_op('-');
1608 gen_bounded_ptr_add();
1609 } else
1610 #endif
1612 gen_opic(op);
1614 /* put again type if gen_opic() swaped operands */
1615 vtop->type = type1;
1617 } else if (is_float(bt1) || is_float(bt2)) {
1618 /* compute bigger type and do implicit casts */
1619 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1620 t = VT_LDOUBLE;
1621 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1622 t = VT_DOUBLE;
1623 } else {
1624 t = VT_FLOAT;
1626 /* floats can only be used for a few operations */
1627 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1628 (op < TOK_ULT || op > TOK_GT))
1629 error("invalid operands for binary operation");
1630 goto std_op;
1631 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1632 /* cast to biggest op */
1633 t = VT_LLONG;
1634 /* convert to unsigned if it does not fit in a long long */
1635 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1636 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1637 t |= VT_UNSIGNED;
1638 goto std_op;
1639 } else {
1640 /* integer operations */
1641 t = VT_INT;
1642 /* convert to unsigned if it does not fit in an integer */
1643 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1644 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1645 t |= VT_UNSIGNED;
1646 std_op:
1647 /* XXX: currently, some unsigned operations are explicit, so
1648 we modify them here */
1649 if (t & VT_UNSIGNED) {
1650 if (op == TOK_SAR)
1651 op = TOK_SHR;
1652 else if (op == '/')
1653 op = TOK_UDIV;
1654 else if (op == '%')
1655 op = TOK_UMOD;
1656 else if (op == TOK_LT)
1657 op = TOK_ULT;
1658 else if (op == TOK_GT)
1659 op = TOK_UGT;
1660 else if (op == TOK_LE)
1661 op = TOK_ULE;
1662 else if (op == TOK_GE)
1663 op = TOK_UGE;
1665 vswap();
1666 type1.t = t;
1667 gen_cast(&type1);
1668 vswap();
1669 /* special case for shifts and long long: we keep the shift as
1670 an integer */
1671 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1672 type1.t = VT_INT;
1673 gen_cast(&type1);
1674 if (is_float(t))
1675 gen_opif(op);
1676 else
1677 gen_opic(op);
1678 if (op >= TOK_ULT && op <= TOK_GT) {
1679 /* relationnal op: the result is an int */
1680 vtop->type.t = VT_INT;
1681 } else {
1682 vtop->type.t = t;
1687 #ifndef TCC_TARGET_ARM
1688 /* generic itof for unsigned long long case */
1689 static void gen_cvt_itof1(int t)
1691 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1692 (VT_LLONG | VT_UNSIGNED)) {
1694 if (t == VT_FLOAT)
1695 vpush_global_sym(&func_old_type, TOK___floatundisf);
1696 #if LDOUBLE_SIZE != 8
1697 else if (t == VT_LDOUBLE)
1698 vpush_global_sym(&func_old_type, TOK___floatundixf);
1699 #endif
1700 else
1701 vpush_global_sym(&func_old_type, TOK___floatundidf);
1702 vrott(2);
1703 gfunc_call(1);
1704 vpushi(0);
1705 vtop->r = reg_fret(t);
1706 } else {
1707 gen_cvt_itof(t);
1710 #endif
1712 /* generic ftoi for unsigned long long case */
1713 static void gen_cvt_ftoi1(int t)
1715 int st;
1717 if (t == (VT_LLONG | VT_UNSIGNED)) {
1718 /* not handled natively */
1719 st = vtop->type.t & VT_BTYPE;
1720 if (st == VT_FLOAT)
1721 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1722 #if LDOUBLE_SIZE != 8
1723 else if (st == VT_LDOUBLE)
1724 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1725 #endif
1726 else
1727 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1728 vrott(2);
1729 gfunc_call(1);
1730 vpushi(0);
1731 vtop->r = REG_IRET;
1732 vtop->r2 = REG_LRET;
1733 } else {
1734 gen_cvt_ftoi(t);
1738 /* force char or short cast */
1739 static void force_charshort_cast(int t)
1741 int bits, dbt;
1742 dbt = t & VT_BTYPE;
1743 /* XXX: add optimization if lvalue : just change type and offset */
1744 if (dbt == VT_BYTE)
1745 bits = 8;
1746 else
1747 bits = 16;
1748 if (t & VT_UNSIGNED) {
1749 vpushi((1 << bits) - 1);
1750 gen_op('&');
1751 } else {
1752 bits = 32 - bits;
1753 vpushi(bits);
1754 gen_op(TOK_SHL);
1755 /* result must be signed or the SAR is converted to an SHL
1756 This was not the case when "t" was a signed short
1757 and the last value on the stack was an unsigned int */
1758 vtop->type.t &= ~VT_UNSIGNED;
1759 vpushi(bits);
1760 gen_op(TOK_SAR);
1764 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1765 static void gen_cast(CType *type)
1767 int sbt, dbt, sf, df, c, p;
1769 /* special delayed cast for char/short */
1770 /* XXX: in some cases (multiple cascaded casts), it may still
1771 be incorrect */
1772 if (vtop->r & VT_MUSTCAST) {
1773 vtop->r &= ~VT_MUSTCAST;
1774 force_charshort_cast(vtop->type.t);
1777 /* bitfields first get cast to ints */
1778 if (vtop->type.t & VT_BITFIELD) {
1779 gv(RC_INT);
1782 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1783 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1785 if (sbt != dbt) {
1786 sf = is_float(sbt);
1787 df = is_float(dbt);
1788 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1789 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1790 if (c) {
1791 /* constant case: we can do it now */
1792 /* XXX: in ISOC, cannot do it if error in convert */
1793 if (sbt == VT_FLOAT)
1794 vtop->c.ld = vtop->c.f;
1795 else if (sbt == VT_DOUBLE)
1796 vtop->c.ld = vtop->c.d;
1798 if (df) {
1799 if ((sbt & VT_BTYPE) == VT_LLONG) {
1800 if (sbt & VT_UNSIGNED)
1801 vtop->c.ld = vtop->c.ull;
1802 else
1803 vtop->c.ld = vtop->c.ll;
1804 } else if(!sf) {
1805 if (sbt & VT_UNSIGNED)
1806 vtop->c.ld = vtop->c.ui;
1807 else
1808 vtop->c.ld = vtop->c.i;
1811 if (dbt == VT_FLOAT)
1812 vtop->c.f = (float)vtop->c.ld;
1813 else if (dbt == VT_DOUBLE)
1814 vtop->c.d = (double)vtop->c.ld;
1815 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1816 vtop->c.ull = (unsigned long long)vtop->c.ld;
1817 } else if (sf && dbt == VT_BOOL) {
1818 vtop->c.i = (vtop->c.ld != 0);
1819 } else {
1820 if(sf)
1821 vtop->c.ll = (long long)vtop->c.ld;
1822 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1823 vtop->c.ll = vtop->c.ull;
1824 else if (sbt & VT_UNSIGNED)
1825 vtop->c.ll = vtop->c.ui;
1826 #ifdef TCC_TARGET_X86_64
1827 else if (sbt == VT_PTR)
1829 #endif
1830 else if (sbt != VT_LLONG)
1831 vtop->c.ll = vtop->c.i;
1833 if (dbt == (VT_LLONG|VT_UNSIGNED))
1834 vtop->c.ull = vtop->c.ll;
1835 else if (dbt == VT_BOOL)
1836 vtop->c.i = (vtop->c.ll != 0);
1837 else if (dbt != VT_LLONG) {
1838 int s = 0;
1839 if ((dbt & VT_BTYPE) == VT_BYTE)
1840 s = 24;
1841 else if ((dbt & VT_BTYPE) == VT_SHORT)
1842 s = 16;
1844 if(dbt & VT_UNSIGNED)
1845 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1846 else
1847 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1850 } else if (p && dbt == VT_BOOL) {
1851 vtop->r = VT_CONST;
1852 vtop->c.i = 1;
1853 } else if (!nocode_wanted) {
1854 /* non constant case: generate code */
1855 if (sf && df) {
1856 /* convert from fp to fp */
1857 gen_cvt_ftof(dbt);
1858 } else if (df) {
1859 /* convert int to fp */
1860 gen_cvt_itof1(dbt);
1861 } else if (sf) {
1862 /* convert fp to int */
1863 if (dbt == VT_BOOL) {
1864 vpushi(0);
1865 gen_op(TOK_NE);
1866 } else {
1867 /* we handle char/short/etc... with generic code */
1868 if (dbt != (VT_INT | VT_UNSIGNED) &&
1869 dbt != (VT_LLONG | VT_UNSIGNED) &&
1870 dbt != VT_LLONG)
1871 dbt = VT_INT;
1872 gen_cvt_ftoi1(dbt);
1873 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1874 /* additional cast for char/short... */
1875 vtop->type.t = dbt;
1876 gen_cast(type);
1879 #ifndef TCC_TARGET_X86_64
1880 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1881 if ((sbt & VT_BTYPE) != VT_LLONG) {
1882 /* scalar to long long */
1883 /* machine independent conversion */
1884 gv(RC_INT);
1885 /* generate high word */
1886 if (sbt == (VT_INT | VT_UNSIGNED)) {
1887 vpushi(0);
1888 gv(RC_INT);
1889 } else {
1890 if (sbt == VT_PTR) {
1891 /* cast from pointer to int before we apply
1892 shift operation, which pointers don't support*/
1893 gen_cast(&int_type);
1895 gv_dup();
1896 vpushi(31);
1897 gen_op(TOK_SAR);
1899 /* patch second register */
1900 vtop[-1].r2 = vtop->r;
1901 vpop();
1903 #else
1904 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1905 (dbt & VT_BTYPE) == VT_PTR ||
1906 (dbt & VT_BTYPE) == VT_FUNC) {
1907 if ((sbt & VT_BTYPE) != VT_LLONG &&
1908 (sbt & VT_BTYPE) != VT_PTR &&
1909 (sbt & VT_BTYPE) != VT_FUNC) {
1910 /* need to convert from 32bit to 64bit */
1911 int r = gv(RC_INT);
1912 if (sbt != (VT_INT | VT_UNSIGNED)) {
1913 /* x86_64 specific: movslq */
1914 o(0x6348);
1915 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1918 #endif
1919 } else if (dbt == VT_BOOL) {
1920 /* scalar to bool */
1921 vpushi(0);
1922 gen_op(TOK_NE);
1923 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1924 (dbt & VT_BTYPE) == VT_SHORT) {
1925 if (sbt == VT_PTR) {
1926 vtop->type.t = VT_INT;
1927 warning("nonportable conversion from pointer to char/short");
1929 force_charshort_cast(dbt);
1930 } else if ((dbt & VT_BTYPE) == VT_INT) {
1931 /* scalar to int */
1932 if (sbt == VT_LLONG) {
1933 /* from long long: just take low order word */
1934 lexpand();
1935 vpop();
1937 /* if lvalue and single word type, nothing to do because
1938 the lvalue already contains the real type size (see
1939 VT_LVAL_xxx constants) */
1942 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1943 /* if we are casting between pointer types,
1944 we must update the VT_LVAL_xxx size */
1945 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1946 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1948 vtop->type = *type;
1951 /* return type size. Put alignment at 'a' */
1952 ST_FUNC int type_size(CType *type, int *a)
1954 Sym *s;
1955 int bt;
1957 bt = type->t & VT_BTYPE;
1958 if (bt == VT_STRUCT) {
1959 /* struct/union */
1960 s = type->ref;
1961 *a = s->r & 0xffffff;
1962 return s->c;
1963 } else if (bt == VT_PTR) {
1964 if (type->t & VT_ARRAY) {
1965 int ts;
1967 s = type->ref;
1968 ts = type_size(&s->type, a);
1970 if (ts < 0 && s->c < 0)
1971 ts = -ts;
1973 return ts * s->c;
1974 } else {
1975 *a = PTR_SIZE;
1976 return PTR_SIZE;
1978 } else if (bt == VT_LDOUBLE) {
1979 *a = LDOUBLE_ALIGN;
1980 return LDOUBLE_SIZE;
1981 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
1982 #ifdef TCC_TARGET_I386
1983 #ifdef TCC_TARGET_PE
1984 *a = 8;
1985 #else
1986 *a = 4;
1987 #endif
1988 #elif defined(TCC_TARGET_ARM)
1989 #ifdef TCC_ARM_EABI
1990 *a = 8;
1991 #else
1992 *a = 4;
1993 #endif
1994 #else
1995 *a = 8;
1996 #endif
1997 return 8;
1998 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
1999 *a = 4;
2000 return 4;
2001 } else if (bt == VT_SHORT) {
2002 *a = 2;
2003 return 2;
2004 } else {
2005 /* char, void, function, _Bool */
2006 *a = 1;
2007 return 1;
2011 /* return the pointed type of t */
2012 static inline CType *pointed_type(CType *type)
2014 return &type->ref->type;
2017 /* modify type so that its it is a pointer to type. */
2018 ST_FUNC void mk_pointer(CType *type)
2020 Sym *s;
2021 s = sym_push(SYM_FIELD, type, 0, -1);
2022 type->t = VT_PTR | (type->t & ~VT_TYPE);
2023 type->ref = s;
2026 /* compare function types. OLD functions match any new functions */
2027 static int is_compatible_func(CType *type1, CType *type2)
2029 Sym *s1, *s2;
2031 s1 = type1->ref;
2032 s2 = type2->ref;
2033 if (!is_compatible_types(&s1->type, &s2->type))
2034 return 0;
2035 /* check func_call */
2036 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2037 return 0;
2038 /* XXX: not complete */
2039 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2040 return 1;
2041 if (s1->c != s2->c)
2042 return 0;
2043 while (s1 != NULL) {
2044 if (s2 == NULL)
2045 return 0;
2046 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2047 return 0;
2048 s1 = s1->next;
2049 s2 = s2->next;
2051 if (s2)
2052 return 0;
2053 return 1;
2056 /* return true if type1 and type2 are the same. If unqualified is
2057 true, qualifiers on the types are ignored.
2059 - enums are not checked as gcc __builtin_types_compatible_p ()
2061 static int compare_types(CType *type1, CType *type2, int unqualified)
2063 int bt1, t1, t2;
2065 t1 = type1->t & VT_TYPE;
2066 t2 = type2->t & VT_TYPE;
2067 if (unqualified) {
2068 /* strip qualifiers before comparing */
2069 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2070 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2072 /* XXX: bitfields ? */
2073 if (t1 != t2)
2074 return 0;
2075 /* test more complicated cases */
2076 bt1 = t1 & VT_BTYPE;
2077 if (bt1 == VT_PTR) {
2078 type1 = pointed_type(type1);
2079 type2 = pointed_type(type2);
2080 return is_compatible_types(type1, type2);
2081 } else if (bt1 == VT_STRUCT) {
2082 return (type1->ref == type2->ref);
2083 } else if (bt1 == VT_FUNC) {
2084 return is_compatible_func(type1, type2);
2085 } else {
2086 return 1;
2090 /* return true if type1 and type2 are exactly the same (including
2091 qualifiers).
2093 static int is_compatible_types(CType *type1, CType *type2)
2095 return compare_types(type1,type2,0);
2098 /* return true if type1 and type2 are the same (ignoring qualifiers).
2100 static int is_compatible_parameter_types(CType *type1, CType *type2)
2102 return compare_types(type1,type2,1);
2105 /* print a type. If 'varstr' is not NULL, then the variable is also
2106 printed in the type */
2107 /* XXX: union */
2108 /* XXX: add array and function pointers */
2109 static void type_to_str(char *buf, int buf_size,
2110 CType *type, const char *varstr)
2112 int bt, v, t;
2113 Sym *s, *sa;
2114 char buf1[256];
2115 const char *tstr;
2117 t = type->t & VT_TYPE;
2118 bt = t & VT_BTYPE;
2119 buf[0] = '\0';
2120 if (t & VT_CONSTANT)
2121 pstrcat(buf, buf_size, "const ");
2122 if (t & VT_VOLATILE)
2123 pstrcat(buf, buf_size, "volatile ");
2124 if (t & VT_UNSIGNED)
2125 pstrcat(buf, buf_size, "unsigned ");
2126 switch(bt) {
2127 case VT_VOID:
2128 tstr = "void";
2129 goto add_tstr;
2130 case VT_BOOL:
2131 tstr = "_Bool";
2132 goto add_tstr;
2133 case VT_BYTE:
2134 tstr = "char";
2135 goto add_tstr;
2136 case VT_SHORT:
2137 tstr = "short";
2138 goto add_tstr;
2139 case VT_INT:
2140 tstr = "int";
2141 goto add_tstr;
2142 case VT_LONG:
2143 tstr = "long";
2144 goto add_tstr;
2145 case VT_LLONG:
2146 tstr = "long long";
2147 goto add_tstr;
2148 case VT_FLOAT:
2149 tstr = "float";
2150 goto add_tstr;
2151 case VT_DOUBLE:
2152 tstr = "double";
2153 goto add_tstr;
2154 case VT_LDOUBLE:
2155 tstr = "long double";
2156 add_tstr:
2157 pstrcat(buf, buf_size, tstr);
2158 break;
2159 case VT_ENUM:
2160 case VT_STRUCT:
2161 if (bt == VT_STRUCT)
2162 tstr = "struct ";
2163 else
2164 tstr = "enum ";
2165 pstrcat(buf, buf_size, tstr);
2166 v = type->ref->v & ~SYM_STRUCT;
2167 if (v >= SYM_FIRST_ANOM)
2168 pstrcat(buf, buf_size, "<anonymous>");
2169 else
2170 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2171 break;
2172 case VT_FUNC:
2173 s = type->ref;
2174 type_to_str(buf, buf_size, &s->type, varstr);
2175 pstrcat(buf, buf_size, "(");
2176 sa = s->next;
2177 while (sa != NULL) {
2178 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2179 pstrcat(buf, buf_size, buf1);
2180 sa = sa->next;
2181 if (sa)
2182 pstrcat(buf, buf_size, ", ");
2184 pstrcat(buf, buf_size, ")");
2185 goto no_var;
2186 case VT_PTR:
2187 s = type->ref;
2188 pstrcpy(buf1, sizeof(buf1), "*");
2189 if (varstr)
2190 pstrcat(buf1, sizeof(buf1), varstr);
2191 type_to_str(buf, buf_size, &s->type, buf1);
2192 goto no_var;
2194 if (varstr) {
2195 pstrcat(buf, buf_size, " ");
2196 pstrcat(buf, buf_size, varstr);
2198 no_var: ;
2201 /* verify type compatibility to store vtop in 'dt' type, and generate
2202 casts if needed. */
2203 static void gen_assign_cast(CType *dt)
2205 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2206 char buf1[256], buf2[256];
2207 int dbt, sbt;
2209 st = &vtop->type; /* source type */
2210 dbt = dt->t & VT_BTYPE;
2211 sbt = st->t & VT_BTYPE;
2212 if (dt->t & VT_CONSTANT)
2213 warning("assignment of read-only location");
2214 switch(dbt) {
2215 case VT_PTR:
2216 /* special cases for pointers */
2217 /* '0' can also be a pointer */
2218 if (is_null_pointer(vtop))
2219 goto type_ok;
2220 /* accept implicit pointer to integer cast with warning */
2221 if (is_integer_btype(sbt)) {
2222 warning("assignment makes pointer from integer without a cast");
2223 goto type_ok;
2225 type1 = pointed_type(dt);
2226 /* a function is implicitely a function pointer */
2227 if (sbt == VT_FUNC) {
2228 if ((type1->t & VT_BTYPE) != VT_VOID &&
2229 !is_compatible_types(pointed_type(dt), st))
2230 warning("assignment from incompatible pointer type");
2231 goto type_ok;
2233 if (sbt != VT_PTR)
2234 goto error;
2235 type2 = pointed_type(st);
2236 if ((type1->t & VT_BTYPE) == VT_VOID ||
2237 (type2->t & VT_BTYPE) == VT_VOID) {
2238 /* void * can match anything */
2239 } else {
2240 /* exact type match, except for unsigned */
2241 tmp_type1 = *type1;
2242 tmp_type2 = *type2;
2243 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2244 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2245 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2246 warning("assignment from incompatible pointer type");
2248 /* check const and volatile */
2249 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2250 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2251 warning("assignment discards qualifiers from pointer target type");
2252 break;
2253 case VT_BYTE:
2254 case VT_SHORT:
2255 case VT_INT:
2256 case VT_LLONG:
2257 if (sbt == VT_PTR || sbt == VT_FUNC) {
2258 warning("assignment makes integer from pointer without a cast");
2260 /* XXX: more tests */
2261 break;
2262 case VT_STRUCT:
2263 tmp_type1 = *dt;
2264 tmp_type2 = *st;
2265 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2266 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2267 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2268 error:
2269 type_to_str(buf1, sizeof(buf1), st, NULL);
2270 type_to_str(buf2, sizeof(buf2), dt, NULL);
2271 error("cannot cast '%s' to '%s'", buf1, buf2);
2273 break;
2275 type_ok:
2276 gen_cast(dt);
2279 /* store vtop in lvalue pushed on stack */
2280 ST_FUNC void vstore(void)
2282 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2284 ft = vtop[-1].type.t;
2285 sbt = vtop->type.t & VT_BTYPE;
2286 dbt = ft & VT_BTYPE;
2287 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2288 (sbt == VT_INT && dbt == VT_SHORT)) {
2289 /* optimize char/short casts */
2290 delayed_cast = VT_MUSTCAST;
2291 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2292 /* XXX: factorize */
2293 if (ft & VT_CONSTANT)
2294 warning("assignment of read-only location");
2295 } else {
2296 delayed_cast = 0;
2297 if (!(ft & VT_BITFIELD))
2298 gen_assign_cast(&vtop[-1].type);
2301 if (sbt == VT_STRUCT) {
2302 /* if structure, only generate pointer */
2303 /* structure assignment : generate memcpy */
2304 /* XXX: optimize if small size */
2305 if (!nocode_wanted) {
2306 size = type_size(&vtop->type, &align);
2308 /* destination */
2309 vswap();
2310 vtop->type.t = VT_PTR;
2311 gaddrof();
2313 /* address of memcpy() */
2314 #ifdef TCC_ARM_EABI
2315 if(!(align & 7))
2316 vpush_global_sym(&func_old_type, TOK_memcpy8);
2317 else if(!(align & 3))
2318 vpush_global_sym(&func_old_type, TOK_memcpy4);
2319 else
2320 #endif
2321 vpush_global_sym(&func_old_type, TOK_memcpy);
2323 vswap();
2324 /* source */
2325 vpushv(vtop - 2);
2326 vtop->type.t = VT_PTR;
2327 gaddrof();
2328 /* type size */
2329 vpushi(size);
2330 gfunc_call(3);
2331 } else {
2332 vswap();
2333 vpop();
2335 /* leave source on stack */
2336 } else if (ft & VT_BITFIELD) {
2337 /* bitfield store handling */
2338 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2339 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2340 /* remove bit field info to avoid loops */
2341 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2343 /* duplicate source into other register */
2344 gv_dup();
2345 vswap();
2346 vrott(3);
2348 if((ft & VT_BTYPE) == VT_BOOL) {
2349 gen_cast(&vtop[-1].type);
2350 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2353 /* duplicate destination */
2354 vdup();
2355 vtop[-1] = vtop[-2];
2357 /* mask and shift source */
2358 if((ft & VT_BTYPE) != VT_BOOL) {
2359 if((ft & VT_BTYPE) == VT_LLONG) {
2360 vpushll((1ULL << bit_size) - 1ULL);
2361 } else {
2362 vpushi((1 << bit_size) - 1);
2364 gen_op('&');
2366 vpushi(bit_pos);
2367 gen_op(TOK_SHL);
2368 /* load destination, mask and or with source */
2369 vswap();
2370 if((ft & VT_BTYPE) == VT_LLONG) {
2371 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2372 } else {
2373 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2375 gen_op('&');
2376 gen_op('|');
2377 /* store result */
2378 vstore();
2380 /* pop off shifted source from "duplicate source..." above */
2381 vpop();
2383 } else {
2384 #ifdef CONFIG_TCC_BCHECK
2385 /* bound check case */
2386 if (vtop[-1].r & VT_MUSTBOUND) {
2387 vswap();
2388 gbound();
2389 vswap();
2391 #endif
2392 if (!nocode_wanted) {
2393 rc = RC_INT;
2394 if (is_float(ft)) {
2395 rc = RC_FLOAT;
2396 #ifdef TCC_TARGET_X86_64
2397 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2398 rc = RC_ST0;
2400 #endif
2402 r = gv(rc); /* generate value */
2403 /* if lvalue was saved on stack, must read it */
2404 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2405 SValue sv;
2406 t = get_reg(RC_INT);
2407 #ifdef TCC_TARGET_X86_64
2408 sv.type.t = VT_PTR;
2409 #else
2410 sv.type.t = VT_INT;
2411 #endif
2412 sv.r = VT_LOCAL | VT_LVAL;
2413 sv.c.ul = vtop[-1].c.ul;
2414 load(t, &sv);
2415 vtop[-1].r = t | VT_LVAL;
2417 store(r, vtop - 1);
2418 #ifndef TCC_TARGET_X86_64
2419 /* two word case handling : store second register at word + 4 */
2420 if ((ft & VT_BTYPE) == VT_LLONG) {
2421 vswap();
2422 /* convert to int to increment easily */
2423 vtop->type.t = VT_INT;
2424 gaddrof();
2425 vpushi(4);
2426 gen_op('+');
2427 vtop->r |= VT_LVAL;
2428 vswap();
2429 /* XXX: it works because r2 is spilled last ! */
2430 store(vtop->r2, vtop - 1);
2432 #endif
2434 vswap();
2435 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2436 vtop->r |= delayed_cast;
2440 /* post defines POST/PRE add. c is the token ++ or -- */
2441 ST_FUNC void inc(int post, int c)
2443 test_lvalue();
2444 vdup(); /* save lvalue */
2445 if (post) {
2446 gv_dup(); /* duplicate value */
2447 vrotb(3);
2448 vrotb(3);
2450 /* add constant */
2451 vpushi(c - TOK_MID);
2452 gen_op('+');
2453 vstore(); /* store value */
2454 if (post)
2455 vpop(); /* if post op, return saved value */
2458 /* Parse GNUC __attribute__ extension. Currently, the following
2459 extensions are recognized:
2460 - aligned(n) : set data/function alignment.
2461 - packed : force data alignment to 1
2462 - section(x) : generate data/code in this section.
2463 - unused : currently ignored, but may be used someday.
2464 - regparm(n) : pass function parameters in registers (i386 only)
2466 static void parse_attribute(AttributeDef *ad)
2468 int t, n;
2470 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2471 next();
2472 skip('(');
2473 skip('(');
2474 while (tok != ')') {
2475 if (tok < TOK_IDENT)
2476 expect("attribute name");
2477 t = tok;
2478 next();
2479 switch(t) {
2480 case TOK_SECTION1:
2481 case TOK_SECTION2:
2482 skip('(');
2483 if (tok != TOK_STR)
2484 expect("section name");
2485 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2486 next();
2487 skip(')');
2488 break;
2489 case TOK_ALIAS1:
2490 case TOK_ALIAS2:
2491 skip('(');
2492 if (tok != TOK_STR)
2493 expect("alias(\"target\")");
2494 ad->alias_target = /* save string as token, for later */
2495 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2496 next();
2497 skip(')');
2498 break;
2499 case TOK_ALIGNED1:
2500 case TOK_ALIGNED2:
2501 if (tok == '(') {
2502 next();
2503 n = expr_const();
2504 if (n <= 0 || (n & (n - 1)) != 0)
2505 error("alignment must be a positive power of two");
2506 skip(')');
2507 } else {
2508 n = MAX_ALIGN;
2510 ad->aligned = n;
2511 break;
2512 case TOK_PACKED1:
2513 case TOK_PACKED2:
2514 ad->packed = 1;
2515 break;
2516 case TOK_WEAK1:
2517 case TOK_WEAK2:
2518 ad->weak = 1;
2519 break;
2520 case TOK_UNUSED1:
2521 case TOK_UNUSED2:
2522 /* currently, no need to handle it because tcc does not
2523 track unused objects */
2524 break;
2525 case TOK_NORETURN1:
2526 case TOK_NORETURN2:
2527 /* currently, no need to handle it because tcc does not
2528 track unused objects */
2529 break;
2530 case TOK_CDECL1:
2531 case TOK_CDECL2:
2532 case TOK_CDECL3:
2533 ad->func_call = FUNC_CDECL;
2534 break;
2535 case TOK_STDCALL1:
2536 case TOK_STDCALL2:
2537 case TOK_STDCALL3:
2538 ad->func_call = FUNC_STDCALL;
2539 break;
2540 #ifdef TCC_TARGET_I386
2541 case TOK_REGPARM1:
2542 case TOK_REGPARM2:
2543 skip('(');
2544 n = expr_const();
2545 if (n > 3)
2546 n = 3;
2547 else if (n < 0)
2548 n = 0;
2549 if (n > 0)
2550 ad->func_call = FUNC_FASTCALL1 + n - 1;
2551 skip(')');
2552 break;
2553 case TOK_FASTCALL1:
2554 case TOK_FASTCALL2:
2555 case TOK_FASTCALL3:
2556 ad->func_call = FUNC_FASTCALLW;
2557 break;
2558 #endif
2559 case TOK_MODE:
2560 skip('(');
2561 switch(tok) {
2562 case TOK_MODE_DI:
2563 ad->mode = VT_LLONG + 1;
2564 break;
2565 case TOK_MODE_HI:
2566 ad->mode = VT_SHORT + 1;
2567 break;
2568 case TOK_MODE_SI:
2569 ad->mode = VT_INT + 1;
2570 break;
2571 default:
2572 warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2573 break;
2575 next();
2576 skip(')');
2577 break;
2578 case TOK_DLLEXPORT:
2579 ad->func_export = 1;
2580 break;
2581 case TOK_DLLIMPORT:
2582 ad->func_import = 1;
2583 break;
2584 default:
2585 if (tcc_state->warn_unsupported)
2586 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2587 /* skip parameters */
2588 if (tok == '(') {
2589 int parenthesis = 0;
2590 do {
2591 if (tok == '(')
2592 parenthesis++;
2593 else if (tok == ')')
2594 parenthesis--;
2595 next();
2596 } while (parenthesis && tok != -1);
2598 break;
2600 if (tok != ',')
2601 break;
2602 next();
2604 skip(')');
2605 skip(')');
2609 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2610 static void struct_decl(CType *type, int u)
2612 int a, v, size, align, maxalign, c, offset;
2613 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt, resize;
2614 Sym *s, *ss, *ass, **ps;
2615 AttributeDef ad;
2616 CType type1, btype;
2618 a = tok; /* save decl type */
2619 next();
2620 if (tok != '{') {
2621 v = tok;
2622 next();
2623 /* struct already defined ? return it */
2624 if (v < TOK_IDENT)
2625 expect("struct/union/enum name");
2626 s = struct_find(v);
2627 if (s) {
2628 if (s->type.t != a)
2629 error("invalid type");
2630 goto do_decl;
2632 } else {
2633 v = anon_sym++;
2635 type1.t = a;
2636 /* we put an undefined size for struct/union */
2637 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2638 s->r = 0; /* default alignment is zero as gcc */
2639 /* put struct/union/enum name in type */
2640 do_decl:
2641 type->t = u;
2642 type->ref = s;
2644 if (tok == '{') {
2645 next();
2646 if (s->c != -1)
2647 error("struct/union/enum already defined");
2648 /* cannot be empty */
2649 c = 0;
2650 /* non empty enums are not allowed */
2651 if (a == TOK_ENUM) {
2652 for(;;) {
2653 v = tok;
2654 if (v < TOK_UIDENT)
2655 expect("identifier");
2656 next();
2657 if (tok == '=') {
2658 next();
2659 c = expr_const();
2661 /* enum symbols have static storage */
2662 ss = sym_push(v, &int_type, VT_CONST, c);
2663 ss->type.t |= VT_STATIC;
2664 if (tok != ',')
2665 break;
2666 next();
2667 c++;
2668 /* NOTE: we accept a trailing comma */
2669 if (tok == '}')
2670 break;
2672 skip('}');
2673 } else {
2674 resize = 0;
2675 maxalign = 1;
2676 ps = &s->next;
2677 prevbt = VT_INT;
2678 bit_pos = 0;
2679 offset = 0;
2680 while (tok != '}') {
2681 parse_btype(&btype, &ad);
2682 while (1) {
2683 bit_size = -1;
2684 v = 0;
2685 type1 = btype;
2686 if (tok != ':') {
2687 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2688 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2689 expect("identifier");
2690 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2691 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2692 error("invalid type for '%s'",
2693 get_tok_str(v, NULL));
2695 if (tok == ':') {
2696 next();
2697 bit_size = expr_const();
2698 /* XXX: handle v = 0 case for messages */
2699 if (bit_size < 0)
2700 error("negative width in bit-field '%s'",
2701 get_tok_str(v, NULL));
2702 if (v && bit_size == 0)
2703 error("zero width for bit-field '%s'",
2704 get_tok_str(v, NULL));
2706 size = type_size(&type1, &align);
2707 if (ad.aligned) {
2708 if (align < ad.aligned)
2709 align = ad.aligned;
2710 } else if (ad.packed) {
2711 align = 1;
2712 } else if (*tcc_state->pack_stack_ptr) {
2713 if (align > *tcc_state->pack_stack_ptr)
2714 align = *tcc_state->pack_stack_ptr;
2716 lbit_pos = 0;
2717 if (bit_size >= 0) {
2718 bt = type1.t & VT_BTYPE;
2719 if (bt != VT_INT &&
2720 bt != VT_BYTE &&
2721 bt != VT_SHORT &&
2722 bt != VT_BOOL &&
2723 bt != VT_ENUM &&
2724 bt != VT_LLONG)
2725 error("bitfields must have scalar type");
2726 bsize = size * 8;
2727 if (bit_size > bsize) {
2728 error("width of '%s' exceeds its type",
2729 get_tok_str(v, NULL));
2730 } else if (bit_size == bsize) {
2731 /* no need for bit fields */
2732 bit_pos = 0;
2733 } else if (bit_size == 0) {
2734 /* XXX: what to do if only padding in a
2735 structure ? */
2736 /* zero size: means to pad */
2737 bit_pos = 0;
2738 } else {
2739 /* we do not have enough room ?
2740 did the type change?
2741 is it a union? */
2742 if ((bit_pos + bit_size) > bsize ||
2743 bt != prevbt || a == TOK_UNION)
2744 bit_pos = 0;
2745 lbit_pos = bit_pos;
2746 /* XXX: handle LSB first */
2747 type1.t |= VT_BITFIELD |
2748 (bit_pos << VT_STRUCT_SHIFT) |
2749 (bit_size << (VT_STRUCT_SHIFT + 6));
2750 bit_pos += bit_size;
2752 prevbt = bt;
2753 } else {
2754 bit_pos = 0;
2756 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2757 /* add new memory data only if starting
2758 bit field */
2759 if (lbit_pos == 0) {
2760 if (a == TOK_STRUCT) {
2761 c = (c + align - 1) & -align;
2762 offset = c;
2763 if (size > 0)
2764 c += size;
2765 if (size < 0)
2766 resize = 1;
2767 } else {
2768 offset = 0;
2769 if (size > c)
2770 c = size;
2772 if (align > maxalign)
2773 maxalign = align;
2775 #if 0
2776 printf("add field %s offset=%d",
2777 get_tok_str(v, NULL), offset);
2778 if (type1.t & VT_BITFIELD) {
2779 printf(" pos=%d size=%d",
2780 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2781 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2783 printf("\n");
2784 #endif
2786 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2787 ass = type1.ref;
2788 while ((ass = ass->next) != NULL) {
2789 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2790 *ps = ss;
2791 ps = &ss->next;
2793 } else if (v) {
2794 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2795 *ps = ss;
2796 ps = &ss->next;
2798 if (tok == ';' || tok == TOK_EOF)
2799 break;
2800 skip(',');
2802 skip(';');
2804 skip('}');
2805 /* store size and alignment */
2806 s->c = (c + maxalign - 1) & -maxalign;
2807 s->r = maxalign | (resize ? (1 << 31) : 0);
2812 /* return 0 if no type declaration. otherwise, return the basic type
2813 and skip it.
2815 static int parse_btype(CType *type, AttributeDef *ad)
2817 int t, u, type_found, typespec_found, typedef_found;
2818 Sym *s;
2819 CType type1;
2821 memset(ad, 0, sizeof(AttributeDef));
2822 type_found = 0;
2823 typespec_found = 0;
2824 typedef_found = 0;
2825 t = 0;
2826 while(1) {
2827 switch(tok) {
2828 case TOK_EXTENSION:
2829 /* currently, we really ignore extension */
2830 next();
2831 continue;
2833 /* basic types */
2834 case TOK_CHAR:
2835 u = VT_BYTE;
2836 basic_type:
2837 next();
2838 basic_type1:
2839 if ((t & VT_BTYPE) != 0)
2840 error("too many basic types");
2841 t |= u;
2842 typespec_found = 1;
2843 break;
2844 case TOK_VOID:
2845 u = VT_VOID;
2846 goto basic_type;
2847 case TOK_SHORT:
2848 u = VT_SHORT;
2849 goto basic_type;
2850 case TOK_INT:
2851 next();
2852 typespec_found = 1;
2853 break;
2854 case TOK_LONG:
2855 next();
2856 if ((t & VT_BTYPE) == VT_DOUBLE) {
2857 #ifndef TCC_TARGET_PE
2858 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2859 #endif
2860 } else if ((t & VT_BTYPE) == VT_LONG) {
2861 t = (t & ~VT_BTYPE) | VT_LLONG;
2862 } else {
2863 u = VT_LONG;
2864 goto basic_type1;
2866 break;
2867 case TOK_BOOL:
2868 u = VT_BOOL;
2869 goto basic_type;
2870 case TOK_FLOAT:
2871 u = VT_FLOAT;
2872 goto basic_type;
2873 case TOK_DOUBLE:
2874 next();
2875 if ((t & VT_BTYPE) == VT_LONG) {
2876 #ifdef TCC_TARGET_PE
2877 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2878 #else
2879 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2880 #endif
2881 } else {
2882 u = VT_DOUBLE;
2883 goto basic_type1;
2885 break;
2886 case TOK_ENUM:
2887 struct_decl(&type1, VT_ENUM);
2888 basic_type2:
2889 u = type1.t;
2890 type->ref = type1.ref;
2891 goto basic_type1;
2892 case TOK_STRUCT:
2893 case TOK_UNION:
2894 struct_decl(&type1, VT_STRUCT);
2895 goto basic_type2;
2897 /* type modifiers */
2898 case TOK_CONST1:
2899 case TOK_CONST2:
2900 case TOK_CONST3:
2901 t |= VT_CONSTANT;
2902 next();
2903 break;
2904 case TOK_VOLATILE1:
2905 case TOK_VOLATILE2:
2906 case TOK_VOLATILE3:
2907 t |= VT_VOLATILE;
2908 next();
2909 break;
2910 case TOK_SIGNED1:
2911 case TOK_SIGNED2:
2912 case TOK_SIGNED3:
2913 typespec_found = 1;
2914 t |= VT_SIGNED;
2915 next();
2916 break;
2917 case TOK_REGISTER:
2918 case TOK_AUTO:
2919 case TOK_RESTRICT1:
2920 case TOK_RESTRICT2:
2921 case TOK_RESTRICT3:
2922 next();
2923 break;
2924 case TOK_UNSIGNED:
2925 t |= VT_UNSIGNED;
2926 next();
2927 typespec_found = 1;
2928 break;
2930 /* storage */
2931 case TOK_EXTERN:
2932 t |= VT_EXTERN;
2933 next();
2934 break;
2935 case TOK_STATIC:
2936 t |= VT_STATIC;
2937 next();
2938 break;
2939 case TOK_TYPEDEF:
2940 t |= VT_TYPEDEF;
2941 next();
2942 break;
2943 case TOK_INLINE1:
2944 case TOK_INLINE2:
2945 case TOK_INLINE3:
2946 t |= VT_INLINE;
2947 next();
2948 break;
2950 /* GNUC attribute */
2951 case TOK_ATTRIBUTE1:
2952 case TOK_ATTRIBUTE2:
2953 parse_attribute(ad);
2954 if (ad->mode) {
2955 u = ad->mode -1;
2956 t = (t & ~VT_BTYPE) | u;
2958 break;
2959 /* GNUC typeof */
2960 case TOK_TYPEOF1:
2961 case TOK_TYPEOF2:
2962 case TOK_TYPEOF3:
2963 next();
2964 parse_expr_type(&type1);
2965 /* remove all storage modifiers except typedef */
2966 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
2967 goto basic_type2;
2968 default:
2969 if (typespec_found || typedef_found)
2970 goto the_end;
2971 s = sym_find(tok);
2972 if (!s || !(s->type.t & VT_TYPEDEF))
2973 goto the_end;
2974 typedef_found = 1;
2975 t |= (s->type.t & ~VT_TYPEDEF);
2976 type->ref = s->type.ref;
2977 if (s->r) {
2978 /* get attributes from typedef */
2979 if (0 == ad->aligned)
2980 ad->aligned = FUNC_ALIGN(s->r);
2981 if (0 == ad->func_call)
2982 ad->func_call = FUNC_CALL(s->r);
2983 ad->packed |= FUNC_PACKED(s->r);
2985 next();
2986 typespec_found = 1;
2987 break;
2989 type_found = 1;
2991 the_end:
2992 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
2993 error("signed and unsigned modifier");
2994 if (tcc_state->char_is_unsigned) {
2995 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
2996 t |= VT_UNSIGNED;
2998 t &= ~VT_SIGNED;
3000 /* long is never used as type */
3001 if ((t & VT_BTYPE) == VT_LONG)
3002 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3003 t = (t & ~VT_BTYPE) | VT_INT;
3004 #else
3005 t = (t & ~VT_BTYPE) | VT_LLONG;
3006 #endif
3007 type->t = t;
3008 return type_found;
3011 /* convert a function parameter type (array to pointer and function to
3012 function pointer) */
3013 static inline void convert_parameter_type(CType *pt)
3015 /* remove const and volatile qualifiers (XXX: const could be used
3016 to indicate a const function parameter */
3017 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3018 /* array must be transformed to pointer according to ANSI C */
3019 pt->t &= ~VT_ARRAY;
3020 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3021 mk_pointer(pt);
3025 ST_FUNC void parse_asm_str(CString *astr)
3027 skip('(');
3028 /* read the string */
3029 if (tok != TOK_STR)
3030 expect("string constant");
3031 cstr_new(astr);
3032 while (tok == TOK_STR) {
3033 /* XXX: add \0 handling too ? */
3034 cstr_cat(astr, tokc.cstr->data);
3035 next();
3037 cstr_ccat(astr, '\0');
3040 /* Parse an asm label and return the label
3041 * Don't forget to free the CString in the caller! */
3042 static void asm_label_instr(CString *astr)
3044 next();
3045 parse_asm_str(astr);
3046 skip(')');
3047 #ifdef ASM_DEBUG
3048 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3049 #endif
3052 static void post_type(CType *type, AttributeDef *ad)
3054 int n, l, t1, arg_size, align;
3055 Sym **plast, *s, *first;
3056 AttributeDef ad1;
3057 CType pt;
3059 if (tok == '(') {
3060 /* function declaration */
3061 next();
3062 l = 0;
3063 first = NULL;
3064 plast = &first;
3065 arg_size = 0;
3066 if (tok != ')') {
3067 for(;;) {
3068 /* read param name and compute offset */
3069 if (l != FUNC_OLD) {
3070 if (!parse_btype(&pt, &ad1)) {
3071 if (l) {
3072 error("invalid type");
3073 } else {
3074 l = FUNC_OLD;
3075 goto old_proto;
3078 l = FUNC_NEW;
3079 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3080 break;
3081 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3082 if ((pt.t & VT_BTYPE) == VT_VOID)
3083 error("parameter declared as void");
3084 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3085 } else {
3086 old_proto:
3087 n = tok;
3088 if (n < TOK_UIDENT)
3089 expect("identifier");
3090 pt.t = VT_INT;
3091 next();
3093 convert_parameter_type(&pt);
3094 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3095 *plast = s;
3096 plast = &s->next;
3097 if (tok == ')')
3098 break;
3099 skip(',');
3100 if (l == FUNC_NEW && tok == TOK_DOTS) {
3101 l = FUNC_ELLIPSIS;
3102 next();
3103 break;
3107 /* if no parameters, then old type prototype */
3108 if (l == 0)
3109 l = FUNC_OLD;
3110 skip(')');
3111 /* NOTE: const is ignored in returned type as it has a special
3112 meaning in gcc / C++ */
3113 type->t &= ~VT_CONSTANT;
3114 /* some ancient pre-K&R C allows a function to return an array
3115 and the array brackets to be put after the arguments, such
3116 that "int c()[]" means something like "int[] c()" */
3117 if (tok == '[') {
3118 next();
3119 skip(']'); /* only handle simple "[]" */
3120 type->t |= VT_PTR;
3122 /* we push a anonymous symbol which will contain the function prototype */
3123 ad->func_args = arg_size;
3124 t1 = type->t & VT_STORAGE;
3125 type->t &= ~VT_STORAGE;
3126 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3127 s->next = first;
3128 type->t = t1 | VT_FUNC;
3129 type->ref = s;
3130 } else if (tok == '[') {
3131 /* array definition */
3132 next();
3133 if (tok == TOK_RESTRICT1)
3134 next();
3135 n = -1;
3136 if (tok != ']') {
3137 n = expr_const();
3138 if (n < 0)
3139 error("invalid array size");
3141 skip(']');
3142 /* parse next post type */
3143 t1 = type->t & VT_STORAGE;
3144 type->t &= ~VT_STORAGE;
3145 post_type(type, ad);
3147 /* we push a anonymous symbol which will contain the array
3148 element type */
3149 s = sym_push(SYM_FIELD, type, 0, n);
3150 if (n < 0)
3151 ARRAY_RESIZE(s->r) = 1;
3152 type->t = t1 | VT_ARRAY | VT_PTR;
3153 type->ref = s;
3157 /* Parse a type declaration (except basic type), and return the type
3158 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3159 expected. 'type' should contain the basic type. 'ad' is the
3160 attribute definition of the basic type. It can be modified by
3161 type_decl().
3163 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3165 Sym *s;
3166 CType type1, *type2;
3167 int qualifiers;
3169 while (tok == '*') {
3170 qualifiers = 0;
3171 redo:
3172 next();
3173 switch(tok) {
3174 case TOK_CONST1:
3175 case TOK_CONST2:
3176 case TOK_CONST3:
3177 qualifiers |= VT_CONSTANT;
3178 goto redo;
3179 case TOK_VOLATILE1:
3180 case TOK_VOLATILE2:
3181 case TOK_VOLATILE3:
3182 qualifiers |= VT_VOLATILE;
3183 goto redo;
3184 case TOK_RESTRICT1:
3185 case TOK_RESTRICT2:
3186 case TOK_RESTRICT3:
3187 goto redo;
3189 mk_pointer(type);
3190 type->t |= qualifiers;
3193 /* XXX: clarify attribute handling */
3194 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3195 parse_attribute(ad);
3197 /* recursive type */
3198 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3199 type1.t = 0; /* XXX: same as int */
3200 if (tok == '(') {
3201 next();
3202 /* XXX: this is not correct to modify 'ad' at this point, but
3203 the syntax is not clear */
3204 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3205 parse_attribute(ad);
3206 type_decl(&type1, ad, v, td);
3207 skip(')');
3208 } else {
3209 /* type identifier */
3210 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3211 *v = tok;
3212 next();
3213 } else {
3214 if (!(td & TYPE_ABSTRACT))
3215 expect("identifier");
3216 *v = 0;
3219 post_type(type, ad);
3220 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3221 parse_attribute(ad);
3223 if (!type1.t)
3224 return;
3225 /* append type at the end of type1 */
3226 type2 = &type1;
3227 for(;;) {
3228 s = type2->ref;
3229 type2 = &s->type;
3230 if (!type2->t) {
3231 *type2 = *type;
3232 break;
3235 *type = type1;
3238 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3239 ST_FUNC int lvalue_type(int t)
3241 int bt, r;
3242 r = VT_LVAL;
3243 bt = t & VT_BTYPE;
3244 if (bt == VT_BYTE || bt == VT_BOOL)
3245 r |= VT_LVAL_BYTE;
3246 else if (bt == VT_SHORT)
3247 r |= VT_LVAL_SHORT;
3248 else
3249 return r;
3250 if (t & VT_UNSIGNED)
3251 r |= VT_LVAL_UNSIGNED;
3252 return r;
3255 /* indirection with full error checking and bound check */
3256 ST_FUNC void indir(void)
3258 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3259 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3260 return;
3261 expect("pointer");
3263 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3264 gv(RC_INT);
3265 vtop->type = *pointed_type(&vtop->type);
3266 /* Arrays and functions are never lvalues */
3267 if (!(vtop->type.t & VT_ARRAY)
3268 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3269 vtop->r |= lvalue_type(vtop->type.t);
3270 /* if bound checking, the referenced pointer must be checked */
3271 #ifdef CONFIG_TCC_BCHECK
3272 if (tcc_state->do_bounds_check)
3273 vtop->r |= VT_MUSTBOUND;
3274 #endif
3278 /* pass a parameter to a function and do type checking and casting */
3279 static void gfunc_param_typed(Sym *func, Sym *arg)
3281 int func_type;
3282 CType type;
3284 func_type = func->c;
3285 if (func_type == FUNC_OLD ||
3286 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3287 /* default casting : only need to convert float to double */
3288 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3289 type.t = VT_DOUBLE;
3290 gen_cast(&type);
3292 } else if (arg == NULL) {
3293 error("too many arguments to function");
3294 } else {
3295 type = arg->type;
3296 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3297 gen_assign_cast(&type);
3301 /* parse an expression of the form '(type)' or '(expr)' and return its
3302 type */
3303 static void parse_expr_type(CType *type)
3305 int n;
3306 AttributeDef ad;
3308 skip('(');
3309 if (parse_btype(type, &ad)) {
3310 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3311 } else {
3312 expr_type(type);
3314 skip(')');
3317 static void parse_type(CType *type)
3319 AttributeDef ad;
3320 int n;
3322 if (!parse_btype(type, &ad)) {
3323 expect("type");
3325 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3328 static void vpush_tokc(int t)
3330 CType type;
3331 type.t = t;
3332 type.ref = 0;
3333 vsetc(&type, VT_CONST, &tokc);
3336 ST_FUNC void unary(void)
3338 int n, t, align, size, r, sizeof_caller;
3339 CType type;
3340 Sym *s;
3341 AttributeDef ad;
3342 static int in_sizeof = 0;
3344 sizeof_caller = in_sizeof;
3345 in_sizeof = 0;
3346 /* XXX: GCC 2.95.3 does not generate a table although it should be
3347 better here */
3348 tok_next:
3349 switch(tok) {
3350 case TOK_EXTENSION:
3351 next();
3352 goto tok_next;
3353 case TOK_CINT:
3354 case TOK_CCHAR:
3355 case TOK_LCHAR:
3356 vpushi(tokc.i);
3357 next();
3358 break;
3359 case TOK_CUINT:
3360 vpush_tokc(VT_INT | VT_UNSIGNED);
3361 next();
3362 break;
3363 case TOK_CLLONG:
3364 vpush_tokc(VT_LLONG);
3365 next();
3366 break;
3367 case TOK_CULLONG:
3368 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3369 next();
3370 break;
3371 case TOK_CFLOAT:
3372 vpush_tokc(VT_FLOAT);
3373 next();
3374 break;
3375 case TOK_CDOUBLE:
3376 vpush_tokc(VT_DOUBLE);
3377 next();
3378 break;
3379 case TOK_CLDOUBLE:
3380 vpush_tokc(VT_LDOUBLE);
3381 next();
3382 break;
3383 case TOK___FUNCTION__:
3384 if (!gnu_ext)
3385 goto tok_identifier;
3386 /* fall thru */
3387 case TOK___FUNC__:
3389 void *ptr;
3390 int len;
3391 /* special function name identifier */
3392 len = strlen(funcname) + 1;
3393 /* generate char[len] type */
3394 type.t = VT_BYTE;
3395 mk_pointer(&type);
3396 type.t |= VT_ARRAY;
3397 type.ref->c = len;
3398 vpush_ref(&type, data_section, data_section->data_offset, len);
3399 ptr = section_ptr_add(data_section, len);
3400 memcpy(ptr, funcname, len);
3401 next();
3403 break;
3404 case TOK_LSTR:
3405 #ifdef TCC_TARGET_PE
3406 t = VT_SHORT | VT_UNSIGNED;
3407 #else
3408 t = VT_INT;
3409 #endif
3410 goto str_init;
3411 case TOK_STR:
3412 /* string parsing */
3413 t = VT_BYTE;
3414 str_init:
3415 if (tcc_state->warn_write_strings)
3416 t |= VT_CONSTANT;
3417 type.t = t;
3418 mk_pointer(&type);
3419 type.t |= VT_ARRAY;
3420 memset(&ad, 0, sizeof(AttributeDef));
3421 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3422 break;
3423 case '(':
3424 next();
3425 /* cast ? */
3426 if (parse_btype(&type, &ad)) {
3427 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3428 skip(')');
3429 /* check ISOC99 compound literal */
3430 if (tok == '{') {
3431 /* data is allocated locally by default */
3432 if (global_expr)
3433 r = VT_CONST;
3434 else
3435 r = VT_LOCAL;
3436 /* all except arrays are lvalues */
3437 if (!(type.t & VT_ARRAY))
3438 r |= lvalue_type(type.t);
3439 memset(&ad, 0, sizeof(AttributeDef));
3440 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3441 } else {
3442 if (sizeof_caller) {
3443 vpush(&type);
3444 return;
3446 unary();
3447 gen_cast(&type);
3449 } else if (tok == '{') {
3450 /* save all registers */
3451 save_regs(0);
3452 /* statement expression : we do not accept break/continue
3453 inside as GCC does */
3454 block(NULL, NULL, NULL, NULL, 0, 1);
3455 skip(')');
3456 } else {
3457 gexpr();
3458 skip(')');
3460 break;
3461 case '*':
3462 next();
3463 unary();
3464 indir();
3465 break;
3466 case '&':
3467 next();
3468 unary();
3469 /* functions names must be treated as function pointers,
3470 except for unary '&' and sizeof. Since we consider that
3471 functions are not lvalues, we only have to handle it
3472 there and in function calls. */
3473 /* arrays can also be used although they are not lvalues */
3474 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3475 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3476 test_lvalue();
3477 mk_pointer(&vtop->type);
3478 gaddrof();
3479 break;
3480 case '!':
3481 next();
3482 unary();
3483 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3484 CType boolean;
3485 boolean.t = VT_BOOL;
3486 gen_cast(&boolean);
3487 vtop->c.i = !vtop->c.i;
3488 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3489 vtop->c.i = vtop->c.i ^ 1;
3490 else {
3491 save_regs(1);
3492 vseti(VT_JMP, gtst(1, 0));
3494 break;
3495 case '~':
3496 next();
3497 unary();
3498 vpushi(-1);
3499 gen_op('^');
3500 break;
3501 case '+':
3502 next();
3503 /* in order to force cast, we add zero */
3504 unary();
3505 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3506 error("pointer not accepted for unary plus");
3507 vpushi(0);
3508 gen_op('+');
3509 break;
3510 case TOK_SIZEOF:
3511 case TOK_ALIGNOF1:
3512 case TOK_ALIGNOF2:
3513 t = tok;
3514 next();
3515 in_sizeof++;
3516 unary_type(&type); // Perform a in_sizeof = 0;
3517 size = type_size(&type, &align);
3518 if (t == TOK_SIZEOF) {
3519 if (size < 0)
3520 error("sizeof applied to an incomplete type");
3521 vpushi(size);
3522 } else {
3523 vpushi(align);
3525 vtop->type.t |= VT_UNSIGNED;
3526 break;
3528 case TOK_builtin_types_compatible_p:
3530 CType type1, type2;
3531 next();
3532 skip('(');
3533 parse_type(&type1);
3534 skip(',');
3535 parse_type(&type2);
3536 skip(')');
3537 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3538 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3539 vpushi(is_compatible_types(&type1, &type2));
3541 break;
3542 case TOK_builtin_constant_p:
3544 int saved_nocode_wanted, res;
3545 next();
3546 skip('(');
3547 saved_nocode_wanted = nocode_wanted;
3548 nocode_wanted = 1;
3549 gexpr();
3550 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3551 vpop();
3552 nocode_wanted = saved_nocode_wanted;
3553 skip(')');
3554 vpushi(res);
3556 break;
3557 case TOK_builtin_frame_address:
3559 CType type;
3560 next();
3561 skip('(');
3562 if (tok != TOK_CINT) {
3563 error("__builtin_frame_address only takes integers");
3565 if (tokc.i != 0) {
3566 error("TCC only supports __builtin_frame_address(0)");
3568 next();
3569 skip(')');
3570 type.t = VT_VOID;
3571 mk_pointer(&type);
3572 vset(&type, VT_LOCAL, 0);
3574 break;
3575 #ifdef TCC_TARGET_X86_64
3576 case TOK_builtin_va_arg_types:
3578 /* This definition must be synced with stdarg.h */
3579 enum __va_arg_type {
3580 __va_gen_reg, __va_float_reg, __va_stack
3582 CType type;
3583 int bt;
3584 next();
3585 skip('(');
3586 parse_type(&type);
3587 skip(')');
3588 bt = type.t & VT_BTYPE;
3589 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3590 vpushi(__va_stack);
3591 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3592 vpushi(__va_float_reg);
3593 } else {
3594 vpushi(__va_gen_reg);
3597 break;
3598 #endif
3599 case TOK_INC:
3600 case TOK_DEC:
3601 t = tok;
3602 next();
3603 unary();
3604 inc(0, t);
3605 break;
3606 case '-':
3607 next();
3608 vpushi(0);
3609 unary();
3610 gen_op('-');
3611 break;
3612 case TOK_LAND:
3613 if (!gnu_ext)
3614 goto tok_identifier;
3615 next();
3616 /* allow to take the address of a label */
3617 if (tok < TOK_UIDENT)
3618 expect("label identifier");
3619 s = label_find(tok);
3620 if (!s) {
3621 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3622 } else {
3623 if (s->r == LABEL_DECLARED)
3624 s->r = LABEL_FORWARD;
3626 if (!s->type.t) {
3627 s->type.t = VT_VOID;
3628 mk_pointer(&s->type);
3629 s->type.t |= VT_STATIC;
3631 vset(&s->type, VT_CONST | VT_SYM, 0);
3632 vtop->sym = s;
3633 next();
3634 break;
3636 // special qnan , snan and infinity values
3637 case TOK___NAN__:
3638 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3639 next();
3640 break;
3641 case TOK___SNAN__:
3642 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3643 next();
3644 break;
3645 case TOK___INF__:
3646 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3647 next();
3648 break;
3650 default:
3651 tok_identifier:
3652 t = tok;
3653 next();
3654 if (t < TOK_UIDENT)
3655 expect("identifier");
3656 s = sym_find(t);
3657 if (!s) {
3658 if (tok != '(')
3659 error("'%s' undeclared", get_tok_str(t, NULL));
3660 /* for simple function calls, we tolerate undeclared
3661 external reference to int() function */
3662 if (tcc_state->warn_implicit_function_declaration)
3663 warning("implicit declaration of function '%s'",
3664 get_tok_str(t, NULL));
3665 s = external_global_sym(t, &func_old_type, 0);
3667 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3668 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3669 /* if referencing an inline function, then we generate a
3670 symbol to it if not already done. It will have the
3671 effect to generate code for it at the end of the
3672 compilation unit. Inline function as always
3673 generated in the text section. */
3674 if (!s->c)
3675 put_extern_sym(s, text_section, 0, 0);
3676 r = VT_SYM | VT_CONST;
3677 } else {
3678 r = s->r;
3680 vset(&s->type, r, s->c);
3681 /* if forward reference, we must point to s */
3682 if (vtop->r & VT_SYM) {
3683 vtop->sym = s;
3684 vtop->c.ul = 0;
3686 break;
3689 /* post operations */
3690 while (1) {
3691 if (tok == TOK_INC || tok == TOK_DEC) {
3692 inc(1, tok);
3693 next();
3694 } else if (tok == '.' || tok == TOK_ARROW) {
3695 int qualifiers;
3696 /* field */
3697 if (tok == TOK_ARROW)
3698 indir();
3699 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3700 test_lvalue();
3701 gaddrof();
3702 next();
3703 /* expect pointer on structure */
3704 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3705 expect("struct or union");
3706 s = vtop->type.ref;
3707 /* find field */
3708 tok |= SYM_FIELD;
3709 while ((s = s->next) != NULL) {
3710 if (s->v == tok)
3711 break;
3713 if (!s)
3714 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3715 /* add field offset to pointer */
3716 vtop->type = char_pointer_type; /* change type to 'char *' */
3717 vpushi(s->c);
3718 gen_op('+');
3719 /* change type to field type, and set to lvalue */
3720 vtop->type = s->type;
3721 vtop->type.t |= qualifiers;
3722 /* an array is never an lvalue */
3723 if (!(vtop->type.t & VT_ARRAY)) {
3724 vtop->r |= lvalue_type(vtop->type.t);
3725 #ifdef CONFIG_TCC_BCHECK
3726 /* if bound checking, the referenced pointer must be checked */
3727 if (tcc_state->do_bounds_check)
3728 vtop->r |= VT_MUSTBOUND;
3729 #endif
3731 next();
3732 } else if (tok == '[') {
3733 next();
3734 gexpr();
3735 gen_op('+');
3736 indir();
3737 skip(']');
3738 } else if (tok == '(') {
3739 SValue ret;
3740 Sym *sa;
3741 int nb_args;
3743 /* function call */
3744 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3745 /* pointer test (no array accepted) */
3746 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3747 vtop->type = *pointed_type(&vtop->type);
3748 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3749 goto error_func;
3750 } else {
3751 error_func:
3752 expect("function pointer");
3754 } else {
3755 vtop->r &= ~VT_LVAL; /* no lvalue */
3757 /* get return type */
3758 s = vtop->type.ref;
3759 next();
3760 sa = s->next; /* first parameter */
3761 nb_args = 0;
3762 ret.r2 = VT_CONST;
3763 /* compute first implicit argument if a structure is returned */
3764 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3765 /* get some space for the returned structure */
3766 size = type_size(&s->type, &align);
3767 loc = (loc - size) & -align;
3768 ret.type = s->type;
3769 ret.r = VT_LOCAL | VT_LVAL;
3770 /* pass it as 'int' to avoid structure arg passing
3771 problems */
3772 vseti(VT_LOCAL, loc);
3773 ret.c = vtop->c;
3774 nb_args++;
3775 } else {
3776 ret.type = s->type;
3777 /* return in register */
3778 if (is_float(ret.type.t)) {
3779 ret.r = reg_fret(ret.type.t);
3780 } else {
3781 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3782 ret.r2 = REG_LRET;
3783 ret.r = REG_IRET;
3785 ret.c.i = 0;
3787 if (tok != ')') {
3788 for(;;) {
3789 expr_eq();
3790 gfunc_param_typed(s, sa);
3791 nb_args++;
3792 if (sa)
3793 sa = sa->next;
3794 if (tok == ')')
3795 break;
3796 skip(',');
3799 if (sa)
3800 error("too few arguments to function");
3801 skip(')');
3802 if (!nocode_wanted) {
3803 gfunc_call(nb_args);
3804 } else {
3805 vtop -= (nb_args + 1);
3807 /* return value */
3808 vsetc(&ret.type, ret.r, &ret.c);
3809 vtop->r2 = ret.r2;
3810 } else {
3811 break;
3816 ST_FUNC void expr_prod(void)
3818 int t;
3820 unary();
3821 while (tok == '*' || tok == '/' || tok == '%') {
3822 t = tok;
3823 next();
3824 unary();
3825 gen_op(t);
3829 ST_FUNC void expr_sum(void)
3831 int t;
3833 expr_prod();
3834 while (tok == '+' || tok == '-') {
3835 t = tok;
3836 next();
3837 expr_prod();
3838 gen_op(t);
3842 static void expr_shift(void)
3844 int t;
3846 expr_sum();
3847 while (tok == TOK_SHL || tok == TOK_SAR) {
3848 t = tok;
3849 next();
3850 expr_sum();
3851 gen_op(t);
3855 static void expr_cmp(void)
3857 int t;
3859 expr_shift();
3860 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3861 tok == TOK_ULT || tok == TOK_UGE) {
3862 t = tok;
3863 next();
3864 expr_shift();
3865 gen_op(t);
3869 static void expr_cmpeq(void)
3871 int t;
3873 expr_cmp();
3874 while (tok == TOK_EQ || tok == TOK_NE) {
3875 t = tok;
3876 next();
3877 expr_cmp();
3878 gen_op(t);
3882 static void expr_and(void)
3884 expr_cmpeq();
3885 while (tok == '&') {
3886 next();
3887 expr_cmpeq();
3888 gen_op('&');
3892 static void expr_xor(void)
3894 expr_and();
3895 while (tok == '^') {
3896 next();
3897 expr_and();
3898 gen_op('^');
3902 static void expr_or(void)
3904 expr_xor();
3905 while (tok == '|') {
3906 next();
3907 expr_xor();
3908 gen_op('|');
3912 /* XXX: fix this mess */
3913 static void expr_land_const(void)
3915 expr_or();
3916 while (tok == TOK_LAND) {
3917 next();
3918 expr_or();
3919 gen_op(TOK_LAND);
3923 /* XXX: fix this mess */
3924 static void expr_lor_const(void)
3926 expr_land_const();
3927 while (tok == TOK_LOR) {
3928 next();
3929 expr_land_const();
3930 gen_op(TOK_LOR);
3934 /* only used if non constant */
3935 static void expr_land(void)
3937 int t;
3939 expr_or();
3940 if (tok == TOK_LAND) {
3941 t = 0;
3942 save_regs(1);
3943 for(;;) {
3944 t = gtst(1, t);
3945 if (tok != TOK_LAND) {
3946 vseti(VT_JMPI, t);
3947 break;
3949 next();
3950 expr_or();
3955 static void expr_lor(void)
3957 int t;
3959 expr_land();
3960 if (tok == TOK_LOR) {
3961 t = 0;
3962 save_regs(1);
3963 for(;;) {
3964 t = gtst(0, t);
3965 if (tok != TOK_LOR) {
3966 vseti(VT_JMP, t);
3967 break;
3969 next();
3970 expr_land();
3975 /* XXX: better constant handling */
3976 static void expr_cond(void)
3978 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
3979 SValue sv;
3980 CType type, type1, type2;
3982 if (const_wanted) {
3983 expr_lor_const();
3984 if (tok == '?') {
3985 CType boolean;
3986 int c;
3987 boolean.t = VT_BOOL;
3988 vdup();
3989 gen_cast(&boolean);
3990 c = vtop->c.i;
3991 vpop();
3992 next();
3993 if (tok != ':' || !gnu_ext) {
3994 vpop();
3995 gexpr();
3997 if (!c)
3998 vpop();
3999 skip(':');
4000 expr_cond();
4001 if (c)
4002 vpop();
4004 } else {
4005 expr_lor();
4006 if (tok == '?') {
4007 next();
4008 if (vtop != vstack) {
4009 /* needed to avoid having different registers saved in
4010 each branch */
4011 if (is_float(vtop->type.t)) {
4012 rc = RC_FLOAT;
4013 #ifdef TCC_TARGET_X86_64
4014 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4015 rc = RC_ST0;
4017 #endif
4019 else
4020 rc = RC_INT;
4021 gv(rc);
4022 save_regs(1);
4024 if (tok == ':' && gnu_ext) {
4025 gv_dup();
4026 tt = gtst(1, 0);
4027 } else {
4028 tt = gtst(1, 0);
4029 gexpr();
4031 type1 = vtop->type;
4032 sv = *vtop; /* save value to handle it later */
4033 vtop--; /* no vpop so that FP stack is not flushed */
4034 skip(':');
4035 u = gjmp(0);
4036 gsym(tt);
4037 expr_cond();
4038 type2 = vtop->type;
4040 t1 = type1.t;
4041 bt1 = t1 & VT_BTYPE;
4042 t2 = type2.t;
4043 bt2 = t2 & VT_BTYPE;
4044 /* cast operands to correct type according to ISOC rules */
4045 if (is_float(bt1) || is_float(bt2)) {
4046 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4047 type.t = VT_LDOUBLE;
4048 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4049 type.t = VT_DOUBLE;
4050 } else {
4051 type.t = VT_FLOAT;
4053 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4054 /* cast to biggest op */
4055 type.t = VT_LLONG;
4056 /* convert to unsigned if it does not fit in a long long */
4057 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4058 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4059 type.t |= VT_UNSIGNED;
4060 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4061 /* XXX: test pointer compatibility */
4062 type = type1;
4063 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4064 /* XXX: test function pointer compatibility */
4065 type = type1;
4066 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4067 /* XXX: test structure compatibility */
4068 type = type1;
4069 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4070 /* NOTE: as an extension, we accept void on only one side */
4071 type.t = VT_VOID;
4072 } else {
4073 /* integer operations */
4074 type.t = VT_INT;
4075 /* convert to unsigned if it does not fit in an integer */
4076 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4077 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4078 type.t |= VT_UNSIGNED;
4081 /* now we convert second operand */
4082 gen_cast(&type);
4083 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4084 gaddrof();
4085 rc = RC_INT;
4086 if (is_float(type.t)) {
4087 rc = RC_FLOAT;
4088 #ifdef TCC_TARGET_X86_64
4089 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4090 rc = RC_ST0;
4092 #endif
4093 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4094 /* for long longs, we use fixed registers to avoid having
4095 to handle a complicated move */
4096 rc = RC_IRET;
4099 r2 = gv(rc);
4100 /* this is horrible, but we must also convert first
4101 operand */
4102 tt = gjmp(0);
4103 gsym(u);
4104 /* put again first value and cast it */
4105 *vtop = sv;
4106 gen_cast(&type);
4107 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4108 gaddrof();
4109 r1 = gv(rc);
4110 move_reg(r2, r1);
4111 vtop->r = r2;
4112 gsym(tt);
4117 static void expr_eq(void)
4119 int t;
4121 expr_cond();
4122 if (tok == '=' ||
4123 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4124 tok == TOK_A_XOR || tok == TOK_A_OR ||
4125 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4126 test_lvalue();
4127 t = tok;
4128 next();
4129 if (t == '=') {
4130 expr_eq();
4131 } else {
4132 vdup();
4133 expr_eq();
4134 gen_op(t & 0x7f);
4136 vstore();
4140 ST_FUNC void gexpr(void)
4142 while (1) {
4143 expr_eq();
4144 if (tok != ',')
4145 break;
4146 vpop();
4147 next();
4151 /* parse an expression and return its type without any side effect. */
4152 static void expr_type(CType *type)
4154 int saved_nocode_wanted;
4156 saved_nocode_wanted = nocode_wanted;
4157 nocode_wanted = 1;
4158 gexpr();
4159 *type = vtop->type;
4160 vpop();
4161 nocode_wanted = saved_nocode_wanted;
4164 /* parse a unary expression and return its type without any side
4165 effect. */
4166 static void unary_type(CType *type)
4168 int a;
4170 a = nocode_wanted;
4171 nocode_wanted = 1;
4172 unary();
4173 *type = vtop->type;
4174 vpop();
4175 nocode_wanted = a;
4178 /* parse a constant expression and return value in vtop. */
4179 static void expr_const1(void)
4181 int a;
4182 a = const_wanted;
4183 const_wanted = 1;
4184 expr_cond();
4185 const_wanted = a;
4188 /* parse an integer constant and return its value. */
4189 ST_FUNC int expr_const(void)
4191 int c;
4192 expr_const1();
4193 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4194 expect("constant expression");
4195 c = vtop->c.i;
4196 vpop();
4197 return c;
4200 /* return the label token if current token is a label, otherwise
4201 return zero */
4202 static int is_label(void)
4204 int last_tok;
4206 /* fast test first */
4207 if (tok < TOK_UIDENT)
4208 return 0;
4209 /* no need to save tokc because tok is an identifier */
4210 last_tok = tok;
4211 next();
4212 if (tok == ':') {
4213 next();
4214 return last_tok;
4215 } else {
4216 unget_tok(last_tok);
4217 return 0;
4221 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4222 int case_reg, int is_expr)
4224 int a, b, c, d;
4225 Sym *s;
4227 /* generate line number info */
4228 if (tcc_state->do_debug &&
4229 (last_line_num != file->line_num || last_ind != ind)) {
4230 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4231 last_ind = ind;
4232 last_line_num = file->line_num;
4235 if (is_expr) {
4236 /* default return value is (void) */
4237 vpushi(0);
4238 vtop->type.t = VT_VOID;
4241 if (tok == TOK_IF) {
4242 /* if test */
4243 next();
4244 skip('(');
4245 gexpr();
4246 skip(')');
4247 a = gtst(1, 0);
4248 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4249 c = tok;
4250 if (c == TOK_ELSE) {
4251 next();
4252 d = gjmp(0);
4253 gsym(a);
4254 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4255 gsym(d); /* patch else jmp */
4256 } else
4257 gsym(a);
4258 } else if (tok == TOK_WHILE) {
4259 next();
4260 d = ind;
4261 skip('(');
4262 gexpr();
4263 skip(')');
4264 a = gtst(1, 0);
4265 b = 0;
4266 block(&a, &b, case_sym, def_sym, case_reg, 0);
4267 gjmp_addr(d);
4268 gsym(a);
4269 gsym_addr(b, d);
4270 } else if (tok == '{') {
4271 Sym *llabel;
4273 next();
4274 /* record local declaration stack position */
4275 s = local_stack;
4276 llabel = local_label_stack;
4277 /* handle local labels declarations */
4278 if (tok == TOK_LABEL) {
4279 next();
4280 for(;;) {
4281 if (tok < TOK_UIDENT)
4282 expect("label identifier");
4283 label_push(&local_label_stack, tok, LABEL_DECLARED);
4284 next();
4285 if (tok == ',') {
4286 next();
4287 } else {
4288 skip(';');
4289 break;
4293 while (tok != '}') {
4294 decl(VT_LOCAL);
4295 if (tok != '}') {
4296 if (is_expr)
4297 vpop();
4298 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4301 /* pop locally defined labels */
4302 label_pop(&local_label_stack, llabel);
4303 /* pop locally defined symbols */
4304 if(is_expr) {
4305 /* XXX: this solution makes only valgrind happy...
4306 triggered by gcc.c-torture/execute/20000917-1.c */
4307 Sym *p;
4308 switch(vtop->type.t & VT_BTYPE) {
4309 case VT_PTR:
4310 case VT_STRUCT:
4311 case VT_ENUM:
4312 case VT_FUNC:
4313 for(p=vtop->type.ref;p;p=p->prev)
4314 if(p->prev==s)
4315 error("unsupported expression type");
4318 sym_pop(&local_stack, s);
4319 next();
4320 } else if (tok == TOK_RETURN) {
4321 next();
4322 if (tok != ';') {
4323 gexpr();
4324 gen_assign_cast(&func_vt);
4325 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4326 CType type;
4327 /* if returning structure, must copy it to implicit
4328 first pointer arg location */
4329 #ifdef TCC_ARM_EABI
4330 int align, size;
4331 size = type_size(&func_vt,&align);
4332 if(size <= 4)
4334 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4335 && (align & 3))
4337 int addr;
4338 loc = (loc - size) & -4;
4339 addr = loc;
4340 type = func_vt;
4341 vset(&type, VT_LOCAL | VT_LVAL, addr);
4342 vswap();
4343 vstore();
4344 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4346 vtop->type = int_type;
4347 gv(RC_IRET);
4348 } else {
4349 #endif
4350 type = func_vt;
4351 mk_pointer(&type);
4352 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4353 indir();
4354 vswap();
4355 /* copy structure value to pointer */
4356 vstore();
4357 #ifdef TCC_ARM_EABI
4359 #endif
4360 } else if (is_float(func_vt.t)) {
4361 gv(rc_fret(func_vt.t));
4362 } else {
4363 gv(RC_IRET);
4365 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4367 skip(';');
4368 rsym = gjmp(rsym); /* jmp */
4369 } else if (tok == TOK_BREAK) {
4370 /* compute jump */
4371 if (!bsym)
4372 error("cannot break");
4373 *bsym = gjmp(*bsym);
4374 next();
4375 skip(';');
4376 } else if (tok == TOK_CONTINUE) {
4377 /* compute jump */
4378 if (!csym)
4379 error("cannot continue");
4380 *csym = gjmp(*csym);
4381 next();
4382 skip(';');
4383 } else if (tok == TOK_FOR) {
4384 int e;
4385 next();
4386 skip('(');
4387 if (tok != ';') {
4388 /* c99 for-loop init decl? */
4389 if (!decl0(VT_LOCAL, 1)) {
4390 /* no, regular for-loop init expr */
4391 gexpr();
4392 vpop();
4395 skip(';');
4396 d = ind;
4397 c = ind;
4398 a = 0;
4399 b = 0;
4400 if (tok != ';') {
4401 gexpr();
4402 a = gtst(1, 0);
4404 skip(';');
4405 if (tok != ')') {
4406 e = gjmp(0);
4407 c = ind;
4408 gexpr();
4409 vpop();
4410 gjmp_addr(d);
4411 gsym(e);
4413 skip(')');
4414 block(&a, &b, case_sym, def_sym, case_reg, 0);
4415 gjmp_addr(c);
4416 gsym(a);
4417 gsym_addr(b, c);
4418 } else
4419 if (tok == TOK_DO) {
4420 next();
4421 a = 0;
4422 b = 0;
4423 d = ind;
4424 block(&a, &b, case_sym, def_sym, case_reg, 0);
4425 skip(TOK_WHILE);
4426 skip('(');
4427 gsym(b);
4428 gexpr();
4429 c = gtst(0, 0);
4430 gsym_addr(c, d);
4431 skip(')');
4432 gsym(a);
4433 skip(';');
4434 } else
4435 if (tok == TOK_SWITCH) {
4436 next();
4437 skip('(');
4438 gexpr();
4439 /* XXX: other types than integer */
4440 case_reg = gv(RC_INT);
4441 vpop();
4442 skip(')');
4443 a = 0;
4444 b = gjmp(0); /* jump to first case */
4445 c = 0;
4446 block(&a, csym, &b, &c, case_reg, 0);
4447 /* if no default, jmp after switch */
4448 if (c == 0)
4449 c = ind;
4450 /* default label */
4451 gsym_addr(b, c);
4452 /* break label */
4453 gsym(a);
4454 } else
4455 if (tok == TOK_CASE) {
4456 int v1, v2;
4457 if (!case_sym)
4458 expect("switch");
4459 next();
4460 v1 = expr_const();
4461 v2 = v1;
4462 if (gnu_ext && tok == TOK_DOTS) {
4463 next();
4464 v2 = expr_const();
4465 if (v2 < v1)
4466 warning("empty case range");
4468 /* since a case is like a label, we must skip it with a jmp */
4469 b = gjmp(0);
4470 gsym(*case_sym);
4471 vseti(case_reg, 0);
4472 vpushi(v1);
4473 if (v1 == v2) {
4474 gen_op(TOK_EQ);
4475 *case_sym = gtst(1, 0);
4476 } else {
4477 gen_op(TOK_GE);
4478 *case_sym = gtst(1, 0);
4479 vseti(case_reg, 0);
4480 vpushi(v2);
4481 gen_op(TOK_LE);
4482 *case_sym = gtst(1, *case_sym);
4484 gsym(b);
4485 skip(':');
4486 is_expr = 0;
4487 goto block_after_label;
4488 } else
4489 if (tok == TOK_DEFAULT) {
4490 next();
4491 skip(':');
4492 if (!def_sym)
4493 expect("switch");
4494 if (*def_sym)
4495 error("too many 'default'");
4496 *def_sym = ind;
4497 is_expr = 0;
4498 goto block_after_label;
4499 } else
4500 if (tok == TOK_GOTO) {
4501 next();
4502 if (tok == '*' && gnu_ext) {
4503 /* computed goto */
4504 next();
4505 gexpr();
4506 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4507 expect("pointer");
4508 ggoto();
4509 } else if (tok >= TOK_UIDENT) {
4510 s = label_find(tok);
4511 /* put forward definition if needed */
4512 if (!s) {
4513 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4514 } else {
4515 if (s->r == LABEL_DECLARED)
4516 s->r = LABEL_FORWARD;
4518 /* label already defined */
4519 if (s->r & LABEL_FORWARD)
4520 s->jnext = gjmp(s->jnext);
4521 else
4522 gjmp_addr(s->jnext);
4523 next();
4524 } else {
4525 expect("label identifier");
4527 skip(';');
4528 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4529 asm_instr();
4530 } else {
4531 b = is_label();
4532 if (b) {
4533 /* label case */
4534 s = label_find(b);
4535 if (s) {
4536 if (s->r == LABEL_DEFINED)
4537 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4538 gsym(s->jnext);
4539 s->r = LABEL_DEFINED;
4540 } else {
4541 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4543 s->jnext = ind;
4544 /* we accept this, but it is a mistake */
4545 block_after_label:
4546 if (tok == '}') {
4547 warning("deprecated use of label at end of compound statement");
4548 } else {
4549 if (is_expr)
4550 vpop();
4551 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4553 } else {
4554 /* expression case */
4555 if (tok != ';') {
4556 if (is_expr) {
4557 vpop();
4558 gexpr();
4559 } else {
4560 gexpr();
4561 vpop();
4564 skip(';');
4569 /* t is the array or struct type. c is the array or struct
4570 address. cur_index/cur_field is the pointer to the current
4571 value. 'size_only' is true if only size info is needed (only used
4572 in arrays) */
4573 static void decl_designator(CType *type, Section *sec, unsigned long c,
4574 int *cur_index, Sym **cur_field,
4575 int size_only)
4577 Sym *s, *f;
4578 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4579 CType type1;
4581 notfirst = 0;
4582 elem_size = 0;
4583 nb_elems = 1;
4584 if (gnu_ext && (l = is_label()) != 0)
4585 goto struct_field;
4586 while (tok == '[' || tok == '.') {
4587 if (tok == '[') {
4588 if (!(type->t & VT_ARRAY))
4589 expect("array type");
4590 s = type->ref;
4591 next();
4592 index = expr_const();
4593 if (index < 0 || (s->c >= 0 && index >= s->c))
4594 expect("invalid index");
4595 if (tok == TOK_DOTS && gnu_ext) {
4596 next();
4597 index_last = expr_const();
4598 if (index_last < 0 ||
4599 (s->c >= 0 && index_last >= s->c) ||
4600 index_last < index)
4601 expect("invalid index");
4602 } else {
4603 index_last = index;
4605 skip(']');
4606 if (!notfirst)
4607 *cur_index = index_last;
4608 type = pointed_type(type);
4609 elem_size = type_size(type, &align);
4610 c += index * elem_size;
4611 /* NOTE: we only support ranges for last designator */
4612 nb_elems = index_last - index + 1;
4613 if (nb_elems != 1) {
4614 notfirst = 1;
4615 break;
4617 } else {
4618 next();
4619 l = tok;
4620 next();
4621 struct_field:
4622 if ((type->t & VT_BTYPE) != VT_STRUCT)
4623 expect("struct/union type");
4624 s = type->ref;
4625 l |= SYM_FIELD;
4626 f = s->next;
4627 while (f) {
4628 if (f->v == l)
4629 break;
4630 f = f->next;
4632 if (!f)
4633 expect("field");
4634 if (!notfirst)
4635 *cur_field = f;
4636 /* XXX: fix this mess by using explicit storage field */
4637 type1 = f->type;
4638 type1.t |= (type->t & ~VT_TYPE);
4639 type = &type1;
4640 c += f->c;
4642 notfirst = 1;
4644 if (notfirst) {
4645 if (tok == '=') {
4646 next();
4647 } else {
4648 if (!gnu_ext)
4649 expect("=");
4651 } else {
4652 if (type->t & VT_ARRAY) {
4653 index = *cur_index;
4654 type = pointed_type(type);
4655 c += index * type_size(type, &align);
4656 } else {
4657 f = *cur_field;
4658 if (!f)
4659 error("too many field init");
4660 /* XXX: fix this mess by using explicit storage field */
4661 type1 = f->type;
4662 type1.t |= (type->t & ~VT_TYPE);
4663 type = &type1;
4664 c += f->c;
4667 decl_initializer(type, sec, c, 0, size_only);
4669 /* XXX: make it more general */
4670 if (!size_only && nb_elems > 1) {
4671 unsigned long c_end;
4672 uint8_t *src, *dst;
4673 int i;
4675 if (!sec)
4676 error("range init not supported yet for dynamic storage");
4677 c_end = c + nb_elems * elem_size;
4678 if (c_end > sec->data_allocated)
4679 section_realloc(sec, c_end);
4680 src = sec->data + c;
4681 dst = src;
4682 for(i = 1; i < nb_elems; i++) {
4683 dst += elem_size;
4684 memcpy(dst, src, elem_size);
4689 #define EXPR_VAL 0
4690 #define EXPR_CONST 1
4691 #define EXPR_ANY 2
4693 /* store a value or an expression directly in global data or in local array */
4694 static void init_putv(CType *type, Section *sec, unsigned long c,
4695 int v, int expr_type)
4697 int saved_global_expr, bt, bit_pos, bit_size;
4698 void *ptr;
4699 unsigned long long bit_mask;
4700 CType dtype;
4702 switch(expr_type) {
4703 case EXPR_VAL:
4704 vpushi(v);
4705 break;
4706 case EXPR_CONST:
4707 /* compound literals must be allocated globally in this case */
4708 saved_global_expr = global_expr;
4709 global_expr = 1;
4710 expr_const1();
4711 global_expr = saved_global_expr;
4712 /* NOTE: symbols are accepted */
4713 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4714 error("initializer element is not constant");
4715 break;
4716 case EXPR_ANY:
4717 expr_eq();
4718 break;
4721 dtype = *type;
4722 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4724 if (sec) {
4725 /* XXX: not portable */
4726 /* XXX: generate error if incorrect relocation */
4727 gen_assign_cast(&dtype);
4728 bt = type->t & VT_BTYPE;
4729 /* we'll write at most 12 bytes */
4730 if (c + 12 > sec->data_allocated) {
4731 section_realloc(sec, c + 12);
4733 ptr = sec->data + c;
4734 /* XXX: make code faster ? */
4735 if (!(type->t & VT_BITFIELD)) {
4736 bit_pos = 0;
4737 bit_size = 32;
4738 bit_mask = -1LL;
4739 } else {
4740 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4741 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4742 bit_mask = (1LL << bit_size) - 1;
4744 if ((vtop->r & VT_SYM) &&
4745 (bt == VT_BYTE ||
4746 bt == VT_SHORT ||
4747 bt == VT_DOUBLE ||
4748 bt == VT_LDOUBLE ||
4749 bt == VT_LLONG ||
4750 (bt == VT_INT && bit_size != 32)))
4751 error("initializer element is not computable at load time");
4752 switch(bt) {
4753 case VT_BOOL:
4754 vtop->c.i = (vtop->c.i != 0);
4755 case VT_BYTE:
4756 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4757 break;
4758 case VT_SHORT:
4759 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4760 break;
4761 case VT_DOUBLE:
4762 *(double *)ptr = vtop->c.d;
4763 break;
4764 case VT_LDOUBLE:
4765 *(long double *)ptr = vtop->c.ld;
4766 break;
4767 case VT_LLONG:
4768 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4769 break;
4770 default:
4771 if (vtop->r & VT_SYM) {
4772 greloc(sec, vtop->sym, c, R_DATA_PTR);
4774 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4775 break;
4777 vtop--;
4778 } else {
4779 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4780 vswap();
4781 vstore();
4782 vpop();
4786 /* put zeros for variable based init */
4787 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4789 if (sec) {
4790 /* nothing to do because globals are already set to zero */
4791 } else {
4792 vpush_global_sym(&func_old_type, TOK_memset);
4793 vseti(VT_LOCAL, c);
4794 vpushi(0);
4795 vpushi(size);
4796 gfunc_call(3);
4800 /* 't' contains the type and storage info. 'c' is the offset of the
4801 object in section 'sec'. If 'sec' is NULL, it means stack based
4802 allocation. 'first' is true if array '{' must be read (multi
4803 dimension implicit array init handling). 'size_only' is true if
4804 size only evaluation is wanted (only for arrays). */
4805 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4806 int first, int size_only)
4808 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
4809 int size1, align1, expr_type;
4810 Sym *s, *f;
4811 CType *t1;
4813 if (type->t & VT_ARRAY) {
4814 s = type->ref;
4815 n = s->c;
4816 array_length = 0;
4817 t1 = pointed_type(type);
4818 size1 = type_size(t1, &align1);
4820 no_oblock = 1;
4821 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4822 tok == '{') {
4823 if (tok != '{')
4824 error("character array initializer must be a literal,"
4825 " optionally enclosed in braces");
4826 skip('{');
4827 no_oblock = 0;
4830 /* only parse strings here if correct type (otherwise: handle
4831 them as ((w)char *) expressions */
4832 if ((tok == TOK_LSTR &&
4833 #ifdef TCC_TARGET_PE
4834 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4835 #else
4836 (t1->t & VT_BTYPE) == VT_INT
4837 #endif
4838 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4839 while (tok == TOK_STR || tok == TOK_LSTR) {
4840 int cstr_len, ch;
4841 CString *cstr;
4843 cstr = tokc.cstr;
4844 /* compute maximum number of chars wanted */
4845 if (tok == TOK_STR)
4846 cstr_len = cstr->size;
4847 else
4848 cstr_len = cstr->size / sizeof(nwchar_t);
4849 cstr_len--;
4850 nb = cstr_len;
4851 if (n >= 0 && nb > (n - array_length))
4852 nb = n - array_length;
4853 if (!size_only) {
4854 if (cstr_len > nb)
4855 warning("initializer-string for array is too long");
4856 /* in order to go faster for common case (char
4857 string in global variable, we handle it
4858 specifically */
4859 if (sec && tok == TOK_STR && size1 == 1) {
4860 memcpy(sec->data + c + array_length, cstr->data, nb);
4861 } else {
4862 for(i=0;i<nb;i++) {
4863 if (tok == TOK_STR)
4864 ch = ((unsigned char *)cstr->data)[i];
4865 else
4866 ch = ((nwchar_t *)cstr->data)[i];
4867 init_putv(t1, sec, c + (array_length + i) * size1,
4868 ch, EXPR_VAL);
4872 array_length += nb;
4873 next();
4875 /* only add trailing zero if enough storage (no
4876 warning in this case since it is standard) */
4877 if (n < 0 || array_length < n) {
4878 if (!size_only) {
4879 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4881 array_length++;
4883 } else {
4884 index = 0;
4885 if (ARRAY_RESIZE(s->r))
4886 n = -1;
4887 while (tok != '}') {
4888 decl_designator(type, sec, c, &index, NULL, size_only);
4889 if (n >= 0 && index >= n)
4890 error("index too large");
4891 /* must put zero in holes (note that doing it that way
4892 ensures that it even works with designators) */
4893 if (!size_only && array_length < index) {
4894 init_putz(t1, sec, c + array_length * size1,
4895 (index - array_length) * size1);
4897 index++;
4898 if (index > array_length)
4899 array_length = index;
4900 /* special test for multi dimensional arrays (may not
4901 be strictly correct if designators are used at the
4902 same time) */
4903 if (index >= n && no_oblock)
4904 break;
4905 if (tok == '}')
4906 break;
4907 skip(',');
4910 if (!no_oblock)
4911 skip('}');
4912 /* put zeros at the end */
4913 if (!size_only && n >= 0 && array_length < n) {
4914 init_putz(t1, sec, c + array_length * size1,
4915 (n - array_length) * size1);
4917 /* patch type size if needed */
4918 if (n < 0)
4919 s->c = array_length;
4920 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4921 (sec || !first || tok == '{')) {
4922 int par_count;
4924 /* NOTE: the previous test is a specific case for automatic
4925 struct/union init */
4926 /* XXX: union needs only one init */
4928 /* XXX: this test is incorrect for local initializers
4929 beginning with ( without {. It would be much more difficult
4930 to do it correctly (ideally, the expression parser should
4931 be used in all cases) */
4932 par_count = 0;
4933 if (tok == '(') {
4934 AttributeDef ad1;
4935 CType type1;
4936 next();
4937 while (tok == '(') {
4938 par_count++;
4939 next();
4941 if (!parse_btype(&type1, &ad1))
4942 expect("cast");
4943 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4944 #if 0
4945 if (!is_assignable_types(type, &type1))
4946 error("invalid type for cast");
4947 #endif
4948 skip(')');
4950 no_oblock = 1;
4951 if (first || tok == '{') {
4952 skip('{');
4953 no_oblock = 0;
4955 s = type->ref;
4956 f = s->next;
4957 array_length = 0;
4958 index = 0;
4959 n = s->c;
4960 if (s->r & (1<<31))
4961 n = -1;
4962 while (tok != '}') {
4963 decl_designator(type, sec, c, NULL, &f, size_only);
4964 index = f->c;
4965 if (!size_only && array_length < index) {
4966 init_putz(type, sec, c + array_length,
4967 index - array_length);
4969 index = index + type_size(&f->type, &align1);
4970 if (index > array_length)
4971 array_length = index;
4973 /* gr: skip fields from same union - ugly. */
4974 while (f->next) {
4975 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
4976 /* test for same offset */
4977 if (f->next->c != f->c)
4978 break;
4979 /* if yes, test for bitfield shift */
4980 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
4981 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4982 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4983 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
4984 if (bit_pos_1 != bit_pos_2)
4985 break;
4987 f = f->next;
4990 f = f->next;
4991 if (no_oblock && f == NULL)
4992 break;
4993 if (tok == '}')
4994 break;
4995 skip(',');
4997 /* put zeros at the end */
4998 if (!size_only && n >= 0 && array_length < n) {
4999 init_putz(type, sec, c + array_length,
5000 n - array_length);
5002 if (!no_oblock)
5003 skip('}');
5004 while (par_count) {
5005 skip(')');
5006 par_count--;
5008 if (n < 0)
5009 s->c = array_length;
5010 } else if (tok == '{') {
5011 next();
5012 decl_initializer(type, sec, c, first, size_only);
5013 skip('}');
5014 } else if (size_only) {
5015 /* just skip expression */
5016 parlevel = parlevel1 = 0;
5017 while ((parlevel > 0 || parlevel1 > 0 ||
5018 (tok != '}' && tok != ',')) && tok != -1) {
5019 if (tok == '(')
5020 parlevel++;
5021 else if (tok == ')')
5022 parlevel--;
5023 else if (tok == '{')
5024 parlevel1++;
5025 else if (tok == '}')
5026 parlevel1--;
5027 next();
5029 } else {
5030 /* currently, we always use constant expression for globals
5031 (may change for scripting case) */
5032 expr_type = EXPR_CONST;
5033 if (!sec)
5034 expr_type = EXPR_ANY;
5035 init_putv(type, sec, c, 0, expr_type);
5039 /* parse an initializer for type 't' if 'has_init' is non zero, and
5040 allocate space in local or global data space ('r' is either
5041 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5042 variable 'v' with an associated name represented by 'asm_label' of
5043 scope 'scope' is declared before initializers are parsed. If 'v' is
5044 zero, then a reference to the new object is put in the value stack.
5045 If 'has_init' is 2, a special parsing is done to handle string
5046 constants. */
5047 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5048 int has_init, int v, char *asm_label,
5049 int scope)
5051 int size, align, addr, data_offset;
5052 int level;
5053 ParseState saved_parse_state = {0};
5054 TokenString init_str;
5055 Section *sec;
5057 /* resize the struct */
5058 if ((type->t & VT_BTYPE) == VT_STRUCT && (type->ref->r & (1<<31)) != 0)
5059 type->ref->c = -1;
5060 size = type_size(type, &align);
5061 /* If unknown size, we must evaluate it before
5062 evaluating initializers because
5063 initializers can generate global data too
5064 (e.g. string pointers or ISOC99 compound
5065 literals). It also simplifies local
5066 initializers handling */
5067 tok_str_new(&init_str);
5068 if (size < 0) {
5069 if (!has_init)
5070 error("unknown type size");
5071 /* get all init string */
5072 if (has_init == 2) {
5073 /* only get strings */
5074 while (tok == TOK_STR || tok == TOK_LSTR) {
5075 tok_str_add_tok(&init_str);
5076 next();
5078 } else {
5079 level = 0;
5080 while (level > 0 || (tok != ',' && tok != ';')) {
5081 if (tok < 0)
5082 error("unexpected end of file in initializer");
5083 tok_str_add_tok(&init_str);
5084 if (tok == '{')
5085 level++;
5086 else if (tok == '}') {
5087 level--;
5088 if (level <= 0) {
5089 next();
5090 break;
5093 next();
5096 tok_str_add(&init_str, -1);
5097 tok_str_add(&init_str, 0);
5099 /* compute size */
5100 save_parse_state(&saved_parse_state);
5102 macro_ptr = init_str.str;
5103 next();
5104 decl_initializer(type, NULL, 0, 1, 1);
5105 /* prepare second initializer parsing */
5106 macro_ptr = init_str.str;
5107 next();
5109 /* if still unknown size, error */
5110 size = type_size(type, &align);
5111 if (size < 0)
5112 error("unknown type size");
5114 /* take into account specified alignment if bigger */
5115 if (ad->aligned) {
5116 if (ad->aligned > align)
5117 align = ad->aligned;
5118 } else if (ad->packed) {
5119 align = 1;
5121 if ((r & VT_VALMASK) == VT_LOCAL) {
5122 sec = NULL;
5123 #ifdef CONFIG_TCC_BCHECK
5124 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
5125 loc--;
5126 #endif
5127 loc = (loc - size) & -align;
5128 addr = loc;
5129 #ifdef CONFIG_TCC_BCHECK
5130 /* handles bounds */
5131 /* XXX: currently, since we do only one pass, we cannot track
5132 '&' operators, so we add only arrays */
5133 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5134 unsigned long *bounds_ptr;
5135 /* add padding between regions */
5136 loc--;
5137 /* then add local bound info */
5138 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5139 bounds_ptr[0] = addr;
5140 bounds_ptr[1] = size;
5142 #endif
5143 if (v) {
5144 /* local variable */
5145 sym_push(v, type, r, addr);
5146 } else {
5147 /* push local reference */
5148 vset(type, r, addr);
5150 } else {
5151 Sym *sym;
5153 sym = NULL;
5154 if (v && scope == VT_CONST) {
5155 /* see if the symbol was already defined */
5156 sym = sym_find(v);
5157 if (sym) {
5158 if (!is_compatible_types(&sym->type, type))
5159 error("incompatible types for redefinition of '%s'",
5160 get_tok_str(v, NULL));
5161 if (sym->type.t & VT_EXTERN) {
5162 /* if the variable is extern, it was not allocated */
5163 sym->type.t &= ~VT_EXTERN;
5164 /* set array size if it was ommited in extern
5165 declaration */
5166 if ((sym->type.t & VT_ARRAY) &&
5167 sym->type.ref->c < 0 &&
5168 type->ref->c >= 0)
5169 sym->type.ref->c = type->ref->c;
5170 } else {
5171 /* we accept several definitions of the same
5172 global variable. this is tricky, because we
5173 must play with the SHN_COMMON type of the symbol */
5174 /* XXX: should check if the variable was already
5175 initialized. It is incorrect to initialized it
5176 twice */
5177 /* no init data, we won't add more to the symbol */
5178 if (!has_init)
5179 goto no_alloc;
5184 /* allocate symbol in corresponding section */
5185 sec = ad->section;
5186 if (!sec) {
5187 if (has_init)
5188 sec = data_section;
5189 else if (tcc_state->nocommon)
5190 sec = bss_section;
5192 if (sec) {
5193 data_offset = sec->data_offset;
5194 data_offset = (data_offset + align - 1) & -align;
5195 addr = data_offset;
5196 /* very important to increment global pointer at this time
5197 because initializers themselves can create new initializers */
5198 data_offset += size;
5199 #ifdef CONFIG_TCC_BCHECK
5200 /* add padding if bound check */
5201 if (tcc_state->do_bounds_check)
5202 data_offset++;
5203 #endif
5204 sec->data_offset = data_offset;
5205 /* allocate section space to put the data */
5206 if (sec->sh_type != SHT_NOBITS &&
5207 data_offset > sec->data_allocated)
5208 section_realloc(sec, data_offset);
5209 /* align section if needed */
5210 if (align > sec->sh_addralign)
5211 sec->sh_addralign = align;
5212 } else {
5213 addr = 0; /* avoid warning */
5216 if (v) {
5217 if (scope != VT_CONST || !sym) {
5218 sym = sym_push(v, type, r | VT_SYM, 0);
5219 sym->asm_label = asm_label;
5221 /* update symbol definition */
5222 if (sec) {
5223 put_extern_sym(sym, sec, addr, size);
5224 } else {
5225 ElfW(Sym) *esym;
5226 /* put a common area */
5227 put_extern_sym(sym, NULL, align, size);
5228 /* XXX: find a nicer way */
5229 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5230 esym->st_shndx = SHN_COMMON;
5232 } else {
5233 CValue cval;
5235 /* push global reference */
5236 sym = get_sym_ref(type, sec, addr, size);
5237 cval.ul = 0;
5238 vsetc(type, VT_CONST | VT_SYM, &cval);
5239 vtop->sym = sym;
5241 /* patch symbol weakness */
5242 if (type->t & VT_WEAK)
5243 weaken_symbol(sym);
5244 #ifdef CONFIG_TCC_BCHECK
5245 /* handles bounds now because the symbol must be defined
5246 before for the relocation */
5247 if (tcc_state->do_bounds_check) {
5248 unsigned long *bounds_ptr;
5250 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5251 /* then add global bound info */
5252 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5253 bounds_ptr[0] = 0; /* relocated */
5254 bounds_ptr[1] = size;
5256 #endif
5258 if (has_init) {
5259 decl_initializer(type, sec, addr, 1, 0);
5260 /* restore parse state if needed */
5261 if (init_str.str) {
5262 tok_str_free(init_str.str);
5263 restore_parse_state(&saved_parse_state);
5266 no_alloc: ;
5269 static void put_func_debug(Sym *sym)
5271 char buf[512];
5273 /* stabs info */
5274 /* XXX: we put here a dummy type */
5275 snprintf(buf, sizeof(buf), "%s:%c1",
5276 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5277 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5278 cur_text_section, sym->c);
5279 /* //gr gdb wants a line at the function */
5280 put_stabn(N_SLINE, 0, file->line_num, 0);
5281 last_ind = 0;
5282 last_line_num = 0;
5285 /* parse an old style function declaration list */
5286 /* XXX: check multiple parameter */
5287 static void func_decl_list(Sym *func_sym)
5289 AttributeDef ad;
5290 int v;
5291 Sym *s;
5292 CType btype, type;
5294 /* parse each declaration */
5295 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5296 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5297 if (!parse_btype(&btype, &ad))
5298 expect("declaration list");
5299 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5300 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5301 tok == ';') {
5302 /* we accept no variable after */
5303 } else {
5304 for(;;) {
5305 type = btype;
5306 type_decl(&type, &ad, &v, TYPE_DIRECT);
5307 /* find parameter in function parameter list */
5308 s = func_sym->next;
5309 while (s != NULL) {
5310 if ((s->v & ~SYM_FIELD) == v)
5311 goto found;
5312 s = s->next;
5314 error("declaration for parameter '%s' but no such parameter",
5315 get_tok_str(v, NULL));
5316 found:
5317 /* check that no storage specifier except 'register' was given */
5318 if (type.t & VT_STORAGE)
5319 error("storage class specified for '%s'", get_tok_str(v, NULL));
5320 convert_parameter_type(&type);
5321 /* we can add the type (NOTE: it could be local to the function) */
5322 s->type = type;
5323 /* accept other parameters */
5324 if (tok == ',')
5325 next();
5326 else
5327 break;
5330 skip(';');
5334 /* parse a function defined by symbol 'sym' and generate its code in
5335 'cur_text_section' */
5336 static void gen_function(Sym *sym)
5338 int saved_nocode_wanted = nocode_wanted;
5339 nocode_wanted = 0;
5340 ind = cur_text_section->data_offset;
5341 /* NOTE: we patch the symbol size later */
5342 put_extern_sym(sym, cur_text_section, ind, 0);
5343 funcname = get_tok_str(sym->v, NULL);
5344 func_ind = ind;
5345 /* put debug symbol */
5346 if (tcc_state->do_debug)
5347 put_func_debug(sym);
5348 /* push a dummy symbol to enable local sym storage */
5349 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5350 gfunc_prolog(&sym->type);
5351 rsym = 0;
5352 block(NULL, NULL, NULL, NULL, 0, 0);
5353 gsym(rsym);
5354 gfunc_epilog();
5355 cur_text_section->data_offset = ind;
5356 label_pop(&global_label_stack, NULL);
5357 sym_pop(&local_stack, NULL); /* reset local stack */
5358 /* end of function */
5359 /* patch symbol size */
5360 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5361 ind - func_ind;
5362 /* patch symbol weakness (this definition overrules any prototype) */
5363 if (sym->type.t & VT_WEAK)
5364 weaken_symbol(sym);
5365 if (tcc_state->do_debug) {
5366 put_stabn(N_FUN, 0, 0, ind - func_ind);
5368 /* It's better to crash than to generate wrong code */
5369 cur_text_section = NULL;
5370 funcname = ""; /* for safety */
5371 func_vt.t = VT_VOID; /* for safety */
5372 ind = 0; /* for safety */
5373 nocode_wanted = saved_nocode_wanted;
5376 ST_FUNC void gen_inline_functions(void)
5378 Sym *sym;
5379 int *str, inline_generated, i;
5380 struct InlineFunc *fn;
5382 /* iterate while inline function are referenced */
5383 for(;;) {
5384 inline_generated = 0;
5385 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5386 fn = tcc_state->inline_fns[i];
5387 sym = fn->sym;
5388 if (sym && sym->c) {
5389 /* the function was used: generate its code and
5390 convert it to a normal function */
5391 str = fn->token_str;
5392 fn->sym = NULL;
5393 if (file)
5394 strcpy(file->filename, fn->filename);
5395 sym->r = VT_SYM | VT_CONST;
5396 sym->type.t &= ~VT_INLINE;
5398 macro_ptr = str;
5399 next();
5400 cur_text_section = text_section;
5401 gen_function(sym);
5402 macro_ptr = NULL; /* fail safe */
5404 inline_generated = 1;
5407 if (!inline_generated)
5408 break;
5410 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5411 fn = tcc_state->inline_fns[i];
5412 str = fn->token_str;
5413 tok_str_free(str);
5415 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5418 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5419 static int decl0(int l, int is_for_loop_init)
5421 int v, has_init, r;
5422 CType type, btype;
5423 Sym *sym;
5424 AttributeDef ad;
5426 while (1) {
5427 if (!parse_btype(&btype, &ad)) {
5428 if (is_for_loop_init)
5429 return 0;
5430 /* skip redundant ';' */
5431 /* XXX: find more elegant solution */
5432 if (tok == ';') {
5433 next();
5434 continue;
5436 if (l == VT_CONST &&
5437 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5438 /* global asm block */
5439 asm_global_instr();
5440 continue;
5442 /* special test for old K&R protos without explicit int
5443 type. Only accepted when defining global data */
5444 if (l == VT_LOCAL || tok < TOK_DEFINE)
5445 break;
5446 btype.t = VT_INT;
5448 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5449 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5450 tok == ';') {
5451 /* we accept no variable after */
5452 next();
5453 continue;
5455 while (1) { /* iterate thru each declaration */
5456 char *asm_label; // associated asm label
5457 type = btype;
5458 type_decl(&type, &ad, &v, TYPE_DIRECT);
5459 #if 0
5461 char buf[500];
5462 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5463 printf("type = '%s'\n", buf);
5465 #endif
5466 if ((type.t & VT_BTYPE) == VT_FUNC) {
5467 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5468 error("function without file scope cannot be static");
5470 /* if old style function prototype, we accept a
5471 declaration list */
5472 sym = type.ref;
5473 if (sym->c == FUNC_OLD)
5474 func_decl_list(sym);
5477 asm_label = NULL;
5478 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5479 CString astr;
5481 asm_label_instr(&astr);
5482 asm_label = tcc_strdup(astr.data);
5483 cstr_free(&astr);
5485 /* parse one last attribute list, after asm label */
5486 parse_attribute(&ad);
5489 if (ad.weak)
5490 type.t |= VT_WEAK;
5491 #ifdef TCC_TARGET_PE
5492 if (ad.func_import)
5493 type.t |= VT_IMPORT;
5494 if (ad.func_export)
5495 type.t |= VT_EXPORT;
5496 #endif
5497 if (tok == '{') {
5498 if (l == VT_LOCAL)
5499 error("cannot use local functions");
5500 if ((type.t & VT_BTYPE) != VT_FUNC)
5501 expect("function definition");
5503 /* reject abstract declarators in function definition */
5504 sym = type.ref;
5505 while ((sym = sym->next) != NULL)
5506 if (!(sym->v & ~SYM_FIELD))
5507 expect("identifier");
5509 /* XXX: cannot do better now: convert extern line to static inline */
5510 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5511 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5513 sym = sym_find(v);
5514 if (sym) {
5515 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5516 goto func_error1;
5518 r = sym->type.ref->r;
5519 /* use func_call from prototype if not defined */
5520 if (FUNC_CALL(r) != FUNC_CDECL
5521 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5522 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5524 /* use export from prototype */
5525 if (FUNC_EXPORT(r))
5526 FUNC_EXPORT(type.ref->r) = 1;
5528 /* use static from prototype */
5529 if (sym->type.t & VT_STATIC)
5530 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5532 if (!is_compatible_types(&sym->type, &type)) {
5533 func_error1:
5534 error("incompatible types for redefinition of '%s'",
5535 get_tok_str(v, NULL));
5537 /* if symbol is already defined, then put complete type */
5538 sym->type = type;
5539 } else {
5540 /* put function symbol */
5541 sym = global_identifier_push(v, type.t, 0);
5542 sym->type.ref = type.ref;
5545 /* static inline functions are just recorded as a kind
5546 of macro. Their code will be emitted at the end of
5547 the compilation unit only if they are used */
5548 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5549 (VT_INLINE | VT_STATIC)) {
5550 TokenString func_str;
5551 int block_level;
5552 struct InlineFunc *fn;
5553 const char *filename;
5555 tok_str_new(&func_str);
5557 block_level = 0;
5558 for(;;) {
5559 int t;
5560 if (tok == TOK_EOF)
5561 error("unexpected end of file");
5562 tok_str_add_tok(&func_str);
5563 t = tok;
5564 next();
5565 if (t == '{') {
5566 block_level++;
5567 } else if (t == '}') {
5568 block_level--;
5569 if (block_level == 0)
5570 break;
5573 tok_str_add(&func_str, -1);
5574 tok_str_add(&func_str, 0);
5575 filename = file ? file->filename : "";
5576 fn = tcc_malloc(sizeof *fn + strlen(filename));
5577 strcpy(fn->filename, filename);
5578 fn->sym = sym;
5579 fn->token_str = func_str.str;
5580 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5582 } else {
5583 /* compute text section */
5584 cur_text_section = ad.section;
5585 if (!cur_text_section)
5586 cur_text_section = text_section;
5587 sym->r = VT_SYM | VT_CONST;
5588 gen_function(sym);
5590 break;
5591 } else {
5592 if (btype.t & VT_TYPEDEF) {
5593 /* save typedefed type */
5594 /* XXX: test storage specifiers ? */
5595 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5596 sym->type.t |= VT_TYPEDEF;
5597 } else {
5598 r = 0;
5599 if ((type.t & VT_BTYPE) == VT_FUNC) {
5600 /* external function definition */
5601 /* specific case for func_call attribute */
5602 type.ref->r = INT_ATTR(&ad);
5603 } else if (!(type.t & VT_ARRAY)) {
5604 /* not lvalue if array */
5605 r |= lvalue_type(type.t);
5607 has_init = (tok == '=');
5608 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5609 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5610 !has_init && l == VT_CONST && type.ref->c < 0)) {
5611 /* external variable or function */
5612 /* NOTE: as GCC, uninitialized global static
5613 arrays of null size are considered as
5614 extern */
5615 sym = external_sym(v, &type, r, asm_label);
5617 if (type.t & VT_WEAK)
5618 weaken_symbol(sym);
5620 if (ad.alias_target) {
5621 Section tsec;
5622 Elf32_Sym *esym;
5623 Sym *alias_target;
5625 alias_target = sym_find(ad.alias_target);
5626 if (!alias_target || !alias_target->c)
5627 error("unsupported forward __alias__ attribute");
5628 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
5629 tsec.sh_num = esym->st_shndx;
5630 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
5632 } else {
5633 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5634 if (type.t & VT_STATIC)
5635 r |= VT_CONST;
5636 else
5637 r |= l;
5638 if (has_init)
5639 next();
5640 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
5643 if (tok != ',') {
5644 if (is_for_loop_init)
5645 return 1;
5646 skip(';');
5647 break;
5649 next();
5653 return 0;
5656 ST_FUNC void decl(int l)
5658 decl0(l, 0);