Make TOK_alloca available for x86-64
[tinycc.git] / tccgen.c
blob7fb7cfe5611525d23bc47bc2c5997f548fdceefd
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 void vla_runtime_type_size(CType *type, int *a);
82 static int is_compatible_parameter_types(CType *type1, CType *type2);
83 static void expr_type(CType *type);
85 ST_INLN int is_float(int t)
87 int bt;
88 bt = t & VT_BTYPE;
89 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
92 ST_FUNC void test_lvalue(void)
94 if (!(vtop->r & VT_LVAL))
95 expect("lvalue");
98 /* ------------------------------------------------------------------------- */
99 /* symbol allocator */
100 static Sym *__sym_malloc(void)
102 Sym *sym_pool, *sym, *last_sym;
103 int i;
105 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
106 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
108 last_sym = sym_free_first;
109 sym = sym_pool;
110 for(i = 0; i < SYM_POOL_NB; i++) {
111 sym->next = last_sym;
112 last_sym = sym;
113 sym++;
115 sym_free_first = last_sym;
116 return last_sym;
119 static inline Sym *sym_malloc(void)
121 Sym *sym;
122 sym = sym_free_first;
123 if (!sym)
124 sym = __sym_malloc();
125 sym_free_first = sym->next;
126 return sym;
129 ST_INLN void sym_free(Sym *sym)
131 sym->next = sym_free_first;
132 sym_free_first = sym;
135 /* push, without hashing */
136 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
138 Sym *s;
139 s = sym_malloc();
140 s->a = 0;
141 s->v = v;
142 s->type.t = t;
143 s->type.ref = NULL;
144 #ifdef _WIN64
145 s->d = NULL;
146 #endif
147 s->c = c;
148 s->next = NULL;
149 /* add in stack */
150 s->prev = *ps;
151 *ps = s;
152 return s;
155 /* find a symbol and return its associated structure. 's' is the top
156 of the symbol stack */
157 ST_FUNC Sym *sym_find2(Sym *s, int v)
159 while (s) {
160 if (s->v == v)
161 return s;
162 s = s->prev;
164 return NULL;
167 /* structure lookup */
168 ST_INLN Sym *struct_find(int v)
170 v -= TOK_IDENT;
171 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
172 return NULL;
173 return table_ident[v]->sym_struct;
176 /* find an identifier */
177 ST_INLN Sym *sym_find(int v)
179 v -= TOK_IDENT;
180 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
181 return NULL;
182 return table_ident[v]->sym_identifier;
185 /* push a given symbol on the symbol stack */
186 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
188 Sym *s, **ps;
189 TokenSym *ts;
191 if (local_stack)
192 ps = &local_stack;
193 else
194 ps = &global_stack;
195 s = sym_push2(ps, v, type->t, c);
196 s->type.ref = type->ref;
197 s->r = r;
198 /* don't record fields or anonymous symbols */
199 /* XXX: simplify */
200 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
201 /* record symbol in token array */
202 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
203 if (v & SYM_STRUCT)
204 ps = &ts->sym_struct;
205 else
206 ps = &ts->sym_identifier;
207 s->prev_tok = *ps;
208 *ps = s;
210 return s;
213 /* push a global identifier */
214 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
216 Sym *s, **ps;
217 s = sym_push2(&global_stack, v, t, c);
218 /* don't record anonymous symbol */
219 if (v < SYM_FIRST_ANOM) {
220 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
221 /* modify the top most local identifier, so that
222 sym_identifier will point to 's' when popped */
223 while (*ps != NULL)
224 ps = &(*ps)->prev_tok;
225 s->prev_tok = NULL;
226 *ps = s;
228 return s;
231 /* pop symbols until top reaches 'b' */
232 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
234 Sym *s, *ss, **ps;
235 TokenSym *ts;
236 int v;
238 s = *ptop;
239 while(s != b) {
240 ss = s->prev;
241 v = s->v;
242 /* remove symbol in token array */
243 /* XXX: simplify */
244 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
245 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
246 if (v & SYM_STRUCT)
247 ps = &ts->sym_struct;
248 else
249 ps = &ts->sym_identifier;
250 *ps = s->prev_tok;
252 sym_free(s);
253 s = ss;
255 *ptop = b;
258 /* ------------------------------------------------------------------------- */
260 ST_FUNC void swap(int *p, int *q)
262 int t;
263 t = *p;
264 *p = *q;
265 *q = t;
268 static void vsetc(CType *type, int r, CValue *vc)
270 int v;
272 if (vtop >= vstack + (VSTACK_SIZE - 1))
273 error("memory full");
274 /* cannot let cpu flags if other instruction are generated. Also
275 avoid leaving VT_JMP anywhere except on the top of the stack
276 because it would complicate the code generator. */
277 if (vtop >= vstack) {
278 v = vtop->r & VT_VALMASK;
279 if (v == VT_CMP || (v & ~1) == VT_JMP)
280 gv(RC_INT);
282 vtop++;
283 vtop->type = *type;
284 vtop->r = r;
285 vtop->r2 = VT_CONST;
286 vtop->c = *vc;
289 /* push constant of type "type" with useless value */
290 void vpush(CType *type)
292 CValue cval;
293 vsetc(type, VT_CONST, &cval);
296 /* push integer constant */
297 ST_FUNC void vpushi(int v)
299 CValue cval;
300 cval.i = v;
301 vsetc(&int_type, VT_CONST, &cval);
304 /* push long long constant */
305 static void vpushll(long long v)
307 CValue cval;
308 CType ctype;
309 ctype.t = VT_LLONG;
310 ctype.ref = 0;
311 cval.ull = v;
312 vsetc(&ctype, VT_CONST, &cval);
315 /* push arbitrary 64bit constant */
316 void vpush64(int ty, unsigned long long v)
318 CValue cval;
319 CType ctype;
320 ctype.t = ty;
321 cval.ull = v;
322 vsetc(&ctype, VT_CONST, &cval);
325 /* Return a static symbol pointing to a section */
326 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
328 int v;
329 Sym *sym;
331 v = anon_sym++;
332 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
333 sym->type.ref = type->ref;
334 sym->r = VT_CONST | VT_SYM;
335 put_extern_sym(sym, sec, offset, size);
336 return sym;
339 /* push a reference to a section offset by adding a dummy symbol */
340 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
342 CValue cval;
344 cval.ul = 0;
345 vsetc(type, VT_CONST | VT_SYM, &cval);
346 vtop->sym = get_sym_ref(type, sec, offset, size);
349 /* define a new external reference to a symbol 'v' of type 'u' */
350 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
352 Sym *s;
354 s = sym_find(v);
355 if (!s) {
356 /* push forward reference */
357 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
358 s->type.ref = type->ref;
359 s->r = r | VT_CONST | VT_SYM;
361 return s;
364 /* define a new external reference to a symbol 'v' of type 'u' */
365 static Sym *external_sym(int v, CType *type, int r)
367 Sym *s;
369 s = sym_find(v);
370 if (!s) {
371 /* push forward reference */
372 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
373 if (type && type->ref && type->ref->a)
374 s->a = type->ref->a;
375 s->type.t |= VT_EXTERN;
376 } else if (s->type.ref == func_old_type.ref) {
377 s->type.ref = type->ref;
378 s->r = r | VT_CONST | VT_SYM;
379 s->type.t |= VT_EXTERN;
380 } else if (!is_compatible_types(&s->type, type)) {
381 error("incompatible types for redefinition of '%s'",
382 get_tok_str(v, NULL));
384 return s;
387 /* push a reference to global symbol v */
388 ST_FUNC void vpush_global_sym(CType *type, int v)
390 Sym *sym;
391 CValue cval;
393 sym = external_global_sym(v, type, 0);
394 cval.ul = 0;
395 vsetc(type, VT_CONST | VT_SYM, &cval);
396 vtop->sym = sym;
399 ST_FUNC void vset(CType *type, int r, int v)
401 CValue cval;
403 cval.i = v;
404 vsetc(type, r, &cval);
407 static void vseti(int r, int v)
409 CType type;
410 type.t = VT_INT;
411 type.ref = 0;
412 vset(&type, r, v);
415 ST_FUNC void vswap(void)
417 SValue tmp;
419 tmp = vtop[0];
420 vtop[0] = vtop[-1];
421 vtop[-1] = tmp;
424 ST_FUNC void vpushv(SValue *v)
426 if (vtop >= vstack + (VSTACK_SIZE - 1))
427 error("memory full");
428 vtop++;
429 *vtop = *v;
432 static void vdup(void)
434 vpushv(vtop);
437 /* save r to the memory stack, and mark it as being free */
438 ST_FUNC void save_reg(int r)
440 int l, saved, size, align;
441 SValue *p, sv;
442 CType *type;
444 /* modify all stack values */
445 saved = 0;
446 l = 0;
447 for(p=vstack;p<=vtop;p++) {
448 if ((p->r & VT_VALMASK) == r ||
449 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
450 /* must save value on stack if not already done */
451 if (!saved) {
452 /* NOTE: must reload 'r' because r might be equal to r2 */
453 r = p->r & VT_VALMASK;
454 /* store register in the stack */
455 type = &p->type;
456 if ((p->r & VT_LVAL) ||
457 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
458 #ifdef TCC_TARGET_X86_64
459 type = &char_pointer_type;
460 #else
461 type = &int_type;
462 #endif
463 size = type_size(type, &align);
464 loc = (loc - size) & -align;
465 sv.type.t = type->t;
466 sv.r = VT_LOCAL | VT_LVAL;
467 sv.c.ul = loc;
468 store(r, &sv);
469 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
470 /* x86 specific: need to pop fp register ST0 if saved */
471 if (r == TREG_ST0) {
472 o(0xd8dd); /* fstp %st(0) */
474 #endif
475 #ifndef TCC_TARGET_X86_64
476 /* special long long case */
477 if ((type->t & VT_BTYPE) == VT_LLONG) {
478 sv.c.ul += 4;
479 store(p->r2, &sv);
481 #endif
482 l = loc;
483 saved = 1;
485 /* mark that stack entry as being saved on the stack */
486 if (p->r & VT_LVAL) {
487 /* also clear the bounded flag because the
488 relocation address of the function was stored in
489 p->c.ul */
490 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
491 } else {
492 p->r = lvalue_type(p->type.t) | VT_LOCAL;
494 p->r2 = VT_CONST;
495 p->c.ul = l;
500 #ifdef TCC_TARGET_ARM
501 /* find a register of class 'rc2' with at most one reference on stack.
502 * If none, call get_reg(rc) */
503 ST_FUNC int get_reg_ex(int rc, int rc2)
505 int r;
506 SValue *p;
508 for(r=0;r<NB_REGS;r++) {
509 if (reg_classes[r] & rc2) {
510 int n;
511 n=0;
512 for(p = vstack; p <= vtop; p++) {
513 if ((p->r & VT_VALMASK) == r ||
514 (p->r2 & VT_VALMASK) == r)
515 n++;
517 if (n <= 1)
518 return r;
521 return get_reg(rc);
523 #endif
525 /* find a free register of class 'rc'. If none, save one register */
526 ST_FUNC int get_reg(int rc)
528 int r;
529 SValue *p;
531 /* find a free register */
532 for(r=0;r<NB_REGS;r++) {
533 if (reg_classes[r] & rc) {
534 for(p=vstack;p<=vtop;p++) {
535 if ((p->r & VT_VALMASK) == r ||
536 (p->r2 & VT_VALMASK) == r)
537 goto notfound;
539 return r;
541 notfound: ;
544 /* no register left : free the first one on the stack (VERY
545 IMPORTANT to start from the bottom to ensure that we don't
546 spill registers used in gen_opi()) */
547 for(p=vstack;p<=vtop;p++) {
548 r = p->r & VT_VALMASK;
549 if (r < VT_CONST && (reg_classes[r] & rc))
550 goto save_found;
551 /* also look at second register (if long long) */
552 r = p->r2 & VT_VALMASK;
553 if (r < VT_CONST && (reg_classes[r] & rc)) {
554 save_found:
555 save_reg(r);
556 return r;
559 /* Should never comes here */
560 return -1;
563 /* save registers up to (vtop - n) stack entry */
564 ST_FUNC void save_regs(int n)
566 int r;
567 SValue *p, *p1;
568 p1 = vtop - n;
569 for(p = vstack;p <= p1; p++) {
570 r = p->r & VT_VALMASK;
571 if (r < VT_CONST) {
572 save_reg(r);
577 /* move register 's' to 'r', and flush previous value of r to memory
578 if needed */
579 static void move_reg(int r, int s)
581 SValue sv;
583 if (r != s) {
584 save_reg(r);
585 sv.type.t = VT_INT;
586 sv.r = s;
587 sv.c.ul = 0;
588 load(r, &sv);
592 /* get address of vtop (vtop MUST BE an lvalue) */
593 static void gaddrof(void)
595 vtop->r &= ~VT_LVAL;
596 /* tricky: if saved lvalue, then we can go back to lvalue */
597 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
598 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
601 #ifdef CONFIG_TCC_BCHECK
602 /* generate lvalue bound code */
603 static void gbound(void)
605 int lval_type;
606 CType type1;
608 vtop->r &= ~VT_MUSTBOUND;
609 /* if lvalue, then use checking code before dereferencing */
610 if (vtop->r & VT_LVAL) {
611 /* if not VT_BOUNDED value, then make one */
612 if (!(vtop->r & VT_BOUNDED)) {
613 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
614 /* must save type because we must set it to int to get pointer */
615 type1 = vtop->type;
616 vtop->type.t = VT_INT;
617 gaddrof();
618 vpushi(0);
619 gen_bounded_ptr_add();
620 vtop->r |= lval_type;
621 vtop->type = type1;
623 /* then check for dereferencing */
624 gen_bounded_ptr_deref();
627 #endif
629 /* store vtop a register belonging to class 'rc'. lvalues are
630 converted to values. Cannot be used if cannot be converted to
631 register value (such as structures). */
632 ST_FUNC int gv(int rc)
634 int r, rc2, bit_pos, bit_size, size, align, i;
636 /* NOTE: get_reg can modify vstack[] */
637 if (vtop->type.t & VT_BITFIELD) {
638 CType type;
639 int bits = 32;
640 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
641 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
642 /* remove bit field info to avoid loops */
643 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
644 /* cast to int to propagate signedness in following ops */
645 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
646 type.t = VT_LLONG;
647 bits = 64;
648 } else
649 type.t = VT_INT;
650 if((vtop->type.t & VT_UNSIGNED) ||
651 (vtop->type.t & VT_BTYPE) == VT_BOOL)
652 type.t |= VT_UNSIGNED;
653 gen_cast(&type);
654 /* generate shifts */
655 vpushi(bits - (bit_pos + bit_size));
656 gen_op(TOK_SHL);
657 vpushi(bits - bit_size);
658 /* NOTE: transformed to SHR if unsigned */
659 gen_op(TOK_SAR);
660 r = gv(rc);
661 } else {
662 if (is_float(vtop->type.t) &&
663 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
664 Sym *sym;
665 int *ptr;
666 unsigned long offset;
667 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
668 CValue check;
669 #endif
671 /* XXX: unify with initializers handling ? */
672 /* CPUs usually cannot use float constants, so we store them
673 generically in data segment */
674 size = type_size(&vtop->type, &align);
675 offset = (data_section->data_offset + align - 1) & -align;
676 data_section->data_offset = offset;
677 /* XXX: not portable yet */
678 #if defined(__i386__) || defined(__x86_64__)
679 /* Zero pad x87 tenbyte long doubles */
680 if (size == LDOUBLE_SIZE)
681 vtop->c.tab[2] &= 0xffff;
682 #endif
683 ptr = section_ptr_add(data_section, size);
684 size = size >> 2;
685 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
686 check.d = 1;
687 if(check.tab[0])
688 for(i=0;i<size;i++)
689 ptr[i] = vtop->c.tab[size-1-i];
690 else
691 #endif
692 for(i=0;i<size;i++)
693 ptr[i] = vtop->c.tab[i];
694 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
695 vtop->r |= VT_LVAL | VT_SYM;
696 vtop->sym = sym;
697 vtop->c.ul = 0;
699 #ifdef CONFIG_TCC_BCHECK
700 if (vtop->r & VT_MUSTBOUND)
701 gbound();
702 #endif
704 r = vtop->r & VT_VALMASK;
705 rc2 = RC_INT;
706 if (rc == RC_IRET)
707 rc2 = RC_LRET;
708 /* need to reload if:
709 - constant
710 - lvalue (need to dereference pointer)
711 - already a register, but not in the right class */
712 if (r >= VT_CONST
713 || (vtop->r & VT_LVAL)
714 || !(reg_classes[r] & rc)
715 #ifndef TCC_TARGET_X86_64
716 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
717 #endif
720 r = get_reg(rc);
721 #ifndef TCC_TARGET_X86_64
722 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
723 int r2;
724 unsigned long long ll;
725 /* two register type load : expand to two words
726 temporarily */
727 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
728 /* load constant */
729 ll = vtop->c.ull;
730 vtop->c.ui = ll; /* first word */
731 load(r, vtop);
732 vtop->r = r; /* save register value */
733 vpushi(ll >> 32); /* second word */
734 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
735 (vtop->r & VT_LVAL)) {
736 /* We do not want to modifier the long long
737 pointer here, so the safest (and less
738 efficient) is to save all the other registers
739 in the stack. XXX: totally inefficient. */
740 save_regs(1);
741 /* load from memory */
742 load(r, vtop);
743 vdup();
744 vtop[-1].r = r; /* save register value */
745 /* increment pointer to get second word */
746 vtop->type.t = VT_INT;
747 gaddrof();
748 vpushi(4);
749 gen_op('+');
750 vtop->r |= VT_LVAL;
751 } else {
752 /* move registers */
753 load(r, vtop);
754 vdup();
755 vtop[-1].r = r; /* save register value */
756 vtop->r = vtop[-1].r2;
758 /* allocate second register */
759 r2 = get_reg(rc2);
760 load(r2, vtop);
761 vpop();
762 /* write second register */
763 vtop->r2 = r2;
764 } else
765 #endif
766 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
767 int t1, t;
768 /* lvalue of scalar type : need to use lvalue type
769 because of possible cast */
770 t = vtop->type.t;
771 t1 = t;
772 /* compute memory access type */
773 if (vtop->r & VT_LVAL_BYTE)
774 t = VT_BYTE;
775 else if (vtop->r & VT_LVAL_SHORT)
776 t = VT_SHORT;
777 if (vtop->r & VT_LVAL_UNSIGNED)
778 t |= VT_UNSIGNED;
779 vtop->type.t = t;
780 load(r, vtop);
781 /* restore wanted type */
782 vtop->type.t = t1;
783 } else {
784 /* one register type load */
785 load(r, vtop);
788 vtop->r = r;
789 #ifdef TCC_TARGET_C67
790 /* uses register pairs for doubles */
791 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
792 vtop->r2 = r+1;
793 #endif
795 return r;
798 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
799 ST_FUNC void gv2(int rc1, int rc2)
801 int v;
803 /* generate more generic register first. But VT_JMP or VT_CMP
804 values must be generated first in all cases to avoid possible
805 reload errors */
806 v = vtop[0].r & VT_VALMASK;
807 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
808 vswap();
809 gv(rc1);
810 vswap();
811 gv(rc2);
812 /* test if reload is needed for first register */
813 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
814 vswap();
815 gv(rc1);
816 vswap();
818 } else {
819 gv(rc2);
820 vswap();
821 gv(rc1);
822 vswap();
823 /* test if reload is needed for first register */
824 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
825 gv(rc2);
830 /* wrapper around RC_FRET to return a register by type */
831 static int rc_fret(int t)
833 #ifdef TCC_TARGET_X86_64
834 if (t == VT_LDOUBLE) {
835 return RC_ST0;
837 #endif
838 return RC_FRET;
841 /* wrapper around REG_FRET to return a register by type */
842 static int reg_fret(int t)
844 #ifdef TCC_TARGET_X86_64
845 if (t == VT_LDOUBLE) {
846 return TREG_ST0;
848 #endif
849 return REG_FRET;
852 /* expand long long on stack in two int registers */
853 static void lexpand(void)
855 int u;
857 u = vtop->type.t & VT_UNSIGNED;
858 gv(RC_INT);
859 vdup();
860 vtop[0].r = vtop[-1].r2;
861 vtop[0].r2 = VT_CONST;
862 vtop[-1].r2 = VT_CONST;
863 vtop[0].type.t = VT_INT | u;
864 vtop[-1].type.t = VT_INT | u;
867 #ifdef TCC_TARGET_ARM
868 /* expand long long on stack */
869 ST_FUNC void lexpand_nr(void)
871 int u,v;
873 u = vtop->type.t & VT_UNSIGNED;
874 vdup();
875 vtop->r2 = VT_CONST;
876 vtop->type.t = VT_INT | u;
877 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
878 if (v == VT_CONST) {
879 vtop[-1].c.ui = vtop->c.ull;
880 vtop->c.ui = vtop->c.ull >> 32;
881 vtop->r = VT_CONST;
882 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
883 vtop->c.ui += 4;
884 vtop->r = vtop[-1].r;
885 } else if (v > VT_CONST) {
886 vtop--;
887 lexpand();
888 } else
889 vtop->r = vtop[-1].r2;
890 vtop[-1].r2 = VT_CONST;
891 vtop[-1].type.t = VT_INT | u;
893 #endif
895 /* build a long long from two ints */
896 static void lbuild(int t)
898 gv2(RC_INT, RC_INT);
899 vtop[-1].r2 = vtop[0].r;
900 vtop[-1].type.t = t;
901 vpop();
904 /* rotate n first stack elements to the bottom
905 I1 ... In -> I2 ... In I1 [top is right]
907 static void vrotb(int n)
909 int i;
910 SValue tmp;
912 tmp = vtop[-n + 1];
913 for(i=-n+1;i!=0;i++)
914 vtop[i] = vtop[i+1];
915 vtop[0] = tmp;
918 /* rotate n first stack elements to the top
919 I1 ... In -> In I1 ... I(n-1) [top is right]
921 ST_FUNC void vrott(int n)
923 int i;
924 SValue tmp;
926 tmp = vtop[0];
927 for(i = 0;i < n - 1; i++)
928 vtop[-i] = vtop[-i - 1];
929 vtop[-n + 1] = tmp;
932 #ifdef TCC_TARGET_ARM
933 /* like vrott but in other direction
934 In ... I1 -> I(n-1) ... I1 In [top is right]
936 ST_FUNC void vnrott(int n)
938 int i;
939 SValue tmp;
941 tmp = vtop[-n + 1];
942 for(i = n - 1; i > 0; i--)
943 vtop[-i] = vtop[-i + 1];
944 vtop[0] = tmp;
946 #endif
948 /* pop stack value */
949 ST_FUNC void vpop(void)
951 int v;
952 v = vtop->r & VT_VALMASK;
953 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
954 /* for x86, we need to pop the FP stack */
955 if (v == TREG_ST0 && !nocode_wanted) {
956 o(0xd8dd); /* fstp %st(0) */
957 } else
958 #endif
959 if (v == VT_JMP || v == VT_JMPI) {
960 /* need to put correct jump if && or || without test */
961 gsym(vtop->c.ul);
963 vtop--;
966 /* convert stack entry to register and duplicate its value in another
967 register */
968 static void gv_dup(void)
970 int rc, t, r, r1;
971 SValue sv;
973 t = vtop->type.t;
974 if ((t & VT_BTYPE) == VT_LLONG) {
975 lexpand();
976 gv_dup();
977 vswap();
978 vrotb(3);
979 gv_dup();
980 vrotb(4);
981 /* stack: H L L1 H1 */
982 lbuild(t);
983 vrotb(3);
984 vrotb(3);
985 vswap();
986 lbuild(t);
987 vswap();
988 } else {
989 /* duplicate value */
990 rc = RC_INT;
991 sv.type.t = VT_INT;
992 if (is_float(t)) {
993 rc = RC_FLOAT;
994 #ifdef TCC_TARGET_X86_64
995 if ((t & VT_BTYPE) == VT_LDOUBLE) {
996 rc = RC_ST0;
998 #endif
999 sv.type.t = t;
1001 r = gv(rc);
1002 r1 = get_reg(rc);
1003 sv.r = r;
1004 sv.c.ul = 0;
1005 load(r1, &sv); /* move r to r1 */
1006 vdup();
1007 /* duplicates value */
1008 if (r != r1)
1009 vtop->r = r1;
1013 #ifndef TCC_TARGET_X86_64
1014 /* generate CPU independent (unsigned) long long operations */
1015 static void gen_opl(int op)
1017 int t, a, b, op1, c, i;
1018 int func;
1019 unsigned short reg_iret = REG_IRET;
1020 unsigned short reg_lret = REG_LRET;
1021 SValue tmp;
1023 switch(op) {
1024 case '/':
1025 case TOK_PDIV:
1026 func = TOK___divdi3;
1027 goto gen_func;
1028 case TOK_UDIV:
1029 func = TOK___udivdi3;
1030 goto gen_func;
1031 case '%':
1032 func = TOK___moddi3;
1033 goto gen_mod_func;
1034 case TOK_UMOD:
1035 func = TOK___umoddi3;
1036 gen_mod_func:
1037 #ifdef TCC_ARM_EABI
1038 reg_iret = TREG_R2;
1039 reg_lret = TREG_R3;
1040 #endif
1041 gen_func:
1042 /* call generic long long function */
1043 vpush_global_sym(&func_old_type, func);
1044 vrott(3);
1045 gfunc_call(2);
1046 vpushi(0);
1047 vtop->r = reg_iret;
1048 vtop->r2 = reg_lret;
1049 break;
1050 case '^':
1051 case '&':
1052 case '|':
1053 case '*':
1054 case '+':
1055 case '-':
1056 t = vtop->type.t;
1057 vswap();
1058 lexpand();
1059 vrotb(3);
1060 lexpand();
1061 /* stack: L1 H1 L2 H2 */
1062 tmp = vtop[0];
1063 vtop[0] = vtop[-3];
1064 vtop[-3] = tmp;
1065 tmp = vtop[-2];
1066 vtop[-2] = vtop[-3];
1067 vtop[-3] = tmp;
1068 vswap();
1069 /* stack: H1 H2 L1 L2 */
1070 if (op == '*') {
1071 vpushv(vtop - 1);
1072 vpushv(vtop - 1);
1073 gen_op(TOK_UMULL);
1074 lexpand();
1075 /* stack: H1 H2 L1 L2 ML MH */
1076 for(i=0;i<4;i++)
1077 vrotb(6);
1078 /* stack: ML MH H1 H2 L1 L2 */
1079 tmp = vtop[0];
1080 vtop[0] = vtop[-2];
1081 vtop[-2] = tmp;
1082 /* stack: ML MH H1 L2 H2 L1 */
1083 gen_op('*');
1084 vrotb(3);
1085 vrotb(3);
1086 gen_op('*');
1087 /* stack: ML MH M1 M2 */
1088 gen_op('+');
1089 gen_op('+');
1090 } else if (op == '+' || op == '-') {
1091 /* XXX: add non carry method too (for MIPS or alpha) */
1092 if (op == '+')
1093 op1 = TOK_ADDC1;
1094 else
1095 op1 = TOK_SUBC1;
1096 gen_op(op1);
1097 /* stack: H1 H2 (L1 op L2) */
1098 vrotb(3);
1099 vrotb(3);
1100 gen_op(op1 + 1); /* TOK_xxxC2 */
1101 } else {
1102 gen_op(op);
1103 /* stack: H1 H2 (L1 op L2) */
1104 vrotb(3);
1105 vrotb(3);
1106 /* stack: (L1 op L2) H1 H2 */
1107 gen_op(op);
1108 /* stack: (L1 op L2) (H1 op H2) */
1110 /* stack: L H */
1111 lbuild(t);
1112 break;
1113 case TOK_SAR:
1114 case TOK_SHR:
1115 case TOK_SHL:
1116 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1117 t = vtop[-1].type.t;
1118 vswap();
1119 lexpand();
1120 vrotb(3);
1121 /* stack: L H shift */
1122 c = (int)vtop->c.i;
1123 /* constant: simpler */
1124 /* NOTE: all comments are for SHL. the other cases are
1125 done by swaping words */
1126 vpop();
1127 if (op != TOK_SHL)
1128 vswap();
1129 if (c >= 32) {
1130 /* stack: L H */
1131 vpop();
1132 if (c > 32) {
1133 vpushi(c - 32);
1134 gen_op(op);
1136 if (op != TOK_SAR) {
1137 vpushi(0);
1138 } else {
1139 gv_dup();
1140 vpushi(31);
1141 gen_op(TOK_SAR);
1143 vswap();
1144 } else {
1145 vswap();
1146 gv_dup();
1147 /* stack: H L L */
1148 vpushi(c);
1149 gen_op(op);
1150 vswap();
1151 vpushi(32 - c);
1152 if (op == TOK_SHL)
1153 gen_op(TOK_SHR);
1154 else
1155 gen_op(TOK_SHL);
1156 vrotb(3);
1157 /* stack: L L H */
1158 vpushi(c);
1159 if (op == TOK_SHL)
1160 gen_op(TOK_SHL);
1161 else
1162 gen_op(TOK_SHR);
1163 gen_op('|');
1165 if (op != TOK_SHL)
1166 vswap();
1167 lbuild(t);
1168 } else {
1169 /* XXX: should provide a faster fallback on x86 ? */
1170 switch(op) {
1171 case TOK_SAR:
1172 func = TOK___ashrdi3;
1173 goto gen_func;
1174 case TOK_SHR:
1175 func = TOK___lshrdi3;
1176 goto gen_func;
1177 case TOK_SHL:
1178 func = TOK___ashldi3;
1179 goto gen_func;
1182 break;
1183 default:
1184 /* compare operations */
1185 t = vtop->type.t;
1186 vswap();
1187 lexpand();
1188 vrotb(3);
1189 lexpand();
1190 /* stack: L1 H1 L2 H2 */
1191 tmp = vtop[-1];
1192 vtop[-1] = vtop[-2];
1193 vtop[-2] = tmp;
1194 /* stack: L1 L2 H1 H2 */
1195 /* compare high */
1196 op1 = op;
1197 /* when values are equal, we need to compare low words. since
1198 the jump is inverted, we invert the test too. */
1199 if (op1 == TOK_LT)
1200 op1 = TOK_LE;
1201 else if (op1 == TOK_GT)
1202 op1 = TOK_GE;
1203 else if (op1 == TOK_ULT)
1204 op1 = TOK_ULE;
1205 else if (op1 == TOK_UGT)
1206 op1 = TOK_UGE;
1207 a = 0;
1208 b = 0;
1209 gen_op(op1);
1210 if (op1 != TOK_NE) {
1211 a = gtst(1, 0);
1213 if (op != TOK_EQ) {
1214 /* generate non equal test */
1215 /* XXX: NOT PORTABLE yet */
1216 if (a == 0) {
1217 b = gtst(0, 0);
1218 } else {
1219 #if defined(TCC_TARGET_I386)
1220 b = psym(0x850f, 0);
1221 #elif defined(TCC_TARGET_ARM)
1222 b = ind;
1223 o(0x1A000000 | encbranch(ind, 0, 1));
1224 #elif defined(TCC_TARGET_C67)
1225 error("not implemented");
1226 #else
1227 #error not supported
1228 #endif
1231 /* compare low. Always unsigned */
1232 op1 = op;
1233 if (op1 == TOK_LT)
1234 op1 = TOK_ULT;
1235 else if (op1 == TOK_LE)
1236 op1 = TOK_ULE;
1237 else if (op1 == TOK_GT)
1238 op1 = TOK_UGT;
1239 else if (op1 == TOK_GE)
1240 op1 = TOK_UGE;
1241 gen_op(op1);
1242 a = gtst(1, a);
1243 gsym(b);
1244 vseti(VT_JMPI, a);
1245 break;
1248 #endif
1250 /* handle integer constant optimizations and various machine
1251 independent opt */
1252 static void gen_opic(int op)
1254 int c1, c2, t1, t2, n;
1255 SValue *v1, *v2;
1256 long long l1, l2;
1257 typedef unsigned long long U;
1259 v1 = vtop - 1;
1260 v2 = vtop;
1261 t1 = v1->type.t & VT_BTYPE;
1262 t2 = v2->type.t & VT_BTYPE;
1264 if (t1 == VT_LLONG)
1265 l1 = v1->c.ll;
1266 else if (v1->type.t & VT_UNSIGNED)
1267 l1 = v1->c.ui;
1268 else
1269 l1 = v1->c.i;
1271 if (t2 == VT_LLONG)
1272 l2 = v2->c.ll;
1273 else if (v2->type.t & VT_UNSIGNED)
1274 l2 = v2->c.ui;
1275 else
1276 l2 = v2->c.i;
1278 /* currently, we cannot do computations with forward symbols */
1279 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1280 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1281 if (c1 && c2) {
1282 switch(op) {
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;
1288 case '*': l1 *= l2; break;
1290 case TOK_PDIV:
1291 case '/':
1292 case '%':
1293 case TOK_UDIV:
1294 case TOK_UMOD:
1295 /* if division by zero, generate explicit division */
1296 if (l2 == 0) {
1297 if (const_wanted)
1298 error("division by zero in constant");
1299 goto general_case;
1301 switch(op) {
1302 default: l1 /= l2; break;
1303 case '%': l1 %= l2; break;
1304 case TOK_UDIV: l1 = (U)l1 / l2; break;
1305 case TOK_UMOD: l1 = (U)l1 % l2; break;
1307 break;
1308 case TOK_SHL: l1 <<= l2; break;
1309 case TOK_SHR: l1 = (U)l1 >> l2; break;
1310 case TOK_SAR: l1 >>= l2; break;
1311 /* tests */
1312 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1313 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1314 case TOK_EQ: l1 = l1 == l2; break;
1315 case TOK_NE: l1 = l1 != l2; break;
1316 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1317 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1318 case TOK_LT: l1 = l1 < l2; break;
1319 case TOK_GE: l1 = l1 >= l2; break;
1320 case TOK_LE: l1 = l1 <= l2; break;
1321 case TOK_GT: l1 = l1 > l2; break;
1322 /* logical */
1323 case TOK_LAND: l1 = l1 && l2; break;
1324 case TOK_LOR: l1 = l1 || l2; break;
1325 default:
1326 goto general_case;
1328 v1->c.ll = l1;
1329 vtop--;
1330 } else {
1331 /* if commutative ops, put c2 as constant */
1332 if (c1 && (op == '+' || op == '&' || op == '^' ||
1333 op == '|' || op == '*')) {
1334 vswap();
1335 c2 = c1; //c = c1, c1 = c2, c2 = c;
1336 l2 = l1; //l = l1, l1 = l2, l2 = l;
1338 /* Filter out NOP operations like x*1, x-0, x&-1... */
1339 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1340 op == TOK_PDIV) &&
1341 l2 == 1) ||
1342 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1343 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1344 l2 == 0) ||
1345 (op == '&' &&
1346 l2 == -1))) {
1347 /* nothing to do */
1348 vtop--;
1349 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1350 /* try to use shifts instead of muls or divs */
1351 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1352 n = -1;
1353 while (l2) {
1354 l2 >>= 1;
1355 n++;
1357 vtop->c.ll = n;
1358 if (op == '*')
1359 op = TOK_SHL;
1360 else if (op == TOK_PDIV)
1361 op = TOK_SAR;
1362 else
1363 op = TOK_SHR;
1365 goto general_case;
1366 } else if (c2 && (op == '+' || op == '-') &&
1367 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1368 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1369 /* symbol + constant case */
1370 if (op == '-')
1371 l2 = -l2;
1372 vtop--;
1373 vtop->c.ll += l2;
1374 } else {
1375 general_case:
1376 if (!nocode_wanted) {
1377 /* call low level op generator */
1378 if (t1 == VT_LLONG || t2 == VT_LLONG)
1379 gen_opl(op);
1380 else
1381 gen_opi(op);
1382 } else {
1383 vtop--;
1389 /* generate a floating point operation with constant propagation */
1390 static void gen_opif(int op)
1392 int c1, c2;
1393 SValue *v1, *v2;
1394 long double f1, f2;
1396 v1 = vtop - 1;
1397 v2 = vtop;
1398 /* currently, we cannot do computations with forward symbols */
1399 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1400 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1401 if (c1 && c2) {
1402 if (v1->type.t == VT_FLOAT) {
1403 f1 = v1->c.f;
1404 f2 = v2->c.f;
1405 } else if (v1->type.t == VT_DOUBLE) {
1406 f1 = v1->c.d;
1407 f2 = v2->c.d;
1408 } else {
1409 f1 = v1->c.ld;
1410 f2 = v2->c.ld;
1413 /* NOTE: we only do constant propagation if finite number (not
1414 NaN or infinity) (ANSI spec) */
1415 if (!ieee_finite(f1) || !ieee_finite(f2))
1416 goto general_case;
1418 switch(op) {
1419 case '+': f1 += f2; break;
1420 case '-': f1 -= f2; break;
1421 case '*': f1 *= f2; break;
1422 case '/':
1423 if (f2 == 0.0) {
1424 if (const_wanted)
1425 error("division by zero in constant");
1426 goto general_case;
1428 f1 /= f2;
1429 break;
1430 /* XXX: also handles tests ? */
1431 default:
1432 goto general_case;
1434 /* XXX: overflow test ? */
1435 if (v1->type.t == VT_FLOAT) {
1436 v1->c.f = f1;
1437 } else if (v1->type.t == VT_DOUBLE) {
1438 v1->c.d = f1;
1439 } else {
1440 v1->c.ld = f1;
1442 vtop--;
1443 } else {
1444 general_case:
1445 if (!nocode_wanted) {
1446 gen_opf(op);
1447 } else {
1448 vtop--;
1453 static int pointed_size(CType *type)
1455 int align;
1456 return type_size(pointed_type(type), &align);
1459 static void vla_runtime_pointed_size(CType *type)
1461 int align;
1462 vla_runtime_type_size(pointed_type(type), &align);
1465 static inline int is_null_pointer(SValue *p)
1467 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1468 return 0;
1469 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1470 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1473 static inline int is_integer_btype(int bt)
1475 return (bt == VT_BYTE || bt == VT_SHORT ||
1476 bt == VT_INT || bt == VT_LLONG);
1479 /* check types for comparison or substraction of pointers */
1480 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1482 CType *type1, *type2, tmp_type1, tmp_type2;
1483 int bt1, bt2;
1485 /* null pointers are accepted for all comparisons as gcc */
1486 if (is_null_pointer(p1) || is_null_pointer(p2))
1487 return;
1488 type1 = &p1->type;
1489 type2 = &p2->type;
1490 bt1 = type1->t & VT_BTYPE;
1491 bt2 = type2->t & VT_BTYPE;
1492 /* accept comparison between pointer and integer with a warning */
1493 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1494 if (op != TOK_LOR && op != TOK_LAND )
1495 warning("comparison between pointer and integer");
1496 return;
1499 /* both must be pointers or implicit function pointers */
1500 if (bt1 == VT_PTR) {
1501 type1 = pointed_type(type1);
1502 } else if (bt1 != VT_FUNC)
1503 goto invalid_operands;
1505 if (bt2 == VT_PTR) {
1506 type2 = pointed_type(type2);
1507 } else if (bt2 != VT_FUNC) {
1508 invalid_operands:
1509 error("invalid operands to binary %s", get_tok_str(op, NULL));
1511 if ((type1->t & VT_BTYPE) == VT_VOID ||
1512 (type2->t & VT_BTYPE) == VT_VOID)
1513 return;
1514 tmp_type1 = *type1;
1515 tmp_type2 = *type2;
1516 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1517 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1518 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1519 /* gcc-like error if '-' is used */
1520 if (op == '-')
1521 goto invalid_operands;
1522 else
1523 warning("comparison of distinct pointer types lacks a cast");
1527 /* generic gen_op: handles types problems */
1528 ST_FUNC void gen_op(int op)
1530 int u, t1, t2, bt1, bt2, t;
1531 CType type1;
1533 t1 = vtop[-1].type.t;
1534 t2 = vtop[0].type.t;
1535 bt1 = t1 & VT_BTYPE;
1536 bt2 = t2 & VT_BTYPE;
1538 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1539 /* at least one operand is a pointer */
1540 /* relationnal op: must be both pointers */
1541 if (op >= TOK_ULT && op <= TOK_LOR) {
1542 check_comparison_pointer_types(vtop - 1, vtop, op);
1543 /* pointers are handled are unsigned */
1544 #ifdef TCC_TARGET_X86_64
1545 t = VT_LLONG | VT_UNSIGNED;
1546 #else
1547 t = VT_INT | VT_UNSIGNED;
1548 #endif
1549 goto std_op;
1551 /* if both pointers, then it must be the '-' op */
1552 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1553 int ptr1_is_vla;
1555 ptr1_is_vla = 0;
1556 if (op != '-')
1557 error("cannot use pointers here");
1558 check_comparison_pointer_types(vtop - 1, vtop, op);
1559 /* XXX: check that types are compatible */
1560 if (vtop[-1].type.t & VT_VLA) {
1561 vla_runtime_pointed_size(&vtop[-1].type);
1562 vrott(3);
1563 ptr1_is_vla = 1;
1564 } else {
1565 u = pointed_size(&vtop[-1].type);
1567 gen_opic(op);
1568 /* set to integer type */
1569 #ifdef TCC_TARGET_X86_64
1570 vtop->type.t = VT_LLONG;
1571 #else
1572 vtop->type.t = VT_INT;
1573 #endif
1574 if (ptr1_is_vla)
1575 vswap();
1576 else
1577 vpushi(u);
1578 gen_op(TOK_PDIV);
1579 } else {
1580 /* exactly one pointer : must be '+' or '-'. */
1581 if (op != '-' && op != '+')
1582 error("cannot use pointers here");
1583 /* Put pointer as first operand */
1584 if (bt2 == VT_PTR) {
1585 vswap();
1586 swap(&t1, &t2);
1588 type1 = vtop[-1].type;
1589 type1.t &= ~(VT_ARRAY|VT_VLA);
1590 if (vtop[-1].type.t & VT_VLA)
1591 vla_runtime_pointed_size(&vtop[-1].type);
1592 else {
1593 u = pointed_size(&vtop[-1].type);
1594 if (u < 0)
1595 error("unknown array element size");
1596 #ifdef TCC_TARGET_X86_64
1597 vpushll(u);
1598 #else
1599 /* XXX: cast to int ? (long long case) */
1600 vpushi(u);
1601 #endif
1603 gen_op('*');
1604 #ifdef CONFIG_TCC_BCHECK
1605 /* if evaluating constant expression, no code should be
1606 generated, so no bound check */
1607 if (tcc_state->do_bounds_check && !const_wanted) {
1608 /* if bounded pointers, we generate a special code to
1609 test bounds */
1610 if (op == '-') {
1611 vpushi(0);
1612 vswap();
1613 gen_op('-');
1615 gen_bounded_ptr_add();
1616 } else
1617 #endif
1619 gen_opic(op);
1621 /* put again type if gen_opic() swaped operands */
1622 vtop->type = type1;
1624 } else if (is_float(bt1) || is_float(bt2)) {
1625 /* compute bigger type and do implicit casts */
1626 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1627 t = VT_LDOUBLE;
1628 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1629 t = VT_DOUBLE;
1630 } else {
1631 t = VT_FLOAT;
1633 /* floats can only be used for a few operations */
1634 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1635 (op < TOK_ULT || op > TOK_GT))
1636 error("invalid operands for binary operation");
1637 goto std_op;
1638 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1639 /* cast to biggest op */
1640 t = VT_LLONG;
1641 /* convert to unsigned if it does not fit in a long long */
1642 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1643 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1644 t |= VT_UNSIGNED;
1645 goto std_op;
1646 } else {
1647 /* integer operations */
1648 t = VT_INT;
1649 /* convert to unsigned if it does not fit in an integer */
1650 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1651 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1652 t |= VT_UNSIGNED;
1653 std_op:
1654 /* XXX: currently, some unsigned operations are explicit, so
1655 we modify them here */
1656 if (t & VT_UNSIGNED) {
1657 if (op == TOK_SAR)
1658 op = TOK_SHR;
1659 else if (op == '/')
1660 op = TOK_UDIV;
1661 else if (op == '%')
1662 op = TOK_UMOD;
1663 else if (op == TOK_LT)
1664 op = TOK_ULT;
1665 else if (op == TOK_GT)
1666 op = TOK_UGT;
1667 else if (op == TOK_LE)
1668 op = TOK_ULE;
1669 else if (op == TOK_GE)
1670 op = TOK_UGE;
1672 vswap();
1673 type1.t = t;
1674 gen_cast(&type1);
1675 vswap();
1676 /* special case for shifts and long long: we keep the shift as
1677 an integer */
1678 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1679 type1.t = VT_INT;
1680 gen_cast(&type1);
1681 if (is_float(t))
1682 gen_opif(op);
1683 else
1684 gen_opic(op);
1685 if (op >= TOK_ULT && op <= TOK_GT) {
1686 /* relationnal op: the result is an int */
1687 vtop->type.t = VT_INT;
1688 } else {
1689 vtop->type.t = t;
1694 #ifndef TCC_TARGET_ARM
1695 /* generic itof for unsigned long long case */
1696 static void gen_cvt_itof1(int t)
1698 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1699 (VT_LLONG | VT_UNSIGNED)) {
1701 if (t == VT_FLOAT)
1702 vpush_global_sym(&func_old_type, TOK___floatundisf);
1703 #if LDOUBLE_SIZE != 8
1704 else if (t == VT_LDOUBLE)
1705 vpush_global_sym(&func_old_type, TOK___floatundixf);
1706 #endif
1707 else
1708 vpush_global_sym(&func_old_type, TOK___floatundidf);
1709 vrott(2);
1710 gfunc_call(1);
1711 vpushi(0);
1712 vtop->r = reg_fret(t);
1713 } else {
1714 gen_cvt_itof(t);
1717 #endif
1719 /* generic ftoi for unsigned long long case */
1720 static void gen_cvt_ftoi1(int t)
1722 int st;
1724 if (t == (VT_LLONG | VT_UNSIGNED)) {
1725 /* not handled natively */
1726 st = vtop->type.t & VT_BTYPE;
1727 if (st == VT_FLOAT)
1728 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1729 #if LDOUBLE_SIZE != 8
1730 else if (st == VT_LDOUBLE)
1731 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1732 #endif
1733 else
1734 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1735 vrott(2);
1736 gfunc_call(1);
1737 vpushi(0);
1738 vtop->r = REG_IRET;
1739 vtop->r2 = REG_LRET;
1740 } else {
1741 gen_cvt_ftoi(t);
1745 /* force char or short cast */
1746 static void force_charshort_cast(int t)
1748 int bits, dbt;
1749 dbt = t & VT_BTYPE;
1750 /* XXX: add optimization if lvalue : just change type and offset */
1751 if (dbt == VT_BYTE)
1752 bits = 8;
1753 else
1754 bits = 16;
1755 if (t & VT_UNSIGNED) {
1756 vpushi((1 << bits) - 1);
1757 gen_op('&');
1758 } else {
1759 bits = 32 - bits;
1760 vpushi(bits);
1761 gen_op(TOK_SHL);
1762 /* result must be signed or the SAR is converted to an SHL
1763 This was not the case when "t" was a signed short
1764 and the last value on the stack was an unsigned int */
1765 vtop->type.t &= ~VT_UNSIGNED;
1766 vpushi(bits);
1767 gen_op(TOK_SAR);
1771 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1772 static void gen_cast(CType *type)
1774 int sbt, dbt, sf, df, c, p;
1776 /* special delayed cast for char/short */
1777 /* XXX: in some cases (multiple cascaded casts), it may still
1778 be incorrect */
1779 if (vtop->r & VT_MUSTCAST) {
1780 vtop->r &= ~VT_MUSTCAST;
1781 force_charshort_cast(vtop->type.t);
1784 /* bitfields first get cast to ints */
1785 if (vtop->type.t & VT_BITFIELD) {
1786 gv(RC_INT);
1789 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1790 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1792 if (sbt != dbt) {
1793 sf = is_float(sbt);
1794 df = is_float(dbt);
1795 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1796 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1797 if (c) {
1798 /* constant case: we can do it now */
1799 /* XXX: in ISOC, cannot do it if error in convert */
1800 if (sbt == VT_FLOAT)
1801 vtop->c.ld = vtop->c.f;
1802 else if (sbt == VT_DOUBLE)
1803 vtop->c.ld = vtop->c.d;
1805 if (df) {
1806 if ((sbt & VT_BTYPE) == VT_LLONG) {
1807 if (sbt & VT_UNSIGNED)
1808 vtop->c.ld = vtop->c.ull;
1809 else
1810 vtop->c.ld = vtop->c.ll;
1811 } else if(!sf) {
1812 if (sbt & VT_UNSIGNED)
1813 vtop->c.ld = vtop->c.ui;
1814 else
1815 vtop->c.ld = vtop->c.i;
1818 if (dbt == VT_FLOAT)
1819 vtop->c.f = (float)vtop->c.ld;
1820 else if (dbt == VT_DOUBLE)
1821 vtop->c.d = (double)vtop->c.ld;
1822 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1823 vtop->c.ull = (unsigned long long)vtop->c.ld;
1824 } else if (sf && dbt == VT_BOOL) {
1825 vtop->c.i = (vtop->c.ld != 0);
1826 } else {
1827 if(sf)
1828 vtop->c.ll = (long long)vtop->c.ld;
1829 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1830 vtop->c.ll = vtop->c.ull;
1831 else if (sbt & VT_UNSIGNED)
1832 vtop->c.ll = vtop->c.ui;
1833 #ifdef TCC_TARGET_X86_64
1834 else if (sbt == VT_PTR)
1836 #endif
1837 else if (sbt != VT_LLONG)
1838 vtop->c.ll = vtop->c.i;
1840 if (dbt == (VT_LLONG|VT_UNSIGNED))
1841 vtop->c.ull = vtop->c.ll;
1842 else if (dbt == VT_BOOL)
1843 vtop->c.i = (vtop->c.ll != 0);
1844 else if (dbt != VT_LLONG) {
1845 int s = 0;
1846 if ((dbt & VT_BTYPE) == VT_BYTE)
1847 s = 24;
1848 else if ((dbt & VT_BTYPE) == VT_SHORT)
1849 s = 16;
1851 if(dbt & VT_UNSIGNED)
1852 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1853 else
1854 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1857 } else if (p && dbt == VT_BOOL) {
1858 vtop->r = VT_CONST;
1859 vtop->c.i = 1;
1860 } else if (!nocode_wanted) {
1861 /* non constant case: generate code */
1862 if (sf && df) {
1863 /* convert from fp to fp */
1864 gen_cvt_ftof(dbt);
1865 } else if (df) {
1866 /* convert int to fp */
1867 gen_cvt_itof1(dbt);
1868 } else if (sf) {
1869 /* convert fp to int */
1870 if (dbt == VT_BOOL) {
1871 vpushi(0);
1872 gen_op(TOK_NE);
1873 } else {
1874 /* we handle char/short/etc... with generic code */
1875 if (dbt != (VT_INT | VT_UNSIGNED) &&
1876 dbt != (VT_LLONG | VT_UNSIGNED) &&
1877 dbt != VT_LLONG)
1878 dbt = VT_INT;
1879 gen_cvt_ftoi1(dbt);
1880 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1881 /* additional cast for char/short... */
1882 vtop->type.t = dbt;
1883 gen_cast(type);
1886 #ifndef TCC_TARGET_X86_64
1887 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1888 if ((sbt & VT_BTYPE) != VT_LLONG) {
1889 /* scalar to long long */
1890 /* machine independent conversion */
1891 gv(RC_INT);
1892 /* generate high word */
1893 if (sbt == (VT_INT | VT_UNSIGNED)) {
1894 vpushi(0);
1895 gv(RC_INT);
1896 } else {
1897 if (sbt == VT_PTR) {
1898 /* cast from pointer to int before we apply
1899 shift operation, which pointers don't support*/
1900 gen_cast(&int_type);
1902 gv_dup();
1903 vpushi(31);
1904 gen_op(TOK_SAR);
1906 /* patch second register */
1907 vtop[-1].r2 = vtop->r;
1908 vpop();
1910 #else
1911 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1912 (dbt & VT_BTYPE) == VT_PTR ||
1913 (dbt & VT_BTYPE) == VT_FUNC) {
1914 if ((sbt & VT_BTYPE) != VT_LLONG &&
1915 (sbt & VT_BTYPE) != VT_PTR &&
1916 (sbt & VT_BTYPE) != VT_FUNC) {
1917 /* need to convert from 32bit to 64bit */
1918 int r = gv(RC_INT);
1919 if (sbt != (VT_INT | VT_UNSIGNED)) {
1920 /* x86_64 specific: movslq */
1921 o(0x6348);
1922 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1925 #endif
1926 } else if (dbt == VT_BOOL) {
1927 /* scalar to bool */
1928 vpushi(0);
1929 gen_op(TOK_NE);
1930 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1931 (dbt & VT_BTYPE) == VT_SHORT) {
1932 if (sbt == VT_PTR) {
1933 vtop->type.t = VT_INT;
1934 warning("nonportable conversion from pointer to char/short");
1936 force_charshort_cast(dbt);
1937 } else if ((dbt & VT_BTYPE) == VT_INT) {
1938 /* scalar to int */
1939 if (sbt == VT_LLONG) {
1940 /* from long long: just take low order word */
1941 lexpand();
1942 vpop();
1944 /* if lvalue and single word type, nothing to do because
1945 the lvalue already contains the real type size (see
1946 VT_LVAL_xxx constants) */
1949 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1950 /* if we are casting between pointer types,
1951 we must update the VT_LVAL_xxx size */
1952 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1953 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1955 vtop->type = *type;
1958 /* return type size as known at compile time. Put alignment at 'a' */
1959 ST_FUNC int type_size(CType *type, int *a)
1961 Sym *s;
1962 int bt;
1964 bt = type->t & VT_BTYPE;
1965 if (bt == VT_STRUCT) {
1966 /* struct/union */
1967 s = type->ref;
1968 *a = s->r;
1969 return s->c;
1970 } else if (bt == VT_PTR) {
1971 if (type->t & VT_VLA) {
1972 *a = 1;
1973 return 0;
1974 } else if (type->t & VT_ARRAY) {
1975 int ts;
1977 s = type->ref;
1978 ts = type_size(&s->type, a);
1980 if (ts < 0 && s->c < 0)
1981 ts = -ts;
1983 return ts * s->c;
1984 } else {
1985 *a = PTR_SIZE;
1986 return PTR_SIZE;
1988 } else if (bt == VT_LDOUBLE) {
1989 *a = LDOUBLE_ALIGN;
1990 return LDOUBLE_SIZE;
1991 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
1992 #ifdef TCC_TARGET_I386
1993 #ifdef TCC_TARGET_PE
1994 *a = 8;
1995 #else
1996 *a = 4;
1997 #endif
1998 #elif defined(TCC_TARGET_ARM)
1999 #ifdef TCC_ARM_EABI
2000 *a = 8;
2001 #else
2002 *a = 4;
2003 #endif
2004 #else
2005 *a = 8;
2006 #endif
2007 return 8;
2008 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2009 *a = 4;
2010 return 4;
2011 } else if (bt == VT_SHORT) {
2012 *a = 2;
2013 return 2;
2014 } else {
2015 /* char, void, function, _Bool */
2016 *a = 1;
2017 return 1;
2021 /* push type size as known at runtime time on top of value stack. Put
2022 alignment at 'a' */
2023 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2025 if (type->t & VT_VLA) {
2026 Sym *s;
2028 s = type->ref;
2029 vla_runtime_type_size(&s->type, a);
2030 vpushv(s->s);
2031 if ((vtop->r & (VT_SYM|VT_LVAL|VT_VALMASK)) != VT_CONST) {
2032 gv_dup();
2033 vswap();
2034 vpop();
2036 gen_op('*');
2037 } else {
2038 int size;
2040 size = type_size(type, a);
2041 vpushi(size);
2045 /* return the pointed type of t */
2046 static inline CType *pointed_type(CType *type)
2048 return &type->ref->type;
2051 /* modify type so that its it is a pointer to type. */
2052 ST_FUNC void mk_pointer(CType *type)
2054 Sym *s;
2055 s = sym_push(SYM_FIELD, type, 0, -1);
2056 type->t = VT_PTR | (type->t & ~VT_TYPE);
2057 type->ref = s;
2060 /* compare function types. OLD functions match any new functions */
2061 static int is_compatible_func(CType *type1, CType *type2)
2063 Sym *s1, *s2;
2065 s1 = type1->ref;
2066 s2 = type2->ref;
2067 if (!is_compatible_types(&s1->type, &s2->type))
2068 return 0;
2069 /* check func_call */
2070 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2071 return 0;
2072 /* XXX: not complete */
2073 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2074 return 1;
2075 if (s1->c != s2->c)
2076 return 0;
2077 while (s1 != NULL) {
2078 if (s2 == NULL)
2079 return 0;
2080 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2081 return 0;
2082 s1 = s1->next;
2083 s2 = s2->next;
2085 if (s2)
2086 return 0;
2087 return 1;
2090 /* return true if type1 and type2 are the same. If unqualified is
2091 true, qualifiers on the types are ignored.
2093 - enums are not checked as gcc __builtin_types_compatible_p ()
2095 static int compare_types(CType *type1, CType *type2, int unqualified)
2097 int bt1, t1, t2;
2099 t1 = type1->t & VT_TYPE;
2100 t2 = type2->t & VT_TYPE;
2101 if (unqualified) {
2102 /* strip qualifiers before comparing */
2103 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2104 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2106 /* XXX: bitfields ? */
2107 if (t1 != t2)
2108 return 0;
2109 /* test more complicated cases */
2110 bt1 = t1 & VT_BTYPE;
2111 if (bt1 == VT_PTR) {
2112 type1 = pointed_type(type1);
2113 type2 = pointed_type(type2);
2114 return is_compatible_types(type1, type2);
2115 } else if (bt1 == VT_STRUCT) {
2116 return (type1->ref == type2->ref);
2117 } else if (bt1 == VT_FUNC) {
2118 return is_compatible_func(type1, type2);
2119 } else {
2120 return 1;
2124 /* return true if type1 and type2 are exactly the same (including
2125 qualifiers).
2127 static int is_compatible_types(CType *type1, CType *type2)
2129 return compare_types(type1,type2,0);
2132 /* return true if type1 and type2 are the same (ignoring qualifiers).
2134 static int is_compatible_parameter_types(CType *type1, CType *type2)
2136 return compare_types(type1,type2,1);
2139 /* print a type. If 'varstr' is not NULL, then the variable is also
2140 printed in the type */
2141 /* XXX: union */
2142 /* XXX: add array and function pointers */
2143 static void type_to_str(char *buf, int buf_size,
2144 CType *type, const char *varstr)
2146 int bt, v, t;
2147 Sym *s, *sa;
2148 char buf1[256];
2149 const char *tstr;
2151 t = type->t & VT_TYPE;
2152 bt = t & VT_BTYPE;
2153 buf[0] = '\0';
2154 if (t & VT_CONSTANT)
2155 pstrcat(buf, buf_size, "const ");
2156 if (t & VT_VOLATILE)
2157 pstrcat(buf, buf_size, "volatile ");
2158 if (t & VT_UNSIGNED)
2159 pstrcat(buf, buf_size, "unsigned ");
2160 switch(bt) {
2161 case VT_VOID:
2162 tstr = "void";
2163 goto add_tstr;
2164 case VT_BOOL:
2165 tstr = "_Bool";
2166 goto add_tstr;
2167 case VT_BYTE:
2168 tstr = "char";
2169 goto add_tstr;
2170 case VT_SHORT:
2171 tstr = "short";
2172 goto add_tstr;
2173 case VT_INT:
2174 tstr = "int";
2175 goto add_tstr;
2176 case VT_LONG:
2177 tstr = "long";
2178 goto add_tstr;
2179 case VT_LLONG:
2180 tstr = "long long";
2181 goto add_tstr;
2182 case VT_FLOAT:
2183 tstr = "float";
2184 goto add_tstr;
2185 case VT_DOUBLE:
2186 tstr = "double";
2187 goto add_tstr;
2188 case VT_LDOUBLE:
2189 tstr = "long double";
2190 add_tstr:
2191 pstrcat(buf, buf_size, tstr);
2192 break;
2193 case VT_ENUM:
2194 case VT_STRUCT:
2195 if (bt == VT_STRUCT)
2196 tstr = "struct ";
2197 else
2198 tstr = "enum ";
2199 pstrcat(buf, buf_size, tstr);
2200 v = type->ref->v & ~SYM_STRUCT;
2201 if (v >= SYM_FIRST_ANOM)
2202 pstrcat(buf, buf_size, "<anonymous>");
2203 else
2204 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2205 break;
2206 case VT_FUNC:
2207 s = type->ref;
2208 type_to_str(buf, buf_size, &s->type, varstr);
2209 pstrcat(buf, buf_size, "(");
2210 sa = s->next;
2211 while (sa != NULL) {
2212 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2213 pstrcat(buf, buf_size, buf1);
2214 sa = sa->next;
2215 if (sa)
2216 pstrcat(buf, buf_size, ", ");
2218 pstrcat(buf, buf_size, ")");
2219 goto no_var;
2220 case VT_PTR:
2221 s = type->ref;
2222 pstrcpy(buf1, sizeof(buf1), "*");
2223 if (varstr)
2224 pstrcat(buf1, sizeof(buf1), varstr);
2225 type_to_str(buf, buf_size, &s->type, buf1);
2226 goto no_var;
2228 if (varstr) {
2229 pstrcat(buf, buf_size, " ");
2230 pstrcat(buf, buf_size, varstr);
2232 no_var: ;
2235 /* verify type compatibility to store vtop in 'dt' type, and generate
2236 casts if needed. */
2237 static void gen_assign_cast(CType *dt)
2239 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2240 char buf1[256], buf2[256];
2241 int dbt, sbt;
2243 st = &vtop->type; /* source type */
2244 dbt = dt->t & VT_BTYPE;
2245 sbt = st->t & VT_BTYPE;
2246 if (dt->t & VT_CONSTANT)
2247 warning("assignment of read-only location");
2248 switch(dbt) {
2249 case VT_PTR:
2250 /* special cases for pointers */
2251 /* '0' can also be a pointer */
2252 if (is_null_pointer(vtop))
2253 goto type_ok;
2254 /* accept implicit pointer to integer cast with warning */
2255 if (is_integer_btype(sbt)) {
2256 warning("assignment makes pointer from integer without a cast");
2257 goto type_ok;
2259 type1 = pointed_type(dt);
2260 /* a function is implicitely a function pointer */
2261 if (sbt == VT_FUNC) {
2262 if ((type1->t & VT_BTYPE) != VT_VOID &&
2263 !is_compatible_types(pointed_type(dt), st))
2264 warning("assignment from incompatible pointer type");
2265 goto type_ok;
2267 if (sbt != VT_PTR)
2268 goto error;
2269 type2 = pointed_type(st);
2270 if ((type1->t & VT_BTYPE) == VT_VOID ||
2271 (type2->t & VT_BTYPE) == VT_VOID) {
2272 /* void * can match anything */
2273 } else {
2274 /* exact type match, except for unsigned */
2275 tmp_type1 = *type1;
2276 tmp_type2 = *type2;
2277 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2278 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2279 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2280 warning("assignment from incompatible pointer type");
2282 /* check const and volatile */
2283 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2284 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2285 warning("assignment discards qualifiers from pointer target type");
2286 break;
2287 case VT_BYTE:
2288 case VT_SHORT:
2289 case VT_INT:
2290 case VT_LLONG:
2291 if (sbt == VT_PTR || sbt == VT_FUNC) {
2292 warning("assignment makes integer from pointer without a cast");
2294 /* XXX: more tests */
2295 break;
2296 case VT_STRUCT:
2297 tmp_type1 = *dt;
2298 tmp_type2 = *st;
2299 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2300 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2301 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2302 error:
2303 type_to_str(buf1, sizeof(buf1), st, NULL);
2304 type_to_str(buf2, sizeof(buf2), dt, NULL);
2305 error("cannot cast '%s' to '%s'", buf1, buf2);
2307 break;
2309 type_ok:
2310 gen_cast(dt);
2313 /* store vtop in lvalue pushed on stack */
2314 ST_FUNC void vstore(void)
2316 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2318 ft = vtop[-1].type.t;
2319 sbt = vtop->type.t & VT_BTYPE;
2320 dbt = ft & VT_BTYPE;
2321 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2322 (sbt == VT_INT && dbt == VT_SHORT)) {
2323 /* optimize char/short casts */
2324 delayed_cast = VT_MUSTCAST;
2325 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2326 /* XXX: factorize */
2327 if (ft & VT_CONSTANT)
2328 warning("assignment of read-only location");
2329 } else {
2330 delayed_cast = 0;
2331 if (!(ft & VT_BITFIELD))
2332 gen_assign_cast(&vtop[-1].type);
2335 if (sbt == VT_STRUCT) {
2336 /* if structure, only generate pointer */
2337 /* structure assignment : generate memcpy */
2338 /* XXX: optimize if small size */
2339 if (!nocode_wanted) {
2340 size = type_size(&vtop->type, &align);
2342 /* destination */
2343 vswap();
2344 vtop->type.t = VT_PTR;
2345 gaddrof();
2347 /* address of memcpy() */
2348 #ifdef TCC_ARM_EABI
2349 if(!(align & 7))
2350 vpush_global_sym(&func_old_type, TOK_memcpy8);
2351 else if(!(align & 3))
2352 vpush_global_sym(&func_old_type, TOK_memcpy4);
2353 else
2354 #endif
2355 vpush_global_sym(&func_old_type, TOK_memcpy);
2357 vswap();
2358 /* source */
2359 vpushv(vtop - 2);
2360 vtop->type.t = VT_PTR;
2361 gaddrof();
2362 /* type size */
2363 vpushi(size);
2364 gfunc_call(3);
2365 } else {
2366 vswap();
2367 vpop();
2369 /* leave source on stack */
2370 } else if (ft & VT_BITFIELD) {
2371 /* bitfield store handling */
2372 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2373 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2374 /* remove bit field info to avoid loops */
2375 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2377 /* duplicate source into other register */
2378 gv_dup();
2379 vswap();
2380 vrott(3);
2382 if((ft & VT_BTYPE) == VT_BOOL) {
2383 gen_cast(&vtop[-1].type);
2384 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2387 /* duplicate destination */
2388 vdup();
2389 vtop[-1] = vtop[-2];
2391 /* mask and shift source */
2392 if((ft & VT_BTYPE) != VT_BOOL) {
2393 if((ft & VT_BTYPE) == VT_LLONG) {
2394 vpushll((1ULL << bit_size) - 1ULL);
2395 } else {
2396 vpushi((1 << bit_size) - 1);
2398 gen_op('&');
2400 vpushi(bit_pos);
2401 gen_op(TOK_SHL);
2402 /* load destination, mask and or with source */
2403 vswap();
2404 if((ft & VT_BTYPE) == VT_LLONG) {
2405 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2406 } else {
2407 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2409 gen_op('&');
2410 gen_op('|');
2411 /* store result */
2412 vstore();
2414 /* pop off shifted source from "duplicate source..." above */
2415 vpop();
2417 } else {
2418 #ifdef CONFIG_TCC_BCHECK
2419 /* bound check case */
2420 if (vtop[-1].r & VT_MUSTBOUND) {
2421 vswap();
2422 gbound();
2423 vswap();
2425 #endif
2426 if (!nocode_wanted) {
2427 rc = RC_INT;
2428 if (is_float(ft)) {
2429 rc = RC_FLOAT;
2430 #ifdef TCC_TARGET_X86_64
2431 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2432 rc = RC_ST0;
2434 #endif
2436 r = gv(rc); /* generate value */
2437 /* if lvalue was saved on stack, must read it */
2438 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2439 SValue sv;
2440 t = get_reg(RC_INT);
2441 #ifdef TCC_TARGET_X86_64
2442 sv.type.t = VT_PTR;
2443 #else
2444 sv.type.t = VT_INT;
2445 #endif
2446 sv.r = VT_LOCAL | VT_LVAL;
2447 sv.c.ul = vtop[-1].c.ul;
2448 load(t, &sv);
2449 vtop[-1].r = t | VT_LVAL;
2451 store(r, vtop - 1);
2452 #ifndef TCC_TARGET_X86_64
2453 /* two word case handling : store second register at word + 4 */
2454 if ((ft & VT_BTYPE) == VT_LLONG) {
2455 vswap();
2456 /* convert to int to increment easily */
2457 vtop->type.t = VT_INT;
2458 gaddrof();
2459 vpushi(4);
2460 gen_op('+');
2461 vtop->r |= VT_LVAL;
2462 vswap();
2463 /* XXX: it works because r2 is spilled last ! */
2464 store(vtop->r2, vtop - 1);
2466 #endif
2468 vswap();
2469 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2470 vtop->r |= delayed_cast;
2474 /* post defines POST/PRE add. c is the token ++ or -- */
2475 ST_FUNC void inc(int post, int c)
2477 test_lvalue();
2478 vdup(); /* save lvalue */
2479 if (post) {
2480 gv_dup(); /* duplicate value */
2481 vrotb(3);
2482 vrotb(3);
2484 /* add constant */
2485 vpushi(c - TOK_MID);
2486 gen_op('+');
2487 vstore(); /* store value */
2488 if (post)
2489 vpop(); /* if post op, return saved value */
2492 /* Parse GNUC __attribute__ extension. Currently, the following
2493 extensions are recognized:
2494 - aligned(n) : set data/function alignment.
2495 - packed : force data alignment to 1
2496 - section(x) : generate data/code in this section.
2497 - unused : currently ignored, but may be used someday.
2498 - regparm(n) : pass function parameters in registers (i386 only)
2500 static void parse_attribute(AttributeDef *ad)
2502 int t, n;
2504 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2505 next();
2506 skip('(');
2507 skip('(');
2508 while (tok != ')') {
2509 if (tok < TOK_IDENT)
2510 expect("attribute name");
2511 t = tok;
2512 next();
2513 switch(t) {
2514 case TOK_SECTION1:
2515 case TOK_SECTION2:
2516 skip('(');
2517 if (tok != TOK_STR)
2518 expect("section name");
2519 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2520 next();
2521 skip(')');
2522 break;
2523 case TOK_ALIGNED1:
2524 case TOK_ALIGNED2:
2525 if (tok == '(') {
2526 next();
2527 n = expr_const();
2528 if (n <= 0 || (n & (n - 1)) != 0)
2529 error("alignment must be a positive power of two");
2530 skip(')');
2531 } else {
2532 n = MAX_ALIGN;
2534 ad->aligned = n;
2535 break;
2536 case TOK_PACKED1:
2537 case TOK_PACKED2:
2538 ad->packed = 1;
2539 break;
2540 case TOK_WEAK1:
2541 case TOK_WEAK2:
2542 ad->weak = 1;
2543 break;
2544 case TOK_UNUSED1:
2545 case TOK_UNUSED2:
2546 /* currently, no need to handle it because tcc does not
2547 track unused objects */
2548 break;
2549 case TOK_NORETURN1:
2550 case TOK_NORETURN2:
2551 /* currently, no need to handle it because tcc does not
2552 track unused objects */
2553 break;
2554 case TOK_CDECL1:
2555 case TOK_CDECL2:
2556 case TOK_CDECL3:
2557 ad->func_call = FUNC_CDECL;
2558 break;
2559 case TOK_STDCALL1:
2560 case TOK_STDCALL2:
2561 case TOK_STDCALL3:
2562 ad->func_call = FUNC_STDCALL;
2563 break;
2564 #ifdef TCC_TARGET_I386
2565 case TOK_REGPARM1:
2566 case TOK_REGPARM2:
2567 skip('(');
2568 n = expr_const();
2569 if (n > 3)
2570 n = 3;
2571 else if (n < 0)
2572 n = 0;
2573 if (n > 0)
2574 ad->func_call = FUNC_FASTCALL1 + n - 1;
2575 skip(')');
2576 break;
2577 case TOK_FASTCALL1:
2578 case TOK_FASTCALL2:
2579 case TOK_FASTCALL3:
2580 ad->func_call = FUNC_FASTCALLW;
2581 break;
2582 #endif
2583 case TOK_MODE:
2584 skip('(');
2585 switch(tok) {
2586 case TOK_MODE_DI:
2587 ad->mode = VT_LLONG + 1;
2588 break;
2589 case TOK_MODE_HI:
2590 ad->mode = VT_SHORT + 1;
2591 break;
2592 case TOK_MODE_SI:
2593 ad->mode = VT_INT + 1;
2594 break;
2595 default:
2596 warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2597 break;
2599 next();
2600 skip(')');
2601 break;
2602 case TOK_DLLEXPORT:
2603 ad->func_export = 1;
2604 break;
2605 case TOK_DLLIMPORT:
2606 ad->func_import = 1;
2607 break;
2608 default:
2609 if (tcc_state->warn_unsupported)
2610 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2611 /* skip parameters */
2612 if (tok == '(') {
2613 int parenthesis = 0;
2614 do {
2615 if (tok == '(')
2616 parenthesis++;
2617 else if (tok == ')')
2618 parenthesis--;
2619 next();
2620 } while (parenthesis && tok != -1);
2622 break;
2624 if (tok != ',')
2625 break;
2626 next();
2628 skip(')');
2629 skip(')');
2633 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2634 static void struct_decl(CType *type, int u)
2636 int a, v, size, align, maxalign, c, offset;
2637 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2638 Sym *s, *ss, *ass, **ps;
2639 AttributeDef ad;
2640 CType type1, btype;
2642 a = tok; /* save decl type */
2643 next();
2644 if (tok != '{') {
2645 v = tok;
2646 next();
2647 /* struct already defined ? return it */
2648 if (v < TOK_IDENT)
2649 expect("struct/union/enum name");
2650 s = struct_find(v);
2651 if (s) {
2652 if (s->type.t != a)
2653 error("invalid type");
2654 goto do_decl;
2656 } else {
2657 v = anon_sym++;
2659 type1.t = a;
2660 /* we put an undefined size for struct/union */
2661 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2662 s->r = 0; /* default alignment is zero as gcc */
2663 /* put struct/union/enum name in type */
2664 do_decl:
2665 type->t = u;
2666 type->ref = s;
2668 if (tok == '{') {
2669 next();
2670 if (s->c != -1)
2671 error("struct/union/enum already defined");
2672 /* cannot be empty */
2673 c = 0;
2674 /* non empty enums are not allowed */
2675 if (a == TOK_ENUM) {
2676 for(;;) {
2677 v = tok;
2678 if (v < TOK_UIDENT)
2679 expect("identifier");
2680 next();
2681 if (tok == '=') {
2682 next();
2683 c = expr_const();
2685 /* enum symbols have static storage */
2686 ss = sym_push(v, &int_type, VT_CONST, c);
2687 ss->type.t |= VT_STATIC;
2688 if (tok != ',')
2689 break;
2690 next();
2691 c++;
2692 /* NOTE: we accept a trailing comma */
2693 if (tok == '}')
2694 break;
2696 skip('}');
2697 } else {
2698 maxalign = 1;
2699 ps = &s->next;
2700 prevbt = VT_INT;
2701 bit_pos = 0;
2702 offset = 0;
2703 while (tok != '}') {
2704 parse_btype(&btype, &ad);
2705 while (1) {
2706 bit_size = -1;
2707 v = 0;
2708 type1 = btype;
2709 if (tok != ':') {
2710 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2711 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2712 expect("identifier");
2713 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2714 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2715 error("invalid type for '%s'",
2716 get_tok_str(v, NULL));
2718 if (tok == ':') {
2719 next();
2720 bit_size = expr_const();
2721 /* XXX: handle v = 0 case for messages */
2722 if (bit_size < 0)
2723 error("negative width in bit-field '%s'",
2724 get_tok_str(v, NULL));
2725 if (v && bit_size == 0)
2726 error("zero width for bit-field '%s'",
2727 get_tok_str(v, NULL));
2729 size = type_size(&type1, &align);
2730 if (ad.aligned) {
2731 if (align < ad.aligned)
2732 align = ad.aligned;
2733 } else if (ad.packed) {
2734 align = 1;
2735 } else if (*tcc_state->pack_stack_ptr) {
2736 if (align > *tcc_state->pack_stack_ptr)
2737 align = *tcc_state->pack_stack_ptr;
2739 lbit_pos = 0;
2740 if (bit_size >= 0) {
2741 bt = type1.t & VT_BTYPE;
2742 if (bt != VT_INT &&
2743 bt != VT_BYTE &&
2744 bt != VT_SHORT &&
2745 bt != VT_BOOL &&
2746 bt != VT_ENUM &&
2747 bt != VT_LLONG)
2748 error("bitfields must have scalar type");
2749 bsize = size * 8;
2750 if (bit_size > bsize) {
2751 error("width of '%s' exceeds its type",
2752 get_tok_str(v, NULL));
2753 } else if (bit_size == bsize) {
2754 /* no need for bit fields */
2755 bit_pos = 0;
2756 } else if (bit_size == 0) {
2757 /* XXX: what to do if only padding in a
2758 structure ? */
2759 /* zero size: means to pad */
2760 bit_pos = 0;
2761 } else {
2762 /* we do not have enough room ?
2763 did the type change?
2764 is it a union? */
2765 if ((bit_pos + bit_size) > bsize ||
2766 bt != prevbt || a == TOK_UNION)
2767 bit_pos = 0;
2768 lbit_pos = bit_pos;
2769 /* XXX: handle LSB first */
2770 type1.t |= VT_BITFIELD |
2771 (bit_pos << VT_STRUCT_SHIFT) |
2772 (bit_size << (VT_STRUCT_SHIFT + 6));
2773 bit_pos += bit_size;
2775 prevbt = bt;
2776 } else {
2777 bit_pos = 0;
2779 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2780 /* add new memory data only if starting
2781 bit field */
2782 if (lbit_pos == 0) {
2783 if (a == TOK_STRUCT) {
2784 c = (c + align - 1) & -align;
2785 offset = c;
2786 if (size > 0)
2787 c += size;
2788 } else {
2789 offset = 0;
2790 if (size > c)
2791 c = size;
2793 if (align > maxalign)
2794 maxalign = align;
2796 #if 0
2797 printf("add field %s offset=%d",
2798 get_tok_str(v, NULL), offset);
2799 if (type1.t & VT_BITFIELD) {
2800 printf(" pos=%d size=%d",
2801 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2802 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2804 printf("\n");
2805 #endif
2807 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2808 ass = type1.ref;
2809 while ((ass = ass->next) != NULL) {
2810 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2811 *ps = ss;
2812 ps = &ss->next;
2814 } else if (v) {
2815 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2816 *ps = ss;
2817 ps = &ss->next;
2819 if (tok == ';' || tok == TOK_EOF)
2820 break;
2821 skip(',');
2823 skip(';');
2825 skip('}');
2826 /* store size and alignment */
2827 s->c = (c + maxalign - 1) & -maxalign;
2828 s->r = maxalign;
2833 /* return 0 if no type declaration. otherwise, return the basic type
2834 and skip it.
2836 static int parse_btype(CType *type, AttributeDef *ad)
2838 int t, u, type_found, typespec_found, typedef_found;
2839 Sym *s;
2840 CType type1;
2842 memset(ad, 0, sizeof(AttributeDef));
2843 type_found = 0;
2844 typespec_found = 0;
2845 typedef_found = 0;
2846 t = 0;
2847 while(1) {
2848 switch(tok) {
2849 case TOK_EXTENSION:
2850 /* currently, we really ignore extension */
2851 next();
2852 continue;
2854 /* basic types */
2855 case TOK_CHAR:
2856 u = VT_BYTE;
2857 basic_type:
2858 next();
2859 basic_type1:
2860 if ((t & VT_BTYPE) != 0)
2861 error("too many basic types");
2862 t |= u;
2863 typespec_found = 1;
2864 break;
2865 case TOK_VOID:
2866 u = VT_VOID;
2867 goto basic_type;
2868 case TOK_SHORT:
2869 u = VT_SHORT;
2870 goto basic_type;
2871 case TOK_INT:
2872 next();
2873 typespec_found = 1;
2874 break;
2875 case TOK_LONG:
2876 next();
2877 if ((t & VT_BTYPE) == VT_DOUBLE) {
2878 #ifndef TCC_TARGET_PE
2879 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2880 #endif
2881 } else if ((t & VT_BTYPE) == VT_LONG) {
2882 t = (t & ~VT_BTYPE) | VT_LLONG;
2883 } else {
2884 u = VT_LONG;
2885 goto basic_type1;
2887 break;
2888 case TOK_BOOL:
2889 u = VT_BOOL;
2890 goto basic_type;
2891 case TOK_FLOAT:
2892 u = VT_FLOAT;
2893 goto basic_type;
2894 case TOK_DOUBLE:
2895 next();
2896 if ((t & VT_BTYPE) == VT_LONG) {
2897 #ifdef TCC_TARGET_PE
2898 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2899 #else
2900 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2901 #endif
2902 } else {
2903 u = VT_DOUBLE;
2904 goto basic_type1;
2906 break;
2907 case TOK_ENUM:
2908 struct_decl(&type1, VT_ENUM);
2909 basic_type2:
2910 u = type1.t;
2911 type->ref = type1.ref;
2912 goto basic_type1;
2913 case TOK_STRUCT:
2914 case TOK_UNION:
2915 struct_decl(&type1, VT_STRUCT);
2916 goto basic_type2;
2918 /* type modifiers */
2919 case TOK_CONST1:
2920 case TOK_CONST2:
2921 case TOK_CONST3:
2922 t |= VT_CONSTANT;
2923 next();
2924 break;
2925 case TOK_VOLATILE1:
2926 case TOK_VOLATILE2:
2927 case TOK_VOLATILE3:
2928 t |= VT_VOLATILE;
2929 next();
2930 break;
2931 case TOK_SIGNED1:
2932 case TOK_SIGNED2:
2933 case TOK_SIGNED3:
2934 typespec_found = 1;
2935 t |= VT_SIGNED;
2936 next();
2937 break;
2938 case TOK_REGISTER:
2939 case TOK_AUTO:
2940 case TOK_RESTRICT1:
2941 case TOK_RESTRICT2:
2942 case TOK_RESTRICT3:
2943 next();
2944 break;
2945 case TOK_UNSIGNED:
2946 t |= VT_UNSIGNED;
2947 next();
2948 typespec_found = 1;
2949 break;
2951 /* storage */
2952 case TOK_EXTERN:
2953 t |= VT_EXTERN;
2954 next();
2955 break;
2956 case TOK_STATIC:
2957 t |= VT_STATIC;
2958 next();
2959 break;
2960 case TOK_TYPEDEF:
2961 t |= VT_TYPEDEF;
2962 next();
2963 break;
2964 case TOK_INLINE1:
2965 case TOK_INLINE2:
2966 case TOK_INLINE3:
2967 t |= VT_INLINE;
2968 next();
2969 break;
2971 /* GNUC attribute */
2972 case TOK_ATTRIBUTE1:
2973 case TOK_ATTRIBUTE2:
2974 parse_attribute(ad);
2975 if (ad->weak) {
2976 t |= VT_WEAK;
2978 if (ad->mode) {
2979 u = ad->mode -1;
2980 t = (t & ~VT_BTYPE) | u;
2982 break;
2983 /* GNUC typeof */
2984 case TOK_TYPEOF1:
2985 case TOK_TYPEOF2:
2986 case TOK_TYPEOF3:
2987 next();
2988 parse_expr_type(&type1);
2989 goto basic_type2;
2990 default:
2991 if (typespec_found || typedef_found)
2992 goto the_end;
2993 s = sym_find(tok);
2994 if (!s || !(s->type.t & VT_TYPEDEF))
2995 goto the_end;
2996 typedef_found = 1;
2997 t |= (s->type.t & ~VT_TYPEDEF);
2998 type->ref = s->type.ref;
2999 if (s->r) {
3000 /* get attributes from typedef */
3001 if (0 == ad->aligned)
3002 ad->aligned = FUNC_ALIGN(s->r);
3003 if (0 == ad->func_call)
3004 ad->func_call = FUNC_CALL(s->r);
3005 ad->packed |= FUNC_PACKED(s->r);
3007 next();
3008 typespec_found = 1;
3009 break;
3011 type_found = 1;
3013 the_end:
3014 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3015 error("signed and unsigned modifier");
3016 if (tcc_state->char_is_unsigned) {
3017 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3018 t |= VT_UNSIGNED;
3020 t &= ~VT_SIGNED;
3022 /* long is never used as type */
3023 if ((t & VT_BTYPE) == VT_LONG)
3024 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3025 t = (t & ~VT_BTYPE) | VT_INT;
3026 #else
3027 t = (t & ~VT_BTYPE) | VT_LLONG;
3028 #endif
3029 type->t = t;
3030 return type_found;
3033 /* convert a function parameter type (array to pointer and function to
3034 function pointer) */
3035 static inline void convert_parameter_type(CType *pt)
3037 /* remove const and volatile qualifiers (XXX: const could be used
3038 to indicate a const function parameter */
3039 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3040 /* array must be transformed to pointer according to ANSI C */
3041 pt->t &= ~VT_ARRAY;
3042 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3043 mk_pointer(pt);
3047 ST_FUNC void parse_asm_str(CString *astr)
3049 skip('(');
3050 /* read the string */
3051 if (tok != TOK_STR)
3052 expect("string constant");
3053 cstr_new(astr);
3054 while (tok == TOK_STR) {
3055 /* XXX: add \0 handling too ? */
3056 cstr_cat(astr, tokc.cstr->data);
3057 next();
3059 cstr_ccat(astr, '\0');
3062 /* Parse an asm label and return the label
3063 * Don't forget to free the CString in the caller! */
3064 static void asm_label_instr(CString *astr)
3066 next();
3067 parse_asm_str(astr);
3068 skip(')');
3069 #ifdef ASM_DEBUG
3070 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3071 #endif
3074 static void post_type(CType *type, AttributeDef *ad)
3076 int n, l, t1, arg_size, align;
3077 Sym **plast, *s, *first;
3078 AttributeDef ad1;
3079 CType pt;
3081 if (tok == '(') {
3082 TokenSym *ts = NULL;
3084 /* function declaration */
3085 next();
3086 l = 0;
3087 first = NULL;
3088 plast = &first;
3089 arg_size = 0;
3090 if (tok != ')') {
3091 for(;;) {
3092 /* read param name and compute offset */
3093 if (l != FUNC_OLD) {
3094 if (!parse_btype(&pt, &ad1)) {
3095 if (l) {
3096 error("invalid type");
3097 } else {
3098 l = FUNC_OLD;
3099 goto old_proto;
3102 l = FUNC_NEW;
3103 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3104 break;
3105 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3106 if ((pt.t & VT_BTYPE) == VT_VOID)
3107 error("parameter declared as void");
3108 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3109 } else {
3110 old_proto:
3111 n = tok;
3112 if (n < TOK_UIDENT)
3113 expect("identifier");
3114 pt.t = VT_INT;
3115 next();
3117 convert_parameter_type(&pt);
3118 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3119 *plast = s;
3120 plast = &s->next;
3121 if (tok == ')')
3122 break;
3123 skip(',');
3124 if (l == FUNC_NEW && tok == TOK_DOTS) {
3125 l = FUNC_ELLIPSIS;
3126 next();
3127 break;
3131 /* if no parameters, then old type prototype */
3132 if (l == 0)
3133 l = FUNC_OLD;
3134 skip(')');
3135 t1 = type->t & VT_STORAGE;
3136 /* NOTE: const is ignored in returned type as it has a special
3137 meaning in gcc / C++ */
3138 type->t &= ~(VT_STORAGE | VT_CONSTANT);
3139 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
3140 CString astr;
3142 asm_label_instr(&astr);
3143 ts = tok_alloc(astr.data, strlen(astr.data));
3144 cstr_free(&astr);
3146 post_type(type, ad);
3147 /* we push a anonymous symbol which will contain the function prototype */
3148 ad->func_args = arg_size;
3149 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3150 if (ts != NULL)
3151 s->a = ts->tok;
3152 s->next = first;
3153 type->t = t1 | VT_FUNC;
3154 type->ref = s;
3155 } else if (tok == '[') {
3156 SValue *last_vtop = NULL;
3158 /* array definition */
3159 next();
3160 if (tok == TOK_RESTRICT1)
3161 next();
3162 n = -1;
3163 if (tok != ']') {
3164 gexpr();
3165 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3166 n = vtop->c.i;
3167 last_vtop = vtop;
3168 if (n < 0)
3169 error("invalid array size");
3170 } else {
3171 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3172 error("size of variable length array should be an integer");
3173 type->t |= VT_VLA;
3174 last_vtop = vtop;
3177 skip(']');
3178 /* parse next post type */
3179 t1 = type->t & (VT_STORAGE|VT_VLA);
3180 type->t &= ~(VT_STORAGE|VT_VLA);
3181 post_type(type, ad);
3182 t1 |= type->t & VT_VLA;
3184 /* we push an anonymous symbol which will contain the array
3185 element type */
3186 s = sym_push(SYM_FIELD, type, 0, n);
3187 if (t1 & VT_VLA) {
3188 s->s = last_vtop; // That's ok, we don't need n with VLA
3189 } else {
3190 if (n >= 0)
3191 vpop();
3193 type->t = t1 | VT_ARRAY | VT_PTR;
3194 type->ref = s;
3198 /* Parse a type declaration (except basic type), and return the type
3199 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3200 expected. 'type' should contain the basic type. 'ad' is the
3201 attribute definition of the basic type. It can be modified by
3202 type_decl().
3204 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3206 Sym *s;
3207 CType type1, *type2;
3208 int qualifiers;
3210 while (tok == '*') {
3211 qualifiers = 0;
3212 redo:
3213 next();
3214 switch(tok) {
3215 case TOK_CONST1:
3216 case TOK_CONST2:
3217 case TOK_CONST3:
3218 qualifiers |= VT_CONSTANT;
3219 goto redo;
3220 case TOK_VOLATILE1:
3221 case TOK_VOLATILE2:
3222 case TOK_VOLATILE3:
3223 qualifiers |= VT_VOLATILE;
3224 goto redo;
3225 case TOK_RESTRICT1:
3226 case TOK_RESTRICT2:
3227 case TOK_RESTRICT3:
3228 goto redo;
3230 mk_pointer(type);
3231 type->t |= qualifiers;
3234 /* XXX: clarify attribute handling */
3235 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3236 parse_attribute(ad);
3238 /* recursive type */
3239 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3240 type1.t = 0; /* XXX: same as int */
3241 if (tok == '(') {
3242 next();
3243 /* XXX: this is not correct to modify 'ad' at this point, but
3244 the syntax is not clear */
3245 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3246 parse_attribute(ad);
3247 type_decl(&type1, ad, v, td);
3248 skip(')');
3249 } else {
3250 /* type identifier */
3251 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3252 *v = tok;
3253 next();
3254 } else {
3255 if (!(td & TYPE_ABSTRACT))
3256 expect("identifier");
3257 *v = 0;
3260 post_type(type, ad);
3261 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3262 parse_attribute(ad);
3264 if (ad->weak)
3265 type->t |= VT_WEAK;
3267 if (!type1.t)
3268 return;
3269 /* append type at the end of type1 */
3270 type2 = &type1;
3271 for(;;) {
3272 s = type2->ref;
3273 type2 = &s->type;
3274 if (!type2->t) {
3275 *type2 = *type;
3276 break;
3279 *type = type1;
3282 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3283 ST_FUNC int lvalue_type(int t)
3285 int bt, r;
3286 r = VT_LVAL;
3287 bt = t & VT_BTYPE;
3288 if (bt == VT_BYTE || bt == VT_BOOL)
3289 r |= VT_LVAL_BYTE;
3290 else if (bt == VT_SHORT)
3291 r |= VT_LVAL_SHORT;
3292 else
3293 return r;
3294 if (t & VT_UNSIGNED)
3295 r |= VT_LVAL_UNSIGNED;
3296 return r;
3299 /* indirection with full error checking and bound check */
3300 ST_FUNC void indir(void)
3302 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3303 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3304 return;
3305 expect("pointer");
3307 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3308 gv(RC_INT);
3309 vtop->type = *pointed_type(&vtop->type);
3310 /* Arrays and functions are never lvalues */
3311 if (!(vtop->type.t & VT_ARRAY)
3312 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3313 vtop->r |= lvalue_type(vtop->type.t);
3314 /* if bound checking, the referenced pointer must be checked */
3315 #ifdef CONFIG_TCC_BCHECK
3316 if (tcc_state->do_bounds_check)
3317 vtop->r |= VT_MUSTBOUND;
3318 #endif
3322 /* pass a parameter to a function and do type checking and casting */
3323 static void gfunc_param_typed(Sym *func, Sym *arg)
3325 int func_type;
3326 CType type;
3328 func_type = func->c;
3329 if (func_type == FUNC_OLD ||
3330 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3331 /* default casting : only need to convert float to double */
3332 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3333 type.t = VT_DOUBLE;
3334 gen_cast(&type);
3336 } else if (arg == NULL) {
3337 error("too many arguments to function");
3338 } else {
3339 type = arg->type;
3340 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3341 gen_assign_cast(&type);
3345 /* parse an expression of the form '(type)' or '(expr)' and return its
3346 type */
3347 static void parse_expr_type(CType *type)
3349 int n;
3350 AttributeDef ad;
3352 skip('(');
3353 if (parse_btype(type, &ad)) {
3354 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3355 } else {
3356 expr_type(type);
3358 skip(')');
3361 static void parse_type(CType *type)
3363 AttributeDef ad;
3364 int n;
3366 if (!parse_btype(type, &ad)) {
3367 expect("type");
3369 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3372 static void vpush_tokc(int t)
3374 CType type;
3375 type.t = t;
3376 type.ref = 0;
3377 vsetc(&type, VT_CONST, &tokc);
3380 ST_FUNC void unary(void)
3382 int n, t, align, size, r, sizeof_caller;
3383 CType type;
3384 Sym *s;
3385 AttributeDef ad;
3386 static int in_sizeof = 0;
3388 sizeof_caller = in_sizeof;
3389 in_sizeof = 0;
3390 /* XXX: GCC 2.95.3 does not generate a table although it should be
3391 better here */
3392 tok_next:
3393 switch(tok) {
3394 case TOK_EXTENSION:
3395 next();
3396 goto tok_next;
3397 case TOK_CINT:
3398 case TOK_CCHAR:
3399 case TOK_LCHAR:
3400 vpushi(tokc.i);
3401 next();
3402 break;
3403 case TOK_CUINT:
3404 vpush_tokc(VT_INT | VT_UNSIGNED);
3405 next();
3406 break;
3407 case TOK_CLLONG:
3408 vpush_tokc(VT_LLONG);
3409 next();
3410 break;
3411 case TOK_CULLONG:
3412 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3413 next();
3414 break;
3415 case TOK_CFLOAT:
3416 vpush_tokc(VT_FLOAT);
3417 next();
3418 break;
3419 case TOK_CDOUBLE:
3420 vpush_tokc(VT_DOUBLE);
3421 next();
3422 break;
3423 case TOK_CLDOUBLE:
3424 vpush_tokc(VT_LDOUBLE);
3425 next();
3426 break;
3427 case TOK___FUNCTION__:
3428 if (!gnu_ext)
3429 goto tok_identifier;
3430 /* fall thru */
3431 case TOK___FUNC__:
3433 void *ptr;
3434 int len;
3435 /* special function name identifier */
3436 len = strlen(funcname) + 1;
3437 /* generate char[len] type */
3438 type.t = VT_BYTE;
3439 mk_pointer(&type);
3440 type.t |= VT_ARRAY;
3441 type.ref->c = len;
3442 vpush_ref(&type, data_section, data_section->data_offset, len);
3443 ptr = section_ptr_add(data_section, len);
3444 memcpy(ptr, funcname, len);
3445 next();
3447 break;
3448 case TOK_LSTR:
3449 #ifdef TCC_TARGET_PE
3450 t = VT_SHORT | VT_UNSIGNED;
3451 #else
3452 t = VT_INT;
3453 #endif
3454 goto str_init;
3455 case TOK_STR:
3456 /* string parsing */
3457 t = VT_BYTE;
3458 str_init:
3459 if (tcc_state->warn_write_strings)
3460 t |= VT_CONSTANT;
3461 type.t = t;
3462 mk_pointer(&type);
3463 type.t |= VT_ARRAY;
3464 memset(&ad, 0, sizeof(AttributeDef));
3465 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3466 break;
3467 case '(':
3468 next();
3469 /* cast ? */
3470 if (parse_btype(&type, &ad)) {
3471 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3472 skip(')');
3473 /* check ISOC99 compound literal */
3474 if (tok == '{') {
3475 /* data is allocated locally by default */
3476 if (global_expr)
3477 r = VT_CONST;
3478 else
3479 r = VT_LOCAL;
3480 /* all except arrays are lvalues */
3481 if (!(type.t & VT_ARRAY))
3482 r |= lvalue_type(type.t);
3483 memset(&ad, 0, sizeof(AttributeDef));
3484 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3485 } else {
3486 if (sizeof_caller) {
3487 vpush(&type);
3488 return;
3490 unary();
3491 gen_cast(&type);
3493 } else if (tok == '{') {
3494 /* save all registers */
3495 save_regs(0);
3496 /* statement expression : we do not accept break/continue
3497 inside as GCC does */
3498 block(NULL, NULL, NULL, NULL, 0, 1);
3499 skip(')');
3500 } else {
3501 gexpr();
3502 skip(')');
3504 break;
3505 case '*':
3506 next();
3507 unary();
3508 indir();
3509 break;
3510 case '&':
3511 next();
3512 unary();
3513 /* functions names must be treated as function pointers,
3514 except for unary '&' and sizeof. Since we consider that
3515 functions are not lvalues, we only have to handle it
3516 there and in function calls. */
3517 /* arrays can also be used although they are not lvalues */
3518 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3519 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3520 test_lvalue();
3521 mk_pointer(&vtop->type);
3522 gaddrof();
3523 break;
3524 case '!':
3525 next();
3526 unary();
3527 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3528 CType boolean;
3529 boolean.t = VT_BOOL;
3530 gen_cast(&boolean);
3531 vtop->c.i = !vtop->c.i;
3532 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3533 vtop->c.i = vtop->c.i ^ 1;
3534 else {
3535 save_regs(1);
3536 vseti(VT_JMP, gtst(1, 0));
3538 break;
3539 case '~':
3540 next();
3541 unary();
3542 vpushi(-1);
3543 gen_op('^');
3544 break;
3545 case '+':
3546 next();
3547 /* in order to force cast, we add zero */
3548 unary();
3549 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3550 error("pointer not accepted for unary plus");
3551 vpushi(0);
3552 gen_op('+');
3553 break;
3554 case TOK_SIZEOF:
3555 case TOK_ALIGNOF1:
3556 case TOK_ALIGNOF2:
3557 t = tok;
3558 next();
3559 in_sizeof++;
3560 unary_type(&type); // Perform a in_sizeof = 0;
3561 if ((t == TOK_SIZEOF) && (type.t & VT_VLA)) {
3562 vla_runtime_type_size(&type, &align);
3563 size = 0;
3564 } else {
3565 size = type_size(&type, &align);
3567 if (t == TOK_SIZEOF) {
3568 if (!(type.t & VT_VLA)) {
3569 if (size < 0)
3570 error("sizeof applied to an incomplete type");
3571 vpushi(size);
3573 } else {
3574 vpushi(align);
3576 vtop->type.t |= VT_UNSIGNED;
3577 break;
3579 case TOK_builtin_types_compatible_p:
3581 CType type1, type2;
3582 next();
3583 skip('(');
3584 parse_type(&type1);
3585 skip(',');
3586 parse_type(&type2);
3587 skip(')');
3588 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3589 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3590 vpushi(is_compatible_types(&type1, &type2));
3592 break;
3593 case TOK_builtin_constant_p:
3595 int saved_nocode_wanted, res;
3596 next();
3597 skip('(');
3598 saved_nocode_wanted = nocode_wanted;
3599 nocode_wanted = 1;
3600 gexpr();
3601 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3602 vpop();
3603 nocode_wanted = saved_nocode_wanted;
3604 skip(')');
3605 vpushi(res);
3607 break;
3608 case TOK_builtin_frame_address:
3610 CType type;
3611 next();
3612 skip('(');
3613 if (tok != TOK_CINT) {
3614 error("__builtin_frame_address only takes integers");
3616 if (tokc.i != 0) {
3617 error("TCC only supports __builtin_frame_address(0)");
3619 next();
3620 skip(')');
3621 type.t = VT_VOID;
3622 mk_pointer(&type);
3623 vset(&type, VT_LOCAL, 0);
3625 break;
3626 #ifdef TCC_TARGET_X86_64
3627 case TOK_builtin_va_arg_types:
3629 /* This definition must be synced with stdarg.h */
3630 enum __va_arg_type {
3631 __va_gen_reg, __va_float_reg, __va_stack
3633 CType type;
3634 int bt;
3635 next();
3636 skip('(');
3637 parse_type(&type);
3638 skip(')');
3639 bt = type.t & VT_BTYPE;
3640 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3641 vpushi(__va_stack);
3642 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3643 vpushi(__va_float_reg);
3644 } else {
3645 vpushi(__va_gen_reg);
3648 break;
3649 #endif
3650 case TOK_INC:
3651 case TOK_DEC:
3652 t = tok;
3653 next();
3654 unary();
3655 inc(0, t);
3656 break;
3657 case '-':
3658 next();
3659 vpushi(0);
3660 unary();
3661 gen_op('-');
3662 break;
3663 case TOK_LAND:
3664 if (!gnu_ext)
3665 goto tok_identifier;
3666 next();
3667 /* allow to take the address of a label */
3668 if (tok < TOK_UIDENT)
3669 expect("label identifier");
3670 s = label_find(tok);
3671 if (!s) {
3672 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3673 } else {
3674 if (s->r == LABEL_DECLARED)
3675 s->r = LABEL_FORWARD;
3677 if (!s->type.t) {
3678 s->type.t = VT_VOID;
3679 mk_pointer(&s->type);
3680 s->type.t |= VT_STATIC;
3682 vset(&s->type, VT_CONST | VT_SYM, 0);
3683 vtop->sym = s;
3684 next();
3685 break;
3687 // special qnan , snan and infinity values
3688 case TOK___NAN__:
3689 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3690 next();
3691 break;
3692 case TOK___SNAN__:
3693 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3694 next();
3695 break;
3696 case TOK___INF__:
3697 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3698 next();
3699 break;
3701 default:
3702 tok_identifier:
3703 t = tok;
3704 next();
3705 if (t < TOK_UIDENT)
3706 expect("identifier");
3707 s = sym_find(t);
3708 if (!s) {
3709 if (tok != '(')
3710 error("'%s' undeclared", get_tok_str(t, NULL));
3711 /* for simple function calls, we tolerate undeclared
3712 external reference to int() function */
3713 if (tcc_state->warn_implicit_function_declaration)
3714 warning("implicit declaration of function '%s'",
3715 get_tok_str(t, NULL));
3716 s = external_global_sym(t, &func_old_type, 0);
3718 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3719 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3720 /* if referencing an inline function, then we generate a
3721 symbol to it if not already done. It will have the
3722 effect to generate code for it at the end of the
3723 compilation unit. Inline function as always
3724 generated in the text section. */
3725 if (!s->c)
3726 put_extern_sym(s, text_section, 0, 0);
3727 r = VT_SYM | VT_CONST;
3728 } else {
3729 r = s->r;
3731 if (s->type.t & VT_VLA)
3732 vpushv(s->s);
3733 else
3734 vset(&s->type, r, s->c);
3735 /* if forward reference, we must point to s */
3736 if (vtop->r & VT_SYM) {
3737 vtop->sym = s;
3738 vtop->c.ul = 0;
3740 break;
3743 /* post operations */
3744 while (1) {
3745 if (tok == TOK_INC || tok == TOK_DEC) {
3746 inc(1, tok);
3747 next();
3748 } else if (tok == '.' || tok == TOK_ARROW) {
3749 int qualifiers;
3750 /* field */
3751 if (tok == TOK_ARROW)
3752 indir();
3753 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3754 test_lvalue();
3755 gaddrof();
3756 next();
3757 /* expect pointer on structure */
3758 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3759 expect("struct or union");
3760 s = vtop->type.ref;
3761 /* find field */
3762 tok |= SYM_FIELD;
3763 while ((s = s->next) != NULL) {
3764 if (s->v == tok)
3765 break;
3767 if (!s)
3768 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3769 /* add field offset to pointer */
3770 vtop->type = char_pointer_type; /* change type to 'char *' */
3771 vpushi(s->c);
3772 gen_op('+');
3773 /* change type to field type, and set to lvalue */
3774 vtop->type = s->type;
3775 vtop->type.t |= qualifiers;
3776 /* an array is never an lvalue */
3777 if (!(vtop->type.t & VT_ARRAY)) {
3778 vtop->r |= lvalue_type(vtop->type.t);
3779 #ifdef CONFIG_TCC_BCHECK
3780 /* if bound checking, the referenced pointer must be checked */
3781 if (tcc_state->do_bounds_check)
3782 vtop->r |= VT_MUSTBOUND;
3783 #endif
3785 next();
3786 } else if (tok == '[') {
3787 next();
3788 gexpr();
3789 gen_op('+');
3790 indir();
3791 skip(']');
3792 } else if (tok == '(') {
3793 SValue ret;
3794 Sym *sa;
3795 int nb_args;
3797 /* function call */
3798 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3799 /* pointer test (no array accepted) */
3800 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3801 vtop->type = *pointed_type(&vtop->type);
3802 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3803 goto error_func;
3804 } else {
3805 error_func:
3806 expect("function pointer");
3808 } else {
3809 vtop->r &= ~VT_LVAL; /* no lvalue */
3811 /* get return type */
3812 s = vtop->type.ref;
3813 next();
3814 sa = s->next; /* first parameter */
3815 nb_args = 0;
3816 ret.r2 = VT_CONST;
3817 /* compute first implicit argument if a structure is returned */
3818 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3819 /* get some space for the returned structure */
3820 size = type_size(&s->type, &align);
3821 loc = (loc - size) & -align;
3822 ret.type = s->type;
3823 ret.r = VT_LOCAL | VT_LVAL;
3824 /* pass it as 'int' to avoid structure arg passing
3825 problems */
3826 vseti(VT_LOCAL, loc);
3827 ret.c = vtop->c;
3828 nb_args++;
3829 } else {
3830 ret.type = s->type;
3831 /* return in register */
3832 if (is_float(ret.type.t)) {
3833 ret.r = reg_fret(ret.type.t);
3834 } else {
3835 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3836 ret.r2 = REG_LRET;
3837 ret.r = REG_IRET;
3839 ret.c.i = 0;
3841 if (tok != ')') {
3842 for(;;) {
3843 expr_eq();
3844 gfunc_param_typed(s, sa);
3845 nb_args++;
3846 if (sa)
3847 sa = sa->next;
3848 if (tok == ')')
3849 break;
3850 skip(',');
3853 if (sa)
3854 error("too few arguments to function");
3855 skip(')');
3856 if (!nocode_wanted) {
3857 gfunc_call(nb_args);
3858 } else {
3859 vtop -= (nb_args + 1);
3861 /* return value */
3862 vsetc(&ret.type, ret.r, &ret.c);
3863 vtop->r2 = ret.r2;
3864 } else {
3865 break;
3870 ST_FUNC void expr_prod(void)
3872 int t;
3874 unary();
3875 while (tok == '*' || tok == '/' || tok == '%') {
3876 t = tok;
3877 next();
3878 unary();
3879 gen_op(t);
3883 ST_FUNC void expr_sum(void)
3885 int t;
3887 expr_prod();
3888 while (tok == '+' || tok == '-') {
3889 t = tok;
3890 next();
3891 expr_prod();
3892 gen_op(t);
3896 static void expr_shift(void)
3898 int t;
3900 expr_sum();
3901 while (tok == TOK_SHL || tok == TOK_SAR) {
3902 t = tok;
3903 next();
3904 expr_sum();
3905 gen_op(t);
3909 static void expr_cmp(void)
3911 int t;
3913 expr_shift();
3914 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3915 tok == TOK_ULT || tok == TOK_UGE) {
3916 t = tok;
3917 next();
3918 expr_shift();
3919 gen_op(t);
3923 static void expr_cmpeq(void)
3925 int t;
3927 expr_cmp();
3928 while (tok == TOK_EQ || tok == TOK_NE) {
3929 t = tok;
3930 next();
3931 expr_cmp();
3932 gen_op(t);
3936 static void expr_and(void)
3938 expr_cmpeq();
3939 while (tok == '&') {
3940 next();
3941 expr_cmpeq();
3942 gen_op('&');
3946 static void expr_xor(void)
3948 expr_and();
3949 while (tok == '^') {
3950 next();
3951 expr_and();
3952 gen_op('^');
3956 static void expr_or(void)
3958 expr_xor();
3959 while (tok == '|') {
3960 next();
3961 expr_xor();
3962 gen_op('|');
3966 /* XXX: fix this mess */
3967 static void expr_land_const(void)
3969 expr_or();
3970 while (tok == TOK_LAND) {
3971 next();
3972 expr_or();
3973 gen_op(TOK_LAND);
3977 /* XXX: fix this mess */
3978 static void expr_lor_const(void)
3980 expr_land_const();
3981 while (tok == TOK_LOR) {
3982 next();
3983 expr_land_const();
3984 gen_op(TOK_LOR);
3988 /* only used if non constant */
3989 static void expr_land(void)
3991 int t;
3993 expr_or();
3994 if (tok == TOK_LAND) {
3995 t = 0;
3996 save_regs(1);
3997 for(;;) {
3998 t = gtst(1, t);
3999 if (tok != TOK_LAND) {
4000 vseti(VT_JMPI, t);
4001 break;
4003 next();
4004 expr_or();
4009 static void expr_lor(void)
4011 int t;
4013 expr_land();
4014 if (tok == TOK_LOR) {
4015 t = 0;
4016 save_regs(1);
4017 for(;;) {
4018 t = gtst(0, t);
4019 if (tok != TOK_LOR) {
4020 vseti(VT_JMP, t);
4021 break;
4023 next();
4024 expr_land();
4029 /* XXX: better constant handling */
4030 static void expr_cond(void)
4032 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4033 SValue sv;
4034 CType type, type1, type2;
4036 if (const_wanted) {
4037 expr_lor_const();
4038 if (tok == '?') {
4039 CType boolean;
4040 int c;
4041 boolean.t = VT_BOOL;
4042 vdup();
4043 gen_cast(&boolean);
4044 c = vtop->c.i;
4045 vpop();
4046 next();
4047 if (tok != ':' || !gnu_ext) {
4048 vpop();
4049 gexpr();
4051 if (!c)
4052 vpop();
4053 skip(':');
4054 expr_cond();
4055 if (c)
4056 vpop();
4058 } else {
4059 expr_lor();
4060 if (tok == '?') {
4061 next();
4062 if (vtop != vstack) {
4063 /* needed to avoid having different registers saved in
4064 each branch */
4065 if (is_float(vtop->type.t)) {
4066 rc = RC_FLOAT;
4067 #ifdef TCC_TARGET_X86_64
4068 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4069 rc = RC_ST0;
4071 #endif
4073 else
4074 rc = RC_INT;
4075 gv(rc);
4076 save_regs(1);
4078 if (tok == ':' && gnu_ext) {
4079 gv_dup();
4080 tt = gtst(1, 0);
4081 } else {
4082 tt = gtst(1, 0);
4083 gexpr();
4085 type1 = vtop->type;
4086 sv = *vtop; /* save value to handle it later */
4087 vtop--; /* no vpop so that FP stack is not flushed */
4088 skip(':');
4089 u = gjmp(0);
4090 gsym(tt);
4091 expr_cond();
4092 type2 = vtop->type;
4094 t1 = type1.t;
4095 bt1 = t1 & VT_BTYPE;
4096 t2 = type2.t;
4097 bt2 = t2 & VT_BTYPE;
4098 /* cast operands to correct type according to ISOC rules */
4099 if (is_float(bt1) || is_float(bt2)) {
4100 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4101 type.t = VT_LDOUBLE;
4102 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4103 type.t = VT_DOUBLE;
4104 } else {
4105 type.t = VT_FLOAT;
4107 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4108 /* cast to biggest op */
4109 type.t = VT_LLONG;
4110 /* convert to unsigned if it does not fit in a long long */
4111 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4112 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4113 type.t |= VT_UNSIGNED;
4114 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4115 /* XXX: test pointer compatibility */
4116 type = type1;
4117 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4118 /* XXX: test function pointer compatibility */
4119 type = type1;
4120 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4121 /* XXX: test structure compatibility */
4122 type = type1;
4123 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4124 /* NOTE: as an extension, we accept void on only one side */
4125 type.t = VT_VOID;
4126 } else {
4127 /* integer operations */
4128 type.t = VT_INT;
4129 /* convert to unsigned if it does not fit in an integer */
4130 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4131 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4132 type.t |= VT_UNSIGNED;
4135 /* now we convert second operand */
4136 gen_cast(&type);
4137 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4138 gaddrof();
4139 rc = RC_INT;
4140 if (is_float(type.t)) {
4141 rc = RC_FLOAT;
4142 #ifdef TCC_TARGET_X86_64
4143 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4144 rc = RC_ST0;
4146 #endif
4147 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4148 /* for long longs, we use fixed registers to avoid having
4149 to handle a complicated move */
4150 rc = RC_IRET;
4153 r2 = gv(rc);
4154 /* this is horrible, but we must also convert first
4155 operand */
4156 tt = gjmp(0);
4157 gsym(u);
4158 /* put again first value and cast it */
4159 *vtop = sv;
4160 gen_cast(&type);
4161 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4162 gaddrof();
4163 r1 = gv(rc);
4164 move_reg(r2, r1);
4165 vtop->r = r2;
4166 gsym(tt);
4171 static void expr_eq(void)
4173 int t;
4175 expr_cond();
4176 if (tok == '=' ||
4177 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4178 tok == TOK_A_XOR || tok == TOK_A_OR ||
4179 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4180 test_lvalue();
4181 t = tok;
4182 next();
4183 if (t == '=') {
4184 expr_eq();
4185 } else {
4186 vdup();
4187 expr_eq();
4188 gen_op(t & 0x7f);
4190 vstore();
4194 ST_FUNC void gexpr(void)
4196 while (1) {
4197 expr_eq();
4198 if (tok != ',')
4199 break;
4200 vpop();
4201 next();
4205 /* parse an expression and return its type without any side effect. */
4206 static void expr_type(CType *type)
4208 int saved_nocode_wanted;
4210 saved_nocode_wanted = nocode_wanted;
4211 nocode_wanted = 1;
4212 gexpr();
4213 *type = vtop->type;
4214 vpop();
4215 nocode_wanted = saved_nocode_wanted;
4218 /* parse a unary expression and return its type without any side
4219 effect. */
4220 static void unary_type(CType *type)
4222 int a;
4224 a = nocode_wanted;
4225 nocode_wanted = 1;
4226 unary();
4227 *type = vtop->type;
4228 vpop();
4229 nocode_wanted = a;
4232 /* parse a constant expression and return value in vtop. */
4233 static void expr_const1(void)
4235 int a;
4236 a = const_wanted;
4237 const_wanted = 1;
4238 expr_cond();
4239 const_wanted = a;
4242 /* parse an integer constant and return its value. */
4243 ST_FUNC int expr_const(void)
4245 int c;
4246 expr_const1();
4247 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4248 expect("constant expression");
4249 c = vtop->c.i;
4250 vpop();
4251 return c;
4254 /* return the label token if current token is a label, otherwise
4255 return zero */
4256 static int is_label(void)
4258 int last_tok;
4260 /* fast test first */
4261 if (tok < TOK_UIDENT)
4262 return 0;
4263 /* no need to save tokc because tok is an identifier */
4264 last_tok = tok;
4265 next();
4266 if (tok == ':') {
4267 next();
4268 return last_tok;
4269 } else {
4270 unget_tok(last_tok);
4271 return 0;
4275 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4276 int case_reg, int is_expr)
4278 int a, b, c, d;
4279 Sym *s;
4281 /* generate line number info */
4282 if (tcc_state->do_debug &&
4283 (last_line_num != file->line_num || last_ind != ind)) {
4284 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4285 last_ind = ind;
4286 last_line_num = file->line_num;
4289 if (is_expr) {
4290 /* default return value is (void) */
4291 vpushi(0);
4292 vtop->type.t = VT_VOID;
4295 if (tok == TOK_IF) {
4296 /* if test */
4297 next();
4298 skip('(');
4299 gexpr();
4300 skip(')');
4301 a = gtst(1, 0);
4302 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4303 c = tok;
4304 if (c == TOK_ELSE) {
4305 next();
4306 d = gjmp(0);
4307 gsym(a);
4308 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4309 gsym(d); /* patch else jmp */
4310 } else
4311 gsym(a);
4312 } else if (tok == TOK_WHILE) {
4313 next();
4314 d = ind;
4315 skip('(');
4316 gexpr();
4317 skip(')');
4318 a = gtst(1, 0);
4319 b = 0;
4320 block(&a, &b, case_sym, def_sym, case_reg, 0);
4321 gjmp_addr(d);
4322 gsym(a);
4323 gsym_addr(b, d);
4324 } else if (tok == '{') {
4325 Sym *llabel;
4327 next();
4328 /* record local declaration stack position */
4329 s = local_stack;
4330 llabel = local_label_stack;
4331 /* handle local labels declarations */
4332 if (tok == TOK_LABEL) {
4333 next();
4334 for(;;) {
4335 if (tok < TOK_UIDENT)
4336 expect("label identifier");
4337 label_push(&local_label_stack, tok, LABEL_DECLARED);
4338 next();
4339 if (tok == ',') {
4340 next();
4341 } else {
4342 skip(';');
4343 break;
4347 while (tok != '}') {
4348 decl(VT_LOCAL);
4349 if (tok != '}') {
4350 if (is_expr)
4351 vpop();
4352 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4355 /* pop locally defined labels */
4356 label_pop(&local_label_stack, llabel);
4357 /* pop locally defined symbols */
4358 if(is_expr) {
4359 /* XXX: this solution makes only valgrind happy...
4360 triggered by gcc.c-torture/execute/20000917-1.c */
4361 Sym *p;
4362 switch(vtop->type.t & VT_BTYPE) {
4363 case VT_PTR:
4364 case VT_STRUCT:
4365 case VT_ENUM:
4366 case VT_FUNC:
4367 for(p=vtop->type.ref;p;p=p->prev)
4368 if(p->prev==s)
4369 error("unsupported expression type");
4372 sym_pop(&local_stack, s);
4373 next();
4374 } else if (tok == TOK_RETURN) {
4375 next();
4376 if (tok != ';') {
4377 gexpr();
4378 gen_assign_cast(&func_vt);
4379 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4380 CType type;
4381 /* if returning structure, must copy it to implicit
4382 first pointer arg location */
4383 #ifdef TCC_ARM_EABI
4384 int align, size;
4385 size = type_size(&func_vt,&align);
4386 if(size <= 4)
4388 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4389 && (align & 3))
4391 int addr;
4392 loc = (loc - size) & -4;
4393 addr = loc;
4394 type = func_vt;
4395 vset(&type, VT_LOCAL | VT_LVAL, addr);
4396 vswap();
4397 vstore();
4398 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4400 vtop->type = int_type;
4401 gv(RC_IRET);
4402 } else {
4403 #endif
4404 type = func_vt;
4405 mk_pointer(&type);
4406 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4407 indir();
4408 vswap();
4409 /* copy structure value to pointer */
4410 vstore();
4411 #ifdef TCC_ARM_EABI
4413 #endif
4414 } else if (is_float(func_vt.t)) {
4415 gv(rc_fret(func_vt.t));
4416 } else {
4417 gv(RC_IRET);
4419 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4421 skip(';');
4422 rsym = gjmp(rsym); /* jmp */
4423 } else if (tok == TOK_BREAK) {
4424 /* compute jump */
4425 if (!bsym)
4426 error("cannot break");
4427 *bsym = gjmp(*bsym);
4428 next();
4429 skip(';');
4430 } else if (tok == TOK_CONTINUE) {
4431 /* compute jump */
4432 if (!csym)
4433 error("cannot continue");
4434 *csym = gjmp(*csym);
4435 next();
4436 skip(';');
4437 } else if (tok == TOK_FOR) {
4438 int e;
4439 next();
4440 skip('(');
4441 if (tok != ';') {
4442 gexpr();
4443 vpop();
4445 skip(';');
4446 d = ind;
4447 c = ind;
4448 a = 0;
4449 b = 0;
4450 if (tok != ';') {
4451 gexpr();
4452 a = gtst(1, 0);
4454 skip(';');
4455 if (tok != ')') {
4456 e = gjmp(0);
4457 c = ind;
4458 gexpr();
4459 vpop();
4460 gjmp_addr(d);
4461 gsym(e);
4463 skip(')');
4464 block(&a, &b, case_sym, def_sym, case_reg, 0);
4465 gjmp_addr(c);
4466 gsym(a);
4467 gsym_addr(b, c);
4468 } else
4469 if (tok == TOK_DO) {
4470 next();
4471 a = 0;
4472 b = 0;
4473 d = ind;
4474 block(&a, &b, case_sym, def_sym, case_reg, 0);
4475 skip(TOK_WHILE);
4476 skip('(');
4477 gsym(b);
4478 gexpr();
4479 c = gtst(0, 0);
4480 gsym_addr(c, d);
4481 skip(')');
4482 gsym(a);
4483 skip(';');
4484 } else
4485 if (tok == TOK_SWITCH) {
4486 next();
4487 skip('(');
4488 gexpr();
4489 /* XXX: other types than integer */
4490 case_reg = gv(RC_INT);
4491 vpop();
4492 skip(')');
4493 a = 0;
4494 b = gjmp(0); /* jump to first case */
4495 c = 0;
4496 block(&a, csym, &b, &c, case_reg, 0);
4497 /* if no default, jmp after switch */
4498 if (c == 0)
4499 c = ind;
4500 /* default label */
4501 gsym_addr(b, c);
4502 /* break label */
4503 gsym(a);
4504 } else
4505 if (tok == TOK_CASE) {
4506 int v1, v2;
4507 if (!case_sym)
4508 expect("switch");
4509 next();
4510 v1 = expr_const();
4511 v2 = v1;
4512 if (gnu_ext && tok == TOK_DOTS) {
4513 next();
4514 v2 = expr_const();
4515 if (v2 < v1)
4516 warning("empty case range");
4518 /* since a case is like a label, we must skip it with a jmp */
4519 b = gjmp(0);
4520 gsym(*case_sym);
4521 vseti(case_reg, 0);
4522 vpushi(v1);
4523 if (v1 == v2) {
4524 gen_op(TOK_EQ);
4525 *case_sym = gtst(1, 0);
4526 } else {
4527 gen_op(TOK_GE);
4528 *case_sym = gtst(1, 0);
4529 vseti(case_reg, 0);
4530 vpushi(v2);
4531 gen_op(TOK_LE);
4532 *case_sym = gtst(1, *case_sym);
4534 gsym(b);
4535 skip(':');
4536 is_expr = 0;
4537 goto block_after_label;
4538 } else
4539 if (tok == TOK_DEFAULT) {
4540 next();
4541 skip(':');
4542 if (!def_sym)
4543 expect("switch");
4544 if (*def_sym)
4545 error("too many 'default'");
4546 *def_sym = ind;
4547 is_expr = 0;
4548 goto block_after_label;
4549 } else
4550 if (tok == TOK_GOTO) {
4551 next();
4552 if (tok == '*' && gnu_ext) {
4553 /* computed goto */
4554 next();
4555 gexpr();
4556 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4557 expect("pointer");
4558 ggoto();
4559 } else if (tok >= TOK_UIDENT) {
4560 s = label_find(tok);
4561 /* put forward definition if needed */
4562 if (!s) {
4563 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4564 } else {
4565 if (s->r == LABEL_DECLARED)
4566 s->r = LABEL_FORWARD;
4568 /* label already defined */
4569 if (s->r & LABEL_FORWARD)
4570 s->jnext = gjmp(s->jnext);
4571 else
4572 gjmp_addr(s->jnext);
4573 next();
4574 } else {
4575 expect("label identifier");
4577 skip(';');
4578 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4579 asm_instr();
4580 } else {
4581 b = is_label();
4582 if (b) {
4583 /* label case */
4584 s = label_find(b);
4585 if (s) {
4586 if (s->r == LABEL_DEFINED)
4587 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4588 gsym(s->jnext);
4589 s->r = LABEL_DEFINED;
4590 } else {
4591 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4593 s->jnext = ind;
4594 /* we accept this, but it is a mistake */
4595 block_after_label:
4596 if (tok == '}') {
4597 warning("deprecated use of label at end of compound statement");
4598 } else {
4599 if (is_expr)
4600 vpop();
4601 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4603 } else {
4604 /* expression case */
4605 if (tok != ';') {
4606 if (is_expr) {
4607 vpop();
4608 gexpr();
4609 } else {
4610 gexpr();
4611 vpop();
4614 skip(';');
4619 /* t is the array or struct type. c is the array or struct
4620 address. cur_index/cur_field is the pointer to the current
4621 value. 'size_only' is true if only size info is needed (only used
4622 in arrays) */
4623 static void decl_designator(CType *type, Section *sec, unsigned long c,
4624 int *cur_index, Sym **cur_field,
4625 int size_only)
4627 Sym *s, *f;
4628 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4629 CType type1;
4631 notfirst = 0;
4632 elem_size = 0;
4633 nb_elems = 1;
4634 if (gnu_ext && (l = is_label()) != 0)
4635 goto struct_field;
4636 while (tok == '[' || tok == '.') {
4637 if (tok == '[') {
4638 if (!(type->t & VT_ARRAY))
4639 expect("array type");
4640 s = type->ref;
4641 next();
4642 index = expr_const();
4643 if (index < 0 || (s->c >= 0 && index >= s->c))
4644 expect("invalid index");
4645 if (tok == TOK_DOTS && gnu_ext) {
4646 next();
4647 index_last = expr_const();
4648 if (index_last < 0 ||
4649 (s->c >= 0 && index_last >= s->c) ||
4650 index_last < index)
4651 expect("invalid index");
4652 } else {
4653 index_last = index;
4655 skip(']');
4656 if (!notfirst)
4657 *cur_index = index_last;
4658 type = pointed_type(type);
4659 elem_size = type_size(type, &align);
4660 c += index * elem_size;
4661 /* NOTE: we only support ranges for last designator */
4662 nb_elems = index_last - index + 1;
4663 if (nb_elems != 1) {
4664 notfirst = 1;
4665 break;
4667 } else {
4668 next();
4669 l = tok;
4670 next();
4671 struct_field:
4672 if ((type->t & VT_BTYPE) != VT_STRUCT)
4673 expect("struct/union type");
4674 s = type->ref;
4675 l |= SYM_FIELD;
4676 f = s->next;
4677 while (f) {
4678 if (f->v == l)
4679 break;
4680 f = f->next;
4682 if (!f)
4683 expect("field");
4684 if (!notfirst)
4685 *cur_field = f;
4686 /* XXX: fix this mess by using explicit storage field */
4687 type1 = f->type;
4688 type1.t |= (type->t & ~VT_TYPE);
4689 type = &type1;
4690 c += f->c;
4692 notfirst = 1;
4694 if (notfirst) {
4695 if (tok == '=') {
4696 next();
4697 } else {
4698 if (!gnu_ext)
4699 expect("=");
4701 } else {
4702 if (type->t & VT_ARRAY) {
4703 index = *cur_index;
4704 type = pointed_type(type);
4705 c += index * type_size(type, &align);
4706 } else {
4707 f = *cur_field;
4708 if (!f)
4709 error("too many field init");
4710 /* XXX: fix this mess by using explicit storage field */
4711 type1 = f->type;
4712 type1.t |= (type->t & ~VT_TYPE);
4713 type = &type1;
4714 c += f->c;
4717 decl_initializer(type, sec, c, 0, size_only);
4719 /* XXX: make it more general */
4720 if (!size_only && nb_elems > 1) {
4721 unsigned long c_end;
4722 uint8_t *src, *dst;
4723 int i;
4725 if (!sec)
4726 error("range init not supported yet for dynamic storage");
4727 c_end = c + nb_elems * elem_size;
4728 if (c_end > sec->data_allocated)
4729 section_realloc(sec, c_end);
4730 src = sec->data + c;
4731 dst = src;
4732 for(i = 1; i < nb_elems; i++) {
4733 dst += elem_size;
4734 memcpy(dst, src, elem_size);
4739 #define EXPR_VAL 0
4740 #define EXPR_CONST 1
4741 #define EXPR_ANY 2
4743 /* store a value or an expression directly in global data or in local array */
4744 static void init_putv(CType *type, Section *sec, unsigned long c,
4745 int v, int expr_type)
4747 int saved_global_expr, bt, bit_pos, bit_size;
4748 void *ptr;
4749 unsigned long long bit_mask;
4750 CType dtype;
4752 switch(expr_type) {
4753 case EXPR_VAL:
4754 vpushi(v);
4755 break;
4756 case EXPR_CONST:
4757 /* compound literals must be allocated globally in this case */
4758 saved_global_expr = global_expr;
4759 global_expr = 1;
4760 expr_const1();
4761 global_expr = saved_global_expr;
4762 /* NOTE: symbols are accepted */
4763 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4764 error("initializer element is not constant");
4765 break;
4766 case EXPR_ANY:
4767 expr_eq();
4768 break;
4771 dtype = *type;
4772 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4774 if (sec) {
4775 /* XXX: not portable */
4776 /* XXX: generate error if incorrect relocation */
4777 gen_assign_cast(&dtype);
4778 bt = type->t & VT_BTYPE;
4779 /* we'll write at most 12 bytes */
4780 if (c + 12 > sec->data_allocated) {
4781 section_realloc(sec, c + 12);
4783 ptr = sec->data + c;
4784 /* XXX: make code faster ? */
4785 if (!(type->t & VT_BITFIELD)) {
4786 bit_pos = 0;
4787 bit_size = 32;
4788 bit_mask = -1LL;
4789 } else {
4790 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4791 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4792 bit_mask = (1LL << bit_size) - 1;
4794 if ((vtop->r & VT_SYM) &&
4795 (bt == VT_BYTE ||
4796 bt == VT_SHORT ||
4797 bt == VT_DOUBLE ||
4798 bt == VT_LDOUBLE ||
4799 bt == VT_LLONG ||
4800 (bt == VT_INT && bit_size != 32)))
4801 error("initializer element is not computable at load time");
4802 switch(bt) {
4803 case VT_BOOL:
4804 vtop->c.i = (vtop->c.i != 0);
4805 case VT_BYTE:
4806 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4807 break;
4808 case VT_SHORT:
4809 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4810 break;
4811 case VT_DOUBLE:
4812 *(double *)ptr = vtop->c.d;
4813 break;
4814 case VT_LDOUBLE:
4815 *(long double *)ptr = vtop->c.ld;
4816 break;
4817 case VT_LLONG:
4818 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4819 break;
4820 default:
4821 if (vtop->r & VT_SYM) {
4822 greloc(sec, vtop->sym, c, R_DATA_PTR);
4824 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4825 break;
4827 vtop--;
4828 } else {
4829 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4830 vswap();
4831 vstore();
4832 vpop();
4836 /* put zeros for variable based init */
4837 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4839 if (sec) {
4840 /* nothing to do because globals are already set to zero */
4841 } else {
4842 vpush_global_sym(&func_old_type, TOK_memset);
4843 vseti(VT_LOCAL, c);
4844 vpushi(0);
4845 vpushi(size);
4846 gfunc_call(3);
4850 /* 't' contains the type and storage info. 'c' is the offset of the
4851 object in section 'sec'. If 'sec' is NULL, it means stack based
4852 allocation. 'first' is true if array '{' must be read (multi
4853 dimension implicit array init handling). 'size_only' is true if
4854 size only evaluation is wanted (only for arrays). */
4855 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4856 int first, int size_only)
4858 int index, array_length, n, no_oblock, nb, parlevel, i;
4859 int size1, align1, expr_type;
4860 Sym *s, *f;
4861 CType *t1;
4863 if (type->t & VT_VLA) {
4864 int a;
4865 CValue retcval;
4867 vpush_global_sym(&func_old_type, TOK_alloca);
4868 vla_runtime_type_size(type, &a);
4869 gfunc_call(1);
4871 /* return value */
4872 retcval.i = 0;
4873 vsetc(type, REG_IRET, &retcval);
4874 } else if (type->t & VT_ARRAY) {
4875 s = type->ref;
4876 n = s->c;
4877 array_length = 0;
4878 t1 = pointed_type(type);
4879 size1 = type_size(t1, &align1);
4881 no_oblock = 1;
4882 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4883 tok == '{') {
4884 if (tok != '{')
4885 error("character array initializer must be a literal,"
4886 " optionally enclosed in braces");
4887 skip('{');
4888 no_oblock = 0;
4891 /* only parse strings here if correct type (otherwise: handle
4892 them as ((w)char *) expressions */
4893 if ((tok == TOK_LSTR &&
4894 #ifdef TCC_TARGET_PE
4895 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4896 #else
4897 (t1->t & VT_BTYPE) == VT_INT
4898 #endif
4899 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4900 while (tok == TOK_STR || tok == TOK_LSTR) {
4901 int cstr_len, ch;
4902 CString *cstr;
4904 cstr = tokc.cstr;
4905 /* compute maximum number of chars wanted */
4906 if (tok == TOK_STR)
4907 cstr_len = cstr->size;
4908 else
4909 cstr_len = cstr->size / sizeof(nwchar_t);
4910 cstr_len--;
4911 nb = cstr_len;
4912 if (n >= 0 && nb > (n - array_length))
4913 nb = n - array_length;
4914 if (!size_only) {
4915 if (cstr_len > nb)
4916 warning("initializer-string for array is too long");
4917 /* in order to go faster for common case (char
4918 string in global variable, we handle it
4919 specifically */
4920 if (sec && tok == TOK_STR && size1 == 1) {
4921 memcpy(sec->data + c + array_length, cstr->data, nb);
4922 } else {
4923 for(i=0;i<nb;i++) {
4924 if (tok == TOK_STR)
4925 ch = ((unsigned char *)cstr->data)[i];
4926 else
4927 ch = ((nwchar_t *)cstr->data)[i];
4928 init_putv(t1, sec, c + (array_length + i) * size1,
4929 ch, EXPR_VAL);
4933 array_length += nb;
4934 next();
4936 /* only add trailing zero if enough storage (no
4937 warning in this case since it is standard) */
4938 if (n < 0 || array_length < n) {
4939 if (!size_only) {
4940 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4942 array_length++;
4944 } else {
4945 index = 0;
4946 while (tok != '}') {
4947 decl_designator(type, sec, c, &index, NULL, size_only);
4948 if (n >= 0 && index >= n)
4949 error("index too large");
4950 /* must put zero in holes (note that doing it that way
4951 ensures that it even works with designators) */
4952 if (!size_only && array_length < index) {
4953 init_putz(t1, sec, c + array_length * size1,
4954 (index - array_length) * size1);
4956 index++;
4957 if (index > array_length)
4958 array_length = index;
4959 /* special test for multi dimensional arrays (may not
4960 be strictly correct if designators are used at the
4961 same time) */
4962 if (index >= n && no_oblock)
4963 break;
4964 if (tok == '}')
4965 break;
4966 skip(',');
4969 if (!no_oblock)
4970 skip('}');
4971 /* put zeros at the end */
4972 if (!size_only && n >= 0 && array_length < n) {
4973 init_putz(t1, sec, c + array_length * size1,
4974 (n - array_length) * size1);
4976 /* patch type size if needed */
4977 if (n < 0)
4978 s->c = array_length;
4979 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4980 (sec || !first || tok == '{')) {
4981 int par_count;
4983 /* NOTE: the previous test is a specific case for automatic
4984 struct/union init */
4985 /* XXX: union needs only one init */
4987 /* XXX: this test is incorrect for local initializers
4988 beginning with ( without {. It would be much more difficult
4989 to do it correctly (ideally, the expression parser should
4990 be used in all cases) */
4991 par_count = 0;
4992 if (tok == '(') {
4993 AttributeDef ad1;
4994 CType type1;
4995 next();
4996 while (tok == '(') {
4997 par_count++;
4998 next();
5000 if (!parse_btype(&type1, &ad1))
5001 expect("cast");
5002 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5003 #if 0
5004 if (!is_assignable_types(type, &type1))
5005 error("invalid type for cast");
5006 #endif
5007 skip(')');
5009 no_oblock = 1;
5010 if (first || tok == '{') {
5011 skip('{');
5012 no_oblock = 0;
5014 s = type->ref;
5015 f = s->next;
5016 array_length = 0;
5017 index = 0;
5018 n = s->c;
5019 while (tok != '}') {
5020 decl_designator(type, sec, c, NULL, &f, size_only);
5021 index = f->c;
5022 if (!size_only && array_length < index) {
5023 init_putz(type, sec, c + array_length,
5024 index - array_length);
5026 index = index + type_size(&f->type, &align1);
5027 if (index > array_length)
5028 array_length = index;
5030 /* gr: skip fields from same union - ugly. */
5031 while (f->next) {
5032 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5033 /* test for same offset */
5034 if (f->next->c != f->c)
5035 break;
5036 /* if yes, test for bitfield shift */
5037 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5038 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5039 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5040 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5041 if (bit_pos_1 != bit_pos_2)
5042 break;
5044 f = f->next;
5047 f = f->next;
5048 if (no_oblock && f == NULL)
5049 break;
5050 if (tok == '}')
5051 break;
5052 skip(',');
5054 /* put zeros at the end */
5055 if (!size_only && array_length < n) {
5056 init_putz(type, sec, c + array_length,
5057 n - array_length);
5059 if (!no_oblock)
5060 skip('}');
5061 while (par_count) {
5062 skip(')');
5063 par_count--;
5065 } else if (tok == '{') {
5066 next();
5067 decl_initializer(type, sec, c, first, size_only);
5068 skip('}');
5069 } else if (size_only) {
5070 /* just skip expression */
5071 parlevel = 0;
5072 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
5073 tok != -1) {
5074 if (tok == '(')
5075 parlevel++;
5076 else if (tok == ')')
5077 parlevel--;
5078 next();
5080 } else {
5081 /* currently, we always use constant expression for globals
5082 (may change for scripting case) */
5083 expr_type = EXPR_CONST;
5084 if (!sec)
5085 expr_type = EXPR_ANY;
5086 init_putv(type, sec, c, 0, expr_type);
5090 /* parse an initializer for type 't' if 'has_init' is non zero, and
5091 allocate space in local or global data space ('r' is either
5092 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5093 variable 'v' of scope 'scope' is declared before initializers are
5094 parsed. If 'v' is zero, then a reference to the new object is put
5095 in the value stack. If 'has_init' is 2, a special parsing is done
5096 to handle string constants. */
5097 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5098 int has_init, int v, int scope)
5100 int size, align, addr, data_offset;
5101 int level;
5102 ParseState saved_parse_state = {0};
5103 TokenString init_str;
5104 Section *sec;
5105 Sym *vla = NULL;
5107 size = type_size(type, &align);
5108 /* If unknown size, we must evaluate it before
5109 evaluating initializers because
5110 initializers can generate global data too
5111 (e.g. string pointers or ISOC99 compound
5112 literals). It also simplifies local
5113 initializers handling */
5114 tok_str_new(&init_str);
5115 if (size < 0) {
5116 if (!has_init)
5117 error("unknown type size");
5118 /* get all init string */
5119 if (has_init == 2) {
5120 /* only get strings */
5121 while (tok == TOK_STR || tok == TOK_LSTR) {
5122 tok_str_add_tok(&init_str);
5123 next();
5125 } else {
5126 level = 0;
5127 while (level > 0 || (tok != ',' && tok != ';')) {
5128 if (tok < 0)
5129 error("unexpected end of file in initializer");
5130 tok_str_add_tok(&init_str);
5131 if (tok == '{')
5132 level++;
5133 else if (tok == '}') {
5134 level--;
5135 if (level <= 0) {
5136 next();
5137 break;
5140 next();
5143 tok_str_add(&init_str, -1);
5144 tok_str_add(&init_str, 0);
5146 /* compute size */
5147 save_parse_state(&saved_parse_state);
5149 macro_ptr = init_str.str;
5150 next();
5151 decl_initializer(type, NULL, 0, 1, 1);
5152 /* prepare second initializer parsing */
5153 macro_ptr = init_str.str;
5154 next();
5156 /* if still unknown size, error */
5157 size = type_size(type, &align);
5158 if (size < 0)
5159 error("unknown type size");
5161 /* take into account specified alignment if bigger */
5162 if (ad->aligned) {
5163 if (ad->aligned > align)
5164 align = ad->aligned;
5165 } else if (ad->packed) {
5166 align = 1;
5168 if ((r & VT_VALMASK) == VT_LOCAL) {
5169 sec = NULL;
5170 #ifdef CONFIG_TCC_BCHECK
5171 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5172 if (type->t & VT_VLA)
5173 warning("Array bound check don't work for VLA");
5174 else
5175 loc--;
5177 #endif
5178 loc = (loc - size) & -align;
5179 addr = loc;
5180 #ifdef CONFIG_TCC_BCHECK
5181 /* handles bounds */
5182 /* XXX: currently, since we do only one pass, we cannot track
5183 '&' operators, so we add only arrays */
5184 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY) &&
5185 !(type->t & VT_VLA)) {
5186 unsigned long *bounds_ptr;
5187 /* add padding between regions */
5188 loc--;
5189 /* then add local bound info */
5190 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5191 bounds_ptr[0] = addr;
5192 bounds_ptr[1] = size;
5194 #endif
5195 if (v) {
5196 /* local variable */
5197 vla = sym_push(v, type, r, addr);
5198 } else {
5199 /* push local reference */
5200 vset(type, r, addr);
5202 } else {
5203 Sym *sym;
5205 sym = NULL;
5206 if (v && scope == VT_CONST) {
5207 /* see if the symbol was already defined */
5208 sym = sym_find(v);
5209 if (sym) {
5210 if (!is_compatible_types(&sym->type, type))
5211 error("incompatible types for redefinition of '%s'",
5212 get_tok_str(v, NULL));
5213 if (sym->type.t & VT_EXTERN) {
5214 /* if the variable is extern, it was not allocated */
5215 sym->type.t &= ~VT_EXTERN;
5216 /* set array size if it was ommited in extern
5217 declaration */
5218 if ((sym->type.t & VT_ARRAY) &&
5219 sym->type.ref->c < 0 &&
5220 type->ref->c >= 0)
5221 sym->type.ref->c = type->ref->c;
5222 } else {
5223 /* we accept several definitions of the same
5224 global variable. this is tricky, because we
5225 must play with the SHN_COMMON type of the symbol */
5226 /* XXX: should check if the variable was already
5227 initialized. It is incorrect to initialized it
5228 twice */
5229 /* no init data, we won't add more to the symbol */
5230 if (!has_init)
5231 goto no_alloc;
5236 /* allocate symbol in corresponding section */
5237 sec = ad->section;
5238 if (!sec) {
5239 if (has_init)
5240 sec = data_section;
5241 else if (tcc_state->nocommon)
5242 sec = bss_section;
5244 if (sec) {
5245 data_offset = sec->data_offset;
5246 data_offset = (data_offset + align - 1) & -align;
5247 addr = data_offset;
5248 /* very important to increment global pointer at this time
5249 because initializers themselves can create new initializers */
5250 data_offset += size;
5251 #ifdef CONFIG_TCC_BCHECK
5252 /* add padding if bound check */
5253 if (tcc_state->do_bounds_check)
5254 data_offset++;
5255 #endif
5256 sec->data_offset = data_offset;
5257 /* allocate section space to put the data */
5258 if (sec->sh_type != SHT_NOBITS &&
5259 data_offset > sec->data_allocated)
5260 section_realloc(sec, data_offset);
5261 /* align section if needed */
5262 if (align > sec->sh_addralign)
5263 sec->sh_addralign = align;
5264 } else {
5265 addr = 0; /* avoid warning */
5268 if (v) {
5269 if (scope != VT_CONST || !sym) {
5270 sym = sym_push(v, type, r | VT_SYM, 0);
5272 /* update symbol definition */
5273 if (sec) {
5274 put_extern_sym(sym, sec, addr, size);
5275 } else {
5276 ElfW(Sym) *esym;
5277 /* put a common area */
5278 put_extern_sym(sym, NULL, align, size);
5279 /* XXX: find a nicer way */
5280 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5281 esym->st_shndx = SHN_COMMON;
5283 } else {
5284 CValue cval;
5286 /* push global reference */
5287 sym = get_sym_ref(type, sec, addr, size);
5288 cval.ul = 0;
5289 vsetc(type, VT_CONST | VT_SYM, &cval);
5290 vtop->sym = sym;
5292 /* patch symbol weakness */
5293 if (type->t & VT_WEAK) {
5294 unsigned char *st_info =
5295 &((ElfW(Sym) *)symtab_section->data)[sym->c].st_info;
5296 *st_info = ELF32_ST_INFO(STB_WEAK, ELF32_ST_TYPE(*st_info));
5298 #ifdef CONFIG_TCC_BCHECK
5299 /* handles bounds now because the symbol must be defined
5300 before for the relocation */
5301 if (tcc_state->do_bounds_check) {
5302 unsigned long *bounds_ptr;
5304 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5305 /* then add global bound info */
5306 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5307 bounds_ptr[0] = 0; /* relocated */
5308 bounds_ptr[1] = size;
5310 #endif
5312 if (has_init || (type->t & VT_VLA)) {
5313 decl_initializer(type, sec, addr, 1, 0);
5314 if (type->t & VT_VLA)
5315 vla->s = vtop;
5316 /* restore parse state if needed */
5317 if (init_str.str) {
5318 tok_str_free(init_str.str);
5319 restore_parse_state(&saved_parse_state);
5322 no_alloc: ;
5325 static void put_func_debug(Sym *sym)
5327 char buf[512];
5329 /* stabs info */
5330 /* XXX: we put here a dummy type */
5331 snprintf(buf, sizeof(buf), "%s:%c1",
5332 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5333 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5334 cur_text_section, sym->c);
5335 /* //gr gdb wants a line at the function */
5336 put_stabn(N_SLINE, 0, file->line_num, 0);
5337 last_ind = 0;
5338 last_line_num = 0;
5341 /* parse an old style function declaration list */
5342 /* XXX: check multiple parameter */
5343 static void func_decl_list(Sym *func_sym)
5345 AttributeDef ad;
5346 int v;
5347 Sym *s;
5348 CType btype, type;
5350 /* parse each declaration */
5351 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
5352 if (!parse_btype(&btype, &ad))
5353 expect("declaration list");
5354 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5355 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5356 tok == ';') {
5357 /* we accept no variable after */
5358 } else {
5359 for(;;) {
5360 type = btype;
5361 type_decl(&type, &ad, &v, TYPE_DIRECT);
5362 /* find parameter in function parameter list */
5363 s = func_sym->next;
5364 while (s != NULL) {
5365 if ((s->v & ~SYM_FIELD) == v)
5366 goto found;
5367 s = s->next;
5369 error("declaration for parameter '%s' but no such parameter",
5370 get_tok_str(v, NULL));
5371 found:
5372 /* check that no storage specifier except 'register' was given */
5373 if (type.t & VT_STORAGE)
5374 error("storage class specified for '%s'", get_tok_str(v, NULL));
5375 convert_parameter_type(&type);
5376 /* we can add the type (NOTE: it could be local to the function) */
5377 s->type = type;
5378 /* accept other parameters */
5379 if (tok == ',')
5380 next();
5381 else
5382 break;
5385 skip(';');
5389 /* parse a function defined by symbol 'sym' and generate its code in
5390 'cur_text_section' */
5391 static void gen_function(Sym *sym)
5393 int saved_nocode_wanted = nocode_wanted;
5394 nocode_wanted = 0;
5395 ind = cur_text_section->data_offset;
5396 /* NOTE: we patch the symbol size later */
5397 put_extern_sym(sym, cur_text_section, ind, 0);
5398 if (sym->a)
5399 funcname = get_tok_str(sym->a, NULL);
5400 else
5401 funcname = get_tok_str(sym->v, NULL);
5402 func_ind = ind;
5403 /* put debug symbol */
5404 if (tcc_state->do_debug)
5405 put_func_debug(sym);
5406 /* push a dummy symbol to enable local sym storage */
5407 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5408 gfunc_prolog(&sym->type);
5409 rsym = 0;
5410 block(NULL, NULL, NULL, NULL, 0, 0);
5411 gsym(rsym);
5412 gfunc_epilog();
5413 cur_text_section->data_offset = ind;
5414 label_pop(&global_label_stack, NULL);
5415 sym_pop(&local_stack, NULL); /* reset local stack */
5416 /* end of function */
5417 /* patch symbol size */
5418 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5419 ind - func_ind;
5420 /* patch symbol weakness (this definition overrules any prototype) */
5421 if (sym->type.t & VT_WEAK) {
5422 unsigned char *st_info =
5423 &((ElfW(Sym) *)symtab_section->data)[sym->c].st_info;
5424 *st_info = ELF32_ST_INFO(STB_WEAK, ELF32_ST_TYPE(*st_info));
5426 if (tcc_state->do_debug) {
5427 put_stabn(N_FUN, 0, 0, ind - func_ind);
5429 /* It's better to crash than to generate wrong code */
5430 cur_text_section = NULL;
5431 funcname = ""; /* for safety */
5432 func_vt.t = VT_VOID; /* for safety */
5433 ind = 0; /* for safety */
5434 nocode_wanted = saved_nocode_wanted;
5437 ST_FUNC void gen_inline_functions(void)
5439 Sym *sym;
5440 int *str, inline_generated, i;
5441 struct InlineFunc *fn;
5443 /* iterate while inline function are referenced */
5444 for(;;) {
5445 inline_generated = 0;
5446 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5447 fn = tcc_state->inline_fns[i];
5448 sym = fn->sym;
5449 if (sym && sym->c) {
5450 /* the function was used: generate its code and
5451 convert it to a normal function */
5452 str = fn->token_str;
5453 fn->sym = NULL;
5454 if (file)
5455 strcpy(file->filename, fn->filename);
5456 sym->r = VT_SYM | VT_CONST;
5457 sym->type.t &= ~VT_INLINE;
5459 macro_ptr = str;
5460 next();
5461 cur_text_section = text_section;
5462 gen_function(sym);
5463 macro_ptr = NULL; /* fail safe */
5465 inline_generated = 1;
5468 if (!inline_generated)
5469 break;
5471 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5472 fn = tcc_state->inline_fns[i];
5473 str = fn->token_str;
5474 tok_str_free(str);
5476 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5479 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5480 ST_FUNC void decl(int l)
5482 int v, has_init, r;
5483 CType type, btype;
5484 Sym *sym;
5485 AttributeDef ad;
5488 * type.ref must be either a valid reference or NULL for external_sym to
5489 * work. As type = btype is executed before external_sym is call, setting
5490 * btype.ref to 0 is enough.
5492 btype.ref = 0;
5493 while (1) {
5494 if (!parse_btype(&btype, &ad)) {
5495 /* skip redundant ';' */
5496 /* XXX: find more elegant solution */
5497 if (tok == ';') {
5498 next();
5499 continue;
5501 if (l == VT_CONST &&
5502 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5503 /* global asm block */
5504 asm_global_instr();
5505 continue;
5507 /* special test for old K&R protos without explicit int
5508 type. Only accepted when defining global data */
5509 if (l == VT_LOCAL || tok < TOK_DEFINE)
5510 break;
5511 btype.t = VT_INT;
5513 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5514 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5515 tok == ';') {
5516 /* we accept no variable after */
5517 next();
5518 continue;
5520 while (1) { /* iterate thru each declaration */
5521 type = btype;
5522 type_decl(&type, &ad, &v, TYPE_DIRECT);
5523 #if 0
5525 char buf[500];
5526 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5527 printf("type = '%s'\n", buf);
5529 #endif
5530 if ((type.t & VT_BTYPE) == VT_FUNC) {
5531 /* if old style function prototype, we accept a
5532 declaration list */
5533 sym = type.ref;
5534 if (sym->c == FUNC_OLD)
5535 func_decl_list(sym);
5538 #ifdef TCC_TARGET_PE
5539 if (ad.func_import)
5540 type.t |= VT_IMPORT;
5541 if (ad.func_export)
5542 type.t |= VT_EXPORT;
5543 #endif
5544 if (tok == '{') {
5545 if (l == VT_LOCAL)
5546 error("cannot use local functions");
5547 if ((type.t & VT_BTYPE) != VT_FUNC)
5548 expect("function definition");
5550 /* reject abstract declarators in function definition */
5551 sym = type.ref;
5552 while ((sym = sym->next) != NULL)
5553 if (!(sym->v & ~SYM_FIELD))
5554 expect("identifier");
5556 /* XXX: cannot do better now: convert extern line to static inline */
5557 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5558 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5560 sym = sym_find(v);
5561 if (sym) {
5562 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5563 goto func_error1;
5565 r = sym->type.ref->r;
5566 /* use func_call from prototype if not defined */
5567 if (FUNC_CALL(r) != FUNC_CDECL
5568 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5569 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5571 /* use export from prototype */
5572 if (FUNC_EXPORT(r))
5573 FUNC_EXPORT(type.ref->r) = 1;
5575 /* use static from prototype */
5576 if (sym->type.t & VT_STATIC)
5577 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5579 if (!is_compatible_types(&sym->type, &type)) {
5580 func_error1:
5581 error("incompatible types for redefinition of '%s'",
5582 get_tok_str(v, NULL));
5584 /* if symbol is already defined, then put complete type */
5585 sym->type = type;
5586 } else {
5587 /* put function symbol */
5588 sym = global_identifier_push(v, type.t, 0);
5589 sym->type.ref = type.ref;
5592 /* static inline functions are just recorded as a kind
5593 of macro. Their code will be emitted at the end of
5594 the compilation unit only if they are used */
5595 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5596 (VT_INLINE | VT_STATIC)) {
5597 TokenString func_str;
5598 int block_level;
5599 struct InlineFunc *fn;
5600 const char *filename;
5602 tok_str_new(&func_str);
5604 block_level = 0;
5605 for(;;) {
5606 int t;
5607 if (tok == TOK_EOF)
5608 error("unexpected end of file");
5609 tok_str_add_tok(&func_str);
5610 t = tok;
5611 next();
5612 if (t == '{') {
5613 block_level++;
5614 } else if (t == '}') {
5615 block_level--;
5616 if (block_level == 0)
5617 break;
5620 tok_str_add(&func_str, -1);
5621 tok_str_add(&func_str, 0);
5622 filename = file ? file->filename : "";
5623 fn = tcc_malloc(sizeof *fn + strlen(filename));
5624 strcpy(fn->filename, filename);
5625 fn->sym = sym;
5626 fn->token_str = func_str.str;
5627 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5629 } else {
5630 /* compute text section */
5631 cur_text_section = ad.section;
5632 if (!cur_text_section)
5633 cur_text_section = text_section;
5634 sym->r = VT_SYM | VT_CONST;
5635 gen_function(sym);
5637 break;
5638 } else {
5639 if (btype.t & VT_TYPEDEF) {
5640 /* save typedefed type */
5641 /* XXX: test storage specifiers ? */
5642 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5643 sym->type.t |= VT_TYPEDEF;
5644 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
5645 Sym *fn;
5646 /* external function definition */
5647 /* specific case for func_call attribute */
5648 type.ref->r = INT_ATTR(&ad);
5649 fn = external_sym(v, &type, 0);
5651 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5652 char target[256];
5654 *target = 0;
5655 next();
5656 skip('(');
5657 /* Part 1: __USER_LABEL_PREFIX__ (user defined) */
5658 if (tok == TOK_STR)
5659 pstrcat(target, sizeof(target), tokc.cstr->data);
5660 else
5661 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5663 next();
5664 /* Part 2: api name */
5665 if (tok == TOK_STR)
5666 pstrcat(target, sizeof(target), tokc.cstr->data);
5667 else
5668 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5670 next();
5671 skip(')');
5672 if (tcc_state->warn_unsupported)
5673 warning("ignoring redirection from %s to %s\n", get_tok_str(v, NULL), target);
5675 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
5676 parse_attribute((AttributeDef *) &fn->type.ref->r);
5678 } else {
5679 /* not lvalue if array */
5680 r = 0;
5681 if (!(type.t & VT_ARRAY))
5682 r |= lvalue_type(type.t);
5683 has_init = (tok == '=');
5684 if (has_init && (type.t & VT_VLA))
5685 error("Variable length array cannot be initialized");
5686 if ((btype.t & VT_EXTERN) ||
5687 ((type.t & VT_ARRAY) && (!(type.t & VT_VLA)) &&
5688 (type.t & VT_STATIC) && !has_init && l == VT_CONST &&
5689 type.ref->c < 0)) {
5690 /* external variable */
5691 /* NOTE: as GCC, uninitialized global static
5692 arrays of null size are considered as
5693 extern */
5694 external_sym(v, &type, r);
5695 } else {
5696 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5697 if (type.t & VT_STATIC)
5698 r |= VT_CONST;
5699 else
5700 r |= l;
5701 if (has_init)
5702 next();
5703 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
5706 if (tok != ',') {
5707 skip(';');
5708 break;
5710 next();