Add support for __FreeBSD_kernel__ kernel
[tinycc.git] / tccgen.c
blob656c33424bff44a270e620fc42cc31f44fdbc1cb
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 static void post_type(CType *type, AttributeDef *ad)
2996 int n, l, t1, arg_size, align;
2997 Sym **plast, *s, *first;
2998 AttributeDef ad1;
2999 CType pt;
3001 if (tok == '(') {
3002 TokenSym *ts = NULL;
3004 /* function declaration */
3005 next();
3006 l = 0;
3007 first = NULL;
3008 plast = &first;
3009 arg_size = 0;
3010 if (tok != ')') {
3011 for(;;) {
3012 /* read param name and compute offset */
3013 if (l != FUNC_OLD) {
3014 if (!parse_btype(&pt, &ad1)) {
3015 if (l) {
3016 error("invalid type");
3017 } else {
3018 l = FUNC_OLD;
3019 goto old_proto;
3022 l = FUNC_NEW;
3023 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3024 break;
3025 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3026 if ((pt.t & VT_BTYPE) == VT_VOID)
3027 error("parameter declared as void");
3028 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3029 } else {
3030 old_proto:
3031 n = tok;
3032 if (n < TOK_UIDENT)
3033 expect("identifier");
3034 pt.t = VT_INT;
3035 next();
3037 convert_parameter_type(&pt);
3038 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3039 *plast = s;
3040 plast = &s->next;
3041 if (tok == ')')
3042 break;
3043 skip(',');
3044 if (l == FUNC_NEW && tok == TOK_DOTS) {
3045 l = FUNC_ELLIPSIS;
3046 next();
3047 break;
3051 /* if no parameters, then old type prototype */
3052 if (l == 0)
3053 l = FUNC_OLD;
3054 skip(')');
3055 t1 = type->t & VT_STORAGE;
3056 /* NOTE: const is ignored in returned type as it has a special
3057 meaning in gcc / C++ */
3058 type->t &= ~(VT_STORAGE | VT_CONSTANT);
3059 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
3060 CString astr;
3062 asm_label_instr(&astr);
3063 ts = tok_alloc(astr.data, strlen(astr.data));
3064 cstr_free(&astr);
3066 post_type(type, ad);
3067 /* we push a anonymous symbol which will contain the function prototype */
3068 ad->func_args = arg_size;
3069 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3070 if (ts != NULL)
3071 s->a = ts->tok;
3072 s->next = first;
3073 type->t = t1 | VT_FUNC;
3074 type->ref = s;
3075 } else if (tok == '[') {
3076 /* array definition */
3077 next();
3078 if (tok == TOK_RESTRICT1)
3079 next();
3080 n = -1;
3081 if (tok != ']') {
3082 n = expr_const();
3083 if (n < 0)
3084 error("invalid array size");
3086 skip(']');
3087 /* parse next post type */
3088 t1 = type->t & VT_STORAGE;
3089 type->t &= ~VT_STORAGE;
3090 post_type(type, ad);
3092 /* we push a anonymous symbol which will contain the array
3093 element type */
3094 s = sym_push(SYM_FIELD, type, 0, n);
3095 type->t = t1 | VT_ARRAY | VT_PTR;
3096 type->ref = s;
3100 /* Parse a type declaration (except basic type), and return the type
3101 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3102 expected. 'type' should contain the basic type. 'ad' is the
3103 attribute definition of the basic type. It can be modified by
3104 type_decl().
3106 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3108 Sym *s;
3109 CType type1, *type2;
3110 int qualifiers;
3112 while (tok == '*') {
3113 qualifiers = 0;
3114 redo:
3115 next();
3116 switch(tok) {
3117 case TOK_CONST1:
3118 case TOK_CONST2:
3119 case TOK_CONST3:
3120 qualifiers |= VT_CONSTANT;
3121 goto redo;
3122 case TOK_VOLATILE1:
3123 case TOK_VOLATILE2:
3124 case TOK_VOLATILE3:
3125 qualifiers |= VT_VOLATILE;
3126 goto redo;
3127 case TOK_RESTRICT1:
3128 case TOK_RESTRICT2:
3129 case TOK_RESTRICT3:
3130 goto redo;
3132 mk_pointer(type);
3133 type->t |= qualifiers;
3136 /* XXX: clarify attribute handling */
3137 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3138 parse_attribute(ad);
3140 /* recursive type */
3141 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3142 type1.t = 0; /* XXX: same as int */
3143 if (tok == '(') {
3144 next();
3145 /* XXX: this is not correct to modify 'ad' at this point, but
3146 the syntax is not clear */
3147 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3148 parse_attribute(ad);
3149 type_decl(&type1, ad, v, td);
3150 skip(')');
3151 } else {
3152 /* type identifier */
3153 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3154 *v = tok;
3155 next();
3156 } else {
3157 if (!(td & TYPE_ABSTRACT))
3158 expect("identifier");
3159 *v = 0;
3162 post_type(type, ad);
3163 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3164 parse_attribute(ad);
3165 if (!type1.t)
3166 return;
3167 /* append type at the end of type1 */
3168 type2 = &type1;
3169 for(;;) {
3170 s = type2->ref;
3171 type2 = &s->type;
3172 if (!type2->t) {
3173 *type2 = *type;
3174 break;
3177 *type = type1;
3180 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3181 ST_FUNC int lvalue_type(int t)
3183 int bt, r;
3184 r = VT_LVAL;
3185 bt = t & VT_BTYPE;
3186 if (bt == VT_BYTE || bt == VT_BOOL)
3187 r |= VT_LVAL_BYTE;
3188 else if (bt == VT_SHORT)
3189 r |= VT_LVAL_SHORT;
3190 else
3191 return r;
3192 if (t & VT_UNSIGNED)
3193 r |= VT_LVAL_UNSIGNED;
3194 return r;
3197 /* indirection with full error checking and bound check */
3198 ST_FUNC void indir(void)
3200 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3201 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3202 return;
3203 expect("pointer");
3205 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3206 gv(RC_INT);
3207 vtop->type = *pointed_type(&vtop->type);
3208 /* Arrays and functions are never lvalues */
3209 if (!(vtop->type.t & VT_ARRAY)
3210 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3211 vtop->r |= lvalue_type(vtop->type.t);
3212 /* if bound checking, the referenced pointer must be checked */
3213 #ifdef CONFIG_TCC_BCHECK
3214 if (tcc_state->do_bounds_check)
3215 vtop->r |= VT_MUSTBOUND;
3216 #endif
3220 /* pass a parameter to a function and do type checking and casting */
3221 static void gfunc_param_typed(Sym *func, Sym *arg)
3223 int func_type;
3224 CType type;
3226 func_type = func->c;
3227 if (func_type == FUNC_OLD ||
3228 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3229 /* default casting : only need to convert float to double */
3230 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3231 type.t = VT_DOUBLE;
3232 gen_cast(&type);
3234 } else if (arg == NULL) {
3235 error("too many arguments to function");
3236 } else {
3237 type = arg->type;
3238 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3239 gen_assign_cast(&type);
3243 /* parse an expression of the form '(type)' or '(expr)' and return its
3244 type */
3245 static void parse_expr_type(CType *type)
3247 int n;
3248 AttributeDef ad;
3250 skip('(');
3251 if (parse_btype(type, &ad)) {
3252 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3253 } else {
3254 expr_type(type);
3256 skip(')');
3259 static void parse_type(CType *type)
3261 AttributeDef ad;
3262 int n;
3264 if (!parse_btype(type, &ad)) {
3265 expect("type");
3267 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3270 static void vpush_tokc(int t)
3272 CType type;
3273 type.t = t;
3274 type.ref = 0;
3275 vsetc(&type, VT_CONST, &tokc);
3278 ST_FUNC void unary(void)
3280 int n, t, align, size, r, sizeof_caller;
3281 CType type;
3282 Sym *s;
3283 AttributeDef ad;
3284 static int in_sizeof = 0;
3286 sizeof_caller = in_sizeof;
3287 in_sizeof = 0;
3288 /* XXX: GCC 2.95.3 does not generate a table although it should be
3289 better here */
3290 tok_next:
3291 switch(tok) {
3292 case TOK_EXTENSION:
3293 next();
3294 goto tok_next;
3295 case TOK_CINT:
3296 case TOK_CCHAR:
3297 case TOK_LCHAR:
3298 vpushi(tokc.i);
3299 next();
3300 break;
3301 case TOK_CUINT:
3302 vpush_tokc(VT_INT | VT_UNSIGNED);
3303 next();
3304 break;
3305 case TOK_CLLONG:
3306 vpush_tokc(VT_LLONG);
3307 next();
3308 break;
3309 case TOK_CULLONG:
3310 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3311 next();
3312 break;
3313 case TOK_CFLOAT:
3314 vpush_tokc(VT_FLOAT);
3315 next();
3316 break;
3317 case TOK_CDOUBLE:
3318 vpush_tokc(VT_DOUBLE);
3319 next();
3320 break;
3321 case TOK_CLDOUBLE:
3322 vpush_tokc(VT_LDOUBLE);
3323 next();
3324 break;
3325 case TOK___FUNCTION__:
3326 if (!gnu_ext)
3327 goto tok_identifier;
3328 /* fall thru */
3329 case TOK___FUNC__:
3331 void *ptr;
3332 int len;
3333 /* special function name identifier */
3334 len = strlen(funcname) + 1;
3335 /* generate char[len] type */
3336 type.t = VT_BYTE;
3337 mk_pointer(&type);
3338 type.t |= VT_ARRAY;
3339 type.ref->c = len;
3340 vpush_ref(&type, data_section, data_section->data_offset, len);
3341 ptr = section_ptr_add(data_section, len);
3342 memcpy(ptr, funcname, len);
3343 next();
3345 break;
3346 case TOK_LSTR:
3347 #ifdef TCC_TARGET_PE
3348 t = VT_SHORT | VT_UNSIGNED;
3349 #else
3350 t = VT_INT;
3351 #endif
3352 goto str_init;
3353 case TOK_STR:
3354 /* string parsing */
3355 t = VT_BYTE;
3356 str_init:
3357 if (tcc_state->warn_write_strings)
3358 t |= VT_CONSTANT;
3359 type.t = t;
3360 mk_pointer(&type);
3361 type.t |= VT_ARRAY;
3362 memset(&ad, 0, sizeof(AttributeDef));
3363 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3364 break;
3365 case '(':
3366 next();
3367 /* cast ? */
3368 if (parse_btype(&type, &ad)) {
3369 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3370 skip(')');
3371 /* check ISOC99 compound literal */
3372 if (tok == '{') {
3373 /* data is allocated locally by default */
3374 if (global_expr)
3375 r = VT_CONST;
3376 else
3377 r = VT_LOCAL;
3378 /* all except arrays are lvalues */
3379 if (!(type.t & VT_ARRAY))
3380 r |= lvalue_type(type.t);
3381 memset(&ad, 0, sizeof(AttributeDef));
3382 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3383 } else {
3384 if (sizeof_caller) {
3385 vpush(&type);
3386 return;
3388 unary();
3389 gen_cast(&type);
3391 } else if (tok == '{') {
3392 /* save all registers */
3393 save_regs(0);
3394 /* statement expression : we do not accept break/continue
3395 inside as GCC does */
3396 block(NULL, NULL, NULL, NULL, 0, 1);
3397 skip(')');
3398 } else {
3399 gexpr();
3400 skip(')');
3402 break;
3403 case '*':
3404 next();
3405 unary();
3406 indir();
3407 break;
3408 case '&':
3409 next();
3410 unary();
3411 /* functions names must be treated as function pointers,
3412 except for unary '&' and sizeof. Since we consider that
3413 functions are not lvalues, we only have to handle it
3414 there and in function calls. */
3415 /* arrays can also be used although they are not lvalues */
3416 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3417 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3418 test_lvalue();
3419 mk_pointer(&vtop->type);
3420 gaddrof();
3421 break;
3422 case '!':
3423 next();
3424 unary();
3425 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3426 CType boolean;
3427 boolean.t = VT_BOOL;
3428 gen_cast(&boolean);
3429 vtop->c.i = !vtop->c.i;
3430 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3431 vtop->c.i = vtop->c.i ^ 1;
3432 else {
3433 save_regs(1);
3434 vseti(VT_JMP, gtst(1, 0));
3436 break;
3437 case '~':
3438 next();
3439 unary();
3440 vpushi(-1);
3441 gen_op('^');
3442 break;
3443 case '+':
3444 next();
3445 /* in order to force cast, we add zero */
3446 unary();
3447 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3448 error("pointer not accepted for unary plus");
3449 vpushi(0);
3450 gen_op('+');
3451 break;
3452 case TOK_SIZEOF:
3453 case TOK_ALIGNOF1:
3454 case TOK_ALIGNOF2:
3455 t = tok;
3456 next();
3457 in_sizeof++;
3458 unary_type(&type); // Perform a in_sizeof = 0;
3459 size = type_size(&type, &align);
3460 if (t == TOK_SIZEOF) {
3461 if (size < 0)
3462 error("sizeof applied to an incomplete type");
3463 vpushi(size);
3464 } else {
3465 vpushi(align);
3467 vtop->type.t |= VT_UNSIGNED;
3468 break;
3470 case TOK_builtin_types_compatible_p:
3472 CType type1, type2;
3473 next();
3474 skip('(');
3475 parse_type(&type1);
3476 skip(',');
3477 parse_type(&type2);
3478 skip(')');
3479 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3480 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3481 vpushi(is_compatible_types(&type1, &type2));
3483 break;
3484 case TOK_builtin_constant_p:
3486 int saved_nocode_wanted, res;
3487 next();
3488 skip('(');
3489 saved_nocode_wanted = nocode_wanted;
3490 nocode_wanted = 1;
3491 gexpr();
3492 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3493 vpop();
3494 nocode_wanted = saved_nocode_wanted;
3495 skip(')');
3496 vpushi(res);
3498 break;
3499 case TOK_builtin_frame_address:
3501 CType type;
3502 next();
3503 skip('(');
3504 if (tok != TOK_CINT) {
3505 error("__builtin_frame_address only takes integers");
3507 if (tokc.i != 0) {
3508 error("TCC only supports __builtin_frame_address(0)");
3510 next();
3511 skip(')');
3512 type.t = VT_VOID;
3513 mk_pointer(&type);
3514 vset(&type, VT_LOCAL, 0);
3516 break;
3517 #ifdef TCC_TARGET_X86_64
3518 case TOK_builtin_malloc:
3519 tok = TOK_malloc;
3520 goto tok_identifier;
3521 case TOK_builtin_free:
3522 tok = TOK_free;
3523 goto tok_identifier;
3524 #endif
3525 case TOK_INC:
3526 case TOK_DEC:
3527 t = tok;
3528 next();
3529 unary();
3530 inc(0, t);
3531 break;
3532 case '-':
3533 next();
3534 vpushi(0);
3535 unary();
3536 gen_op('-');
3537 break;
3538 case TOK_LAND:
3539 if (!gnu_ext)
3540 goto tok_identifier;
3541 next();
3542 /* allow to take the address of a label */
3543 if (tok < TOK_UIDENT)
3544 expect("label identifier");
3545 s = label_find(tok);
3546 if (!s) {
3547 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3548 } else {
3549 if (s->r == LABEL_DECLARED)
3550 s->r = LABEL_FORWARD;
3552 if (!s->type.t) {
3553 s->type.t = VT_VOID;
3554 mk_pointer(&s->type);
3555 s->type.t |= VT_STATIC;
3557 vset(&s->type, VT_CONST | VT_SYM, 0);
3558 vtop->sym = s;
3559 next();
3560 break;
3562 // special qnan , snan and infinity values
3563 case TOK___NAN__:
3564 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3565 next();
3566 break;
3567 case TOK___SNAN__:
3568 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3569 next();
3570 break;
3571 case TOK___INF__:
3572 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3573 next();
3574 break;
3576 default:
3577 tok_identifier:
3578 t = tok;
3579 next();
3580 if (t < TOK_UIDENT)
3581 expect("identifier");
3582 s = sym_find(t);
3583 if (!s) {
3584 if (tok != '(')
3585 error("'%s' undeclared", get_tok_str(t, NULL));
3586 /* for simple function calls, we tolerate undeclared
3587 external reference to int() function */
3588 if (tcc_state->warn_implicit_function_declaration)
3589 warning("implicit declaration of function '%s'",
3590 get_tok_str(t, NULL));
3591 s = external_global_sym(t, &func_old_type, 0);
3593 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3594 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3595 /* if referencing an inline function, then we generate a
3596 symbol to it if not already done. It will have the
3597 effect to generate code for it at the end of the
3598 compilation unit. Inline function as always
3599 generated in the text section. */
3600 if (!s->c)
3601 put_extern_sym(s, text_section, 0, 0);
3602 r = VT_SYM | VT_CONST;
3603 } else {
3604 r = s->r;
3606 vset(&s->type, r, s->c);
3607 /* if forward reference, we must point to s */
3608 if (vtop->r & VT_SYM) {
3609 vtop->sym = s;
3610 vtop->c.ul = 0;
3612 break;
3615 /* post operations */
3616 while (1) {
3617 if (tok == TOK_INC || tok == TOK_DEC) {
3618 inc(1, tok);
3619 next();
3620 } else if (tok == '.' || tok == TOK_ARROW) {
3621 int qualifiers;
3622 /* field */
3623 if (tok == TOK_ARROW)
3624 indir();
3625 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3626 test_lvalue();
3627 gaddrof();
3628 next();
3629 /* expect pointer on structure */
3630 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3631 expect("struct or union");
3632 s = vtop->type.ref;
3633 /* find field */
3634 tok |= SYM_FIELD;
3635 while ((s = s->next) != NULL) {
3636 if (s->v == tok)
3637 break;
3639 if (!s)
3640 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3641 /* add field offset to pointer */
3642 vtop->type = char_pointer_type; /* change type to 'char *' */
3643 vpushi(s->c);
3644 gen_op('+');
3645 /* change type to field type, and set to lvalue */
3646 vtop->type = s->type;
3647 vtop->type.t |= qualifiers;
3648 /* an array is never an lvalue */
3649 if (!(vtop->type.t & VT_ARRAY)) {
3650 vtop->r |= lvalue_type(vtop->type.t);
3651 #ifdef CONFIG_TCC_BCHECK
3652 /* if bound checking, the referenced pointer must be checked */
3653 if (tcc_state->do_bounds_check)
3654 vtop->r |= VT_MUSTBOUND;
3655 #endif
3657 next();
3658 } else if (tok == '[') {
3659 next();
3660 gexpr();
3661 gen_op('+');
3662 indir();
3663 skip(']');
3664 } else if (tok == '(') {
3665 SValue ret;
3666 Sym *sa;
3667 int nb_args;
3669 /* function call */
3670 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3671 /* pointer test (no array accepted) */
3672 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3673 vtop->type = *pointed_type(&vtop->type);
3674 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3675 goto error_func;
3676 } else {
3677 error_func:
3678 expect("function pointer");
3680 } else {
3681 vtop->r &= ~VT_LVAL; /* no lvalue */
3683 /* get return type */
3684 s = vtop->type.ref;
3685 next();
3686 sa = s->next; /* first parameter */
3687 nb_args = 0;
3688 ret.r2 = VT_CONST;
3689 /* compute first implicit argument if a structure is returned */
3690 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3691 /* get some space for the returned structure */
3692 size = type_size(&s->type, &align);
3693 loc = (loc - size) & -align;
3694 ret.type = s->type;
3695 ret.r = VT_LOCAL | VT_LVAL;
3696 /* pass it as 'int' to avoid structure arg passing
3697 problems */
3698 vseti(VT_LOCAL, loc);
3699 ret.c = vtop->c;
3700 nb_args++;
3701 } else {
3702 ret.type = s->type;
3703 /* return in register */
3704 if (is_float(ret.type.t)) {
3705 ret.r = reg_fret(ret.type.t);
3706 } else {
3707 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3708 ret.r2 = REG_LRET;
3709 ret.r = REG_IRET;
3711 ret.c.i = 0;
3713 if (tok != ')') {
3714 for(;;) {
3715 expr_eq();
3716 gfunc_param_typed(s, sa);
3717 nb_args++;
3718 if (sa)
3719 sa = sa->next;
3720 if (tok == ')')
3721 break;
3722 skip(',');
3725 if (sa)
3726 error("too few arguments to function");
3727 skip(')');
3728 if (!nocode_wanted) {
3729 gfunc_call(nb_args);
3730 } else {
3731 vtop -= (nb_args + 1);
3733 /* return value */
3734 vsetc(&ret.type, ret.r, &ret.c);
3735 vtop->r2 = ret.r2;
3736 } else {
3737 break;
3742 static void uneq(void)
3744 int t;
3746 unary();
3747 if (tok == '=' ||
3748 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
3749 tok == TOK_A_XOR || tok == TOK_A_OR ||
3750 tok == TOK_A_SHL || tok == TOK_A_SAR) {
3751 test_lvalue();
3752 t = tok;
3753 next();
3754 if (t == '=') {
3755 expr_eq();
3756 } else {
3757 vdup();
3758 expr_eq();
3759 gen_op(t & 0x7f);
3761 vstore();
3765 ST_FUNC void expr_prod(void)
3767 int t;
3769 uneq();
3770 while (tok == '*' || tok == '/' || tok == '%') {
3771 t = tok;
3772 next();
3773 uneq();
3774 gen_op(t);
3778 ST_FUNC void expr_sum(void)
3780 int t;
3782 expr_prod();
3783 while (tok == '+' || tok == '-') {
3784 t = tok;
3785 next();
3786 expr_prod();
3787 gen_op(t);
3791 static void expr_shift(void)
3793 int t;
3795 expr_sum();
3796 while (tok == TOK_SHL || tok == TOK_SAR) {
3797 t = tok;
3798 next();
3799 expr_sum();
3800 gen_op(t);
3804 static void expr_cmp(void)
3806 int t;
3808 expr_shift();
3809 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3810 tok == TOK_ULT || tok == TOK_UGE) {
3811 t = tok;
3812 next();
3813 expr_shift();
3814 gen_op(t);
3818 static void expr_cmpeq(void)
3820 int t;
3822 expr_cmp();
3823 while (tok == TOK_EQ || tok == TOK_NE) {
3824 t = tok;
3825 next();
3826 expr_cmp();
3827 gen_op(t);
3831 static void expr_and(void)
3833 expr_cmpeq();
3834 while (tok == '&') {
3835 next();
3836 expr_cmpeq();
3837 gen_op('&');
3841 static void expr_xor(void)
3843 expr_and();
3844 while (tok == '^') {
3845 next();
3846 expr_and();
3847 gen_op('^');
3851 static void expr_or(void)
3853 expr_xor();
3854 while (tok == '|') {
3855 next();
3856 expr_xor();
3857 gen_op('|');
3861 /* XXX: fix this mess */
3862 static void expr_land_const(void)
3864 expr_or();
3865 while (tok == TOK_LAND) {
3866 next();
3867 expr_or();
3868 gen_op(TOK_LAND);
3872 /* XXX: fix this mess */
3873 static void expr_lor_const(void)
3875 expr_land_const();
3876 while (tok == TOK_LOR) {
3877 next();
3878 expr_land_const();
3879 gen_op(TOK_LOR);
3883 /* only used if non constant */
3884 static void expr_land(void)
3886 int t;
3888 expr_or();
3889 if (tok == TOK_LAND) {
3890 t = 0;
3891 save_regs(1);
3892 for(;;) {
3893 t = gtst(1, t);
3894 if (tok != TOK_LAND) {
3895 vseti(VT_JMPI, t);
3896 break;
3898 next();
3899 expr_or();
3904 static void expr_lor(void)
3906 int t;
3908 expr_land();
3909 if (tok == TOK_LOR) {
3910 t = 0;
3911 save_regs(1);
3912 for(;;) {
3913 t = gtst(0, t);
3914 if (tok != TOK_LOR) {
3915 vseti(VT_JMP, t);
3916 break;
3918 next();
3919 expr_land();
3924 /* XXX: better constant handling */
3925 static void expr_eq(void)
3927 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
3928 SValue sv;
3929 CType type, type1, type2;
3931 if (const_wanted) {
3932 expr_lor_const();
3933 if (tok == '?') {
3934 CType boolean;
3935 int c;
3936 boolean.t = VT_BOOL;
3937 vdup();
3938 gen_cast(&boolean);
3939 c = vtop->c.i;
3940 vpop();
3941 next();
3942 if (tok != ':' || !gnu_ext) {
3943 vpop();
3944 gexpr();
3946 if (!c)
3947 vpop();
3948 skip(':');
3949 expr_eq();
3950 if (c)
3951 vpop();
3953 } else {
3954 expr_lor();
3955 if (tok == '?') {
3956 next();
3957 if (vtop != vstack) {
3958 /* needed to avoid having different registers saved in
3959 each branch */
3960 if (is_float(vtop->type.t)) {
3961 rc = RC_FLOAT;
3962 #ifdef TCC_TARGET_X86_64
3963 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
3964 rc = RC_ST0;
3966 #endif
3968 else
3969 rc = RC_INT;
3970 gv(rc);
3971 save_regs(1);
3973 if (tok == ':' && gnu_ext) {
3974 gv_dup();
3975 tt = gtst(1, 0);
3976 } else {
3977 tt = gtst(1, 0);
3978 gexpr();
3980 type1 = vtop->type;
3981 sv = *vtop; /* save value to handle it later */
3982 vtop--; /* no vpop so that FP stack is not flushed */
3983 skip(':');
3984 u = gjmp(0);
3985 gsym(tt);
3986 expr_eq();
3987 type2 = vtop->type;
3989 t1 = type1.t;
3990 bt1 = t1 & VT_BTYPE;
3991 t2 = type2.t;
3992 bt2 = t2 & VT_BTYPE;
3993 /* cast operands to correct type according to ISOC rules */
3994 if (is_float(bt1) || is_float(bt2)) {
3995 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3996 type.t = VT_LDOUBLE;
3997 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3998 type.t = VT_DOUBLE;
3999 } else {
4000 type.t = VT_FLOAT;
4002 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4003 /* cast to biggest op */
4004 type.t = VT_LLONG;
4005 /* convert to unsigned if it does not fit in a long long */
4006 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4007 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4008 type.t |= VT_UNSIGNED;
4009 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4010 /* XXX: test pointer compatibility */
4011 type = type1;
4012 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4013 /* XXX: test function pointer compatibility */
4014 type = type1;
4015 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4016 /* XXX: test structure compatibility */
4017 type = type1;
4018 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4019 /* NOTE: as an extension, we accept void on only one side */
4020 type.t = VT_VOID;
4021 } else {
4022 /* integer operations */
4023 type.t = VT_INT;
4024 /* convert to unsigned if it does not fit in an integer */
4025 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4026 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4027 type.t |= VT_UNSIGNED;
4030 /* now we convert second operand */
4031 gen_cast(&type);
4032 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4033 gaddrof();
4034 rc = RC_INT;
4035 if (is_float(type.t)) {
4036 rc = RC_FLOAT;
4037 #ifdef TCC_TARGET_X86_64
4038 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4039 rc = RC_ST0;
4041 #endif
4042 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4043 /* for long longs, we use fixed registers to avoid having
4044 to handle a complicated move */
4045 rc = RC_IRET;
4048 r2 = gv(rc);
4049 /* this is horrible, but we must also convert first
4050 operand */
4051 tt = gjmp(0);
4052 gsym(u);
4053 /* put again first value and cast it */
4054 *vtop = sv;
4055 gen_cast(&type);
4056 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4057 gaddrof();
4058 r1 = gv(rc);
4059 move_reg(r2, r1);
4060 vtop->r = r2;
4061 gsym(tt);
4066 ST_FUNC void gexpr(void)
4068 while (1) {
4069 expr_eq();
4070 if (tok != ',')
4071 break;
4072 vpop();
4073 next();
4077 /* parse an expression and return its type without any side effect. */
4078 static void expr_type(CType *type)
4080 int saved_nocode_wanted;
4082 saved_nocode_wanted = nocode_wanted;
4083 nocode_wanted = 1;
4084 gexpr();
4085 *type = vtop->type;
4086 vpop();
4087 nocode_wanted = saved_nocode_wanted;
4090 /* parse a unary expression and return its type without any side
4091 effect. */
4092 static void unary_type(CType *type)
4094 int a;
4096 a = nocode_wanted;
4097 nocode_wanted = 1;
4098 unary();
4099 *type = vtop->type;
4100 vpop();
4101 nocode_wanted = a;
4104 /* parse a constant expression and return value in vtop. */
4105 static void expr_const1(void)
4107 int a;
4108 a = const_wanted;
4109 const_wanted = 1;
4110 expr_eq();
4111 const_wanted = a;
4114 /* parse an integer constant and return its value. */
4115 ST_FUNC int expr_const(void)
4117 int c;
4118 expr_const1();
4119 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4120 expect("constant expression");
4121 c = vtop->c.i;
4122 vpop();
4123 return c;
4126 /* return the label token if current token is a label, otherwise
4127 return zero */
4128 static int is_label(void)
4130 int last_tok;
4132 /* fast test first */
4133 if (tok < TOK_UIDENT)
4134 return 0;
4135 /* no need to save tokc because tok is an identifier */
4136 last_tok = tok;
4137 next();
4138 if (tok == ':') {
4139 next();
4140 return last_tok;
4141 } else {
4142 unget_tok(last_tok);
4143 return 0;
4147 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4148 int case_reg, int is_expr)
4150 int a, b, c, d;
4151 Sym *s;
4153 /* generate line number info */
4154 if (tcc_state->do_debug &&
4155 (last_line_num != file->line_num || last_ind != ind)) {
4156 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4157 last_ind = ind;
4158 last_line_num = file->line_num;
4161 if (is_expr) {
4162 /* default return value is (void) */
4163 vpushi(0);
4164 vtop->type.t = VT_VOID;
4167 if (tok == TOK_IF) {
4168 /* if test */
4169 next();
4170 skip('(');
4171 gexpr();
4172 skip(')');
4173 a = gtst(1, 0);
4174 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4175 c = tok;
4176 if (c == TOK_ELSE) {
4177 next();
4178 d = gjmp(0);
4179 gsym(a);
4180 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4181 gsym(d); /* patch else jmp */
4182 } else
4183 gsym(a);
4184 } else if (tok == TOK_WHILE) {
4185 next();
4186 d = ind;
4187 skip('(');
4188 gexpr();
4189 skip(')');
4190 a = gtst(1, 0);
4191 b = 0;
4192 block(&a, &b, case_sym, def_sym, case_reg, 0);
4193 gjmp_addr(d);
4194 gsym(a);
4195 gsym_addr(b, d);
4196 } else if (tok == '{') {
4197 Sym *llabel;
4199 next();
4200 /* record local declaration stack position */
4201 s = local_stack;
4202 llabel = local_label_stack;
4203 /* handle local labels declarations */
4204 if (tok == TOK_LABEL) {
4205 next();
4206 for(;;) {
4207 if (tok < TOK_UIDENT)
4208 expect("label identifier");
4209 label_push(&local_label_stack, tok, LABEL_DECLARED);
4210 next();
4211 if (tok == ',') {
4212 next();
4213 } else {
4214 skip(';');
4215 break;
4219 while (tok != '}') {
4220 decl(VT_LOCAL);
4221 if (tok != '}') {
4222 if (is_expr)
4223 vpop();
4224 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4227 /* pop locally defined labels */
4228 label_pop(&local_label_stack, llabel);
4229 /* pop locally defined symbols */
4230 if(is_expr) {
4231 /* XXX: this solution makes only valgrind happy...
4232 triggered by gcc.c-torture/execute/20000917-1.c */
4233 Sym *p;
4234 switch(vtop->type.t & VT_BTYPE) {
4235 case VT_PTR:
4236 case VT_STRUCT:
4237 case VT_ENUM:
4238 case VT_FUNC:
4239 for(p=vtop->type.ref;p;p=p->prev)
4240 if(p->prev==s)
4241 error("unsupported expression type");
4244 sym_pop(&local_stack, s);
4245 next();
4246 } else if (tok == TOK_RETURN) {
4247 next();
4248 if (tok != ';') {
4249 gexpr();
4250 gen_assign_cast(&func_vt);
4251 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4252 CType type;
4253 /* if returning structure, must copy it to implicit
4254 first pointer arg location */
4255 #ifdef TCC_ARM_EABI
4256 int align, size;
4257 size = type_size(&func_vt,&align);
4258 if(size <= 4)
4260 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4261 && (align & 3))
4263 int addr;
4264 loc = (loc - size) & -4;
4265 addr = loc;
4266 type = func_vt;
4267 vset(&type, VT_LOCAL | VT_LVAL, addr);
4268 vswap();
4269 vstore();
4270 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4272 vtop->type = int_type;
4273 gv(RC_IRET);
4274 } else {
4275 #endif
4276 type = func_vt;
4277 mk_pointer(&type);
4278 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4279 indir();
4280 vswap();
4281 /* copy structure value to pointer */
4282 vstore();
4283 #ifdef TCC_ARM_EABI
4285 #endif
4286 } else if (is_float(func_vt.t)) {
4287 gv(rc_fret(func_vt.t));
4288 } else {
4289 gv(RC_IRET);
4291 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4293 skip(';');
4294 rsym = gjmp(rsym); /* jmp */
4295 } else if (tok == TOK_BREAK) {
4296 /* compute jump */
4297 if (!bsym)
4298 error("cannot break");
4299 *bsym = gjmp(*bsym);
4300 next();
4301 skip(';');
4302 } else if (tok == TOK_CONTINUE) {
4303 /* compute jump */
4304 if (!csym)
4305 error("cannot continue");
4306 *csym = gjmp(*csym);
4307 next();
4308 skip(';');
4309 } else if (tok == TOK_FOR) {
4310 int e;
4311 next();
4312 skip('(');
4313 if (tok != ';') {
4314 gexpr();
4315 vpop();
4317 skip(';');
4318 d = ind;
4319 c = ind;
4320 a = 0;
4321 b = 0;
4322 if (tok != ';') {
4323 gexpr();
4324 a = gtst(1, 0);
4326 skip(';');
4327 if (tok != ')') {
4328 e = gjmp(0);
4329 c = ind;
4330 gexpr();
4331 vpop();
4332 gjmp_addr(d);
4333 gsym(e);
4335 skip(')');
4336 block(&a, &b, case_sym, def_sym, case_reg, 0);
4337 gjmp_addr(c);
4338 gsym(a);
4339 gsym_addr(b, c);
4340 } else
4341 if (tok == TOK_DO) {
4342 next();
4343 a = 0;
4344 b = 0;
4345 d = ind;
4346 block(&a, &b, case_sym, def_sym, case_reg, 0);
4347 skip(TOK_WHILE);
4348 skip('(');
4349 gsym(b);
4350 gexpr();
4351 c = gtst(0, 0);
4352 gsym_addr(c, d);
4353 skip(')');
4354 gsym(a);
4355 skip(';');
4356 } else
4357 if (tok == TOK_SWITCH) {
4358 next();
4359 skip('(');
4360 gexpr();
4361 /* XXX: other types than integer */
4362 case_reg = gv(RC_INT);
4363 vpop();
4364 skip(')');
4365 a = 0;
4366 b = gjmp(0); /* jump to first case */
4367 c = 0;
4368 block(&a, csym, &b, &c, case_reg, 0);
4369 /* if no default, jmp after switch */
4370 if (c == 0)
4371 c = ind;
4372 /* default label */
4373 gsym_addr(b, c);
4374 /* break label */
4375 gsym(a);
4376 } else
4377 if (tok == TOK_CASE) {
4378 int v1, v2;
4379 if (!case_sym)
4380 expect("switch");
4381 next();
4382 v1 = expr_const();
4383 v2 = v1;
4384 if (gnu_ext && tok == TOK_DOTS) {
4385 next();
4386 v2 = expr_const();
4387 if (v2 < v1)
4388 warning("empty case range");
4390 /* since a case is like a label, we must skip it with a jmp */
4391 b = gjmp(0);
4392 gsym(*case_sym);
4393 vseti(case_reg, 0);
4394 vpushi(v1);
4395 if (v1 == v2) {
4396 gen_op(TOK_EQ);
4397 *case_sym = gtst(1, 0);
4398 } else {
4399 gen_op(TOK_GE);
4400 *case_sym = gtst(1, 0);
4401 vseti(case_reg, 0);
4402 vpushi(v2);
4403 gen_op(TOK_LE);
4404 *case_sym = gtst(1, *case_sym);
4406 gsym(b);
4407 skip(':');
4408 is_expr = 0;
4409 goto block_after_label;
4410 } else
4411 if (tok == TOK_DEFAULT) {
4412 next();
4413 skip(':');
4414 if (!def_sym)
4415 expect("switch");
4416 if (*def_sym)
4417 error("too many 'default'");
4418 *def_sym = ind;
4419 is_expr = 0;
4420 goto block_after_label;
4421 } else
4422 if (tok == TOK_GOTO) {
4423 next();
4424 if (tok == '*' && gnu_ext) {
4425 /* computed goto */
4426 next();
4427 gexpr();
4428 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4429 expect("pointer");
4430 ggoto();
4431 } else if (tok >= TOK_UIDENT) {
4432 s = label_find(tok);
4433 /* put forward definition if needed */
4434 if (!s) {
4435 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4436 } else {
4437 if (s->r == LABEL_DECLARED)
4438 s->r = LABEL_FORWARD;
4440 /* label already defined */
4441 if (s->r & LABEL_FORWARD)
4442 s->jnext = gjmp(s->jnext);
4443 else
4444 gjmp_addr(s->jnext);
4445 next();
4446 } else {
4447 expect("label identifier");
4449 skip(';');
4450 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4451 asm_instr();
4452 } else {
4453 b = is_label();
4454 if (b) {
4455 /* label case */
4456 s = label_find(b);
4457 if (s) {
4458 if (s->r == LABEL_DEFINED)
4459 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4460 gsym(s->jnext);
4461 s->r = LABEL_DEFINED;
4462 } else {
4463 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4465 s->jnext = ind;
4466 /* we accept this, but it is a mistake */
4467 block_after_label:
4468 if (tok == '}') {
4469 warning("deprecated use of label at end of compound statement");
4470 } else {
4471 if (is_expr)
4472 vpop();
4473 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4475 } else {
4476 /* expression case */
4477 if (tok != ';') {
4478 if (is_expr) {
4479 vpop();
4480 gexpr();
4481 } else {
4482 gexpr();
4483 vpop();
4486 skip(';');
4491 /* t is the array or struct type. c is the array or struct
4492 address. cur_index/cur_field is the pointer to the current
4493 value. 'size_only' is true if only size info is needed (only used
4494 in arrays) */
4495 static void decl_designator(CType *type, Section *sec, unsigned long c,
4496 int *cur_index, Sym **cur_field,
4497 int size_only)
4499 Sym *s, *f;
4500 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4501 CType type1;
4503 notfirst = 0;
4504 elem_size = 0;
4505 nb_elems = 1;
4506 if (gnu_ext && (l = is_label()) != 0)
4507 goto struct_field;
4508 while (tok == '[' || tok == '.') {
4509 if (tok == '[') {
4510 if (!(type->t & VT_ARRAY))
4511 expect("array type");
4512 s = type->ref;
4513 next();
4514 index = expr_const();
4515 if (index < 0 || (s->c >= 0 && index >= s->c))
4516 expect("invalid index");
4517 if (tok == TOK_DOTS && gnu_ext) {
4518 next();
4519 index_last = expr_const();
4520 if (index_last < 0 ||
4521 (s->c >= 0 && index_last >= s->c) ||
4522 index_last < index)
4523 expect("invalid index");
4524 } else {
4525 index_last = index;
4527 skip(']');
4528 if (!notfirst)
4529 *cur_index = index_last;
4530 type = pointed_type(type);
4531 elem_size = type_size(type, &align);
4532 c += index * elem_size;
4533 /* NOTE: we only support ranges for last designator */
4534 nb_elems = index_last - index + 1;
4535 if (nb_elems != 1) {
4536 notfirst = 1;
4537 break;
4539 } else {
4540 next();
4541 l = tok;
4542 next();
4543 struct_field:
4544 if ((type->t & VT_BTYPE) != VT_STRUCT)
4545 expect("struct/union type");
4546 s = type->ref;
4547 l |= SYM_FIELD;
4548 f = s->next;
4549 while (f) {
4550 if (f->v == l)
4551 break;
4552 f = f->next;
4554 if (!f)
4555 expect("field");
4556 if (!notfirst)
4557 *cur_field = f;
4558 /* XXX: fix this mess by using explicit storage field */
4559 type1 = f->type;
4560 type1.t |= (type->t & ~VT_TYPE);
4561 type = &type1;
4562 c += f->c;
4564 notfirst = 1;
4566 if (notfirst) {
4567 if (tok == '=') {
4568 next();
4569 } else {
4570 if (!gnu_ext)
4571 expect("=");
4573 } else {
4574 if (type->t & VT_ARRAY) {
4575 index = *cur_index;
4576 type = pointed_type(type);
4577 c += index * type_size(type, &align);
4578 } else {
4579 f = *cur_field;
4580 if (!f)
4581 error("too many field init");
4582 /* XXX: fix this mess by using explicit storage field */
4583 type1 = f->type;
4584 type1.t |= (type->t & ~VT_TYPE);
4585 type = &type1;
4586 c += f->c;
4589 decl_initializer(type, sec, c, 0, size_only);
4591 /* XXX: make it more general */
4592 if (!size_only && nb_elems > 1) {
4593 unsigned long c_end;
4594 uint8_t *src, *dst;
4595 int i;
4597 if (!sec)
4598 error("range init not supported yet for dynamic storage");
4599 c_end = c + nb_elems * elem_size;
4600 if (c_end > sec->data_allocated)
4601 section_realloc(sec, c_end);
4602 src = sec->data + c;
4603 dst = src;
4604 for(i = 1; i < nb_elems; i++) {
4605 dst += elem_size;
4606 memcpy(dst, src, elem_size);
4611 #define EXPR_VAL 0
4612 #define EXPR_CONST 1
4613 #define EXPR_ANY 2
4615 /* store a value or an expression directly in global data or in local array */
4616 static void init_putv(CType *type, Section *sec, unsigned long c,
4617 int v, int expr_type)
4619 int saved_global_expr, bt, bit_pos, bit_size;
4620 void *ptr;
4621 unsigned long long bit_mask;
4622 CType dtype;
4624 switch(expr_type) {
4625 case EXPR_VAL:
4626 vpushi(v);
4627 break;
4628 case EXPR_CONST:
4629 /* compound literals must be allocated globally in this case */
4630 saved_global_expr = global_expr;
4631 global_expr = 1;
4632 expr_const1();
4633 global_expr = saved_global_expr;
4634 /* NOTE: symbols are accepted */
4635 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4636 error("initializer element is not constant");
4637 break;
4638 case EXPR_ANY:
4639 expr_eq();
4640 break;
4643 dtype = *type;
4644 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4646 if (sec) {
4647 /* XXX: not portable */
4648 /* XXX: generate error if incorrect relocation */
4649 gen_assign_cast(&dtype);
4650 bt = type->t & VT_BTYPE;
4651 /* we'll write at most 12 bytes */
4652 if (c + 12 > sec->data_allocated) {
4653 section_realloc(sec, c + 12);
4655 ptr = sec->data + c;
4656 /* XXX: make code faster ? */
4657 if (!(type->t & VT_BITFIELD)) {
4658 bit_pos = 0;
4659 bit_size = 32;
4660 bit_mask = -1LL;
4661 } else {
4662 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4663 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4664 bit_mask = (1LL << bit_size) - 1;
4666 if ((vtop->r & VT_SYM) &&
4667 (bt == VT_BYTE ||
4668 bt == VT_SHORT ||
4669 bt == VT_DOUBLE ||
4670 bt == VT_LDOUBLE ||
4671 bt == VT_LLONG ||
4672 (bt == VT_INT && bit_size != 32)))
4673 error("initializer element is not computable at load time");
4674 switch(bt) {
4675 case VT_BOOL:
4676 vtop->c.i = (vtop->c.i != 0);
4677 case VT_BYTE:
4678 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4679 break;
4680 case VT_SHORT:
4681 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4682 break;
4683 case VT_DOUBLE:
4684 *(double *)ptr = vtop->c.d;
4685 break;
4686 case VT_LDOUBLE:
4687 *(long double *)ptr = vtop->c.ld;
4688 break;
4689 case VT_LLONG:
4690 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4691 break;
4692 default:
4693 if (vtop->r & VT_SYM) {
4694 greloc(sec, vtop->sym, c, R_DATA_PTR);
4696 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4697 break;
4699 vtop--;
4700 } else {
4701 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4702 vswap();
4703 vstore();
4704 vpop();
4708 /* put zeros for variable based init */
4709 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4711 if (sec) {
4712 /* nothing to do because globals are already set to zero */
4713 } else {
4714 vpush_global_sym(&func_old_type, TOK_memset);
4715 vseti(VT_LOCAL, c);
4716 vpushi(0);
4717 vpushi(size);
4718 gfunc_call(3);
4722 /* 't' contains the type and storage info. 'c' is the offset of the
4723 object in section 'sec'. If 'sec' is NULL, it means stack based
4724 allocation. 'first' is true if array '{' must be read (multi
4725 dimension implicit array init handling). 'size_only' is true if
4726 size only evaluation is wanted (only for arrays). */
4727 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4728 int first, int size_only)
4730 int index, array_length, n, no_oblock, nb, parlevel, i;
4731 int size1, align1, expr_type;
4732 Sym *s, *f;
4733 CType *t1;
4735 if (type->t & VT_ARRAY) {
4736 s = type->ref;
4737 n = s->c;
4738 array_length = 0;
4739 t1 = pointed_type(type);
4740 size1 = type_size(t1, &align1);
4742 no_oblock = 1;
4743 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4744 tok == '{') {
4745 if (tok != '{')
4746 error("character array initializer must be a literal,"
4747 " optionally enclosed in braces");
4748 skip('{');
4749 no_oblock = 0;
4752 /* only parse strings here if correct type (otherwise: handle
4753 them as ((w)char *) expressions */
4754 if ((tok == TOK_LSTR &&
4755 #ifdef TCC_TARGET_PE
4756 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4757 #else
4758 (t1->t & VT_BTYPE) == VT_INT
4759 #endif
4760 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4761 while (tok == TOK_STR || tok == TOK_LSTR) {
4762 int cstr_len, ch;
4763 CString *cstr;
4765 cstr = tokc.cstr;
4766 /* compute maximum number of chars wanted */
4767 if (tok == TOK_STR)
4768 cstr_len = cstr->size;
4769 else
4770 cstr_len = cstr->size / sizeof(nwchar_t);
4771 cstr_len--;
4772 nb = cstr_len;
4773 if (n >= 0 && nb > (n - array_length))
4774 nb = n - array_length;
4775 if (!size_only) {
4776 if (cstr_len > nb)
4777 warning("initializer-string for array is too long");
4778 /* in order to go faster for common case (char
4779 string in global variable, we handle it
4780 specifically */
4781 if (sec && tok == TOK_STR && size1 == 1) {
4782 memcpy(sec->data + c + array_length, cstr->data, nb);
4783 } else {
4784 for(i=0;i<nb;i++) {
4785 if (tok == TOK_STR)
4786 ch = ((unsigned char *)cstr->data)[i];
4787 else
4788 ch = ((nwchar_t *)cstr->data)[i];
4789 init_putv(t1, sec, c + (array_length + i) * size1,
4790 ch, EXPR_VAL);
4794 array_length += nb;
4795 next();
4797 /* only add trailing zero if enough storage (no
4798 warning in this case since it is standard) */
4799 if (n < 0 || array_length < n) {
4800 if (!size_only) {
4801 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4803 array_length++;
4805 } else {
4806 index = 0;
4807 while (tok != '}') {
4808 decl_designator(type, sec, c, &index, NULL, size_only);
4809 if (n >= 0 && index >= n)
4810 error("index too large");
4811 /* must put zero in holes (note that doing it that way
4812 ensures that it even works with designators) */
4813 if (!size_only && array_length < index) {
4814 init_putz(t1, sec, c + array_length * size1,
4815 (index - array_length) * size1);
4817 index++;
4818 if (index > array_length)
4819 array_length = index;
4820 /* special test for multi dimensional arrays (may not
4821 be strictly correct if designators are used at the
4822 same time) */
4823 if (index >= n && no_oblock)
4824 break;
4825 if (tok == '}')
4826 break;
4827 skip(',');
4830 if (!no_oblock)
4831 skip('}');
4832 /* put zeros at the end */
4833 if (!size_only && n >= 0 && array_length < n) {
4834 init_putz(t1, sec, c + array_length * size1,
4835 (n - array_length) * size1);
4837 /* patch type size if needed */
4838 if (n < 0)
4839 s->c = array_length;
4840 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4841 (sec || !first || tok == '{')) {
4842 int par_count;
4844 /* NOTE: the previous test is a specific case for automatic
4845 struct/union init */
4846 /* XXX: union needs only one init */
4848 /* XXX: this test is incorrect for local initializers
4849 beginning with ( without {. It would be much more difficult
4850 to do it correctly (ideally, the expression parser should
4851 be used in all cases) */
4852 par_count = 0;
4853 if (tok == '(') {
4854 AttributeDef ad1;
4855 CType type1;
4856 next();
4857 while (tok == '(') {
4858 par_count++;
4859 next();
4861 if (!parse_btype(&type1, &ad1))
4862 expect("cast");
4863 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4864 #if 0
4865 if (!is_assignable_types(type, &type1))
4866 error("invalid type for cast");
4867 #endif
4868 skip(')');
4870 no_oblock = 1;
4871 if (first || tok == '{') {
4872 skip('{');
4873 no_oblock = 0;
4875 s = type->ref;
4876 f = s->next;
4877 array_length = 0;
4878 index = 0;
4879 n = s->c;
4880 while (tok != '}') {
4881 decl_designator(type, sec, c, NULL, &f, size_only);
4882 index = f->c;
4883 if (!size_only && array_length < index) {
4884 init_putz(type, sec, c + array_length,
4885 index - array_length);
4887 index = index + type_size(&f->type, &align1);
4888 if (index > array_length)
4889 array_length = index;
4891 /* gr: skip fields from same union - ugly. */
4892 while (f->next) {
4893 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
4894 /* test for same offset */
4895 if (f->next->c != f->c)
4896 break;
4897 /* if yes, test for bitfield shift */
4898 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
4899 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4900 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4901 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
4902 if (bit_pos_1 != bit_pos_2)
4903 break;
4905 f = f->next;
4908 f = f->next;
4909 if (no_oblock && f == NULL)
4910 break;
4911 if (tok == '}')
4912 break;
4913 skip(',');
4915 /* put zeros at the end */
4916 if (!size_only && array_length < n) {
4917 init_putz(type, sec, c + array_length,
4918 n - array_length);
4920 if (!no_oblock)
4921 skip('}');
4922 while (par_count) {
4923 skip(')');
4924 par_count--;
4926 } else if (tok == '{') {
4927 next();
4928 decl_initializer(type, sec, c, first, size_only);
4929 skip('}');
4930 } else if (size_only) {
4931 /* just skip expression */
4932 parlevel = 0;
4933 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4934 tok != -1) {
4935 if (tok == '(')
4936 parlevel++;
4937 else if (tok == ')')
4938 parlevel--;
4939 next();
4941 } else {
4942 /* currently, we always use constant expression for globals
4943 (may change for scripting case) */
4944 expr_type = EXPR_CONST;
4945 if (!sec)
4946 expr_type = EXPR_ANY;
4947 init_putv(type, sec, c, 0, expr_type);
4951 /* parse an initializer for type 't' if 'has_init' is non zero, and
4952 allocate space in local or global data space ('r' is either
4953 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
4954 variable 'v' of scope 'scope' is declared before initializers are
4955 parsed. If 'v' is zero, then a reference to the new object is put
4956 in the value stack. If 'has_init' is 2, a special parsing is done
4957 to handle string constants. */
4958 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
4959 int has_init, int v, int scope)
4961 int size, align, addr, data_offset;
4962 int level;
4963 ParseState saved_parse_state = {0};
4964 TokenString init_str;
4965 Section *sec;
4967 size = type_size(type, &align);
4968 /* If unknown size, we must evaluate it before
4969 evaluating initializers because
4970 initializers can generate global data too
4971 (e.g. string pointers or ISOC99 compound
4972 literals). It also simplifies local
4973 initializers handling */
4974 tok_str_new(&init_str);
4975 if (size < 0) {
4976 if (!has_init)
4977 error("unknown type size");
4978 /* get all init string */
4979 if (has_init == 2) {
4980 /* only get strings */
4981 while (tok == TOK_STR || tok == TOK_LSTR) {
4982 tok_str_add_tok(&init_str);
4983 next();
4985 } else {
4986 level = 0;
4987 while (level > 0 || (tok != ',' && tok != ';')) {
4988 if (tok < 0)
4989 error("unexpected end of file in initializer");
4990 tok_str_add_tok(&init_str);
4991 if (tok == '{')
4992 level++;
4993 else if (tok == '}') {
4994 level--;
4995 if (level <= 0) {
4996 next();
4997 break;
5000 next();
5003 tok_str_add(&init_str, -1);
5004 tok_str_add(&init_str, 0);
5006 /* compute size */
5007 save_parse_state(&saved_parse_state);
5009 macro_ptr = init_str.str;
5010 next();
5011 decl_initializer(type, NULL, 0, 1, 1);
5012 /* prepare second initializer parsing */
5013 macro_ptr = init_str.str;
5014 next();
5016 /* if still unknown size, error */
5017 size = type_size(type, &align);
5018 if (size < 0)
5019 error("unknown type size");
5021 /* take into account specified alignment if bigger */
5022 if (ad->aligned) {
5023 if (ad->aligned > align)
5024 align = ad->aligned;
5025 } else if (ad->packed) {
5026 align = 1;
5028 if ((r & VT_VALMASK) == VT_LOCAL) {
5029 sec = NULL;
5030 #ifdef CONFIG_TCC_BCHECK
5031 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
5032 loc--;
5033 #endif
5034 loc = (loc - size) & -align;
5035 addr = loc;
5036 #ifdef CONFIG_TCC_BCHECK
5037 /* handles bounds */
5038 /* XXX: currently, since we do only one pass, we cannot track
5039 '&' operators, so we add only arrays */
5040 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5041 unsigned long *bounds_ptr;
5042 /* add padding between regions */
5043 loc--;
5044 /* then add local bound info */
5045 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5046 bounds_ptr[0] = addr;
5047 bounds_ptr[1] = size;
5049 #endif
5050 if (v) {
5051 /* local variable */
5052 sym_push(v, type, r, addr);
5053 } else {
5054 /* push local reference */
5055 vset(type, r, addr);
5057 } else {
5058 Sym *sym;
5060 sym = NULL;
5061 if (v && scope == VT_CONST) {
5062 /* see if the symbol was already defined */
5063 sym = sym_find(v);
5064 if (sym) {
5065 if (!is_compatible_types(&sym->type, type))
5066 error("incompatible types for redefinition of '%s'",
5067 get_tok_str(v, NULL));
5068 if (sym->type.t & VT_EXTERN) {
5069 /* if the variable is extern, it was not allocated */
5070 sym->type.t &= ~VT_EXTERN;
5071 /* set array size if it was ommited in extern
5072 declaration */
5073 if ((sym->type.t & VT_ARRAY) &&
5074 sym->type.ref->c < 0 &&
5075 type->ref->c >= 0)
5076 sym->type.ref->c = type->ref->c;
5077 } else {
5078 /* we accept several definitions of the same
5079 global variable. this is tricky, because we
5080 must play with the SHN_COMMON type of the symbol */
5081 /* XXX: should check if the variable was already
5082 initialized. It is incorrect to initialized it
5083 twice */
5084 /* no init data, we won't add more to the symbol */
5085 if (!has_init)
5086 goto no_alloc;
5091 /* allocate symbol in corresponding section */
5092 sec = ad->section;
5093 if (!sec) {
5094 if (has_init)
5095 sec = data_section;
5096 else if (tcc_state->nocommon)
5097 sec = bss_section;
5099 if (sec) {
5100 data_offset = sec->data_offset;
5101 data_offset = (data_offset + align - 1) & -align;
5102 addr = data_offset;
5103 /* very important to increment global pointer at this time
5104 because initializers themselves can create new initializers */
5105 data_offset += size;
5106 #ifdef CONFIG_TCC_BCHECK
5107 /* add padding if bound check */
5108 if (tcc_state->do_bounds_check)
5109 data_offset++;
5110 #endif
5111 sec->data_offset = data_offset;
5112 /* allocate section space to put the data */
5113 if (sec->sh_type != SHT_NOBITS &&
5114 data_offset > sec->data_allocated)
5115 section_realloc(sec, data_offset);
5116 /* align section if needed */
5117 if (align > sec->sh_addralign)
5118 sec->sh_addralign = align;
5119 } else {
5120 addr = 0; /* avoid warning */
5123 if (v) {
5124 if (scope != VT_CONST || !sym) {
5125 sym = sym_push(v, type, r | VT_SYM, 0);
5127 /* update symbol definition */
5128 if (sec) {
5129 put_extern_sym(sym, sec, addr, size);
5130 } else {
5131 ElfW(Sym) *esym;
5132 /* put a common area */
5133 put_extern_sym(sym, NULL, align, size);
5134 /* XXX: find a nicer way */
5135 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5136 esym->st_shndx = SHN_COMMON;
5138 } else {
5139 CValue cval;
5141 /* push global reference */
5142 sym = get_sym_ref(type, sec, addr, size);
5143 cval.ul = 0;
5144 vsetc(type, VT_CONST | VT_SYM, &cval);
5145 vtop->sym = sym;
5147 #ifdef CONFIG_TCC_BCHECK
5148 /* handles bounds now because the symbol must be defined
5149 before for the relocation */
5150 if (tcc_state->do_bounds_check) {
5151 unsigned long *bounds_ptr;
5153 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5154 /* then add global bound info */
5155 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5156 bounds_ptr[0] = 0; /* relocated */
5157 bounds_ptr[1] = size;
5159 #endif
5161 if (has_init) {
5162 decl_initializer(type, sec, addr, 1, 0);
5163 /* restore parse state if needed */
5164 if (init_str.str) {
5165 tok_str_free(init_str.str);
5166 restore_parse_state(&saved_parse_state);
5169 no_alloc: ;
5172 static void put_func_debug(Sym *sym)
5174 char buf[512];
5176 /* stabs info */
5177 /* XXX: we put here a dummy type */
5178 snprintf(buf, sizeof(buf), "%s:%c1",
5179 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5180 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5181 cur_text_section, sym->c);
5182 /* //gr gdb wants a line at the function */
5183 put_stabn(N_SLINE, 0, file->line_num, 0);
5184 last_ind = 0;
5185 last_line_num = 0;
5188 /* parse an old style function declaration list */
5189 /* XXX: check multiple parameter */
5190 static void func_decl_list(Sym *func_sym)
5192 AttributeDef ad;
5193 int v;
5194 Sym *s;
5195 CType btype, type;
5197 /* parse each declaration */
5198 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
5199 if (!parse_btype(&btype, &ad))
5200 expect("declaration list");
5201 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5202 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5203 tok == ';') {
5204 /* we accept no variable after */
5205 } else {
5206 for(;;) {
5207 type = btype;
5208 type_decl(&type, &ad, &v, TYPE_DIRECT);
5209 /* find parameter in function parameter list */
5210 s = func_sym->next;
5211 while (s != NULL) {
5212 if ((s->v & ~SYM_FIELD) == v)
5213 goto found;
5214 s = s->next;
5216 error("declaration for parameter '%s' but no such parameter",
5217 get_tok_str(v, NULL));
5218 found:
5219 /* check that no storage specifier except 'register' was given */
5220 if (type.t & VT_STORAGE)
5221 error("storage class specified for '%s'", get_tok_str(v, NULL));
5222 convert_parameter_type(&type);
5223 /* we can add the type (NOTE: it could be local to the function) */
5224 s->type = type;
5225 /* accept other parameters */
5226 if (tok == ',')
5227 next();
5228 else
5229 break;
5232 skip(';');
5236 /* parse a function defined by symbol 'sym' and generate its code in
5237 'cur_text_section' */
5238 static void gen_function(Sym *sym)
5240 int saved_nocode_wanted = nocode_wanted;
5241 nocode_wanted = 0;
5242 ind = cur_text_section->data_offset;
5243 /* NOTE: we patch the symbol size later */
5244 put_extern_sym(sym, cur_text_section, ind, 0);
5245 if (sym->a)
5246 funcname = get_tok_str(sym->a, NULL);
5247 else
5248 funcname = get_tok_str(sym->v, NULL);
5249 func_ind = ind;
5250 /* put debug symbol */
5251 if (tcc_state->do_debug)
5252 put_func_debug(sym);
5253 /* push a dummy symbol to enable local sym storage */
5254 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5255 gfunc_prolog(&sym->type);
5256 rsym = 0;
5257 block(NULL, NULL, NULL, NULL, 0, 0);
5258 gsym(rsym);
5259 gfunc_epilog();
5260 cur_text_section->data_offset = ind;
5261 label_pop(&global_label_stack, NULL);
5262 sym_pop(&local_stack, NULL); /* reset local stack */
5263 /* end of function */
5264 /* patch symbol size */
5265 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5266 ind - func_ind;
5267 if (tcc_state->do_debug) {
5268 put_stabn(N_FUN, 0, 0, ind - func_ind);
5270 /* It's better to crash than to generate wrong code */
5271 cur_text_section = NULL;
5272 funcname = ""; /* for safety */
5273 func_vt.t = VT_VOID; /* for safety */
5274 ind = 0; /* for safety */
5275 nocode_wanted = saved_nocode_wanted;
5278 ST_FUNC void gen_inline_functions(void)
5280 Sym *sym;
5281 int *str, inline_generated, i;
5282 struct InlineFunc *fn;
5284 /* iterate while inline function are referenced */
5285 for(;;) {
5286 inline_generated = 0;
5287 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5288 fn = tcc_state->inline_fns[i];
5289 sym = fn->sym;
5290 if (sym && sym->c) {
5291 /* the function was used: generate its code and
5292 convert it to a normal function */
5293 str = fn->token_str;
5294 fn->sym = NULL;
5295 if (file)
5296 strcpy(file->filename, fn->filename);
5297 sym->r = VT_SYM | VT_CONST;
5298 sym->type.t &= ~VT_INLINE;
5300 macro_ptr = str;
5301 next();
5302 cur_text_section = text_section;
5303 gen_function(sym);
5304 macro_ptr = NULL; /* fail safe */
5306 inline_generated = 1;
5309 if (!inline_generated)
5310 break;
5312 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5313 fn = tcc_state->inline_fns[i];
5314 str = fn->token_str;
5315 tok_str_free(str);
5317 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5320 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5321 ST_FUNC void decl(int l)
5323 int v, has_init, r;
5324 CType type, btype;
5325 Sym *sym;
5326 AttributeDef ad;
5329 * type.ref must be either a valid reference or NULL for external_sym to
5330 * work. As type = btype is executed before external_sym is call, setting
5331 * btype.ref to 0 is enough.
5333 btype.ref = 0;
5334 while (1) {
5335 if (!parse_btype(&btype, &ad)) {
5336 /* skip redundant ';' */
5337 /* XXX: find more elegant solution */
5338 if (tok == ';') {
5339 next();
5340 continue;
5342 if (l == VT_CONST &&
5343 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5344 /* global asm block */
5345 asm_global_instr();
5346 continue;
5348 /* special test for old K&R protos without explicit int
5349 type. Only accepted when defining global data */
5350 if (l == VT_LOCAL || tok < TOK_DEFINE)
5351 break;
5352 btype.t = VT_INT;
5354 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5355 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5356 tok == ';') {
5357 /* we accept no variable after */
5358 next();
5359 continue;
5361 while (1) { /* iterate thru each declaration */
5362 type = btype;
5363 type_decl(&type, &ad, &v, TYPE_DIRECT);
5364 #if 0
5366 char buf[500];
5367 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5368 printf("type = '%s'\n", buf);
5370 #endif
5371 if ((type.t & VT_BTYPE) == VT_FUNC) {
5372 /* if old style function prototype, we accept a
5373 declaration list */
5374 sym = type.ref;
5375 if (sym->c == FUNC_OLD)
5376 func_decl_list(sym);
5379 #ifdef TCC_TARGET_PE
5380 if (ad.func_import)
5381 type.t |= VT_IMPORT;
5382 if (ad.func_export)
5383 type.t |= VT_EXPORT;
5384 #endif
5385 if (tok == '{') {
5386 if (l == VT_LOCAL)
5387 error("cannot use local functions");
5388 if ((type.t & VT_BTYPE) != VT_FUNC)
5389 expect("function definition");
5391 /* reject abstract declarators in function definition */
5392 sym = type.ref;
5393 while ((sym = sym->next) != NULL)
5394 if (!(sym->v & ~SYM_FIELD))
5395 expect("identifier");
5397 /* XXX: cannot do better now: convert extern line to static inline */
5398 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5399 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5401 sym = sym_find(v);
5402 if (sym) {
5403 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5404 goto func_error1;
5406 r = sym->type.ref->r;
5407 /* use func_call from prototype if not defined */
5408 if (FUNC_CALL(r) != FUNC_CDECL
5409 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5410 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5412 /* use export from prototype */
5413 if (FUNC_EXPORT(r))
5414 FUNC_EXPORT(type.ref->r) = 1;
5416 /* use static from prototype */
5417 if (sym->type.t & VT_STATIC)
5418 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5420 if (!is_compatible_types(&sym->type, &type)) {
5421 func_error1:
5422 error("incompatible types for redefinition of '%s'",
5423 get_tok_str(v, NULL));
5425 /* if symbol is already defined, then put complete type */
5426 sym->type = type;
5427 } else {
5428 /* put function symbol */
5429 sym = global_identifier_push(v, type.t, 0);
5430 sym->type.ref = type.ref;
5433 /* static inline functions are just recorded as a kind
5434 of macro. Their code will be emitted at the end of
5435 the compilation unit only if they are used */
5436 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5437 (VT_INLINE | VT_STATIC)) {
5438 TokenString func_str;
5439 int block_level;
5440 struct InlineFunc *fn;
5441 const char *filename;
5443 tok_str_new(&func_str);
5445 block_level = 0;
5446 for(;;) {
5447 int t;
5448 if (tok == TOK_EOF)
5449 error("unexpected end of file");
5450 tok_str_add_tok(&func_str);
5451 t = tok;
5452 next();
5453 if (t == '{') {
5454 block_level++;
5455 } else if (t == '}') {
5456 block_level--;
5457 if (block_level == 0)
5458 break;
5461 tok_str_add(&func_str, -1);
5462 tok_str_add(&func_str, 0);
5463 filename = file ? file->filename : "";
5464 fn = tcc_malloc(sizeof *fn + strlen(filename));
5465 strcpy(fn->filename, filename);
5466 fn->sym = sym;
5467 fn->token_str = func_str.str;
5468 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5470 } else {
5471 /* compute text section */
5472 cur_text_section = ad.section;
5473 if (!cur_text_section)
5474 cur_text_section = text_section;
5475 sym->r = VT_SYM | VT_CONST;
5476 gen_function(sym);
5478 break;
5479 } else {
5480 if (btype.t & VT_TYPEDEF) {
5481 /* save typedefed type */
5482 /* XXX: test storage specifiers ? */
5483 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5484 sym->type.t |= VT_TYPEDEF;
5485 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
5486 Sym *fn;
5487 /* external function definition */
5488 /* specific case for func_call attribute */
5489 type.ref->r = INT_ATTR(&ad);
5490 fn = external_sym(v, &type, 0);
5492 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5493 char target[256];
5495 *target = 0;
5496 next();
5497 skip('(');
5498 /* Part 1: __USER_LABEL_PREFIX__ (user defined) */
5499 if (tok == TOK_STR)
5500 pstrcat(target, sizeof(target), tokc.cstr->data);
5501 else
5502 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5504 next();
5505 /* Part 2: api name */
5506 if (tok == TOK_STR)
5507 pstrcat(target, sizeof(target), tokc.cstr->data);
5508 else
5509 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5511 next();
5512 skip(')');
5513 if (tcc_state->warn_unsupported)
5514 warning("ignoring redirection from %s to %s\n", get_tok_str(v, NULL), target);
5516 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
5517 parse_attribute((AttributeDef *) &fn->type.ref->r);
5519 } else {
5520 /* not lvalue if array */
5521 r = 0;
5522 if (!(type.t & VT_ARRAY))
5523 r |= lvalue_type(type.t);
5524 has_init = (tok == '=');
5525 if ((btype.t & VT_EXTERN) ||
5526 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5527 !has_init && l == VT_CONST && type.ref->c < 0)) {
5528 /* external variable */
5529 /* NOTE: as GCC, uninitialized global static
5530 arrays of null size are considered as
5531 extern */
5532 external_sym(v, &type, r);
5533 } else {
5534 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5535 if (type.t & VT_STATIC)
5536 r |= VT_CONST;
5537 else
5538 r |= l;
5539 if (has_init)
5540 next();
5541 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
5544 if (tok != ',') {
5545 skip(';');
5546 break;
5548 next();