tccrun: rt_printline: fix no-stabs case
[tinycc.git] / tccgen.c
blobfe4a0706281bdb30d579dbe1e256e67628a60119
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, char *asm_label, int scope);
79 static int decl0(int l, int is_for_loop_init);
80 static void expr_eq(void);
81 static void unary_type(CType *type);
82 static void vla_runtime_type_size(CType *type, int *a);
83 static int is_compatible_parameter_types(CType *type1, CType *type2);
84 static void expr_type(CType *type);
86 ST_INLN int is_float(int t)
88 int bt;
89 bt = t & VT_BTYPE;
90 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
93 ST_FUNC void test_lvalue(void)
95 if (!(vtop->r & VT_LVAL))
96 expect("lvalue");
99 /* ------------------------------------------------------------------------- */
100 /* symbol allocator */
101 static Sym *__sym_malloc(void)
103 Sym *sym_pool, *sym, *last_sym;
104 int i;
106 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
107 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
109 last_sym = sym_free_first;
110 sym = sym_pool;
111 for(i = 0; i < SYM_POOL_NB; i++) {
112 sym->next = last_sym;
113 last_sym = sym;
114 sym++;
116 sym_free_first = last_sym;
117 return last_sym;
120 static inline Sym *sym_malloc(void)
122 Sym *sym;
123 sym = sym_free_first;
124 if (!sym)
125 sym = __sym_malloc();
126 sym_free_first = sym->next;
127 return sym;
130 ST_INLN void sym_free(Sym *sym)
132 sym->next = sym_free_first;
133 tcc_free(sym->asm_label);
134 sym_free_first = sym;
137 /* push, without hashing */
138 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
140 Sym *s;
141 s = sym_malloc();
142 s->asm_label = NULL;
143 s->v = v;
144 s->type.t = t;
145 s->type.ref = NULL;
146 #ifdef _WIN64
147 s->d = NULL;
148 #endif
149 s->c = c;
150 s->next = NULL;
151 /* add in stack */
152 s->prev = *ps;
153 *ps = s;
154 return s;
157 /* find a symbol and return its associated structure. 's' is the top
158 of the symbol stack */
159 ST_FUNC Sym *sym_find2(Sym *s, int v)
161 while (s) {
162 if (s->v == v)
163 return s;
164 s = s->prev;
166 return NULL;
169 /* structure lookup */
170 ST_INLN Sym *struct_find(int v)
172 v -= TOK_IDENT;
173 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
174 return NULL;
175 return table_ident[v]->sym_struct;
178 /* find an identifier */
179 ST_INLN Sym *sym_find(int v)
181 v -= TOK_IDENT;
182 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
183 return NULL;
184 return table_ident[v]->sym_identifier;
187 /* push a given symbol on the symbol stack */
188 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
190 Sym *s, **ps;
191 TokenSym *ts;
193 if (local_stack)
194 ps = &local_stack;
195 else
196 ps = &global_stack;
197 s = sym_push2(ps, v, type->t, c);
198 s->type.ref = type->ref;
199 s->r = r;
200 /* don't record fields or anonymous symbols */
201 /* XXX: simplify */
202 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
203 /* record symbol in token array */
204 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
205 if (v & SYM_STRUCT)
206 ps = &ts->sym_struct;
207 else
208 ps = &ts->sym_identifier;
209 s->prev_tok = *ps;
210 *ps = s;
212 return s;
215 /* push a global identifier */
216 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
218 Sym *s, **ps;
219 s = sym_push2(&global_stack, v, t, c);
220 /* don't record anonymous symbol */
221 if (v < SYM_FIRST_ANOM) {
222 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
223 /* modify the top most local identifier, so that
224 sym_identifier will point to 's' when popped */
225 while (*ps != NULL)
226 ps = &(*ps)->prev_tok;
227 s->prev_tok = NULL;
228 *ps = s;
230 return s;
233 /* pop symbols until top reaches 'b' */
234 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
236 Sym *s, *ss, **ps;
237 TokenSym *ts;
238 int v;
240 s = *ptop;
241 while(s != b) {
242 ss = s->prev;
243 v = s->v;
244 /* remove symbol in token array */
245 /* XXX: simplify */
246 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
247 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
248 if (v & SYM_STRUCT)
249 ps = &ts->sym_struct;
250 else
251 ps = &ts->sym_identifier;
252 *ps = s->prev_tok;
254 sym_free(s);
255 s = ss;
257 *ptop = b;
260 static void weaken_symbol(Sym *sym)
262 sym->type.t |= VT_WEAK;
263 if (sym->c > 0) {
264 int esym_type;
265 ElfW(Sym) *esym;
267 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
268 esym_type = ELFW(ST_TYPE)(esym->st_info);
269 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
273 /* ------------------------------------------------------------------------- */
275 ST_FUNC void swap(int *p, int *q)
277 int t;
278 t = *p;
279 *p = *q;
280 *q = t;
283 static void vsetc(CType *type, int r, CValue *vc)
285 int v;
287 if (vtop >= vstack + (VSTACK_SIZE - 1))
288 error("memory full");
289 /* cannot let cpu flags if other instruction are generated. Also
290 avoid leaving VT_JMP anywhere except on the top of the stack
291 because it would complicate the code generator. */
292 if (vtop >= vstack) {
293 v = vtop->r & VT_VALMASK;
294 if (v == VT_CMP || (v & ~1) == VT_JMP)
295 gv(RC_INT);
297 vtop++;
298 vtop->type = *type;
299 vtop->r = r;
300 vtop->r2 = VT_CONST;
301 vtop->c = *vc;
304 /* push constant of type "type" with useless value */
305 void vpush(CType *type)
307 CValue cval;
308 vsetc(type, VT_CONST, &cval);
311 /* push integer constant */
312 ST_FUNC void vpushi(int v)
314 CValue cval;
315 cval.i = v;
316 vsetc(&int_type, VT_CONST, &cval);
319 /* push long long constant */
320 static void vpushll(long long v)
322 CValue cval;
323 CType ctype;
324 ctype.t = VT_LLONG;
325 ctype.ref = 0;
326 cval.ull = v;
327 vsetc(&ctype, VT_CONST, &cval);
330 /* push arbitrary 64bit constant */
331 void vpush64(int ty, unsigned long long v)
333 CValue cval;
334 CType ctype;
335 ctype.t = ty;
336 cval.ull = v;
337 vsetc(&ctype, VT_CONST, &cval);
340 /* Return a static symbol pointing to a section */
341 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
343 int v;
344 Sym *sym;
346 v = anon_sym++;
347 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
348 sym->type.ref = type->ref;
349 sym->r = VT_CONST | VT_SYM;
350 put_extern_sym(sym, sec, offset, size);
351 return sym;
354 /* push a reference to a section offset by adding a dummy symbol */
355 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
357 CValue cval;
359 cval.ul = 0;
360 vsetc(type, VT_CONST | VT_SYM, &cval);
361 vtop->sym = get_sym_ref(type, sec, offset, size);
364 /* define a new external reference to a symbol 'v' of type 'u' */
365 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
367 Sym *s;
369 s = sym_find(v);
370 if (!s) {
371 /* push forward reference */
372 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
373 s->type.ref = type->ref;
374 s->r = r | VT_CONST | VT_SYM;
376 return s;
379 /* define a new external reference to a symbol 'v' with alternate asm
380 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
381 is no alternate name (most cases) */
382 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
384 Sym *s;
386 s = sym_find(v);
387 if (!s) {
388 /* push forward reference */
389 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
390 s->asm_label = asm_label;
391 s->type.t |= VT_EXTERN;
392 } else if (s->type.ref == func_old_type.ref) {
393 s->type.ref = type->ref;
394 s->r = r | VT_CONST | VT_SYM;
395 s->type.t |= VT_EXTERN;
396 } else if (!is_compatible_types(&s->type, type)) {
397 error("incompatible types for redefinition of '%s'",
398 get_tok_str(v, NULL));
400 return s;
403 /* push a reference to global symbol v */
404 ST_FUNC void vpush_global_sym(CType *type, int v)
406 Sym *sym;
407 CValue cval;
409 sym = external_global_sym(v, type, 0);
410 cval.ul = 0;
411 vsetc(type, VT_CONST | VT_SYM, &cval);
412 vtop->sym = sym;
415 ST_FUNC void vset(CType *type, int r, int v)
417 CValue cval;
419 cval.i = v;
420 vsetc(type, r, &cval);
423 static void vseti(int r, int v)
425 CType type;
426 type.t = VT_INT;
427 type.ref = 0;
428 vset(&type, r, v);
431 ST_FUNC void vswap(void)
433 SValue tmp;
435 tmp = vtop[0];
436 vtop[0] = vtop[-1];
437 vtop[-1] = tmp;
440 ST_FUNC void vpushv(SValue *v)
442 if (vtop >= vstack + (VSTACK_SIZE - 1))
443 error("memory full");
444 vtop++;
445 *vtop = *v;
448 static void vdup(void)
450 vpushv(vtop);
453 /* save r to the memory stack, and mark it as being free */
454 ST_FUNC void save_reg(int r)
456 int l, saved, size, align;
457 SValue *p, sv;
458 CType *type;
460 /* modify all stack values */
461 saved = 0;
462 l = 0;
463 for(p=vstack;p<=vtop;p++) {
464 if ((p->r & VT_VALMASK) == r ||
465 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
466 /* must save value on stack if not already done */
467 if (!saved) {
468 /* NOTE: must reload 'r' because r might be equal to r2 */
469 r = p->r & VT_VALMASK;
470 /* store register in the stack */
471 type = &p->type;
472 if ((p->r & VT_LVAL) ||
473 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
474 #ifdef TCC_TARGET_X86_64
475 type = &char_pointer_type;
476 #else
477 type = &int_type;
478 #endif
479 size = type_size(type, &align);
480 loc = (loc - size) & -align;
481 sv.type.t = type->t;
482 sv.r = VT_LOCAL | VT_LVAL;
483 sv.c.ul = loc;
484 store(r, &sv);
485 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
486 /* x86 specific: need to pop fp register ST0 if saved */
487 if (r == TREG_ST0) {
488 o(0xd8dd); /* fstp %st(0) */
490 #endif
491 #ifndef TCC_TARGET_X86_64
492 /* special long long case */
493 if ((type->t & VT_BTYPE) == VT_LLONG) {
494 sv.c.ul += 4;
495 store(p->r2, &sv);
497 #endif
498 l = loc;
499 saved = 1;
501 /* mark that stack entry as being saved on the stack */
502 if (p->r & VT_LVAL) {
503 /* also clear the bounded flag because the
504 relocation address of the function was stored in
505 p->c.ul */
506 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
507 } else {
508 p->r = lvalue_type(p->type.t) | VT_LOCAL;
510 p->r2 = VT_CONST;
511 p->c.ul = l;
516 #ifdef TCC_TARGET_ARM
517 /* find a register of class 'rc2' with at most one reference on stack.
518 * If none, call get_reg(rc) */
519 ST_FUNC int get_reg_ex(int rc, int rc2)
521 int r;
522 SValue *p;
524 for(r=0;r<NB_REGS;r++) {
525 if (reg_classes[r] & rc2) {
526 int n;
527 n=0;
528 for(p = vstack; p <= vtop; p++) {
529 if ((p->r & VT_VALMASK) == r ||
530 (p->r2 & VT_VALMASK) == r)
531 n++;
533 if (n <= 1)
534 return r;
537 return get_reg(rc);
539 #endif
541 /* find a free register of class 'rc'. If none, save one register */
542 ST_FUNC int get_reg(int rc)
544 int r;
545 SValue *p;
547 /* find a free register */
548 for(r=0;r<NB_REGS;r++) {
549 if (reg_classes[r] & rc) {
550 for(p=vstack;p<=vtop;p++) {
551 if ((p->r & VT_VALMASK) == r ||
552 (p->r2 & VT_VALMASK) == r)
553 goto notfound;
555 return r;
557 notfound: ;
560 /* no register left : free the first one on the stack (VERY
561 IMPORTANT to start from the bottom to ensure that we don't
562 spill registers used in gen_opi()) */
563 for(p=vstack;p<=vtop;p++) {
564 r = p->r & VT_VALMASK;
565 if (r < VT_CONST && (reg_classes[r] & rc))
566 goto save_found;
567 /* also look at second register (if long long) */
568 r = p->r2 & VT_VALMASK;
569 if (r < VT_CONST && (reg_classes[r] & rc)) {
570 save_found:
571 save_reg(r);
572 return r;
575 /* Should never comes here */
576 return -1;
579 /* save registers up to (vtop - n) stack entry */
580 ST_FUNC void save_regs(int n)
582 int r;
583 SValue *p, *p1;
584 p1 = vtop - n;
585 for(p = vstack;p <= p1; p++) {
586 r = p->r & VT_VALMASK;
587 if (r < VT_CONST) {
588 save_reg(r);
593 /* move register 's' to 'r', and flush previous value of r to memory
594 if needed */
595 static void move_reg(int r, int s)
597 SValue sv;
599 if (r != s) {
600 save_reg(r);
601 sv.type.t = VT_INT;
602 sv.r = s;
603 sv.c.ul = 0;
604 load(r, &sv);
608 /* get address of vtop (vtop MUST BE an lvalue) */
609 static void gaddrof(void)
611 vtop->r &= ~VT_LVAL;
612 /* tricky: if saved lvalue, then we can go back to lvalue */
613 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
614 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
617 #ifdef CONFIG_TCC_BCHECK
618 /* generate lvalue bound code */
619 static void gbound(void)
621 int lval_type;
622 CType type1;
624 vtop->r &= ~VT_MUSTBOUND;
625 /* if lvalue, then use checking code before dereferencing */
626 if (vtop->r & VT_LVAL) {
627 /* if not VT_BOUNDED value, then make one */
628 if (!(vtop->r & VT_BOUNDED)) {
629 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
630 /* must save type because we must set it to int to get pointer */
631 type1 = vtop->type;
632 vtop->type.t = VT_INT;
633 gaddrof();
634 vpushi(0);
635 gen_bounded_ptr_add();
636 vtop->r |= lval_type;
637 vtop->type = type1;
639 /* then check for dereferencing */
640 gen_bounded_ptr_deref();
643 #endif
645 /* store vtop a register belonging to class 'rc'. lvalues are
646 converted to values. Cannot be used if cannot be converted to
647 register value (such as structures). */
648 ST_FUNC int gv(int rc)
650 int r, bit_pos, bit_size, size, align, i;
651 #ifndef TCC_TARGET_X86_64
652 int rc2;
653 #endif
655 /* NOTE: get_reg can modify vstack[] */
656 if (vtop->type.t & VT_BITFIELD) {
657 CType type;
658 int bits = 32;
659 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
660 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
661 /* remove bit field info to avoid loops */
662 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
663 /* cast to int to propagate signedness in following ops */
664 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
665 type.t = VT_LLONG;
666 bits = 64;
667 } else
668 type.t = VT_INT;
669 if((vtop->type.t & VT_UNSIGNED) ||
670 (vtop->type.t & VT_BTYPE) == VT_BOOL)
671 type.t |= VT_UNSIGNED;
672 gen_cast(&type);
673 /* generate shifts */
674 vpushi(bits - (bit_pos + bit_size));
675 gen_op(TOK_SHL);
676 vpushi(bits - bit_size);
677 /* NOTE: transformed to SHR if unsigned */
678 gen_op(TOK_SAR);
679 r = gv(rc);
680 } else {
681 if (is_float(vtop->type.t) &&
682 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
683 Sym *sym;
684 int *ptr;
685 unsigned long offset;
686 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
687 CValue check;
688 #endif
690 /* XXX: unify with initializers handling ? */
691 /* CPUs usually cannot use float constants, so we store them
692 generically in data segment */
693 size = type_size(&vtop->type, &align);
694 offset = (data_section->data_offset + align - 1) & -align;
695 data_section->data_offset = offset;
696 /* XXX: not portable yet */
697 #if defined(__i386__) || defined(__x86_64__)
698 /* Zero pad x87 tenbyte long doubles */
699 if (size == LDOUBLE_SIZE)
700 vtop->c.tab[2] &= 0xffff;
701 #endif
702 ptr = section_ptr_add(data_section, size);
703 size = size >> 2;
704 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
705 check.d = 1;
706 if(check.tab[0])
707 for(i=0;i<size;i++)
708 ptr[i] = vtop->c.tab[size-1-i];
709 else
710 #endif
711 for(i=0;i<size;i++)
712 ptr[i] = vtop->c.tab[i];
713 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
714 vtop->r |= VT_LVAL | VT_SYM;
715 vtop->sym = sym;
716 vtop->c.ul = 0;
718 #ifdef CONFIG_TCC_BCHECK
719 if (vtop->r & VT_MUSTBOUND)
720 gbound();
721 #endif
723 r = vtop->r & VT_VALMASK;
724 #ifndef TCC_TARGET_X86_64
725 rc2 = RC_INT;
726 if (rc == RC_IRET)
727 rc2 = RC_LRET;
728 #endif
729 /* need to reload if:
730 - constant
731 - lvalue (need to dereference pointer)
732 - already a register, but not in the right class */
733 if (r >= VT_CONST
734 || (vtop->r & VT_LVAL)
735 || !(reg_classes[r] & rc)
736 #ifndef TCC_TARGET_X86_64
737 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
738 #endif
741 r = get_reg(rc);
742 #ifndef TCC_TARGET_X86_64
743 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
744 int r2;
745 unsigned long long ll;
746 /* two register type load : expand to two words
747 temporarily */
748 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
749 /* load constant */
750 ll = vtop->c.ull;
751 vtop->c.ui = ll; /* first word */
752 load(r, vtop);
753 vtop->r = r; /* save register value */
754 vpushi(ll >> 32); /* second word */
755 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
756 (vtop->r & VT_LVAL)) {
757 /* We do not want to modifier the long long
758 pointer here, so the safest (and less
759 efficient) is to save all the other registers
760 in the stack. XXX: totally inefficient. */
761 save_regs(1);
762 /* load from memory */
763 load(r, vtop);
764 vdup();
765 vtop[-1].r = r; /* save register value */
766 /* increment pointer to get second word */
767 vtop->type.t = VT_INT;
768 gaddrof();
769 vpushi(4);
770 gen_op('+');
771 vtop->r |= VT_LVAL;
772 } else {
773 /* move registers */
774 load(r, vtop);
775 vdup();
776 vtop[-1].r = r; /* save register value */
777 vtop->r = vtop[-1].r2;
779 /* allocate second register */
780 r2 = get_reg(rc2);
781 load(r2, vtop);
782 vpop();
783 /* write second register */
784 vtop->r2 = r2;
785 } else
786 #endif
787 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
788 int t1, t;
789 /* lvalue of scalar type : need to use lvalue type
790 because of possible cast */
791 t = vtop->type.t;
792 t1 = t;
793 /* compute memory access type */
794 if (vtop->r & VT_LVAL_BYTE)
795 t = VT_BYTE;
796 else if (vtop->r & VT_LVAL_SHORT)
797 t = VT_SHORT;
798 if (vtop->r & VT_LVAL_UNSIGNED)
799 t |= VT_UNSIGNED;
800 vtop->type.t = t;
801 load(r, vtop);
802 /* restore wanted type */
803 vtop->type.t = t1;
804 } else {
805 /* one register type load */
806 load(r, vtop);
809 vtop->r = r;
810 #ifdef TCC_TARGET_C67
811 /* uses register pairs for doubles */
812 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
813 vtop->r2 = r+1;
814 #endif
816 return r;
819 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
820 ST_FUNC void gv2(int rc1, int rc2)
822 int v;
824 /* generate more generic register first. But VT_JMP or VT_CMP
825 values must be generated first in all cases to avoid possible
826 reload errors */
827 v = vtop[0].r & VT_VALMASK;
828 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
829 vswap();
830 gv(rc1);
831 vswap();
832 gv(rc2);
833 /* test if reload is needed for first register */
834 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
835 vswap();
836 gv(rc1);
837 vswap();
839 } else {
840 gv(rc2);
841 vswap();
842 gv(rc1);
843 vswap();
844 /* test if reload is needed for first register */
845 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
846 gv(rc2);
851 /* wrapper around RC_FRET to return a register by type */
852 static int rc_fret(int t)
854 #ifdef TCC_TARGET_X86_64
855 if (t == VT_LDOUBLE) {
856 return RC_ST0;
858 #endif
859 return RC_FRET;
862 /* wrapper around REG_FRET to return a register by type */
863 static int reg_fret(int t)
865 #ifdef TCC_TARGET_X86_64
866 if (t == VT_LDOUBLE) {
867 return TREG_ST0;
869 #endif
870 return REG_FRET;
873 /* expand long long on stack in two int registers */
874 static void lexpand(void)
876 int u;
878 u = vtop->type.t & VT_UNSIGNED;
879 gv(RC_INT);
880 vdup();
881 vtop[0].r = vtop[-1].r2;
882 vtop[0].r2 = VT_CONST;
883 vtop[-1].r2 = VT_CONST;
884 vtop[0].type.t = VT_INT | u;
885 vtop[-1].type.t = VT_INT | u;
888 #ifdef TCC_TARGET_ARM
889 /* expand long long on stack */
890 ST_FUNC void lexpand_nr(void)
892 int u,v;
894 u = vtop->type.t & VT_UNSIGNED;
895 vdup();
896 vtop->r2 = VT_CONST;
897 vtop->type.t = VT_INT | u;
898 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
899 if (v == VT_CONST) {
900 vtop[-1].c.ui = vtop->c.ull;
901 vtop->c.ui = vtop->c.ull >> 32;
902 vtop->r = VT_CONST;
903 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
904 vtop->c.ui += 4;
905 vtop->r = vtop[-1].r;
906 } else if (v > VT_CONST) {
907 vtop--;
908 lexpand();
909 } else
910 vtop->r = vtop[-1].r2;
911 vtop[-1].r2 = VT_CONST;
912 vtop[-1].type.t = VT_INT | u;
914 #endif
916 /* build a long long from two ints */
917 static void lbuild(int t)
919 gv2(RC_INT, RC_INT);
920 vtop[-1].r2 = vtop[0].r;
921 vtop[-1].type.t = t;
922 vpop();
925 /* rotate n first stack elements to the bottom
926 I1 ... In -> I2 ... In I1 [top is right]
928 static void vrotb(int n)
930 int i;
931 SValue tmp;
933 tmp = vtop[-n + 1];
934 for(i=-n+1;i!=0;i++)
935 vtop[i] = vtop[i+1];
936 vtop[0] = tmp;
939 /* rotate n first stack elements to the top
940 I1 ... In -> In I1 ... I(n-1) [top is right]
942 ST_FUNC void vrott(int n)
944 int i;
945 SValue tmp;
947 tmp = vtop[0];
948 for(i = 0;i < n - 1; i++)
949 vtop[-i] = vtop[-i - 1];
950 vtop[-n + 1] = tmp;
953 #ifdef TCC_TARGET_ARM
954 /* like vrott but in other direction
955 In ... I1 -> I(n-1) ... I1 In [top is right]
957 ST_FUNC void vnrott(int n)
959 int i;
960 SValue tmp;
962 tmp = vtop[-n + 1];
963 for(i = n - 1; i > 0; i--)
964 vtop[-i] = vtop[-i + 1];
965 vtop[0] = tmp;
967 #endif
969 /* pop stack value */
970 ST_FUNC void vpop(void)
972 int v;
973 v = vtop->r & VT_VALMASK;
974 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
975 /* for x86, we need to pop the FP stack */
976 if (v == TREG_ST0 && !nocode_wanted) {
977 o(0xd8dd); /* fstp %st(0) */
978 } else
979 #endif
980 if (v == VT_JMP || v == VT_JMPI) {
981 /* need to put correct jump if && or || without test */
982 gsym(vtop->c.ul);
984 vtop--;
987 /* convert stack entry to register and duplicate its value in another
988 register */
989 static void gv_dup(void)
991 int rc, t, r, r1;
992 SValue sv;
994 t = vtop->type.t;
995 if ((t & VT_BTYPE) == VT_LLONG) {
996 lexpand();
997 gv_dup();
998 vswap();
999 vrotb(3);
1000 gv_dup();
1001 vrotb(4);
1002 /* stack: H L L1 H1 */
1003 lbuild(t);
1004 vrotb(3);
1005 vrotb(3);
1006 vswap();
1007 lbuild(t);
1008 vswap();
1009 } else {
1010 /* duplicate value */
1011 rc = RC_INT;
1012 sv.type.t = VT_INT;
1013 if (is_float(t)) {
1014 rc = RC_FLOAT;
1015 #ifdef TCC_TARGET_X86_64
1016 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1017 rc = RC_ST0;
1019 #endif
1020 sv.type.t = t;
1022 r = gv(rc);
1023 r1 = get_reg(rc);
1024 sv.r = r;
1025 sv.c.ul = 0;
1026 load(r1, &sv); /* move r to r1 */
1027 vdup();
1028 /* duplicates value */
1029 if (r != r1)
1030 vtop->r = r1;
1034 #ifndef TCC_TARGET_X86_64
1035 /* generate CPU independent (unsigned) long long operations */
1036 static void gen_opl(int op)
1038 int t, a, b, op1, c, i;
1039 int func;
1040 unsigned short reg_iret = REG_IRET;
1041 unsigned short reg_lret = REG_LRET;
1042 SValue tmp;
1044 switch(op) {
1045 case '/':
1046 case TOK_PDIV:
1047 func = TOK___divdi3;
1048 goto gen_func;
1049 case TOK_UDIV:
1050 func = TOK___udivdi3;
1051 goto gen_func;
1052 case '%':
1053 func = TOK___moddi3;
1054 goto gen_mod_func;
1055 case TOK_UMOD:
1056 func = TOK___umoddi3;
1057 gen_mod_func:
1058 #ifdef TCC_ARM_EABI
1059 reg_iret = TREG_R2;
1060 reg_lret = TREG_R3;
1061 #endif
1062 gen_func:
1063 /* call generic long long function */
1064 vpush_global_sym(&func_old_type, func);
1065 vrott(3);
1066 gfunc_call(2);
1067 vpushi(0);
1068 vtop->r = reg_iret;
1069 vtop->r2 = reg_lret;
1070 break;
1071 case '^':
1072 case '&':
1073 case '|':
1074 case '*':
1075 case '+':
1076 case '-':
1077 t = vtop->type.t;
1078 vswap();
1079 lexpand();
1080 vrotb(3);
1081 lexpand();
1082 /* stack: L1 H1 L2 H2 */
1083 tmp = vtop[0];
1084 vtop[0] = vtop[-3];
1085 vtop[-3] = tmp;
1086 tmp = vtop[-2];
1087 vtop[-2] = vtop[-3];
1088 vtop[-3] = tmp;
1089 vswap();
1090 /* stack: H1 H2 L1 L2 */
1091 if (op == '*') {
1092 vpushv(vtop - 1);
1093 vpushv(vtop - 1);
1094 gen_op(TOK_UMULL);
1095 lexpand();
1096 /* stack: H1 H2 L1 L2 ML MH */
1097 for(i=0;i<4;i++)
1098 vrotb(6);
1099 /* stack: ML MH H1 H2 L1 L2 */
1100 tmp = vtop[0];
1101 vtop[0] = vtop[-2];
1102 vtop[-2] = tmp;
1103 /* stack: ML MH H1 L2 H2 L1 */
1104 gen_op('*');
1105 vrotb(3);
1106 vrotb(3);
1107 gen_op('*');
1108 /* stack: ML MH M1 M2 */
1109 gen_op('+');
1110 gen_op('+');
1111 } else if (op == '+' || op == '-') {
1112 /* XXX: add non carry method too (for MIPS or alpha) */
1113 if (op == '+')
1114 op1 = TOK_ADDC1;
1115 else
1116 op1 = TOK_SUBC1;
1117 gen_op(op1);
1118 /* stack: H1 H2 (L1 op L2) */
1119 vrotb(3);
1120 vrotb(3);
1121 gen_op(op1 + 1); /* TOK_xxxC2 */
1122 } else {
1123 gen_op(op);
1124 /* stack: H1 H2 (L1 op L2) */
1125 vrotb(3);
1126 vrotb(3);
1127 /* stack: (L1 op L2) H1 H2 */
1128 gen_op(op);
1129 /* stack: (L1 op L2) (H1 op H2) */
1131 /* stack: L H */
1132 lbuild(t);
1133 break;
1134 case TOK_SAR:
1135 case TOK_SHR:
1136 case TOK_SHL:
1137 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1138 t = vtop[-1].type.t;
1139 vswap();
1140 lexpand();
1141 vrotb(3);
1142 /* stack: L H shift */
1143 c = (int)vtop->c.i;
1144 /* constant: simpler */
1145 /* NOTE: all comments are for SHL. the other cases are
1146 done by swaping words */
1147 vpop();
1148 if (op != TOK_SHL)
1149 vswap();
1150 if (c >= 32) {
1151 /* stack: L H */
1152 vpop();
1153 if (c > 32) {
1154 vpushi(c - 32);
1155 gen_op(op);
1157 if (op != TOK_SAR) {
1158 vpushi(0);
1159 } else {
1160 gv_dup();
1161 vpushi(31);
1162 gen_op(TOK_SAR);
1164 vswap();
1165 } else {
1166 vswap();
1167 gv_dup();
1168 /* stack: H L L */
1169 vpushi(c);
1170 gen_op(op);
1171 vswap();
1172 vpushi(32 - c);
1173 if (op == TOK_SHL)
1174 gen_op(TOK_SHR);
1175 else
1176 gen_op(TOK_SHL);
1177 vrotb(3);
1178 /* stack: L L H */
1179 vpushi(c);
1180 if (op == TOK_SHL)
1181 gen_op(TOK_SHL);
1182 else
1183 gen_op(TOK_SHR);
1184 gen_op('|');
1186 if (op != TOK_SHL)
1187 vswap();
1188 lbuild(t);
1189 } else {
1190 /* XXX: should provide a faster fallback on x86 ? */
1191 switch(op) {
1192 case TOK_SAR:
1193 func = TOK___ashrdi3;
1194 goto gen_func;
1195 case TOK_SHR:
1196 func = TOK___lshrdi3;
1197 goto gen_func;
1198 case TOK_SHL:
1199 func = TOK___ashldi3;
1200 goto gen_func;
1203 break;
1204 default:
1205 /* compare operations */
1206 t = vtop->type.t;
1207 vswap();
1208 lexpand();
1209 vrotb(3);
1210 lexpand();
1211 /* stack: L1 H1 L2 H2 */
1212 tmp = vtop[-1];
1213 vtop[-1] = vtop[-2];
1214 vtop[-2] = tmp;
1215 /* stack: L1 L2 H1 H2 */
1216 /* compare high */
1217 op1 = op;
1218 /* when values are equal, we need to compare low words. since
1219 the jump is inverted, we invert the test too. */
1220 if (op1 == TOK_LT)
1221 op1 = TOK_LE;
1222 else if (op1 == TOK_GT)
1223 op1 = TOK_GE;
1224 else if (op1 == TOK_ULT)
1225 op1 = TOK_ULE;
1226 else if (op1 == TOK_UGT)
1227 op1 = TOK_UGE;
1228 a = 0;
1229 b = 0;
1230 gen_op(op1);
1231 if (op1 != TOK_NE) {
1232 a = gtst(1, 0);
1234 if (op != TOK_EQ) {
1235 /* generate non equal test */
1236 /* XXX: NOT PORTABLE yet */
1237 if (a == 0) {
1238 b = gtst(0, 0);
1239 } else {
1240 #if defined(TCC_TARGET_I386)
1241 b = psym(0x850f, 0);
1242 #elif defined(TCC_TARGET_ARM)
1243 b = ind;
1244 o(0x1A000000 | encbranch(ind, 0, 1));
1245 #elif defined(TCC_TARGET_C67)
1246 error("not implemented");
1247 #else
1248 #error not supported
1249 #endif
1252 /* compare low. Always unsigned */
1253 op1 = op;
1254 if (op1 == TOK_LT)
1255 op1 = TOK_ULT;
1256 else if (op1 == TOK_LE)
1257 op1 = TOK_ULE;
1258 else if (op1 == TOK_GT)
1259 op1 = TOK_UGT;
1260 else if (op1 == TOK_GE)
1261 op1 = TOK_UGE;
1262 gen_op(op1);
1263 a = gtst(1, a);
1264 gsym(b);
1265 vseti(VT_JMPI, a);
1266 break;
1269 #endif
1271 /* handle integer constant optimizations and various machine
1272 independent opt */
1273 static void gen_opic(int op)
1275 int c1, c2, t1, t2, n;
1276 SValue *v1, *v2;
1277 long long l1, l2;
1278 typedef unsigned long long U;
1280 v1 = vtop - 1;
1281 v2 = vtop;
1282 t1 = v1->type.t & VT_BTYPE;
1283 t2 = v2->type.t & VT_BTYPE;
1285 if (t1 == VT_LLONG)
1286 l1 = v1->c.ll;
1287 else if (v1->type.t & VT_UNSIGNED)
1288 l1 = v1->c.ui;
1289 else
1290 l1 = v1->c.i;
1292 if (t2 == VT_LLONG)
1293 l2 = v2->c.ll;
1294 else if (v2->type.t & VT_UNSIGNED)
1295 l2 = v2->c.ui;
1296 else
1297 l2 = v2->c.i;
1299 /* currently, we cannot do computations with forward symbols */
1300 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1301 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1302 if (c1 && c2) {
1303 switch(op) {
1304 case '+': l1 += l2; break;
1305 case '-': l1 -= l2; break;
1306 case '&': l1 &= l2; break;
1307 case '^': l1 ^= l2; break;
1308 case '|': l1 |= l2; break;
1309 case '*': l1 *= l2; break;
1311 case TOK_PDIV:
1312 case '/':
1313 case '%':
1314 case TOK_UDIV:
1315 case TOK_UMOD:
1316 /* if division by zero, generate explicit division */
1317 if (l2 == 0) {
1318 if (const_wanted)
1319 error("division by zero in constant");
1320 goto general_case;
1322 switch(op) {
1323 default: l1 /= l2; break;
1324 case '%': l1 %= l2; break;
1325 case TOK_UDIV: l1 = (U)l1 / l2; break;
1326 case TOK_UMOD: l1 = (U)l1 % l2; break;
1328 break;
1329 case TOK_SHL: l1 <<= l2; break;
1330 case TOK_SHR: l1 = (U)l1 >> l2; break;
1331 case TOK_SAR: l1 >>= l2; break;
1332 /* tests */
1333 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1334 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1335 case TOK_EQ: l1 = l1 == l2; break;
1336 case TOK_NE: l1 = l1 != l2; break;
1337 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1338 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1339 case TOK_LT: l1 = l1 < l2; break;
1340 case TOK_GE: l1 = l1 >= l2; break;
1341 case TOK_LE: l1 = l1 <= l2; break;
1342 case TOK_GT: l1 = l1 > l2; break;
1343 /* logical */
1344 case TOK_LAND: l1 = l1 && l2; break;
1345 case TOK_LOR: l1 = l1 || l2; break;
1346 default:
1347 goto general_case;
1349 v1->c.ll = l1;
1350 vtop--;
1351 } else {
1352 /* if commutative ops, put c2 as constant */
1353 if (c1 && (op == '+' || op == '&' || op == '^' ||
1354 op == '|' || op == '*')) {
1355 vswap();
1356 c2 = c1; //c = c1, c1 = c2, c2 = c;
1357 l2 = l1; //l = l1, l1 = l2, l2 = l;
1359 /* Filter out NOP operations like x*1, x-0, x&-1... */
1360 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1361 op == TOK_PDIV) &&
1362 l2 == 1) ||
1363 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1364 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1365 l2 == 0) ||
1366 (op == '&' &&
1367 l2 == -1))) {
1368 /* nothing to do */
1369 vtop--;
1370 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1371 /* try to use shifts instead of muls or divs */
1372 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1373 n = -1;
1374 while (l2) {
1375 l2 >>= 1;
1376 n++;
1378 vtop->c.ll = n;
1379 if (op == '*')
1380 op = TOK_SHL;
1381 else if (op == TOK_PDIV)
1382 op = TOK_SAR;
1383 else
1384 op = TOK_SHR;
1386 goto general_case;
1387 } else if (c2 && (op == '+' || op == '-') &&
1388 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1389 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1390 /* symbol + constant case */
1391 if (op == '-')
1392 l2 = -l2;
1393 vtop--;
1394 vtop->c.ll += l2;
1395 } else {
1396 general_case:
1397 if (!nocode_wanted) {
1398 /* call low level op generator */
1399 if (t1 == VT_LLONG || t2 == VT_LLONG)
1400 gen_opl(op);
1401 else
1402 gen_opi(op);
1403 } else {
1404 vtop--;
1410 /* generate a floating point operation with constant propagation */
1411 static void gen_opif(int op)
1413 int c1, c2;
1414 SValue *v1, *v2;
1415 long double f1, f2;
1417 v1 = vtop - 1;
1418 v2 = vtop;
1419 /* currently, we cannot do computations with forward symbols */
1420 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1421 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1422 if (c1 && c2) {
1423 if (v1->type.t == VT_FLOAT) {
1424 f1 = v1->c.f;
1425 f2 = v2->c.f;
1426 } else if (v1->type.t == VT_DOUBLE) {
1427 f1 = v1->c.d;
1428 f2 = v2->c.d;
1429 } else {
1430 f1 = v1->c.ld;
1431 f2 = v2->c.ld;
1434 /* NOTE: we only do constant propagation if finite number (not
1435 NaN or infinity) (ANSI spec) */
1436 if (!ieee_finite(f1) || !ieee_finite(f2))
1437 goto general_case;
1439 switch(op) {
1440 case '+': f1 += f2; break;
1441 case '-': f1 -= f2; break;
1442 case '*': f1 *= f2; break;
1443 case '/':
1444 if (f2 == 0.0) {
1445 if (const_wanted)
1446 error("division by zero in constant");
1447 goto general_case;
1449 f1 /= f2;
1450 break;
1451 /* XXX: also handles tests ? */
1452 default:
1453 goto general_case;
1455 /* XXX: overflow test ? */
1456 if (v1->type.t == VT_FLOAT) {
1457 v1->c.f = f1;
1458 } else if (v1->type.t == VT_DOUBLE) {
1459 v1->c.d = f1;
1460 } else {
1461 v1->c.ld = f1;
1463 vtop--;
1464 } else {
1465 general_case:
1466 if (!nocode_wanted) {
1467 gen_opf(op);
1468 } else {
1469 vtop--;
1474 static int pointed_size(CType *type)
1476 int align;
1477 return type_size(pointed_type(type), &align);
1480 static void vla_runtime_pointed_size(CType *type)
1482 int align;
1483 vla_runtime_type_size(pointed_type(type), &align);
1486 static inline int is_null_pointer(SValue *p)
1488 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1489 return 0;
1490 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1491 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1494 static inline int is_integer_btype(int bt)
1496 return (bt == VT_BYTE || bt == VT_SHORT ||
1497 bt == VT_INT || bt == VT_LLONG);
1500 /* check types for comparison or substraction of pointers */
1501 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1503 CType *type1, *type2, tmp_type1, tmp_type2;
1504 int bt1, bt2;
1506 /* null pointers are accepted for all comparisons as gcc */
1507 if (is_null_pointer(p1) || is_null_pointer(p2))
1508 return;
1509 type1 = &p1->type;
1510 type2 = &p2->type;
1511 bt1 = type1->t & VT_BTYPE;
1512 bt2 = type2->t & VT_BTYPE;
1513 /* accept comparison between pointer and integer with a warning */
1514 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1515 if (op != TOK_LOR && op != TOK_LAND )
1516 warning("comparison between pointer and integer");
1517 return;
1520 /* both must be pointers or implicit function pointers */
1521 if (bt1 == VT_PTR) {
1522 type1 = pointed_type(type1);
1523 } else if (bt1 != VT_FUNC)
1524 goto invalid_operands;
1526 if (bt2 == VT_PTR) {
1527 type2 = pointed_type(type2);
1528 } else if (bt2 != VT_FUNC) {
1529 invalid_operands:
1530 error("invalid operands to binary %s", get_tok_str(op, NULL));
1532 if ((type1->t & VT_BTYPE) == VT_VOID ||
1533 (type2->t & VT_BTYPE) == VT_VOID)
1534 return;
1535 tmp_type1 = *type1;
1536 tmp_type2 = *type2;
1537 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1538 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1539 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1540 /* gcc-like error if '-' is used */
1541 if (op == '-')
1542 goto invalid_operands;
1543 else
1544 warning("comparison of distinct pointer types lacks a cast");
1548 /* generic gen_op: handles types problems */
1549 ST_FUNC void gen_op(int op)
1551 int u, t1, t2, bt1, bt2, t;
1552 CType type1;
1554 t1 = vtop[-1].type.t;
1555 t2 = vtop[0].type.t;
1556 bt1 = t1 & VT_BTYPE;
1557 bt2 = t2 & VT_BTYPE;
1559 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1560 /* at least one operand is a pointer */
1561 /* relationnal op: must be both pointers */
1562 if (op >= TOK_ULT && op <= TOK_LOR) {
1563 check_comparison_pointer_types(vtop - 1, vtop, op);
1564 /* pointers are handled are unsigned */
1565 #ifdef TCC_TARGET_X86_64
1566 t = VT_LLONG | VT_UNSIGNED;
1567 #else
1568 t = VT_INT | VT_UNSIGNED;
1569 #endif
1570 goto std_op;
1572 /* if both pointers, then it must be the '-' op */
1573 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1574 if (op != '-')
1575 error("cannot use pointers here");
1576 check_comparison_pointer_types(vtop - 1, vtop, op);
1577 /* XXX: check that types are compatible */
1578 if (vtop[-1].type.t & VT_VLA) {
1579 vla_runtime_pointed_size(&vtop[-1].type);
1580 } else {
1581 vpushi(pointed_size(&vtop[-1].type));
1583 vrott(3);
1584 gen_opic(op);
1585 /* set to integer type */
1586 #ifdef TCC_TARGET_X86_64
1587 vtop->type.t = VT_LLONG;
1588 #else
1589 vtop->type.t = VT_INT;
1590 #endif
1591 vswap();
1592 gen_op(TOK_PDIV);
1593 } else {
1594 /* exactly one pointer : must be '+' or '-'. */
1595 if (op != '-' && op != '+')
1596 error("cannot use pointers here");
1597 /* Put pointer as first operand */
1598 if (bt2 == VT_PTR) {
1599 vswap();
1600 swap(&t1, &t2);
1602 type1 = vtop[-1].type;
1603 type1.t &= ~VT_ARRAY;
1604 if (vtop[-1].type.t & VT_VLA)
1605 vla_runtime_pointed_size(&vtop[-1].type);
1606 else {
1607 u = pointed_size(&vtop[-1].type);
1608 if (u < 0)
1609 error("unknown array element size");
1610 #ifdef TCC_TARGET_X86_64
1611 vpushll(u);
1612 #else
1613 /* XXX: cast to int ? (long long case) */
1614 vpushi(u);
1615 #endif
1617 gen_op('*');
1618 #ifdef CONFIG_TCC_BCHECK
1619 /* if evaluating constant expression, no code should be
1620 generated, so no bound check */
1621 if (tcc_state->do_bounds_check && !const_wanted) {
1622 /* if bounded pointers, we generate a special code to
1623 test bounds */
1624 if (op == '-') {
1625 vpushi(0);
1626 vswap();
1627 gen_op('-');
1629 gen_bounded_ptr_add();
1630 } else
1631 #endif
1633 gen_opic(op);
1635 /* put again type if gen_opic() swaped operands */
1636 vtop->type = type1;
1638 } else if (is_float(bt1) || is_float(bt2)) {
1639 /* compute bigger type and do implicit casts */
1640 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1641 t = VT_LDOUBLE;
1642 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1643 t = VT_DOUBLE;
1644 } else {
1645 t = VT_FLOAT;
1647 /* floats can only be used for a few operations */
1648 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1649 (op < TOK_ULT || op > TOK_GT))
1650 error("invalid operands for binary operation");
1651 goto std_op;
1652 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1653 /* cast to biggest op */
1654 t = VT_LLONG;
1655 /* convert to unsigned if it does not fit in a long long */
1656 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1657 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1658 t |= VT_UNSIGNED;
1659 goto std_op;
1660 } else {
1661 /* integer operations */
1662 t = VT_INT;
1663 /* convert to unsigned if it does not fit in an integer */
1664 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1665 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1666 t |= VT_UNSIGNED;
1667 std_op:
1668 /* XXX: currently, some unsigned operations are explicit, so
1669 we modify them here */
1670 if (t & VT_UNSIGNED) {
1671 if (op == TOK_SAR)
1672 op = TOK_SHR;
1673 else if (op == '/')
1674 op = TOK_UDIV;
1675 else if (op == '%')
1676 op = TOK_UMOD;
1677 else if (op == TOK_LT)
1678 op = TOK_ULT;
1679 else if (op == TOK_GT)
1680 op = TOK_UGT;
1681 else if (op == TOK_LE)
1682 op = TOK_ULE;
1683 else if (op == TOK_GE)
1684 op = TOK_UGE;
1686 vswap();
1687 type1.t = t;
1688 gen_cast(&type1);
1689 vswap();
1690 /* special case for shifts and long long: we keep the shift as
1691 an integer */
1692 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1693 type1.t = VT_INT;
1694 gen_cast(&type1);
1695 if (is_float(t))
1696 gen_opif(op);
1697 else
1698 gen_opic(op);
1699 if (op >= TOK_ULT && op <= TOK_GT) {
1700 /* relationnal op: the result is an int */
1701 vtop->type.t = VT_INT;
1702 } else {
1703 vtop->type.t = t;
1708 #ifndef TCC_TARGET_ARM
1709 /* generic itof for unsigned long long case */
1710 static void gen_cvt_itof1(int t)
1712 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1713 (VT_LLONG | VT_UNSIGNED)) {
1715 if (t == VT_FLOAT)
1716 vpush_global_sym(&func_old_type, TOK___floatundisf);
1717 #if LDOUBLE_SIZE != 8
1718 else if (t == VT_LDOUBLE)
1719 vpush_global_sym(&func_old_type, TOK___floatundixf);
1720 #endif
1721 else
1722 vpush_global_sym(&func_old_type, TOK___floatundidf);
1723 vrott(2);
1724 gfunc_call(1);
1725 vpushi(0);
1726 vtop->r = reg_fret(t);
1727 } else {
1728 gen_cvt_itof(t);
1731 #endif
1733 /* generic ftoi for unsigned long long case */
1734 static void gen_cvt_ftoi1(int t)
1736 int st;
1738 if (t == (VT_LLONG | VT_UNSIGNED)) {
1739 /* not handled natively */
1740 st = vtop->type.t & VT_BTYPE;
1741 if (st == VT_FLOAT)
1742 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1743 #if LDOUBLE_SIZE != 8
1744 else if (st == VT_LDOUBLE)
1745 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1746 #endif
1747 else
1748 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1749 vrott(2);
1750 gfunc_call(1);
1751 vpushi(0);
1752 vtop->r = REG_IRET;
1753 vtop->r2 = REG_LRET;
1754 } else {
1755 gen_cvt_ftoi(t);
1759 /* force char or short cast */
1760 static void force_charshort_cast(int t)
1762 int bits, dbt;
1763 dbt = t & VT_BTYPE;
1764 /* XXX: add optimization if lvalue : just change type and offset */
1765 if (dbt == VT_BYTE)
1766 bits = 8;
1767 else
1768 bits = 16;
1769 if (t & VT_UNSIGNED) {
1770 vpushi((1 << bits) - 1);
1771 gen_op('&');
1772 } else {
1773 bits = 32 - bits;
1774 vpushi(bits);
1775 gen_op(TOK_SHL);
1776 /* result must be signed or the SAR is converted to an SHL
1777 This was not the case when "t" was a signed short
1778 and the last value on the stack was an unsigned int */
1779 vtop->type.t &= ~VT_UNSIGNED;
1780 vpushi(bits);
1781 gen_op(TOK_SAR);
1785 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1786 static void gen_cast(CType *type)
1788 int sbt, dbt, sf, df, c, p;
1790 /* special delayed cast for char/short */
1791 /* XXX: in some cases (multiple cascaded casts), it may still
1792 be incorrect */
1793 if (vtop->r & VT_MUSTCAST) {
1794 vtop->r &= ~VT_MUSTCAST;
1795 force_charshort_cast(vtop->type.t);
1798 /* bitfields first get cast to ints */
1799 if (vtop->type.t & VT_BITFIELD) {
1800 gv(RC_INT);
1803 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1804 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1806 if (sbt != dbt) {
1807 sf = is_float(sbt);
1808 df = is_float(dbt);
1809 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1810 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1811 if (c) {
1812 /* constant case: we can do it now */
1813 /* XXX: in ISOC, cannot do it if error in convert */
1814 if (sbt == VT_FLOAT)
1815 vtop->c.ld = vtop->c.f;
1816 else if (sbt == VT_DOUBLE)
1817 vtop->c.ld = vtop->c.d;
1819 if (df) {
1820 if ((sbt & VT_BTYPE) == VT_LLONG) {
1821 if (sbt & VT_UNSIGNED)
1822 vtop->c.ld = vtop->c.ull;
1823 else
1824 vtop->c.ld = vtop->c.ll;
1825 } else if(!sf) {
1826 if (sbt & VT_UNSIGNED)
1827 vtop->c.ld = vtop->c.ui;
1828 else
1829 vtop->c.ld = vtop->c.i;
1832 if (dbt == VT_FLOAT)
1833 vtop->c.f = (float)vtop->c.ld;
1834 else if (dbt == VT_DOUBLE)
1835 vtop->c.d = (double)vtop->c.ld;
1836 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1837 vtop->c.ull = (unsigned long long)vtop->c.ld;
1838 } else if (sf && dbt == VT_BOOL) {
1839 vtop->c.i = (vtop->c.ld != 0);
1840 } else {
1841 if(sf)
1842 vtop->c.ll = (long long)vtop->c.ld;
1843 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1844 vtop->c.ll = vtop->c.ull;
1845 else if (sbt & VT_UNSIGNED)
1846 vtop->c.ll = vtop->c.ui;
1847 #ifdef TCC_TARGET_X86_64
1848 else if (sbt == VT_PTR)
1850 #endif
1851 else if (sbt != VT_LLONG)
1852 vtop->c.ll = vtop->c.i;
1854 if (dbt == (VT_LLONG|VT_UNSIGNED))
1855 vtop->c.ull = vtop->c.ll;
1856 else if (dbt == VT_BOOL)
1857 vtop->c.i = (vtop->c.ll != 0);
1858 else if (dbt != VT_LLONG) {
1859 int s = 0;
1860 if ((dbt & VT_BTYPE) == VT_BYTE)
1861 s = 24;
1862 else if ((dbt & VT_BTYPE) == VT_SHORT)
1863 s = 16;
1865 if(dbt & VT_UNSIGNED)
1866 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1867 else
1868 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1871 } else if (p && dbt == VT_BOOL) {
1872 vtop->r = VT_CONST;
1873 vtop->c.i = 1;
1874 } else if (!nocode_wanted) {
1875 /* non constant case: generate code */
1876 if (sf && df) {
1877 /* convert from fp to fp */
1878 gen_cvt_ftof(dbt);
1879 } else if (df) {
1880 /* convert int to fp */
1881 gen_cvt_itof1(dbt);
1882 } else if (sf) {
1883 /* convert fp to int */
1884 if (dbt == VT_BOOL) {
1885 vpushi(0);
1886 gen_op(TOK_NE);
1887 } else {
1888 /* we handle char/short/etc... with generic code */
1889 if (dbt != (VT_INT | VT_UNSIGNED) &&
1890 dbt != (VT_LLONG | VT_UNSIGNED) &&
1891 dbt != VT_LLONG)
1892 dbt = VT_INT;
1893 gen_cvt_ftoi1(dbt);
1894 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1895 /* additional cast for char/short... */
1896 vtop->type.t = dbt;
1897 gen_cast(type);
1900 #ifndef TCC_TARGET_X86_64
1901 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1902 if ((sbt & VT_BTYPE) != VT_LLONG) {
1903 /* scalar to long long */
1904 /* machine independent conversion */
1905 gv(RC_INT);
1906 /* generate high word */
1907 if (sbt == (VT_INT | VT_UNSIGNED)) {
1908 vpushi(0);
1909 gv(RC_INT);
1910 } else {
1911 if (sbt == VT_PTR) {
1912 /* cast from pointer to int before we apply
1913 shift operation, which pointers don't support*/
1914 gen_cast(&int_type);
1916 gv_dup();
1917 vpushi(31);
1918 gen_op(TOK_SAR);
1920 /* patch second register */
1921 vtop[-1].r2 = vtop->r;
1922 vpop();
1924 #else
1925 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1926 (dbt & VT_BTYPE) == VT_PTR ||
1927 (dbt & VT_BTYPE) == VT_FUNC) {
1928 if ((sbt & VT_BTYPE) != VT_LLONG &&
1929 (sbt & VT_BTYPE) != VT_PTR &&
1930 (sbt & VT_BTYPE) != VT_FUNC) {
1931 /* need to convert from 32bit to 64bit */
1932 int r = gv(RC_INT);
1933 if (sbt != (VT_INT | VT_UNSIGNED)) {
1934 /* x86_64 specific: movslq */
1935 o(0x6348);
1936 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1939 #endif
1940 } else if (dbt == VT_BOOL) {
1941 /* scalar to bool */
1942 vpushi(0);
1943 gen_op(TOK_NE);
1944 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1945 (dbt & VT_BTYPE) == VT_SHORT) {
1946 if (sbt == VT_PTR) {
1947 vtop->type.t = VT_INT;
1948 warning("nonportable conversion from pointer to char/short");
1950 force_charshort_cast(dbt);
1951 } else if ((dbt & VT_BTYPE) == VT_INT) {
1952 /* scalar to int */
1953 if (sbt == VT_LLONG) {
1954 /* from long long: just take low order word */
1955 lexpand();
1956 vpop();
1958 /* if lvalue and single word type, nothing to do because
1959 the lvalue already contains the real type size (see
1960 VT_LVAL_xxx constants) */
1963 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1964 /* if we are casting between pointer types,
1965 we must update the VT_LVAL_xxx size */
1966 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1967 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1969 vtop->type = *type;
1972 /* return type size as known at compile time. Put alignment at 'a' */
1973 ST_FUNC int type_size(CType *type, int *a)
1975 Sym *s;
1976 int bt;
1978 bt = type->t & VT_BTYPE;
1979 if (bt == VT_STRUCT) {
1980 /* struct/union */
1981 s = type->ref;
1982 *a = s->r;
1983 return s->c;
1984 } else if (bt == VT_PTR) {
1985 if (type->t & VT_ARRAY) {
1986 int ts;
1988 s = type->ref;
1989 ts = type_size(&s->type, a);
1991 if (ts < 0 && s->c < 0)
1992 ts = -ts;
1994 return ts * s->c;
1995 } else {
1996 *a = PTR_SIZE;
1997 return PTR_SIZE;
1999 } else if (bt == VT_LDOUBLE) {
2000 *a = LDOUBLE_ALIGN;
2001 return LDOUBLE_SIZE;
2002 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2003 #ifdef TCC_TARGET_I386
2004 #ifdef TCC_TARGET_PE
2005 *a = 8;
2006 #else
2007 *a = 4;
2008 #endif
2009 #elif defined(TCC_TARGET_ARM)
2010 #ifdef TCC_ARM_EABI
2011 *a = 8;
2012 #else
2013 *a = 4;
2014 #endif
2015 #else
2016 *a = 8;
2017 #endif
2018 return 8;
2019 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2020 *a = 4;
2021 return 4;
2022 } else if (bt == VT_SHORT) {
2023 *a = 2;
2024 return 2;
2025 } else {
2026 /* char, void, function, _Bool */
2027 *a = 1;
2028 return 1;
2032 /* push type size as known at runtime time on top of value stack. Put
2033 alignment at 'a' */
2034 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2036 if (type->t & VT_VLA) {
2037 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2038 } else {
2039 vpushi(type_size(type, a));
2043 /* return the pointed type of t */
2044 static inline CType *pointed_type(CType *type)
2046 return &type->ref->type;
2049 /* modify type so that its it is a pointer to type. */
2050 ST_FUNC void mk_pointer(CType *type)
2052 Sym *s;
2053 s = sym_push(SYM_FIELD, type, 0, -1);
2054 type->t = VT_PTR | (type->t & ~VT_TYPE);
2055 type->ref = s;
2058 /* compare function types. OLD functions match any new functions */
2059 static int is_compatible_func(CType *type1, CType *type2)
2061 Sym *s1, *s2;
2063 s1 = type1->ref;
2064 s2 = type2->ref;
2065 if (!is_compatible_types(&s1->type, &s2->type))
2066 return 0;
2067 /* check func_call */
2068 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2069 return 0;
2070 /* XXX: not complete */
2071 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2072 return 1;
2073 if (s1->c != s2->c)
2074 return 0;
2075 while (s1 != NULL) {
2076 if (s2 == NULL)
2077 return 0;
2078 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2079 return 0;
2080 s1 = s1->next;
2081 s2 = s2->next;
2083 if (s2)
2084 return 0;
2085 return 1;
2088 /* return true if type1 and type2 are the same. If unqualified is
2089 true, qualifiers on the types are ignored.
2091 - enums are not checked as gcc __builtin_types_compatible_p ()
2093 static int compare_types(CType *type1, CType *type2, int unqualified)
2095 int bt1, t1, t2;
2097 t1 = type1->t & VT_TYPE;
2098 t2 = type2->t & VT_TYPE;
2099 if (unqualified) {
2100 /* strip qualifiers before comparing */
2101 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2102 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2104 /* XXX: bitfields ? */
2105 if (t1 != t2)
2106 return 0;
2107 /* test more complicated cases */
2108 bt1 = t1 & VT_BTYPE;
2109 if (bt1 == VT_PTR) {
2110 type1 = pointed_type(type1);
2111 type2 = pointed_type(type2);
2112 return is_compatible_types(type1, type2);
2113 } else if (bt1 == VT_STRUCT) {
2114 return (type1->ref == type2->ref);
2115 } else if (bt1 == VT_FUNC) {
2116 return is_compatible_func(type1, type2);
2117 } else {
2118 return 1;
2122 /* return true if type1 and type2 are exactly the same (including
2123 qualifiers).
2125 static int is_compatible_types(CType *type1, CType *type2)
2127 return compare_types(type1,type2,0);
2130 /* return true if type1 and type2 are the same (ignoring qualifiers).
2132 static int is_compatible_parameter_types(CType *type1, CType *type2)
2134 return compare_types(type1,type2,1);
2137 /* print a type. If 'varstr' is not NULL, then the variable is also
2138 printed in the type */
2139 /* XXX: union */
2140 /* XXX: add array and function pointers */
2141 static void type_to_str(char *buf, int buf_size,
2142 CType *type, const char *varstr)
2144 int bt, v, t;
2145 Sym *s, *sa;
2146 char buf1[256];
2147 const char *tstr;
2149 t = type->t & VT_TYPE;
2150 bt = t & VT_BTYPE;
2151 buf[0] = '\0';
2152 if (t & VT_CONSTANT)
2153 pstrcat(buf, buf_size, "const ");
2154 if (t & VT_VOLATILE)
2155 pstrcat(buf, buf_size, "volatile ");
2156 if (t & VT_UNSIGNED)
2157 pstrcat(buf, buf_size, "unsigned ");
2158 switch(bt) {
2159 case VT_VOID:
2160 tstr = "void";
2161 goto add_tstr;
2162 case VT_BOOL:
2163 tstr = "_Bool";
2164 goto add_tstr;
2165 case VT_BYTE:
2166 tstr = "char";
2167 goto add_tstr;
2168 case VT_SHORT:
2169 tstr = "short";
2170 goto add_tstr;
2171 case VT_INT:
2172 tstr = "int";
2173 goto add_tstr;
2174 case VT_LONG:
2175 tstr = "long";
2176 goto add_tstr;
2177 case VT_LLONG:
2178 tstr = "long long";
2179 goto add_tstr;
2180 case VT_FLOAT:
2181 tstr = "float";
2182 goto add_tstr;
2183 case VT_DOUBLE:
2184 tstr = "double";
2185 goto add_tstr;
2186 case VT_LDOUBLE:
2187 tstr = "long double";
2188 add_tstr:
2189 pstrcat(buf, buf_size, tstr);
2190 break;
2191 case VT_ENUM:
2192 case VT_STRUCT:
2193 if (bt == VT_STRUCT)
2194 tstr = "struct ";
2195 else
2196 tstr = "enum ";
2197 pstrcat(buf, buf_size, tstr);
2198 v = type->ref->v & ~SYM_STRUCT;
2199 if (v >= SYM_FIRST_ANOM)
2200 pstrcat(buf, buf_size, "<anonymous>");
2201 else
2202 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2203 break;
2204 case VT_FUNC:
2205 s = type->ref;
2206 type_to_str(buf, buf_size, &s->type, varstr);
2207 pstrcat(buf, buf_size, "(");
2208 sa = s->next;
2209 while (sa != NULL) {
2210 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2211 pstrcat(buf, buf_size, buf1);
2212 sa = sa->next;
2213 if (sa)
2214 pstrcat(buf, buf_size, ", ");
2216 pstrcat(buf, buf_size, ")");
2217 goto no_var;
2218 case VT_PTR:
2219 s = type->ref;
2220 pstrcpy(buf1, sizeof(buf1), "*");
2221 if (varstr)
2222 pstrcat(buf1, sizeof(buf1), varstr);
2223 type_to_str(buf, buf_size, &s->type, buf1);
2224 goto no_var;
2226 if (varstr) {
2227 pstrcat(buf, buf_size, " ");
2228 pstrcat(buf, buf_size, varstr);
2230 no_var: ;
2233 /* verify type compatibility to store vtop in 'dt' type, and generate
2234 casts if needed. */
2235 static void gen_assign_cast(CType *dt)
2237 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2238 char buf1[256], buf2[256];
2239 int dbt, sbt;
2241 st = &vtop->type; /* source type */
2242 dbt = dt->t & VT_BTYPE;
2243 sbt = st->t & VT_BTYPE;
2244 if (dt->t & VT_CONSTANT)
2245 warning("assignment of read-only location");
2246 switch(dbt) {
2247 case VT_PTR:
2248 /* special cases for pointers */
2249 /* '0' can also be a pointer */
2250 if (is_null_pointer(vtop))
2251 goto type_ok;
2252 /* accept implicit pointer to integer cast with warning */
2253 if (is_integer_btype(sbt)) {
2254 warning("assignment makes pointer from integer without a cast");
2255 goto type_ok;
2257 type1 = pointed_type(dt);
2258 /* a function is implicitely a function pointer */
2259 if (sbt == VT_FUNC) {
2260 if ((type1->t & VT_BTYPE) != VT_VOID &&
2261 !is_compatible_types(pointed_type(dt), st))
2262 warning("assignment from incompatible pointer type");
2263 goto type_ok;
2265 if (sbt != VT_PTR)
2266 goto error;
2267 type2 = pointed_type(st);
2268 if ((type1->t & VT_BTYPE) == VT_VOID ||
2269 (type2->t & VT_BTYPE) == VT_VOID) {
2270 /* void * can match anything */
2271 } else {
2272 /* exact type match, except for unsigned */
2273 tmp_type1 = *type1;
2274 tmp_type2 = *type2;
2275 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2276 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2277 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2278 warning("assignment from incompatible pointer type");
2280 /* check const and volatile */
2281 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2282 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2283 warning("assignment discards qualifiers from pointer target type");
2284 break;
2285 case VT_BYTE:
2286 case VT_SHORT:
2287 case VT_INT:
2288 case VT_LLONG:
2289 if (sbt == VT_PTR || sbt == VT_FUNC) {
2290 warning("assignment makes integer from pointer without a cast");
2292 /* XXX: more tests */
2293 break;
2294 case VT_STRUCT:
2295 tmp_type1 = *dt;
2296 tmp_type2 = *st;
2297 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2298 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2299 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2300 error:
2301 type_to_str(buf1, sizeof(buf1), st, NULL);
2302 type_to_str(buf2, sizeof(buf2), dt, NULL);
2303 error("cannot cast '%s' to '%s'", buf1, buf2);
2305 break;
2307 type_ok:
2308 gen_cast(dt);
2311 /* store vtop in lvalue pushed on stack */
2312 ST_FUNC void vstore(void)
2314 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2316 ft = vtop[-1].type.t;
2317 sbt = vtop->type.t & VT_BTYPE;
2318 dbt = ft & VT_BTYPE;
2319 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2320 (sbt == VT_INT && dbt == VT_SHORT)) {
2321 /* optimize char/short casts */
2322 delayed_cast = VT_MUSTCAST;
2323 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2324 /* XXX: factorize */
2325 if (ft & VT_CONSTANT)
2326 warning("assignment of read-only location");
2327 } else {
2328 delayed_cast = 0;
2329 if (!(ft & VT_BITFIELD))
2330 gen_assign_cast(&vtop[-1].type);
2333 if (sbt == VT_STRUCT) {
2334 /* if structure, only generate pointer */
2335 /* structure assignment : generate memcpy */
2336 /* XXX: optimize if small size */
2337 if (!nocode_wanted) {
2338 size = type_size(&vtop->type, &align);
2340 /* destination */
2341 vswap();
2342 vtop->type.t = VT_PTR;
2343 gaddrof();
2345 /* address of memcpy() */
2346 #ifdef TCC_ARM_EABI
2347 if(!(align & 7))
2348 vpush_global_sym(&func_old_type, TOK_memcpy8);
2349 else if(!(align & 3))
2350 vpush_global_sym(&func_old_type, TOK_memcpy4);
2351 else
2352 #endif
2353 vpush_global_sym(&func_old_type, TOK_memcpy);
2355 vswap();
2356 /* source */
2357 vpushv(vtop - 2);
2358 vtop->type.t = VT_PTR;
2359 gaddrof();
2360 /* type size */
2361 vpushi(size);
2362 gfunc_call(3);
2363 } else {
2364 vswap();
2365 vpop();
2367 /* leave source on stack */
2368 } else if (ft & VT_BITFIELD) {
2369 /* bitfield store handling */
2370 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2371 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2372 /* remove bit field info to avoid loops */
2373 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2375 /* duplicate source into other register */
2376 gv_dup();
2377 vswap();
2378 vrott(3);
2380 if((ft & VT_BTYPE) == VT_BOOL) {
2381 gen_cast(&vtop[-1].type);
2382 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2385 /* duplicate destination */
2386 vdup();
2387 vtop[-1] = vtop[-2];
2389 /* mask and shift source */
2390 if((ft & VT_BTYPE) != VT_BOOL) {
2391 if((ft & VT_BTYPE) == VT_LLONG) {
2392 vpushll((1ULL << bit_size) - 1ULL);
2393 } else {
2394 vpushi((1 << bit_size) - 1);
2396 gen_op('&');
2398 vpushi(bit_pos);
2399 gen_op(TOK_SHL);
2400 /* load destination, mask and or with source */
2401 vswap();
2402 if((ft & VT_BTYPE) == VT_LLONG) {
2403 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2404 } else {
2405 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2407 gen_op('&');
2408 gen_op('|');
2409 /* store result */
2410 vstore();
2412 /* pop off shifted source from "duplicate source..." above */
2413 vpop();
2415 } else {
2416 #ifdef CONFIG_TCC_BCHECK
2417 /* bound check case */
2418 if (vtop[-1].r & VT_MUSTBOUND) {
2419 vswap();
2420 gbound();
2421 vswap();
2423 #endif
2424 if (!nocode_wanted) {
2425 rc = RC_INT;
2426 if (is_float(ft)) {
2427 rc = RC_FLOAT;
2428 #ifdef TCC_TARGET_X86_64
2429 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2430 rc = RC_ST0;
2432 #endif
2434 r = gv(rc); /* generate value */
2435 /* if lvalue was saved on stack, must read it */
2436 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2437 SValue sv;
2438 t = get_reg(RC_INT);
2439 #ifdef TCC_TARGET_X86_64
2440 sv.type.t = VT_PTR;
2441 #else
2442 sv.type.t = VT_INT;
2443 #endif
2444 sv.r = VT_LOCAL | VT_LVAL;
2445 sv.c.ul = vtop[-1].c.ul;
2446 load(t, &sv);
2447 vtop[-1].r = t | VT_LVAL;
2449 store(r, vtop - 1);
2450 #ifndef TCC_TARGET_X86_64
2451 /* two word case handling : store second register at word + 4 */
2452 if ((ft & VT_BTYPE) == VT_LLONG) {
2453 vswap();
2454 /* convert to int to increment easily */
2455 vtop->type.t = VT_INT;
2456 gaddrof();
2457 vpushi(4);
2458 gen_op('+');
2459 vtop->r |= VT_LVAL;
2460 vswap();
2461 /* XXX: it works because r2 is spilled last ! */
2462 store(vtop->r2, vtop - 1);
2464 #endif
2466 vswap();
2467 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2468 vtop->r |= delayed_cast;
2472 /* post defines POST/PRE add. c is the token ++ or -- */
2473 ST_FUNC void inc(int post, int c)
2475 test_lvalue();
2476 vdup(); /* save lvalue */
2477 if (post) {
2478 gv_dup(); /* duplicate value */
2479 vrotb(3);
2480 vrotb(3);
2482 /* add constant */
2483 vpushi(c - TOK_MID);
2484 gen_op('+');
2485 vstore(); /* store value */
2486 if (post)
2487 vpop(); /* if post op, return saved value */
2490 /* Parse GNUC __attribute__ extension. Currently, the following
2491 extensions are recognized:
2492 - aligned(n) : set data/function alignment.
2493 - packed : force data alignment to 1
2494 - section(x) : generate data/code in this section.
2495 - unused : currently ignored, but may be used someday.
2496 - regparm(n) : pass function parameters in registers (i386 only)
2498 static void parse_attribute(AttributeDef *ad)
2500 int t, n;
2502 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2503 next();
2504 skip('(');
2505 skip('(');
2506 while (tok != ')') {
2507 if (tok < TOK_IDENT)
2508 expect("attribute name");
2509 t = tok;
2510 next();
2511 switch(t) {
2512 case TOK_SECTION1:
2513 case TOK_SECTION2:
2514 skip('(');
2515 if (tok != TOK_STR)
2516 expect("section name");
2517 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2518 next();
2519 skip(')');
2520 break;
2521 case TOK_ALIAS1:
2522 case TOK_ALIAS2:
2523 skip('(');
2524 if (tok != TOK_STR)
2525 expect("alias(\"target\")");
2526 ad->alias_target = /* save string as token, for later */
2527 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2528 next();
2529 skip(')');
2530 break;
2531 case TOK_ALIGNED1:
2532 case TOK_ALIGNED2:
2533 if (tok == '(') {
2534 next();
2535 n = expr_const();
2536 if (n <= 0 || (n & (n - 1)) != 0)
2537 error("alignment must be a positive power of two");
2538 skip(')');
2539 } else {
2540 n = MAX_ALIGN;
2542 ad->aligned = n;
2543 break;
2544 case TOK_PACKED1:
2545 case TOK_PACKED2:
2546 ad->packed = 1;
2547 break;
2548 case TOK_WEAK1:
2549 case TOK_WEAK2:
2550 ad->weak = 1;
2551 break;
2552 case TOK_UNUSED1:
2553 case TOK_UNUSED2:
2554 /* currently, no need to handle it because tcc does not
2555 track unused objects */
2556 break;
2557 case TOK_NORETURN1:
2558 case TOK_NORETURN2:
2559 /* currently, no need to handle it because tcc does not
2560 track unused objects */
2561 break;
2562 case TOK_CDECL1:
2563 case TOK_CDECL2:
2564 case TOK_CDECL3:
2565 ad->func_call = FUNC_CDECL;
2566 break;
2567 case TOK_STDCALL1:
2568 case TOK_STDCALL2:
2569 case TOK_STDCALL3:
2570 ad->func_call = FUNC_STDCALL;
2571 break;
2572 #ifdef TCC_TARGET_I386
2573 case TOK_REGPARM1:
2574 case TOK_REGPARM2:
2575 skip('(');
2576 n = expr_const();
2577 if (n > 3)
2578 n = 3;
2579 else if (n < 0)
2580 n = 0;
2581 if (n > 0)
2582 ad->func_call = FUNC_FASTCALL1 + n - 1;
2583 skip(')');
2584 break;
2585 case TOK_FASTCALL1:
2586 case TOK_FASTCALL2:
2587 case TOK_FASTCALL3:
2588 ad->func_call = FUNC_FASTCALLW;
2589 break;
2590 #endif
2591 case TOK_MODE:
2592 skip('(');
2593 switch(tok) {
2594 case TOK_MODE_DI:
2595 ad->mode = VT_LLONG + 1;
2596 break;
2597 case TOK_MODE_HI:
2598 ad->mode = VT_SHORT + 1;
2599 break;
2600 case TOK_MODE_SI:
2601 ad->mode = VT_INT + 1;
2602 break;
2603 default:
2604 warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2605 break;
2607 next();
2608 skip(')');
2609 break;
2610 case TOK_DLLEXPORT:
2611 ad->func_export = 1;
2612 break;
2613 case TOK_DLLIMPORT:
2614 ad->func_import = 1;
2615 break;
2616 default:
2617 if (tcc_state->warn_unsupported)
2618 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2619 /* skip parameters */
2620 if (tok == '(') {
2621 int parenthesis = 0;
2622 do {
2623 if (tok == '(')
2624 parenthesis++;
2625 else if (tok == ')')
2626 parenthesis--;
2627 next();
2628 } while (parenthesis && tok != -1);
2630 break;
2632 if (tok != ',')
2633 break;
2634 next();
2636 skip(')');
2637 skip(')');
2641 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2642 static void struct_decl(CType *type, int u)
2644 int a, v, size, align, maxalign, c, offset;
2645 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2646 Sym *s, *ss, *ass, **ps;
2647 AttributeDef ad;
2648 CType type1, btype;
2650 a = tok; /* save decl type */
2651 next();
2652 if (tok != '{') {
2653 v = tok;
2654 next();
2655 /* struct already defined ? return it */
2656 if (v < TOK_IDENT)
2657 expect("struct/union/enum name");
2658 s = struct_find(v);
2659 if (s) {
2660 if (s->type.t != a)
2661 error("invalid type");
2662 goto do_decl;
2664 } else {
2665 v = anon_sym++;
2667 type1.t = a;
2668 /* we put an undefined size for struct/union */
2669 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2670 s->r = 0; /* default alignment is zero as gcc */
2671 /* put struct/union/enum name in type */
2672 do_decl:
2673 type->t = u;
2674 type->ref = s;
2676 if (tok == '{') {
2677 next();
2678 if (s->c != -1)
2679 error("struct/union/enum already defined");
2680 /* cannot be empty */
2681 c = 0;
2682 /* non empty enums are not allowed */
2683 if (a == TOK_ENUM) {
2684 for(;;) {
2685 v = tok;
2686 if (v < TOK_UIDENT)
2687 expect("identifier");
2688 next();
2689 if (tok == '=') {
2690 next();
2691 c = expr_const();
2693 /* enum symbols have static storage */
2694 ss = sym_push(v, &int_type, VT_CONST, c);
2695 ss->type.t |= VT_STATIC;
2696 if (tok != ',')
2697 break;
2698 next();
2699 c++;
2700 /* NOTE: we accept a trailing comma */
2701 if (tok == '}')
2702 break;
2704 skip('}');
2705 } else {
2706 maxalign = 1;
2707 ps = &s->next;
2708 prevbt = VT_INT;
2709 bit_pos = 0;
2710 offset = 0;
2711 while (tok != '}') {
2712 parse_btype(&btype, &ad);
2713 while (1) {
2714 bit_size = -1;
2715 v = 0;
2716 type1 = btype;
2717 if (tok != ':') {
2718 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2719 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2720 expect("identifier");
2721 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2722 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2723 error("invalid type for '%s'",
2724 get_tok_str(v, NULL));
2726 if (tok == ':') {
2727 next();
2728 bit_size = expr_const();
2729 /* XXX: handle v = 0 case for messages */
2730 if (bit_size < 0)
2731 error("negative width in bit-field '%s'",
2732 get_tok_str(v, NULL));
2733 if (v && bit_size == 0)
2734 error("zero width for bit-field '%s'",
2735 get_tok_str(v, NULL));
2737 size = type_size(&type1, &align);
2738 if (ad.aligned) {
2739 if (align < ad.aligned)
2740 align = ad.aligned;
2741 } else if (ad.packed) {
2742 align = 1;
2743 } else if (*tcc_state->pack_stack_ptr) {
2744 if (align > *tcc_state->pack_stack_ptr)
2745 align = *tcc_state->pack_stack_ptr;
2747 lbit_pos = 0;
2748 if (bit_size >= 0) {
2749 bt = type1.t & VT_BTYPE;
2750 if (bt != VT_INT &&
2751 bt != VT_BYTE &&
2752 bt != VT_SHORT &&
2753 bt != VT_BOOL &&
2754 bt != VT_ENUM &&
2755 bt != VT_LLONG)
2756 error("bitfields must have scalar type");
2757 bsize = size * 8;
2758 if (bit_size > bsize) {
2759 error("width of '%s' exceeds its type",
2760 get_tok_str(v, NULL));
2761 } else if (bit_size == bsize) {
2762 /* no need for bit fields */
2763 bit_pos = 0;
2764 } else if (bit_size == 0) {
2765 /* XXX: what to do if only padding in a
2766 structure ? */
2767 /* zero size: means to pad */
2768 bit_pos = 0;
2769 } else {
2770 /* we do not have enough room ?
2771 did the type change?
2772 is it a union? */
2773 if ((bit_pos + bit_size) > bsize ||
2774 bt != prevbt || a == TOK_UNION)
2775 bit_pos = 0;
2776 lbit_pos = bit_pos;
2777 /* XXX: handle LSB first */
2778 type1.t |= VT_BITFIELD |
2779 (bit_pos << VT_STRUCT_SHIFT) |
2780 (bit_size << (VT_STRUCT_SHIFT + 6));
2781 bit_pos += bit_size;
2783 prevbt = bt;
2784 } else {
2785 bit_pos = 0;
2787 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2788 /* add new memory data only if starting
2789 bit field */
2790 if (lbit_pos == 0) {
2791 if (a == TOK_STRUCT) {
2792 c = (c + align - 1) & -align;
2793 offset = c;
2794 if (size > 0)
2795 c += size;
2796 } else {
2797 offset = 0;
2798 if (size > c)
2799 c = size;
2801 if (align > maxalign)
2802 maxalign = align;
2804 #if 0
2805 printf("add field %s offset=%d",
2806 get_tok_str(v, NULL), offset);
2807 if (type1.t & VT_BITFIELD) {
2808 printf(" pos=%d size=%d",
2809 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2810 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2812 printf("\n");
2813 #endif
2815 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2816 ass = type1.ref;
2817 while ((ass = ass->next) != NULL) {
2818 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2819 *ps = ss;
2820 ps = &ss->next;
2822 } else if (v) {
2823 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2824 *ps = ss;
2825 ps = &ss->next;
2827 if (tok == ';' || tok == TOK_EOF)
2828 break;
2829 skip(',');
2831 skip(';');
2833 skip('}');
2834 /* store size and alignment */
2835 s->c = (c + maxalign - 1) & -maxalign;
2836 s->r = maxalign;
2841 /* return 0 if no type declaration. otherwise, return the basic type
2842 and skip it.
2844 static int parse_btype(CType *type, AttributeDef *ad)
2846 int t, u, type_found, typespec_found, typedef_found;
2847 Sym *s;
2848 CType type1;
2850 memset(ad, 0, sizeof(AttributeDef));
2851 type_found = 0;
2852 typespec_found = 0;
2853 typedef_found = 0;
2854 t = 0;
2855 while(1) {
2856 switch(tok) {
2857 case TOK_EXTENSION:
2858 /* currently, we really ignore extension */
2859 next();
2860 continue;
2862 /* basic types */
2863 case TOK_CHAR:
2864 u = VT_BYTE;
2865 basic_type:
2866 next();
2867 basic_type1:
2868 if ((t & VT_BTYPE) != 0)
2869 error("too many basic types");
2870 t |= u;
2871 typespec_found = 1;
2872 break;
2873 case TOK_VOID:
2874 u = VT_VOID;
2875 goto basic_type;
2876 case TOK_SHORT:
2877 u = VT_SHORT;
2878 goto basic_type;
2879 case TOK_INT:
2880 next();
2881 typespec_found = 1;
2882 break;
2883 case TOK_LONG:
2884 next();
2885 if ((t & VT_BTYPE) == VT_DOUBLE) {
2886 #ifndef TCC_TARGET_PE
2887 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2888 #endif
2889 } else if ((t & VT_BTYPE) == VT_LONG) {
2890 t = (t & ~VT_BTYPE) | VT_LLONG;
2891 } else {
2892 u = VT_LONG;
2893 goto basic_type1;
2895 break;
2896 case TOK_BOOL:
2897 u = VT_BOOL;
2898 goto basic_type;
2899 case TOK_FLOAT:
2900 u = VT_FLOAT;
2901 goto basic_type;
2902 case TOK_DOUBLE:
2903 next();
2904 if ((t & VT_BTYPE) == VT_LONG) {
2905 #ifdef TCC_TARGET_PE
2906 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2907 #else
2908 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2909 #endif
2910 } else {
2911 u = VT_DOUBLE;
2912 goto basic_type1;
2914 break;
2915 case TOK_ENUM:
2916 struct_decl(&type1, VT_ENUM);
2917 basic_type2:
2918 u = type1.t;
2919 type->ref = type1.ref;
2920 goto basic_type1;
2921 case TOK_STRUCT:
2922 case TOK_UNION:
2923 struct_decl(&type1, VT_STRUCT);
2924 goto basic_type2;
2926 /* type modifiers */
2927 case TOK_CONST1:
2928 case TOK_CONST2:
2929 case TOK_CONST3:
2930 t |= VT_CONSTANT;
2931 next();
2932 break;
2933 case TOK_VOLATILE1:
2934 case TOK_VOLATILE2:
2935 case TOK_VOLATILE3:
2936 t |= VT_VOLATILE;
2937 next();
2938 break;
2939 case TOK_SIGNED1:
2940 case TOK_SIGNED2:
2941 case TOK_SIGNED3:
2942 typespec_found = 1;
2943 t |= VT_SIGNED;
2944 next();
2945 break;
2946 case TOK_REGISTER:
2947 case TOK_AUTO:
2948 case TOK_RESTRICT1:
2949 case TOK_RESTRICT2:
2950 case TOK_RESTRICT3:
2951 next();
2952 break;
2953 case TOK_UNSIGNED:
2954 t |= VT_UNSIGNED;
2955 next();
2956 typespec_found = 1;
2957 break;
2959 /* storage */
2960 case TOK_EXTERN:
2961 t |= VT_EXTERN;
2962 next();
2963 break;
2964 case TOK_STATIC:
2965 t |= VT_STATIC;
2966 next();
2967 break;
2968 case TOK_TYPEDEF:
2969 t |= VT_TYPEDEF;
2970 next();
2971 break;
2972 case TOK_INLINE1:
2973 case TOK_INLINE2:
2974 case TOK_INLINE3:
2975 t |= VT_INLINE;
2976 next();
2977 break;
2979 /* GNUC attribute */
2980 case TOK_ATTRIBUTE1:
2981 case TOK_ATTRIBUTE2:
2982 parse_attribute(ad);
2983 if (ad->mode) {
2984 u = ad->mode -1;
2985 t = (t & ~VT_BTYPE) | u;
2987 break;
2988 /* GNUC typeof */
2989 case TOK_TYPEOF1:
2990 case TOK_TYPEOF2:
2991 case TOK_TYPEOF3:
2992 next();
2993 parse_expr_type(&type1);
2994 /* remove all storage modifiers except typedef */
2995 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
2996 goto basic_type2;
2997 default:
2998 if (typespec_found || typedef_found)
2999 goto the_end;
3000 s = sym_find(tok);
3001 if (!s || !(s->type.t & VT_TYPEDEF))
3002 goto the_end;
3003 typedef_found = 1;
3004 t |= (s->type.t & ~VT_TYPEDEF);
3005 type->ref = s->type.ref;
3006 if (s->r) {
3007 /* get attributes from typedef */
3008 if (0 == ad->aligned)
3009 ad->aligned = FUNC_ALIGN(s->r);
3010 if (0 == ad->func_call)
3011 ad->func_call = FUNC_CALL(s->r);
3012 ad->packed |= FUNC_PACKED(s->r);
3014 next();
3015 typespec_found = 1;
3016 break;
3018 type_found = 1;
3020 the_end:
3021 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3022 error("signed and unsigned modifier");
3023 if (tcc_state->char_is_unsigned) {
3024 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3025 t |= VT_UNSIGNED;
3027 t &= ~VT_SIGNED;
3029 /* long is never used as type */
3030 if ((t & VT_BTYPE) == VT_LONG)
3031 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3032 t = (t & ~VT_BTYPE) | VT_INT;
3033 #else
3034 t = (t & ~VT_BTYPE) | VT_LLONG;
3035 #endif
3036 type->t = t;
3037 return type_found;
3040 /* convert a function parameter type (array to pointer and function to
3041 function pointer) */
3042 static inline void convert_parameter_type(CType *pt)
3044 /* remove const and volatile qualifiers (XXX: const could be used
3045 to indicate a const function parameter */
3046 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3047 /* array must be transformed to pointer according to ANSI C */
3048 pt->t &= ~VT_ARRAY;
3049 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3050 mk_pointer(pt);
3054 ST_FUNC void parse_asm_str(CString *astr)
3056 skip('(');
3057 /* read the string */
3058 if (tok != TOK_STR)
3059 expect("string constant");
3060 cstr_new(astr);
3061 while (tok == TOK_STR) {
3062 /* XXX: add \0 handling too ? */
3063 cstr_cat(astr, tokc.cstr->data);
3064 next();
3066 cstr_ccat(astr, '\0');
3069 /* Parse an asm label and return the label
3070 * Don't forget to free the CString in the caller! */
3071 static void asm_label_instr(CString *astr)
3073 next();
3074 parse_asm_str(astr);
3075 skip(')');
3076 #ifdef ASM_DEBUG
3077 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3078 #endif
3081 static void post_type(CType *type, AttributeDef *ad)
3083 int n, l, t1, arg_size, align;
3084 Sym **plast, *s, *first;
3085 AttributeDef ad1;
3086 CType pt;
3088 if (tok == '(') {
3089 /* function declaration */
3090 next();
3091 l = 0;
3092 first = NULL;
3093 plast = &first;
3094 arg_size = 0;
3095 if (tok != ')') {
3096 for(;;) {
3097 /* read param name and compute offset */
3098 if (l != FUNC_OLD) {
3099 if (!parse_btype(&pt, &ad1)) {
3100 if (l) {
3101 error("invalid type");
3102 } else {
3103 l = FUNC_OLD;
3104 goto old_proto;
3107 l = FUNC_NEW;
3108 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3109 break;
3110 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3111 if ((pt.t & VT_BTYPE) == VT_VOID)
3112 error("parameter declared as void");
3113 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3114 } else {
3115 old_proto:
3116 n = tok;
3117 if (n < TOK_UIDENT)
3118 expect("identifier");
3119 pt.t = VT_INT;
3120 next();
3122 convert_parameter_type(&pt);
3123 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3124 *plast = s;
3125 plast = &s->next;
3126 if (tok == ')')
3127 break;
3128 skip(',');
3129 if (l == FUNC_NEW && tok == TOK_DOTS) {
3130 l = FUNC_ELLIPSIS;
3131 next();
3132 break;
3136 /* if no parameters, then old type prototype */
3137 if (l == 0)
3138 l = FUNC_OLD;
3139 skip(')');
3140 /* NOTE: const is ignored in returned type as it has a special
3141 meaning in gcc / C++ */
3142 type->t &= ~VT_CONSTANT;
3143 /* some ancient pre-K&R C allows a function to return an array
3144 and the array brackets to be put after the arguments, such
3145 that "int c()[]" means something like "int[] c()" */
3146 if (tok == '[') {
3147 next();
3148 skip(']'); /* only handle simple "[]" */
3149 type->t |= VT_PTR;
3151 /* we push a anonymous symbol which will contain the function prototype */
3152 ad->func_args = arg_size;
3153 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3154 s->next = first;
3155 type->t = VT_FUNC;
3156 type->ref = s;
3157 } else if (tok == '[') {
3158 /* array definition */
3159 next();
3160 if (tok == TOK_RESTRICT1)
3161 next();
3162 n = -1;
3163 t1 = 0;
3164 if (tok != ']') {
3165 gexpr();
3166 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3167 n = vtop->c.i;
3168 if (n < 0)
3169 error("invalid array size");
3170 } else if (!local_stack) {
3171 error("expected constant expression (variably modified array at file scope)");
3172 } else {
3173 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3174 error("size of variable length array should be an integer");
3175 t1 = VT_VLA;
3178 skip(']');
3179 /* parse next post type */
3180 post_type(type, ad);
3181 t1 |= type->t & VT_VLA;
3183 if (t1 & VT_VLA) {
3184 loc -= type_size(&int_type, &align);
3185 loc &= -align;
3186 n = loc;
3188 vla_runtime_type_size(type, &align);
3189 gen_op('*');
3190 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3191 vswap();
3192 vstore();
3194 if (n != -1)
3195 vpop();
3197 /* we push an anonymous symbol which will contain the array
3198 element type */
3199 s = sym_push(SYM_FIELD, type, 0, n);
3200 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3201 type->ref = s;
3205 /* Parse a type declaration (except basic type), and return the type
3206 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3207 expected. 'type' should contain the basic type. 'ad' is the
3208 attribute definition of the basic type. It can be modified by
3209 type_decl().
3211 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3213 Sym *s;
3214 CType type1, *type2;
3215 int qualifiers, storage;
3217 while (tok == '*') {
3218 qualifiers = 0;
3219 redo:
3220 next();
3221 switch(tok) {
3222 case TOK_CONST1:
3223 case TOK_CONST2:
3224 case TOK_CONST3:
3225 qualifiers |= VT_CONSTANT;
3226 goto redo;
3227 case TOK_VOLATILE1:
3228 case TOK_VOLATILE2:
3229 case TOK_VOLATILE3:
3230 qualifiers |= VT_VOLATILE;
3231 goto redo;
3232 case TOK_RESTRICT1:
3233 case TOK_RESTRICT2:
3234 case TOK_RESTRICT3:
3235 goto redo;
3237 mk_pointer(type);
3238 type->t |= qualifiers;
3241 /* XXX: clarify attribute handling */
3242 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3243 parse_attribute(ad);
3245 /* recursive type */
3246 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3247 type1.t = 0; /* XXX: same as int */
3248 if (tok == '(') {
3249 next();
3250 /* XXX: this is not correct to modify 'ad' at this point, but
3251 the syntax is not clear */
3252 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3253 parse_attribute(ad);
3254 type_decl(&type1, ad, v, td);
3255 skip(')');
3256 } else {
3257 /* type identifier */
3258 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3259 *v = tok;
3260 next();
3261 } else {
3262 if (!(td & TYPE_ABSTRACT))
3263 expect("identifier");
3264 *v = 0;
3267 storage = type->t & VT_STORAGE;
3268 type->t &= ~VT_STORAGE;
3269 post_type(type, ad);
3270 type->t |= storage;
3271 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3272 parse_attribute(ad);
3274 if (!type1.t)
3275 return;
3276 /* append type at the end of type1 */
3277 type2 = &type1;
3278 for(;;) {
3279 s = type2->ref;
3280 type2 = &s->type;
3281 if (!type2->t) {
3282 *type2 = *type;
3283 break;
3286 *type = type1;
3289 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3290 ST_FUNC int lvalue_type(int t)
3292 int bt, r;
3293 r = VT_LVAL;
3294 bt = t & VT_BTYPE;
3295 if (bt == VT_BYTE || bt == VT_BOOL)
3296 r |= VT_LVAL_BYTE;
3297 else if (bt == VT_SHORT)
3298 r |= VT_LVAL_SHORT;
3299 else
3300 return r;
3301 if (t & VT_UNSIGNED)
3302 r |= VT_LVAL_UNSIGNED;
3303 return r;
3306 /* indirection with full error checking and bound check */
3307 ST_FUNC void indir(void)
3309 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3310 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3311 return;
3312 expect("pointer");
3314 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3315 gv(RC_INT);
3316 vtop->type = *pointed_type(&vtop->type);
3317 /* Arrays and functions are never lvalues */
3318 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3319 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3320 vtop->r |= lvalue_type(vtop->type.t);
3321 /* if bound checking, the referenced pointer must be checked */
3322 #ifdef CONFIG_TCC_BCHECK
3323 if (tcc_state->do_bounds_check)
3324 vtop->r |= VT_MUSTBOUND;
3325 #endif
3329 /* pass a parameter to a function and do type checking and casting */
3330 static void gfunc_param_typed(Sym *func, Sym *arg)
3332 int func_type;
3333 CType type;
3335 func_type = func->c;
3336 if (func_type == FUNC_OLD ||
3337 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3338 /* default casting : only need to convert float to double */
3339 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3340 type.t = VT_DOUBLE;
3341 gen_cast(&type);
3343 } else if (arg == NULL) {
3344 error("too many arguments to function");
3345 } else {
3346 type = arg->type;
3347 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3348 gen_assign_cast(&type);
3352 /* parse an expression of the form '(type)' or '(expr)' and return its
3353 type */
3354 static void parse_expr_type(CType *type)
3356 int n;
3357 AttributeDef ad;
3359 skip('(');
3360 if (parse_btype(type, &ad)) {
3361 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3362 } else {
3363 expr_type(type);
3365 skip(')');
3368 static void parse_type(CType *type)
3370 AttributeDef ad;
3371 int n;
3373 if (!parse_btype(type, &ad)) {
3374 expect("type");
3376 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3379 static void vpush_tokc(int t)
3381 CType type;
3382 type.t = t;
3383 type.ref = 0;
3384 vsetc(&type, VT_CONST, &tokc);
3387 ST_FUNC void unary(void)
3389 int n, t, align, size, r, sizeof_caller;
3390 CType type;
3391 Sym *s;
3392 AttributeDef ad;
3393 static int in_sizeof = 0;
3395 sizeof_caller = in_sizeof;
3396 in_sizeof = 0;
3397 /* XXX: GCC 2.95.3 does not generate a table although it should be
3398 better here */
3399 tok_next:
3400 switch(tok) {
3401 case TOK_EXTENSION:
3402 next();
3403 goto tok_next;
3404 case TOK_CINT:
3405 case TOK_CCHAR:
3406 case TOK_LCHAR:
3407 vpushi(tokc.i);
3408 next();
3409 break;
3410 case TOK_CUINT:
3411 vpush_tokc(VT_INT | VT_UNSIGNED);
3412 next();
3413 break;
3414 case TOK_CLLONG:
3415 vpush_tokc(VT_LLONG);
3416 next();
3417 break;
3418 case TOK_CULLONG:
3419 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3420 next();
3421 break;
3422 case TOK_CFLOAT:
3423 vpush_tokc(VT_FLOAT);
3424 next();
3425 break;
3426 case TOK_CDOUBLE:
3427 vpush_tokc(VT_DOUBLE);
3428 next();
3429 break;
3430 case TOK_CLDOUBLE:
3431 vpush_tokc(VT_LDOUBLE);
3432 next();
3433 break;
3434 case TOK___FUNCTION__:
3435 if (!gnu_ext)
3436 goto tok_identifier;
3437 /* fall thru */
3438 case TOK___FUNC__:
3440 void *ptr;
3441 int len;
3442 /* special function name identifier */
3443 len = strlen(funcname) + 1;
3444 /* generate char[len] type */
3445 type.t = VT_BYTE;
3446 mk_pointer(&type);
3447 type.t |= VT_ARRAY;
3448 type.ref->c = len;
3449 vpush_ref(&type, data_section, data_section->data_offset, len);
3450 ptr = section_ptr_add(data_section, len);
3451 memcpy(ptr, funcname, len);
3452 next();
3454 break;
3455 case TOK_LSTR:
3456 #ifdef TCC_TARGET_PE
3457 t = VT_SHORT | VT_UNSIGNED;
3458 #else
3459 t = VT_INT;
3460 #endif
3461 goto str_init;
3462 case TOK_STR:
3463 /* string parsing */
3464 t = VT_BYTE;
3465 str_init:
3466 if (tcc_state->warn_write_strings)
3467 t |= VT_CONSTANT;
3468 type.t = t;
3469 mk_pointer(&type);
3470 type.t |= VT_ARRAY;
3471 memset(&ad, 0, sizeof(AttributeDef));
3472 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3473 break;
3474 case '(':
3475 next();
3476 /* cast ? */
3477 if (parse_btype(&type, &ad)) {
3478 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3479 skip(')');
3480 /* check ISOC99 compound literal */
3481 if (tok == '{') {
3482 /* data is allocated locally by default */
3483 if (global_expr)
3484 r = VT_CONST;
3485 else
3486 r = VT_LOCAL;
3487 /* all except arrays are lvalues */
3488 if (!(type.t & VT_ARRAY))
3489 r |= lvalue_type(type.t);
3490 memset(&ad, 0, sizeof(AttributeDef));
3491 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3492 } else {
3493 if (sizeof_caller) {
3494 vpush(&type);
3495 return;
3497 unary();
3498 gen_cast(&type);
3500 } else if (tok == '{') {
3501 /* save all registers */
3502 save_regs(0);
3503 /* statement expression : we do not accept break/continue
3504 inside as GCC does */
3505 block(NULL, NULL, NULL, NULL, 0, 1);
3506 skip(')');
3507 } else {
3508 gexpr();
3509 skip(')');
3511 break;
3512 case '*':
3513 next();
3514 unary();
3515 indir();
3516 break;
3517 case '&':
3518 next();
3519 unary();
3520 /* functions names must be treated as function pointers,
3521 except for unary '&' and sizeof. Since we consider that
3522 functions are not lvalues, we only have to handle it
3523 there and in function calls. */
3524 /* arrays can also be used although they are not lvalues */
3525 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3526 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3527 test_lvalue();
3528 mk_pointer(&vtop->type);
3529 gaddrof();
3530 break;
3531 case '!':
3532 next();
3533 unary();
3534 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3535 CType boolean;
3536 boolean.t = VT_BOOL;
3537 gen_cast(&boolean);
3538 vtop->c.i = !vtop->c.i;
3539 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3540 vtop->c.i = vtop->c.i ^ 1;
3541 else {
3542 save_regs(1);
3543 vseti(VT_JMP, gtst(1, 0));
3545 break;
3546 case '~':
3547 next();
3548 unary();
3549 vpushi(-1);
3550 gen_op('^');
3551 break;
3552 case '+':
3553 next();
3554 /* in order to force cast, we add zero */
3555 unary();
3556 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3557 error("pointer not accepted for unary plus");
3558 vpushi(0);
3559 gen_op('+');
3560 break;
3561 case TOK_SIZEOF:
3562 case TOK_ALIGNOF1:
3563 case TOK_ALIGNOF2:
3564 t = tok;
3565 next();
3566 in_sizeof++;
3567 unary_type(&type); // Perform a in_sizeof = 0;
3568 size = type_size(&type, &align);
3569 if (t == TOK_SIZEOF) {
3570 if (!(type.t & VT_VLA)) {
3571 if (size < 0)
3572 error("sizeof applied to an incomplete type");
3573 vpushi(size);
3574 } else {
3575 vla_runtime_type_size(&type, &align);
3577 } else {
3578 vpushi(align);
3580 vtop->type.t |= VT_UNSIGNED;
3581 break;
3583 case TOK_builtin_types_compatible_p:
3585 CType type1, type2;
3586 next();
3587 skip('(');
3588 parse_type(&type1);
3589 skip(',');
3590 parse_type(&type2);
3591 skip(')');
3592 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3593 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3594 vpushi(is_compatible_types(&type1, &type2));
3596 break;
3597 case TOK_builtin_constant_p:
3599 int saved_nocode_wanted, res;
3600 next();
3601 skip('(');
3602 saved_nocode_wanted = nocode_wanted;
3603 nocode_wanted = 1;
3604 gexpr();
3605 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3606 vpop();
3607 nocode_wanted = saved_nocode_wanted;
3608 skip(')');
3609 vpushi(res);
3611 break;
3612 case TOK_builtin_frame_address:
3614 CType type;
3615 next();
3616 skip('(');
3617 if (tok != TOK_CINT) {
3618 error("__builtin_frame_address only takes integers");
3620 if (tokc.i != 0) {
3621 error("TCC only supports __builtin_frame_address(0)");
3623 next();
3624 skip(')');
3625 type.t = VT_VOID;
3626 mk_pointer(&type);
3627 vset(&type, VT_LOCAL, 0);
3629 break;
3630 #ifdef TCC_TARGET_X86_64
3631 case TOK_builtin_va_arg_types:
3633 /* This definition must be synced with stdarg.h */
3634 enum __va_arg_type {
3635 __va_gen_reg, __va_float_reg, __va_stack
3637 CType type;
3638 int bt;
3639 next();
3640 skip('(');
3641 parse_type(&type);
3642 skip(')');
3643 bt = type.t & VT_BTYPE;
3644 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3645 vpushi(__va_stack);
3646 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3647 vpushi(__va_float_reg);
3648 } else {
3649 vpushi(__va_gen_reg);
3652 break;
3653 #endif
3654 case TOK_INC:
3655 case TOK_DEC:
3656 t = tok;
3657 next();
3658 unary();
3659 inc(0, t);
3660 break;
3661 case '-':
3662 next();
3663 vpushi(0);
3664 unary();
3665 gen_op('-');
3666 break;
3667 case TOK_LAND:
3668 if (!gnu_ext)
3669 goto tok_identifier;
3670 next();
3671 /* allow to take the address of a label */
3672 if (tok < TOK_UIDENT)
3673 expect("label identifier");
3674 s = label_find(tok);
3675 if (!s) {
3676 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3677 } else {
3678 if (s->r == LABEL_DECLARED)
3679 s->r = LABEL_FORWARD;
3681 if (!s->type.t) {
3682 s->type.t = VT_VOID;
3683 mk_pointer(&s->type);
3684 s->type.t |= VT_STATIC;
3686 vset(&s->type, VT_CONST | VT_SYM, 0);
3687 vtop->sym = s;
3688 next();
3689 break;
3691 // special qnan , snan and infinity values
3692 case TOK___NAN__:
3693 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3694 next();
3695 break;
3696 case TOK___SNAN__:
3697 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3698 next();
3699 break;
3700 case TOK___INF__:
3701 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3702 next();
3703 break;
3705 default:
3706 tok_identifier:
3707 t = tok;
3708 next();
3709 if (t < TOK_UIDENT)
3710 expect("identifier");
3711 s = sym_find(t);
3712 if (!s) {
3713 if (tok != '(')
3714 error("'%s' undeclared", get_tok_str(t, NULL));
3715 /* for simple function calls, we tolerate undeclared
3716 external reference to int() function */
3717 if (tcc_state->warn_implicit_function_declaration)
3718 warning("implicit declaration of function '%s'",
3719 get_tok_str(t, NULL));
3720 s = external_global_sym(t, &func_old_type, 0);
3722 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3723 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3724 /* if referencing an inline function, then we generate a
3725 symbol to it if not already done. It will have the
3726 effect to generate code for it at the end of the
3727 compilation unit. Inline function as always
3728 generated in the text section. */
3729 if (!s->c)
3730 put_extern_sym(s, text_section, 0, 0);
3731 r = VT_SYM | VT_CONST;
3732 } else {
3733 r = s->r;
3735 vset(&s->type, r, s->c);
3736 /* if forward reference, we must point to s */
3737 if (vtop->r & VT_SYM) {
3738 vtop->sym = s;
3739 vtop->c.ul = 0;
3741 break;
3744 /* post operations */
3745 while (1) {
3746 if (tok == TOK_INC || tok == TOK_DEC) {
3747 inc(1, tok);
3748 next();
3749 } else if (tok == '.' || tok == TOK_ARROW) {
3750 int qualifiers;
3751 /* field */
3752 if (tok == TOK_ARROW)
3753 indir();
3754 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3755 test_lvalue();
3756 gaddrof();
3757 next();
3758 /* expect pointer on structure */
3759 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3760 expect("struct or union");
3761 s = vtop->type.ref;
3762 /* find field */
3763 tok |= SYM_FIELD;
3764 while ((s = s->next) != NULL) {
3765 if (s->v == tok)
3766 break;
3768 if (!s)
3769 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3770 /* add field offset to pointer */
3771 vtop->type = char_pointer_type; /* change type to 'char *' */
3772 vpushi(s->c);
3773 gen_op('+');
3774 /* change type to field type, and set to lvalue */
3775 vtop->type = s->type;
3776 vtop->type.t |= qualifiers;
3777 /* an array is never an lvalue */
3778 if (!(vtop->type.t & VT_ARRAY)) {
3779 vtop->r |= lvalue_type(vtop->type.t);
3780 #ifdef CONFIG_TCC_BCHECK
3781 /* if bound checking, the referenced pointer must be checked */
3782 if (tcc_state->do_bounds_check)
3783 vtop->r |= VT_MUSTBOUND;
3784 #endif
3786 next();
3787 } else if (tok == '[') {
3788 next();
3789 gexpr();
3790 gen_op('+');
3791 indir();
3792 skip(']');
3793 } else if (tok == '(') {
3794 SValue ret;
3795 Sym *sa;
3796 int nb_args;
3798 /* function call */
3799 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3800 /* pointer test (no array accepted) */
3801 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3802 vtop->type = *pointed_type(&vtop->type);
3803 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3804 goto error_func;
3805 } else {
3806 error_func:
3807 expect("function pointer");
3809 } else {
3810 vtop->r &= ~VT_LVAL; /* no lvalue */
3812 /* get return type */
3813 s = vtop->type.ref;
3814 next();
3815 sa = s->next; /* first parameter */
3816 nb_args = 0;
3817 ret.r2 = VT_CONST;
3818 /* compute first implicit argument if a structure is returned */
3819 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3820 /* get some space for the returned structure */
3821 size = type_size(&s->type, &align);
3822 loc = (loc - size) & -align;
3823 ret.type = s->type;
3824 ret.r = VT_LOCAL | VT_LVAL;
3825 /* pass it as 'int' to avoid structure arg passing
3826 problems */
3827 vseti(VT_LOCAL, loc);
3828 ret.c = vtop->c;
3829 nb_args++;
3830 } else {
3831 ret.type = s->type;
3832 /* return in register */
3833 if (is_float(ret.type.t)) {
3834 ret.r = reg_fret(ret.type.t);
3835 } else {
3836 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3837 ret.r2 = REG_LRET;
3838 ret.r = REG_IRET;
3840 ret.c.i = 0;
3842 if (tok != ')') {
3843 for(;;) {
3844 expr_eq();
3845 gfunc_param_typed(s, sa);
3846 nb_args++;
3847 if (sa)
3848 sa = sa->next;
3849 if (tok == ')')
3850 break;
3851 skip(',');
3854 if (sa)
3855 error("too few arguments to function");
3856 skip(')');
3857 if (!nocode_wanted) {
3858 gfunc_call(nb_args);
3859 } else {
3860 vtop -= (nb_args + 1);
3862 /* return value */
3863 vsetc(&ret.type, ret.r, &ret.c);
3864 vtop->r2 = ret.r2;
3865 } else {
3866 break;
3871 ST_FUNC void expr_prod(void)
3873 int t;
3875 unary();
3876 while (tok == '*' || tok == '/' || tok == '%') {
3877 t = tok;
3878 next();
3879 unary();
3880 gen_op(t);
3884 ST_FUNC void expr_sum(void)
3886 int t;
3888 expr_prod();
3889 while (tok == '+' || tok == '-') {
3890 t = tok;
3891 next();
3892 expr_prod();
3893 gen_op(t);
3897 static void expr_shift(void)
3899 int t;
3901 expr_sum();
3902 while (tok == TOK_SHL || tok == TOK_SAR) {
3903 t = tok;
3904 next();
3905 expr_sum();
3906 gen_op(t);
3910 static void expr_cmp(void)
3912 int t;
3914 expr_shift();
3915 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3916 tok == TOK_ULT || tok == TOK_UGE) {
3917 t = tok;
3918 next();
3919 expr_shift();
3920 gen_op(t);
3924 static void expr_cmpeq(void)
3926 int t;
3928 expr_cmp();
3929 while (tok == TOK_EQ || tok == TOK_NE) {
3930 t = tok;
3931 next();
3932 expr_cmp();
3933 gen_op(t);
3937 static void expr_and(void)
3939 expr_cmpeq();
3940 while (tok == '&') {
3941 next();
3942 expr_cmpeq();
3943 gen_op('&');
3947 static void expr_xor(void)
3949 expr_and();
3950 while (tok == '^') {
3951 next();
3952 expr_and();
3953 gen_op('^');
3957 static void expr_or(void)
3959 expr_xor();
3960 while (tok == '|') {
3961 next();
3962 expr_xor();
3963 gen_op('|');
3967 /* XXX: fix this mess */
3968 static void expr_land_const(void)
3970 expr_or();
3971 while (tok == TOK_LAND) {
3972 next();
3973 expr_or();
3974 gen_op(TOK_LAND);
3978 /* XXX: fix this mess */
3979 static void expr_lor_const(void)
3981 expr_land_const();
3982 while (tok == TOK_LOR) {
3983 next();
3984 expr_land_const();
3985 gen_op(TOK_LOR);
3989 /* only used if non constant */
3990 static void expr_land(void)
3992 int t;
3994 expr_or();
3995 if (tok == TOK_LAND) {
3996 t = 0;
3997 save_regs(1);
3998 for(;;) {
3999 t = gtst(1, t);
4000 if (tok != TOK_LAND) {
4001 vseti(VT_JMPI, t);
4002 break;
4004 next();
4005 expr_or();
4010 static void expr_lor(void)
4012 int t;
4014 expr_land();
4015 if (tok == TOK_LOR) {
4016 t = 0;
4017 save_regs(1);
4018 for(;;) {
4019 t = gtst(0, t);
4020 if (tok != TOK_LOR) {
4021 vseti(VT_JMP, t);
4022 break;
4024 next();
4025 expr_land();
4030 /* XXX: better constant handling */
4031 static void expr_cond(void)
4033 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4034 SValue sv;
4035 CType type, type1, type2;
4037 if (const_wanted) {
4038 expr_lor_const();
4039 } else {
4040 expr_lor();
4042 if (const_wanted || ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)) {
4043 if (tok == '?') {
4044 CType boolean;
4045 int c;
4046 boolean.t = VT_BOOL;
4047 vdup();
4048 gen_cast(&boolean);
4049 c = vtop->c.i;
4050 vpop();
4051 next();
4052 if (tok != ':' || !gnu_ext) {
4053 vpop();
4054 gexpr();
4056 if (!c)
4057 vpop();
4058 skip(':');
4059 expr_cond();
4060 if (c)
4061 vpop();
4063 } else {
4064 if (tok == '?') {
4065 next();
4066 if (vtop != vstack) {
4067 /* needed to avoid having different registers saved in
4068 each branch */
4069 if (is_float(vtop->type.t)) {
4070 rc = RC_FLOAT;
4071 #ifdef TCC_TARGET_X86_64
4072 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4073 rc = RC_ST0;
4075 #endif
4077 else
4078 rc = RC_INT;
4079 gv(rc);
4080 save_regs(1);
4082 if (tok == ':' && gnu_ext) {
4083 gv_dup();
4084 tt = gtst(1, 0);
4085 } else {
4086 tt = gtst(1, 0);
4087 gexpr();
4089 type1 = vtop->type;
4090 sv = *vtop; /* save value to handle it later */
4091 vtop--; /* no vpop so that FP stack is not flushed */
4092 skip(':');
4093 u = gjmp(0);
4094 gsym(tt);
4095 expr_cond();
4096 type2 = vtop->type;
4098 t1 = type1.t;
4099 bt1 = t1 & VT_BTYPE;
4100 t2 = type2.t;
4101 bt2 = t2 & VT_BTYPE;
4102 /* cast operands to correct type according to ISOC rules */
4103 if (is_float(bt1) || is_float(bt2)) {
4104 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4105 type.t = VT_LDOUBLE;
4106 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4107 type.t = VT_DOUBLE;
4108 } else {
4109 type.t = VT_FLOAT;
4111 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4112 /* cast to biggest op */
4113 type.t = VT_LLONG;
4114 /* convert to unsigned if it does not fit in a long long */
4115 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4116 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4117 type.t |= VT_UNSIGNED;
4118 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4119 /* XXX: test pointer compatibility */
4120 type = type1;
4121 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4122 /* XXX: test function pointer compatibility */
4123 type = type1;
4124 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4125 /* XXX: test structure compatibility */
4126 type = type1;
4127 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4128 /* NOTE: as an extension, we accept void on only one side */
4129 type.t = VT_VOID;
4130 } else {
4131 /* integer operations */
4132 type.t = VT_INT;
4133 /* convert to unsigned if it does not fit in an integer */
4134 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4135 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4136 type.t |= VT_UNSIGNED;
4139 /* now we convert second operand */
4140 gen_cast(&type);
4141 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4142 gaddrof();
4143 rc = RC_INT;
4144 if (is_float(type.t)) {
4145 rc = RC_FLOAT;
4146 #ifdef TCC_TARGET_X86_64
4147 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4148 rc = RC_ST0;
4150 #endif
4151 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4152 /* for long longs, we use fixed registers to avoid having
4153 to handle a complicated move */
4154 rc = RC_IRET;
4157 r2 = gv(rc);
4158 /* this is horrible, but we must also convert first
4159 operand */
4160 tt = gjmp(0);
4161 gsym(u);
4162 /* put again first value and cast it */
4163 *vtop = sv;
4164 gen_cast(&type);
4165 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4166 gaddrof();
4167 r1 = gv(rc);
4168 move_reg(r2, r1);
4169 vtop->r = r2;
4170 gsym(tt);
4175 static void expr_eq(void)
4177 int t;
4179 expr_cond();
4180 if (tok == '=' ||
4181 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4182 tok == TOK_A_XOR || tok == TOK_A_OR ||
4183 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4184 test_lvalue();
4185 t = tok;
4186 next();
4187 if (t == '=') {
4188 expr_eq();
4189 } else {
4190 vdup();
4191 expr_eq();
4192 gen_op(t & 0x7f);
4194 vstore();
4198 ST_FUNC void gexpr(void)
4200 while (1) {
4201 expr_eq();
4202 if (tok != ',')
4203 break;
4204 vpop();
4205 next();
4209 /* parse an expression and return its type without any side effect. */
4210 static void expr_type(CType *type)
4212 int saved_nocode_wanted;
4214 saved_nocode_wanted = nocode_wanted;
4215 nocode_wanted = 1;
4216 gexpr();
4217 *type = vtop->type;
4218 vpop();
4219 nocode_wanted = saved_nocode_wanted;
4222 /* parse a unary expression and return its type without any side
4223 effect. */
4224 static void unary_type(CType *type)
4226 int a;
4228 a = nocode_wanted;
4229 nocode_wanted = 1;
4230 unary();
4231 *type = vtop->type;
4232 vpop();
4233 nocode_wanted = a;
4236 /* parse a constant expression and return value in vtop. */
4237 static void expr_const1(void)
4239 int a;
4240 a = const_wanted;
4241 const_wanted = 1;
4242 expr_cond();
4243 const_wanted = a;
4246 /* parse an integer constant and return its value. */
4247 ST_FUNC int expr_const(void)
4249 int c;
4250 expr_const1();
4251 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4252 expect("constant expression");
4253 c = vtop->c.i;
4254 vpop();
4255 return c;
4258 /* return the label token if current token is a label, otherwise
4259 return zero */
4260 static int is_label(void)
4262 int last_tok;
4264 /* fast test first */
4265 if (tok < TOK_UIDENT)
4266 return 0;
4267 /* no need to save tokc because tok is an identifier */
4268 last_tok = tok;
4269 next();
4270 if (tok == ':') {
4271 next();
4272 return last_tok;
4273 } else {
4274 unget_tok(last_tok);
4275 return 0;
4279 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4280 int case_reg, int is_expr)
4282 int a, b, c, d;
4283 Sym *s;
4285 /* generate line number info */
4286 if (tcc_state->do_debug &&
4287 (last_line_num != file->line_num || last_ind != ind)) {
4288 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4289 last_ind = ind;
4290 last_line_num = file->line_num;
4293 if (is_expr) {
4294 /* default return value is (void) */
4295 vpushi(0);
4296 vtop->type.t = VT_VOID;
4299 if (tok == TOK_IF) {
4300 /* if test */
4301 next();
4302 skip('(');
4303 gexpr();
4304 skip(')');
4305 a = gtst(1, 0);
4306 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4307 c = tok;
4308 if (c == TOK_ELSE) {
4309 next();
4310 d = gjmp(0);
4311 gsym(a);
4312 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4313 gsym(d); /* patch else jmp */
4314 } else
4315 gsym(a);
4316 } else if (tok == TOK_WHILE) {
4317 next();
4318 d = ind;
4319 skip('(');
4320 gexpr();
4321 skip(')');
4322 a = gtst(1, 0);
4323 b = 0;
4324 block(&a, &b, case_sym, def_sym, case_reg, 0);
4325 gjmp_addr(d);
4326 gsym(a);
4327 gsym_addr(b, d);
4328 } else if (tok == '{') {
4329 Sym *llabel;
4331 next();
4332 /* record local declaration stack position */
4333 s = local_stack;
4334 llabel = local_label_stack;
4335 /* handle local labels declarations */
4336 if (tok == TOK_LABEL) {
4337 next();
4338 for(;;) {
4339 if (tok < TOK_UIDENT)
4340 expect("label identifier");
4341 label_push(&local_label_stack, tok, LABEL_DECLARED);
4342 next();
4343 if (tok == ',') {
4344 next();
4345 } else {
4346 skip(';');
4347 break;
4351 while (tok != '}') {
4352 decl(VT_LOCAL);
4353 if (tok != '}') {
4354 if (is_expr)
4355 vpop();
4356 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4359 /* pop locally defined labels */
4360 label_pop(&local_label_stack, llabel);
4361 if(is_expr) {
4362 /* XXX: this solution makes only valgrind happy...
4363 triggered by gcc.c-torture/execute/20000917-1.c */
4364 Sym *p;
4365 switch(vtop->type.t & VT_BTYPE) {
4366 case VT_PTR:
4367 case VT_STRUCT:
4368 case VT_ENUM:
4369 case VT_FUNC:
4370 for(p=vtop->type.ref;p;p=p->prev)
4371 if(p->prev==s)
4372 error("unsupported expression type");
4375 /* pop locally defined symbols */
4376 sym_pop(&local_stack, s);
4377 next();
4378 } else if (tok == TOK_RETURN) {
4379 next();
4380 if (tok != ';') {
4381 gexpr();
4382 gen_assign_cast(&func_vt);
4383 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4384 CType type;
4385 /* if returning structure, must copy it to implicit
4386 first pointer arg location */
4387 #ifdef TCC_ARM_EABI
4388 int align, size;
4389 size = type_size(&func_vt,&align);
4390 if(size <= 4)
4392 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4393 && (align & 3))
4395 int addr;
4396 loc = (loc - size) & -4;
4397 addr = loc;
4398 type = func_vt;
4399 vset(&type, VT_LOCAL | VT_LVAL, addr);
4400 vswap();
4401 vstore();
4402 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4404 vtop->type = int_type;
4405 gv(RC_IRET);
4406 } else {
4407 #endif
4408 type = func_vt;
4409 mk_pointer(&type);
4410 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4411 indir();
4412 vswap();
4413 /* copy structure value to pointer */
4414 vstore();
4415 #ifdef TCC_ARM_EABI
4417 #endif
4418 } else if (is_float(func_vt.t)) {
4419 gv(rc_fret(func_vt.t));
4420 } else {
4421 gv(RC_IRET);
4423 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4425 skip(';');
4426 rsym = gjmp(rsym); /* jmp */
4427 } else if (tok == TOK_BREAK) {
4428 /* compute jump */
4429 if (!bsym)
4430 error("cannot break");
4431 *bsym = gjmp(*bsym);
4432 next();
4433 skip(';');
4434 } else if (tok == TOK_CONTINUE) {
4435 /* compute jump */
4436 if (!csym)
4437 error("cannot continue");
4438 *csym = gjmp(*csym);
4439 next();
4440 skip(';');
4441 } else if (tok == TOK_FOR) {
4442 int e;
4443 next();
4444 skip('(');
4445 s = local_stack;
4446 if (tok != ';') {
4447 /* c99 for-loop init decl? */
4448 if (!decl0(VT_LOCAL, 1)) {
4449 /* no, regular for-loop init expr */
4450 gexpr();
4451 vpop();
4454 skip(';');
4455 d = ind;
4456 c = ind;
4457 a = 0;
4458 b = 0;
4459 if (tok != ';') {
4460 gexpr();
4461 a = gtst(1, 0);
4463 skip(';');
4464 if (tok != ')') {
4465 e = gjmp(0);
4466 c = ind;
4467 gexpr();
4468 vpop();
4469 gjmp_addr(d);
4470 gsym(e);
4472 skip(')');
4473 block(&a, &b, case_sym, def_sym, case_reg, 0);
4474 gjmp_addr(c);
4475 gsym(a);
4476 gsym_addr(b, c);
4477 sym_pop(&local_stack, s);
4478 } else
4479 if (tok == TOK_DO) {
4480 next();
4481 a = 0;
4482 b = 0;
4483 d = ind;
4484 block(&a, &b, case_sym, def_sym, case_reg, 0);
4485 skip(TOK_WHILE);
4486 skip('(');
4487 gsym(b);
4488 gexpr();
4489 c = gtst(0, 0);
4490 gsym_addr(c, d);
4491 skip(')');
4492 gsym(a);
4493 skip(';');
4494 } else
4495 if (tok == TOK_SWITCH) {
4496 next();
4497 skip('(');
4498 gexpr();
4499 /* XXX: other types than integer */
4500 case_reg = gv(RC_INT);
4501 vpop();
4502 skip(')');
4503 a = 0;
4504 b = gjmp(0); /* jump to first case */
4505 c = 0;
4506 block(&a, csym, &b, &c, case_reg, 0);
4507 /* if no default, jmp after switch */
4508 if (c == 0)
4509 c = ind;
4510 /* default label */
4511 gsym_addr(b, c);
4512 /* break label */
4513 gsym(a);
4514 } else
4515 if (tok == TOK_CASE) {
4516 int v1, v2;
4517 if (!case_sym)
4518 expect("switch");
4519 next();
4520 v1 = expr_const();
4521 v2 = v1;
4522 if (gnu_ext && tok == TOK_DOTS) {
4523 next();
4524 v2 = expr_const();
4525 if (v2 < v1)
4526 warning("empty case range");
4528 /* since a case is like a label, we must skip it with a jmp */
4529 b = gjmp(0);
4530 gsym(*case_sym);
4531 vseti(case_reg, 0);
4532 vpushi(v1);
4533 if (v1 == v2) {
4534 gen_op(TOK_EQ);
4535 *case_sym = gtst(1, 0);
4536 } else {
4537 gen_op(TOK_GE);
4538 *case_sym = gtst(1, 0);
4539 vseti(case_reg, 0);
4540 vpushi(v2);
4541 gen_op(TOK_LE);
4542 *case_sym = gtst(1, *case_sym);
4544 gsym(b);
4545 skip(':');
4546 is_expr = 0;
4547 goto block_after_label;
4548 } else
4549 if (tok == TOK_DEFAULT) {
4550 next();
4551 skip(':');
4552 if (!def_sym)
4553 expect("switch");
4554 if (*def_sym)
4555 error("too many 'default'");
4556 *def_sym = ind;
4557 is_expr = 0;
4558 goto block_after_label;
4559 } else
4560 if (tok == TOK_GOTO) {
4561 next();
4562 if (tok == '*' && gnu_ext) {
4563 /* computed goto */
4564 next();
4565 gexpr();
4566 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4567 expect("pointer");
4568 ggoto();
4569 } else if (tok >= TOK_UIDENT) {
4570 s = label_find(tok);
4571 /* put forward definition if needed */
4572 if (!s) {
4573 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4574 } else {
4575 if (s->r == LABEL_DECLARED)
4576 s->r = LABEL_FORWARD;
4578 /* label already defined */
4579 if (s->r & LABEL_FORWARD)
4580 s->jnext = gjmp(s->jnext);
4581 else
4582 gjmp_addr(s->jnext);
4583 next();
4584 } else {
4585 expect("label identifier");
4587 skip(';');
4588 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4589 asm_instr();
4590 } else {
4591 b = is_label();
4592 if (b) {
4593 /* label case */
4594 s = label_find(b);
4595 if (s) {
4596 if (s->r == LABEL_DEFINED)
4597 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4598 gsym(s->jnext);
4599 s->r = LABEL_DEFINED;
4600 } else {
4601 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4603 s->jnext = ind;
4604 /* we accept this, but it is a mistake */
4605 block_after_label:
4606 if (tok == '}') {
4607 warning("deprecated use of label at end of compound statement");
4608 } else {
4609 if (is_expr)
4610 vpop();
4611 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4613 } else {
4614 /* expression case */
4615 if (tok != ';') {
4616 if (is_expr) {
4617 vpop();
4618 gexpr();
4619 } else {
4620 gexpr();
4621 vpop();
4624 skip(';');
4629 /* t is the array or struct type. c is the array or struct
4630 address. cur_index/cur_field is the pointer to the current
4631 value. 'size_only' is true if only size info is needed (only used
4632 in arrays) */
4633 static void decl_designator(CType *type, Section *sec, unsigned long c,
4634 int *cur_index, Sym **cur_field,
4635 int size_only)
4637 Sym *s, *f;
4638 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4639 CType type1;
4641 notfirst = 0;
4642 elem_size = 0;
4643 nb_elems = 1;
4644 if (gnu_ext && (l = is_label()) != 0)
4645 goto struct_field;
4646 while (tok == '[' || tok == '.') {
4647 if (tok == '[') {
4648 if (!(type->t & VT_ARRAY))
4649 expect("array type");
4650 s = type->ref;
4651 next();
4652 index = expr_const();
4653 if (index < 0 || (s->c >= 0 && index >= s->c))
4654 expect("invalid index");
4655 if (tok == TOK_DOTS && gnu_ext) {
4656 next();
4657 index_last = expr_const();
4658 if (index_last < 0 ||
4659 (s->c >= 0 && index_last >= s->c) ||
4660 index_last < index)
4661 expect("invalid index");
4662 } else {
4663 index_last = index;
4665 skip(']');
4666 if (!notfirst)
4667 *cur_index = index_last;
4668 type = pointed_type(type);
4669 elem_size = type_size(type, &align);
4670 c += index * elem_size;
4671 /* NOTE: we only support ranges for last designator */
4672 nb_elems = index_last - index + 1;
4673 if (nb_elems != 1) {
4674 notfirst = 1;
4675 break;
4677 } else {
4678 next();
4679 l = tok;
4680 next();
4681 struct_field:
4682 if ((type->t & VT_BTYPE) != VT_STRUCT)
4683 expect("struct/union type");
4684 s = type->ref;
4685 l |= SYM_FIELD;
4686 f = s->next;
4687 while (f) {
4688 if (f->v == l)
4689 break;
4690 f = f->next;
4692 if (!f)
4693 expect("field");
4694 if (!notfirst)
4695 *cur_field = f;
4696 /* XXX: fix this mess by using explicit storage field */
4697 type1 = f->type;
4698 type1.t |= (type->t & ~VT_TYPE);
4699 type = &type1;
4700 c += f->c;
4702 notfirst = 1;
4704 if (notfirst) {
4705 if (tok == '=') {
4706 next();
4707 } else {
4708 if (!gnu_ext)
4709 expect("=");
4711 } else {
4712 if (type->t & VT_ARRAY) {
4713 index = *cur_index;
4714 type = pointed_type(type);
4715 c += index * type_size(type, &align);
4716 } else {
4717 f = *cur_field;
4718 if (!f)
4719 error("too many field init");
4720 /* XXX: fix this mess by using explicit storage field */
4721 type1 = f->type;
4722 type1.t |= (type->t & ~VT_TYPE);
4723 type = &type1;
4724 c += f->c;
4727 decl_initializer(type, sec, c, 0, size_only);
4729 /* XXX: make it more general */
4730 if (!size_only && nb_elems > 1) {
4731 unsigned long c_end;
4732 uint8_t *src, *dst;
4733 int i;
4735 if (!sec)
4736 error("range init not supported yet for dynamic storage");
4737 c_end = c + nb_elems * elem_size;
4738 if (c_end > sec->data_allocated)
4739 section_realloc(sec, c_end);
4740 src = sec->data + c;
4741 dst = src;
4742 for(i = 1; i < nb_elems; i++) {
4743 dst += elem_size;
4744 memcpy(dst, src, elem_size);
4749 #define EXPR_VAL 0
4750 #define EXPR_CONST 1
4751 #define EXPR_ANY 2
4753 /* store a value or an expression directly in global data or in local array */
4754 static void init_putv(CType *type, Section *sec, unsigned long c,
4755 int v, int expr_type)
4757 int saved_global_expr, bt, bit_pos, bit_size;
4758 void *ptr;
4759 unsigned long long bit_mask;
4760 CType dtype;
4762 switch(expr_type) {
4763 case EXPR_VAL:
4764 vpushi(v);
4765 break;
4766 case EXPR_CONST:
4767 /* compound literals must be allocated globally in this case */
4768 saved_global_expr = global_expr;
4769 global_expr = 1;
4770 expr_const1();
4771 global_expr = saved_global_expr;
4772 /* NOTE: symbols are accepted */
4773 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4774 error("initializer element is not constant");
4775 break;
4776 case EXPR_ANY:
4777 expr_eq();
4778 break;
4781 dtype = *type;
4782 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4784 if (sec) {
4785 /* XXX: not portable */
4786 /* XXX: generate error if incorrect relocation */
4787 gen_assign_cast(&dtype);
4788 bt = type->t & VT_BTYPE;
4789 /* we'll write at most 12 bytes */
4790 if (c + 12 > sec->data_allocated) {
4791 section_realloc(sec, c + 12);
4793 ptr = sec->data + c;
4794 /* XXX: make code faster ? */
4795 if (!(type->t & VT_BITFIELD)) {
4796 bit_pos = 0;
4797 bit_size = 32;
4798 bit_mask = -1LL;
4799 } else {
4800 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4801 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4802 bit_mask = (1LL << bit_size) - 1;
4804 if ((vtop->r & VT_SYM) &&
4805 (bt == VT_BYTE ||
4806 bt == VT_SHORT ||
4807 bt == VT_DOUBLE ||
4808 bt == VT_LDOUBLE ||
4809 bt == VT_LLONG ||
4810 (bt == VT_INT && bit_size != 32)))
4811 error("initializer element is not computable at load time");
4812 switch(bt) {
4813 case VT_BOOL:
4814 vtop->c.i = (vtop->c.i != 0);
4815 case VT_BYTE:
4816 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4817 break;
4818 case VT_SHORT:
4819 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4820 break;
4821 case VT_DOUBLE:
4822 *(double *)ptr = vtop->c.d;
4823 break;
4824 case VT_LDOUBLE:
4825 *(long double *)ptr = vtop->c.ld;
4826 break;
4827 case VT_LLONG:
4828 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4829 break;
4830 default:
4831 if (vtop->r & VT_SYM) {
4832 greloc(sec, vtop->sym, c, R_DATA_PTR);
4834 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4835 break;
4837 vtop--;
4838 } else {
4839 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4840 vswap();
4841 vstore();
4842 vpop();
4846 /* put zeros for variable based init */
4847 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4849 if (sec) {
4850 /* nothing to do because globals are already set to zero */
4851 } else {
4852 vpush_global_sym(&func_old_type, TOK_memset);
4853 vseti(VT_LOCAL, c);
4854 vpushi(0);
4855 vpushi(size);
4856 gfunc_call(3);
4860 /* 't' contains the type and storage info. 'c' is the offset of the
4861 object in section 'sec'. If 'sec' is NULL, it means stack based
4862 allocation. 'first' is true if array '{' must be read (multi
4863 dimension implicit array init handling). 'size_only' is true if
4864 size only evaluation is wanted (only for arrays). */
4865 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4866 int first, int size_only)
4868 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
4869 int size1, align1, expr_type;
4870 Sym *s, *f;
4871 CType *t1;
4873 if (type->t & VT_VLA) {
4874 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
4875 int a;
4876 CValue retcval;
4878 vpush_global_sym(&func_old_type, TOK_alloca);
4879 vla_runtime_type_size(type, &a);
4880 gfunc_call(1);
4882 /* return value */
4883 retcval.i = 0;
4884 vsetc(type, REG_IRET, &retcval);
4885 vset(type, VT_LOCAL|VT_LVAL, c);
4886 vswap();
4887 vstore();
4888 vpop();
4889 #else
4890 error("variable length arrays unsupported for this target");
4891 #endif
4892 } else if (type->t & VT_ARRAY) {
4893 s = type->ref;
4894 n = s->c;
4895 array_length = 0;
4896 t1 = pointed_type(type);
4897 size1 = type_size(t1, &align1);
4899 no_oblock = 1;
4900 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4901 tok == '{') {
4902 if (tok != '{')
4903 error("character array initializer must be a literal,"
4904 " optionally enclosed in braces");
4905 skip('{');
4906 no_oblock = 0;
4909 /* only parse strings here if correct type (otherwise: handle
4910 them as ((w)char *) expressions */
4911 if ((tok == TOK_LSTR &&
4912 #ifdef TCC_TARGET_PE
4913 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4914 #else
4915 (t1->t & VT_BTYPE) == VT_INT
4916 #endif
4917 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4918 while (tok == TOK_STR || tok == TOK_LSTR) {
4919 int cstr_len, ch;
4920 CString *cstr;
4922 cstr = tokc.cstr;
4923 /* compute maximum number of chars wanted */
4924 if (tok == TOK_STR)
4925 cstr_len = cstr->size;
4926 else
4927 cstr_len = cstr->size / sizeof(nwchar_t);
4928 cstr_len--;
4929 nb = cstr_len;
4930 if (n >= 0 && nb > (n - array_length))
4931 nb = n - array_length;
4932 if (!size_only) {
4933 if (cstr_len > nb)
4934 warning("initializer-string for array is too long");
4935 /* in order to go faster for common case (char
4936 string in global variable, we handle it
4937 specifically */
4938 if (sec && tok == TOK_STR && size1 == 1) {
4939 memcpy(sec->data + c + array_length, cstr->data, nb);
4940 } else {
4941 for(i=0;i<nb;i++) {
4942 if (tok == TOK_STR)
4943 ch = ((unsigned char *)cstr->data)[i];
4944 else
4945 ch = ((nwchar_t *)cstr->data)[i];
4946 init_putv(t1, sec, c + (array_length + i) * size1,
4947 ch, EXPR_VAL);
4951 array_length += nb;
4952 next();
4954 /* only add trailing zero if enough storage (no
4955 warning in this case since it is standard) */
4956 if (n < 0 || array_length < n) {
4957 if (!size_only) {
4958 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4960 array_length++;
4962 } else {
4963 index = 0;
4964 while (tok != '}') {
4965 decl_designator(type, sec, c, &index, NULL, size_only);
4966 if (n >= 0 && index >= n)
4967 error("index too large");
4968 /* must put zero in holes (note that doing it that way
4969 ensures that it even works with designators) */
4970 if (!size_only && array_length < index) {
4971 init_putz(t1, sec, c + array_length * size1,
4972 (index - array_length) * size1);
4974 index++;
4975 if (index > array_length)
4976 array_length = index;
4977 /* special test for multi dimensional arrays (may not
4978 be strictly correct if designators are used at the
4979 same time) */
4980 if (index >= n && no_oblock)
4981 break;
4982 if (tok == '}')
4983 break;
4984 skip(',');
4987 if (!no_oblock)
4988 skip('}');
4989 /* put zeros at the end */
4990 if (!size_only && n >= 0 && array_length < n) {
4991 init_putz(t1, sec, c + array_length * size1,
4992 (n - array_length) * size1);
4994 /* patch type size if needed */
4995 if (n < 0)
4996 s->c = array_length;
4997 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4998 (sec || !first || tok == '{')) {
4999 int par_count;
5001 /* NOTE: the previous test is a specific case for automatic
5002 struct/union init */
5003 /* XXX: union needs only one init */
5005 /* XXX: this test is incorrect for local initializers
5006 beginning with ( without {. It would be much more difficult
5007 to do it correctly (ideally, the expression parser should
5008 be used in all cases) */
5009 par_count = 0;
5010 if (tok == '(') {
5011 AttributeDef ad1;
5012 CType type1;
5013 next();
5014 while (tok == '(') {
5015 par_count++;
5016 next();
5018 if (!parse_btype(&type1, &ad1))
5019 expect("cast");
5020 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5021 #if 0
5022 if (!is_assignable_types(type, &type1))
5023 error("invalid type for cast");
5024 #endif
5025 skip(')');
5027 no_oblock = 1;
5028 if (first || tok == '{') {
5029 skip('{');
5030 no_oblock = 0;
5032 s = type->ref;
5033 f = s->next;
5034 array_length = 0;
5035 index = 0;
5036 n = s->c;
5037 while (tok != '}') {
5038 decl_designator(type, sec, c, NULL, &f, size_only);
5039 index = f->c;
5040 if (!size_only && array_length < index) {
5041 init_putz(type, sec, c + array_length,
5042 index - array_length);
5044 index = index + type_size(&f->type, &align1);
5045 if (index > array_length)
5046 array_length = index;
5048 /* gr: skip fields from same union - ugly. */
5049 while (f->next) {
5050 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5051 /* test for same offset */
5052 if (f->next->c != f->c)
5053 break;
5054 /* if yes, test for bitfield shift */
5055 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5056 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5057 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5058 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5059 if (bit_pos_1 != bit_pos_2)
5060 break;
5062 f = f->next;
5065 f = f->next;
5066 if (no_oblock && f == NULL)
5067 break;
5068 if (tok == '}')
5069 break;
5070 skip(',');
5072 /* put zeros at the end */
5073 if (!size_only && array_length < n) {
5074 init_putz(type, sec, c + array_length,
5075 n - array_length);
5077 if (!no_oblock)
5078 skip('}');
5079 while (par_count) {
5080 skip(')');
5081 par_count--;
5083 } else if (tok == '{') {
5084 next();
5085 decl_initializer(type, sec, c, first, size_only);
5086 skip('}');
5087 } else if (size_only) {
5088 /* just skip expression */
5089 parlevel = parlevel1 = 0;
5090 while ((parlevel > 0 || parlevel1 > 0 ||
5091 (tok != '}' && tok != ',')) && tok != -1) {
5092 if (tok == '(')
5093 parlevel++;
5094 else if (tok == ')')
5095 parlevel--;
5096 else if (tok == '{')
5097 parlevel1++;
5098 else if (tok == '}')
5099 parlevel1--;
5100 next();
5102 } else {
5103 /* currently, we always use constant expression for globals
5104 (may change for scripting case) */
5105 expr_type = EXPR_CONST;
5106 if (!sec)
5107 expr_type = EXPR_ANY;
5108 init_putv(type, sec, c, 0, expr_type);
5112 /* parse an initializer for type 't' if 'has_init' is non zero, and
5113 allocate space in local or global data space ('r' is either
5114 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5115 variable 'v' with an associated name represented by 'asm_label' of
5116 scope 'scope' is declared before initializers are parsed. If 'v' is
5117 zero, then a reference to the new object is put in the value stack.
5118 If 'has_init' is 2, a special parsing is done to handle string
5119 constants. */
5120 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5121 int has_init, int v, char *asm_label,
5122 int scope)
5124 int size, align, addr, data_offset;
5125 int level;
5126 ParseState saved_parse_state = {0};
5127 TokenString init_str;
5128 Section *sec;
5129 Sym *flexible_array;
5131 flexible_array = NULL;
5132 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5133 Sym *field;
5134 field = type->ref;
5135 while (field && field->next)
5136 field = field->next;
5137 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5138 flexible_array = field;
5141 size = type_size(type, &align);
5142 /* If unknown size, we must evaluate it before
5143 evaluating initializers because
5144 initializers can generate global data too
5145 (e.g. string pointers or ISOC99 compound
5146 literals). It also simplifies local
5147 initializers handling */
5148 tok_str_new(&init_str);
5149 if (size < 0 || (flexible_array && has_init)) {
5150 if (!has_init)
5151 error("unknown type size");
5152 /* get all init string */
5153 if (has_init == 2) {
5154 /* only get strings */
5155 while (tok == TOK_STR || tok == TOK_LSTR) {
5156 tok_str_add_tok(&init_str);
5157 next();
5159 } else {
5160 level = 0;
5161 while (level > 0 || (tok != ',' && tok != ';')) {
5162 if (tok < 0)
5163 error("unexpected end of file in initializer");
5164 tok_str_add_tok(&init_str);
5165 if (tok == '{')
5166 level++;
5167 else if (tok == '}') {
5168 level--;
5169 if (level <= 0) {
5170 next();
5171 break;
5174 next();
5177 tok_str_add(&init_str, -1);
5178 tok_str_add(&init_str, 0);
5180 /* compute size */
5181 save_parse_state(&saved_parse_state);
5183 macro_ptr = init_str.str;
5184 next();
5185 decl_initializer(type, NULL, 0, 1, 1);
5186 /* prepare second initializer parsing */
5187 macro_ptr = init_str.str;
5188 next();
5190 /* if still unknown size, error */
5191 size = type_size(type, &align);
5192 if (size < 0)
5193 error("unknown type size");
5195 if (flexible_array)
5196 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5197 /* take into account specified alignment if bigger */
5198 if (ad->aligned) {
5199 if (ad->aligned > align)
5200 align = ad->aligned;
5201 } else if (ad->packed) {
5202 align = 1;
5204 if ((r & VT_VALMASK) == VT_LOCAL) {
5205 sec = NULL;
5206 #ifdef CONFIG_TCC_BCHECK
5207 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5208 loc--;
5210 #endif
5211 loc = (loc - size) & -align;
5212 addr = loc;
5213 #ifdef CONFIG_TCC_BCHECK
5214 /* handles bounds */
5215 /* XXX: currently, since we do only one pass, we cannot track
5216 '&' operators, so we add only arrays */
5217 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5218 unsigned long *bounds_ptr;
5219 /* add padding between regions */
5220 loc--;
5221 /* then add local bound info */
5222 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5223 bounds_ptr[0] = addr;
5224 bounds_ptr[1] = size;
5226 #endif
5227 if (v) {
5228 /* local variable */
5229 sym_push(v, type, r, addr);
5230 } else {
5231 /* push local reference */
5232 vset(type, r, addr);
5234 } else {
5235 Sym *sym;
5237 sym = NULL;
5238 if (v && scope == VT_CONST) {
5239 /* see if the symbol was already defined */
5240 sym = sym_find(v);
5241 if (sym) {
5242 if (!is_compatible_types(&sym->type, type))
5243 error("incompatible types for redefinition of '%s'",
5244 get_tok_str(v, NULL));
5245 if (sym->type.t & VT_EXTERN) {
5246 /* if the variable is extern, it was not allocated */
5247 sym->type.t &= ~VT_EXTERN;
5248 /* set array size if it was ommited in extern
5249 declaration */
5250 if ((sym->type.t & VT_ARRAY) &&
5251 sym->type.ref->c < 0 &&
5252 type->ref->c >= 0)
5253 sym->type.ref->c = type->ref->c;
5254 } else {
5255 /* we accept several definitions of the same
5256 global variable. this is tricky, because we
5257 must play with the SHN_COMMON type of the symbol */
5258 /* XXX: should check if the variable was already
5259 initialized. It is incorrect to initialized it
5260 twice */
5261 /* no init data, we won't add more to the symbol */
5262 if (!has_init)
5263 goto no_alloc;
5268 /* allocate symbol in corresponding section */
5269 sec = ad->section;
5270 if (!sec) {
5271 if (has_init)
5272 sec = data_section;
5273 else if (tcc_state->nocommon)
5274 sec = bss_section;
5276 if (sec) {
5277 data_offset = sec->data_offset;
5278 data_offset = (data_offset + align - 1) & -align;
5279 addr = data_offset;
5280 /* very important to increment global pointer at this time
5281 because initializers themselves can create new initializers */
5282 data_offset += size;
5283 #ifdef CONFIG_TCC_BCHECK
5284 /* add padding if bound check */
5285 if (tcc_state->do_bounds_check)
5286 data_offset++;
5287 #endif
5288 sec->data_offset = data_offset;
5289 /* allocate section space to put the data */
5290 if (sec->sh_type != SHT_NOBITS &&
5291 data_offset > sec->data_allocated)
5292 section_realloc(sec, data_offset);
5293 /* align section if needed */
5294 if (align > sec->sh_addralign)
5295 sec->sh_addralign = align;
5296 } else {
5297 addr = 0; /* avoid warning */
5300 if (v) {
5301 if (scope != VT_CONST || !sym) {
5302 sym = sym_push(v, type, r | VT_SYM, 0);
5303 sym->asm_label = asm_label;
5305 /* update symbol definition */
5306 if (sec) {
5307 put_extern_sym(sym, sec, addr, size);
5308 } else {
5309 ElfW(Sym) *esym;
5310 /* put a common area */
5311 put_extern_sym(sym, NULL, align, size);
5312 /* XXX: find a nicer way */
5313 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5314 esym->st_shndx = SHN_COMMON;
5316 } else {
5317 CValue cval;
5319 /* push global reference */
5320 sym = get_sym_ref(type, sec, addr, size);
5321 cval.ul = 0;
5322 vsetc(type, VT_CONST | VT_SYM, &cval);
5323 vtop->sym = sym;
5325 /* patch symbol weakness */
5326 if (type->t & VT_WEAK)
5327 weaken_symbol(sym);
5328 #ifdef CONFIG_TCC_BCHECK
5329 /* handles bounds now because the symbol must be defined
5330 before for the relocation */
5331 if (tcc_state->do_bounds_check) {
5332 unsigned long *bounds_ptr;
5334 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5335 /* then add global bound info */
5336 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5337 bounds_ptr[0] = 0; /* relocated */
5338 bounds_ptr[1] = size;
5340 #endif
5342 if (has_init || (type->t & VT_VLA)) {
5343 decl_initializer(type, sec, addr, 1, 0);
5344 /* restore parse state if needed */
5345 if (init_str.str) {
5346 tok_str_free(init_str.str);
5347 restore_parse_state(&saved_parse_state);
5349 /* patch flexible array member size back to -1, */
5350 /* for possible subsequent similar declarations */
5351 if (flexible_array)
5352 flexible_array->type.ref->c = -1;
5354 no_alloc: ;
5357 static void put_func_debug(Sym *sym)
5359 char buf[512];
5361 /* stabs info */
5362 /* XXX: we put here a dummy type */
5363 snprintf(buf, sizeof(buf), "%s:%c1",
5364 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5365 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5366 cur_text_section, sym->c);
5367 /* //gr gdb wants a line at the function */
5368 put_stabn(N_SLINE, 0, file->line_num, 0);
5369 last_ind = 0;
5370 last_line_num = 0;
5373 /* parse an old style function declaration list */
5374 /* XXX: check multiple parameter */
5375 static void func_decl_list(Sym *func_sym)
5377 AttributeDef ad;
5378 int v;
5379 Sym *s;
5380 CType btype, type;
5382 /* parse each declaration */
5383 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5384 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5385 if (!parse_btype(&btype, &ad))
5386 expect("declaration list");
5387 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5388 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5389 tok == ';') {
5390 /* we accept no variable after */
5391 } else {
5392 for(;;) {
5393 type = btype;
5394 type_decl(&type, &ad, &v, TYPE_DIRECT);
5395 /* find parameter in function parameter list */
5396 s = func_sym->next;
5397 while (s != NULL) {
5398 if ((s->v & ~SYM_FIELD) == v)
5399 goto found;
5400 s = s->next;
5402 error("declaration for parameter '%s' but no such parameter",
5403 get_tok_str(v, NULL));
5404 found:
5405 /* check that no storage specifier except 'register' was given */
5406 if (type.t & VT_STORAGE)
5407 error("storage class specified for '%s'", get_tok_str(v, NULL));
5408 convert_parameter_type(&type);
5409 /* we can add the type (NOTE: it could be local to the function) */
5410 s->type = type;
5411 /* accept other parameters */
5412 if (tok == ',')
5413 next();
5414 else
5415 break;
5418 skip(';');
5422 /* parse a function defined by symbol 'sym' and generate its code in
5423 'cur_text_section' */
5424 static void gen_function(Sym *sym)
5426 int saved_nocode_wanted = nocode_wanted;
5427 nocode_wanted = 0;
5428 ind = cur_text_section->data_offset;
5429 /* NOTE: we patch the symbol size later */
5430 put_extern_sym(sym, cur_text_section, ind, 0);
5431 funcname = get_tok_str(sym->v, NULL);
5432 func_ind = ind;
5433 /* put debug symbol */
5434 if (tcc_state->do_debug)
5435 put_func_debug(sym);
5436 /* push a dummy symbol to enable local sym storage */
5437 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5438 gfunc_prolog(&sym->type);
5439 rsym = 0;
5440 block(NULL, NULL, NULL, NULL, 0, 0);
5441 gsym(rsym);
5442 gfunc_epilog();
5443 cur_text_section->data_offset = ind;
5444 label_pop(&global_label_stack, NULL);
5445 sym_pop(&local_stack, NULL); /* reset local stack */
5446 /* end of function */
5447 /* patch symbol size */
5448 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5449 ind - func_ind;
5450 /* patch symbol weakness (this definition overrules any prototype) */
5451 if (sym->type.t & VT_WEAK)
5452 weaken_symbol(sym);
5453 if (tcc_state->do_debug) {
5454 put_stabn(N_FUN, 0, 0, ind - func_ind);
5456 /* It's better to crash than to generate wrong code */
5457 cur_text_section = NULL;
5458 funcname = ""; /* for safety */
5459 func_vt.t = VT_VOID; /* for safety */
5460 ind = 0; /* for safety */
5461 nocode_wanted = saved_nocode_wanted;
5464 ST_FUNC void gen_inline_functions(void)
5466 Sym *sym;
5467 int *str, inline_generated, i;
5468 struct InlineFunc *fn;
5470 /* iterate while inline function are referenced */
5471 for(;;) {
5472 inline_generated = 0;
5473 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5474 fn = tcc_state->inline_fns[i];
5475 sym = fn->sym;
5476 if (sym && sym->c) {
5477 /* the function was used: generate its code and
5478 convert it to a normal function */
5479 str = fn->token_str;
5480 fn->sym = NULL;
5481 if (file)
5482 strcpy(file->filename, fn->filename);
5483 sym->r = VT_SYM | VT_CONST;
5484 sym->type.t &= ~VT_INLINE;
5486 macro_ptr = str;
5487 next();
5488 cur_text_section = text_section;
5489 gen_function(sym);
5490 macro_ptr = NULL; /* fail safe */
5492 inline_generated = 1;
5495 if (!inline_generated)
5496 break;
5498 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5499 fn = tcc_state->inline_fns[i];
5500 str = fn->token_str;
5501 tok_str_free(str);
5503 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5506 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5507 static int decl0(int l, int is_for_loop_init)
5509 int v, has_init, r;
5510 CType type, btype;
5511 Sym *sym;
5512 AttributeDef ad;
5514 while (1) {
5515 if (!parse_btype(&btype, &ad)) {
5516 if (is_for_loop_init)
5517 return 0;
5518 /* skip redundant ';' */
5519 /* XXX: find more elegant solution */
5520 if (tok == ';') {
5521 next();
5522 continue;
5524 if (l == VT_CONST &&
5525 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5526 /* global asm block */
5527 asm_global_instr();
5528 continue;
5530 /* special test for old K&R protos without explicit int
5531 type. Only accepted when defining global data */
5532 if (l == VT_LOCAL || tok < TOK_DEFINE)
5533 break;
5534 btype.t = VT_INT;
5536 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5537 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5538 tok == ';') {
5539 /* we accept no variable after */
5540 next();
5541 continue;
5543 while (1) { /* iterate thru each declaration */
5544 char *asm_label; // associated asm label
5545 type = btype;
5546 type_decl(&type, &ad, &v, TYPE_DIRECT);
5547 #if 0
5549 char buf[500];
5550 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5551 printf("type = '%s'\n", buf);
5553 #endif
5554 if ((type.t & VT_BTYPE) == VT_FUNC) {
5555 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5556 error("function without file scope cannot be static");
5558 /* if old style function prototype, we accept a
5559 declaration list */
5560 sym = type.ref;
5561 if (sym->c == FUNC_OLD)
5562 func_decl_list(sym);
5565 asm_label = NULL;
5566 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5567 CString astr;
5569 asm_label_instr(&astr);
5570 asm_label = tcc_strdup(astr.data);
5571 cstr_free(&astr);
5573 /* parse one last attribute list, after asm label */
5574 parse_attribute(&ad);
5577 if (ad.weak)
5578 type.t |= VT_WEAK;
5579 #ifdef TCC_TARGET_PE
5580 if (ad.func_import)
5581 type.t |= VT_IMPORT;
5582 if (ad.func_export)
5583 type.t |= VT_EXPORT;
5584 #endif
5585 if (tok == '{') {
5586 if (l == VT_LOCAL)
5587 error("cannot use local functions");
5588 if ((type.t & VT_BTYPE) != VT_FUNC)
5589 expect("function definition");
5591 /* reject abstract declarators in function definition */
5592 sym = type.ref;
5593 while ((sym = sym->next) != NULL)
5594 if (!(sym->v & ~SYM_FIELD))
5595 expect("identifier");
5597 /* XXX: cannot do better now: convert extern line to static inline */
5598 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5599 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5601 sym = sym_find(v);
5602 if (sym) {
5603 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5604 goto func_error1;
5606 r = sym->type.ref->r;
5607 /* use func_call from prototype if not defined */
5608 if (FUNC_CALL(r) != FUNC_CDECL
5609 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5610 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5612 /* use export from prototype */
5613 if (FUNC_EXPORT(r))
5614 FUNC_EXPORT(type.ref->r) = 1;
5616 /* use static from prototype */
5617 if (sym->type.t & VT_STATIC)
5618 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5620 if (!is_compatible_types(&sym->type, &type)) {
5621 func_error1:
5622 error("incompatible types for redefinition of '%s'",
5623 get_tok_str(v, NULL));
5625 /* if symbol is already defined, then put complete type */
5626 sym->type = type;
5627 } else {
5628 /* put function symbol */
5629 sym = global_identifier_push(v, type.t, 0);
5630 sym->type.ref = type.ref;
5633 /* static inline functions are just recorded as a kind
5634 of macro. Their code will be emitted at the end of
5635 the compilation unit only if they are used */
5636 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5637 (VT_INLINE | VT_STATIC)) {
5638 TokenString func_str;
5639 int block_level;
5640 struct InlineFunc *fn;
5641 const char *filename;
5643 tok_str_new(&func_str);
5645 block_level = 0;
5646 for(;;) {
5647 int t;
5648 if (tok == TOK_EOF)
5649 error("unexpected end of file");
5650 tok_str_add_tok(&func_str);
5651 t = tok;
5652 next();
5653 if (t == '{') {
5654 block_level++;
5655 } else if (t == '}') {
5656 block_level--;
5657 if (block_level == 0)
5658 break;
5661 tok_str_add(&func_str, -1);
5662 tok_str_add(&func_str, 0);
5663 filename = file ? file->filename : "";
5664 fn = tcc_malloc(sizeof *fn + strlen(filename));
5665 strcpy(fn->filename, filename);
5666 fn->sym = sym;
5667 fn->token_str = func_str.str;
5668 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5670 } else {
5671 /* compute text section */
5672 cur_text_section = ad.section;
5673 if (!cur_text_section)
5674 cur_text_section = text_section;
5675 sym->r = VT_SYM | VT_CONST;
5676 gen_function(sym);
5678 break;
5679 } else {
5680 if (btype.t & VT_TYPEDEF) {
5681 /* save typedefed type */
5682 /* XXX: test storage specifiers ? */
5683 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5684 sym->type.t |= VT_TYPEDEF;
5685 } else {
5686 r = 0;
5687 if ((type.t & VT_BTYPE) == VT_FUNC) {
5688 /* external function definition */
5689 /* specific case for func_call attribute */
5690 type.ref->r = INT_ATTR(&ad);
5691 } else if (!(type.t & VT_ARRAY)) {
5692 /* not lvalue if array */
5693 r |= lvalue_type(type.t);
5695 has_init = (tok == '=');
5696 if (has_init && (type.t & VT_VLA))
5697 error("Variable length array cannot be initialized");
5698 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5699 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5700 !has_init && l == VT_CONST && type.ref->c < 0)) {
5701 /* external variable or function */
5702 /* NOTE: as GCC, uninitialized global static
5703 arrays of null size are considered as
5704 extern */
5705 sym = external_sym(v, &type, r, asm_label);
5707 if (type.t & VT_WEAK)
5708 weaken_symbol(sym);
5710 if (ad.alias_target) {
5711 Section tsec;
5712 Elf32_Sym *esym;
5713 Sym *alias_target;
5715 alias_target = sym_find(ad.alias_target);
5716 if (!alias_target || !alias_target->c)
5717 error("unsupported forward __alias__ attribute");
5718 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
5719 tsec.sh_num = esym->st_shndx;
5720 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
5722 } else {
5723 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5724 if (type.t & VT_STATIC)
5725 r |= VT_CONST;
5726 else
5727 r |= l;
5728 if (has_init)
5729 next();
5730 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
5733 if (tok != ',') {
5734 if (is_for_loop_init)
5735 return 1;
5736 skip(';');
5737 break;
5739 next();
5741 ad.aligned = 0;
5744 return 0;
5747 ST_FUNC void decl(int l)
5749 decl0(l, 0);