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