support weak attribute on variables
[tinycc.git] / tccgen.c
blob2d7e4aecac048bc82b3bf02ea0528857b309dc69
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->weak) {
2926 t |= VT_WEAK;
2928 if (ad->mode) {
2929 u = ad->mode -1;
2930 t = (t & ~VT_BTYPE) | u;
2932 break;
2933 /* GNUC typeof */
2934 case TOK_TYPEOF1:
2935 case TOK_TYPEOF2:
2936 case TOK_TYPEOF3:
2937 next();
2938 parse_expr_type(&type1);
2939 goto basic_type2;
2940 default:
2941 if (typespec_found || typedef_found)
2942 goto the_end;
2943 s = sym_find(tok);
2944 if (!s || !(s->type.t & VT_TYPEDEF))
2945 goto the_end;
2946 typedef_found = 1;
2947 t |= (s->type.t & ~VT_TYPEDEF);
2948 type->ref = s->type.ref;
2949 if (s->r) {
2950 /* get attributes from typedef */
2951 if (0 == ad->aligned)
2952 ad->aligned = FUNC_ALIGN(s->r);
2953 if (0 == ad->func_call)
2954 ad->func_call = FUNC_CALL(s->r);
2955 ad->packed |= FUNC_PACKED(s->r);
2957 next();
2958 typespec_found = 1;
2959 break;
2961 type_found = 1;
2963 the_end:
2964 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
2965 error("signed and unsigned modifier");
2966 if (tcc_state->char_is_unsigned) {
2967 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
2968 t |= VT_UNSIGNED;
2970 t &= ~VT_SIGNED;
2972 /* long is never used as type */
2973 if ((t & VT_BTYPE) == VT_LONG)
2974 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
2975 t = (t & ~VT_BTYPE) | VT_INT;
2976 #else
2977 t = (t & ~VT_BTYPE) | VT_LLONG;
2978 #endif
2979 type->t = t;
2980 return type_found;
2983 /* convert a function parameter type (array to pointer and function to
2984 function pointer) */
2985 static inline void convert_parameter_type(CType *pt)
2987 /* remove const and volatile qualifiers (XXX: const could be used
2988 to indicate a const function parameter */
2989 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
2990 /* array must be transformed to pointer according to ANSI C */
2991 pt->t &= ~VT_ARRAY;
2992 if ((pt->t & VT_BTYPE) == VT_FUNC) {
2993 mk_pointer(pt);
2997 ST_FUNC void parse_asm_str(CString *astr)
2999 skip('(');
3000 /* read the string */
3001 if (tok != TOK_STR)
3002 expect("string constant");
3003 cstr_new(astr);
3004 while (tok == TOK_STR) {
3005 /* XXX: add \0 handling too ? */
3006 cstr_cat(astr, tokc.cstr->data);
3007 next();
3009 cstr_ccat(astr, '\0');
3012 /* Parse an asm label and return the label
3013 * Don't forget to free the CString in the caller! */
3014 static void asm_label_instr(CString *astr)
3016 next();
3017 parse_asm_str(astr);
3018 skip(')');
3019 #ifdef ASM_DEBUG
3020 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3021 #endif
3024 static void post_type(CType *type, AttributeDef *ad)
3026 int n, l, t1, arg_size, align;
3027 Sym **plast, *s, *first;
3028 AttributeDef ad1;
3029 CType pt;
3031 if (tok == '(') {
3032 TokenSym *ts = NULL;
3034 /* function declaration */
3035 next();
3036 l = 0;
3037 first = NULL;
3038 plast = &first;
3039 arg_size = 0;
3040 if (tok != ')') {
3041 for(;;) {
3042 /* read param name and compute offset */
3043 if (l != FUNC_OLD) {
3044 if (!parse_btype(&pt, &ad1)) {
3045 if (l) {
3046 error("invalid type");
3047 } else {
3048 l = FUNC_OLD;
3049 goto old_proto;
3052 l = FUNC_NEW;
3053 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3054 break;
3055 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3056 if ((pt.t & VT_BTYPE) == VT_VOID)
3057 error("parameter declared as void");
3058 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3059 } else {
3060 old_proto:
3061 n = tok;
3062 if (n < TOK_UIDENT)
3063 expect("identifier");
3064 pt.t = VT_INT;
3065 next();
3067 convert_parameter_type(&pt);
3068 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3069 *plast = s;
3070 plast = &s->next;
3071 if (tok == ')')
3072 break;
3073 skip(',');
3074 if (l == FUNC_NEW && tok == TOK_DOTS) {
3075 l = FUNC_ELLIPSIS;
3076 next();
3077 break;
3081 /* if no parameters, then old type prototype */
3082 if (l == 0)
3083 l = FUNC_OLD;
3084 skip(')');
3085 t1 = type->t & VT_STORAGE;
3086 /* NOTE: const is ignored in returned type as it has a special
3087 meaning in gcc / C++ */
3088 type->t &= ~(VT_STORAGE | VT_CONSTANT);
3089 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
3090 CString astr;
3092 asm_label_instr(&astr);
3093 ts = tok_alloc(astr.data, strlen(astr.data));
3094 cstr_free(&astr);
3096 post_type(type, ad);
3097 /* we push a anonymous symbol which will contain the function prototype */
3098 ad->func_args = arg_size;
3099 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3100 if (ts != NULL)
3101 s->a = ts->tok;
3102 s->next = first;
3103 type->t = t1 | VT_FUNC;
3104 type->ref = s;
3105 } else if (tok == '[') {
3106 /* array definition */
3107 next();
3108 if (tok == TOK_RESTRICT1)
3109 next();
3110 n = -1;
3111 if (tok != ']') {
3112 n = expr_const();
3113 if (n < 0)
3114 error("invalid array size");
3116 skip(']');
3117 /* parse next post type */
3118 t1 = type->t & VT_STORAGE;
3119 type->t &= ~VT_STORAGE;
3120 post_type(type, ad);
3122 /* we push a anonymous symbol which will contain the array
3123 element type */
3124 s = sym_push(SYM_FIELD, type, 0, n);
3125 type->t = t1 | VT_ARRAY | VT_PTR;
3126 type->ref = s;
3130 /* Parse a type declaration (except basic type), and return the type
3131 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3132 expected. 'type' should contain the basic type. 'ad' is the
3133 attribute definition of the basic type. It can be modified by
3134 type_decl().
3136 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3138 Sym *s;
3139 CType type1, *type2;
3140 int qualifiers;
3142 while (tok == '*') {
3143 qualifiers = 0;
3144 redo:
3145 next();
3146 switch(tok) {
3147 case TOK_CONST1:
3148 case TOK_CONST2:
3149 case TOK_CONST3:
3150 qualifiers |= VT_CONSTANT;
3151 goto redo;
3152 case TOK_VOLATILE1:
3153 case TOK_VOLATILE2:
3154 case TOK_VOLATILE3:
3155 qualifiers |= VT_VOLATILE;
3156 goto redo;
3157 case TOK_RESTRICT1:
3158 case TOK_RESTRICT2:
3159 case TOK_RESTRICT3:
3160 goto redo;
3162 mk_pointer(type);
3163 type->t |= qualifiers;
3166 /* XXX: clarify attribute handling */
3167 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3168 parse_attribute(ad);
3170 /* recursive type */
3171 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3172 type1.t = 0; /* XXX: same as int */
3173 if (tok == '(') {
3174 next();
3175 /* XXX: this is not correct to modify 'ad' at this point, but
3176 the syntax is not clear */
3177 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3178 parse_attribute(ad);
3179 type_decl(&type1, ad, v, td);
3180 skip(')');
3181 } else {
3182 /* type identifier */
3183 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3184 *v = tok;
3185 next();
3186 } else {
3187 if (!(td & TYPE_ABSTRACT))
3188 expect("identifier");
3189 *v = 0;
3192 post_type(type, ad);
3193 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3194 parse_attribute(ad);
3196 if (ad->weak)
3197 type->t |= VT_WEAK;
3199 if (!type1.t)
3200 return;
3201 /* append type at the end of type1 */
3202 type2 = &type1;
3203 for(;;) {
3204 s = type2->ref;
3205 type2 = &s->type;
3206 if (!type2->t) {
3207 *type2 = *type;
3208 break;
3211 *type = type1;
3214 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3215 ST_FUNC int lvalue_type(int t)
3217 int bt, r;
3218 r = VT_LVAL;
3219 bt = t & VT_BTYPE;
3220 if (bt == VT_BYTE || bt == VT_BOOL)
3221 r |= VT_LVAL_BYTE;
3222 else if (bt == VT_SHORT)
3223 r |= VT_LVAL_SHORT;
3224 else
3225 return r;
3226 if (t & VT_UNSIGNED)
3227 r |= VT_LVAL_UNSIGNED;
3228 return r;
3231 /* indirection with full error checking and bound check */
3232 ST_FUNC void indir(void)
3234 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3235 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3236 return;
3237 expect("pointer");
3239 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3240 gv(RC_INT);
3241 vtop->type = *pointed_type(&vtop->type);
3242 /* Arrays and functions are never lvalues */
3243 if (!(vtop->type.t & VT_ARRAY)
3244 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3245 vtop->r |= lvalue_type(vtop->type.t);
3246 /* if bound checking, the referenced pointer must be checked */
3247 #ifdef CONFIG_TCC_BCHECK
3248 if (tcc_state->do_bounds_check)
3249 vtop->r |= VT_MUSTBOUND;
3250 #endif
3254 /* pass a parameter to a function and do type checking and casting */
3255 static void gfunc_param_typed(Sym *func, Sym *arg)
3257 int func_type;
3258 CType type;
3260 func_type = func->c;
3261 if (func_type == FUNC_OLD ||
3262 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3263 /* default casting : only need to convert float to double */
3264 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3265 type.t = VT_DOUBLE;
3266 gen_cast(&type);
3268 } else if (arg == NULL) {
3269 error("too many arguments to function");
3270 } else {
3271 type = arg->type;
3272 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3273 gen_assign_cast(&type);
3277 /* parse an expression of the form '(type)' or '(expr)' and return its
3278 type */
3279 static void parse_expr_type(CType *type)
3281 int n;
3282 AttributeDef ad;
3284 skip('(');
3285 if (parse_btype(type, &ad)) {
3286 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3287 } else {
3288 expr_type(type);
3290 skip(')');
3293 static void parse_type(CType *type)
3295 AttributeDef ad;
3296 int n;
3298 if (!parse_btype(type, &ad)) {
3299 expect("type");
3301 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3304 static void vpush_tokc(int t)
3306 CType type;
3307 type.t = t;
3308 type.ref = 0;
3309 vsetc(&type, VT_CONST, &tokc);
3312 ST_FUNC void unary(void)
3314 int n, t, align, size, r, sizeof_caller;
3315 CType type;
3316 Sym *s;
3317 AttributeDef ad;
3318 static int in_sizeof = 0;
3320 sizeof_caller = in_sizeof;
3321 in_sizeof = 0;
3322 /* XXX: GCC 2.95.3 does not generate a table although it should be
3323 better here */
3324 tok_next:
3325 switch(tok) {
3326 case TOK_EXTENSION:
3327 next();
3328 goto tok_next;
3329 case TOK_CINT:
3330 case TOK_CCHAR:
3331 case TOK_LCHAR:
3332 vpushi(tokc.i);
3333 next();
3334 break;
3335 case TOK_CUINT:
3336 vpush_tokc(VT_INT | VT_UNSIGNED);
3337 next();
3338 break;
3339 case TOK_CLLONG:
3340 vpush_tokc(VT_LLONG);
3341 next();
3342 break;
3343 case TOK_CULLONG:
3344 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3345 next();
3346 break;
3347 case TOK_CFLOAT:
3348 vpush_tokc(VT_FLOAT);
3349 next();
3350 break;
3351 case TOK_CDOUBLE:
3352 vpush_tokc(VT_DOUBLE);
3353 next();
3354 break;
3355 case TOK_CLDOUBLE:
3356 vpush_tokc(VT_LDOUBLE);
3357 next();
3358 break;
3359 case TOK___FUNCTION__:
3360 if (!gnu_ext)
3361 goto tok_identifier;
3362 /* fall thru */
3363 case TOK___FUNC__:
3365 void *ptr;
3366 int len;
3367 /* special function name identifier */
3368 len = strlen(funcname) + 1;
3369 /* generate char[len] type */
3370 type.t = VT_BYTE;
3371 mk_pointer(&type);
3372 type.t |= VT_ARRAY;
3373 type.ref->c = len;
3374 vpush_ref(&type, data_section, data_section->data_offset, len);
3375 ptr = section_ptr_add(data_section, len);
3376 memcpy(ptr, funcname, len);
3377 next();
3379 break;
3380 case TOK_LSTR:
3381 #ifdef TCC_TARGET_PE
3382 t = VT_SHORT | VT_UNSIGNED;
3383 #else
3384 t = VT_INT;
3385 #endif
3386 goto str_init;
3387 case TOK_STR:
3388 /* string parsing */
3389 t = VT_BYTE;
3390 str_init:
3391 if (tcc_state->warn_write_strings)
3392 t |= VT_CONSTANT;
3393 type.t = t;
3394 mk_pointer(&type);
3395 type.t |= VT_ARRAY;
3396 memset(&ad, 0, sizeof(AttributeDef));
3397 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3398 break;
3399 case '(':
3400 next();
3401 /* cast ? */
3402 if (parse_btype(&type, &ad)) {
3403 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3404 skip(')');
3405 /* check ISOC99 compound literal */
3406 if (tok == '{') {
3407 /* data is allocated locally by default */
3408 if (global_expr)
3409 r = VT_CONST;
3410 else
3411 r = VT_LOCAL;
3412 /* all except arrays are lvalues */
3413 if (!(type.t & VT_ARRAY))
3414 r |= lvalue_type(type.t);
3415 memset(&ad, 0, sizeof(AttributeDef));
3416 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3417 } else {
3418 if (sizeof_caller) {
3419 vpush(&type);
3420 return;
3422 unary();
3423 gen_cast(&type);
3425 } else if (tok == '{') {
3426 /* save all registers */
3427 save_regs(0);
3428 /* statement expression : we do not accept break/continue
3429 inside as GCC does */
3430 block(NULL, NULL, NULL, NULL, 0, 1);
3431 skip(')');
3432 } else {
3433 gexpr();
3434 skip(')');
3436 break;
3437 case '*':
3438 next();
3439 unary();
3440 indir();
3441 break;
3442 case '&':
3443 next();
3444 unary();
3445 /* functions names must be treated as function pointers,
3446 except for unary '&' and sizeof. Since we consider that
3447 functions are not lvalues, we only have to handle it
3448 there and in function calls. */
3449 /* arrays can also be used although they are not lvalues */
3450 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3451 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3452 test_lvalue();
3453 mk_pointer(&vtop->type);
3454 gaddrof();
3455 break;
3456 case '!':
3457 next();
3458 unary();
3459 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3460 CType boolean;
3461 boolean.t = VT_BOOL;
3462 gen_cast(&boolean);
3463 vtop->c.i = !vtop->c.i;
3464 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3465 vtop->c.i = vtop->c.i ^ 1;
3466 else {
3467 save_regs(1);
3468 vseti(VT_JMP, gtst(1, 0));
3470 break;
3471 case '~':
3472 next();
3473 unary();
3474 vpushi(-1);
3475 gen_op('^');
3476 break;
3477 case '+':
3478 next();
3479 /* in order to force cast, we add zero */
3480 unary();
3481 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3482 error("pointer not accepted for unary plus");
3483 vpushi(0);
3484 gen_op('+');
3485 break;
3486 case TOK_SIZEOF:
3487 case TOK_ALIGNOF1:
3488 case TOK_ALIGNOF2:
3489 t = tok;
3490 next();
3491 in_sizeof++;
3492 unary_type(&type); // Perform a in_sizeof = 0;
3493 size = type_size(&type, &align);
3494 if (t == TOK_SIZEOF) {
3495 if (size < 0)
3496 error("sizeof applied to an incomplete type");
3497 vpushi(size);
3498 } else {
3499 vpushi(align);
3501 vtop->type.t |= VT_UNSIGNED;
3502 break;
3504 case TOK_builtin_types_compatible_p:
3506 CType type1, type2;
3507 next();
3508 skip('(');
3509 parse_type(&type1);
3510 skip(',');
3511 parse_type(&type2);
3512 skip(')');
3513 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3514 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3515 vpushi(is_compatible_types(&type1, &type2));
3517 break;
3518 case TOK_builtin_constant_p:
3520 int saved_nocode_wanted, res;
3521 next();
3522 skip('(');
3523 saved_nocode_wanted = nocode_wanted;
3524 nocode_wanted = 1;
3525 gexpr();
3526 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3527 vpop();
3528 nocode_wanted = saved_nocode_wanted;
3529 skip(')');
3530 vpushi(res);
3532 break;
3533 case TOK_builtin_frame_address:
3535 CType type;
3536 next();
3537 skip('(');
3538 if (tok != TOK_CINT) {
3539 error("__builtin_frame_address only takes integers");
3541 if (tokc.i != 0) {
3542 error("TCC only supports __builtin_frame_address(0)");
3544 next();
3545 skip(')');
3546 type.t = VT_VOID;
3547 mk_pointer(&type);
3548 vset(&type, VT_LOCAL, 0);
3550 break;
3551 #ifdef TCC_TARGET_X86_64
3552 case TOK_builtin_va_arg_types:
3554 /* This definition must be synced with stdarg.h */
3555 enum __va_arg_type {
3556 __va_gen_reg, __va_float_reg, __va_stack
3558 CType type;
3559 int bt;
3560 next();
3561 skip('(');
3562 parse_type(&type);
3563 skip(')');
3564 bt = type.t & VT_BTYPE;
3565 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3566 vpushi(__va_stack);
3567 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3568 vpushi(__va_float_reg);
3569 } else {
3570 vpushi(__va_gen_reg);
3573 break;
3574 #endif
3575 case TOK_INC:
3576 case TOK_DEC:
3577 t = tok;
3578 next();
3579 unary();
3580 inc(0, t);
3581 break;
3582 case '-':
3583 next();
3584 vpushi(0);
3585 unary();
3586 gen_op('-');
3587 break;
3588 case TOK_LAND:
3589 if (!gnu_ext)
3590 goto tok_identifier;
3591 next();
3592 /* allow to take the address of a label */
3593 if (tok < TOK_UIDENT)
3594 expect("label identifier");
3595 s = label_find(tok);
3596 if (!s) {
3597 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3598 } else {
3599 if (s->r == LABEL_DECLARED)
3600 s->r = LABEL_FORWARD;
3602 if (!s->type.t) {
3603 s->type.t = VT_VOID;
3604 mk_pointer(&s->type);
3605 s->type.t |= VT_STATIC;
3607 vset(&s->type, VT_CONST | VT_SYM, 0);
3608 vtop->sym = s;
3609 next();
3610 break;
3612 // special qnan , snan and infinity values
3613 case TOK___NAN__:
3614 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3615 next();
3616 break;
3617 case TOK___SNAN__:
3618 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3619 next();
3620 break;
3621 case TOK___INF__:
3622 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3623 next();
3624 break;
3626 default:
3627 tok_identifier:
3628 t = tok;
3629 next();
3630 if (t < TOK_UIDENT)
3631 expect("identifier");
3632 s = sym_find(t);
3633 if (!s) {
3634 if (tok != '(')
3635 error("'%s' undeclared", get_tok_str(t, NULL));
3636 /* for simple function calls, we tolerate undeclared
3637 external reference to int() function */
3638 if (tcc_state->warn_implicit_function_declaration)
3639 warning("implicit declaration of function '%s'",
3640 get_tok_str(t, NULL));
3641 s = external_global_sym(t, &func_old_type, 0);
3643 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3644 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3645 /* if referencing an inline function, then we generate a
3646 symbol to it if not already done. It will have the
3647 effect to generate code for it at the end of the
3648 compilation unit. Inline function as always
3649 generated in the text section. */
3650 if (!s->c)
3651 put_extern_sym(s, text_section, 0, 0);
3652 r = VT_SYM | VT_CONST;
3653 } else {
3654 r = s->r;
3656 vset(&s->type, r, s->c);
3657 /* if forward reference, we must point to s */
3658 if (vtop->r & VT_SYM) {
3659 vtop->sym = s;
3660 vtop->c.ul = 0;
3662 break;
3665 /* post operations */
3666 while (1) {
3667 if (tok == TOK_INC || tok == TOK_DEC) {
3668 inc(1, tok);
3669 next();
3670 } else if (tok == '.' || tok == TOK_ARROW) {
3671 int qualifiers;
3672 /* field */
3673 if (tok == TOK_ARROW)
3674 indir();
3675 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3676 test_lvalue();
3677 gaddrof();
3678 next();
3679 /* expect pointer on structure */
3680 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3681 expect("struct or union");
3682 s = vtop->type.ref;
3683 /* find field */
3684 tok |= SYM_FIELD;
3685 while ((s = s->next) != NULL) {
3686 if (s->v == tok)
3687 break;
3689 if (!s)
3690 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3691 /* add field offset to pointer */
3692 vtop->type = char_pointer_type; /* change type to 'char *' */
3693 vpushi(s->c);
3694 gen_op('+');
3695 /* change type to field type, and set to lvalue */
3696 vtop->type = s->type;
3697 vtop->type.t |= qualifiers;
3698 /* an array is never an lvalue */
3699 if (!(vtop->type.t & VT_ARRAY)) {
3700 vtop->r |= lvalue_type(vtop->type.t);
3701 #ifdef CONFIG_TCC_BCHECK
3702 /* if bound checking, the referenced pointer must be checked */
3703 if (tcc_state->do_bounds_check)
3704 vtop->r |= VT_MUSTBOUND;
3705 #endif
3707 next();
3708 } else if (tok == '[') {
3709 next();
3710 gexpr();
3711 gen_op('+');
3712 indir();
3713 skip(']');
3714 } else if (tok == '(') {
3715 SValue ret;
3716 Sym *sa;
3717 int nb_args;
3719 /* function call */
3720 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3721 /* pointer test (no array accepted) */
3722 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3723 vtop->type = *pointed_type(&vtop->type);
3724 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3725 goto error_func;
3726 } else {
3727 error_func:
3728 expect("function pointer");
3730 } else {
3731 vtop->r &= ~VT_LVAL; /* no lvalue */
3733 /* get return type */
3734 s = vtop->type.ref;
3735 next();
3736 sa = s->next; /* first parameter */
3737 nb_args = 0;
3738 ret.r2 = VT_CONST;
3739 /* compute first implicit argument if a structure is returned */
3740 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3741 /* get some space for the returned structure */
3742 size = type_size(&s->type, &align);
3743 loc = (loc - size) & -align;
3744 ret.type = s->type;
3745 ret.r = VT_LOCAL | VT_LVAL;
3746 /* pass it as 'int' to avoid structure arg passing
3747 problems */
3748 vseti(VT_LOCAL, loc);
3749 ret.c = vtop->c;
3750 nb_args++;
3751 } else {
3752 ret.type = s->type;
3753 /* return in register */
3754 if (is_float(ret.type.t)) {
3755 ret.r = reg_fret(ret.type.t);
3756 } else {
3757 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3758 ret.r2 = REG_LRET;
3759 ret.r = REG_IRET;
3761 ret.c.i = 0;
3763 if (tok != ')') {
3764 for(;;) {
3765 expr_eq();
3766 gfunc_param_typed(s, sa);
3767 nb_args++;
3768 if (sa)
3769 sa = sa->next;
3770 if (tok == ')')
3771 break;
3772 skip(',');
3775 if (sa)
3776 error("too few arguments to function");
3777 skip(')');
3778 if (!nocode_wanted) {
3779 gfunc_call(nb_args);
3780 } else {
3781 vtop -= (nb_args + 1);
3783 /* return value */
3784 vsetc(&ret.type, ret.r, &ret.c);
3785 vtop->r2 = ret.r2;
3786 } else {
3787 break;
3792 ST_FUNC void expr_prod(void)
3794 int t;
3796 unary();
3797 while (tok == '*' || tok == '/' || tok == '%') {
3798 t = tok;
3799 next();
3800 unary();
3801 gen_op(t);
3805 ST_FUNC void expr_sum(void)
3807 int t;
3809 expr_prod();
3810 while (tok == '+' || tok == '-') {
3811 t = tok;
3812 next();
3813 expr_prod();
3814 gen_op(t);
3818 static void expr_shift(void)
3820 int t;
3822 expr_sum();
3823 while (tok == TOK_SHL || tok == TOK_SAR) {
3824 t = tok;
3825 next();
3826 expr_sum();
3827 gen_op(t);
3831 static void expr_cmp(void)
3833 int t;
3835 expr_shift();
3836 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3837 tok == TOK_ULT || tok == TOK_UGE) {
3838 t = tok;
3839 next();
3840 expr_shift();
3841 gen_op(t);
3845 static void expr_cmpeq(void)
3847 int t;
3849 expr_cmp();
3850 while (tok == TOK_EQ || tok == TOK_NE) {
3851 t = tok;
3852 next();
3853 expr_cmp();
3854 gen_op(t);
3858 static void expr_and(void)
3860 expr_cmpeq();
3861 while (tok == '&') {
3862 next();
3863 expr_cmpeq();
3864 gen_op('&');
3868 static void expr_xor(void)
3870 expr_and();
3871 while (tok == '^') {
3872 next();
3873 expr_and();
3874 gen_op('^');
3878 static void expr_or(void)
3880 expr_xor();
3881 while (tok == '|') {
3882 next();
3883 expr_xor();
3884 gen_op('|');
3888 /* XXX: fix this mess */
3889 static void expr_land_const(void)
3891 expr_or();
3892 while (tok == TOK_LAND) {
3893 next();
3894 expr_or();
3895 gen_op(TOK_LAND);
3899 /* XXX: fix this mess */
3900 static void expr_lor_const(void)
3902 expr_land_const();
3903 while (tok == TOK_LOR) {
3904 next();
3905 expr_land_const();
3906 gen_op(TOK_LOR);
3910 /* only used if non constant */
3911 static void expr_land(void)
3913 int t;
3915 expr_or();
3916 if (tok == TOK_LAND) {
3917 t = 0;
3918 save_regs(1);
3919 for(;;) {
3920 t = gtst(1, t);
3921 if (tok != TOK_LAND) {
3922 vseti(VT_JMPI, t);
3923 break;
3925 next();
3926 expr_or();
3931 static void expr_lor(void)
3933 int t;
3935 expr_land();
3936 if (tok == TOK_LOR) {
3937 t = 0;
3938 save_regs(1);
3939 for(;;) {
3940 t = gtst(0, t);
3941 if (tok != TOK_LOR) {
3942 vseti(VT_JMP, t);
3943 break;
3945 next();
3946 expr_land();
3951 /* XXX: better constant handling */
3952 static void expr_cond(void)
3954 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
3955 SValue sv;
3956 CType type, type1, type2;
3958 if (const_wanted) {
3959 expr_lor_const();
3960 if (tok == '?') {
3961 CType boolean;
3962 int c;
3963 boolean.t = VT_BOOL;
3964 vdup();
3965 gen_cast(&boolean);
3966 c = vtop->c.i;
3967 vpop();
3968 next();
3969 if (tok != ':' || !gnu_ext) {
3970 vpop();
3971 gexpr();
3973 if (!c)
3974 vpop();
3975 skip(':');
3976 expr_cond();
3977 if (c)
3978 vpop();
3980 } else {
3981 expr_lor();
3982 if (tok == '?') {
3983 next();
3984 if (vtop != vstack) {
3985 /* needed to avoid having different registers saved in
3986 each branch */
3987 if (is_float(vtop->type.t)) {
3988 rc = RC_FLOAT;
3989 #ifdef TCC_TARGET_X86_64
3990 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
3991 rc = RC_ST0;
3993 #endif
3995 else
3996 rc = RC_INT;
3997 gv(rc);
3998 save_regs(1);
4000 if (tok == ':' && gnu_ext) {
4001 gv_dup();
4002 tt = gtst(1, 0);
4003 } else {
4004 tt = gtst(1, 0);
4005 gexpr();
4007 type1 = vtop->type;
4008 sv = *vtop; /* save value to handle it later */
4009 vtop--; /* no vpop so that FP stack is not flushed */
4010 skip(':');
4011 u = gjmp(0);
4012 gsym(tt);
4013 expr_cond();
4014 type2 = vtop->type;
4016 t1 = type1.t;
4017 bt1 = t1 & VT_BTYPE;
4018 t2 = type2.t;
4019 bt2 = t2 & VT_BTYPE;
4020 /* cast operands to correct type according to ISOC rules */
4021 if (is_float(bt1) || is_float(bt2)) {
4022 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4023 type.t = VT_LDOUBLE;
4024 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4025 type.t = VT_DOUBLE;
4026 } else {
4027 type.t = VT_FLOAT;
4029 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4030 /* cast to biggest op */
4031 type.t = VT_LLONG;
4032 /* convert to unsigned if it does not fit in a long long */
4033 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4034 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4035 type.t |= VT_UNSIGNED;
4036 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4037 /* XXX: test pointer compatibility */
4038 type = type1;
4039 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4040 /* XXX: test function pointer compatibility */
4041 type = type1;
4042 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4043 /* XXX: test structure compatibility */
4044 type = type1;
4045 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4046 /* NOTE: as an extension, we accept void on only one side */
4047 type.t = VT_VOID;
4048 } else {
4049 /* integer operations */
4050 type.t = VT_INT;
4051 /* convert to unsigned if it does not fit in an integer */
4052 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4053 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4054 type.t |= VT_UNSIGNED;
4057 /* now we convert second operand */
4058 gen_cast(&type);
4059 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4060 gaddrof();
4061 rc = RC_INT;
4062 if (is_float(type.t)) {
4063 rc = RC_FLOAT;
4064 #ifdef TCC_TARGET_X86_64
4065 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4066 rc = RC_ST0;
4068 #endif
4069 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4070 /* for long longs, we use fixed registers to avoid having
4071 to handle a complicated move */
4072 rc = RC_IRET;
4075 r2 = gv(rc);
4076 /* this is horrible, but we must also convert first
4077 operand */
4078 tt = gjmp(0);
4079 gsym(u);
4080 /* put again first value and cast it */
4081 *vtop = sv;
4082 gen_cast(&type);
4083 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4084 gaddrof();
4085 r1 = gv(rc);
4086 move_reg(r2, r1);
4087 vtop->r = r2;
4088 gsym(tt);
4093 static void expr_eq(void)
4095 int t;
4097 expr_cond();
4098 if (tok == '=' ||
4099 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4100 tok == TOK_A_XOR || tok == TOK_A_OR ||
4101 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4102 test_lvalue();
4103 t = tok;
4104 next();
4105 if (t == '=') {
4106 expr_eq();
4107 } else {
4108 vdup();
4109 expr_eq();
4110 gen_op(t & 0x7f);
4112 vstore();
4116 ST_FUNC void gexpr(void)
4118 while (1) {
4119 expr_eq();
4120 if (tok != ',')
4121 break;
4122 vpop();
4123 next();
4127 /* parse an expression and return its type without any side effect. */
4128 static void expr_type(CType *type)
4130 int saved_nocode_wanted;
4132 saved_nocode_wanted = nocode_wanted;
4133 nocode_wanted = 1;
4134 gexpr();
4135 *type = vtop->type;
4136 vpop();
4137 nocode_wanted = saved_nocode_wanted;
4140 /* parse a unary expression and return its type without any side
4141 effect. */
4142 static void unary_type(CType *type)
4144 int a;
4146 a = nocode_wanted;
4147 nocode_wanted = 1;
4148 unary();
4149 *type = vtop->type;
4150 vpop();
4151 nocode_wanted = a;
4154 /* parse a constant expression and return value in vtop. */
4155 static void expr_const1(void)
4157 int a;
4158 a = const_wanted;
4159 const_wanted = 1;
4160 expr_cond();
4161 const_wanted = a;
4164 /* parse an integer constant and return its value. */
4165 ST_FUNC int expr_const(void)
4167 int c;
4168 expr_const1();
4169 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4170 expect("constant expression");
4171 c = vtop->c.i;
4172 vpop();
4173 return c;
4176 /* return the label token if current token is a label, otherwise
4177 return zero */
4178 static int is_label(void)
4180 int last_tok;
4182 /* fast test first */
4183 if (tok < TOK_UIDENT)
4184 return 0;
4185 /* no need to save tokc because tok is an identifier */
4186 last_tok = tok;
4187 next();
4188 if (tok == ':') {
4189 next();
4190 return last_tok;
4191 } else {
4192 unget_tok(last_tok);
4193 return 0;
4197 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4198 int case_reg, int is_expr)
4200 int a, b, c, d;
4201 Sym *s;
4203 /* generate line number info */
4204 if (tcc_state->do_debug &&
4205 (last_line_num != file->line_num || last_ind != ind)) {
4206 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4207 last_ind = ind;
4208 last_line_num = file->line_num;
4211 if (is_expr) {
4212 /* default return value is (void) */
4213 vpushi(0);
4214 vtop->type.t = VT_VOID;
4217 if (tok == TOK_IF) {
4218 /* if test */
4219 next();
4220 skip('(');
4221 gexpr();
4222 skip(')');
4223 a = gtst(1, 0);
4224 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4225 c = tok;
4226 if (c == TOK_ELSE) {
4227 next();
4228 d = gjmp(0);
4229 gsym(a);
4230 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4231 gsym(d); /* patch else jmp */
4232 } else
4233 gsym(a);
4234 } else if (tok == TOK_WHILE) {
4235 next();
4236 d = ind;
4237 skip('(');
4238 gexpr();
4239 skip(')');
4240 a = gtst(1, 0);
4241 b = 0;
4242 block(&a, &b, case_sym, def_sym, case_reg, 0);
4243 gjmp_addr(d);
4244 gsym(a);
4245 gsym_addr(b, d);
4246 } else if (tok == '{') {
4247 Sym *llabel;
4249 next();
4250 /* record local declaration stack position */
4251 s = local_stack;
4252 llabel = local_label_stack;
4253 /* handle local labels declarations */
4254 if (tok == TOK_LABEL) {
4255 next();
4256 for(;;) {
4257 if (tok < TOK_UIDENT)
4258 expect("label identifier");
4259 label_push(&local_label_stack, tok, LABEL_DECLARED);
4260 next();
4261 if (tok == ',') {
4262 next();
4263 } else {
4264 skip(';');
4265 break;
4269 while (tok != '}') {
4270 decl(VT_LOCAL);
4271 if (tok != '}') {
4272 if (is_expr)
4273 vpop();
4274 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4277 /* pop locally defined labels */
4278 label_pop(&local_label_stack, llabel);
4279 /* pop locally defined symbols */
4280 if(is_expr) {
4281 /* XXX: this solution makes only valgrind happy...
4282 triggered by gcc.c-torture/execute/20000917-1.c */
4283 Sym *p;
4284 switch(vtop->type.t & VT_BTYPE) {
4285 case VT_PTR:
4286 case VT_STRUCT:
4287 case VT_ENUM:
4288 case VT_FUNC:
4289 for(p=vtop->type.ref;p;p=p->prev)
4290 if(p->prev==s)
4291 error("unsupported expression type");
4294 sym_pop(&local_stack, s);
4295 next();
4296 } else if (tok == TOK_RETURN) {
4297 next();
4298 if (tok != ';') {
4299 gexpr();
4300 gen_assign_cast(&func_vt);
4301 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4302 CType type;
4303 /* if returning structure, must copy it to implicit
4304 first pointer arg location */
4305 #ifdef TCC_ARM_EABI
4306 int align, size;
4307 size = type_size(&func_vt,&align);
4308 if(size <= 4)
4310 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4311 && (align & 3))
4313 int addr;
4314 loc = (loc - size) & -4;
4315 addr = loc;
4316 type = func_vt;
4317 vset(&type, VT_LOCAL | VT_LVAL, addr);
4318 vswap();
4319 vstore();
4320 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4322 vtop->type = int_type;
4323 gv(RC_IRET);
4324 } else {
4325 #endif
4326 type = func_vt;
4327 mk_pointer(&type);
4328 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4329 indir();
4330 vswap();
4331 /* copy structure value to pointer */
4332 vstore();
4333 #ifdef TCC_ARM_EABI
4335 #endif
4336 } else if (is_float(func_vt.t)) {
4337 gv(rc_fret(func_vt.t));
4338 } else {
4339 gv(RC_IRET);
4341 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4343 skip(';');
4344 rsym = gjmp(rsym); /* jmp */
4345 } else if (tok == TOK_BREAK) {
4346 /* compute jump */
4347 if (!bsym)
4348 error("cannot break");
4349 *bsym = gjmp(*bsym);
4350 next();
4351 skip(';');
4352 } else if (tok == TOK_CONTINUE) {
4353 /* compute jump */
4354 if (!csym)
4355 error("cannot continue");
4356 *csym = gjmp(*csym);
4357 next();
4358 skip(';');
4359 } else if (tok == TOK_FOR) {
4360 int e;
4361 next();
4362 skip('(');
4363 if (tok != ';') {
4364 gexpr();
4365 vpop();
4367 skip(';');
4368 d = ind;
4369 c = ind;
4370 a = 0;
4371 b = 0;
4372 if (tok != ';') {
4373 gexpr();
4374 a = gtst(1, 0);
4376 skip(';');
4377 if (tok != ')') {
4378 e = gjmp(0);
4379 c = ind;
4380 gexpr();
4381 vpop();
4382 gjmp_addr(d);
4383 gsym(e);
4385 skip(')');
4386 block(&a, &b, case_sym, def_sym, case_reg, 0);
4387 gjmp_addr(c);
4388 gsym(a);
4389 gsym_addr(b, c);
4390 } else
4391 if (tok == TOK_DO) {
4392 next();
4393 a = 0;
4394 b = 0;
4395 d = ind;
4396 block(&a, &b, case_sym, def_sym, case_reg, 0);
4397 skip(TOK_WHILE);
4398 skip('(');
4399 gsym(b);
4400 gexpr();
4401 c = gtst(0, 0);
4402 gsym_addr(c, d);
4403 skip(')');
4404 gsym(a);
4405 skip(';');
4406 } else
4407 if (tok == TOK_SWITCH) {
4408 next();
4409 skip('(');
4410 gexpr();
4411 /* XXX: other types than integer */
4412 case_reg = gv(RC_INT);
4413 vpop();
4414 skip(')');
4415 a = 0;
4416 b = gjmp(0); /* jump to first case */
4417 c = 0;
4418 block(&a, csym, &b, &c, case_reg, 0);
4419 /* if no default, jmp after switch */
4420 if (c == 0)
4421 c = ind;
4422 /* default label */
4423 gsym_addr(b, c);
4424 /* break label */
4425 gsym(a);
4426 } else
4427 if (tok == TOK_CASE) {
4428 int v1, v2;
4429 if (!case_sym)
4430 expect("switch");
4431 next();
4432 v1 = expr_const();
4433 v2 = v1;
4434 if (gnu_ext && tok == TOK_DOTS) {
4435 next();
4436 v2 = expr_const();
4437 if (v2 < v1)
4438 warning("empty case range");
4440 /* since a case is like a label, we must skip it with a jmp */
4441 b = gjmp(0);
4442 gsym(*case_sym);
4443 vseti(case_reg, 0);
4444 vpushi(v1);
4445 if (v1 == v2) {
4446 gen_op(TOK_EQ);
4447 *case_sym = gtst(1, 0);
4448 } else {
4449 gen_op(TOK_GE);
4450 *case_sym = gtst(1, 0);
4451 vseti(case_reg, 0);
4452 vpushi(v2);
4453 gen_op(TOK_LE);
4454 *case_sym = gtst(1, *case_sym);
4456 gsym(b);
4457 skip(':');
4458 is_expr = 0;
4459 goto block_after_label;
4460 } else
4461 if (tok == TOK_DEFAULT) {
4462 next();
4463 skip(':');
4464 if (!def_sym)
4465 expect("switch");
4466 if (*def_sym)
4467 error("too many 'default'");
4468 *def_sym = ind;
4469 is_expr = 0;
4470 goto block_after_label;
4471 } else
4472 if (tok == TOK_GOTO) {
4473 next();
4474 if (tok == '*' && gnu_ext) {
4475 /* computed goto */
4476 next();
4477 gexpr();
4478 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4479 expect("pointer");
4480 ggoto();
4481 } else if (tok >= TOK_UIDENT) {
4482 s = label_find(tok);
4483 /* put forward definition if needed */
4484 if (!s) {
4485 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4486 } else {
4487 if (s->r == LABEL_DECLARED)
4488 s->r = LABEL_FORWARD;
4490 /* label already defined */
4491 if (s->r & LABEL_FORWARD)
4492 s->jnext = gjmp(s->jnext);
4493 else
4494 gjmp_addr(s->jnext);
4495 next();
4496 } else {
4497 expect("label identifier");
4499 skip(';');
4500 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4501 asm_instr();
4502 } else {
4503 b = is_label();
4504 if (b) {
4505 /* label case */
4506 s = label_find(b);
4507 if (s) {
4508 if (s->r == LABEL_DEFINED)
4509 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4510 gsym(s->jnext);
4511 s->r = LABEL_DEFINED;
4512 } else {
4513 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4515 s->jnext = ind;
4516 /* we accept this, but it is a mistake */
4517 block_after_label:
4518 if (tok == '}') {
4519 warning("deprecated use of label at end of compound statement");
4520 } else {
4521 if (is_expr)
4522 vpop();
4523 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4525 } else {
4526 /* expression case */
4527 if (tok != ';') {
4528 if (is_expr) {
4529 vpop();
4530 gexpr();
4531 } else {
4532 gexpr();
4533 vpop();
4536 skip(';');
4541 /* t is the array or struct type. c is the array or struct
4542 address. cur_index/cur_field is the pointer to the current
4543 value. 'size_only' is true if only size info is needed (only used
4544 in arrays) */
4545 static void decl_designator(CType *type, Section *sec, unsigned long c,
4546 int *cur_index, Sym **cur_field,
4547 int size_only)
4549 Sym *s, *f;
4550 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4551 CType type1;
4553 notfirst = 0;
4554 elem_size = 0;
4555 nb_elems = 1;
4556 if (gnu_ext && (l = is_label()) != 0)
4557 goto struct_field;
4558 while (tok == '[' || tok == '.') {
4559 if (tok == '[') {
4560 if (!(type->t & VT_ARRAY))
4561 expect("array type");
4562 s = type->ref;
4563 next();
4564 index = expr_const();
4565 if (index < 0 || (s->c >= 0 && index >= s->c))
4566 expect("invalid index");
4567 if (tok == TOK_DOTS && gnu_ext) {
4568 next();
4569 index_last = expr_const();
4570 if (index_last < 0 ||
4571 (s->c >= 0 && index_last >= s->c) ||
4572 index_last < index)
4573 expect("invalid index");
4574 } else {
4575 index_last = index;
4577 skip(']');
4578 if (!notfirst)
4579 *cur_index = index_last;
4580 type = pointed_type(type);
4581 elem_size = type_size(type, &align);
4582 c += index * elem_size;
4583 /* NOTE: we only support ranges for last designator */
4584 nb_elems = index_last - index + 1;
4585 if (nb_elems != 1) {
4586 notfirst = 1;
4587 break;
4589 } else {
4590 next();
4591 l = tok;
4592 next();
4593 struct_field:
4594 if ((type->t & VT_BTYPE) != VT_STRUCT)
4595 expect("struct/union type");
4596 s = type->ref;
4597 l |= SYM_FIELD;
4598 f = s->next;
4599 while (f) {
4600 if (f->v == l)
4601 break;
4602 f = f->next;
4604 if (!f)
4605 expect("field");
4606 if (!notfirst)
4607 *cur_field = f;
4608 /* XXX: fix this mess by using explicit storage field */
4609 type1 = f->type;
4610 type1.t |= (type->t & ~VT_TYPE);
4611 type = &type1;
4612 c += f->c;
4614 notfirst = 1;
4616 if (notfirst) {
4617 if (tok == '=') {
4618 next();
4619 } else {
4620 if (!gnu_ext)
4621 expect("=");
4623 } else {
4624 if (type->t & VT_ARRAY) {
4625 index = *cur_index;
4626 type = pointed_type(type);
4627 c += index * type_size(type, &align);
4628 } else {
4629 f = *cur_field;
4630 if (!f)
4631 error("too many field init");
4632 /* XXX: fix this mess by using explicit storage field */
4633 type1 = f->type;
4634 type1.t |= (type->t & ~VT_TYPE);
4635 type = &type1;
4636 c += f->c;
4639 decl_initializer(type, sec, c, 0, size_only);
4641 /* XXX: make it more general */
4642 if (!size_only && nb_elems > 1) {
4643 unsigned long c_end;
4644 uint8_t *src, *dst;
4645 int i;
4647 if (!sec)
4648 error("range init not supported yet for dynamic storage");
4649 c_end = c + nb_elems * elem_size;
4650 if (c_end > sec->data_allocated)
4651 section_realloc(sec, c_end);
4652 src = sec->data + c;
4653 dst = src;
4654 for(i = 1; i < nb_elems; i++) {
4655 dst += elem_size;
4656 memcpy(dst, src, elem_size);
4661 #define EXPR_VAL 0
4662 #define EXPR_CONST 1
4663 #define EXPR_ANY 2
4665 /* store a value or an expression directly in global data or in local array */
4666 static void init_putv(CType *type, Section *sec, unsigned long c,
4667 int v, int expr_type)
4669 int saved_global_expr, bt, bit_pos, bit_size;
4670 void *ptr;
4671 unsigned long long bit_mask;
4672 CType dtype;
4674 switch(expr_type) {
4675 case EXPR_VAL:
4676 vpushi(v);
4677 break;
4678 case EXPR_CONST:
4679 /* compound literals must be allocated globally in this case */
4680 saved_global_expr = global_expr;
4681 global_expr = 1;
4682 expr_const1();
4683 global_expr = saved_global_expr;
4684 /* NOTE: symbols are accepted */
4685 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4686 error("initializer element is not constant");
4687 break;
4688 case EXPR_ANY:
4689 expr_eq();
4690 break;
4693 dtype = *type;
4694 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4696 if (sec) {
4697 /* XXX: not portable */
4698 /* XXX: generate error if incorrect relocation */
4699 gen_assign_cast(&dtype);
4700 bt = type->t & VT_BTYPE;
4701 /* we'll write at most 12 bytes */
4702 if (c + 12 > sec->data_allocated) {
4703 section_realloc(sec, c + 12);
4705 ptr = sec->data + c;
4706 /* XXX: make code faster ? */
4707 if (!(type->t & VT_BITFIELD)) {
4708 bit_pos = 0;
4709 bit_size = 32;
4710 bit_mask = -1LL;
4711 } else {
4712 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4713 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4714 bit_mask = (1LL << bit_size) - 1;
4716 if ((vtop->r & VT_SYM) &&
4717 (bt == VT_BYTE ||
4718 bt == VT_SHORT ||
4719 bt == VT_DOUBLE ||
4720 bt == VT_LDOUBLE ||
4721 bt == VT_LLONG ||
4722 (bt == VT_INT && bit_size != 32)))
4723 error("initializer element is not computable at load time");
4724 switch(bt) {
4725 case VT_BOOL:
4726 vtop->c.i = (vtop->c.i != 0);
4727 case VT_BYTE:
4728 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4729 break;
4730 case VT_SHORT:
4731 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4732 break;
4733 case VT_DOUBLE:
4734 *(double *)ptr = vtop->c.d;
4735 break;
4736 case VT_LDOUBLE:
4737 *(long double *)ptr = vtop->c.ld;
4738 break;
4739 case VT_LLONG:
4740 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4741 break;
4742 default:
4743 if (vtop->r & VT_SYM) {
4744 greloc(sec, vtop->sym, c, R_DATA_PTR);
4746 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4747 break;
4749 vtop--;
4750 } else {
4751 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4752 vswap();
4753 vstore();
4754 vpop();
4758 /* put zeros for variable based init */
4759 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4761 if (sec) {
4762 /* nothing to do because globals are already set to zero */
4763 } else {
4764 vpush_global_sym(&func_old_type, TOK_memset);
4765 vseti(VT_LOCAL, c);
4766 vpushi(0);
4767 vpushi(size);
4768 gfunc_call(3);
4772 /* 't' contains the type and storage info. 'c' is the offset of the
4773 object in section 'sec'. If 'sec' is NULL, it means stack based
4774 allocation. 'first' is true if array '{' must be read (multi
4775 dimension implicit array init handling). 'size_only' is true if
4776 size only evaluation is wanted (only for arrays). */
4777 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4778 int first, int size_only)
4780 int index, array_length, n, no_oblock, nb, parlevel, i;
4781 int size1, align1, expr_type;
4782 Sym *s, *f;
4783 CType *t1;
4785 if (type->t & VT_ARRAY) {
4786 s = type->ref;
4787 n = s->c;
4788 array_length = 0;
4789 t1 = pointed_type(type);
4790 size1 = type_size(t1, &align1);
4792 no_oblock = 1;
4793 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4794 tok == '{') {
4795 if (tok != '{')
4796 error("character array initializer must be a literal,"
4797 " optionally enclosed in braces");
4798 skip('{');
4799 no_oblock = 0;
4802 /* only parse strings here if correct type (otherwise: handle
4803 them as ((w)char *) expressions */
4804 if ((tok == TOK_LSTR &&
4805 #ifdef TCC_TARGET_PE
4806 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4807 #else
4808 (t1->t & VT_BTYPE) == VT_INT
4809 #endif
4810 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4811 while (tok == TOK_STR || tok == TOK_LSTR) {
4812 int cstr_len, ch;
4813 CString *cstr;
4815 cstr = tokc.cstr;
4816 /* compute maximum number of chars wanted */
4817 if (tok == TOK_STR)
4818 cstr_len = cstr->size;
4819 else
4820 cstr_len = cstr->size / sizeof(nwchar_t);
4821 cstr_len--;
4822 nb = cstr_len;
4823 if (n >= 0 && nb > (n - array_length))
4824 nb = n - array_length;
4825 if (!size_only) {
4826 if (cstr_len > nb)
4827 warning("initializer-string for array is too long");
4828 /* in order to go faster for common case (char
4829 string in global variable, we handle it
4830 specifically */
4831 if (sec && tok == TOK_STR && size1 == 1) {
4832 memcpy(sec->data + c + array_length, cstr->data, nb);
4833 } else {
4834 for(i=0;i<nb;i++) {
4835 if (tok == TOK_STR)
4836 ch = ((unsigned char *)cstr->data)[i];
4837 else
4838 ch = ((nwchar_t *)cstr->data)[i];
4839 init_putv(t1, sec, c + (array_length + i) * size1,
4840 ch, EXPR_VAL);
4844 array_length += nb;
4845 next();
4847 /* only add trailing zero if enough storage (no
4848 warning in this case since it is standard) */
4849 if (n < 0 || array_length < n) {
4850 if (!size_only) {
4851 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4853 array_length++;
4855 } else {
4856 index = 0;
4857 while (tok != '}') {
4858 decl_designator(type, sec, c, &index, NULL, size_only);
4859 if (n >= 0 && index >= n)
4860 error("index too large");
4861 /* must put zero in holes (note that doing it that way
4862 ensures that it even works with designators) */
4863 if (!size_only && array_length < index) {
4864 init_putz(t1, sec, c + array_length * size1,
4865 (index - array_length) * size1);
4867 index++;
4868 if (index > array_length)
4869 array_length = index;
4870 /* special test for multi dimensional arrays (may not
4871 be strictly correct if designators are used at the
4872 same time) */
4873 if (index >= n && no_oblock)
4874 break;
4875 if (tok == '}')
4876 break;
4877 skip(',');
4880 if (!no_oblock)
4881 skip('}');
4882 /* put zeros at the end */
4883 if (!size_only && n >= 0 && array_length < n) {
4884 init_putz(t1, sec, c + array_length * size1,
4885 (n - array_length) * size1);
4887 /* patch type size if needed */
4888 if (n < 0)
4889 s->c = array_length;
4890 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4891 (sec || !first || tok == '{')) {
4892 int par_count;
4894 /* NOTE: the previous test is a specific case for automatic
4895 struct/union init */
4896 /* XXX: union needs only one init */
4898 /* XXX: this test is incorrect for local initializers
4899 beginning with ( without {. It would be much more difficult
4900 to do it correctly (ideally, the expression parser should
4901 be used in all cases) */
4902 par_count = 0;
4903 if (tok == '(') {
4904 AttributeDef ad1;
4905 CType type1;
4906 next();
4907 while (tok == '(') {
4908 par_count++;
4909 next();
4911 if (!parse_btype(&type1, &ad1))
4912 expect("cast");
4913 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4914 #if 0
4915 if (!is_assignable_types(type, &type1))
4916 error("invalid type for cast");
4917 #endif
4918 skip(')');
4920 no_oblock = 1;
4921 if (first || tok == '{') {
4922 skip('{');
4923 no_oblock = 0;
4925 s = type->ref;
4926 f = s->next;
4927 array_length = 0;
4928 index = 0;
4929 n = s->c;
4930 while (tok != '}') {
4931 decl_designator(type, sec, c, NULL, &f, size_only);
4932 index = f->c;
4933 if (!size_only && array_length < index) {
4934 init_putz(type, sec, c + array_length,
4935 index - array_length);
4937 index = index + type_size(&f->type, &align1);
4938 if (index > array_length)
4939 array_length = index;
4941 /* gr: skip fields from same union - ugly. */
4942 while (f->next) {
4943 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
4944 /* test for same offset */
4945 if (f->next->c != f->c)
4946 break;
4947 /* if yes, test for bitfield shift */
4948 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
4949 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4950 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4951 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
4952 if (bit_pos_1 != bit_pos_2)
4953 break;
4955 f = f->next;
4958 f = f->next;
4959 if (no_oblock && f == NULL)
4960 break;
4961 if (tok == '}')
4962 break;
4963 skip(',');
4965 /* put zeros at the end */
4966 if (!size_only && array_length < n) {
4967 init_putz(type, sec, c + array_length,
4968 n - array_length);
4970 if (!no_oblock)
4971 skip('}');
4972 while (par_count) {
4973 skip(')');
4974 par_count--;
4976 } else if (tok == '{') {
4977 next();
4978 decl_initializer(type, sec, c, first, size_only);
4979 skip('}');
4980 } else if (size_only) {
4981 /* just skip expression */
4982 parlevel = 0;
4983 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4984 tok != -1) {
4985 if (tok == '(')
4986 parlevel++;
4987 else if (tok == ')')
4988 parlevel--;
4989 next();
4991 } else {
4992 /* currently, we always use constant expression for globals
4993 (may change for scripting case) */
4994 expr_type = EXPR_CONST;
4995 if (!sec)
4996 expr_type = EXPR_ANY;
4997 init_putv(type, sec, c, 0, expr_type);
5001 /* parse an initializer for type 't' if 'has_init' is non zero, and
5002 allocate space in local or global data space ('r' is either
5003 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5004 variable 'v' of scope 'scope' is declared before initializers are
5005 parsed. If 'v' is zero, then a reference to the new object is put
5006 in the value stack. If 'has_init' is 2, a special parsing is done
5007 to handle string constants. */
5008 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5009 int has_init, int v, int scope)
5011 int size, align, addr, data_offset;
5012 int level;
5013 ParseState saved_parse_state = {0};
5014 TokenString init_str;
5015 Section *sec;
5017 size = type_size(type, &align);
5018 /* If unknown size, we must evaluate it before
5019 evaluating initializers because
5020 initializers can generate global data too
5021 (e.g. string pointers or ISOC99 compound
5022 literals). It also simplifies local
5023 initializers handling */
5024 tok_str_new(&init_str);
5025 if (size < 0) {
5026 if (!has_init)
5027 error("unknown type size");
5028 /* get all init string */
5029 if (has_init == 2) {
5030 /* only get strings */
5031 while (tok == TOK_STR || tok == TOK_LSTR) {
5032 tok_str_add_tok(&init_str);
5033 next();
5035 } else {
5036 level = 0;
5037 while (level > 0 || (tok != ',' && tok != ';')) {
5038 if (tok < 0)
5039 error("unexpected end of file in initializer");
5040 tok_str_add_tok(&init_str);
5041 if (tok == '{')
5042 level++;
5043 else if (tok == '}') {
5044 level--;
5045 if (level <= 0) {
5046 next();
5047 break;
5050 next();
5053 tok_str_add(&init_str, -1);
5054 tok_str_add(&init_str, 0);
5056 /* compute size */
5057 save_parse_state(&saved_parse_state);
5059 macro_ptr = init_str.str;
5060 next();
5061 decl_initializer(type, NULL, 0, 1, 1);
5062 /* prepare second initializer parsing */
5063 macro_ptr = init_str.str;
5064 next();
5066 /* if still unknown size, error */
5067 size = type_size(type, &align);
5068 if (size < 0)
5069 error("unknown type size");
5071 /* take into account specified alignment if bigger */
5072 if (ad->aligned) {
5073 if (ad->aligned > align)
5074 align = ad->aligned;
5075 } else if (ad->packed) {
5076 align = 1;
5078 if ((r & VT_VALMASK) == VT_LOCAL) {
5079 sec = NULL;
5080 #ifdef CONFIG_TCC_BCHECK
5081 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
5082 loc--;
5083 #endif
5084 loc = (loc - size) & -align;
5085 addr = loc;
5086 #ifdef CONFIG_TCC_BCHECK
5087 /* handles bounds */
5088 /* XXX: currently, since we do only one pass, we cannot track
5089 '&' operators, so we add only arrays */
5090 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5091 unsigned long *bounds_ptr;
5092 /* add padding between regions */
5093 loc--;
5094 /* then add local bound info */
5095 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5096 bounds_ptr[0] = addr;
5097 bounds_ptr[1] = size;
5099 #endif
5100 if (v) {
5101 /* local variable */
5102 sym_push(v, type, r, addr);
5103 } else {
5104 /* push local reference */
5105 vset(type, r, addr);
5107 } else {
5108 Sym *sym;
5110 sym = NULL;
5111 if (v && scope == VT_CONST) {
5112 /* see if the symbol was already defined */
5113 sym = sym_find(v);
5114 if (sym) {
5115 if (!is_compatible_types(&sym->type, type))
5116 error("incompatible types for redefinition of '%s'",
5117 get_tok_str(v, NULL));
5118 if (sym->type.t & VT_EXTERN) {
5119 /* if the variable is extern, it was not allocated */
5120 sym->type.t &= ~VT_EXTERN;
5121 /* set array size if it was ommited in extern
5122 declaration */
5123 if ((sym->type.t & VT_ARRAY) &&
5124 sym->type.ref->c < 0 &&
5125 type->ref->c >= 0)
5126 sym->type.ref->c = type->ref->c;
5127 } else {
5128 /* we accept several definitions of the same
5129 global variable. this is tricky, because we
5130 must play with the SHN_COMMON type of the symbol */
5131 /* XXX: should check if the variable was already
5132 initialized. It is incorrect to initialized it
5133 twice */
5134 /* no init data, we won't add more to the symbol */
5135 if (!has_init)
5136 goto no_alloc;
5141 /* allocate symbol in corresponding section */
5142 sec = ad->section;
5143 if (!sec) {
5144 if (has_init)
5145 sec = data_section;
5146 else if (tcc_state->nocommon)
5147 sec = bss_section;
5149 if (sec) {
5150 data_offset = sec->data_offset;
5151 data_offset = (data_offset + align - 1) & -align;
5152 addr = data_offset;
5153 /* very important to increment global pointer at this time
5154 because initializers themselves can create new initializers */
5155 data_offset += size;
5156 #ifdef CONFIG_TCC_BCHECK
5157 /* add padding if bound check */
5158 if (tcc_state->do_bounds_check)
5159 data_offset++;
5160 #endif
5161 sec->data_offset = data_offset;
5162 /* allocate section space to put the data */
5163 if (sec->sh_type != SHT_NOBITS &&
5164 data_offset > sec->data_allocated)
5165 section_realloc(sec, data_offset);
5166 /* align section if needed */
5167 if (align > sec->sh_addralign)
5168 sec->sh_addralign = align;
5169 } else {
5170 addr = 0; /* avoid warning */
5173 if (v) {
5174 if (scope != VT_CONST || !sym) {
5175 sym = sym_push(v, type, r | VT_SYM, 0);
5177 /* update symbol definition */
5178 if (sec) {
5179 put_extern_sym(sym, sec, addr, size);
5180 } else {
5181 ElfW(Sym) *esym;
5182 /* put a common area */
5183 put_extern_sym(sym, NULL, align, size);
5184 /* XXX: find a nicer way */
5185 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5186 esym->st_shndx = SHN_COMMON;
5188 } else {
5189 CValue cval;
5191 /* push global reference */
5192 sym = get_sym_ref(type, sec, addr, size);
5193 cval.ul = 0;
5194 vsetc(type, VT_CONST | VT_SYM, &cval);
5195 vtop->sym = sym;
5197 #ifdef CONFIG_TCC_BCHECK
5198 /* handles bounds now because the symbol must be defined
5199 before for the relocation */
5200 if (tcc_state->do_bounds_check) {
5201 unsigned long *bounds_ptr;
5203 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5204 /* then add global bound info */
5205 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5206 bounds_ptr[0] = 0; /* relocated */
5207 bounds_ptr[1] = size;
5209 #endif
5211 if (has_init) {
5212 decl_initializer(type, sec, addr, 1, 0);
5213 /* restore parse state if needed */
5214 if (init_str.str) {
5215 tok_str_free(init_str.str);
5216 restore_parse_state(&saved_parse_state);
5219 no_alloc: ;
5222 static void put_func_debug(Sym *sym)
5224 char buf[512];
5226 /* stabs info */
5227 /* XXX: we put here a dummy type */
5228 snprintf(buf, sizeof(buf), "%s:%c1",
5229 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5230 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5231 cur_text_section, sym->c);
5232 /* //gr gdb wants a line at the function */
5233 put_stabn(N_SLINE, 0, file->line_num, 0);
5234 last_ind = 0;
5235 last_line_num = 0;
5238 /* parse an old style function declaration list */
5239 /* XXX: check multiple parameter */
5240 static void func_decl_list(Sym *func_sym)
5242 AttributeDef ad;
5243 int v;
5244 Sym *s;
5245 CType btype, type;
5247 /* parse each declaration */
5248 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
5249 if (!parse_btype(&btype, &ad))
5250 expect("declaration list");
5251 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5252 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5253 tok == ';') {
5254 /* we accept no variable after */
5255 } else {
5256 for(;;) {
5257 type = btype;
5258 type_decl(&type, &ad, &v, TYPE_DIRECT);
5259 /* find parameter in function parameter list */
5260 s = func_sym->next;
5261 while (s != NULL) {
5262 if ((s->v & ~SYM_FIELD) == v)
5263 goto found;
5264 s = s->next;
5266 error("declaration for parameter '%s' but no such parameter",
5267 get_tok_str(v, NULL));
5268 found:
5269 /* check that no storage specifier except 'register' was given */
5270 if (type.t & VT_STORAGE)
5271 error("storage class specified for '%s'", get_tok_str(v, NULL));
5272 convert_parameter_type(&type);
5273 /* we can add the type (NOTE: it could be local to the function) */
5274 s->type = type;
5275 /* accept other parameters */
5276 if (tok == ',')
5277 next();
5278 else
5279 break;
5282 skip(';');
5286 /* parse a function defined by symbol 'sym' and generate its code in
5287 'cur_text_section' */
5288 static void gen_function(Sym *sym)
5290 int saved_nocode_wanted = nocode_wanted;
5291 nocode_wanted = 0;
5292 ind = cur_text_section->data_offset;
5293 /* NOTE: we patch the symbol size later */
5294 put_extern_sym(sym, cur_text_section, ind, 0);
5295 if (sym->a)
5296 funcname = get_tok_str(sym->a, NULL);
5297 else
5298 funcname = get_tok_str(sym->v, NULL);
5299 func_ind = ind;
5300 /* put debug symbol */
5301 if (tcc_state->do_debug)
5302 put_func_debug(sym);
5303 /* push a dummy symbol to enable local sym storage */
5304 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5305 gfunc_prolog(&sym->type);
5306 rsym = 0;
5307 block(NULL, NULL, NULL, NULL, 0, 0);
5308 gsym(rsym);
5309 gfunc_epilog();
5310 cur_text_section->data_offset = ind;
5311 label_pop(&global_label_stack, NULL);
5312 sym_pop(&local_stack, NULL); /* reset local stack */
5313 /* end of function */
5314 /* patch symbol size */
5315 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5316 ind - func_ind;
5317 if (tcc_state->do_debug) {
5318 put_stabn(N_FUN, 0, 0, ind - func_ind);
5320 /* It's better to crash than to generate wrong code */
5321 cur_text_section = NULL;
5322 funcname = ""; /* for safety */
5323 func_vt.t = VT_VOID; /* for safety */
5324 ind = 0; /* for safety */
5325 nocode_wanted = saved_nocode_wanted;
5328 ST_FUNC void gen_inline_functions(void)
5330 Sym *sym;
5331 int *str, inline_generated, i;
5332 struct InlineFunc *fn;
5334 /* iterate while inline function are referenced */
5335 for(;;) {
5336 inline_generated = 0;
5337 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5338 fn = tcc_state->inline_fns[i];
5339 sym = fn->sym;
5340 if (sym && sym->c) {
5341 /* the function was used: generate its code and
5342 convert it to a normal function */
5343 str = fn->token_str;
5344 fn->sym = NULL;
5345 if (file)
5346 strcpy(file->filename, fn->filename);
5347 sym->r = VT_SYM | VT_CONST;
5348 sym->type.t &= ~VT_INLINE;
5350 macro_ptr = str;
5351 next();
5352 cur_text_section = text_section;
5353 gen_function(sym);
5354 macro_ptr = NULL; /* fail safe */
5356 inline_generated = 1;
5359 if (!inline_generated)
5360 break;
5362 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5363 fn = tcc_state->inline_fns[i];
5364 str = fn->token_str;
5365 tok_str_free(str);
5367 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5370 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5371 ST_FUNC void decl(int l)
5373 int v, has_init, r;
5374 CType type, btype;
5375 Sym *sym;
5376 AttributeDef ad;
5379 * type.ref must be either a valid reference or NULL for external_sym to
5380 * work. As type = btype is executed before external_sym is call, setting
5381 * btype.ref to 0 is enough.
5383 btype.ref = 0;
5384 while (1) {
5385 if (!parse_btype(&btype, &ad)) {
5386 /* skip redundant ';' */
5387 /* XXX: find more elegant solution */
5388 if (tok == ';') {
5389 next();
5390 continue;
5392 if (l == VT_CONST &&
5393 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5394 /* global asm block */
5395 asm_global_instr();
5396 continue;
5398 /* special test for old K&R protos without explicit int
5399 type. Only accepted when defining global data */
5400 if (l == VT_LOCAL || tok < TOK_DEFINE)
5401 break;
5402 btype.t = VT_INT;
5404 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5405 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5406 tok == ';') {
5407 /* we accept no variable after */
5408 next();
5409 continue;
5411 while (1) { /* iterate thru each declaration */
5412 type = btype;
5413 type_decl(&type, &ad, &v, TYPE_DIRECT);
5414 #if 0
5416 char buf[500];
5417 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5418 printf("type = '%s'\n", buf);
5420 #endif
5421 if ((type.t & VT_BTYPE) == VT_FUNC) {
5422 /* if old style function prototype, we accept a
5423 declaration list */
5424 sym = type.ref;
5425 if (sym->c == FUNC_OLD)
5426 func_decl_list(sym);
5429 #ifdef TCC_TARGET_PE
5430 if (ad.func_import)
5431 type.t |= VT_IMPORT;
5432 if (ad.func_export)
5433 type.t |= VT_EXPORT;
5434 #endif
5435 if (tok == '{') {
5436 if (l == VT_LOCAL)
5437 error("cannot use local functions");
5438 if ((type.t & VT_BTYPE) != VT_FUNC)
5439 expect("function definition");
5441 /* reject abstract declarators in function definition */
5442 sym = type.ref;
5443 while ((sym = sym->next) != NULL)
5444 if (!(sym->v & ~SYM_FIELD))
5445 expect("identifier");
5447 /* XXX: cannot do better now: convert extern line to static inline */
5448 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5449 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5451 sym = sym_find(v);
5452 if (sym) {
5453 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5454 goto func_error1;
5456 r = sym->type.ref->r;
5457 /* use func_call from prototype if not defined */
5458 if (FUNC_CALL(r) != FUNC_CDECL
5459 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5460 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5462 /* use export from prototype */
5463 if (FUNC_EXPORT(r))
5464 FUNC_EXPORT(type.ref->r) = 1;
5466 /* use static from prototype */
5467 if (sym->type.t & VT_STATIC)
5468 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5470 if (!is_compatible_types(&sym->type, &type)) {
5471 func_error1:
5472 error("incompatible types for redefinition of '%s'",
5473 get_tok_str(v, NULL));
5475 /* if symbol is already defined, then put complete type */
5476 sym->type = type;
5477 } else {
5478 /* put function symbol */
5479 sym = global_identifier_push(v, type.t, 0);
5480 sym->type.ref = type.ref;
5483 /* static inline functions are just recorded as a kind
5484 of macro. Their code will be emitted at the end of
5485 the compilation unit only if they are used */
5486 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5487 (VT_INLINE | VT_STATIC)) {
5488 TokenString func_str;
5489 int block_level;
5490 struct InlineFunc *fn;
5491 const char *filename;
5493 tok_str_new(&func_str);
5495 block_level = 0;
5496 for(;;) {
5497 int t;
5498 if (tok == TOK_EOF)
5499 error("unexpected end of file");
5500 tok_str_add_tok(&func_str);
5501 t = tok;
5502 next();
5503 if (t == '{') {
5504 block_level++;
5505 } else if (t == '}') {
5506 block_level--;
5507 if (block_level == 0)
5508 break;
5511 tok_str_add(&func_str, -1);
5512 tok_str_add(&func_str, 0);
5513 filename = file ? file->filename : "";
5514 fn = tcc_malloc(sizeof *fn + strlen(filename));
5515 strcpy(fn->filename, filename);
5516 fn->sym = sym;
5517 fn->token_str = func_str.str;
5518 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5520 } else {
5521 /* compute text section */
5522 cur_text_section = ad.section;
5523 if (!cur_text_section)
5524 cur_text_section = text_section;
5525 sym->r = VT_SYM | VT_CONST;
5526 gen_function(sym);
5528 break;
5529 } else {
5530 if (btype.t & VT_TYPEDEF) {
5531 /* save typedefed type */
5532 /* XXX: test storage specifiers ? */
5533 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5534 sym->type.t |= VT_TYPEDEF;
5535 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
5536 Sym *fn;
5537 /* external function definition */
5538 /* specific case for func_call attribute */
5539 type.ref->r = INT_ATTR(&ad);
5540 fn = external_sym(v, &type, 0);
5542 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5543 char target[256];
5545 *target = 0;
5546 next();
5547 skip('(');
5548 /* Part 1: __USER_LABEL_PREFIX__ (user defined) */
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 /* Part 2: api name */
5556 if (tok == TOK_STR)
5557 pstrcat(target, sizeof(target), tokc.cstr->data);
5558 else
5559 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5561 next();
5562 skip(')');
5563 if (tcc_state->warn_unsupported)
5564 warning("ignoring redirection from %s to %s\n", get_tok_str(v, NULL), target);
5566 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
5567 parse_attribute((AttributeDef *) &fn->type.ref->r);
5569 } else {
5570 /* not lvalue if array */
5571 r = 0;
5572 if (!(type.t & VT_ARRAY))
5573 r |= lvalue_type(type.t);
5574 has_init = (tok == '=');
5575 if ((btype.t & VT_EXTERN) ||
5576 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5577 !has_init && l == VT_CONST && type.ref->c < 0)) {
5578 /* external variable */
5579 /* NOTE: as GCC, uninitialized global static
5580 arrays of null size are considered as
5581 extern */
5582 external_sym(v, &type, r);
5583 } else {
5584 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5585 if (type.t & VT_STATIC)
5586 r |= VT_CONST;
5587 else
5588 r |= l;
5589 if (has_init)
5590 next();
5591 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
5594 if (tok != ',') {
5595 skip(';');
5596 break;
5598 next();