i386-asm: accept retl as a synonym for ret
[tinycc/miki.git] / tccgen.c
blob3c6adbc434cf5574bce95c23b0365e29a48dca1b
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, int scope);
79 static void expr_eq(void);
80 static void unary_type(CType *type);
81 static int is_compatible_parameter_types(CType *type1, CType *type2);
82 static void expr_type(CType *type);
84 ST_INLN int is_float(int t)
86 int bt;
87 bt = t & VT_BTYPE;
88 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
91 ST_FUNC void test_lvalue(void)
93 if (!(vtop->r & VT_LVAL))
94 expect("lvalue");
97 /* ------------------------------------------------------------------------- */
98 /* symbol allocator */
99 static Sym *__sym_malloc(void)
101 Sym *sym_pool, *sym, *last_sym;
102 int i;
104 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
105 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
107 last_sym = sym_free_first;
108 sym = sym_pool;
109 for(i = 0; i < SYM_POOL_NB; i++) {
110 sym->next = last_sym;
111 last_sym = sym;
112 sym++;
114 sym_free_first = last_sym;
115 return last_sym;
118 static inline Sym *sym_malloc(void)
120 Sym *sym;
121 sym = sym_free_first;
122 if (!sym)
123 sym = __sym_malloc();
124 sym_free_first = sym->next;
125 return sym;
128 ST_INLN void sym_free(Sym *sym)
130 sym->next = sym_free_first;
131 sym_free_first = sym;
134 /* push, without hashing */
135 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
137 Sym *s;
138 s = sym_malloc();
139 s->a = 0;
140 s->v = v;
141 s->type.t = t;
142 s->type.ref = NULL;
143 #ifdef _WIN64
144 s->d = NULL;
145 #endif
146 s->c = c;
147 s->next = NULL;
148 /* add in stack */
149 s->prev = *ps;
150 *ps = s;
151 return s;
154 /* find a symbol and return its associated structure. 's' is the top
155 of the symbol stack */
156 ST_FUNC Sym *sym_find2(Sym *s, int v)
158 while (s) {
159 if (s->v == v)
160 return s;
161 s = s->prev;
163 return NULL;
166 /* structure lookup */
167 ST_INLN Sym *struct_find(int v)
169 v -= TOK_IDENT;
170 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
171 return NULL;
172 return table_ident[v]->sym_struct;
175 /* find an identifier */
176 ST_INLN Sym *sym_find(int v)
178 v -= TOK_IDENT;
179 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
180 return NULL;
181 return table_ident[v]->sym_identifier;
184 /* push a given symbol on the symbol stack */
185 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
187 Sym *s, **ps;
188 TokenSym *ts;
190 if (local_stack)
191 ps = &local_stack;
192 else
193 ps = &global_stack;
194 s = sym_push2(ps, v, type->t, c);
195 s->type.ref = type->ref;
196 s->r = r;
197 /* don't record fields or anonymous symbols */
198 /* XXX: simplify */
199 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
200 /* record symbol in token array */
201 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
202 if (v & SYM_STRUCT)
203 ps = &ts->sym_struct;
204 else
205 ps = &ts->sym_identifier;
206 s->prev_tok = *ps;
207 *ps = s;
209 return s;
212 /* push a global identifier */
213 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
215 Sym *s, **ps;
216 s = sym_push2(&global_stack, v, t, c);
217 /* don't record anonymous symbol */
218 if (v < SYM_FIRST_ANOM) {
219 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
220 /* modify the top most local identifier, so that
221 sym_identifier will point to 's' when popped */
222 while (*ps != NULL)
223 ps = &(*ps)->prev_tok;
224 s->prev_tok = NULL;
225 *ps = s;
227 return s;
230 /* pop symbols until top reaches 'b' */
231 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
233 Sym *s, *ss, **ps;
234 TokenSym *ts;
235 int v;
237 s = *ptop;
238 while(s != b) {
239 ss = s->prev;
240 v = s->v;
241 /* remove symbol in token array */
242 /* XXX: simplify */
243 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
244 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
245 if (v & SYM_STRUCT)
246 ps = &ts->sym_struct;
247 else
248 ps = &ts->sym_identifier;
249 *ps = s->prev_tok;
251 sym_free(s);
252 s = ss;
254 *ptop = b;
257 /* ------------------------------------------------------------------------- */
259 ST_FUNC void swap(int *p, int *q)
261 int t;
262 t = *p;
263 *p = *q;
264 *q = t;
267 static void vsetc(CType *type, int r, CValue *vc)
269 int v;
271 if (vtop >= vstack + (VSTACK_SIZE - 1))
272 error("memory full");
273 /* cannot let cpu flags if other instruction are generated. Also
274 avoid leaving VT_JMP anywhere except on the top of the stack
275 because it would complicate the code generator. */
276 if (vtop >= vstack) {
277 v = vtop->r & VT_VALMASK;
278 if (v == VT_CMP || (v & ~1) == VT_JMP)
279 gv(RC_INT);
281 vtop++;
282 vtop->type = *type;
283 vtop->r = r;
284 vtop->r2 = VT_CONST;
285 vtop->c = *vc;
288 /* push constant of type "type" with useless value */
289 void vpush(CType *type)
291 CValue cval;
292 vsetc(type, VT_CONST, &cval);
295 /* push integer constant */
296 ST_FUNC void vpushi(int v)
298 CValue cval;
299 cval.i = v;
300 vsetc(&int_type, VT_CONST, &cval);
303 /* push long long constant */
304 static void vpushll(long long v)
306 CValue cval;
307 CType ctype;
308 ctype.t = VT_LLONG;
309 ctype.ref = 0;
310 cval.ull = v;
311 vsetc(&ctype, VT_CONST, &cval);
314 /* push arbitrary 64bit constant */
315 void vpush64(int ty, unsigned long long v)
317 CValue cval;
318 CType ctype;
319 ctype.t = ty;
320 cval.ull = v;
321 vsetc(&ctype, VT_CONST, &cval);
324 /* Return a static symbol pointing to a section */
325 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
327 int v;
328 Sym *sym;
330 v = anon_sym++;
331 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
332 sym->type.ref = type->ref;
333 sym->r = VT_CONST | VT_SYM;
334 put_extern_sym(sym, sec, offset, size);
335 return sym;
338 /* push a reference to a section offset by adding a dummy symbol */
339 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
341 CValue cval;
343 cval.ul = 0;
344 vsetc(type, VT_CONST | VT_SYM, &cval);
345 vtop->sym = get_sym_ref(type, sec, offset, size);
348 /* define a new external reference to a symbol 'v' of type 'u' */
349 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
351 Sym *s;
353 s = sym_find(v);
354 if (!s) {
355 /* push forward reference */
356 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
357 s->type.ref = type->ref;
358 s->r = r | VT_CONST | VT_SYM;
360 return s;
363 /* define a new external reference to a symbol 'v' of type 'u' */
364 static Sym *external_sym(int v, CType *type, int r)
366 Sym *s;
368 s = sym_find(v);
369 if (!s) {
370 /* push forward reference */
371 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
372 if (type && type->ref && type->ref->a)
373 s->a = type->ref->a;
374 s->type.t |= VT_EXTERN;
375 } else if (s->type.ref == func_old_type.ref) {
376 s->type.ref = type->ref;
377 s->r = r | VT_CONST | VT_SYM;
378 s->type.t |= VT_EXTERN;
379 } else if (!is_compatible_types(&s->type, type)) {
380 error("incompatible types for redefinition of '%s'",
381 get_tok_str(v, NULL));
383 return s;
386 /* push a reference to global symbol v */
387 ST_FUNC void vpush_global_sym(CType *type, int v)
389 Sym *sym;
390 CValue cval;
392 sym = external_global_sym(v, type, 0);
393 cval.ul = 0;
394 vsetc(type, VT_CONST | VT_SYM, &cval);
395 vtop->sym = sym;
398 ST_FUNC void vset(CType *type, int r, int v)
400 CValue cval;
402 cval.i = v;
403 vsetc(type, r, &cval);
406 static void vseti(int r, int v)
408 CType type;
409 type.t = VT_INT;
410 type.ref = 0;
411 vset(&type, r, v);
414 ST_FUNC void vswap(void)
416 SValue tmp;
418 tmp = vtop[0];
419 vtop[0] = vtop[-1];
420 vtop[-1] = tmp;
423 ST_FUNC void vpushv(SValue *v)
425 if (vtop >= vstack + (VSTACK_SIZE - 1))
426 error("memory full");
427 vtop++;
428 *vtop = *v;
431 static void vdup(void)
433 vpushv(vtop);
436 /* save r to the memory stack, and mark it as being free */
437 ST_FUNC void save_reg(int r)
439 int l, saved, size, align;
440 SValue *p, sv;
441 CType *type;
443 /* modify all stack values */
444 saved = 0;
445 l = 0;
446 for(p=vstack;p<=vtop;p++) {
447 if ((p->r & VT_VALMASK) == r ||
448 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
449 /* must save value on stack if not already done */
450 if (!saved) {
451 /* NOTE: must reload 'r' because r might be equal to r2 */
452 r = p->r & VT_VALMASK;
453 /* store register in the stack */
454 type = &p->type;
455 if ((p->r & VT_LVAL) ||
456 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
457 #ifdef TCC_TARGET_X86_64
458 type = &char_pointer_type;
459 #else
460 type = &int_type;
461 #endif
462 size = type_size(type, &align);
463 loc = (loc - size) & -align;
464 sv.type.t = type->t;
465 sv.r = VT_LOCAL | VT_LVAL;
466 sv.c.ul = loc;
467 store(r, &sv);
468 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
469 /* x86 specific: need to pop fp register ST0 if saved */
470 if (r == TREG_ST0) {
471 o(0xd8dd); /* fstp %st(0) */
473 #endif
474 #ifndef TCC_TARGET_X86_64
475 /* special long long case */
476 if ((type->t & VT_BTYPE) == VT_LLONG) {
477 sv.c.ul += 4;
478 store(p->r2, &sv);
480 #endif
481 l = loc;
482 saved = 1;
484 /* mark that stack entry as being saved on the stack */
485 if (p->r & VT_LVAL) {
486 /* also clear the bounded flag because the
487 relocation address of the function was stored in
488 p->c.ul */
489 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
490 } else {
491 p->r = lvalue_type(p->type.t) | VT_LOCAL;
493 p->r2 = VT_CONST;
494 p->c.ul = l;
499 #ifdef TCC_TARGET_ARM
500 /* find a register of class 'rc2' with at most one reference on stack.
501 * If none, call get_reg(rc) */
502 ST_FUNC int get_reg_ex(int rc, int rc2)
504 int r;
505 SValue *p;
507 for(r=0;r<NB_REGS;r++) {
508 if (reg_classes[r] & rc2) {
509 int n;
510 n=0;
511 for(p = vstack; p <= vtop; p++) {
512 if ((p->r & VT_VALMASK) == r ||
513 (p->r2 & VT_VALMASK) == r)
514 n++;
516 if (n <= 1)
517 return r;
520 return get_reg(rc);
522 #endif
524 /* find a free register of class 'rc'. If none, save one register */
525 ST_FUNC int get_reg(int rc)
527 int r;
528 SValue *p;
530 /* find a free register */
531 for(r=0;r<NB_REGS;r++) {
532 if (reg_classes[r] & rc) {
533 for(p=vstack;p<=vtop;p++) {
534 if ((p->r & VT_VALMASK) == r ||
535 (p->r2 & VT_VALMASK) == r)
536 goto notfound;
538 return r;
540 notfound: ;
543 /* no register left : free the first one on the stack (VERY
544 IMPORTANT to start from the bottom to ensure that we don't
545 spill registers used in gen_opi()) */
546 for(p=vstack;p<=vtop;p++) {
547 r = p->r & VT_VALMASK;
548 if (r < VT_CONST && (reg_classes[r] & rc))
549 goto save_found;
550 /* also look at second register (if long long) */
551 r = p->r2 & VT_VALMASK;
552 if (r < VT_CONST && (reg_classes[r] & rc)) {
553 save_found:
554 save_reg(r);
555 return r;
558 /* Should never comes here */
559 return -1;
562 /* save registers up to (vtop - n) stack entry */
563 ST_FUNC void save_regs(int n)
565 int r;
566 SValue *p, *p1;
567 p1 = vtop - n;
568 for(p = vstack;p <= p1; p++) {
569 r = p->r & VT_VALMASK;
570 if (r < VT_CONST) {
571 save_reg(r);
576 /* move register 's' to 'r', and flush previous value of r to memory
577 if needed */
578 static void move_reg(int r, int s)
580 SValue sv;
582 if (r != s) {
583 save_reg(r);
584 sv.type.t = VT_INT;
585 sv.r = s;
586 sv.c.ul = 0;
587 load(r, &sv);
591 /* get address of vtop (vtop MUST BE an lvalue) */
592 static void gaddrof(void)
594 vtop->r &= ~VT_LVAL;
595 /* tricky: if saved lvalue, then we can go back to lvalue */
596 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
597 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
600 #ifdef CONFIG_TCC_BCHECK
601 /* generate lvalue bound code */
602 static void gbound(void)
604 int lval_type;
605 CType type1;
607 vtop->r &= ~VT_MUSTBOUND;
608 /* if lvalue, then use checking code before dereferencing */
609 if (vtop->r & VT_LVAL) {
610 /* if not VT_BOUNDED value, then make one */
611 if (!(vtop->r & VT_BOUNDED)) {
612 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
613 /* must save type because we must set it to int to get pointer */
614 type1 = vtop->type;
615 vtop->type.t = VT_INT;
616 gaddrof();
617 vpushi(0);
618 gen_bounded_ptr_add();
619 vtop->r |= lval_type;
620 vtop->type = type1;
622 /* then check for dereferencing */
623 gen_bounded_ptr_deref();
626 #endif
628 /* store vtop a register belonging to class 'rc'. lvalues are
629 converted to values. Cannot be used if cannot be converted to
630 register value (such as structures). */
631 ST_FUNC int gv(int rc)
633 int r, rc2, bit_pos, bit_size, size, align, i;
635 /* NOTE: get_reg can modify vstack[] */
636 if (vtop->type.t & VT_BITFIELD) {
637 CType type;
638 int bits = 32;
639 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
640 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
641 /* remove bit field info to avoid loops */
642 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
643 /* cast to int to propagate signedness in following ops */
644 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
645 type.t = VT_LLONG;
646 bits = 64;
647 } else
648 type.t = VT_INT;
649 if((vtop->type.t & VT_UNSIGNED) ||
650 (vtop->type.t & VT_BTYPE) == VT_BOOL)
651 type.t |= VT_UNSIGNED;
652 gen_cast(&type);
653 /* generate shifts */
654 vpushi(bits - (bit_pos + bit_size));
655 gen_op(TOK_SHL);
656 vpushi(bits - bit_size);
657 /* NOTE: transformed to SHR if unsigned */
658 gen_op(TOK_SAR);
659 r = gv(rc);
660 } else {
661 if (is_float(vtop->type.t) &&
662 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
663 Sym *sym;
664 int *ptr;
665 unsigned long offset;
666 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
667 CValue check;
668 #endif
670 /* XXX: unify with initializers handling ? */
671 /* CPUs usually cannot use float constants, so we store them
672 generically in data segment */
673 size = type_size(&vtop->type, &align);
674 offset = (data_section->data_offset + align - 1) & -align;
675 data_section->data_offset = offset;
676 /* XXX: not portable yet */
677 #if defined(__i386__) || defined(__x86_64__)
678 /* Zero pad x87 tenbyte long doubles */
679 if (size == LDOUBLE_SIZE)
680 vtop->c.tab[2] &= 0xffff;
681 #endif
682 ptr = section_ptr_add(data_section, size);
683 size = size >> 2;
684 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
685 check.d = 1;
686 if(check.tab[0])
687 for(i=0;i<size;i++)
688 ptr[i] = vtop->c.tab[size-1-i];
689 else
690 #endif
691 for(i=0;i<size;i++)
692 ptr[i] = vtop->c.tab[i];
693 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
694 vtop->r |= VT_LVAL | VT_SYM;
695 vtop->sym = sym;
696 vtop->c.ul = 0;
698 #ifdef CONFIG_TCC_BCHECK
699 if (vtop->r & VT_MUSTBOUND)
700 gbound();
701 #endif
703 r = vtop->r & VT_VALMASK;
704 rc2 = RC_INT;
705 if (rc == RC_IRET)
706 rc2 = RC_LRET;
707 /* need to reload if:
708 - constant
709 - lvalue (need to dereference pointer)
710 - already a register, but not in the right class */
711 if (r >= VT_CONST
712 || (vtop->r & VT_LVAL)
713 || !(reg_classes[r] & rc)
714 #ifndef TCC_TARGET_X86_64
715 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
716 #endif
719 r = get_reg(rc);
720 #ifndef TCC_TARGET_X86_64
721 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
722 int r2;
723 unsigned long long ll;
724 /* two register type load : expand to two words
725 temporarily */
726 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
727 /* load constant */
728 ll = vtop->c.ull;
729 vtop->c.ui = ll; /* first word */
730 load(r, vtop);
731 vtop->r = r; /* save register value */
732 vpushi(ll >> 32); /* second word */
733 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
734 (vtop->r & VT_LVAL)) {
735 /* We do not want to modifier the long long
736 pointer here, so the safest (and less
737 efficient) is to save all the other registers
738 in the stack. XXX: totally inefficient. */
739 save_regs(1);
740 /* load from memory */
741 load(r, vtop);
742 vdup();
743 vtop[-1].r = r; /* save register value */
744 /* increment pointer to get second word */
745 vtop->type.t = VT_INT;
746 gaddrof();
747 vpushi(4);
748 gen_op('+');
749 vtop->r |= VT_LVAL;
750 } else {
751 /* move registers */
752 load(r, vtop);
753 vdup();
754 vtop[-1].r = r; /* save register value */
755 vtop->r = vtop[-1].r2;
757 /* allocate second register */
758 r2 = get_reg(rc2);
759 load(r2, vtop);
760 vpop();
761 /* write second register */
762 vtop->r2 = r2;
763 } else
764 #endif
765 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
766 int t1, t;
767 /* lvalue of scalar type : need to use lvalue type
768 because of possible cast */
769 t = vtop->type.t;
770 t1 = t;
771 /* compute memory access type */
772 if (vtop->r & VT_LVAL_BYTE)
773 t = VT_BYTE;
774 else if (vtop->r & VT_LVAL_SHORT)
775 t = VT_SHORT;
776 if (vtop->r & VT_LVAL_UNSIGNED)
777 t |= VT_UNSIGNED;
778 vtop->type.t = t;
779 load(r, vtop);
780 /* restore wanted type */
781 vtop->type.t = t1;
782 } else {
783 /* one register type load */
784 load(r, vtop);
787 vtop->r = r;
788 #ifdef TCC_TARGET_C67
789 /* uses register pairs for doubles */
790 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
791 vtop->r2 = r+1;
792 #endif
794 return r;
797 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
798 ST_FUNC void gv2(int rc1, int rc2)
800 int v;
802 /* generate more generic register first. But VT_JMP or VT_CMP
803 values must be generated first in all cases to avoid possible
804 reload errors */
805 v = vtop[0].r & VT_VALMASK;
806 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
807 vswap();
808 gv(rc1);
809 vswap();
810 gv(rc2);
811 /* test if reload is needed for first register */
812 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
813 vswap();
814 gv(rc1);
815 vswap();
817 } else {
818 gv(rc2);
819 vswap();
820 gv(rc1);
821 vswap();
822 /* test if reload is needed for first register */
823 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
824 gv(rc2);
829 /* wrapper around RC_FRET to return a register by type */
830 static int rc_fret(int t)
832 #ifdef TCC_TARGET_X86_64
833 if (t == VT_LDOUBLE) {
834 return RC_ST0;
836 #endif
837 return RC_FRET;
840 /* wrapper around REG_FRET to return a register by type */
841 static int reg_fret(int t)
843 #ifdef TCC_TARGET_X86_64
844 if (t == VT_LDOUBLE) {
845 return TREG_ST0;
847 #endif
848 return REG_FRET;
851 /* expand long long on stack in two int registers */
852 static void lexpand(void)
854 int u;
856 u = vtop->type.t & VT_UNSIGNED;
857 gv(RC_INT);
858 vdup();
859 vtop[0].r = vtop[-1].r2;
860 vtop[0].r2 = VT_CONST;
861 vtop[-1].r2 = VT_CONST;
862 vtop[0].type.t = VT_INT | u;
863 vtop[-1].type.t = VT_INT | u;
866 #ifdef TCC_TARGET_ARM
867 /* expand long long on stack */
868 ST_FUNC void lexpand_nr(void)
870 int u,v;
872 u = vtop->type.t & VT_UNSIGNED;
873 vdup();
874 vtop->r2 = VT_CONST;
875 vtop->type.t = VT_INT | u;
876 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
877 if (v == VT_CONST) {
878 vtop[-1].c.ui = vtop->c.ull;
879 vtop->c.ui = vtop->c.ull >> 32;
880 vtop->r = VT_CONST;
881 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
882 vtop->c.ui += 4;
883 vtop->r = vtop[-1].r;
884 } else if (v > VT_CONST) {
885 vtop--;
886 lexpand();
887 } else
888 vtop->r = vtop[-1].r2;
889 vtop[-1].r2 = VT_CONST;
890 vtop[-1].type.t = VT_INT | u;
892 #endif
894 /* build a long long from two ints */
895 static void lbuild(int t)
897 gv2(RC_INT, RC_INT);
898 vtop[-1].r2 = vtop[0].r;
899 vtop[-1].type.t = t;
900 vpop();
903 /* rotate n first stack elements to the bottom
904 I1 ... In -> I2 ... In I1 [top is right]
906 static void vrotb(int n)
908 int i;
909 SValue tmp;
911 tmp = vtop[-n + 1];
912 for(i=-n+1;i!=0;i++)
913 vtop[i] = vtop[i+1];
914 vtop[0] = tmp;
917 /* rotate n first stack elements to the top
918 I1 ... In -> In I1 ... I(n-1) [top is right]
920 ST_FUNC void vrott(int n)
922 int i;
923 SValue tmp;
925 tmp = vtop[0];
926 for(i = 0;i < n - 1; i++)
927 vtop[-i] = vtop[-i - 1];
928 vtop[-n + 1] = tmp;
931 #ifdef TCC_TARGET_ARM
932 /* like vrott but in other direction
933 In ... I1 -> I(n-1) ... I1 In [top is right]
935 ST_FUNC void vnrott(int n)
937 int i;
938 SValue tmp;
940 tmp = vtop[-n + 1];
941 for(i = n - 1; i > 0; i--)
942 vtop[-i] = vtop[-i + 1];
943 vtop[0] = tmp;
945 #endif
947 /* pop stack value */
948 ST_FUNC void vpop(void)
950 int v;
951 v = vtop->r & VT_VALMASK;
952 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
953 /* for x86, we need to pop the FP stack */
954 if (v == TREG_ST0 && !nocode_wanted) {
955 o(0xd8dd); /* fstp %st(0) */
956 } else
957 #endif
958 if (v == VT_JMP || v == VT_JMPI) {
959 /* need to put correct jump if && or || without test */
960 gsym(vtop->c.ul);
962 vtop--;
965 /* convert stack entry to register and duplicate its value in another
966 register */
967 static void gv_dup(void)
969 int rc, t, r, r1;
970 SValue sv;
972 t = vtop->type.t;
973 if ((t & VT_BTYPE) == VT_LLONG) {
974 lexpand();
975 gv_dup();
976 vswap();
977 vrotb(3);
978 gv_dup();
979 vrotb(4);
980 /* stack: H L L1 H1 */
981 lbuild(t);
982 vrotb(3);
983 vrotb(3);
984 vswap();
985 lbuild(t);
986 vswap();
987 } else {
988 /* duplicate value */
989 rc = RC_INT;
990 sv.type.t = VT_INT;
991 if (is_float(t)) {
992 rc = RC_FLOAT;
993 #ifdef TCC_TARGET_X86_64
994 if ((t & VT_BTYPE) == VT_LDOUBLE) {
995 rc = RC_ST0;
997 #endif
998 sv.type.t = t;
1000 r = gv(rc);
1001 r1 = get_reg(rc);
1002 sv.r = r;
1003 sv.c.ul = 0;
1004 load(r1, &sv); /* move r to r1 */
1005 vdup();
1006 /* duplicates value */
1007 if (r != r1)
1008 vtop->r = r1;
1012 #ifndef TCC_TARGET_X86_64
1013 /* generate CPU independent (unsigned) long long operations */
1014 static void gen_opl(int op)
1016 int t, a, b, op1, c, i;
1017 int func;
1018 unsigned short reg_iret = REG_IRET;
1019 unsigned short reg_lret = REG_LRET;
1020 SValue tmp;
1022 switch(op) {
1023 case '/':
1024 case TOK_PDIV:
1025 func = TOK___divdi3;
1026 goto gen_func;
1027 case TOK_UDIV:
1028 func = TOK___udivdi3;
1029 goto gen_func;
1030 case '%':
1031 func = TOK___moddi3;
1032 goto gen_mod_func;
1033 case TOK_UMOD:
1034 func = TOK___umoddi3;
1035 gen_mod_func:
1036 #ifdef TCC_ARM_EABI
1037 reg_iret = TREG_R2;
1038 reg_lret = TREG_R3;
1039 #endif
1040 gen_func:
1041 /* call generic long long function */
1042 vpush_global_sym(&func_old_type, func);
1043 vrott(3);
1044 gfunc_call(2);
1045 vpushi(0);
1046 vtop->r = reg_iret;
1047 vtop->r2 = reg_lret;
1048 break;
1049 case '^':
1050 case '&':
1051 case '|':
1052 case '*':
1053 case '+':
1054 case '-':
1055 t = vtop->type.t;
1056 vswap();
1057 lexpand();
1058 vrotb(3);
1059 lexpand();
1060 /* stack: L1 H1 L2 H2 */
1061 tmp = vtop[0];
1062 vtop[0] = vtop[-3];
1063 vtop[-3] = tmp;
1064 tmp = vtop[-2];
1065 vtop[-2] = vtop[-3];
1066 vtop[-3] = tmp;
1067 vswap();
1068 /* stack: H1 H2 L1 L2 */
1069 if (op == '*') {
1070 vpushv(vtop - 1);
1071 vpushv(vtop - 1);
1072 gen_op(TOK_UMULL);
1073 lexpand();
1074 /* stack: H1 H2 L1 L2 ML MH */
1075 for(i=0;i<4;i++)
1076 vrotb(6);
1077 /* stack: ML MH H1 H2 L1 L2 */
1078 tmp = vtop[0];
1079 vtop[0] = vtop[-2];
1080 vtop[-2] = tmp;
1081 /* stack: ML MH H1 L2 H2 L1 */
1082 gen_op('*');
1083 vrotb(3);
1084 vrotb(3);
1085 gen_op('*');
1086 /* stack: ML MH M1 M2 */
1087 gen_op('+');
1088 gen_op('+');
1089 } else if (op == '+' || op == '-') {
1090 /* XXX: add non carry method too (for MIPS or alpha) */
1091 if (op == '+')
1092 op1 = TOK_ADDC1;
1093 else
1094 op1 = TOK_SUBC1;
1095 gen_op(op1);
1096 /* stack: H1 H2 (L1 op L2) */
1097 vrotb(3);
1098 vrotb(3);
1099 gen_op(op1 + 1); /* TOK_xxxC2 */
1100 } else {
1101 gen_op(op);
1102 /* stack: H1 H2 (L1 op L2) */
1103 vrotb(3);
1104 vrotb(3);
1105 /* stack: (L1 op L2) H1 H2 */
1106 gen_op(op);
1107 /* stack: (L1 op L2) (H1 op H2) */
1109 /* stack: L H */
1110 lbuild(t);
1111 break;
1112 case TOK_SAR:
1113 case TOK_SHR:
1114 case TOK_SHL:
1115 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1116 t = vtop[-1].type.t;
1117 vswap();
1118 lexpand();
1119 vrotb(3);
1120 /* stack: L H shift */
1121 c = (int)vtop->c.i;
1122 /* constant: simpler */
1123 /* NOTE: all comments are for SHL. the other cases are
1124 done by swaping words */
1125 vpop();
1126 if (op != TOK_SHL)
1127 vswap();
1128 if (c >= 32) {
1129 /* stack: L H */
1130 vpop();
1131 if (c > 32) {
1132 vpushi(c - 32);
1133 gen_op(op);
1135 if (op != TOK_SAR) {
1136 vpushi(0);
1137 } else {
1138 gv_dup();
1139 vpushi(31);
1140 gen_op(TOK_SAR);
1142 vswap();
1143 } else {
1144 vswap();
1145 gv_dup();
1146 /* stack: H L L */
1147 vpushi(c);
1148 gen_op(op);
1149 vswap();
1150 vpushi(32 - c);
1151 if (op == TOK_SHL)
1152 gen_op(TOK_SHR);
1153 else
1154 gen_op(TOK_SHL);
1155 vrotb(3);
1156 /* stack: L L H */
1157 vpushi(c);
1158 if (op == TOK_SHL)
1159 gen_op(TOK_SHL);
1160 else
1161 gen_op(TOK_SHR);
1162 gen_op('|');
1164 if (op != TOK_SHL)
1165 vswap();
1166 lbuild(t);
1167 } else {
1168 /* XXX: should provide a faster fallback on x86 ? */
1169 switch(op) {
1170 case TOK_SAR:
1171 func = TOK___ashrdi3;
1172 goto gen_func;
1173 case TOK_SHR:
1174 func = TOK___lshrdi3;
1175 goto gen_func;
1176 case TOK_SHL:
1177 func = TOK___ashldi3;
1178 goto gen_func;
1181 break;
1182 default:
1183 /* compare operations */
1184 t = vtop->type.t;
1185 vswap();
1186 lexpand();
1187 vrotb(3);
1188 lexpand();
1189 /* stack: L1 H1 L2 H2 */
1190 tmp = vtop[-1];
1191 vtop[-1] = vtop[-2];
1192 vtop[-2] = tmp;
1193 /* stack: L1 L2 H1 H2 */
1194 /* compare high */
1195 op1 = op;
1196 /* when values are equal, we need to compare low words. since
1197 the jump is inverted, we invert the test too. */
1198 if (op1 == TOK_LT)
1199 op1 = TOK_LE;
1200 else if (op1 == TOK_GT)
1201 op1 = TOK_GE;
1202 else if (op1 == TOK_ULT)
1203 op1 = TOK_ULE;
1204 else if (op1 == TOK_UGT)
1205 op1 = TOK_UGE;
1206 a = 0;
1207 b = 0;
1208 gen_op(op1);
1209 if (op1 != TOK_NE) {
1210 a = gtst(1, 0);
1212 if (op != TOK_EQ) {
1213 /* generate non equal test */
1214 /* XXX: NOT PORTABLE yet */
1215 if (a == 0) {
1216 b = gtst(0, 0);
1217 } else {
1218 #if defined(TCC_TARGET_I386)
1219 b = psym(0x850f, 0);
1220 #elif defined(TCC_TARGET_ARM)
1221 b = ind;
1222 o(0x1A000000 | encbranch(ind, 0, 1));
1223 #elif defined(TCC_TARGET_C67)
1224 error("not implemented");
1225 #else
1226 #error not supported
1227 #endif
1230 /* compare low. Always unsigned */
1231 op1 = op;
1232 if (op1 == TOK_LT)
1233 op1 = TOK_ULT;
1234 else if (op1 == TOK_LE)
1235 op1 = TOK_ULE;
1236 else if (op1 == TOK_GT)
1237 op1 = TOK_UGT;
1238 else if (op1 == TOK_GE)
1239 op1 = TOK_UGE;
1240 gen_op(op1);
1241 a = gtst(1, a);
1242 gsym(b);
1243 vseti(VT_JMPI, a);
1244 break;
1247 #endif
1249 /* handle integer constant optimizations and various machine
1250 independent opt */
1251 static void gen_opic(int op)
1253 int c1, c2, t1, t2, n;
1254 SValue *v1, *v2;
1255 long long l1, l2;
1256 typedef unsigned long long U;
1258 v1 = vtop - 1;
1259 v2 = vtop;
1260 t1 = v1->type.t & VT_BTYPE;
1261 t2 = v2->type.t & VT_BTYPE;
1263 if (t1 == VT_LLONG)
1264 l1 = v1->c.ll;
1265 else if (v1->type.t & VT_UNSIGNED)
1266 l1 = v1->c.ui;
1267 else
1268 l1 = v1->c.i;
1270 if (t2 == VT_LLONG)
1271 l2 = v2->c.ll;
1272 else if (v2->type.t & VT_UNSIGNED)
1273 l2 = v2->c.ui;
1274 else
1275 l2 = v2->c.i;
1277 /* currently, we cannot do computations with forward symbols */
1278 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1279 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1280 if (c1 && c2) {
1281 switch(op) {
1282 case '+': l1 += l2; break;
1283 case '-': l1 -= l2; break;
1284 case '&': l1 &= l2; break;
1285 case '^': l1 ^= l2; break;
1286 case '|': l1 |= l2; break;
1287 case '*': l1 *= l2; break;
1289 case TOK_PDIV:
1290 case '/':
1291 case '%':
1292 case TOK_UDIV:
1293 case TOK_UMOD:
1294 /* if division by zero, generate explicit division */
1295 if (l2 == 0) {
1296 if (const_wanted)
1297 error("division by zero in constant");
1298 goto general_case;
1300 switch(op) {
1301 default: l1 /= l2; break;
1302 case '%': l1 %= l2; break;
1303 case TOK_UDIV: l1 = (U)l1 / l2; break;
1304 case TOK_UMOD: l1 = (U)l1 % l2; break;
1306 break;
1307 case TOK_SHL: l1 <<= l2; break;
1308 case TOK_SHR: l1 = (U)l1 >> l2; break;
1309 case TOK_SAR: l1 >>= l2; break;
1310 /* tests */
1311 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1312 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1313 case TOK_EQ: l1 = l1 == l2; break;
1314 case TOK_NE: l1 = l1 != l2; break;
1315 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1316 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1317 case TOK_LT: l1 = l1 < l2; break;
1318 case TOK_GE: l1 = l1 >= l2; break;
1319 case TOK_LE: l1 = l1 <= l2; break;
1320 case TOK_GT: l1 = l1 > l2; break;
1321 /* logical */
1322 case TOK_LAND: l1 = l1 && l2; break;
1323 case TOK_LOR: l1 = l1 || l2; break;
1324 default:
1325 goto general_case;
1327 v1->c.ll = l1;
1328 vtop--;
1329 } else {
1330 /* if commutative ops, put c2 as constant */
1331 if (c1 && (op == '+' || op == '&' || op == '^' ||
1332 op == '|' || op == '*')) {
1333 vswap();
1334 c2 = c1; //c = c1, c1 = c2, c2 = c;
1335 l2 = l1; //l = l1, l1 = l2, l2 = l;
1337 /* Filter out NOP operations like x*1, x-0, x&-1... */
1338 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1339 op == TOK_PDIV) &&
1340 l2 == 1) ||
1341 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1342 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1343 l2 == 0) ||
1344 (op == '&' &&
1345 l2 == -1))) {
1346 /* nothing to do */
1347 vtop--;
1348 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1349 /* try to use shifts instead of muls or divs */
1350 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1351 n = -1;
1352 while (l2) {
1353 l2 >>= 1;
1354 n++;
1356 vtop->c.ll = n;
1357 if (op == '*')
1358 op = TOK_SHL;
1359 else if (op == TOK_PDIV)
1360 op = TOK_SAR;
1361 else
1362 op = TOK_SHR;
1364 goto general_case;
1365 } else if (c2 && (op == '+' || op == '-') &&
1366 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1367 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1368 /* symbol + constant case */
1369 if (op == '-')
1370 l2 = -l2;
1371 vtop--;
1372 vtop->c.ll += l2;
1373 } else {
1374 general_case:
1375 if (!nocode_wanted) {
1376 /* call low level op generator */
1377 if (t1 == VT_LLONG || t2 == VT_LLONG)
1378 gen_opl(op);
1379 else
1380 gen_opi(op);
1381 } else {
1382 vtop--;
1388 /* generate a floating point operation with constant propagation */
1389 static void gen_opif(int op)
1391 int c1, c2;
1392 SValue *v1, *v2;
1393 long double f1, f2;
1395 v1 = vtop - 1;
1396 v2 = vtop;
1397 /* currently, we cannot do computations with forward symbols */
1398 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1399 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1400 if (c1 && c2) {
1401 if (v1->type.t == VT_FLOAT) {
1402 f1 = v1->c.f;
1403 f2 = v2->c.f;
1404 } else if (v1->type.t == VT_DOUBLE) {
1405 f1 = v1->c.d;
1406 f2 = v2->c.d;
1407 } else {
1408 f1 = v1->c.ld;
1409 f2 = v2->c.ld;
1412 /* NOTE: we only do constant propagation if finite number (not
1413 NaN or infinity) (ANSI spec) */
1414 if (!ieee_finite(f1) || !ieee_finite(f2))
1415 goto general_case;
1417 switch(op) {
1418 case '+': f1 += f2; break;
1419 case '-': f1 -= f2; break;
1420 case '*': f1 *= f2; break;
1421 case '/':
1422 if (f2 == 0.0) {
1423 if (const_wanted)
1424 error("division by zero in constant");
1425 goto general_case;
1427 f1 /= f2;
1428 break;
1429 /* XXX: also handles tests ? */
1430 default:
1431 goto general_case;
1433 /* XXX: overflow test ? */
1434 if (v1->type.t == VT_FLOAT) {
1435 v1->c.f = f1;
1436 } else if (v1->type.t == VT_DOUBLE) {
1437 v1->c.d = f1;
1438 } else {
1439 v1->c.ld = f1;
1441 vtop--;
1442 } else {
1443 general_case:
1444 if (!nocode_wanted) {
1445 gen_opf(op);
1446 } else {
1447 vtop--;
1452 static int pointed_size(CType *type)
1454 int align;
1455 return type_size(pointed_type(type), &align);
1458 static inline int is_null_pointer(SValue *p)
1460 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1461 return 0;
1462 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1463 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1466 static inline int is_integer_btype(int bt)
1468 return (bt == VT_BYTE || bt == VT_SHORT ||
1469 bt == VT_INT || bt == VT_LLONG);
1472 /* check types for comparison or substraction of pointers */
1473 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1475 CType *type1, *type2, tmp_type1, tmp_type2;
1476 int bt1, bt2;
1478 /* null pointers are accepted for all comparisons as gcc */
1479 if (is_null_pointer(p1) || is_null_pointer(p2))
1480 return;
1481 type1 = &p1->type;
1482 type2 = &p2->type;
1483 bt1 = type1->t & VT_BTYPE;
1484 bt2 = type2->t & VT_BTYPE;
1485 /* accept comparison between pointer and integer with a warning */
1486 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1487 if (op != TOK_LOR && op != TOK_LAND )
1488 warning("comparison between pointer and integer");
1489 return;
1492 /* both must be pointers or implicit function pointers */
1493 if (bt1 == VT_PTR) {
1494 type1 = pointed_type(type1);
1495 } else if (bt1 != VT_FUNC)
1496 goto invalid_operands;
1498 if (bt2 == VT_PTR) {
1499 type2 = pointed_type(type2);
1500 } else if (bt2 != VT_FUNC) {
1501 invalid_operands:
1502 error("invalid operands to binary %s", get_tok_str(op, NULL));
1504 if ((type1->t & VT_BTYPE) == VT_VOID ||
1505 (type2->t & VT_BTYPE) == VT_VOID)
1506 return;
1507 tmp_type1 = *type1;
1508 tmp_type2 = *type2;
1509 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1510 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1511 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1512 /* gcc-like error if '-' is used */
1513 if (op == '-')
1514 goto invalid_operands;
1515 else
1516 warning("comparison of distinct pointer types lacks a cast");
1520 /* generic gen_op: handles types problems */
1521 ST_FUNC void gen_op(int op)
1523 int u, t1, t2, bt1, bt2, t;
1524 CType type1;
1526 t1 = vtop[-1].type.t;
1527 t2 = vtop[0].type.t;
1528 bt1 = t1 & VT_BTYPE;
1529 bt2 = t2 & VT_BTYPE;
1531 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1532 /* at least one operand is a pointer */
1533 /* relationnal op: must be both pointers */
1534 if (op >= TOK_ULT && op <= TOK_LOR) {
1535 check_comparison_pointer_types(vtop - 1, vtop, op);
1536 /* pointers are handled are unsigned */
1537 #ifdef TCC_TARGET_X86_64
1538 t = VT_LLONG | VT_UNSIGNED;
1539 #else
1540 t = VT_INT | VT_UNSIGNED;
1541 #endif
1542 goto std_op;
1544 /* if both pointers, then it must be the '-' op */
1545 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1546 if (op != '-')
1547 error("cannot use pointers here");
1548 check_comparison_pointer_types(vtop - 1, vtop, op);
1549 /* XXX: check that types are compatible */
1550 u = pointed_size(&vtop[-1].type);
1551 gen_opic(op);
1552 /* set to integer type */
1553 #ifdef TCC_TARGET_X86_64
1554 vtop->type.t = VT_LLONG;
1555 #else
1556 vtop->type.t = VT_INT;
1557 #endif
1558 vpushi(u);
1559 gen_op(TOK_PDIV);
1560 } else {
1561 /* exactly one pointer : must be '+' or '-'. */
1562 if (op != '-' && op != '+')
1563 error("cannot use pointers here");
1564 /* Put pointer as first operand */
1565 if (bt2 == VT_PTR) {
1566 vswap();
1567 swap(&t1, &t2);
1569 type1 = vtop[-1].type;
1570 type1.t &= ~VT_ARRAY;
1571 u = pointed_size(&vtop[-1].type);
1572 if (u < 0)
1573 error("unknown array element size");
1574 #ifdef TCC_TARGET_X86_64
1575 vpushll(u);
1576 #else
1577 /* XXX: cast to int ? (long long case) */
1578 vpushi(u);
1579 #endif
1580 gen_op('*');
1581 #ifdef CONFIG_TCC_BCHECK
1582 /* if evaluating constant expression, no code should be
1583 generated, so no bound check */
1584 if (tcc_state->do_bounds_check && !const_wanted) {
1585 /* if bounded pointers, we generate a special code to
1586 test bounds */
1587 if (op == '-') {
1588 vpushi(0);
1589 vswap();
1590 gen_op('-');
1592 gen_bounded_ptr_add();
1593 } else
1594 #endif
1596 gen_opic(op);
1598 /* put again type if gen_opic() swaped operands */
1599 vtop->type = type1;
1601 } else if (is_float(bt1) || is_float(bt2)) {
1602 /* compute bigger type and do implicit casts */
1603 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1604 t = VT_LDOUBLE;
1605 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1606 t = VT_DOUBLE;
1607 } else {
1608 t = VT_FLOAT;
1610 /* floats can only be used for a few operations */
1611 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1612 (op < TOK_ULT || op > TOK_GT))
1613 error("invalid operands for binary operation");
1614 goto std_op;
1615 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1616 /* cast to biggest op */
1617 t = VT_LLONG;
1618 /* convert to unsigned if it does not fit in a long long */
1619 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1620 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1621 t |= VT_UNSIGNED;
1622 goto std_op;
1623 } else {
1624 /* integer operations */
1625 t = VT_INT;
1626 /* convert to unsigned if it does not fit in an integer */
1627 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1628 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1629 t |= VT_UNSIGNED;
1630 std_op:
1631 /* XXX: currently, some unsigned operations are explicit, so
1632 we modify them here */
1633 if (t & VT_UNSIGNED) {
1634 if (op == TOK_SAR)
1635 op = TOK_SHR;
1636 else if (op == '/')
1637 op = TOK_UDIV;
1638 else if (op == '%')
1639 op = TOK_UMOD;
1640 else if (op == TOK_LT)
1641 op = TOK_ULT;
1642 else if (op == TOK_GT)
1643 op = TOK_UGT;
1644 else if (op == TOK_LE)
1645 op = TOK_ULE;
1646 else if (op == TOK_GE)
1647 op = TOK_UGE;
1649 vswap();
1650 type1.t = t;
1651 gen_cast(&type1);
1652 vswap();
1653 /* special case for shifts and long long: we keep the shift as
1654 an integer */
1655 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1656 type1.t = VT_INT;
1657 gen_cast(&type1);
1658 if (is_float(t))
1659 gen_opif(op);
1660 else
1661 gen_opic(op);
1662 if (op >= TOK_ULT && op <= TOK_GT) {
1663 /* relationnal op: the result is an int */
1664 vtop->type.t = VT_INT;
1665 } else {
1666 vtop->type.t = t;
1671 #ifndef TCC_TARGET_ARM
1672 /* generic itof for unsigned long long case */
1673 static void gen_cvt_itof1(int t)
1675 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1676 (VT_LLONG | VT_UNSIGNED)) {
1678 if (t == VT_FLOAT)
1679 vpush_global_sym(&func_old_type, TOK___floatundisf);
1680 #if LDOUBLE_SIZE != 8
1681 else if (t == VT_LDOUBLE)
1682 vpush_global_sym(&func_old_type, TOK___floatundixf);
1683 #endif
1684 else
1685 vpush_global_sym(&func_old_type, TOK___floatundidf);
1686 vrott(2);
1687 gfunc_call(1);
1688 vpushi(0);
1689 vtop->r = reg_fret(t);
1690 } else {
1691 gen_cvt_itof(t);
1694 #endif
1696 /* generic ftoi for unsigned long long case */
1697 static void gen_cvt_ftoi1(int t)
1699 int st;
1701 if (t == (VT_LLONG | VT_UNSIGNED)) {
1702 /* not handled natively */
1703 st = vtop->type.t & VT_BTYPE;
1704 if (st == VT_FLOAT)
1705 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1706 #if LDOUBLE_SIZE != 8
1707 else if (st == VT_LDOUBLE)
1708 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1709 #endif
1710 else
1711 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1712 vrott(2);
1713 gfunc_call(1);
1714 vpushi(0);
1715 vtop->r = REG_IRET;
1716 vtop->r2 = REG_LRET;
1717 } else {
1718 gen_cvt_ftoi(t);
1722 /* force char or short cast */
1723 static void force_charshort_cast(int t)
1725 int bits, dbt;
1726 dbt = t & VT_BTYPE;
1727 /* XXX: add optimization if lvalue : just change type and offset */
1728 if (dbt == VT_BYTE)
1729 bits = 8;
1730 else
1731 bits = 16;
1732 if (t & VT_UNSIGNED) {
1733 vpushi((1 << bits) - 1);
1734 gen_op('&');
1735 } else {
1736 bits = 32 - bits;
1737 vpushi(bits);
1738 gen_op(TOK_SHL);
1739 /* result must be signed or the SAR is converted to an SHL
1740 This was not the case when "t" was a signed short
1741 and the last value on the stack was an unsigned int */
1742 vtop->type.t &= ~VT_UNSIGNED;
1743 vpushi(bits);
1744 gen_op(TOK_SAR);
1748 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1749 static void gen_cast(CType *type)
1751 int sbt, dbt, sf, df, c, p;
1753 /* special delayed cast for char/short */
1754 /* XXX: in some cases (multiple cascaded casts), it may still
1755 be incorrect */
1756 if (vtop->r & VT_MUSTCAST) {
1757 vtop->r &= ~VT_MUSTCAST;
1758 force_charshort_cast(vtop->type.t);
1761 /* bitfields first get cast to ints */
1762 if (vtop->type.t & VT_BITFIELD) {
1763 gv(RC_INT);
1766 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1767 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1769 if (sbt != dbt) {
1770 sf = is_float(sbt);
1771 df = is_float(dbt);
1772 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1773 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1774 if (c) {
1775 /* constant case: we can do it now */
1776 /* XXX: in ISOC, cannot do it if error in convert */
1777 if (sbt == VT_FLOAT)
1778 vtop->c.ld = vtop->c.f;
1779 else if (sbt == VT_DOUBLE)
1780 vtop->c.ld = vtop->c.d;
1782 if (df) {
1783 if ((sbt & VT_BTYPE) == VT_LLONG) {
1784 if (sbt & VT_UNSIGNED)
1785 vtop->c.ld = vtop->c.ull;
1786 else
1787 vtop->c.ld = vtop->c.ll;
1788 } else if(!sf) {
1789 if (sbt & VT_UNSIGNED)
1790 vtop->c.ld = vtop->c.ui;
1791 else
1792 vtop->c.ld = vtop->c.i;
1795 if (dbt == VT_FLOAT)
1796 vtop->c.f = (float)vtop->c.ld;
1797 else if (dbt == VT_DOUBLE)
1798 vtop->c.d = (double)vtop->c.ld;
1799 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1800 vtop->c.ull = (unsigned long long)vtop->c.ld;
1801 } else if (sf && dbt == VT_BOOL) {
1802 vtop->c.i = (vtop->c.ld != 0);
1803 } else {
1804 if(sf)
1805 vtop->c.ll = (long long)vtop->c.ld;
1806 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1807 vtop->c.ll = vtop->c.ull;
1808 else if (sbt & VT_UNSIGNED)
1809 vtop->c.ll = vtop->c.ui;
1810 #ifdef TCC_TARGET_X86_64
1811 else if (sbt == VT_PTR)
1813 #endif
1814 else if (sbt != VT_LLONG)
1815 vtop->c.ll = vtop->c.i;
1817 if (dbt == (VT_LLONG|VT_UNSIGNED))
1818 vtop->c.ull = vtop->c.ll;
1819 else if (dbt == VT_BOOL)
1820 vtop->c.i = (vtop->c.ll != 0);
1821 else if (dbt != VT_LLONG) {
1822 int s = 0;
1823 if ((dbt & VT_BTYPE) == VT_BYTE)
1824 s = 24;
1825 else if ((dbt & VT_BTYPE) == VT_SHORT)
1826 s = 16;
1828 if(dbt & VT_UNSIGNED)
1829 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1830 else
1831 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1834 } else if (p && dbt == VT_BOOL) {
1835 vtop->r = VT_CONST;
1836 vtop->c.i = 1;
1837 } else if (!nocode_wanted) {
1838 /* non constant case: generate code */
1839 if (sf && df) {
1840 /* convert from fp to fp */
1841 gen_cvt_ftof(dbt);
1842 } else if (df) {
1843 /* convert int to fp */
1844 gen_cvt_itof1(dbt);
1845 } else if (sf) {
1846 /* convert fp to int */
1847 if (dbt == VT_BOOL) {
1848 vpushi(0);
1849 gen_op(TOK_NE);
1850 } else {
1851 /* we handle char/short/etc... with generic code */
1852 if (dbt != (VT_INT | VT_UNSIGNED) &&
1853 dbt != (VT_LLONG | VT_UNSIGNED) &&
1854 dbt != VT_LLONG)
1855 dbt = VT_INT;
1856 gen_cvt_ftoi1(dbt);
1857 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1858 /* additional cast for char/short... */
1859 vtop->type.t = dbt;
1860 gen_cast(type);
1863 #ifndef TCC_TARGET_X86_64
1864 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1865 if ((sbt & VT_BTYPE) != VT_LLONG) {
1866 /* scalar to long long */
1867 /* machine independent conversion */
1868 gv(RC_INT);
1869 /* generate high word */
1870 if (sbt == (VT_INT | VT_UNSIGNED)) {
1871 vpushi(0);
1872 gv(RC_INT);
1873 } else {
1874 if (sbt == VT_PTR) {
1875 /* cast from pointer to int before we apply
1876 shift operation, which pointers don't support*/
1877 gen_cast(&int_type);
1879 gv_dup();
1880 vpushi(31);
1881 gen_op(TOK_SAR);
1883 /* patch second register */
1884 vtop[-1].r2 = vtop->r;
1885 vpop();
1887 #else
1888 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1889 (dbt & VT_BTYPE) == VT_PTR ||
1890 (dbt & VT_BTYPE) == VT_FUNC) {
1891 if ((sbt & VT_BTYPE) != VT_LLONG &&
1892 (sbt & VT_BTYPE) != VT_PTR &&
1893 (sbt & VT_BTYPE) != VT_FUNC) {
1894 /* need to convert from 32bit to 64bit */
1895 int r = gv(RC_INT);
1896 if (sbt != (VT_INT | VT_UNSIGNED)) {
1897 /* x86_64 specific: movslq */
1898 o(0x6348);
1899 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1902 #endif
1903 } else if (dbt == VT_BOOL) {
1904 /* scalar to bool */
1905 vpushi(0);
1906 gen_op(TOK_NE);
1907 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1908 (dbt & VT_BTYPE) == VT_SHORT) {
1909 if (sbt == VT_PTR) {
1910 vtop->type.t = VT_INT;
1911 warning("nonportable conversion from pointer to char/short");
1913 force_charshort_cast(dbt);
1914 } else if ((dbt & VT_BTYPE) == VT_INT) {
1915 /* scalar to int */
1916 if (sbt == VT_LLONG) {
1917 /* from long long: just take low order word */
1918 lexpand();
1919 vpop();
1921 /* if lvalue and single word type, nothing to do because
1922 the lvalue already contains the real type size (see
1923 VT_LVAL_xxx constants) */
1926 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1927 /* if we are casting between pointer types,
1928 we must update the VT_LVAL_xxx size */
1929 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1930 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1932 vtop->type = *type;
1935 /* return type size. Put alignment at 'a' */
1936 ST_FUNC int type_size(CType *type, int *a)
1938 Sym *s;
1939 int bt;
1941 bt = type->t & VT_BTYPE;
1942 if (bt == VT_STRUCT) {
1943 /* struct/union */
1944 s = type->ref;
1945 *a = s->r;
1946 return s->c;
1947 } else if (bt == VT_PTR) {
1948 if (type->t & VT_ARRAY) {
1949 int ts;
1951 s = type->ref;
1952 ts = type_size(&s->type, a);
1954 if (ts < 0 && s->c < 0)
1955 ts = -ts;
1957 return ts * s->c;
1958 } else {
1959 *a = PTR_SIZE;
1960 return PTR_SIZE;
1962 } else if (bt == VT_LDOUBLE) {
1963 *a = LDOUBLE_ALIGN;
1964 return LDOUBLE_SIZE;
1965 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
1966 #ifdef TCC_TARGET_I386
1967 #ifdef TCC_TARGET_PE
1968 *a = 8;
1969 #else
1970 *a = 4;
1971 #endif
1972 #elif defined(TCC_TARGET_ARM)
1973 #ifdef TCC_ARM_EABI
1974 *a = 8;
1975 #else
1976 *a = 4;
1977 #endif
1978 #else
1979 *a = 8;
1980 #endif
1981 return 8;
1982 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
1983 *a = 4;
1984 return 4;
1985 } else if (bt == VT_SHORT) {
1986 *a = 2;
1987 return 2;
1988 } else {
1989 /* char, void, function, _Bool */
1990 *a = 1;
1991 return 1;
1995 /* return the pointed type of t */
1996 static inline CType *pointed_type(CType *type)
1998 return &type->ref->type;
2001 /* modify type so that its it is a pointer to type. */
2002 ST_FUNC void mk_pointer(CType *type)
2004 Sym *s;
2005 s = sym_push(SYM_FIELD, type, 0, -1);
2006 type->t = VT_PTR | (type->t & ~VT_TYPE);
2007 type->ref = s;
2010 /* compare function types. OLD functions match any new functions */
2011 static int is_compatible_func(CType *type1, CType *type2)
2013 Sym *s1, *s2;
2015 s1 = type1->ref;
2016 s2 = type2->ref;
2017 if (!is_compatible_types(&s1->type, &s2->type))
2018 return 0;
2019 /* check func_call */
2020 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2021 return 0;
2022 /* XXX: not complete */
2023 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2024 return 1;
2025 if (s1->c != s2->c)
2026 return 0;
2027 while (s1 != NULL) {
2028 if (s2 == NULL)
2029 return 0;
2030 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2031 return 0;
2032 s1 = s1->next;
2033 s2 = s2->next;
2035 if (s2)
2036 return 0;
2037 return 1;
2040 /* return true if type1 and type2 are the same. If unqualified is
2041 true, qualifiers on the types are ignored.
2043 - enums are not checked as gcc __builtin_types_compatible_p ()
2045 static int compare_types(CType *type1, CType *type2, int unqualified)
2047 int bt1, t1, t2;
2049 t1 = type1->t & VT_TYPE;
2050 t2 = type2->t & VT_TYPE;
2051 if (unqualified) {
2052 /* strip qualifiers before comparing */
2053 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2054 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2056 /* XXX: bitfields ? */
2057 if (t1 != t2)
2058 return 0;
2059 /* test more complicated cases */
2060 bt1 = t1 & VT_BTYPE;
2061 if (bt1 == VT_PTR) {
2062 type1 = pointed_type(type1);
2063 type2 = pointed_type(type2);
2064 return is_compatible_types(type1, type2);
2065 } else if (bt1 == VT_STRUCT) {
2066 return (type1->ref == type2->ref);
2067 } else if (bt1 == VT_FUNC) {
2068 return is_compatible_func(type1, type2);
2069 } else {
2070 return 1;
2074 /* return true if type1 and type2 are exactly the same (including
2075 qualifiers).
2077 static int is_compatible_types(CType *type1, CType *type2)
2079 return compare_types(type1,type2,0);
2082 /* return true if type1 and type2 are the same (ignoring qualifiers).
2084 static int is_compatible_parameter_types(CType *type1, CType *type2)
2086 return compare_types(type1,type2,1);
2089 /* print a type. If 'varstr' is not NULL, then the variable is also
2090 printed in the type */
2091 /* XXX: union */
2092 /* XXX: add array and function pointers */
2093 static void type_to_str(char *buf, int buf_size,
2094 CType *type, const char *varstr)
2096 int bt, v, t;
2097 Sym *s, *sa;
2098 char buf1[256];
2099 const char *tstr;
2101 t = type->t & VT_TYPE;
2102 bt = t & VT_BTYPE;
2103 buf[0] = '\0';
2104 if (t & VT_CONSTANT)
2105 pstrcat(buf, buf_size, "const ");
2106 if (t & VT_VOLATILE)
2107 pstrcat(buf, buf_size, "volatile ");
2108 if (t & VT_UNSIGNED)
2109 pstrcat(buf, buf_size, "unsigned ");
2110 switch(bt) {
2111 case VT_VOID:
2112 tstr = "void";
2113 goto add_tstr;
2114 case VT_BOOL:
2115 tstr = "_Bool";
2116 goto add_tstr;
2117 case VT_BYTE:
2118 tstr = "char";
2119 goto add_tstr;
2120 case VT_SHORT:
2121 tstr = "short";
2122 goto add_tstr;
2123 case VT_INT:
2124 tstr = "int";
2125 goto add_tstr;
2126 case VT_LONG:
2127 tstr = "long";
2128 goto add_tstr;
2129 case VT_LLONG:
2130 tstr = "long long";
2131 goto add_tstr;
2132 case VT_FLOAT:
2133 tstr = "float";
2134 goto add_tstr;
2135 case VT_DOUBLE:
2136 tstr = "double";
2137 goto add_tstr;
2138 case VT_LDOUBLE:
2139 tstr = "long double";
2140 add_tstr:
2141 pstrcat(buf, buf_size, tstr);
2142 break;
2143 case VT_ENUM:
2144 case VT_STRUCT:
2145 if (bt == VT_STRUCT)
2146 tstr = "struct ";
2147 else
2148 tstr = "enum ";
2149 pstrcat(buf, buf_size, tstr);
2150 v = type->ref->v & ~SYM_STRUCT;
2151 if (v >= SYM_FIRST_ANOM)
2152 pstrcat(buf, buf_size, "<anonymous>");
2153 else
2154 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2155 break;
2156 case VT_FUNC:
2157 s = type->ref;
2158 type_to_str(buf, buf_size, &s->type, varstr);
2159 pstrcat(buf, buf_size, "(");
2160 sa = s->next;
2161 while (sa != NULL) {
2162 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2163 pstrcat(buf, buf_size, buf1);
2164 sa = sa->next;
2165 if (sa)
2166 pstrcat(buf, buf_size, ", ");
2168 pstrcat(buf, buf_size, ")");
2169 goto no_var;
2170 case VT_PTR:
2171 s = type->ref;
2172 pstrcpy(buf1, sizeof(buf1), "*");
2173 if (varstr)
2174 pstrcat(buf1, sizeof(buf1), varstr);
2175 type_to_str(buf, buf_size, &s->type, buf1);
2176 goto no_var;
2178 if (varstr) {
2179 pstrcat(buf, buf_size, " ");
2180 pstrcat(buf, buf_size, varstr);
2182 no_var: ;
2185 /* verify type compatibility to store vtop in 'dt' type, and generate
2186 casts if needed. */
2187 static void gen_assign_cast(CType *dt)
2189 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2190 char buf1[256], buf2[256];
2191 int dbt, sbt;
2193 st = &vtop->type; /* source type */
2194 dbt = dt->t & VT_BTYPE;
2195 sbt = st->t & VT_BTYPE;
2196 if (dt->t & VT_CONSTANT)
2197 warning("assignment of read-only location");
2198 switch(dbt) {
2199 case VT_PTR:
2200 /* special cases for pointers */
2201 /* '0' can also be a pointer */
2202 if (is_null_pointer(vtop))
2203 goto type_ok;
2204 /* accept implicit pointer to integer cast with warning */
2205 if (is_integer_btype(sbt)) {
2206 warning("assignment makes pointer from integer without a cast");
2207 goto type_ok;
2209 type1 = pointed_type(dt);
2210 /* a function is implicitely a function pointer */
2211 if (sbt == VT_FUNC) {
2212 if ((type1->t & VT_BTYPE) != VT_VOID &&
2213 !is_compatible_types(pointed_type(dt), st))
2214 warning("assignment from incompatible pointer type");
2215 goto type_ok;
2217 if (sbt != VT_PTR)
2218 goto error;
2219 type2 = pointed_type(st);
2220 if ((type1->t & VT_BTYPE) == VT_VOID ||
2221 (type2->t & VT_BTYPE) == VT_VOID) {
2222 /* void * can match anything */
2223 } else {
2224 /* exact type match, except for unsigned */
2225 tmp_type1 = *type1;
2226 tmp_type2 = *type2;
2227 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2228 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2229 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2230 warning("assignment from incompatible pointer type");
2232 /* check const and volatile */
2233 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2234 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2235 warning("assignment discards qualifiers from pointer target type");
2236 break;
2237 case VT_BYTE:
2238 case VT_SHORT:
2239 case VT_INT:
2240 case VT_LLONG:
2241 if (sbt == VT_PTR || sbt == VT_FUNC) {
2242 warning("assignment makes integer from pointer without a cast");
2244 /* XXX: more tests */
2245 break;
2246 case VT_STRUCT:
2247 tmp_type1 = *dt;
2248 tmp_type2 = *st;
2249 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2250 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2251 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2252 error:
2253 type_to_str(buf1, sizeof(buf1), st, NULL);
2254 type_to_str(buf2, sizeof(buf2), dt, NULL);
2255 error("cannot cast '%s' to '%s'", buf1, buf2);
2257 break;
2259 type_ok:
2260 gen_cast(dt);
2263 /* store vtop in lvalue pushed on stack */
2264 ST_FUNC void vstore(void)
2266 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2268 ft = vtop[-1].type.t;
2269 sbt = vtop->type.t & VT_BTYPE;
2270 dbt = ft & VT_BTYPE;
2271 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2272 (sbt == VT_INT && dbt == VT_SHORT)) {
2273 /* optimize char/short casts */
2274 delayed_cast = VT_MUSTCAST;
2275 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2276 /* XXX: factorize */
2277 if (ft & VT_CONSTANT)
2278 warning("assignment of read-only location");
2279 } else {
2280 delayed_cast = 0;
2281 if (!(ft & VT_BITFIELD))
2282 gen_assign_cast(&vtop[-1].type);
2285 if (sbt == VT_STRUCT) {
2286 /* if structure, only generate pointer */
2287 /* structure assignment : generate memcpy */
2288 /* XXX: optimize if small size */
2289 if (!nocode_wanted) {
2290 size = type_size(&vtop->type, &align);
2292 /* destination */
2293 vswap();
2294 vtop->type.t = VT_PTR;
2295 gaddrof();
2297 /* address of memcpy() */
2298 #ifdef TCC_ARM_EABI
2299 if(!(align & 7))
2300 vpush_global_sym(&func_old_type, TOK_memcpy8);
2301 else if(!(align & 3))
2302 vpush_global_sym(&func_old_type, TOK_memcpy4);
2303 else
2304 #endif
2305 vpush_global_sym(&func_old_type, TOK_memcpy);
2307 vswap();
2308 /* source */
2309 vpushv(vtop - 2);
2310 vtop->type.t = VT_PTR;
2311 gaddrof();
2312 /* type size */
2313 vpushi(size);
2314 gfunc_call(3);
2315 } else {
2316 vswap();
2317 vpop();
2319 /* leave source on stack */
2320 } else if (ft & VT_BITFIELD) {
2321 /* bitfield store handling */
2322 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2323 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2324 /* remove bit field info to avoid loops */
2325 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2327 /* duplicate source into other register */
2328 gv_dup();
2329 vswap();
2330 vrott(3);
2332 if((ft & VT_BTYPE) == VT_BOOL) {
2333 gen_cast(&vtop[-1].type);
2334 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2337 /* duplicate destination */
2338 vdup();
2339 vtop[-1] = vtop[-2];
2341 /* mask and shift source */
2342 if((ft & VT_BTYPE) != VT_BOOL) {
2343 if((ft & VT_BTYPE) == VT_LLONG) {
2344 vpushll((1ULL << bit_size) - 1ULL);
2345 } else {
2346 vpushi((1 << bit_size) - 1);
2348 gen_op('&');
2350 vpushi(bit_pos);
2351 gen_op(TOK_SHL);
2352 /* load destination, mask and or with source */
2353 vswap();
2354 if((ft & VT_BTYPE) == VT_LLONG) {
2355 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2356 } else {
2357 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2359 gen_op('&');
2360 gen_op('|');
2361 /* store result */
2362 vstore();
2364 /* pop off shifted source from "duplicate source..." above */
2365 vpop();
2367 } else {
2368 #ifdef CONFIG_TCC_BCHECK
2369 /* bound check case */
2370 if (vtop[-1].r & VT_MUSTBOUND) {
2371 vswap();
2372 gbound();
2373 vswap();
2375 #endif
2376 if (!nocode_wanted) {
2377 rc = RC_INT;
2378 if (is_float(ft)) {
2379 rc = RC_FLOAT;
2380 #ifdef TCC_TARGET_X86_64
2381 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2382 rc = RC_ST0;
2384 #endif
2386 r = gv(rc); /* generate value */
2387 /* if lvalue was saved on stack, must read it */
2388 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2389 SValue sv;
2390 t = get_reg(RC_INT);
2391 #ifdef TCC_TARGET_X86_64
2392 sv.type.t = VT_PTR;
2393 #else
2394 sv.type.t = VT_INT;
2395 #endif
2396 sv.r = VT_LOCAL | VT_LVAL;
2397 sv.c.ul = vtop[-1].c.ul;
2398 load(t, &sv);
2399 vtop[-1].r = t | VT_LVAL;
2401 store(r, vtop - 1);
2402 #ifndef TCC_TARGET_X86_64
2403 /* two word case handling : store second register at word + 4 */
2404 if ((ft & VT_BTYPE) == VT_LLONG) {
2405 vswap();
2406 /* convert to int to increment easily */
2407 vtop->type.t = VT_INT;
2408 gaddrof();
2409 vpushi(4);
2410 gen_op('+');
2411 vtop->r |= VT_LVAL;
2412 vswap();
2413 /* XXX: it works because r2 is spilled last ! */
2414 store(vtop->r2, vtop - 1);
2416 #endif
2418 vswap();
2419 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2420 vtop->r |= delayed_cast;
2424 /* post defines POST/PRE add. c is the token ++ or -- */
2425 ST_FUNC void inc(int post, int c)
2427 test_lvalue();
2428 vdup(); /* save lvalue */
2429 if (post) {
2430 gv_dup(); /* duplicate value */
2431 vrotb(3);
2432 vrotb(3);
2434 /* add constant */
2435 vpushi(c - TOK_MID);
2436 gen_op('+');
2437 vstore(); /* store value */
2438 if (post)
2439 vpop(); /* if post op, return saved value */
2442 /* Parse GNUC __attribute__ extension. Currently, the following
2443 extensions are recognized:
2444 - aligned(n) : set data/function alignment.
2445 - packed : force data alignment to 1
2446 - section(x) : generate data/code in this section.
2447 - unused : currently ignored, but may be used someday.
2448 - regparm(n) : pass function parameters in registers (i386 only)
2450 static void parse_attribute(AttributeDef *ad)
2452 int t, n;
2454 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2455 next();
2456 skip('(');
2457 skip('(');
2458 while (tok != ')') {
2459 if (tok < TOK_IDENT)
2460 expect("attribute name");
2461 t = tok;
2462 next();
2463 switch(t) {
2464 case TOK_SECTION1:
2465 case TOK_SECTION2:
2466 skip('(');
2467 if (tok != TOK_STR)
2468 expect("section name");
2469 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2470 next();
2471 skip(')');
2472 break;
2473 case TOK_ALIGNED1:
2474 case TOK_ALIGNED2:
2475 if (tok == '(') {
2476 next();
2477 n = expr_const();
2478 if (n <= 0 || (n & (n - 1)) != 0)
2479 error("alignment must be a positive power of two");
2480 skip(')');
2481 } else {
2482 n = MAX_ALIGN;
2484 ad->aligned = n;
2485 break;
2486 case TOK_PACKED1:
2487 case TOK_PACKED2:
2488 ad->packed = 1;
2489 break;
2490 case TOK_WEAK1:
2491 case TOK_WEAK2:
2492 ad->weak = 1;
2493 break;
2494 case TOK_UNUSED1:
2495 case TOK_UNUSED2:
2496 /* currently, no need to handle it because tcc does not
2497 track unused objects */
2498 break;
2499 case TOK_NORETURN1:
2500 case TOK_NORETURN2:
2501 /* currently, no need to handle it because tcc does not
2502 track unused objects */
2503 break;
2504 case TOK_CDECL1:
2505 case TOK_CDECL2:
2506 case TOK_CDECL3:
2507 ad->func_call = FUNC_CDECL;
2508 break;
2509 case TOK_STDCALL1:
2510 case TOK_STDCALL2:
2511 case TOK_STDCALL3:
2512 ad->func_call = FUNC_STDCALL;
2513 break;
2514 #ifdef TCC_TARGET_I386
2515 case TOK_REGPARM1:
2516 case TOK_REGPARM2:
2517 skip('(');
2518 n = expr_const();
2519 if (n > 3)
2520 n = 3;
2521 else if (n < 0)
2522 n = 0;
2523 if (n > 0)
2524 ad->func_call = FUNC_FASTCALL1 + n - 1;
2525 skip(')');
2526 break;
2527 case TOK_FASTCALL1:
2528 case TOK_FASTCALL2:
2529 case TOK_FASTCALL3:
2530 ad->func_call = FUNC_FASTCALLW;
2531 break;
2532 #endif
2533 case TOK_MODE:
2534 skip('(');
2535 switch(tok) {
2536 case TOK_MODE_DI:
2537 ad->mode = VT_LLONG + 1;
2538 break;
2539 case TOK_MODE_HI:
2540 ad->mode = VT_SHORT + 1;
2541 break;
2542 case TOK_MODE_SI:
2543 ad->mode = VT_INT + 1;
2544 break;
2545 default:
2546 warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2547 break;
2549 next();
2550 skip(')');
2551 break;
2552 case TOK_DLLEXPORT:
2553 ad->func_export = 1;
2554 break;
2555 case TOK_DLLIMPORT:
2556 ad->func_import = 1;
2557 break;
2558 default:
2559 if (tcc_state->warn_unsupported)
2560 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2561 /* skip parameters */
2562 if (tok == '(') {
2563 int parenthesis = 0;
2564 do {
2565 if (tok == '(')
2566 parenthesis++;
2567 else if (tok == ')')
2568 parenthesis--;
2569 next();
2570 } while (parenthesis && tok != -1);
2572 break;
2574 if (tok != ',')
2575 break;
2576 next();
2578 skip(')');
2579 skip(')');
2583 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2584 static void struct_decl(CType *type, int u)
2586 int a, v, size, align, maxalign, c, offset;
2587 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2588 Sym *s, *ss, *ass, **ps;
2589 AttributeDef ad;
2590 CType type1, btype;
2592 a = tok; /* save decl type */
2593 next();
2594 if (tok != '{') {
2595 v = tok;
2596 next();
2597 /* struct already defined ? return it */
2598 if (v < TOK_IDENT)
2599 expect("struct/union/enum name");
2600 s = struct_find(v);
2601 if (s) {
2602 if (s->type.t != a)
2603 error("invalid type");
2604 goto do_decl;
2606 } else {
2607 v = anon_sym++;
2609 type1.t = a;
2610 /* we put an undefined size for struct/union */
2611 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2612 s->r = 0; /* default alignment is zero as gcc */
2613 /* put struct/union/enum name in type */
2614 do_decl:
2615 type->t = u;
2616 type->ref = s;
2618 if (tok == '{') {
2619 next();
2620 if (s->c != -1)
2621 error("struct/union/enum already defined");
2622 /* cannot be empty */
2623 c = 0;
2624 /* non empty enums are not allowed */
2625 if (a == TOK_ENUM) {
2626 for(;;) {
2627 v = tok;
2628 if (v < TOK_UIDENT)
2629 expect("identifier");
2630 next();
2631 if (tok == '=') {
2632 next();
2633 c = expr_const();
2635 /* enum symbols have static storage */
2636 ss = sym_push(v, &int_type, VT_CONST, c);
2637 ss->type.t |= VT_STATIC;
2638 if (tok != ',')
2639 break;
2640 next();
2641 c++;
2642 /* NOTE: we accept a trailing comma */
2643 if (tok == '}')
2644 break;
2646 skip('}');
2647 } else {
2648 maxalign = 1;
2649 ps = &s->next;
2650 prevbt = VT_INT;
2651 bit_pos = 0;
2652 offset = 0;
2653 while (tok != '}') {
2654 parse_btype(&btype, &ad);
2655 while (1) {
2656 bit_size = -1;
2657 v = 0;
2658 type1 = btype;
2659 if (tok != ':') {
2660 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2661 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2662 expect("identifier");
2663 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2664 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2665 error("invalid type for '%s'",
2666 get_tok_str(v, NULL));
2668 if (tok == ':') {
2669 next();
2670 bit_size = expr_const();
2671 /* XXX: handle v = 0 case for messages */
2672 if (bit_size < 0)
2673 error("negative width in bit-field '%s'",
2674 get_tok_str(v, NULL));
2675 if (v && bit_size == 0)
2676 error("zero width for bit-field '%s'",
2677 get_tok_str(v, NULL));
2679 size = type_size(&type1, &align);
2680 if (ad.aligned) {
2681 if (align < ad.aligned)
2682 align = ad.aligned;
2683 } else if (ad.packed) {
2684 align = 1;
2685 } else if (*tcc_state->pack_stack_ptr) {
2686 if (align > *tcc_state->pack_stack_ptr)
2687 align = *tcc_state->pack_stack_ptr;
2689 lbit_pos = 0;
2690 if (bit_size >= 0) {
2691 bt = type1.t & VT_BTYPE;
2692 if (bt != VT_INT &&
2693 bt != VT_BYTE &&
2694 bt != VT_SHORT &&
2695 bt != VT_BOOL &&
2696 bt != VT_ENUM &&
2697 bt != VT_LLONG)
2698 error("bitfields must have scalar type");
2699 bsize = size * 8;
2700 if (bit_size > bsize) {
2701 error("width of '%s' exceeds its type",
2702 get_tok_str(v, NULL));
2703 } else if (bit_size == bsize) {
2704 /* no need for bit fields */
2705 bit_pos = 0;
2706 } else if (bit_size == 0) {
2707 /* XXX: what to do if only padding in a
2708 structure ? */
2709 /* zero size: means to pad */
2710 bit_pos = 0;
2711 } else {
2712 /* we do not have enough room ?
2713 did the type change?
2714 is it a union? */
2715 if ((bit_pos + bit_size) > bsize ||
2716 bt != prevbt || a == TOK_UNION)
2717 bit_pos = 0;
2718 lbit_pos = bit_pos;
2719 /* XXX: handle LSB first */
2720 type1.t |= VT_BITFIELD |
2721 (bit_pos << VT_STRUCT_SHIFT) |
2722 (bit_size << (VT_STRUCT_SHIFT + 6));
2723 bit_pos += bit_size;
2725 prevbt = bt;
2726 } else {
2727 bit_pos = 0;
2729 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2730 /* add new memory data only if starting
2731 bit field */
2732 if (lbit_pos == 0) {
2733 if (a == TOK_STRUCT) {
2734 c = (c + align - 1) & -align;
2735 offset = c;
2736 if (size > 0)
2737 c += size;
2738 } else {
2739 offset = 0;
2740 if (size > c)
2741 c = size;
2743 if (align > maxalign)
2744 maxalign = align;
2746 #if 0
2747 printf("add field %s offset=%d",
2748 get_tok_str(v, NULL), offset);
2749 if (type1.t & VT_BITFIELD) {
2750 printf(" pos=%d size=%d",
2751 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2752 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2754 printf("\n");
2755 #endif
2757 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2758 ass = type1.ref;
2759 while ((ass = ass->next) != NULL) {
2760 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2761 *ps = ss;
2762 ps = &ss->next;
2764 } else if (v) {
2765 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2766 *ps = ss;
2767 ps = &ss->next;
2769 if (tok == ';' || tok == TOK_EOF)
2770 break;
2771 skip(',');
2773 skip(';');
2775 skip('}');
2776 /* store size and alignment */
2777 s->c = (c + maxalign - 1) & -maxalign;
2778 s->r = maxalign;
2783 /* return 0 if no type declaration. otherwise, return the basic type
2784 and skip it.
2786 static int parse_btype(CType *type, AttributeDef *ad)
2788 int t, u, type_found, typespec_found, typedef_found;
2789 Sym *s;
2790 CType type1;
2792 memset(ad, 0, sizeof(AttributeDef));
2793 type_found = 0;
2794 typespec_found = 0;
2795 typedef_found = 0;
2796 t = 0;
2797 while(1) {
2798 switch(tok) {
2799 case TOK_EXTENSION:
2800 /* currently, we really ignore extension */
2801 next();
2802 continue;
2804 /* basic types */
2805 case TOK_CHAR:
2806 u = VT_BYTE;
2807 basic_type:
2808 next();
2809 basic_type1:
2810 if ((t & VT_BTYPE) != 0)
2811 error("too many basic types");
2812 t |= u;
2813 typespec_found = 1;
2814 break;
2815 case TOK_VOID:
2816 u = VT_VOID;
2817 goto basic_type;
2818 case TOK_SHORT:
2819 u = VT_SHORT;
2820 goto basic_type;
2821 case TOK_INT:
2822 next();
2823 typespec_found = 1;
2824 break;
2825 case TOK_LONG:
2826 next();
2827 if ((t & VT_BTYPE) == VT_DOUBLE) {
2828 #ifndef TCC_TARGET_PE
2829 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2830 #endif
2831 } else if ((t & VT_BTYPE) == VT_LONG) {
2832 t = (t & ~VT_BTYPE) | VT_LLONG;
2833 } else {
2834 u = VT_LONG;
2835 goto basic_type1;
2837 break;
2838 case TOK_BOOL:
2839 u = VT_BOOL;
2840 goto basic_type;
2841 case TOK_FLOAT:
2842 u = VT_FLOAT;
2843 goto basic_type;
2844 case TOK_DOUBLE:
2845 next();
2846 if ((t & VT_BTYPE) == VT_LONG) {
2847 #ifdef TCC_TARGET_PE
2848 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2849 #else
2850 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2851 #endif
2852 } else {
2853 u = VT_DOUBLE;
2854 goto basic_type1;
2856 break;
2857 case TOK_ENUM:
2858 struct_decl(&type1, VT_ENUM);
2859 basic_type2:
2860 u = type1.t;
2861 type->ref = type1.ref;
2862 goto basic_type1;
2863 case TOK_STRUCT:
2864 case TOK_UNION:
2865 struct_decl(&type1, VT_STRUCT);
2866 goto basic_type2;
2868 /* type modifiers */
2869 case TOK_CONST1:
2870 case TOK_CONST2:
2871 case TOK_CONST3:
2872 t |= VT_CONSTANT;
2873 next();
2874 break;
2875 case TOK_VOLATILE1:
2876 case TOK_VOLATILE2:
2877 case TOK_VOLATILE3:
2878 t |= VT_VOLATILE;
2879 next();
2880 break;
2881 case TOK_SIGNED1:
2882 case TOK_SIGNED2:
2883 case TOK_SIGNED3:
2884 typespec_found = 1;
2885 t |= VT_SIGNED;
2886 next();
2887 break;
2888 case TOK_REGISTER:
2889 case TOK_AUTO:
2890 case TOK_RESTRICT1:
2891 case TOK_RESTRICT2:
2892 case TOK_RESTRICT3:
2893 next();
2894 break;
2895 case TOK_UNSIGNED:
2896 t |= VT_UNSIGNED;
2897 next();
2898 typespec_found = 1;
2899 break;
2901 /* storage */
2902 case TOK_EXTERN:
2903 t |= VT_EXTERN;
2904 next();
2905 break;
2906 case TOK_STATIC:
2907 t |= VT_STATIC;
2908 next();
2909 break;
2910 case TOK_TYPEDEF:
2911 t |= VT_TYPEDEF;
2912 next();
2913 break;
2914 case TOK_INLINE1:
2915 case TOK_INLINE2:
2916 case TOK_INLINE3:
2917 t |= VT_INLINE;
2918 next();
2919 break;
2921 /* GNUC attribute */
2922 case TOK_ATTRIBUTE1:
2923 case TOK_ATTRIBUTE2:
2924 parse_attribute(ad);
2925 if (ad->mode) {
2926 u = ad->mode -1;
2927 t = (t & ~VT_BTYPE) | u;
2929 break;
2930 /* GNUC typeof */
2931 case TOK_TYPEOF1:
2932 case TOK_TYPEOF2:
2933 case TOK_TYPEOF3:
2934 next();
2935 parse_expr_type(&type1);
2936 goto basic_type2;
2937 default:
2938 if (typespec_found || typedef_found)
2939 goto the_end;
2940 s = sym_find(tok);
2941 if (!s || !(s->type.t & VT_TYPEDEF))
2942 goto the_end;
2943 typedef_found = 1;
2944 t |= (s->type.t & ~VT_TYPEDEF);
2945 type->ref = s->type.ref;
2946 if (s->r) {
2947 /* get attributes from typedef */
2948 if (0 == ad->aligned)
2949 ad->aligned = FUNC_ALIGN(s->r);
2950 if (0 == ad->func_call)
2951 ad->func_call = FUNC_CALL(s->r);
2952 ad->packed |= FUNC_PACKED(s->r);
2954 next();
2955 typespec_found = 1;
2956 break;
2958 type_found = 1;
2960 the_end:
2961 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
2962 error("signed and unsigned modifier");
2963 if (tcc_state->char_is_unsigned) {
2964 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
2965 t |= VT_UNSIGNED;
2967 t &= ~VT_SIGNED;
2969 /* long is never used as type */
2970 if ((t & VT_BTYPE) == VT_LONG)
2971 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
2972 t = (t & ~VT_BTYPE) | VT_INT;
2973 #else
2974 t = (t & ~VT_BTYPE) | VT_LLONG;
2975 #endif
2976 type->t = t;
2977 return type_found;
2980 /* convert a function parameter type (array to pointer and function to
2981 function pointer) */
2982 static inline void convert_parameter_type(CType *pt)
2984 /* remove const and volatile qualifiers (XXX: const could be used
2985 to indicate a const function parameter */
2986 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
2987 /* array must be transformed to pointer according to ANSI C */
2988 pt->t &= ~VT_ARRAY;
2989 if ((pt->t & VT_BTYPE) == VT_FUNC) {
2990 mk_pointer(pt);
2994 ST_FUNC void parse_asm_str(CString *astr)
2996 skip('(');
2997 /* read the string */
2998 if (tok != TOK_STR)
2999 expect("string constant");
3000 cstr_new(astr);
3001 while (tok == TOK_STR) {
3002 /* XXX: add \0 handling too ? */
3003 cstr_cat(astr, tokc.cstr->data);
3004 next();
3006 cstr_ccat(astr, '\0');
3009 /* Parse an asm label and return the label
3010 * Don't forget to free the CString in the caller! */
3011 static void asm_label_instr(CString *astr)
3013 next();
3014 parse_asm_str(astr);
3015 skip(')');
3016 #ifdef ASM_DEBUG
3017 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3018 #endif
3021 static void post_type(CType *type, AttributeDef *ad)
3023 int n, l, t1, arg_size, align;
3024 Sym **plast, *s, *first;
3025 AttributeDef ad1;
3026 CType pt;
3028 if (tok == '(') {
3029 TokenSym *ts = NULL;
3031 /* function declaration */
3032 next();
3033 l = 0;
3034 first = NULL;
3035 plast = &first;
3036 arg_size = 0;
3037 if (tok != ')') {
3038 for(;;) {
3039 /* read param name and compute offset */
3040 if (l != FUNC_OLD) {
3041 if (!parse_btype(&pt, &ad1)) {
3042 if (l) {
3043 error("invalid type");
3044 } else {
3045 l = FUNC_OLD;
3046 goto old_proto;
3049 l = FUNC_NEW;
3050 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3051 break;
3052 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3053 if ((pt.t & VT_BTYPE) == VT_VOID)
3054 error("parameter declared as void");
3055 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3056 } else {
3057 old_proto:
3058 n = tok;
3059 if (n < TOK_UIDENT)
3060 expect("identifier");
3061 pt.t = VT_INT;
3062 next();
3064 convert_parameter_type(&pt);
3065 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3066 *plast = s;
3067 plast = &s->next;
3068 if (tok == ')')
3069 break;
3070 skip(',');
3071 if (l == FUNC_NEW && tok == TOK_DOTS) {
3072 l = FUNC_ELLIPSIS;
3073 next();
3074 break;
3078 /* if no parameters, then old type prototype */
3079 if (l == 0)
3080 l = FUNC_OLD;
3081 skip(')');
3082 t1 = type->t & VT_STORAGE;
3083 /* NOTE: const is ignored in returned type as it has a special
3084 meaning in gcc / C++ */
3085 type->t &= ~(VT_STORAGE | VT_CONSTANT);
3086 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
3087 CString astr;
3089 asm_label_instr(&astr);
3090 ts = tok_alloc(astr.data, strlen(astr.data));
3091 cstr_free(&astr);
3093 post_type(type, ad);
3094 /* we push a anonymous symbol which will contain the function prototype */
3095 ad->func_args = arg_size;
3096 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3097 if (ts != NULL)
3098 s->a = ts->tok;
3099 s->next = first;
3100 type->t = t1 | VT_FUNC;
3101 type->ref = s;
3102 } else if (tok == '[') {
3103 /* array definition */
3104 next();
3105 if (tok == TOK_RESTRICT1)
3106 next();
3107 n = -1;
3108 if (tok != ']') {
3109 n = expr_const();
3110 if (n < 0)
3111 error("invalid array size");
3113 skip(']');
3114 /* parse next post type */
3115 t1 = type->t & VT_STORAGE;
3116 type->t &= ~VT_STORAGE;
3117 post_type(type, ad);
3119 /* we push a anonymous symbol which will contain the array
3120 element type */
3121 s = sym_push(SYM_FIELD, type, 0, n);
3122 type->t = t1 | VT_ARRAY | VT_PTR;
3123 type->ref = s;
3127 /* Parse a type declaration (except basic type), and return the type
3128 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3129 expected. 'type' should contain the basic type. 'ad' is the
3130 attribute definition of the basic type. It can be modified by
3131 type_decl().
3133 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3135 Sym *s;
3136 CType type1, *type2;
3137 int qualifiers;
3139 while (tok == '*') {
3140 qualifiers = 0;
3141 redo:
3142 next();
3143 switch(tok) {
3144 case TOK_CONST1:
3145 case TOK_CONST2:
3146 case TOK_CONST3:
3147 qualifiers |= VT_CONSTANT;
3148 goto redo;
3149 case TOK_VOLATILE1:
3150 case TOK_VOLATILE2:
3151 case TOK_VOLATILE3:
3152 qualifiers |= VT_VOLATILE;
3153 goto redo;
3154 case TOK_RESTRICT1:
3155 case TOK_RESTRICT2:
3156 case TOK_RESTRICT3:
3157 goto redo;
3159 mk_pointer(type);
3160 type->t |= qualifiers;
3163 /* XXX: clarify attribute handling */
3164 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3165 parse_attribute(ad);
3167 /* recursive type */
3168 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3169 type1.t = 0; /* XXX: same as int */
3170 if (tok == '(') {
3171 next();
3172 /* XXX: this is not correct to modify 'ad' at this point, but
3173 the syntax is not clear */
3174 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3175 parse_attribute(ad);
3176 type_decl(&type1, ad, v, td);
3177 skip(')');
3178 } else {
3179 /* type identifier */
3180 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3181 *v = tok;
3182 next();
3183 } else {
3184 if (!(td & TYPE_ABSTRACT))
3185 expect("identifier");
3186 *v = 0;
3189 post_type(type, ad);
3190 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3191 parse_attribute(ad);
3192 if (!type1.t)
3193 return;
3194 /* append type at the end of type1 */
3195 type2 = &type1;
3196 for(;;) {
3197 s = type2->ref;
3198 type2 = &s->type;
3199 if (!type2->t) {
3200 *type2 = *type;
3201 break;
3204 *type = type1;
3207 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3208 ST_FUNC int lvalue_type(int t)
3210 int bt, r;
3211 r = VT_LVAL;
3212 bt = t & VT_BTYPE;
3213 if (bt == VT_BYTE || bt == VT_BOOL)
3214 r |= VT_LVAL_BYTE;
3215 else if (bt == VT_SHORT)
3216 r |= VT_LVAL_SHORT;
3217 else
3218 return r;
3219 if (t & VT_UNSIGNED)
3220 r |= VT_LVAL_UNSIGNED;
3221 return r;
3224 /* indirection with full error checking and bound check */
3225 ST_FUNC void indir(void)
3227 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3228 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3229 return;
3230 expect("pointer");
3232 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3233 gv(RC_INT);
3234 vtop->type = *pointed_type(&vtop->type);
3235 /* Arrays and functions are never lvalues */
3236 if (!(vtop->type.t & VT_ARRAY)
3237 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3238 vtop->r |= lvalue_type(vtop->type.t);
3239 /* if bound checking, the referenced pointer must be checked */
3240 #ifdef CONFIG_TCC_BCHECK
3241 if (tcc_state->do_bounds_check)
3242 vtop->r |= VT_MUSTBOUND;
3243 #endif
3247 /* pass a parameter to a function and do type checking and casting */
3248 static void gfunc_param_typed(Sym *func, Sym *arg)
3250 int func_type;
3251 CType type;
3253 func_type = func->c;
3254 if (func_type == FUNC_OLD ||
3255 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3256 /* default casting : only need to convert float to double */
3257 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3258 type.t = VT_DOUBLE;
3259 gen_cast(&type);
3261 } else if (arg == NULL) {
3262 error("too many arguments to function");
3263 } else {
3264 type = arg->type;
3265 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3266 gen_assign_cast(&type);
3270 /* parse an expression of the form '(type)' or '(expr)' and return its
3271 type */
3272 static void parse_expr_type(CType *type)
3274 int n;
3275 AttributeDef ad;
3277 skip('(');
3278 if (parse_btype(type, &ad)) {
3279 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3280 } else {
3281 expr_type(type);
3283 skip(')');
3286 static void parse_type(CType *type)
3288 AttributeDef ad;
3289 int n;
3291 if (!parse_btype(type, &ad)) {
3292 expect("type");
3294 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3297 static void vpush_tokc(int t)
3299 CType type;
3300 type.t = t;
3301 type.ref = 0;
3302 vsetc(&type, VT_CONST, &tokc);
3305 ST_FUNC void unary(void)
3307 int n, t, align, size, r, sizeof_caller;
3308 CType type;
3309 Sym *s;
3310 AttributeDef ad;
3311 static int in_sizeof = 0;
3313 sizeof_caller = in_sizeof;
3314 in_sizeof = 0;
3315 /* XXX: GCC 2.95.3 does not generate a table although it should be
3316 better here */
3317 tok_next:
3318 switch(tok) {
3319 case TOK_EXTENSION:
3320 next();
3321 goto tok_next;
3322 case TOK_CINT:
3323 case TOK_CCHAR:
3324 case TOK_LCHAR:
3325 vpushi(tokc.i);
3326 next();
3327 break;
3328 case TOK_CUINT:
3329 vpush_tokc(VT_INT | VT_UNSIGNED);
3330 next();
3331 break;
3332 case TOK_CLLONG:
3333 vpush_tokc(VT_LLONG);
3334 next();
3335 break;
3336 case TOK_CULLONG:
3337 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3338 next();
3339 break;
3340 case TOK_CFLOAT:
3341 vpush_tokc(VT_FLOAT);
3342 next();
3343 break;
3344 case TOK_CDOUBLE:
3345 vpush_tokc(VT_DOUBLE);
3346 next();
3347 break;
3348 case TOK_CLDOUBLE:
3349 vpush_tokc(VT_LDOUBLE);
3350 next();
3351 break;
3352 case TOK___FUNCTION__:
3353 if (!gnu_ext)
3354 goto tok_identifier;
3355 /* fall thru */
3356 case TOK___FUNC__:
3358 void *ptr;
3359 int len;
3360 /* special function name identifier */
3361 len = strlen(funcname) + 1;
3362 /* generate char[len] type */
3363 type.t = VT_BYTE;
3364 mk_pointer(&type);
3365 type.t |= VT_ARRAY;
3366 type.ref->c = len;
3367 vpush_ref(&type, data_section, data_section->data_offset, len);
3368 ptr = section_ptr_add(data_section, len);
3369 memcpy(ptr, funcname, len);
3370 next();
3372 break;
3373 case TOK_LSTR:
3374 #ifdef TCC_TARGET_PE
3375 t = VT_SHORT | VT_UNSIGNED;
3376 #else
3377 t = VT_INT;
3378 #endif
3379 goto str_init;
3380 case TOK_STR:
3381 /* string parsing */
3382 t = VT_BYTE;
3383 str_init:
3384 if (tcc_state->warn_write_strings)
3385 t |= VT_CONSTANT;
3386 type.t = t;
3387 mk_pointer(&type);
3388 type.t |= VT_ARRAY;
3389 memset(&ad, 0, sizeof(AttributeDef));
3390 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3391 break;
3392 case '(':
3393 next();
3394 /* cast ? */
3395 if (parse_btype(&type, &ad)) {
3396 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3397 skip(')');
3398 /* check ISOC99 compound literal */
3399 if (tok == '{') {
3400 /* data is allocated locally by default */
3401 if (global_expr)
3402 r = VT_CONST;
3403 else
3404 r = VT_LOCAL;
3405 /* all except arrays are lvalues */
3406 if (!(type.t & VT_ARRAY))
3407 r |= lvalue_type(type.t);
3408 memset(&ad, 0, sizeof(AttributeDef));
3409 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3410 } else {
3411 if (sizeof_caller) {
3412 vpush(&type);
3413 return;
3415 unary();
3416 gen_cast(&type);
3418 } else if (tok == '{') {
3419 /* save all registers */
3420 save_regs(0);
3421 /* statement expression : we do not accept break/continue
3422 inside as GCC does */
3423 block(NULL, NULL, NULL, NULL, 0, 1);
3424 skip(')');
3425 } else {
3426 gexpr();
3427 skip(')');
3429 break;
3430 case '*':
3431 next();
3432 unary();
3433 indir();
3434 break;
3435 case '&':
3436 next();
3437 unary();
3438 /* functions names must be treated as function pointers,
3439 except for unary '&' and sizeof. Since we consider that
3440 functions are not lvalues, we only have to handle it
3441 there and in function calls. */
3442 /* arrays can also be used although they are not lvalues */
3443 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3444 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3445 test_lvalue();
3446 mk_pointer(&vtop->type);
3447 gaddrof();
3448 break;
3449 case '!':
3450 next();
3451 unary();
3452 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3453 CType boolean;
3454 boolean.t = VT_BOOL;
3455 gen_cast(&boolean);
3456 vtop->c.i = !vtop->c.i;
3457 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3458 vtop->c.i = vtop->c.i ^ 1;
3459 else {
3460 save_regs(1);
3461 vseti(VT_JMP, gtst(1, 0));
3463 break;
3464 case '~':
3465 next();
3466 unary();
3467 vpushi(-1);
3468 gen_op('^');
3469 break;
3470 case '+':
3471 next();
3472 /* in order to force cast, we add zero */
3473 unary();
3474 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3475 error("pointer not accepted for unary plus");
3476 vpushi(0);
3477 gen_op('+');
3478 break;
3479 case TOK_SIZEOF:
3480 case TOK_ALIGNOF1:
3481 case TOK_ALIGNOF2:
3482 t = tok;
3483 next();
3484 in_sizeof++;
3485 unary_type(&type); // Perform a in_sizeof = 0;
3486 size = type_size(&type, &align);
3487 if (t == TOK_SIZEOF) {
3488 if (size < 0)
3489 error("sizeof applied to an incomplete type");
3490 vpushi(size);
3491 } else {
3492 vpushi(align);
3494 vtop->type.t |= VT_UNSIGNED;
3495 break;
3497 case TOK_builtin_types_compatible_p:
3499 CType type1, type2;
3500 next();
3501 skip('(');
3502 parse_type(&type1);
3503 skip(',');
3504 parse_type(&type2);
3505 skip(')');
3506 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3507 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3508 vpushi(is_compatible_types(&type1, &type2));
3510 break;
3511 case TOK_builtin_constant_p:
3513 int saved_nocode_wanted, res;
3514 next();
3515 skip('(');
3516 saved_nocode_wanted = nocode_wanted;
3517 nocode_wanted = 1;
3518 gexpr();
3519 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3520 vpop();
3521 nocode_wanted = saved_nocode_wanted;
3522 skip(')');
3523 vpushi(res);
3525 break;
3526 case TOK_builtin_frame_address:
3528 CType type;
3529 next();
3530 skip('(');
3531 if (tok != TOK_CINT) {
3532 error("__builtin_frame_address only takes integers");
3534 if (tokc.i != 0) {
3535 error("TCC only supports __builtin_frame_address(0)");
3537 next();
3538 skip(')');
3539 type.t = VT_VOID;
3540 mk_pointer(&type);
3541 vset(&type, VT_LOCAL, 0);
3543 break;
3544 #ifdef TCC_TARGET_X86_64
3545 case TOK_builtin_va_arg_types:
3547 /* This definition must be synced with stdarg.h */
3548 enum __va_arg_type {
3549 __va_gen_reg, __va_float_reg, __va_stack
3551 CType type;
3552 int bt;
3553 next();
3554 skip('(');
3555 parse_type(&type);
3556 skip(')');
3557 bt = type.t & VT_BTYPE;
3558 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3559 vpushi(__va_stack);
3560 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3561 vpushi(__va_float_reg);
3562 } else {
3563 vpushi(__va_gen_reg);
3566 break;
3567 #endif
3568 case TOK_INC:
3569 case TOK_DEC:
3570 t = tok;
3571 next();
3572 unary();
3573 inc(0, t);
3574 break;
3575 case '-':
3576 next();
3577 vpushi(0);
3578 unary();
3579 gen_op('-');
3580 break;
3581 case TOK_LAND:
3582 if (!gnu_ext)
3583 goto tok_identifier;
3584 next();
3585 /* allow to take the address of a label */
3586 if (tok < TOK_UIDENT)
3587 expect("label identifier");
3588 s = label_find(tok);
3589 if (!s) {
3590 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3591 } else {
3592 if (s->r == LABEL_DECLARED)
3593 s->r = LABEL_FORWARD;
3595 if (!s->type.t) {
3596 s->type.t = VT_VOID;
3597 mk_pointer(&s->type);
3598 s->type.t |= VT_STATIC;
3600 vset(&s->type, VT_CONST | VT_SYM, 0);
3601 vtop->sym = s;
3602 next();
3603 break;
3605 // special qnan , snan and infinity values
3606 case TOK___NAN__:
3607 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3608 next();
3609 break;
3610 case TOK___SNAN__:
3611 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3612 next();
3613 break;
3614 case TOK___INF__:
3615 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3616 next();
3617 break;
3619 default:
3620 tok_identifier:
3621 t = tok;
3622 next();
3623 if (t < TOK_UIDENT)
3624 expect("identifier");
3625 s = sym_find(t);
3626 if (!s) {
3627 if (tok != '(')
3628 error("'%s' undeclared", get_tok_str(t, NULL));
3629 /* for simple function calls, we tolerate undeclared
3630 external reference to int() function */
3631 if (tcc_state->warn_implicit_function_declaration)
3632 warning("implicit declaration of function '%s'",
3633 get_tok_str(t, NULL));
3634 s = external_global_sym(t, &func_old_type, 0);
3636 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3637 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3638 /* if referencing an inline function, then we generate a
3639 symbol to it if not already done. It will have the
3640 effect to generate code for it at the end of the
3641 compilation unit. Inline function as always
3642 generated in the text section. */
3643 if (!s->c)
3644 put_extern_sym(s, text_section, 0, 0);
3645 r = VT_SYM | VT_CONST;
3646 } else {
3647 r = s->r;
3649 vset(&s->type, r, s->c);
3650 /* if forward reference, we must point to s */
3651 if (vtop->r & VT_SYM) {
3652 vtop->sym = s;
3653 vtop->c.ul = 0;
3655 break;
3658 /* post operations */
3659 while (1) {
3660 if (tok == TOK_INC || tok == TOK_DEC) {
3661 inc(1, tok);
3662 next();
3663 } else if (tok == '.' || tok == TOK_ARROW) {
3664 int qualifiers;
3665 /* field */
3666 if (tok == TOK_ARROW)
3667 indir();
3668 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3669 test_lvalue();
3670 gaddrof();
3671 next();
3672 /* expect pointer on structure */
3673 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3674 expect("struct or union");
3675 s = vtop->type.ref;
3676 /* find field */
3677 tok |= SYM_FIELD;
3678 while ((s = s->next) != NULL) {
3679 if (s->v == tok)
3680 break;
3682 if (!s)
3683 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3684 /* add field offset to pointer */
3685 vtop->type = char_pointer_type; /* change type to 'char *' */
3686 vpushi(s->c);
3687 gen_op('+');
3688 /* change type to field type, and set to lvalue */
3689 vtop->type = s->type;
3690 vtop->type.t |= qualifiers;
3691 /* an array is never an lvalue */
3692 if (!(vtop->type.t & VT_ARRAY)) {
3693 vtop->r |= lvalue_type(vtop->type.t);
3694 #ifdef CONFIG_TCC_BCHECK
3695 /* if bound checking, the referenced pointer must be checked */
3696 if (tcc_state->do_bounds_check)
3697 vtop->r |= VT_MUSTBOUND;
3698 #endif
3700 next();
3701 } else if (tok == '[') {
3702 next();
3703 gexpr();
3704 gen_op('+');
3705 indir();
3706 skip(']');
3707 } else if (tok == '(') {
3708 SValue ret;
3709 Sym *sa;
3710 int nb_args;
3712 /* function call */
3713 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3714 /* pointer test (no array accepted) */
3715 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3716 vtop->type = *pointed_type(&vtop->type);
3717 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3718 goto error_func;
3719 } else {
3720 error_func:
3721 expect("function pointer");
3723 } else {
3724 vtop->r &= ~VT_LVAL; /* no lvalue */
3726 /* get return type */
3727 s = vtop->type.ref;
3728 next();
3729 sa = s->next; /* first parameter */
3730 nb_args = 0;
3731 ret.r2 = VT_CONST;
3732 /* compute first implicit argument if a structure is returned */
3733 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3734 /* get some space for the returned structure */
3735 size = type_size(&s->type, &align);
3736 loc = (loc - size) & -align;
3737 ret.type = s->type;
3738 ret.r = VT_LOCAL | VT_LVAL;
3739 /* pass it as 'int' to avoid structure arg passing
3740 problems */
3741 vseti(VT_LOCAL, loc);
3742 ret.c = vtop->c;
3743 nb_args++;
3744 } else {
3745 ret.type = s->type;
3746 /* return in register */
3747 if (is_float(ret.type.t)) {
3748 ret.r = reg_fret(ret.type.t);
3749 } else {
3750 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3751 ret.r2 = REG_LRET;
3752 ret.r = REG_IRET;
3754 ret.c.i = 0;
3756 if (tok != ')') {
3757 for(;;) {
3758 expr_eq();
3759 gfunc_param_typed(s, sa);
3760 nb_args++;
3761 if (sa)
3762 sa = sa->next;
3763 if (tok == ')')
3764 break;
3765 skip(',');
3768 if (sa)
3769 error("too few arguments to function");
3770 skip(')');
3771 if (!nocode_wanted) {
3772 gfunc_call(nb_args);
3773 } else {
3774 vtop -= (nb_args + 1);
3776 /* return value */
3777 vsetc(&ret.type, ret.r, &ret.c);
3778 vtop->r2 = ret.r2;
3779 } else {
3780 break;
3785 ST_FUNC void expr_prod(void)
3787 int t;
3789 unary();
3790 while (tok == '*' || tok == '/' || tok == '%') {
3791 t = tok;
3792 next();
3793 unary();
3794 gen_op(t);
3798 ST_FUNC void expr_sum(void)
3800 int t;
3802 expr_prod();
3803 while (tok == '+' || tok == '-') {
3804 t = tok;
3805 next();
3806 expr_prod();
3807 gen_op(t);
3811 static void expr_shift(void)
3813 int t;
3815 expr_sum();
3816 while (tok == TOK_SHL || tok == TOK_SAR) {
3817 t = tok;
3818 next();
3819 expr_sum();
3820 gen_op(t);
3824 static void expr_cmp(void)
3826 int t;
3828 expr_shift();
3829 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3830 tok == TOK_ULT || tok == TOK_UGE) {
3831 t = tok;
3832 next();
3833 expr_shift();
3834 gen_op(t);
3838 static void expr_cmpeq(void)
3840 int t;
3842 expr_cmp();
3843 while (tok == TOK_EQ || tok == TOK_NE) {
3844 t = tok;
3845 next();
3846 expr_cmp();
3847 gen_op(t);
3851 static void expr_and(void)
3853 expr_cmpeq();
3854 while (tok == '&') {
3855 next();
3856 expr_cmpeq();
3857 gen_op('&');
3861 static void expr_xor(void)
3863 expr_and();
3864 while (tok == '^') {
3865 next();
3866 expr_and();
3867 gen_op('^');
3871 static void expr_or(void)
3873 expr_xor();
3874 while (tok == '|') {
3875 next();
3876 expr_xor();
3877 gen_op('|');
3881 /* XXX: fix this mess */
3882 static void expr_land_const(void)
3884 expr_or();
3885 while (tok == TOK_LAND) {
3886 next();
3887 expr_or();
3888 gen_op(TOK_LAND);
3892 /* XXX: fix this mess */
3893 static void expr_lor_const(void)
3895 expr_land_const();
3896 while (tok == TOK_LOR) {
3897 next();
3898 expr_land_const();
3899 gen_op(TOK_LOR);
3903 /* only used if non constant */
3904 static void expr_land(void)
3906 int t;
3908 expr_or();
3909 if (tok == TOK_LAND) {
3910 t = 0;
3911 save_regs(1);
3912 for(;;) {
3913 t = gtst(1, t);
3914 if (tok != TOK_LAND) {
3915 vseti(VT_JMPI, t);
3916 break;
3918 next();
3919 expr_or();
3924 static void expr_lor(void)
3926 int t;
3928 expr_land();
3929 if (tok == TOK_LOR) {
3930 t = 0;
3931 save_regs(1);
3932 for(;;) {
3933 t = gtst(0, t);
3934 if (tok != TOK_LOR) {
3935 vseti(VT_JMP, t);
3936 break;
3938 next();
3939 expr_land();
3944 /* XXX: better constant handling */
3945 static void expr_cond(void)
3947 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
3948 SValue sv;
3949 CType type, type1, type2;
3951 if (const_wanted) {
3952 expr_lor_const();
3953 if (tok == '?') {
3954 CType boolean;
3955 int c;
3956 boolean.t = VT_BOOL;
3957 vdup();
3958 gen_cast(&boolean);
3959 c = vtop->c.i;
3960 vpop();
3961 next();
3962 if (tok != ':' || !gnu_ext) {
3963 vpop();
3964 gexpr();
3966 if (!c)
3967 vpop();
3968 skip(':');
3969 expr_cond();
3970 if (c)
3971 vpop();
3973 } else {
3974 expr_lor();
3975 if (tok == '?') {
3976 next();
3977 if (vtop != vstack) {
3978 /* needed to avoid having different registers saved in
3979 each branch */
3980 if (is_float(vtop->type.t)) {
3981 rc = RC_FLOAT;
3982 #ifdef TCC_TARGET_X86_64
3983 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
3984 rc = RC_ST0;
3986 #endif
3988 else
3989 rc = RC_INT;
3990 gv(rc);
3991 save_regs(1);
3993 if (tok == ':' && gnu_ext) {
3994 gv_dup();
3995 tt = gtst(1, 0);
3996 } else {
3997 tt = gtst(1, 0);
3998 gexpr();
4000 type1 = vtop->type;
4001 sv = *vtop; /* save value to handle it later */
4002 vtop--; /* no vpop so that FP stack is not flushed */
4003 skip(':');
4004 u = gjmp(0);
4005 gsym(tt);
4006 expr_cond();
4007 type2 = vtop->type;
4009 t1 = type1.t;
4010 bt1 = t1 & VT_BTYPE;
4011 t2 = type2.t;
4012 bt2 = t2 & VT_BTYPE;
4013 /* cast operands to correct type according to ISOC rules */
4014 if (is_float(bt1) || is_float(bt2)) {
4015 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4016 type.t = VT_LDOUBLE;
4017 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4018 type.t = VT_DOUBLE;
4019 } else {
4020 type.t = VT_FLOAT;
4022 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4023 /* cast to biggest op */
4024 type.t = VT_LLONG;
4025 /* convert to unsigned if it does not fit in a long long */
4026 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4027 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4028 type.t |= VT_UNSIGNED;
4029 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4030 /* XXX: test pointer compatibility */
4031 type = type1;
4032 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4033 /* XXX: test function pointer compatibility */
4034 type = type1;
4035 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4036 /* XXX: test structure compatibility */
4037 type = type1;
4038 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4039 /* NOTE: as an extension, we accept void on only one side */
4040 type.t = VT_VOID;
4041 } else {
4042 /* integer operations */
4043 type.t = VT_INT;
4044 /* convert to unsigned if it does not fit in an integer */
4045 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4046 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4047 type.t |= VT_UNSIGNED;
4050 /* now we convert second operand */
4051 gen_cast(&type);
4052 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4053 gaddrof();
4054 rc = RC_INT;
4055 if (is_float(type.t)) {
4056 rc = RC_FLOAT;
4057 #ifdef TCC_TARGET_X86_64
4058 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4059 rc = RC_ST0;
4061 #endif
4062 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4063 /* for long longs, we use fixed registers to avoid having
4064 to handle a complicated move */
4065 rc = RC_IRET;
4068 r2 = gv(rc);
4069 /* this is horrible, but we must also convert first
4070 operand */
4071 tt = gjmp(0);
4072 gsym(u);
4073 /* put again first value and cast it */
4074 *vtop = sv;
4075 gen_cast(&type);
4076 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4077 gaddrof();
4078 r1 = gv(rc);
4079 move_reg(r2, r1);
4080 vtop->r = r2;
4081 gsym(tt);
4086 static void expr_eq(void)
4088 int t;
4090 expr_cond();
4091 if (tok == '=' ||
4092 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4093 tok == TOK_A_XOR || tok == TOK_A_OR ||
4094 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4095 test_lvalue();
4096 t = tok;
4097 next();
4098 if (t == '=') {
4099 expr_eq();
4100 } else {
4101 vdup();
4102 expr_eq();
4103 gen_op(t & 0x7f);
4105 vstore();
4109 ST_FUNC void gexpr(void)
4111 while (1) {
4112 expr_eq();
4113 if (tok != ',')
4114 break;
4115 vpop();
4116 next();
4120 /* parse an expression and return its type without any side effect. */
4121 static void expr_type(CType *type)
4123 int saved_nocode_wanted;
4125 saved_nocode_wanted = nocode_wanted;
4126 nocode_wanted = 1;
4127 gexpr();
4128 *type = vtop->type;
4129 vpop();
4130 nocode_wanted = saved_nocode_wanted;
4133 /* parse a unary expression and return its type without any side
4134 effect. */
4135 static void unary_type(CType *type)
4137 int a;
4139 a = nocode_wanted;
4140 nocode_wanted = 1;
4141 unary();
4142 *type = vtop->type;
4143 vpop();
4144 nocode_wanted = a;
4147 /* parse a constant expression and return value in vtop. */
4148 static void expr_const1(void)
4150 int a;
4151 a = const_wanted;
4152 const_wanted = 1;
4153 expr_cond();
4154 const_wanted = a;
4157 /* parse an integer constant and return its value. */
4158 ST_FUNC int expr_const(void)
4160 int c;
4161 expr_const1();
4162 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4163 expect("constant expression");
4164 c = vtop->c.i;
4165 vpop();
4166 return c;
4169 /* return the label token if current token is a label, otherwise
4170 return zero */
4171 static int is_label(void)
4173 int last_tok;
4175 /* fast test first */
4176 if (tok < TOK_UIDENT)
4177 return 0;
4178 /* no need to save tokc because tok is an identifier */
4179 last_tok = tok;
4180 next();
4181 if (tok == ':') {
4182 next();
4183 return last_tok;
4184 } else {
4185 unget_tok(last_tok);
4186 return 0;
4190 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4191 int case_reg, int is_expr)
4193 int a, b, c, d;
4194 Sym *s;
4196 /* generate line number info */
4197 if (tcc_state->do_debug &&
4198 (last_line_num != file->line_num || last_ind != ind)) {
4199 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4200 last_ind = ind;
4201 last_line_num = file->line_num;
4204 if (is_expr) {
4205 /* default return value is (void) */
4206 vpushi(0);
4207 vtop->type.t = VT_VOID;
4210 if (tok == TOK_IF) {
4211 /* if test */
4212 next();
4213 skip('(');
4214 gexpr();
4215 skip(')');
4216 a = gtst(1, 0);
4217 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4218 c = tok;
4219 if (c == TOK_ELSE) {
4220 next();
4221 d = gjmp(0);
4222 gsym(a);
4223 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4224 gsym(d); /* patch else jmp */
4225 } else
4226 gsym(a);
4227 } else if (tok == TOK_WHILE) {
4228 next();
4229 d = ind;
4230 skip('(');
4231 gexpr();
4232 skip(')');
4233 a = gtst(1, 0);
4234 b = 0;
4235 block(&a, &b, case_sym, def_sym, case_reg, 0);
4236 gjmp_addr(d);
4237 gsym(a);
4238 gsym_addr(b, d);
4239 } else if (tok == '{') {
4240 Sym *llabel;
4242 next();
4243 /* record local declaration stack position */
4244 s = local_stack;
4245 llabel = local_label_stack;
4246 /* handle local labels declarations */
4247 if (tok == TOK_LABEL) {
4248 next();
4249 for(;;) {
4250 if (tok < TOK_UIDENT)
4251 expect("label identifier");
4252 label_push(&local_label_stack, tok, LABEL_DECLARED);
4253 next();
4254 if (tok == ',') {
4255 next();
4256 } else {
4257 skip(';');
4258 break;
4262 while (tok != '}') {
4263 decl(VT_LOCAL);
4264 if (tok != '}') {
4265 if (is_expr)
4266 vpop();
4267 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4270 /* pop locally defined labels */
4271 label_pop(&local_label_stack, llabel);
4272 /* pop locally defined symbols */
4273 if(is_expr) {
4274 /* XXX: this solution makes only valgrind happy...
4275 triggered by gcc.c-torture/execute/20000917-1.c */
4276 Sym *p;
4277 switch(vtop->type.t & VT_BTYPE) {
4278 case VT_PTR:
4279 case VT_STRUCT:
4280 case VT_ENUM:
4281 case VT_FUNC:
4282 for(p=vtop->type.ref;p;p=p->prev)
4283 if(p->prev==s)
4284 error("unsupported expression type");
4287 sym_pop(&local_stack, s);
4288 next();
4289 } else if (tok == TOK_RETURN) {
4290 next();
4291 if (tok != ';') {
4292 gexpr();
4293 gen_assign_cast(&func_vt);
4294 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4295 CType type;
4296 /* if returning structure, must copy it to implicit
4297 first pointer arg location */
4298 #ifdef TCC_ARM_EABI
4299 int align, size;
4300 size = type_size(&func_vt,&align);
4301 if(size <= 4)
4303 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4304 && (align & 3))
4306 int addr;
4307 loc = (loc - size) & -4;
4308 addr = loc;
4309 type = func_vt;
4310 vset(&type, VT_LOCAL | VT_LVAL, addr);
4311 vswap();
4312 vstore();
4313 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4315 vtop->type = int_type;
4316 gv(RC_IRET);
4317 } else {
4318 #endif
4319 type = func_vt;
4320 mk_pointer(&type);
4321 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4322 indir();
4323 vswap();
4324 /* copy structure value to pointer */
4325 vstore();
4326 #ifdef TCC_ARM_EABI
4328 #endif
4329 } else if (is_float(func_vt.t)) {
4330 gv(rc_fret(func_vt.t));
4331 } else {
4332 gv(RC_IRET);
4334 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4336 skip(';');
4337 rsym = gjmp(rsym); /* jmp */
4338 } else if (tok == TOK_BREAK) {
4339 /* compute jump */
4340 if (!bsym)
4341 error("cannot break");
4342 *bsym = gjmp(*bsym);
4343 next();
4344 skip(';');
4345 } else if (tok == TOK_CONTINUE) {
4346 /* compute jump */
4347 if (!csym)
4348 error("cannot continue");
4349 *csym = gjmp(*csym);
4350 next();
4351 skip(';');
4352 } else if (tok == TOK_FOR) {
4353 int e;
4354 next();
4355 skip('(');
4356 if (tok != ';') {
4357 gexpr();
4358 vpop();
4360 skip(';');
4361 d = ind;
4362 c = ind;
4363 a = 0;
4364 b = 0;
4365 if (tok != ';') {
4366 gexpr();
4367 a = gtst(1, 0);
4369 skip(';');
4370 if (tok != ')') {
4371 e = gjmp(0);
4372 c = ind;
4373 gexpr();
4374 vpop();
4375 gjmp_addr(d);
4376 gsym(e);
4378 skip(')');
4379 block(&a, &b, case_sym, def_sym, case_reg, 0);
4380 gjmp_addr(c);
4381 gsym(a);
4382 gsym_addr(b, c);
4383 } else
4384 if (tok == TOK_DO) {
4385 next();
4386 a = 0;
4387 b = 0;
4388 d = ind;
4389 block(&a, &b, case_sym, def_sym, case_reg, 0);
4390 skip(TOK_WHILE);
4391 skip('(');
4392 gsym(b);
4393 gexpr();
4394 c = gtst(0, 0);
4395 gsym_addr(c, d);
4396 skip(')');
4397 gsym(a);
4398 skip(';');
4399 } else
4400 if (tok == TOK_SWITCH) {
4401 next();
4402 skip('(');
4403 gexpr();
4404 /* XXX: other types than integer */
4405 case_reg = gv(RC_INT);
4406 vpop();
4407 skip(')');
4408 a = 0;
4409 b = gjmp(0); /* jump to first case */
4410 c = 0;
4411 block(&a, csym, &b, &c, case_reg, 0);
4412 /* if no default, jmp after switch */
4413 if (c == 0)
4414 c = ind;
4415 /* default label */
4416 gsym_addr(b, c);
4417 /* break label */
4418 gsym(a);
4419 } else
4420 if (tok == TOK_CASE) {
4421 int v1, v2;
4422 if (!case_sym)
4423 expect("switch");
4424 next();
4425 v1 = expr_const();
4426 v2 = v1;
4427 if (gnu_ext && tok == TOK_DOTS) {
4428 next();
4429 v2 = expr_const();
4430 if (v2 < v1)
4431 warning("empty case range");
4433 /* since a case is like a label, we must skip it with a jmp */
4434 b = gjmp(0);
4435 gsym(*case_sym);
4436 vseti(case_reg, 0);
4437 vpushi(v1);
4438 if (v1 == v2) {
4439 gen_op(TOK_EQ);
4440 *case_sym = gtst(1, 0);
4441 } else {
4442 gen_op(TOK_GE);
4443 *case_sym = gtst(1, 0);
4444 vseti(case_reg, 0);
4445 vpushi(v2);
4446 gen_op(TOK_LE);
4447 *case_sym = gtst(1, *case_sym);
4449 gsym(b);
4450 skip(':');
4451 is_expr = 0;
4452 goto block_after_label;
4453 } else
4454 if (tok == TOK_DEFAULT) {
4455 next();
4456 skip(':');
4457 if (!def_sym)
4458 expect("switch");
4459 if (*def_sym)
4460 error("too many 'default'");
4461 *def_sym = ind;
4462 is_expr = 0;
4463 goto block_after_label;
4464 } else
4465 if (tok == TOK_GOTO) {
4466 next();
4467 if (tok == '*' && gnu_ext) {
4468 /* computed goto */
4469 next();
4470 gexpr();
4471 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4472 expect("pointer");
4473 ggoto();
4474 } else if (tok >= TOK_UIDENT) {
4475 s = label_find(tok);
4476 /* put forward definition if needed */
4477 if (!s) {
4478 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4479 } else {
4480 if (s->r == LABEL_DECLARED)
4481 s->r = LABEL_FORWARD;
4483 /* label already defined */
4484 if (s->r & LABEL_FORWARD)
4485 s->jnext = gjmp(s->jnext);
4486 else
4487 gjmp_addr(s->jnext);
4488 next();
4489 } else {
4490 expect("label identifier");
4492 skip(';');
4493 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4494 asm_instr();
4495 } else {
4496 b = is_label();
4497 if (b) {
4498 /* label case */
4499 s = label_find(b);
4500 if (s) {
4501 if (s->r == LABEL_DEFINED)
4502 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4503 gsym(s->jnext);
4504 s->r = LABEL_DEFINED;
4505 } else {
4506 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4508 s->jnext = ind;
4509 /* we accept this, but it is a mistake */
4510 block_after_label:
4511 if (tok == '}') {
4512 warning("deprecated use of label at end of compound statement");
4513 } else {
4514 if (is_expr)
4515 vpop();
4516 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4518 } else {
4519 /* expression case */
4520 if (tok != ';') {
4521 if (is_expr) {
4522 vpop();
4523 gexpr();
4524 } else {
4525 gexpr();
4526 vpop();
4529 skip(';');
4534 /* t is the array or struct type. c is the array or struct
4535 address. cur_index/cur_field is the pointer to the current
4536 value. 'size_only' is true if only size info is needed (only used
4537 in arrays) */
4538 static void decl_designator(CType *type, Section *sec, unsigned long c,
4539 int *cur_index, Sym **cur_field,
4540 int size_only)
4542 Sym *s, *f;
4543 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4544 CType type1;
4546 notfirst = 0;
4547 elem_size = 0;
4548 nb_elems = 1;
4549 if (gnu_ext && (l = is_label()) != 0)
4550 goto struct_field;
4551 while (tok == '[' || tok == '.') {
4552 if (tok == '[') {
4553 if (!(type->t & VT_ARRAY))
4554 expect("array type");
4555 s = type->ref;
4556 next();
4557 index = expr_const();
4558 if (index < 0 || (s->c >= 0 && index >= s->c))
4559 expect("invalid index");
4560 if (tok == TOK_DOTS && gnu_ext) {
4561 next();
4562 index_last = expr_const();
4563 if (index_last < 0 ||
4564 (s->c >= 0 && index_last >= s->c) ||
4565 index_last < index)
4566 expect("invalid index");
4567 } else {
4568 index_last = index;
4570 skip(']');
4571 if (!notfirst)
4572 *cur_index = index_last;
4573 type = pointed_type(type);
4574 elem_size = type_size(type, &align);
4575 c += index * elem_size;
4576 /* NOTE: we only support ranges for last designator */
4577 nb_elems = index_last - index + 1;
4578 if (nb_elems != 1) {
4579 notfirst = 1;
4580 break;
4582 } else {
4583 next();
4584 l = tok;
4585 next();
4586 struct_field:
4587 if ((type->t & VT_BTYPE) != VT_STRUCT)
4588 expect("struct/union type");
4589 s = type->ref;
4590 l |= SYM_FIELD;
4591 f = s->next;
4592 while (f) {
4593 if (f->v == l)
4594 break;
4595 f = f->next;
4597 if (!f)
4598 expect("field");
4599 if (!notfirst)
4600 *cur_field = f;
4601 /* XXX: fix this mess by using explicit storage field */
4602 type1 = f->type;
4603 type1.t |= (type->t & ~VT_TYPE);
4604 type = &type1;
4605 c += f->c;
4607 notfirst = 1;
4609 if (notfirst) {
4610 if (tok == '=') {
4611 next();
4612 } else {
4613 if (!gnu_ext)
4614 expect("=");
4616 } else {
4617 if (type->t & VT_ARRAY) {
4618 index = *cur_index;
4619 type = pointed_type(type);
4620 c += index * type_size(type, &align);
4621 } else {
4622 f = *cur_field;
4623 if (!f)
4624 error("too many field init");
4625 /* XXX: fix this mess by using explicit storage field */
4626 type1 = f->type;
4627 type1.t |= (type->t & ~VT_TYPE);
4628 type = &type1;
4629 c += f->c;
4632 decl_initializer(type, sec, c, 0, size_only);
4634 /* XXX: make it more general */
4635 if (!size_only && nb_elems > 1) {
4636 unsigned long c_end;
4637 uint8_t *src, *dst;
4638 int i;
4640 if (!sec)
4641 error("range init not supported yet for dynamic storage");
4642 c_end = c + nb_elems * elem_size;
4643 if (c_end > sec->data_allocated)
4644 section_realloc(sec, c_end);
4645 src = sec->data + c;
4646 dst = src;
4647 for(i = 1; i < nb_elems; i++) {
4648 dst += elem_size;
4649 memcpy(dst, src, elem_size);
4654 #define EXPR_VAL 0
4655 #define EXPR_CONST 1
4656 #define EXPR_ANY 2
4658 /* store a value or an expression directly in global data or in local array */
4659 static void init_putv(CType *type, Section *sec, unsigned long c,
4660 int v, int expr_type)
4662 int saved_global_expr, bt, bit_pos, bit_size;
4663 void *ptr;
4664 unsigned long long bit_mask;
4665 CType dtype;
4667 switch(expr_type) {
4668 case EXPR_VAL:
4669 vpushi(v);
4670 break;
4671 case EXPR_CONST:
4672 /* compound literals must be allocated globally in this case */
4673 saved_global_expr = global_expr;
4674 global_expr = 1;
4675 expr_const1();
4676 global_expr = saved_global_expr;
4677 /* NOTE: symbols are accepted */
4678 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4679 error("initializer element is not constant");
4680 break;
4681 case EXPR_ANY:
4682 expr_eq();
4683 break;
4686 dtype = *type;
4687 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4689 if (sec) {
4690 /* XXX: not portable */
4691 /* XXX: generate error if incorrect relocation */
4692 gen_assign_cast(&dtype);
4693 bt = type->t & VT_BTYPE;
4694 /* we'll write at most 12 bytes */
4695 if (c + 12 > sec->data_allocated) {
4696 section_realloc(sec, c + 12);
4698 ptr = sec->data + c;
4699 /* XXX: make code faster ? */
4700 if (!(type->t & VT_BITFIELD)) {
4701 bit_pos = 0;
4702 bit_size = 32;
4703 bit_mask = -1LL;
4704 } else {
4705 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4706 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4707 bit_mask = (1LL << bit_size) - 1;
4709 if ((vtop->r & VT_SYM) &&
4710 (bt == VT_BYTE ||
4711 bt == VT_SHORT ||
4712 bt == VT_DOUBLE ||
4713 bt == VT_LDOUBLE ||
4714 bt == VT_LLONG ||
4715 (bt == VT_INT && bit_size != 32)))
4716 error("initializer element is not computable at load time");
4717 switch(bt) {
4718 case VT_BOOL:
4719 vtop->c.i = (vtop->c.i != 0);
4720 case VT_BYTE:
4721 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4722 break;
4723 case VT_SHORT:
4724 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4725 break;
4726 case VT_DOUBLE:
4727 *(double *)ptr = vtop->c.d;
4728 break;
4729 case VT_LDOUBLE:
4730 *(long double *)ptr = vtop->c.ld;
4731 break;
4732 case VT_LLONG:
4733 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4734 break;
4735 default:
4736 if (vtop->r & VT_SYM) {
4737 greloc(sec, vtop->sym, c, R_DATA_PTR);
4739 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4740 break;
4742 vtop--;
4743 } else {
4744 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4745 vswap();
4746 vstore();
4747 vpop();
4751 /* put zeros for variable based init */
4752 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4754 if (sec) {
4755 /* nothing to do because globals are already set to zero */
4756 } else {
4757 vpush_global_sym(&func_old_type, TOK_memset);
4758 vseti(VT_LOCAL, c);
4759 vpushi(0);
4760 vpushi(size);
4761 gfunc_call(3);
4765 /* 't' contains the type and storage info. 'c' is the offset of the
4766 object in section 'sec'. If 'sec' is NULL, it means stack based
4767 allocation. 'first' is true if array '{' must be read (multi
4768 dimension implicit array init handling). 'size_only' is true if
4769 size only evaluation is wanted (only for arrays). */
4770 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4771 int first, int size_only)
4773 int index, array_length, n, no_oblock, nb, parlevel, i;
4774 int size1, align1, expr_type;
4775 Sym *s, *f;
4776 CType *t1;
4778 if (type->t & VT_ARRAY) {
4779 s = type->ref;
4780 n = s->c;
4781 array_length = 0;
4782 t1 = pointed_type(type);
4783 size1 = type_size(t1, &align1);
4785 no_oblock = 1;
4786 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4787 tok == '{') {
4788 if (tok != '{')
4789 error("character array initializer must be a literal,"
4790 " optionally enclosed in braces");
4791 skip('{');
4792 no_oblock = 0;
4795 /* only parse strings here if correct type (otherwise: handle
4796 them as ((w)char *) expressions */
4797 if ((tok == TOK_LSTR &&
4798 #ifdef TCC_TARGET_PE
4799 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4800 #else
4801 (t1->t & VT_BTYPE) == VT_INT
4802 #endif
4803 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4804 while (tok == TOK_STR || tok == TOK_LSTR) {
4805 int cstr_len, ch;
4806 CString *cstr;
4808 cstr = tokc.cstr;
4809 /* compute maximum number of chars wanted */
4810 if (tok == TOK_STR)
4811 cstr_len = cstr->size;
4812 else
4813 cstr_len = cstr->size / sizeof(nwchar_t);
4814 cstr_len--;
4815 nb = cstr_len;
4816 if (n >= 0 && nb > (n - array_length))
4817 nb = n - array_length;
4818 if (!size_only) {
4819 if (cstr_len > nb)
4820 warning("initializer-string for array is too long");
4821 /* in order to go faster for common case (char
4822 string in global variable, we handle it
4823 specifically */
4824 if (sec && tok == TOK_STR && size1 == 1) {
4825 memcpy(sec->data + c + array_length, cstr->data, nb);
4826 } else {
4827 for(i=0;i<nb;i++) {
4828 if (tok == TOK_STR)
4829 ch = ((unsigned char *)cstr->data)[i];
4830 else
4831 ch = ((nwchar_t *)cstr->data)[i];
4832 init_putv(t1, sec, c + (array_length + i) * size1,
4833 ch, EXPR_VAL);
4837 array_length += nb;
4838 next();
4840 /* only add trailing zero if enough storage (no
4841 warning in this case since it is standard) */
4842 if (n < 0 || array_length < n) {
4843 if (!size_only) {
4844 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4846 array_length++;
4848 } else {
4849 index = 0;
4850 while (tok != '}') {
4851 decl_designator(type, sec, c, &index, NULL, size_only);
4852 if (n >= 0 && index >= n)
4853 error("index too large");
4854 /* must put zero in holes (note that doing it that way
4855 ensures that it even works with designators) */
4856 if (!size_only && array_length < index) {
4857 init_putz(t1, sec, c + array_length * size1,
4858 (index - array_length) * size1);
4860 index++;
4861 if (index > array_length)
4862 array_length = index;
4863 /* special test for multi dimensional arrays (may not
4864 be strictly correct if designators are used at the
4865 same time) */
4866 if (index >= n && no_oblock)
4867 break;
4868 if (tok == '}')
4869 break;
4870 skip(',');
4873 if (!no_oblock)
4874 skip('}');
4875 /* put zeros at the end */
4876 if (!size_only && n >= 0 && array_length < n) {
4877 init_putz(t1, sec, c + array_length * size1,
4878 (n - array_length) * size1);
4880 /* patch type size if needed */
4881 if (n < 0)
4882 s->c = array_length;
4883 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4884 (sec || !first || tok == '{')) {
4885 int par_count;
4887 /* NOTE: the previous test is a specific case for automatic
4888 struct/union init */
4889 /* XXX: union needs only one init */
4891 /* XXX: this test is incorrect for local initializers
4892 beginning with ( without {. It would be much more difficult
4893 to do it correctly (ideally, the expression parser should
4894 be used in all cases) */
4895 par_count = 0;
4896 if (tok == '(') {
4897 AttributeDef ad1;
4898 CType type1;
4899 next();
4900 while (tok == '(') {
4901 par_count++;
4902 next();
4904 if (!parse_btype(&type1, &ad1))
4905 expect("cast");
4906 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4907 #if 0
4908 if (!is_assignable_types(type, &type1))
4909 error("invalid type for cast");
4910 #endif
4911 skip(')');
4913 no_oblock = 1;
4914 if (first || tok == '{') {
4915 skip('{');
4916 no_oblock = 0;
4918 s = type->ref;
4919 f = s->next;
4920 array_length = 0;
4921 index = 0;
4922 n = s->c;
4923 while (tok != '}') {
4924 decl_designator(type, sec, c, NULL, &f, size_only);
4925 index = f->c;
4926 if (!size_only && array_length < index) {
4927 init_putz(type, sec, c + array_length,
4928 index - array_length);
4930 index = index + type_size(&f->type, &align1);
4931 if (index > array_length)
4932 array_length = index;
4934 /* gr: skip fields from same union - ugly. */
4935 while (f->next) {
4936 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
4937 /* test for same offset */
4938 if (f->next->c != f->c)
4939 break;
4940 /* if yes, test for bitfield shift */
4941 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
4942 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4943 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4944 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
4945 if (bit_pos_1 != bit_pos_2)
4946 break;
4948 f = f->next;
4951 f = f->next;
4952 if (no_oblock && f == NULL)
4953 break;
4954 if (tok == '}')
4955 break;
4956 skip(',');
4958 /* put zeros at the end */
4959 if (!size_only && array_length < n) {
4960 init_putz(type, sec, c + array_length,
4961 n - array_length);
4963 if (!no_oblock)
4964 skip('}');
4965 while (par_count) {
4966 skip(')');
4967 par_count--;
4969 } else if (tok == '{') {
4970 next();
4971 decl_initializer(type, sec, c, first, size_only);
4972 skip('}');
4973 } else if (size_only) {
4974 /* just skip expression */
4975 parlevel = 0;
4976 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4977 tok != -1) {
4978 if (tok == '(')
4979 parlevel++;
4980 else if (tok == ')')
4981 parlevel--;
4982 next();
4984 } else {
4985 /* currently, we always use constant expression for globals
4986 (may change for scripting case) */
4987 expr_type = EXPR_CONST;
4988 if (!sec)
4989 expr_type = EXPR_ANY;
4990 init_putv(type, sec, c, 0, expr_type);
4994 /* parse an initializer for type 't' if 'has_init' is non zero, and
4995 allocate space in local or global data space ('r' is either
4996 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
4997 variable 'v' of scope 'scope' is declared before initializers are
4998 parsed. If 'v' is zero, then a reference to the new object is put
4999 in the value stack. If 'has_init' is 2, a special parsing is done
5000 to handle string constants. */
5001 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5002 int has_init, int v, int scope)
5004 int size, align, addr, data_offset;
5005 int level;
5006 ParseState saved_parse_state = {0};
5007 TokenString init_str;
5008 Section *sec;
5010 size = type_size(type, &align);
5011 /* If unknown size, we must evaluate it before
5012 evaluating initializers because
5013 initializers can generate global data too
5014 (e.g. string pointers or ISOC99 compound
5015 literals). It also simplifies local
5016 initializers handling */
5017 tok_str_new(&init_str);
5018 if (size < 0) {
5019 if (!has_init)
5020 error("unknown type size");
5021 /* get all init string */
5022 if (has_init == 2) {
5023 /* only get strings */
5024 while (tok == TOK_STR || tok == TOK_LSTR) {
5025 tok_str_add_tok(&init_str);
5026 next();
5028 } else {
5029 level = 0;
5030 while (level > 0 || (tok != ',' && tok != ';')) {
5031 if (tok < 0)
5032 error("unexpected end of file in initializer");
5033 tok_str_add_tok(&init_str);
5034 if (tok == '{')
5035 level++;
5036 else if (tok == '}') {
5037 level--;
5038 if (level <= 0) {
5039 next();
5040 break;
5043 next();
5046 tok_str_add(&init_str, -1);
5047 tok_str_add(&init_str, 0);
5049 /* compute size */
5050 save_parse_state(&saved_parse_state);
5052 macro_ptr = init_str.str;
5053 next();
5054 decl_initializer(type, NULL, 0, 1, 1);
5055 /* prepare second initializer parsing */
5056 macro_ptr = init_str.str;
5057 next();
5059 /* if still unknown size, error */
5060 size = type_size(type, &align);
5061 if (size < 0)
5062 error("unknown type size");
5064 /* take into account specified alignment if bigger */
5065 if (ad->aligned) {
5066 if (ad->aligned > align)
5067 align = ad->aligned;
5068 } else if (ad->packed) {
5069 align = 1;
5071 if ((r & VT_VALMASK) == VT_LOCAL) {
5072 sec = NULL;
5073 #ifdef CONFIG_TCC_BCHECK
5074 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
5075 loc--;
5076 #endif
5077 loc = (loc - size) & -align;
5078 addr = loc;
5079 #ifdef CONFIG_TCC_BCHECK
5080 /* handles bounds */
5081 /* XXX: currently, since we do only one pass, we cannot track
5082 '&' operators, so we add only arrays */
5083 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5084 unsigned long *bounds_ptr;
5085 /* add padding between regions */
5086 loc--;
5087 /* then add local bound info */
5088 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5089 bounds_ptr[0] = addr;
5090 bounds_ptr[1] = size;
5092 #endif
5093 if (v) {
5094 /* local variable */
5095 sym_push(v, type, r, addr);
5096 } else {
5097 /* push local reference */
5098 vset(type, r, addr);
5100 } else {
5101 Sym *sym;
5103 sym = NULL;
5104 if (v && scope == VT_CONST) {
5105 /* see if the symbol was already defined */
5106 sym = sym_find(v);
5107 if (sym) {
5108 if (!is_compatible_types(&sym->type, type))
5109 error("incompatible types for redefinition of '%s'",
5110 get_tok_str(v, NULL));
5111 if (sym->type.t & VT_EXTERN) {
5112 /* if the variable is extern, it was not allocated */
5113 sym->type.t &= ~VT_EXTERN;
5114 /* set array size if it was ommited in extern
5115 declaration */
5116 if ((sym->type.t & VT_ARRAY) &&
5117 sym->type.ref->c < 0 &&
5118 type->ref->c >= 0)
5119 sym->type.ref->c = type->ref->c;
5120 } else {
5121 /* we accept several definitions of the same
5122 global variable. this is tricky, because we
5123 must play with the SHN_COMMON type of the symbol */
5124 /* XXX: should check if the variable was already
5125 initialized. It is incorrect to initialized it
5126 twice */
5127 /* no init data, we won't add more to the symbol */
5128 if (!has_init)
5129 goto no_alloc;
5134 /* allocate symbol in corresponding section */
5135 sec = ad->section;
5136 if (!sec) {
5137 if (has_init)
5138 sec = data_section;
5139 else if (tcc_state->nocommon)
5140 sec = bss_section;
5142 if (sec) {
5143 data_offset = sec->data_offset;
5144 data_offset = (data_offset + align - 1) & -align;
5145 addr = data_offset;
5146 /* very important to increment global pointer at this time
5147 because initializers themselves can create new initializers */
5148 data_offset += size;
5149 #ifdef CONFIG_TCC_BCHECK
5150 /* add padding if bound check */
5151 if (tcc_state->do_bounds_check)
5152 data_offset++;
5153 #endif
5154 sec->data_offset = data_offset;
5155 /* allocate section space to put the data */
5156 if (sec->sh_type != SHT_NOBITS &&
5157 data_offset > sec->data_allocated)
5158 section_realloc(sec, data_offset);
5159 /* align section if needed */
5160 if (align > sec->sh_addralign)
5161 sec->sh_addralign = align;
5162 } else {
5163 addr = 0; /* avoid warning */
5166 if (v) {
5167 if (scope != VT_CONST || !sym) {
5168 sym = sym_push(v, type, r | VT_SYM, 0);
5170 /* update symbol definition */
5171 if (sec) {
5172 put_extern_sym(sym, sec, addr, size);
5173 } else {
5174 ElfW(Sym) *esym;
5175 /* put a common area */
5176 put_extern_sym(sym, NULL, align, size);
5177 /* XXX: find a nicer way */
5178 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5179 esym->st_shndx = SHN_COMMON;
5181 } else {
5182 CValue cval;
5184 /* push global reference */
5185 sym = get_sym_ref(type, sec, addr, size);
5186 cval.ul = 0;
5187 vsetc(type, VT_CONST | VT_SYM, &cval);
5188 vtop->sym = sym;
5190 #ifdef CONFIG_TCC_BCHECK
5191 /* handles bounds now because the symbol must be defined
5192 before for the relocation */
5193 if (tcc_state->do_bounds_check) {
5194 unsigned long *bounds_ptr;
5196 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5197 /* then add global bound info */
5198 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5199 bounds_ptr[0] = 0; /* relocated */
5200 bounds_ptr[1] = size;
5202 #endif
5204 if (has_init) {
5205 decl_initializer(type, sec, addr, 1, 0);
5206 /* restore parse state if needed */
5207 if (init_str.str) {
5208 tok_str_free(init_str.str);
5209 restore_parse_state(&saved_parse_state);
5212 no_alloc: ;
5215 static void put_func_debug(Sym *sym)
5217 char buf[512];
5219 /* stabs info */
5220 /* XXX: we put here a dummy type */
5221 snprintf(buf, sizeof(buf), "%s:%c1",
5222 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5223 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5224 cur_text_section, sym->c);
5225 /* //gr gdb wants a line at the function */
5226 put_stabn(N_SLINE, 0, file->line_num, 0);
5227 last_ind = 0;
5228 last_line_num = 0;
5231 /* parse an old style function declaration list */
5232 /* XXX: check multiple parameter */
5233 static void func_decl_list(Sym *func_sym)
5235 AttributeDef ad;
5236 int v;
5237 Sym *s;
5238 CType btype, type;
5240 /* parse each declaration */
5241 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
5242 if (!parse_btype(&btype, &ad))
5243 expect("declaration list");
5244 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5245 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5246 tok == ';') {
5247 /* we accept no variable after */
5248 } else {
5249 for(;;) {
5250 type = btype;
5251 type_decl(&type, &ad, &v, TYPE_DIRECT);
5252 /* find parameter in function parameter list */
5253 s = func_sym->next;
5254 while (s != NULL) {
5255 if ((s->v & ~SYM_FIELD) == v)
5256 goto found;
5257 s = s->next;
5259 error("declaration for parameter '%s' but no such parameter",
5260 get_tok_str(v, NULL));
5261 found:
5262 /* check that no storage specifier except 'register' was given */
5263 if (type.t & VT_STORAGE)
5264 error("storage class specified for '%s'", get_tok_str(v, NULL));
5265 convert_parameter_type(&type);
5266 /* we can add the type (NOTE: it could be local to the function) */
5267 s->type = type;
5268 /* accept other parameters */
5269 if (tok == ',')
5270 next();
5271 else
5272 break;
5275 skip(';');
5279 /* parse a function defined by symbol 'sym' and generate its code in
5280 'cur_text_section' */
5281 static void gen_function(Sym *sym)
5283 int saved_nocode_wanted = nocode_wanted;
5284 nocode_wanted = 0;
5285 ind = cur_text_section->data_offset;
5286 /* NOTE: we patch the symbol size later */
5287 put_extern_sym(sym, cur_text_section, ind, 0);
5288 if (sym->a)
5289 funcname = get_tok_str(sym->a, NULL);
5290 else
5291 funcname = get_tok_str(sym->v, NULL);
5292 func_ind = ind;
5293 /* put debug symbol */
5294 if (tcc_state->do_debug)
5295 put_func_debug(sym);
5296 /* push a dummy symbol to enable local sym storage */
5297 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5298 gfunc_prolog(&sym->type);
5299 rsym = 0;
5300 block(NULL, NULL, NULL, NULL, 0, 0);
5301 gsym(rsym);
5302 gfunc_epilog();
5303 cur_text_section->data_offset = ind;
5304 label_pop(&global_label_stack, NULL);
5305 sym_pop(&local_stack, NULL); /* reset local stack */
5306 /* end of function */
5307 /* patch symbol size */
5308 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5309 ind - func_ind;
5310 if (tcc_state->do_debug) {
5311 put_stabn(N_FUN, 0, 0, ind - func_ind);
5313 /* It's better to crash than to generate wrong code */
5314 cur_text_section = NULL;
5315 funcname = ""; /* for safety */
5316 func_vt.t = VT_VOID; /* for safety */
5317 ind = 0; /* for safety */
5318 nocode_wanted = saved_nocode_wanted;
5321 ST_FUNC void gen_inline_functions(void)
5323 Sym *sym;
5324 int *str, inline_generated, i;
5325 struct InlineFunc *fn;
5327 /* iterate while inline function are referenced */
5328 for(;;) {
5329 inline_generated = 0;
5330 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5331 fn = tcc_state->inline_fns[i];
5332 sym = fn->sym;
5333 if (sym && sym->c) {
5334 /* the function was used: generate its code and
5335 convert it to a normal function */
5336 str = fn->token_str;
5337 fn->sym = NULL;
5338 if (file)
5339 strcpy(file->filename, fn->filename);
5340 sym->r = VT_SYM | VT_CONST;
5341 sym->type.t &= ~VT_INLINE;
5343 macro_ptr = str;
5344 next();
5345 cur_text_section = text_section;
5346 gen_function(sym);
5347 macro_ptr = NULL; /* fail safe */
5349 inline_generated = 1;
5352 if (!inline_generated)
5353 break;
5355 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5356 fn = tcc_state->inline_fns[i];
5357 str = fn->token_str;
5358 tok_str_free(str);
5360 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5363 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5364 ST_FUNC void decl(int l)
5366 int v, has_init, r;
5367 CType type, btype;
5368 Sym *sym;
5369 AttributeDef ad;
5372 * type.ref must be either a valid reference or NULL for external_sym to
5373 * work. As type = btype is executed before external_sym is call, setting
5374 * btype.ref to 0 is enough.
5376 btype.ref = 0;
5377 while (1) {
5378 if (!parse_btype(&btype, &ad)) {
5379 /* skip redundant ';' */
5380 /* XXX: find more elegant solution */
5381 if (tok == ';') {
5382 next();
5383 continue;
5385 if (l == VT_CONST &&
5386 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5387 /* global asm block */
5388 asm_global_instr();
5389 continue;
5391 /* special test for old K&R protos without explicit int
5392 type. Only accepted when defining global data */
5393 if (l == VT_LOCAL || tok < TOK_DEFINE)
5394 break;
5395 btype.t = VT_INT;
5397 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5398 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5399 tok == ';') {
5400 /* we accept no variable after */
5401 next();
5402 continue;
5404 while (1) { /* iterate thru each declaration */
5405 type = btype;
5406 type_decl(&type, &ad, &v, TYPE_DIRECT);
5407 #if 0
5409 char buf[500];
5410 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5411 printf("type = '%s'\n", buf);
5413 #endif
5414 if ((type.t & VT_BTYPE) == VT_FUNC) {
5415 /* if old style function prototype, we accept a
5416 declaration list */
5417 sym = type.ref;
5418 if (sym->c == FUNC_OLD)
5419 func_decl_list(sym);
5422 #ifdef TCC_TARGET_PE
5423 if (ad.func_import)
5424 type.t |= VT_IMPORT;
5425 if (ad.func_export)
5426 type.t |= VT_EXPORT;
5427 #endif
5428 if (tok == '{') {
5429 if (l == VT_LOCAL)
5430 error("cannot use local functions");
5431 if ((type.t & VT_BTYPE) != VT_FUNC)
5432 expect("function definition");
5434 /* reject abstract declarators in function definition */
5435 sym = type.ref;
5436 while ((sym = sym->next) != NULL)
5437 if (!(sym->v & ~SYM_FIELD))
5438 expect("identifier");
5440 /* XXX: cannot do better now: convert extern line to static inline */
5441 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5442 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5444 sym = sym_find(v);
5445 if (sym) {
5446 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5447 goto func_error1;
5449 r = sym->type.ref->r;
5450 /* use func_call from prototype if not defined */
5451 if (FUNC_CALL(r) != FUNC_CDECL
5452 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5453 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5455 /* use export from prototype */
5456 if (FUNC_EXPORT(r))
5457 FUNC_EXPORT(type.ref->r) = 1;
5459 /* use static from prototype */
5460 if (sym->type.t & VT_STATIC)
5461 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5463 if (!is_compatible_types(&sym->type, &type)) {
5464 func_error1:
5465 error("incompatible types for redefinition of '%s'",
5466 get_tok_str(v, NULL));
5468 /* if symbol is already defined, then put complete type */
5469 sym->type = type;
5470 } else {
5471 /* put function symbol */
5472 sym = global_identifier_push(v, type.t, 0);
5473 sym->type.ref = type.ref;
5476 /* static inline functions are just recorded as a kind
5477 of macro. Their code will be emitted at the end of
5478 the compilation unit only if they are used */
5479 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5480 (VT_INLINE | VT_STATIC)) {
5481 TokenString func_str;
5482 int block_level;
5483 struct InlineFunc *fn;
5484 const char *filename;
5486 tok_str_new(&func_str);
5488 block_level = 0;
5489 for(;;) {
5490 int t;
5491 if (tok == TOK_EOF)
5492 error("unexpected end of file");
5493 tok_str_add_tok(&func_str);
5494 t = tok;
5495 next();
5496 if (t == '{') {
5497 block_level++;
5498 } else if (t == '}') {
5499 block_level--;
5500 if (block_level == 0)
5501 break;
5504 tok_str_add(&func_str, -1);
5505 tok_str_add(&func_str, 0);
5506 filename = file ? file->filename : "";
5507 fn = tcc_malloc(sizeof *fn + strlen(filename));
5508 strcpy(fn->filename, filename);
5509 fn->sym = sym;
5510 fn->token_str = func_str.str;
5511 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5513 } else {
5514 /* compute text section */
5515 cur_text_section = ad.section;
5516 if (!cur_text_section)
5517 cur_text_section = text_section;
5518 sym->r = VT_SYM | VT_CONST;
5519 gen_function(sym);
5521 break;
5522 } else {
5523 if (btype.t & VT_TYPEDEF) {
5524 /* save typedefed type */
5525 /* XXX: test storage specifiers ? */
5526 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5527 sym->type.t |= VT_TYPEDEF;
5528 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
5529 Sym *fn;
5530 /* external function definition */
5531 /* specific case for func_call attribute */
5532 type.ref->r = INT_ATTR(&ad);
5533 fn = external_sym(v, &type, 0);
5535 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5536 char target[256];
5538 *target = 0;
5539 next();
5540 skip('(');
5541 /* Part 1: __USER_LABEL_PREFIX__ (user defined) */
5542 if (tok == TOK_STR)
5543 pstrcat(target, sizeof(target), tokc.cstr->data);
5544 else
5545 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5547 next();
5548 /* Part 2: api name */
5549 if (tok == TOK_STR)
5550 pstrcat(target, sizeof(target), tokc.cstr->data);
5551 else
5552 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5554 next();
5555 skip(')');
5556 if (tcc_state->warn_unsupported)
5557 warning("ignoring redirection from %s to %s\n", get_tok_str(v, NULL), target);
5559 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
5560 parse_attribute((AttributeDef *) &fn->type.ref->r);
5562 } else {
5563 /* not lvalue if array */
5564 r = 0;
5565 if (!(type.t & VT_ARRAY))
5566 r |= lvalue_type(type.t);
5567 has_init = (tok == '=');
5568 if ((btype.t & VT_EXTERN) ||
5569 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5570 !has_init && l == VT_CONST && type.ref->c < 0)) {
5571 /* external variable */
5572 /* NOTE: as GCC, uninitialized global static
5573 arrays of null size are considered as
5574 extern */
5575 external_sym(v, &type, r);
5576 } else {
5577 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5578 if (type.t & VT_STATIC)
5579 r |= VT_CONST;
5580 else
5581 r |= l;
5582 if (has_init)
5583 next();
5584 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
5587 if (tok != ',') {
5588 skip(';');
5589 break;
5591 next();