Move logic for if (int value) to tccgen.c
[tinycc.git] / tccgen.c
blob55b03e690150ba973574b46bcaa1ff603e5ea672
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 *scope_stack_bottom;
54 ST_DATA Sym *define_stack;
55 ST_DATA Sym *global_label_stack;
56 ST_DATA Sym *local_label_stack;
58 ST_DATA int vla_sp_loc_tmp; /* vla_sp_loc is set to this when the value won't be needed later */
59 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
60 ST_DATA int *vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
61 ST_DATA int vla_flags; /* VLA_* flags */
63 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
65 ST_DATA int const_wanted; /* true if constant wanted */
66 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
67 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
68 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
69 ST_DATA int func_vc;
70 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
71 ST_DATA char *funcname;
73 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
75 /* ------------------------------------------------------------------------- */
76 static void gen_cast(CType *type);
77 static inline CType *pointed_type(CType *type);
78 static int is_compatible_types(CType *type1, CType *type2);
79 static int parse_btype(CType *type, AttributeDef *ad);
80 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
81 static void parse_expr_type(CType *type);
82 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
83 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
84 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
85 static int decl0(int l, int is_for_loop_init);
86 static void expr_eq(void);
87 static void unary_type(CType *type);
88 static void vla_runtime_type_size(CType *type, int *a);
89 static void vla_sp_save(void);
90 static int is_compatible_parameter_types(CType *type1, CType *type2);
91 static void expr_type(CType *type);
93 ST_INLN int is_float(int t)
95 int bt;
96 bt = t & VT_BTYPE;
97 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
100 /* we use our own 'finite' function to avoid potential problems with
101 non standard math libs */
102 /* XXX: endianness dependent */
103 ST_FUNC int ieee_finite(double d)
105 int *p = (int *)&d;
106 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
109 ST_FUNC void test_lvalue(void)
111 if (!(vtop->r & VT_LVAL))
112 expect("lvalue");
115 /* ------------------------------------------------------------------------- */
116 /* symbol allocator */
117 static Sym *__sym_malloc(void)
119 Sym *sym_pool, *sym, *last_sym;
120 int i;
122 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
123 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
125 last_sym = sym_free_first;
126 sym = sym_pool;
127 for(i = 0; i < SYM_POOL_NB; i++) {
128 sym->next = last_sym;
129 last_sym = sym;
130 sym++;
132 sym_free_first = last_sym;
133 return last_sym;
136 static inline Sym *sym_malloc(void)
138 Sym *sym;
139 sym = sym_free_first;
140 if (!sym)
141 sym = __sym_malloc();
142 sym_free_first = sym->next;
143 return sym;
146 ST_INLN void sym_free(Sym *sym)
148 sym->next = sym_free_first;
149 tcc_free(sym->asm_label);
150 sym_free_first = sym;
153 /* push, without hashing */
154 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
156 Sym *s;
157 if (ps == &local_stack) {
158 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
159 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
160 tcc_error("incompatible types for redefinition of '%s'",
161 get_tok_str(v, NULL));
163 s = *ps;
164 s = sym_malloc();
165 s->asm_label = NULL;
166 s->v = v;
167 s->type.t = t;
168 s->type.ref = NULL;
169 #ifdef _WIN64
170 s->d = NULL;
171 #endif
172 s->c = c;
173 s->next = NULL;
174 /* add in stack */
175 s->prev = *ps;
176 *ps = s;
177 return s;
180 /* find a symbol and return its associated structure. 's' is the top
181 of the symbol stack */
182 ST_FUNC Sym *sym_find2(Sym *s, int v)
184 while (s) {
185 if (s->v == v)
186 return s;
187 s = s->prev;
189 return NULL;
192 /* structure lookup */
193 ST_INLN Sym *struct_find(int v)
195 v -= TOK_IDENT;
196 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
197 return NULL;
198 return table_ident[v]->sym_struct;
201 /* find an identifier */
202 ST_INLN Sym *sym_find(int v)
204 v -= TOK_IDENT;
205 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
206 return NULL;
207 return table_ident[v]->sym_identifier;
210 /* push a given symbol on the symbol stack */
211 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
213 Sym *s, **ps;
214 TokenSym *ts;
216 if (local_stack)
217 ps = &local_stack;
218 else
219 ps = &global_stack;
220 s = sym_push2(ps, v, type->t, c);
221 s->type.ref = type->ref;
222 s->r = r;
223 /* don't record fields or anonymous symbols */
224 /* XXX: simplify */
225 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
226 /* record symbol in token array */
227 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
228 if (v & SYM_STRUCT)
229 ps = &ts->sym_struct;
230 else
231 ps = &ts->sym_identifier;
232 s->prev_tok = *ps;
233 *ps = s;
235 return s;
238 /* push a global identifier */
239 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
241 Sym *s, **ps;
242 s = sym_push2(&global_stack, v, t, c);
243 /* don't record anonymous symbol */
244 if (v < SYM_FIRST_ANOM) {
245 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
246 /* modify the top most local identifier, so that
247 sym_identifier will point to 's' when popped */
248 while (*ps != NULL)
249 ps = &(*ps)->prev_tok;
250 s->prev_tok = NULL;
251 *ps = s;
253 return s;
256 /* pop symbols until top reaches 'b' */
257 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
259 Sym *s, *ss, **ps;
260 TokenSym *ts;
261 int v;
263 s = *ptop;
264 while(s != b) {
265 ss = s->prev;
266 v = s->v;
267 /* remove symbol in token array */
268 /* XXX: simplify */
269 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
270 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
271 if (v & SYM_STRUCT)
272 ps = &ts->sym_struct;
273 else
274 ps = &ts->sym_identifier;
275 *ps = s->prev_tok;
277 sym_free(s);
278 s = ss;
280 *ptop = b;
283 static void weaken_symbol(Sym *sym)
285 sym->type.t |= VT_WEAK;
286 if (sym->c > 0) {
287 int esym_type;
288 ElfW(Sym) *esym;
290 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
291 esym_type = ELFW(ST_TYPE)(esym->st_info);
292 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
296 /* ------------------------------------------------------------------------- */
298 ST_FUNC void swap(int *p, int *q)
300 int t;
301 t = *p;
302 *p = *q;
303 *q = t;
306 static void vsetc(CType *type, int r, CValue *vc)
308 int v;
310 if (vtop >= vstack + (VSTACK_SIZE - 1))
311 tcc_error("memory full");
312 /* cannot let cpu flags if other instruction are generated. Also
313 avoid leaving VT_JMP anywhere except on the top of the stack
314 because it would complicate the code generator. */
315 if (vtop >= vstack) {
316 v = vtop->r & VT_VALMASK;
317 if (v == VT_CMP || (v & ~1) == VT_JMP)
318 gv(RC_INT);
320 vtop++;
321 vtop->type = *type;
322 vtop->r = r;
323 vtop->r2 = VT_CONST;
324 vtop->c = *vc;
327 /* push constant of type "type" with useless value */
328 void vpush(CType *type)
330 CValue cval;
331 vsetc(type, VT_CONST, &cval);
334 /* push integer constant */
335 ST_FUNC void vpushi(int v)
337 CValue cval;
338 cval.i = v;
339 vsetc(&int_type, VT_CONST, &cval);
342 /* push a pointer sized constant */
343 static void vpushs(long long v)
345 CValue cval;
346 if (PTR_SIZE == 4)
347 cval.i = (int)v;
348 else
349 cval.ull = v;
350 vsetc(&size_type, VT_CONST, &cval);
353 /* push arbitrary 64bit constant */
354 void vpush64(int ty, unsigned long long v)
356 CValue cval;
357 CType ctype;
358 ctype.t = ty;
359 ctype.ref = NULL;
360 cval.ull = v;
361 vsetc(&ctype, VT_CONST, &cval);
364 /* push long long constant */
365 static inline void vpushll(long long v)
367 vpush64(VT_LLONG, v);
370 /* Return a static symbol pointing to a section */
371 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
373 int v;
374 Sym *sym;
376 v = anon_sym++;
377 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
378 sym->type.ref = type->ref;
379 sym->r = VT_CONST | VT_SYM;
380 put_extern_sym(sym, sec, offset, size);
381 return sym;
384 /* push a reference to a section offset by adding a dummy symbol */
385 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
387 CValue cval;
389 cval.ul = 0;
390 vsetc(type, VT_CONST | VT_SYM, &cval);
391 vtop->sym = get_sym_ref(type, sec, offset, size);
394 /* define a new external reference to a symbol 'v' of type 'u' */
395 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
397 Sym *s;
399 s = sym_find(v);
400 if (!s) {
401 /* push forward reference */
402 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
403 s->type.ref = type->ref;
404 s->r = r | VT_CONST | VT_SYM;
406 return s;
409 /* define a new external reference to a symbol 'v' with alternate asm
410 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
411 is no alternate name (most cases) */
412 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
414 Sym *s;
416 s = sym_find(v);
417 if (!s) {
418 /* push forward reference */
419 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
420 s->asm_label = asm_label;
421 s->type.t |= VT_EXTERN;
422 } else if (s->type.ref == func_old_type.ref) {
423 s->type.ref = type->ref;
424 s->r = r | VT_CONST | VT_SYM;
425 s->type.t |= VT_EXTERN;
426 } else if (!is_compatible_types(&s->type, type)) {
427 tcc_error("incompatible types for redefinition of '%s'",
428 get_tok_str(v, NULL));
430 return s;
433 /* push a reference to global symbol v */
434 ST_FUNC void vpush_global_sym(CType *type, int v)
436 Sym *sym;
437 CValue cval;
439 sym = external_global_sym(v, type, 0);
440 cval.ul = 0;
441 vsetc(type, VT_CONST | VT_SYM, &cval);
442 vtop->sym = sym;
445 ST_FUNC void vset(CType *type, int r, int v)
447 CValue cval;
449 cval.i = v;
450 vsetc(type, r, &cval);
453 static void vseti(int r, int v)
455 CType type;
456 type.t = VT_INT;
457 type.ref = 0;
458 vset(&type, r, v);
461 ST_FUNC void vswap(void)
463 SValue tmp;
464 /* cannot let cpu flags if other instruction are generated. Also
465 avoid leaving VT_JMP anywhere except on the top of the stack
466 because it would complicate the code generator. */
467 if (vtop >= vstack) {
468 int v = vtop->r & VT_VALMASK;
469 if (v == VT_CMP || (v & ~1) == VT_JMP)
470 gv(RC_INT);
472 tmp = vtop[0];
473 vtop[0] = vtop[-1];
474 vtop[-1] = tmp;
476 /* XXX: +2% overall speed possible with optimized memswap
478 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
482 ST_FUNC void vpushv(SValue *v)
484 if (vtop >= vstack + (VSTACK_SIZE - 1))
485 tcc_error("memory full");
486 vtop++;
487 *vtop = *v;
490 static void vdup(void)
492 vpushv(vtop);
495 /* save r to the memory stack, and mark it as being free */
496 ST_FUNC void save_reg(int r)
498 int l, saved, size, align;
499 SValue *p, sv;
500 CType *type;
502 /* modify all stack values */
503 saved = 0;
504 l = 0;
505 for(p=vstack;p<=vtop;p++) {
506 if ((p->r & VT_VALMASK) == r ||
507 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
508 /* must save value on stack if not already done */
509 if (!saved) {
510 /* NOTE: must reload 'r' because r might be equal to r2 */
511 r = p->r & VT_VALMASK;
512 /* store register in the stack */
513 type = &p->type;
514 if ((p->r & VT_LVAL) ||
515 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
516 #ifdef TCC_TARGET_X86_64
517 type = &char_pointer_type;
518 #else
519 type = &int_type;
520 #endif
521 size = type_size(type, &align);
522 loc = (loc - size) & -align;
523 sv.type.t = type->t;
524 sv.r = VT_LOCAL | VT_LVAL;
525 sv.c.ul = loc;
526 store(r, &sv);
527 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
528 /* x86 specific: need to pop fp register ST0 if saved */
529 if (r == TREG_ST0) {
530 o(0xd8dd); /* fstp %st(0) */
532 #endif
533 #ifndef TCC_TARGET_X86_64
534 /* special long long case */
535 if ((type->t & VT_BTYPE) == VT_LLONG) {
536 sv.c.ul += 4;
537 store(p->r2, &sv);
539 #endif
540 l = loc;
541 saved = 1;
543 /* mark that stack entry as being saved on the stack */
544 if (p->r & VT_LVAL) {
545 /* also clear the bounded flag because the
546 relocation address of the function was stored in
547 p->c.ul */
548 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
549 } else {
550 p->r = lvalue_type(p->type.t) | VT_LOCAL;
552 p->r2 = VT_CONST;
553 p->c.ul = l;
558 #ifdef TCC_TARGET_ARM
559 /* find a register of class 'rc2' with at most one reference on stack.
560 * If none, call get_reg(rc) */
561 ST_FUNC int get_reg_ex(int rc, int rc2)
563 int r;
564 SValue *p;
566 for(r=0;r<NB_REGS;r++) {
567 if (reg_classes[r] & rc2) {
568 int n;
569 n=0;
570 for(p = vstack; p <= vtop; p++) {
571 if ((p->r & VT_VALMASK) == r ||
572 (p->r2 & VT_VALMASK) == r)
573 n++;
575 if (n <= 1)
576 return r;
579 return get_reg(rc);
581 #endif
583 /* find a free register of class 'rc'. If none, save one register */
584 ST_FUNC int get_reg(int rc)
586 int r;
587 SValue *p;
589 /* find a free register */
590 for(r=0;r<NB_REGS;r++) {
591 if (reg_classes[r] & rc) {
592 for(p=vstack;p<=vtop;p++) {
593 if ((p->r & VT_VALMASK) == r ||
594 (p->r2 & VT_VALMASK) == r)
595 goto notfound;
597 return r;
599 notfound: ;
602 /* no register left : free the first one on the stack (VERY
603 IMPORTANT to start from the bottom to ensure that we don't
604 spill registers used in gen_opi()) */
605 for(p=vstack;p<=vtop;p++) {
606 /* look at second register (if long long) */
607 r = p->r2 & VT_VALMASK;
608 if (r < VT_CONST && (reg_classes[r] & rc))
609 goto save_found;
610 r = p->r & VT_VALMASK;
611 if (r < VT_CONST && (reg_classes[r] & rc)) {
612 save_found:
613 save_reg(r);
614 return r;
617 /* Should never comes here */
618 return -1;
621 /* save registers up to (vtop - n) stack entry */
622 ST_FUNC void save_regs(int n)
624 int r;
625 SValue *p, *p1;
626 p1 = vtop - n;
627 for(p = vstack;p <= p1; p++) {
628 r = p->r & VT_VALMASK;
629 if (r < VT_CONST) {
630 save_reg(r);
635 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
636 if needed */
637 static void move_reg(int r, int s, int t)
639 SValue sv;
641 if (r != s) {
642 save_reg(r);
643 sv.type.t = t;
644 sv.type.ref = NULL;
645 sv.r = s;
646 sv.c.ul = 0;
647 load(r, &sv);
651 /* get address of vtop (vtop MUST BE an lvalue) */
652 static void gaddrof(void)
654 if (vtop->r & VT_REF)
655 gv(RC_INT);
656 vtop->r &= ~VT_LVAL;
657 /* tricky: if saved lvalue, then we can go back to lvalue */
658 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
659 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
664 #ifdef CONFIG_TCC_BCHECK
665 /* generate lvalue bound code */
666 static void gbound(void)
668 int lval_type;
669 CType type1;
671 vtop->r &= ~VT_MUSTBOUND;
672 /* if lvalue, then use checking code before dereferencing */
673 if (vtop->r & VT_LVAL) {
674 /* if not VT_BOUNDED value, then make one */
675 if (!(vtop->r & VT_BOUNDED)) {
676 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
677 /* must save type because we must set it to int to get pointer */
678 type1 = vtop->type;
679 vtop->type.t = VT_INT;
680 gaddrof();
681 vpushi(0);
682 gen_bounded_ptr_add();
683 vtop->r |= lval_type;
684 vtop->type = type1;
686 /* then check for dereferencing */
687 gen_bounded_ptr_deref();
690 #endif
692 /* store vtop a register belonging to class 'rc'. lvalues are
693 converted to values. Cannot be used if cannot be converted to
694 register value (such as structures). */
695 ST_FUNC int gv(int rc)
697 int r, bit_pos, bit_size, size, align, i;
698 int rc2;
700 /* NOTE: get_reg can modify vstack[] */
701 if (vtop->type.t & VT_BITFIELD) {
702 CType type;
703 int bits = 32;
704 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
705 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
706 /* remove bit field info to avoid loops */
707 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
708 /* cast to int to propagate signedness in following ops */
709 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
710 type.t = VT_LLONG;
711 bits = 64;
712 } else
713 type.t = VT_INT;
714 if((vtop->type.t & VT_UNSIGNED) ||
715 (vtop->type.t & VT_BTYPE) == VT_BOOL)
716 type.t |= VT_UNSIGNED;
717 gen_cast(&type);
718 /* generate shifts */
719 vpushi(bits - (bit_pos + bit_size));
720 gen_op(TOK_SHL);
721 vpushi(bits - bit_size);
722 /* NOTE: transformed to SHR if unsigned */
723 gen_op(TOK_SAR);
724 r = gv(rc);
725 } else {
726 if (is_float(vtop->type.t) &&
727 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
728 Sym *sym;
729 int *ptr;
730 unsigned long offset;
731 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
732 CValue check;
733 #endif
735 /* XXX: unify with initializers handling ? */
736 /* CPUs usually cannot use float constants, so we store them
737 generically in data segment */
738 size = type_size(&vtop->type, &align);
739 offset = (data_section->data_offset + align - 1) & -align;
740 data_section->data_offset = offset;
741 /* XXX: not portable yet */
742 #if defined(__i386__) || defined(__x86_64__)
743 /* Zero pad x87 tenbyte long doubles */
744 if (size == LDOUBLE_SIZE) {
745 vtop->c.tab[2] &= 0xffff;
746 #if LDOUBLE_SIZE == 16
747 vtop->c.tab[3] = 0;
748 #endif
750 #endif
751 ptr = section_ptr_add(data_section, size);
752 size = size >> 2;
753 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
754 check.d = 1;
755 if(check.tab[0])
756 for(i=0;i<size;i++)
757 ptr[i] = vtop->c.tab[size-1-i];
758 else
759 #endif
760 for(i=0;i<size;i++)
761 ptr[i] = vtop->c.tab[i];
762 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
763 vtop->r |= VT_LVAL | VT_SYM;
764 vtop->sym = sym;
765 vtop->c.ul = 0;
767 #ifdef CONFIG_TCC_BCHECK
768 if (vtop->r & VT_MUSTBOUND)
769 gbound();
770 #endif
772 r = vtop->r & VT_VALMASK;
773 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
774 if (rc == RC_IRET)
775 rc2 = RC_LRET;
776 #ifdef TCC_TARGET_X86_64
777 else if (rc == RC_FRET)
778 rc2 = RC_QRET;
779 #endif
781 /* need to reload if:
782 - constant
783 - lvalue (need to dereference pointer)
784 - already a register, but not in the right class */
785 if (r >= VT_CONST
786 || (vtop->r & VT_LVAL)
787 || !(reg_classes[r] & rc)
788 #ifdef TCC_TARGET_X86_64
789 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
790 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
791 #else
792 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
793 #endif
796 r = get_reg(rc);
797 #ifdef TCC_TARGET_X86_64
798 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
799 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
800 #else
801 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
802 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
803 unsigned long long ll;
804 #endif
805 int r2, original_type;
806 original_type = vtop->type.t;
807 /* two register type load : expand to two words
808 temporarily */
809 #ifndef TCC_TARGET_X86_64
810 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
811 /* load constant */
812 ll = vtop->c.ull;
813 vtop->c.ui = ll; /* first word */
814 load(r, vtop);
815 vtop->r = r; /* save register value */
816 vpushi(ll >> 32); /* second word */
817 } else
818 #endif
819 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
820 (vtop->r & VT_LVAL)) {
821 /* We do not want to modifier the long long
822 pointer here, so the safest (and less
823 efficient) is to save all the other registers
824 in the stack. XXX: totally inefficient. */
825 save_regs(1);
826 /* load from memory */
827 vtop->type.t = load_type;
828 load(r, vtop);
829 vdup();
830 vtop[-1].r = r; /* save register value */
831 /* increment pointer to get second word */
832 vtop->type.t = addr_type;
833 gaddrof();
834 vpushi(load_size);
835 gen_op('+');
836 vtop->r |= VT_LVAL;
837 vtop->type.t = load_type;
838 } else {
839 /* move registers */
840 load(r, vtop);
841 vdup();
842 vtop[-1].r = r; /* save register value */
843 vtop->r = vtop[-1].r2;
845 /* Allocate second register. Here we rely on the fact that
846 get_reg() tries first to free r2 of an SValue. */
847 r2 = get_reg(rc2);
848 load(r2, vtop);
849 vpop();
850 /* write second register */
851 vtop->r2 = r2;
852 vtop->type.t = original_type;
853 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
854 int t1, t;
855 /* lvalue of scalar type : need to use lvalue type
856 because of possible cast */
857 t = vtop->type.t;
858 t1 = t;
859 /* compute memory access type */
860 if (vtop->r & VT_REF)
861 #ifdef TCC_TARGET_X86_64
862 t = VT_PTR;
863 #else
864 t = VT_INT;
865 #endif
866 else if (vtop->r & VT_LVAL_BYTE)
867 t = VT_BYTE;
868 else if (vtop->r & VT_LVAL_SHORT)
869 t = VT_SHORT;
870 if (vtop->r & VT_LVAL_UNSIGNED)
871 t |= VT_UNSIGNED;
872 vtop->type.t = t;
873 load(r, vtop);
874 /* restore wanted type */
875 vtop->type.t = t1;
876 } else {
877 /* one register type load */
878 load(r, vtop);
881 vtop->r = r;
882 #ifdef TCC_TARGET_C67
883 /* uses register pairs for doubles */
884 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
885 vtop->r2 = r+1;
886 #endif
888 return r;
891 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
892 ST_FUNC void gv2(int rc1, int rc2)
894 int v;
896 /* generate more generic register first. But VT_JMP or VT_CMP
897 values must be generated first in all cases to avoid possible
898 reload errors */
899 v = vtop[0].r & VT_VALMASK;
900 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
901 vswap();
902 gv(rc1);
903 vswap();
904 gv(rc2);
905 /* test if reload is needed for first register */
906 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
907 vswap();
908 gv(rc1);
909 vswap();
911 } else {
912 gv(rc2);
913 vswap();
914 gv(rc1);
915 vswap();
916 /* test if reload is needed for first register */
917 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
918 gv(rc2);
923 /* wrapper around RC_FRET to return a register by type */
924 static int rc_fret(int t)
926 #ifdef TCC_TARGET_X86_64
927 if (t == VT_LDOUBLE) {
928 return RC_ST0;
930 #endif
931 return RC_FRET;
934 /* wrapper around REG_FRET to return a register by type */
935 static int reg_fret(int t)
937 #ifdef TCC_TARGET_X86_64
938 if (t == VT_LDOUBLE) {
939 return TREG_ST0;
941 #endif
942 return REG_FRET;
945 /* expand long long on stack in two int registers */
946 static void lexpand(void)
948 int u;
950 u = vtop->type.t & VT_UNSIGNED;
951 gv(RC_INT);
952 vdup();
953 vtop[0].r = vtop[-1].r2;
954 vtop[0].r2 = VT_CONST;
955 vtop[-1].r2 = VT_CONST;
956 vtop[0].type.t = VT_INT | u;
957 vtop[-1].type.t = VT_INT | u;
960 #ifdef TCC_TARGET_ARM
961 /* expand long long on stack */
962 ST_FUNC void lexpand_nr(void)
964 int u,v;
966 u = vtop->type.t & VT_UNSIGNED;
967 vdup();
968 vtop->r2 = VT_CONST;
969 vtop->type.t = VT_INT | u;
970 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
971 if (v == VT_CONST) {
972 vtop[-1].c.ui = vtop->c.ull;
973 vtop->c.ui = vtop->c.ull >> 32;
974 vtop->r = VT_CONST;
975 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
976 vtop->c.ui += 4;
977 vtop->r = vtop[-1].r;
978 } else if (v > VT_CONST) {
979 vtop--;
980 lexpand();
981 } else
982 vtop->r = vtop[-1].r2;
983 vtop[-1].r2 = VT_CONST;
984 vtop[-1].type.t = VT_INT | u;
986 #endif
988 /* build a long long from two ints */
989 static void lbuild(int t)
991 gv2(RC_INT, RC_INT);
992 vtop[-1].r2 = vtop[0].r;
993 vtop[-1].type.t = t;
994 vpop();
997 /* rotate n first stack elements to the bottom
998 I1 ... In -> I2 ... In I1 [top is right]
1000 ST_FUNC void vrotb(int n)
1002 int i;
1003 SValue tmp;
1005 tmp = vtop[-n + 1];
1006 for(i=-n+1;i!=0;i++)
1007 vtop[i] = vtop[i+1];
1008 vtop[0] = tmp;
1011 /* rotate the n elements before entry e towards the top
1012 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1014 ST_FUNC void vrote(SValue *e, int n)
1016 int i;
1017 SValue tmp;
1019 tmp = *e;
1020 for(i = 0;i < n - 1; i++)
1021 e[-i] = e[-i - 1];
1022 e[-n + 1] = tmp;
1025 /* rotate n first stack elements to the top
1026 I1 ... In -> In I1 ... I(n-1) [top is right]
1028 ST_FUNC void vrott(int n)
1030 vrote(vtop, n);
1033 /* pop stack value */
1034 ST_FUNC void vpop(void)
1036 int v;
1037 v = vtop->r & VT_VALMASK;
1038 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1039 /* for x86, we need to pop the FP stack */
1040 if (v == TREG_ST0 && !nocode_wanted) {
1041 o(0xd8dd); /* fstp %st(0) */
1042 } else
1043 #endif
1044 if (v == VT_JMP || v == VT_JMPI) {
1045 /* need to put correct jump if && or || without test */
1046 gsym(vtop->c.ul);
1048 vtop--;
1051 /* convert stack entry to register and duplicate its value in another
1052 register */
1053 static void gv_dup(void)
1055 int rc, t, r, r1;
1056 SValue sv;
1058 t = vtop->type.t;
1059 if ((t & VT_BTYPE) == VT_LLONG) {
1060 lexpand();
1061 gv_dup();
1062 vswap();
1063 vrotb(3);
1064 gv_dup();
1065 vrotb(4);
1066 /* stack: H L L1 H1 */
1067 lbuild(t);
1068 vrotb(3);
1069 vrotb(3);
1070 vswap();
1071 lbuild(t);
1072 vswap();
1073 } else {
1074 /* duplicate value */
1075 rc = RC_INT;
1076 sv.type.t = VT_INT;
1077 if (is_float(t)) {
1078 rc = RC_FLOAT;
1079 #ifdef TCC_TARGET_X86_64
1080 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1081 rc = RC_ST0;
1083 #endif
1084 sv.type.t = t;
1086 r = gv(rc);
1087 r1 = get_reg(rc);
1088 sv.r = r;
1089 sv.c.ul = 0;
1090 load(r1, &sv); /* move r to r1 */
1091 vdup();
1092 /* duplicates value */
1093 if (r != r1)
1094 vtop->r = r1;
1098 /* Generate value test
1100 * Generate a test for any value (jump, comparison and integers) */
1101 int gvtst(int inv, int t)
1103 int v = vtop->r & VT_VALMASK;
1104 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1105 vpushi(0);
1106 gen_op(TOK_NE);
1108 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1109 /* constant jmp optimization */
1110 if ((vtop->c.i != 0) != inv)
1111 t = gjmp(t);
1112 vtop--;
1113 return t;
1115 return gtst(inv, t);
1118 #ifndef TCC_TARGET_X86_64
1119 /* generate CPU independent (unsigned) long long operations */
1120 static void gen_opl(int op)
1122 int t, a, b, op1, c, i;
1123 int func;
1124 unsigned short reg_iret = REG_IRET;
1125 unsigned short reg_lret = REG_LRET;
1126 SValue tmp;
1128 switch(op) {
1129 case '/':
1130 case TOK_PDIV:
1131 func = TOK___divdi3;
1132 goto gen_func;
1133 case TOK_UDIV:
1134 func = TOK___udivdi3;
1135 goto gen_func;
1136 case '%':
1137 func = TOK___moddi3;
1138 goto gen_mod_func;
1139 case TOK_UMOD:
1140 func = TOK___umoddi3;
1141 gen_mod_func:
1142 #ifdef TCC_ARM_EABI
1143 reg_iret = TREG_R2;
1144 reg_lret = TREG_R3;
1145 #endif
1146 gen_func:
1147 /* call generic long long function */
1148 vpush_global_sym(&func_old_type, func);
1149 vrott(3);
1150 gfunc_call(2);
1151 vpushi(0);
1152 vtop->r = reg_iret;
1153 vtop->r2 = reg_lret;
1154 break;
1155 case '^':
1156 case '&':
1157 case '|':
1158 case '*':
1159 case '+':
1160 case '-':
1161 t = vtop->type.t;
1162 vswap();
1163 lexpand();
1164 vrotb(3);
1165 lexpand();
1166 /* stack: L1 H1 L2 H2 */
1167 tmp = vtop[0];
1168 vtop[0] = vtop[-3];
1169 vtop[-3] = tmp;
1170 tmp = vtop[-2];
1171 vtop[-2] = vtop[-3];
1172 vtop[-3] = tmp;
1173 vswap();
1174 /* stack: H1 H2 L1 L2 */
1175 if (op == '*') {
1176 vpushv(vtop - 1);
1177 vpushv(vtop - 1);
1178 gen_op(TOK_UMULL);
1179 lexpand();
1180 /* stack: H1 H2 L1 L2 ML MH */
1181 for(i=0;i<4;i++)
1182 vrotb(6);
1183 /* stack: ML MH H1 H2 L1 L2 */
1184 tmp = vtop[0];
1185 vtop[0] = vtop[-2];
1186 vtop[-2] = tmp;
1187 /* stack: ML MH H1 L2 H2 L1 */
1188 gen_op('*');
1189 vrotb(3);
1190 vrotb(3);
1191 gen_op('*');
1192 /* stack: ML MH M1 M2 */
1193 gen_op('+');
1194 gen_op('+');
1195 } else if (op == '+' || op == '-') {
1196 /* XXX: add non carry method too (for MIPS or alpha) */
1197 if (op == '+')
1198 op1 = TOK_ADDC1;
1199 else
1200 op1 = TOK_SUBC1;
1201 gen_op(op1);
1202 /* stack: H1 H2 (L1 op L2) */
1203 vrotb(3);
1204 vrotb(3);
1205 gen_op(op1 + 1); /* TOK_xxxC2 */
1206 } else {
1207 gen_op(op);
1208 /* stack: H1 H2 (L1 op L2) */
1209 vrotb(3);
1210 vrotb(3);
1211 /* stack: (L1 op L2) H1 H2 */
1212 gen_op(op);
1213 /* stack: (L1 op L2) (H1 op H2) */
1215 /* stack: L H */
1216 lbuild(t);
1217 break;
1218 case TOK_SAR:
1219 case TOK_SHR:
1220 case TOK_SHL:
1221 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1222 t = vtop[-1].type.t;
1223 vswap();
1224 lexpand();
1225 vrotb(3);
1226 /* stack: L H shift */
1227 c = (int)vtop->c.i;
1228 /* constant: simpler */
1229 /* NOTE: all comments are for SHL. the other cases are
1230 done by swaping words */
1231 vpop();
1232 if (op != TOK_SHL)
1233 vswap();
1234 if (c >= 32) {
1235 /* stack: L H */
1236 vpop();
1237 if (c > 32) {
1238 vpushi(c - 32);
1239 gen_op(op);
1241 if (op != TOK_SAR) {
1242 vpushi(0);
1243 } else {
1244 gv_dup();
1245 vpushi(31);
1246 gen_op(TOK_SAR);
1248 vswap();
1249 } else {
1250 vswap();
1251 gv_dup();
1252 /* stack: H L L */
1253 vpushi(c);
1254 gen_op(op);
1255 vswap();
1256 vpushi(32 - c);
1257 if (op == TOK_SHL)
1258 gen_op(TOK_SHR);
1259 else
1260 gen_op(TOK_SHL);
1261 vrotb(3);
1262 /* stack: L L H */
1263 vpushi(c);
1264 if (op == TOK_SHL)
1265 gen_op(TOK_SHL);
1266 else
1267 gen_op(TOK_SHR);
1268 gen_op('|');
1270 if (op != TOK_SHL)
1271 vswap();
1272 lbuild(t);
1273 } else {
1274 /* XXX: should provide a faster fallback on x86 ? */
1275 switch(op) {
1276 case TOK_SAR:
1277 func = TOK___ashrdi3;
1278 goto gen_func;
1279 case TOK_SHR:
1280 func = TOK___lshrdi3;
1281 goto gen_func;
1282 case TOK_SHL:
1283 func = TOK___ashldi3;
1284 goto gen_func;
1287 break;
1288 default:
1289 /* compare operations */
1290 t = vtop->type.t;
1291 vswap();
1292 lexpand();
1293 vrotb(3);
1294 lexpand();
1295 /* stack: L1 H1 L2 H2 */
1296 tmp = vtop[-1];
1297 vtop[-1] = vtop[-2];
1298 vtop[-2] = tmp;
1299 /* stack: L1 L2 H1 H2 */
1300 /* compare high */
1301 op1 = op;
1302 /* when values are equal, we need to compare low words. since
1303 the jump is inverted, we invert the test too. */
1304 if (op1 == TOK_LT)
1305 op1 = TOK_LE;
1306 else if (op1 == TOK_GT)
1307 op1 = TOK_GE;
1308 else if (op1 == TOK_ULT)
1309 op1 = TOK_ULE;
1310 else if (op1 == TOK_UGT)
1311 op1 = TOK_UGE;
1312 a = 0;
1313 b = 0;
1314 gen_op(op1);
1315 if (op1 != TOK_NE) {
1316 a = gvtst(1, 0);
1318 if (op != TOK_EQ) {
1319 /* generate non equal test */
1320 /* XXX: NOT PORTABLE yet */
1321 if (a == 0) {
1322 b = gvtst(0, 0);
1323 } else {
1324 #if defined(TCC_TARGET_I386)
1325 b = psym(0x850f, 0);
1326 #elif defined(TCC_TARGET_ARM)
1327 b = ind;
1328 o(0x1A000000 | encbranch(ind, 0, 1));
1329 #elif defined(TCC_TARGET_C67)
1330 tcc_error("not implemented");
1331 #else
1332 #error not supported
1333 #endif
1336 /* compare low. Always unsigned */
1337 op1 = op;
1338 if (op1 == TOK_LT)
1339 op1 = TOK_ULT;
1340 else if (op1 == TOK_LE)
1341 op1 = TOK_ULE;
1342 else if (op1 == TOK_GT)
1343 op1 = TOK_UGT;
1344 else if (op1 == TOK_GE)
1345 op1 = TOK_UGE;
1346 gen_op(op1);
1347 a = gvtst(1, a);
1348 gsym(b);
1349 vseti(VT_JMPI, a);
1350 break;
1353 #endif
1355 /* handle integer constant optimizations and various machine
1356 independent opt */
1357 static void gen_opic(int op)
1359 int c1, c2, t1, t2, n;
1360 SValue *v1, *v2;
1361 long long l1, l2;
1362 typedef unsigned long long U;
1364 v1 = vtop - 1;
1365 v2 = vtop;
1366 t1 = v1->type.t & VT_BTYPE;
1367 t2 = v2->type.t & VT_BTYPE;
1369 if (t1 == VT_LLONG)
1370 l1 = v1->c.ll;
1371 else if (v1->type.t & VT_UNSIGNED)
1372 l1 = v1->c.ui;
1373 else
1374 l1 = v1->c.i;
1376 if (t2 == VT_LLONG)
1377 l2 = v2->c.ll;
1378 else if (v2->type.t & VT_UNSIGNED)
1379 l2 = v2->c.ui;
1380 else
1381 l2 = v2->c.i;
1383 /* currently, we cannot do computations with forward symbols */
1384 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1385 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1386 if (c1 && c2) {
1387 switch(op) {
1388 case '+': l1 += l2; break;
1389 case '-': l1 -= l2; break;
1390 case '&': l1 &= l2; break;
1391 case '^': l1 ^= l2; break;
1392 case '|': l1 |= l2; break;
1393 case '*': l1 *= l2; break;
1395 case TOK_PDIV:
1396 case '/':
1397 case '%':
1398 case TOK_UDIV:
1399 case TOK_UMOD:
1400 /* if division by zero, generate explicit division */
1401 if (l2 == 0) {
1402 if (const_wanted)
1403 tcc_error("division by zero in constant");
1404 goto general_case;
1406 switch(op) {
1407 default: l1 /= l2; break;
1408 case '%': l1 %= l2; break;
1409 case TOK_UDIV: l1 = (U)l1 / l2; break;
1410 case TOK_UMOD: l1 = (U)l1 % l2; break;
1412 break;
1413 case TOK_SHL: l1 <<= l2; break;
1414 case TOK_SHR: l1 = (U)l1 >> l2; break;
1415 case TOK_SAR: l1 >>= l2; break;
1416 /* tests */
1417 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1418 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1419 case TOK_EQ: l1 = l1 == l2; break;
1420 case TOK_NE: l1 = l1 != l2; break;
1421 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1422 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1423 case TOK_LT: l1 = l1 < l2; break;
1424 case TOK_GE: l1 = l1 >= l2; break;
1425 case TOK_LE: l1 = l1 <= l2; break;
1426 case TOK_GT: l1 = l1 > l2; break;
1427 /* logical */
1428 case TOK_LAND: l1 = l1 && l2; break;
1429 case TOK_LOR: l1 = l1 || l2; break;
1430 default:
1431 goto general_case;
1433 v1->c.ll = l1;
1434 vtop--;
1435 } else {
1436 /* if commutative ops, put c2 as constant */
1437 if (c1 && (op == '+' || op == '&' || op == '^' ||
1438 op == '|' || op == '*')) {
1439 vswap();
1440 c2 = c1; //c = c1, c1 = c2, c2 = c;
1441 l2 = l1; //l = l1, l1 = l2, l2 = l;
1443 /* Filter out NOP operations like x*1, x-0, x&-1... */
1444 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1445 op == TOK_PDIV) &&
1446 l2 == 1) ||
1447 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1448 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1449 l2 == 0) ||
1450 (op == '&' &&
1451 l2 == -1))) {
1452 /* nothing to do */
1453 vtop--;
1454 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1455 /* try to use shifts instead of muls or divs */
1456 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1457 n = -1;
1458 while (l2) {
1459 l2 >>= 1;
1460 n++;
1462 vtop->c.ll = n;
1463 if (op == '*')
1464 op = TOK_SHL;
1465 else if (op == TOK_PDIV)
1466 op = TOK_SAR;
1467 else
1468 op = TOK_SHR;
1470 goto general_case;
1471 } else if (c2 && (op == '+' || op == '-') &&
1472 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1473 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1474 /* symbol + constant case */
1475 if (op == '-')
1476 l2 = -l2;
1477 vtop--;
1478 vtop->c.ll += l2;
1479 } else {
1480 general_case:
1481 if (!nocode_wanted) {
1482 /* call low level op generator */
1483 if (t1 == VT_LLONG || t2 == VT_LLONG)
1484 gen_opl(op);
1485 else
1486 gen_opi(op);
1487 } else {
1488 vtop--;
1494 /* generate a floating point operation with constant propagation */
1495 static void gen_opif(int op)
1497 int c1, c2;
1498 SValue *v1, *v2;
1499 long double f1, f2;
1501 v1 = vtop - 1;
1502 v2 = vtop;
1503 /* currently, we cannot do computations with forward symbols */
1504 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1505 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1506 if (c1 && c2) {
1507 if (v1->type.t == VT_FLOAT) {
1508 f1 = v1->c.f;
1509 f2 = v2->c.f;
1510 } else if (v1->type.t == VT_DOUBLE) {
1511 f1 = v1->c.d;
1512 f2 = v2->c.d;
1513 } else {
1514 f1 = v1->c.ld;
1515 f2 = v2->c.ld;
1518 /* NOTE: we only do constant propagation if finite number (not
1519 NaN or infinity) (ANSI spec) */
1520 if (!ieee_finite(f1) || !ieee_finite(f2))
1521 goto general_case;
1523 switch(op) {
1524 case '+': f1 += f2; break;
1525 case '-': f1 -= f2; break;
1526 case '*': f1 *= f2; break;
1527 case '/':
1528 if (f2 == 0.0) {
1529 if (const_wanted)
1530 tcc_error("division by zero in constant");
1531 goto general_case;
1533 f1 /= f2;
1534 break;
1535 /* XXX: also handles tests ? */
1536 default:
1537 goto general_case;
1539 /* XXX: overflow test ? */
1540 if (v1->type.t == VT_FLOAT) {
1541 v1->c.f = f1;
1542 } else if (v1->type.t == VT_DOUBLE) {
1543 v1->c.d = f1;
1544 } else {
1545 v1->c.ld = f1;
1547 vtop--;
1548 } else {
1549 general_case:
1550 if (!nocode_wanted) {
1551 gen_opf(op);
1552 } else {
1553 vtop--;
1558 static int pointed_size(CType *type)
1560 int align;
1561 return type_size(pointed_type(type), &align);
1564 static void vla_runtime_pointed_size(CType *type)
1566 int align;
1567 vla_runtime_type_size(pointed_type(type), &align);
1570 static inline int is_null_pointer(SValue *p)
1572 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1573 return 0;
1574 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1575 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1576 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
1579 static inline int is_integer_btype(int bt)
1581 return (bt == VT_BYTE || bt == VT_SHORT ||
1582 bt == VT_INT || bt == VT_LLONG);
1585 /* check types for comparison or substraction of pointers */
1586 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1588 CType *type1, *type2, tmp_type1, tmp_type2;
1589 int bt1, bt2;
1591 /* null pointers are accepted for all comparisons as gcc */
1592 if (is_null_pointer(p1) || is_null_pointer(p2))
1593 return;
1594 type1 = &p1->type;
1595 type2 = &p2->type;
1596 bt1 = type1->t & VT_BTYPE;
1597 bt2 = type2->t & VT_BTYPE;
1598 /* accept comparison between pointer and integer with a warning */
1599 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1600 if (op != TOK_LOR && op != TOK_LAND )
1601 tcc_warning("comparison between pointer and integer");
1602 return;
1605 /* both must be pointers or implicit function pointers */
1606 if (bt1 == VT_PTR) {
1607 type1 = pointed_type(type1);
1608 } else if (bt1 != VT_FUNC)
1609 goto invalid_operands;
1611 if (bt2 == VT_PTR) {
1612 type2 = pointed_type(type2);
1613 } else if (bt2 != VT_FUNC) {
1614 invalid_operands:
1615 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1617 if ((type1->t & VT_BTYPE) == VT_VOID ||
1618 (type2->t & VT_BTYPE) == VT_VOID)
1619 return;
1620 tmp_type1 = *type1;
1621 tmp_type2 = *type2;
1622 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1623 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1624 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1625 /* gcc-like error if '-' is used */
1626 if (op == '-')
1627 goto invalid_operands;
1628 else
1629 tcc_warning("comparison of distinct pointer types lacks a cast");
1633 /* generic gen_op: handles types problems */
1634 ST_FUNC void gen_op(int op)
1636 int u, t1, t2, bt1, bt2, t;
1637 CType type1;
1639 t1 = vtop[-1].type.t;
1640 t2 = vtop[0].type.t;
1641 bt1 = t1 & VT_BTYPE;
1642 bt2 = t2 & VT_BTYPE;
1644 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1645 /* at least one operand is a pointer */
1646 /* relationnal op: must be both pointers */
1647 if (op >= TOK_ULT && op <= TOK_LOR) {
1648 check_comparison_pointer_types(vtop - 1, vtop, op);
1649 /* pointers are handled are unsigned */
1650 #ifdef TCC_TARGET_X86_64
1651 t = VT_LLONG | VT_UNSIGNED;
1652 #else
1653 t = VT_INT | VT_UNSIGNED;
1654 #endif
1655 goto std_op;
1657 /* if both pointers, then it must be the '-' op */
1658 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1659 if (op != '-')
1660 tcc_error("cannot use pointers here");
1661 check_comparison_pointer_types(vtop - 1, vtop, op);
1662 /* XXX: check that types are compatible */
1663 if (vtop[-1].type.t & VT_VLA) {
1664 vla_runtime_pointed_size(&vtop[-1].type);
1665 } else {
1666 vpushi(pointed_size(&vtop[-1].type));
1668 vrott(3);
1669 gen_opic(op);
1670 /* set to integer type */
1671 #ifdef TCC_TARGET_X86_64
1672 vtop->type.t = VT_LLONG;
1673 #else
1674 vtop->type.t = VT_INT;
1675 #endif
1676 vswap();
1677 gen_op(TOK_PDIV);
1678 } else {
1679 /* exactly one pointer : must be '+' or '-'. */
1680 if (op != '-' && op != '+')
1681 tcc_error("cannot use pointers here");
1682 /* Put pointer as first operand */
1683 if (bt2 == VT_PTR) {
1684 vswap();
1685 swap(&t1, &t2);
1687 type1 = vtop[-1].type;
1688 type1.t &= ~VT_ARRAY;
1689 if (vtop[-1].type.t & VT_VLA)
1690 vla_runtime_pointed_size(&vtop[-1].type);
1691 else {
1692 u = pointed_size(&vtop[-1].type);
1693 if (u < 0)
1694 tcc_error("unknown array element size");
1695 #ifdef TCC_TARGET_X86_64
1696 vpushll(u);
1697 #else
1698 /* XXX: cast to int ? (long long case) */
1699 vpushi(u);
1700 #endif
1702 gen_op('*');
1703 #ifdef CONFIG_TCC_BCHECK
1704 /* if evaluating constant expression, no code should be
1705 generated, so no bound check */
1706 if (tcc_state->do_bounds_check && !const_wanted) {
1707 /* if bounded pointers, we generate a special code to
1708 test bounds */
1709 if (op == '-') {
1710 vpushi(0);
1711 vswap();
1712 gen_op('-');
1714 gen_bounded_ptr_add();
1715 } else
1716 #endif
1718 gen_opic(op);
1720 /* put again type if gen_opic() swaped operands */
1721 vtop->type = type1;
1723 } else if (is_float(bt1) || is_float(bt2)) {
1724 /* compute bigger type and do implicit casts */
1725 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1726 t = VT_LDOUBLE;
1727 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1728 t = VT_DOUBLE;
1729 } else {
1730 t = VT_FLOAT;
1732 /* floats can only be used for a few operations */
1733 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1734 (op < TOK_ULT || op > TOK_GT))
1735 tcc_error("invalid operands for binary operation");
1736 goto std_op;
1737 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1738 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1739 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1740 t |= VT_UNSIGNED;
1741 goto std_op;
1742 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1743 /* cast to biggest op */
1744 t = VT_LLONG;
1745 /* convert to unsigned if it does not fit in a long long */
1746 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1747 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1748 t |= VT_UNSIGNED;
1749 goto std_op;
1750 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1751 tcc_error("comparison of struct");
1752 } else {
1753 /* integer operations */
1754 t = VT_INT;
1755 /* convert to unsigned if it does not fit in an integer */
1756 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1757 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1758 t |= VT_UNSIGNED;
1759 std_op:
1760 /* XXX: currently, some unsigned operations are explicit, so
1761 we modify them here */
1762 if (t & VT_UNSIGNED) {
1763 if (op == TOK_SAR)
1764 op = TOK_SHR;
1765 else if (op == '/')
1766 op = TOK_UDIV;
1767 else if (op == '%')
1768 op = TOK_UMOD;
1769 else if (op == TOK_LT)
1770 op = TOK_ULT;
1771 else if (op == TOK_GT)
1772 op = TOK_UGT;
1773 else if (op == TOK_LE)
1774 op = TOK_ULE;
1775 else if (op == TOK_GE)
1776 op = TOK_UGE;
1778 vswap();
1779 type1.t = t;
1780 gen_cast(&type1);
1781 vswap();
1782 /* special case for shifts and long long: we keep the shift as
1783 an integer */
1784 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1785 type1.t = VT_INT;
1786 gen_cast(&type1);
1787 if (is_float(t))
1788 gen_opif(op);
1789 else
1790 gen_opic(op);
1791 if (op >= TOK_ULT && op <= TOK_GT) {
1792 /* relationnal op: the result is an int */
1793 vtop->type.t = VT_INT;
1794 } else {
1795 vtop->type.t = t;
1800 #ifndef TCC_TARGET_ARM
1801 /* generic itof for unsigned long long case */
1802 static void gen_cvt_itof1(int t)
1804 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1805 (VT_LLONG | VT_UNSIGNED)) {
1807 if (t == VT_FLOAT)
1808 vpush_global_sym(&func_old_type, TOK___floatundisf);
1809 #if LDOUBLE_SIZE != 8
1810 else if (t == VT_LDOUBLE)
1811 vpush_global_sym(&func_old_type, TOK___floatundixf);
1812 #endif
1813 else
1814 vpush_global_sym(&func_old_type, TOK___floatundidf);
1815 vrott(2);
1816 gfunc_call(1);
1817 vpushi(0);
1818 vtop->r = reg_fret(t);
1819 } else {
1820 gen_cvt_itof(t);
1823 #endif
1825 /* generic ftoi for unsigned long long case */
1826 static void gen_cvt_ftoi1(int t)
1828 int st;
1830 if (t == (VT_LLONG | VT_UNSIGNED)) {
1831 /* not handled natively */
1832 st = vtop->type.t & VT_BTYPE;
1833 if (st == VT_FLOAT)
1834 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1835 #if LDOUBLE_SIZE != 8
1836 else if (st == VT_LDOUBLE)
1837 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1838 #endif
1839 else
1840 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1841 vrott(2);
1842 gfunc_call(1);
1843 vpushi(0);
1844 vtop->r = REG_IRET;
1845 vtop->r2 = REG_LRET;
1846 } else {
1847 gen_cvt_ftoi(t);
1851 /* force char or short cast */
1852 static void force_charshort_cast(int t)
1854 int bits, dbt;
1855 dbt = t & VT_BTYPE;
1856 /* XXX: add optimization if lvalue : just change type and offset */
1857 if (dbt == VT_BYTE)
1858 bits = 8;
1859 else
1860 bits = 16;
1861 if (t & VT_UNSIGNED) {
1862 vpushi((1 << bits) - 1);
1863 gen_op('&');
1864 } else {
1865 bits = 32 - bits;
1866 vpushi(bits);
1867 gen_op(TOK_SHL);
1868 /* result must be signed or the SAR is converted to an SHL
1869 This was not the case when "t" was a signed short
1870 and the last value on the stack was an unsigned int */
1871 vtop->type.t &= ~VT_UNSIGNED;
1872 vpushi(bits);
1873 gen_op(TOK_SAR);
1877 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1878 static void gen_cast(CType *type)
1880 int sbt, dbt, sf, df, c, p;
1882 /* special delayed cast for char/short */
1883 /* XXX: in some cases (multiple cascaded casts), it may still
1884 be incorrect */
1885 if (vtop->r & VT_MUSTCAST) {
1886 vtop->r &= ~VT_MUSTCAST;
1887 force_charshort_cast(vtop->type.t);
1890 /* bitfields first get cast to ints */
1891 if (vtop->type.t & VT_BITFIELD) {
1892 gv(RC_INT);
1895 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1896 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1898 if (sbt != dbt) {
1899 sf = is_float(sbt);
1900 df = is_float(dbt);
1901 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1902 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1903 if (c) {
1904 /* constant case: we can do it now */
1905 /* XXX: in ISOC, cannot do it if error in convert */
1906 if (sbt == VT_FLOAT)
1907 vtop->c.ld = vtop->c.f;
1908 else if (sbt == VT_DOUBLE)
1909 vtop->c.ld = vtop->c.d;
1911 if (df) {
1912 if ((sbt & VT_BTYPE) == VT_LLONG) {
1913 if (sbt & VT_UNSIGNED)
1914 vtop->c.ld = vtop->c.ull;
1915 else
1916 vtop->c.ld = vtop->c.ll;
1917 } else if(!sf) {
1918 if (sbt & VT_UNSIGNED)
1919 vtop->c.ld = vtop->c.ui;
1920 else
1921 vtop->c.ld = vtop->c.i;
1924 if (dbt == VT_FLOAT)
1925 vtop->c.f = (float)vtop->c.ld;
1926 else if (dbt == VT_DOUBLE)
1927 vtop->c.d = (double)vtop->c.ld;
1928 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1929 vtop->c.ull = (unsigned long long)vtop->c.ld;
1930 } else if (sf && dbt == VT_BOOL) {
1931 vtop->c.i = (vtop->c.ld != 0);
1932 } else {
1933 if(sf)
1934 vtop->c.ll = (long long)vtop->c.ld;
1935 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1936 vtop->c.ll = vtop->c.ull;
1937 else if (sbt & VT_UNSIGNED)
1938 vtop->c.ll = vtop->c.ui;
1939 #ifdef TCC_TARGET_X86_64
1940 else if (sbt == VT_PTR)
1942 #endif
1943 else if (sbt != VT_LLONG)
1944 vtop->c.ll = vtop->c.i;
1946 if (dbt == (VT_LLONG|VT_UNSIGNED))
1947 vtop->c.ull = vtop->c.ll;
1948 else if (dbt == VT_BOOL)
1949 vtop->c.i = (vtop->c.ll != 0);
1950 else if (dbt != VT_LLONG) {
1951 int s = 0;
1952 if ((dbt & VT_BTYPE) == VT_BYTE)
1953 s = 24;
1954 else if ((dbt & VT_BTYPE) == VT_SHORT)
1955 s = 16;
1957 if(dbt & VT_UNSIGNED)
1958 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1959 else
1960 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1963 } else if (p && dbt == VT_BOOL) {
1964 vtop->r = VT_CONST;
1965 vtop->c.i = 1;
1966 } else if (!nocode_wanted) {
1967 /* non constant case: generate code */
1968 if (sf && df) {
1969 /* convert from fp to fp */
1970 gen_cvt_ftof(dbt);
1971 } else if (df) {
1972 /* convert int to fp */
1973 gen_cvt_itof1(dbt);
1974 } else if (sf) {
1975 /* convert fp to int */
1976 if (dbt == VT_BOOL) {
1977 vpushi(0);
1978 gen_op(TOK_NE);
1979 } else {
1980 /* we handle char/short/etc... with generic code */
1981 if (dbt != (VT_INT | VT_UNSIGNED) &&
1982 dbt != (VT_LLONG | VT_UNSIGNED) &&
1983 dbt != VT_LLONG)
1984 dbt = VT_INT;
1985 gen_cvt_ftoi1(dbt);
1986 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1987 /* additional cast for char/short... */
1988 vtop->type.t = dbt;
1989 gen_cast(type);
1992 #ifndef TCC_TARGET_X86_64
1993 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1994 if ((sbt & VT_BTYPE) != VT_LLONG) {
1995 /* scalar to long long */
1996 /* machine independent conversion */
1997 gv(RC_INT);
1998 /* generate high word */
1999 if (sbt == (VT_INT | VT_UNSIGNED)) {
2000 vpushi(0);
2001 gv(RC_INT);
2002 } else {
2003 if (sbt == VT_PTR) {
2004 /* cast from pointer to int before we apply
2005 shift operation, which pointers don't support*/
2006 gen_cast(&int_type);
2008 gv_dup();
2009 vpushi(31);
2010 gen_op(TOK_SAR);
2012 /* patch second register */
2013 vtop[-1].r2 = vtop->r;
2014 vpop();
2016 #else
2017 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2018 (dbt & VT_BTYPE) == VT_PTR ||
2019 (dbt & VT_BTYPE) == VT_FUNC) {
2020 if ((sbt & VT_BTYPE) != VT_LLONG &&
2021 (sbt & VT_BTYPE) != VT_PTR &&
2022 (sbt & VT_BTYPE) != VT_FUNC) {
2023 /* need to convert from 32bit to 64bit */
2024 int r = gv(RC_INT);
2025 if (sbt != (VT_INT | VT_UNSIGNED)) {
2026 /* x86_64 specific: movslq */
2027 o(0x6348);
2028 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2031 #endif
2032 } else if (dbt == VT_BOOL) {
2033 /* scalar to bool */
2034 vpushi(0);
2035 gen_op(TOK_NE);
2036 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2037 (dbt & VT_BTYPE) == VT_SHORT) {
2038 if (sbt == VT_PTR) {
2039 vtop->type.t = VT_INT;
2040 tcc_warning("nonportable conversion from pointer to char/short");
2042 force_charshort_cast(dbt);
2043 } else if ((dbt & VT_BTYPE) == VT_INT) {
2044 /* scalar to int */
2045 if (sbt == VT_LLONG) {
2046 /* from long long: just take low order word */
2047 lexpand();
2048 vpop();
2050 /* if lvalue and single word type, nothing to do because
2051 the lvalue already contains the real type size (see
2052 VT_LVAL_xxx constants) */
2055 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2056 /* if we are casting between pointer types,
2057 we must update the VT_LVAL_xxx size */
2058 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2059 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2061 vtop->type = *type;
2064 /* return type size as known at compile time. Put alignment at 'a' */
2065 ST_FUNC int type_size(CType *type, int *a)
2067 Sym *s;
2068 int bt;
2070 bt = type->t & VT_BTYPE;
2071 if (bt == VT_STRUCT) {
2072 /* struct/union */
2073 s = type->ref;
2074 *a = s->r;
2075 return s->c;
2076 } else if (bt == VT_PTR) {
2077 if (type->t & VT_ARRAY) {
2078 int ts;
2080 s = type->ref;
2081 ts = type_size(&s->type, a);
2083 if (ts < 0 && s->c < 0)
2084 ts = -ts;
2086 return ts * s->c;
2087 } else {
2088 *a = PTR_SIZE;
2089 return PTR_SIZE;
2091 } else if (bt == VT_LDOUBLE) {
2092 *a = LDOUBLE_ALIGN;
2093 return LDOUBLE_SIZE;
2094 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2095 #ifdef TCC_TARGET_I386
2096 #ifdef TCC_TARGET_PE
2097 *a = 8;
2098 #else
2099 *a = 4;
2100 #endif
2101 #elif defined(TCC_TARGET_ARM)
2102 #ifdef TCC_ARM_EABI
2103 *a = 8;
2104 #else
2105 *a = 4;
2106 #endif
2107 #else
2108 *a = 8;
2109 #endif
2110 return 8;
2111 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2112 *a = 4;
2113 return 4;
2114 } else if (bt == VT_SHORT) {
2115 *a = 2;
2116 return 2;
2117 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2118 *a = 8;
2119 return 16;
2120 } else {
2121 /* char, void, function, _Bool */
2122 *a = 1;
2123 return 1;
2127 /* push type size as known at runtime time on top of value stack. Put
2128 alignment at 'a' */
2129 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2131 if (type->t & VT_VLA) {
2132 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2133 } else {
2134 vpushi(type_size(type, a));
2138 static void vla_sp_save(void) {
2139 if (!(vla_flags & VLA_SP_LOC_SET)) {
2140 *vla_sp_loc = (loc -= PTR_SIZE);
2141 vla_flags |= VLA_SP_LOC_SET;
2143 if (!(vla_flags & VLA_SP_SAVED)) {
2144 gen_vla_sp_save(*vla_sp_loc);
2145 vla_flags |= VLA_SP_SAVED;
2149 /* return the pointed type of t */
2150 static inline CType *pointed_type(CType *type)
2152 return &type->ref->type;
2155 /* modify type so that its it is a pointer to type. */
2156 ST_FUNC void mk_pointer(CType *type)
2158 Sym *s;
2159 s = sym_push(SYM_FIELD, type, 0, -1);
2160 type->t = VT_PTR | (type->t & ~VT_TYPE);
2161 type->ref = s;
2164 /* compare function types. OLD functions match any new functions */
2165 static int is_compatible_func(CType *type1, CType *type2)
2167 Sym *s1, *s2;
2169 s1 = type1->ref;
2170 s2 = type2->ref;
2171 if (!is_compatible_types(&s1->type, &s2->type))
2172 return 0;
2173 /* check func_call */
2174 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2175 return 0;
2176 /* XXX: not complete */
2177 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2178 return 1;
2179 if (s1->c != s2->c)
2180 return 0;
2181 while (s1 != NULL) {
2182 if (s2 == NULL)
2183 return 0;
2184 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2185 return 0;
2186 s1 = s1->next;
2187 s2 = s2->next;
2189 if (s2)
2190 return 0;
2191 return 1;
2194 /* return true if type1 and type2 are the same. If unqualified is
2195 true, qualifiers on the types are ignored.
2197 - enums are not checked as gcc __builtin_types_compatible_p ()
2199 static int compare_types(CType *type1, CType *type2, int unqualified)
2201 int bt1, t1, t2;
2203 t1 = type1->t & VT_TYPE;
2204 t2 = type2->t & VT_TYPE;
2205 if (unqualified) {
2206 /* strip qualifiers before comparing */
2207 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2208 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2210 /* XXX: bitfields ? */
2211 if (t1 != t2)
2212 return 0;
2213 /* test more complicated cases */
2214 bt1 = t1 & VT_BTYPE;
2215 if (bt1 == VT_PTR) {
2216 type1 = pointed_type(type1);
2217 type2 = pointed_type(type2);
2218 return is_compatible_types(type1, type2);
2219 } else if (bt1 == VT_STRUCT) {
2220 return (type1->ref == type2->ref);
2221 } else if (bt1 == VT_FUNC) {
2222 return is_compatible_func(type1, type2);
2223 } else {
2224 return 1;
2228 /* return true if type1 and type2 are exactly the same (including
2229 qualifiers).
2231 static int is_compatible_types(CType *type1, CType *type2)
2233 return compare_types(type1,type2,0);
2236 /* return true if type1 and type2 are the same (ignoring qualifiers).
2238 static int is_compatible_parameter_types(CType *type1, CType *type2)
2240 return compare_types(type1,type2,1);
2243 /* print a type. If 'varstr' is not NULL, then the variable is also
2244 printed in the type */
2245 /* XXX: union */
2246 /* XXX: add array and function pointers */
2247 static void type_to_str(char *buf, int buf_size,
2248 CType *type, const char *varstr)
2250 int bt, v, t;
2251 Sym *s, *sa;
2252 char buf1[256];
2253 const char *tstr;
2255 t = type->t & VT_TYPE;
2256 bt = t & VT_BTYPE;
2257 buf[0] = '\0';
2258 if (t & VT_CONSTANT)
2259 pstrcat(buf, buf_size, "const ");
2260 if (t & VT_VOLATILE)
2261 pstrcat(buf, buf_size, "volatile ");
2262 if (t & VT_UNSIGNED)
2263 pstrcat(buf, buf_size, "unsigned ");
2264 switch(bt) {
2265 case VT_VOID:
2266 tstr = "void";
2267 goto add_tstr;
2268 case VT_BOOL:
2269 tstr = "_Bool";
2270 goto add_tstr;
2271 case VT_BYTE:
2272 tstr = "char";
2273 goto add_tstr;
2274 case VT_SHORT:
2275 tstr = "short";
2276 goto add_tstr;
2277 case VT_INT:
2278 tstr = "int";
2279 goto add_tstr;
2280 case VT_LONG:
2281 tstr = "long";
2282 goto add_tstr;
2283 case VT_LLONG:
2284 tstr = "long long";
2285 goto add_tstr;
2286 case VT_FLOAT:
2287 tstr = "float";
2288 goto add_tstr;
2289 case VT_DOUBLE:
2290 tstr = "double";
2291 goto add_tstr;
2292 case VT_LDOUBLE:
2293 tstr = "long double";
2294 add_tstr:
2295 pstrcat(buf, buf_size, tstr);
2296 break;
2297 case VT_ENUM:
2298 case VT_STRUCT:
2299 if (bt == VT_STRUCT)
2300 tstr = "struct ";
2301 else
2302 tstr = "enum ";
2303 pstrcat(buf, buf_size, tstr);
2304 v = type->ref->v & ~SYM_STRUCT;
2305 if (v >= SYM_FIRST_ANOM)
2306 pstrcat(buf, buf_size, "<anonymous>");
2307 else
2308 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2309 break;
2310 case VT_FUNC:
2311 s = type->ref;
2312 type_to_str(buf, buf_size, &s->type, varstr);
2313 pstrcat(buf, buf_size, "(");
2314 sa = s->next;
2315 while (sa != NULL) {
2316 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2317 pstrcat(buf, buf_size, buf1);
2318 sa = sa->next;
2319 if (sa)
2320 pstrcat(buf, buf_size, ", ");
2322 pstrcat(buf, buf_size, ")");
2323 goto no_var;
2324 case VT_PTR:
2325 s = type->ref;
2326 pstrcpy(buf1, sizeof(buf1), "*");
2327 if (varstr)
2328 pstrcat(buf1, sizeof(buf1), varstr);
2329 type_to_str(buf, buf_size, &s->type, buf1);
2330 goto no_var;
2332 if (varstr) {
2333 pstrcat(buf, buf_size, " ");
2334 pstrcat(buf, buf_size, varstr);
2336 no_var: ;
2339 /* verify type compatibility to store vtop in 'dt' type, and generate
2340 casts if needed. */
2341 static void gen_assign_cast(CType *dt)
2343 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2344 char buf1[256], buf2[256];
2345 int dbt, sbt;
2347 st = &vtop->type; /* source type */
2348 dbt = dt->t & VT_BTYPE;
2349 sbt = st->t & VT_BTYPE;
2350 if (sbt == VT_VOID)
2351 tcc_error("Cannot assign void value");
2352 if (dt->t & VT_CONSTANT)
2353 tcc_warning("assignment of read-only location");
2354 switch(dbt) {
2355 case VT_PTR:
2356 /* special cases for pointers */
2357 /* '0' can also be a pointer */
2358 if (is_null_pointer(vtop))
2359 goto type_ok;
2360 /* accept implicit pointer to integer cast with warning */
2361 if (is_integer_btype(sbt)) {
2362 tcc_warning("assignment makes pointer from integer without a cast");
2363 goto type_ok;
2365 type1 = pointed_type(dt);
2366 /* a function is implicitely a function pointer */
2367 if (sbt == VT_FUNC) {
2368 if ((type1->t & VT_BTYPE) != VT_VOID &&
2369 !is_compatible_types(pointed_type(dt), st))
2370 tcc_warning("assignment from incompatible pointer type");
2371 goto type_ok;
2373 if (sbt != VT_PTR)
2374 goto error;
2375 type2 = pointed_type(st);
2376 if ((type1->t & VT_BTYPE) == VT_VOID ||
2377 (type2->t & VT_BTYPE) == VT_VOID) {
2378 /* void * can match anything */
2379 } else {
2380 /* exact type match, except for unsigned */
2381 tmp_type1 = *type1;
2382 tmp_type2 = *type2;
2383 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2384 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2385 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2386 tcc_warning("assignment from incompatible pointer type");
2388 /* check const and volatile */
2389 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2390 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2391 tcc_warning("assignment discards qualifiers from pointer target type");
2392 break;
2393 case VT_BYTE:
2394 case VT_SHORT:
2395 case VT_INT:
2396 case VT_LLONG:
2397 if (sbt == VT_PTR || sbt == VT_FUNC) {
2398 tcc_warning("assignment makes integer from pointer without a cast");
2400 /* XXX: more tests */
2401 break;
2402 case VT_STRUCT:
2403 tmp_type1 = *dt;
2404 tmp_type2 = *st;
2405 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2406 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2407 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2408 error:
2409 type_to_str(buf1, sizeof(buf1), st, NULL);
2410 type_to_str(buf2, sizeof(buf2), dt, NULL);
2411 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2413 break;
2415 type_ok:
2416 gen_cast(dt);
2419 /* store vtop in lvalue pushed on stack */
2420 ST_FUNC void vstore(void)
2422 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2424 ft = vtop[-1].type.t;
2425 sbt = vtop->type.t & VT_BTYPE;
2426 dbt = ft & VT_BTYPE;
2427 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2428 (sbt == VT_INT && dbt == VT_SHORT))
2429 && !(vtop->type.t & VT_BITFIELD)) {
2430 /* optimize char/short casts */
2431 delayed_cast = VT_MUSTCAST;
2432 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2433 /* XXX: factorize */
2434 if (ft & VT_CONSTANT)
2435 tcc_warning("assignment of read-only location");
2436 } else {
2437 delayed_cast = 0;
2438 if (!(ft & VT_BITFIELD))
2439 gen_assign_cast(&vtop[-1].type);
2442 if (sbt == VT_STRUCT) {
2443 /* if structure, only generate pointer */
2444 /* structure assignment : generate memcpy */
2445 /* XXX: optimize if small size */
2446 if (!nocode_wanted) {
2447 size = type_size(&vtop->type, &align);
2449 /* destination */
2450 vswap();
2451 vtop->type.t = VT_PTR;
2452 gaddrof();
2454 /* address of memcpy() */
2455 #ifdef TCC_ARM_EABI
2456 if(!(align & 7))
2457 vpush_global_sym(&func_old_type, TOK_memcpy8);
2458 else if(!(align & 3))
2459 vpush_global_sym(&func_old_type, TOK_memcpy4);
2460 else
2461 #endif
2462 vpush_global_sym(&func_old_type, TOK_memcpy);
2464 vswap();
2465 /* source */
2466 vpushv(vtop - 2);
2467 vtop->type.t = VT_PTR;
2468 gaddrof();
2469 /* type size */
2470 vpushi(size);
2471 gfunc_call(3);
2472 } else {
2473 vswap();
2474 vpop();
2476 /* leave source on stack */
2477 } else if (ft & VT_BITFIELD) {
2478 /* bitfield store handling */
2479 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2480 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2481 /* remove bit field info to avoid loops */
2482 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2484 /* duplicate source into other register */
2485 gv_dup();
2486 vswap();
2487 vrott(3);
2489 if((ft & VT_BTYPE) == VT_BOOL) {
2490 gen_cast(&vtop[-1].type);
2491 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2494 /* duplicate destination */
2495 vdup();
2496 vtop[-1] = vtop[-2];
2498 /* mask and shift source */
2499 if((ft & VT_BTYPE) != VT_BOOL) {
2500 if((ft & VT_BTYPE) == VT_LLONG) {
2501 vpushll((1ULL << bit_size) - 1ULL);
2502 } else {
2503 vpushi((1 << bit_size) - 1);
2505 gen_op('&');
2507 vpushi(bit_pos);
2508 gen_op(TOK_SHL);
2509 /* load destination, mask and or with source */
2510 vswap();
2511 if((ft & VT_BTYPE) == VT_LLONG) {
2512 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2513 } else {
2514 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2516 gen_op('&');
2517 gen_op('|');
2518 /* store result */
2519 vstore();
2521 /* pop off shifted source from "duplicate source..." above */
2522 vpop();
2524 } else {
2525 #ifdef CONFIG_TCC_BCHECK
2526 /* bound check case */
2527 if (vtop[-1].r & VT_MUSTBOUND) {
2528 vswap();
2529 gbound();
2530 vswap();
2532 #endif
2533 if (!nocode_wanted) {
2534 rc = RC_INT;
2535 if (is_float(ft)) {
2536 rc = RC_FLOAT;
2537 #ifdef TCC_TARGET_X86_64
2538 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2539 rc = RC_ST0;
2540 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2541 rc = RC_FRET;
2543 #endif
2545 r = gv(rc); /* generate value */
2546 /* if lvalue was saved on stack, must read it */
2547 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2548 SValue sv;
2549 t = get_reg(RC_INT);
2550 #ifdef TCC_TARGET_X86_64
2551 sv.type.t = VT_PTR;
2552 #else
2553 sv.type.t = VT_INT;
2554 #endif
2555 sv.r = VT_LOCAL | VT_LVAL;
2556 sv.c.ul = vtop[-1].c.ul;
2557 load(t, &sv);
2558 vtop[-1].r = t | VT_LVAL;
2560 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2561 #ifdef TCC_TARGET_X86_64
2562 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2563 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2564 #else
2565 if ((ft & VT_BTYPE) == VT_LLONG) {
2566 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2567 #endif
2568 vtop[-1].type.t = load_type;
2569 store(r, vtop - 1);
2570 vswap();
2571 /* convert to int to increment easily */
2572 vtop->type.t = addr_type;
2573 gaddrof();
2574 vpushi(load_size);
2575 gen_op('+');
2576 vtop->r |= VT_LVAL;
2577 vswap();
2578 vtop[-1].type.t = load_type;
2579 /* XXX: it works because r2 is spilled last ! */
2580 store(vtop->r2, vtop - 1);
2581 } else {
2582 store(r, vtop - 1);
2585 vswap();
2586 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2587 vtop->r |= delayed_cast;
2591 /* post defines POST/PRE add. c is the token ++ or -- */
2592 ST_FUNC void inc(int post, int c)
2594 test_lvalue();
2595 vdup(); /* save lvalue */
2596 if (post) {
2597 gv_dup(); /* duplicate value */
2598 vrotb(3);
2599 vrotb(3);
2601 /* add constant */
2602 vpushi(c - TOK_MID);
2603 gen_op('+');
2604 vstore(); /* store value */
2605 if (post)
2606 vpop(); /* if post op, return saved value */
2609 /* Parse GNUC __attribute__ extension. Currently, the following
2610 extensions are recognized:
2611 - aligned(n) : set data/function alignment.
2612 - packed : force data alignment to 1
2613 - section(x) : generate data/code in this section.
2614 - unused : currently ignored, but may be used someday.
2615 - regparm(n) : pass function parameters in registers (i386 only)
2617 static void parse_attribute(AttributeDef *ad)
2619 int t, n;
2621 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2622 next();
2623 skip('(');
2624 skip('(');
2625 while (tok != ')') {
2626 if (tok < TOK_IDENT)
2627 expect("attribute name");
2628 t = tok;
2629 next();
2630 switch(t) {
2631 case TOK_SECTION1:
2632 case TOK_SECTION2:
2633 skip('(');
2634 if (tok != TOK_STR)
2635 expect("section name");
2636 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2637 next();
2638 skip(')');
2639 break;
2640 case TOK_ALIAS1:
2641 case TOK_ALIAS2:
2642 skip('(');
2643 if (tok != TOK_STR)
2644 expect("alias(\"target\")");
2645 ad->alias_target = /* save string as token, for later */
2646 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2647 next();
2648 skip(')');
2649 break;
2650 case TOK_ALIGNED1:
2651 case TOK_ALIGNED2:
2652 if (tok == '(') {
2653 next();
2654 n = expr_const();
2655 if (n <= 0 || (n & (n - 1)) != 0)
2656 tcc_error("alignment must be a positive power of two");
2657 skip(')');
2658 } else {
2659 n = MAX_ALIGN;
2661 ad->aligned = n;
2662 break;
2663 case TOK_PACKED1:
2664 case TOK_PACKED2:
2665 ad->packed = 1;
2666 break;
2667 case TOK_WEAK1:
2668 case TOK_WEAK2:
2669 ad->weak = 1;
2670 break;
2671 case TOK_UNUSED1:
2672 case TOK_UNUSED2:
2673 /* currently, no need to handle it because tcc does not
2674 track unused objects */
2675 break;
2676 case TOK_NORETURN1:
2677 case TOK_NORETURN2:
2678 /* currently, no need to handle it because tcc does not
2679 track unused objects */
2680 break;
2681 case TOK_CDECL1:
2682 case TOK_CDECL2:
2683 case TOK_CDECL3:
2684 ad->func_call = FUNC_CDECL;
2685 break;
2686 case TOK_STDCALL1:
2687 case TOK_STDCALL2:
2688 case TOK_STDCALL3:
2689 ad->func_call = FUNC_STDCALL;
2690 break;
2691 #ifdef TCC_TARGET_I386
2692 case TOK_REGPARM1:
2693 case TOK_REGPARM2:
2694 skip('(');
2695 n = expr_const();
2696 if (n > 3)
2697 n = 3;
2698 else if (n < 0)
2699 n = 0;
2700 if (n > 0)
2701 ad->func_call = FUNC_FASTCALL1 + n - 1;
2702 skip(')');
2703 break;
2704 case TOK_FASTCALL1:
2705 case TOK_FASTCALL2:
2706 case TOK_FASTCALL3:
2707 ad->func_call = FUNC_FASTCALLW;
2708 break;
2709 #endif
2710 case TOK_MODE:
2711 skip('(');
2712 switch(tok) {
2713 case TOK_MODE_DI:
2714 ad->mode = VT_LLONG + 1;
2715 break;
2716 case TOK_MODE_HI:
2717 ad->mode = VT_SHORT + 1;
2718 break;
2719 case TOK_MODE_SI:
2720 ad->mode = VT_INT + 1;
2721 break;
2722 default:
2723 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2724 break;
2726 next();
2727 skip(')');
2728 break;
2729 case TOK_DLLEXPORT:
2730 ad->func_export = 1;
2731 break;
2732 case TOK_DLLIMPORT:
2733 ad->func_import = 1;
2734 break;
2735 default:
2736 if (tcc_state->warn_unsupported)
2737 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2738 /* skip parameters */
2739 if (tok == '(') {
2740 int parenthesis = 0;
2741 do {
2742 if (tok == '(')
2743 parenthesis++;
2744 else if (tok == ')')
2745 parenthesis--;
2746 next();
2747 } while (parenthesis && tok != -1);
2749 break;
2751 if (tok != ',')
2752 break;
2753 next();
2755 skip(')');
2756 skip(')');
2760 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2761 static void struct_decl(CType *type, int u, int tdef)
2763 int a, v, size, align, maxalign, c, offset, flexible;
2764 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2765 Sym *s, *ss, *ass, **ps;
2766 AttributeDef ad;
2767 CType type1, btype;
2769 a = tok; /* save decl type */
2770 next();
2771 if (tok != '{') {
2772 v = tok;
2773 next();
2774 /* struct already defined ? return it */
2775 if (v < TOK_IDENT)
2776 expect("struct/union/enum name");
2777 s = struct_find(v);
2778 if (s) {
2779 if (s->type.t != a)
2780 tcc_error("invalid type");
2781 goto do_decl;
2782 } else if (tok >= TOK_IDENT && !tdef)
2783 tcc_error("unknown struct/union/enum");
2784 } else {
2785 v = anon_sym++;
2787 type1.t = a;
2788 type1.ref = NULL;
2789 /* we put an undefined size for struct/union */
2790 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2791 s->r = 0; /* default alignment is zero as gcc */
2792 /* put struct/union/enum name in type */
2793 do_decl:
2794 type->t = u;
2795 type->ref = s;
2797 if (tok == '{') {
2798 next();
2799 if (s->c != -1)
2800 tcc_error("struct/union/enum already defined");
2801 /* cannot be empty */
2802 c = 0;
2803 /* non empty enums are not allowed */
2804 if (a == TOK_ENUM) {
2805 for(;;) {
2806 v = tok;
2807 if (v < TOK_UIDENT)
2808 expect("identifier");
2809 ss = sym_find(v);
2810 if (ss)
2811 tcc_error("redefinition of enumerator '%s'",
2812 get_tok_str(v, NULL));
2813 next();
2814 if (tok == '=') {
2815 next();
2816 c = expr_const();
2818 /* enum symbols have static storage */
2819 ss = sym_push(v, &int_type, VT_CONST, c);
2820 ss->type.t |= VT_STATIC;
2821 if (tok != ',')
2822 break;
2823 next();
2824 c++;
2825 /* NOTE: we accept a trailing comma */
2826 if (tok == '}')
2827 break;
2829 s->c = type_size(&int_type, &align);
2830 skip('}');
2831 } else {
2832 maxalign = 1;
2833 ps = &s->next;
2834 prevbt = VT_INT;
2835 bit_pos = 0;
2836 offset = 0;
2837 flexible = 0;
2838 while (tok != '}') {
2839 parse_btype(&btype, &ad);
2840 while (1) {
2841 if (flexible)
2842 tcc_error("flexible array member '%s' not at the end of struct",
2843 get_tok_str(v, NULL));
2844 bit_size = -1;
2845 v = 0;
2846 type1 = btype;
2847 if (tok != ':') {
2848 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2849 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2850 expect("identifier");
2851 if (type_size(&type1, &align) < 0) {
2852 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
2853 flexible = 1;
2854 else
2855 tcc_error("field '%s' has incomplete type",
2856 get_tok_str(v, NULL));
2858 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2859 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2860 tcc_error("invalid type for '%s'",
2861 get_tok_str(v, NULL));
2863 if (tok == ':') {
2864 next();
2865 bit_size = expr_const();
2866 /* XXX: handle v = 0 case for messages */
2867 if (bit_size < 0)
2868 tcc_error("negative width in bit-field '%s'",
2869 get_tok_str(v, NULL));
2870 if (v && bit_size == 0)
2871 tcc_error("zero width for bit-field '%s'",
2872 get_tok_str(v, NULL));
2874 size = type_size(&type1, &align);
2875 if (ad.aligned) {
2876 if (align < ad.aligned)
2877 align = ad.aligned;
2878 } else if (ad.packed) {
2879 align = 1;
2880 } else if (*tcc_state->pack_stack_ptr) {
2881 if (align > *tcc_state->pack_stack_ptr)
2882 align = *tcc_state->pack_stack_ptr;
2884 lbit_pos = 0;
2885 if (bit_size >= 0) {
2886 bt = type1.t & VT_BTYPE;
2887 if (bt != VT_INT &&
2888 bt != VT_BYTE &&
2889 bt != VT_SHORT &&
2890 bt != VT_BOOL &&
2891 bt != VT_ENUM &&
2892 bt != VT_LLONG)
2893 tcc_error("bitfields must have scalar type");
2894 bsize = size * 8;
2895 if (bit_size > bsize) {
2896 tcc_error("width of '%s' exceeds its type",
2897 get_tok_str(v, NULL));
2898 } else if (bit_size == bsize) {
2899 /* no need for bit fields */
2900 bit_pos = 0;
2901 } else if (bit_size == 0) {
2902 /* XXX: what to do if only padding in a
2903 structure ? */
2904 /* zero size: means to pad */
2905 bit_pos = 0;
2906 } else {
2907 /* we do not have enough room ?
2908 did the type change?
2909 is it a union? */
2910 if ((bit_pos + bit_size) > bsize ||
2911 bt != prevbt || a == TOK_UNION)
2912 bit_pos = 0;
2913 lbit_pos = bit_pos;
2914 /* XXX: handle LSB first */
2915 type1.t |= VT_BITFIELD |
2916 (bit_pos << VT_STRUCT_SHIFT) |
2917 (bit_size << (VT_STRUCT_SHIFT + 6));
2918 bit_pos += bit_size;
2920 prevbt = bt;
2921 } else {
2922 bit_pos = 0;
2924 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2925 /* add new memory data only if starting
2926 bit field */
2927 if (lbit_pos == 0) {
2928 if (a == TOK_STRUCT) {
2929 c = (c + align - 1) & -align;
2930 offset = c;
2931 if (size > 0)
2932 c += size;
2933 } else {
2934 offset = 0;
2935 if (size > c)
2936 c = size;
2938 if (align > maxalign)
2939 maxalign = align;
2941 #if 0
2942 printf("add field %s offset=%d",
2943 get_tok_str(v, NULL), offset);
2944 if (type1.t & VT_BITFIELD) {
2945 printf(" pos=%d size=%d",
2946 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2947 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2949 printf("\n");
2950 #endif
2952 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2953 ass = type1.ref;
2954 while ((ass = ass->next) != NULL) {
2955 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2956 *ps = ss;
2957 ps = &ss->next;
2959 } else if (v) {
2960 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2961 *ps = ss;
2962 ps = &ss->next;
2964 if (tok == ';' || tok == TOK_EOF)
2965 break;
2966 skip(',');
2968 skip(';');
2970 skip('}');
2971 /* store size and alignment */
2972 s->c = (c + maxalign - 1) & -maxalign;
2973 s->r = maxalign;
2978 /* return 0 if no type declaration. otherwise, return the basic type
2979 and skip it.
2981 static int parse_btype(CType *type, AttributeDef *ad)
2983 int t, u, type_found, typespec_found, typedef_found;
2984 Sym *s;
2985 CType type1;
2987 memset(ad, 0, sizeof(AttributeDef));
2988 type_found = 0;
2989 typespec_found = 0;
2990 typedef_found = 0;
2991 t = 0;
2992 while(1) {
2993 switch(tok) {
2994 case TOK_EXTENSION:
2995 /* currently, we really ignore extension */
2996 next();
2997 continue;
2999 /* basic types */
3000 case TOK_CHAR:
3001 u = VT_BYTE;
3002 basic_type:
3003 next();
3004 basic_type1:
3005 if ((t & VT_BTYPE) != 0)
3006 tcc_error("too many basic types");
3007 t |= u;
3008 typespec_found = 1;
3009 break;
3010 case TOK_VOID:
3011 u = VT_VOID;
3012 goto basic_type;
3013 case TOK_SHORT:
3014 u = VT_SHORT;
3015 goto basic_type;
3016 case TOK_INT:
3017 next();
3018 typespec_found = 1;
3019 break;
3020 case TOK_LONG:
3021 next();
3022 if ((t & VT_BTYPE) == VT_DOUBLE) {
3023 #ifndef TCC_TARGET_PE
3024 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3025 #endif
3026 } else if ((t & VT_BTYPE) == VT_LONG) {
3027 t = (t & ~VT_BTYPE) | VT_LLONG;
3028 } else {
3029 u = VT_LONG;
3030 goto basic_type1;
3032 break;
3033 case TOK_BOOL:
3034 u = VT_BOOL;
3035 goto basic_type;
3036 case TOK_FLOAT:
3037 u = VT_FLOAT;
3038 goto basic_type;
3039 case TOK_DOUBLE:
3040 next();
3041 if ((t & VT_BTYPE) == VT_LONG) {
3042 #ifdef TCC_TARGET_PE
3043 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3044 #else
3045 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3046 #endif
3047 } else {
3048 u = VT_DOUBLE;
3049 goto basic_type1;
3051 break;
3052 case TOK_ENUM:
3053 struct_decl(&type1, VT_ENUM, t & VT_TYPEDEF);
3054 basic_type2:
3055 u = type1.t;
3056 type->ref = type1.ref;
3057 goto basic_type1;
3058 case TOK_STRUCT:
3059 case TOK_UNION:
3060 struct_decl(&type1, VT_STRUCT, t & VT_TYPEDEF);
3061 goto basic_type2;
3063 /* type modifiers */
3064 case TOK_CONST1:
3065 case TOK_CONST2:
3066 case TOK_CONST3:
3067 t |= VT_CONSTANT;
3068 next();
3069 break;
3070 case TOK_VOLATILE1:
3071 case TOK_VOLATILE2:
3072 case TOK_VOLATILE3:
3073 t |= VT_VOLATILE;
3074 next();
3075 break;
3076 case TOK_SIGNED1:
3077 case TOK_SIGNED2:
3078 case TOK_SIGNED3:
3079 typespec_found = 1;
3080 t |= VT_SIGNED;
3081 next();
3082 break;
3083 case TOK_REGISTER:
3084 case TOK_AUTO:
3085 case TOK_RESTRICT1:
3086 case TOK_RESTRICT2:
3087 case TOK_RESTRICT3:
3088 next();
3089 break;
3090 case TOK_UNSIGNED:
3091 t |= VT_UNSIGNED;
3092 next();
3093 typespec_found = 1;
3094 break;
3096 /* storage */
3097 case TOK_EXTERN:
3098 t |= VT_EXTERN;
3099 next();
3100 break;
3101 case TOK_STATIC:
3102 t |= VT_STATIC;
3103 next();
3104 break;
3105 case TOK_TYPEDEF:
3106 t |= VT_TYPEDEF;
3107 next();
3108 break;
3109 case TOK_INLINE1:
3110 case TOK_INLINE2:
3111 case TOK_INLINE3:
3112 t |= VT_INLINE;
3113 next();
3114 break;
3116 /* GNUC attribute */
3117 case TOK_ATTRIBUTE1:
3118 case TOK_ATTRIBUTE2:
3119 parse_attribute(ad);
3120 if (ad->mode) {
3121 u = ad->mode -1;
3122 t = (t & ~VT_BTYPE) | u;
3124 break;
3125 /* GNUC typeof */
3126 case TOK_TYPEOF1:
3127 case TOK_TYPEOF2:
3128 case TOK_TYPEOF3:
3129 next();
3130 parse_expr_type(&type1);
3131 /* remove all storage modifiers except typedef */
3132 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3133 goto basic_type2;
3134 default:
3135 if (typespec_found || typedef_found)
3136 goto the_end;
3137 s = sym_find(tok);
3138 if (!s || !(s->type.t & VT_TYPEDEF))
3139 goto the_end;
3140 typedef_found = 1;
3141 t |= (s->type.t & ~VT_TYPEDEF);
3142 type->ref = s->type.ref;
3143 if (s->r) {
3144 /* get attributes from typedef */
3145 if (0 == ad->aligned)
3146 ad->aligned = FUNC_ALIGN(s->r);
3147 if (0 == ad->func_call)
3148 ad->func_call = FUNC_CALL(s->r);
3149 ad->packed |= FUNC_PACKED(s->r);
3151 next();
3152 typespec_found = 1;
3153 break;
3155 type_found = 1;
3157 the_end:
3158 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3159 tcc_error("signed and unsigned modifier");
3160 if (tcc_state->char_is_unsigned) {
3161 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3162 t |= VT_UNSIGNED;
3164 t &= ~VT_SIGNED;
3166 /* long is never used as type */
3167 if ((t & VT_BTYPE) == VT_LONG)
3168 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3169 t = (t & ~VT_BTYPE) | VT_INT;
3170 #else
3171 t = (t & ~VT_BTYPE) | VT_LLONG;
3172 #endif
3173 type->t = t;
3174 return type_found;
3177 /* convert a function parameter type (array to pointer and function to
3178 function pointer) */
3179 static inline void convert_parameter_type(CType *pt)
3181 /* remove const and volatile qualifiers (XXX: const could be used
3182 to indicate a const function parameter */
3183 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3184 /* array must be transformed to pointer according to ANSI C */
3185 pt->t &= ~VT_ARRAY;
3186 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3187 mk_pointer(pt);
3191 ST_FUNC void parse_asm_str(CString *astr)
3193 skip('(');
3194 /* read the string */
3195 if (tok != TOK_STR)
3196 expect("string constant");
3197 cstr_new(astr);
3198 while (tok == TOK_STR) {
3199 /* XXX: add \0 handling too ? */
3200 cstr_cat(astr, tokc.cstr->data);
3201 next();
3203 cstr_ccat(astr, '\0');
3206 /* Parse an asm label and return the label
3207 * Don't forget to free the CString in the caller! */
3208 static void asm_label_instr(CString *astr)
3210 next();
3211 parse_asm_str(astr);
3212 skip(')');
3213 #ifdef ASM_DEBUG
3214 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3215 #endif
3218 static void post_type(CType *type, AttributeDef *ad)
3220 int n, l, t1, arg_size, align;
3221 Sym **plast, *s, *first;
3222 AttributeDef ad1;
3223 CType pt;
3225 if (tok == '(') {
3226 /* function declaration */
3227 next();
3228 l = 0;
3229 first = NULL;
3230 plast = &first;
3231 arg_size = 0;
3232 if (tok != ')') {
3233 for(;;) {
3234 /* read param name and compute offset */
3235 if (l != FUNC_OLD) {
3236 if (!parse_btype(&pt, &ad1)) {
3237 if (l) {
3238 tcc_error("invalid type");
3239 } else {
3240 l = FUNC_OLD;
3241 goto old_proto;
3244 l = FUNC_NEW;
3245 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3246 break;
3247 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3248 if ((pt.t & VT_BTYPE) == VT_VOID)
3249 tcc_error("parameter declared as void");
3250 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3251 } else {
3252 old_proto:
3253 n = tok;
3254 if (n < TOK_UIDENT)
3255 expect("identifier");
3256 pt.t = VT_INT;
3257 next();
3259 convert_parameter_type(&pt);
3260 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3261 *plast = s;
3262 plast = &s->next;
3263 if (tok == ')')
3264 break;
3265 skip(',');
3266 if (l == FUNC_NEW && tok == TOK_DOTS) {
3267 l = FUNC_ELLIPSIS;
3268 next();
3269 break;
3273 /* if no parameters, then old type prototype */
3274 if (l == 0)
3275 l = FUNC_OLD;
3276 skip(')');
3277 /* NOTE: const is ignored in returned type as it has a special
3278 meaning in gcc / C++ */
3279 type->t &= ~VT_CONSTANT;
3280 /* some ancient pre-K&R C allows a function to return an array
3281 and the array brackets to be put after the arguments, such
3282 that "int c()[]" means something like "int[] c()" */
3283 if (tok == '[') {
3284 next();
3285 skip(']'); /* only handle simple "[]" */
3286 type->t |= VT_PTR;
3288 /* we push a anonymous symbol which will contain the function prototype */
3289 ad->func_args = arg_size;
3290 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3291 s->next = first;
3292 type->t = VT_FUNC;
3293 type->ref = s;
3294 } else if (tok == '[') {
3295 /* array definition */
3296 next();
3297 if (tok == TOK_RESTRICT1)
3298 next();
3299 n = -1;
3300 t1 = 0;
3301 if (tok != ']') {
3302 if (!local_stack || nocode_wanted)
3303 vpushi(expr_const());
3304 else gexpr();
3305 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3306 n = vtop->c.i;
3307 if (n < 0)
3308 tcc_error("invalid array size");
3309 } else {
3310 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3311 tcc_error("size of variable length array should be an integer");
3312 t1 = VT_VLA;
3315 skip(']');
3316 /* parse next post type */
3317 post_type(type, ad);
3318 if (type->t == VT_FUNC)
3319 tcc_error("declaration of an array of functions");
3320 t1 |= type->t & VT_VLA;
3322 if (t1 & VT_VLA) {
3323 loc -= type_size(&int_type, &align);
3324 loc &= -align;
3325 n = loc;
3327 vla_runtime_type_size(type, &align);
3328 gen_op('*');
3329 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3330 vswap();
3331 vstore();
3333 if (n != -1)
3334 vpop();
3336 /* we push an anonymous symbol which will contain the array
3337 element type */
3338 s = sym_push(SYM_FIELD, type, 0, n);
3339 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3340 type->ref = s;
3344 /* Parse a type declaration (except basic type), and return the type
3345 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3346 expected. 'type' should contain the basic type. 'ad' is the
3347 attribute definition of the basic type. It can be modified by
3348 type_decl().
3350 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3352 Sym *s;
3353 CType type1, *type2;
3354 int qualifiers, storage;
3356 while (tok == '*') {
3357 qualifiers = 0;
3358 redo:
3359 next();
3360 switch(tok) {
3361 case TOK_CONST1:
3362 case TOK_CONST2:
3363 case TOK_CONST3:
3364 qualifiers |= VT_CONSTANT;
3365 goto redo;
3366 case TOK_VOLATILE1:
3367 case TOK_VOLATILE2:
3368 case TOK_VOLATILE3:
3369 qualifiers |= VT_VOLATILE;
3370 goto redo;
3371 case TOK_RESTRICT1:
3372 case TOK_RESTRICT2:
3373 case TOK_RESTRICT3:
3374 goto redo;
3376 mk_pointer(type);
3377 type->t |= qualifiers;
3380 /* XXX: clarify attribute handling */
3381 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3382 parse_attribute(ad);
3384 /* recursive type */
3385 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3386 type1.t = 0; /* XXX: same as int */
3387 if (tok == '(') {
3388 next();
3389 /* XXX: this is not correct to modify 'ad' at this point, but
3390 the syntax is not clear */
3391 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3392 parse_attribute(ad);
3393 type_decl(&type1, ad, v, td);
3394 skip(')');
3395 } else {
3396 /* type identifier */
3397 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3398 *v = tok;
3399 next();
3400 } else {
3401 if (!(td & TYPE_ABSTRACT))
3402 expect("identifier");
3403 *v = 0;
3406 storage = type->t & VT_STORAGE;
3407 type->t &= ~VT_STORAGE;
3408 if (storage & VT_STATIC) {
3409 int saved_nocode_wanted = nocode_wanted;
3410 nocode_wanted = 1;
3411 post_type(type, ad);
3412 nocode_wanted = saved_nocode_wanted;
3413 } else
3414 post_type(type, ad);
3415 type->t |= storage;
3416 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3417 parse_attribute(ad);
3419 if (!type1.t)
3420 return;
3421 /* append type at the end of type1 */
3422 type2 = &type1;
3423 for(;;) {
3424 s = type2->ref;
3425 type2 = &s->type;
3426 if (!type2->t) {
3427 *type2 = *type;
3428 break;
3431 *type = type1;
3434 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3435 ST_FUNC int lvalue_type(int t)
3437 int bt, r;
3438 r = VT_LVAL;
3439 bt = t & VT_BTYPE;
3440 if (bt == VT_BYTE || bt == VT_BOOL)
3441 r |= VT_LVAL_BYTE;
3442 else if (bt == VT_SHORT)
3443 r |= VT_LVAL_SHORT;
3444 else
3445 return r;
3446 if (t & VT_UNSIGNED)
3447 r |= VT_LVAL_UNSIGNED;
3448 return r;
3451 /* indirection with full error checking and bound check */
3452 ST_FUNC void indir(void)
3454 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3455 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3456 return;
3457 expect("pointer");
3459 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3460 gv(RC_INT);
3461 vtop->type = *pointed_type(&vtop->type);
3462 /* Arrays and functions are never lvalues */
3463 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3464 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3465 vtop->r |= lvalue_type(vtop->type.t);
3466 /* if bound checking, the referenced pointer must be checked */
3467 #ifdef CONFIG_TCC_BCHECK
3468 if (tcc_state->do_bounds_check)
3469 vtop->r |= VT_MUSTBOUND;
3470 #endif
3474 /* pass a parameter to a function and do type checking and casting */
3475 static void gfunc_param_typed(Sym *func, Sym *arg)
3477 int func_type;
3478 CType type;
3480 func_type = func->c;
3481 if (func_type == FUNC_OLD ||
3482 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3483 /* default casting : only need to convert float to double */
3484 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3485 type.t = VT_DOUBLE;
3486 gen_cast(&type);
3488 } else if (arg == NULL) {
3489 tcc_error("too many arguments to function");
3490 } else {
3491 type = arg->type;
3492 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3493 gen_assign_cast(&type);
3497 /* parse an expression of the form '(type)' or '(expr)' and return its
3498 type */
3499 static void parse_expr_type(CType *type)
3501 int n;
3502 AttributeDef ad;
3504 skip('(');
3505 if (parse_btype(type, &ad)) {
3506 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3507 } else {
3508 expr_type(type);
3510 skip(')');
3513 static void parse_type(CType *type)
3515 AttributeDef ad;
3516 int n;
3518 if (!parse_btype(type, &ad)) {
3519 expect("type");
3521 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3524 static void vpush_tokc(int t)
3526 CType type;
3527 type.t = t;
3528 type.ref = 0;
3529 vsetc(&type, VT_CONST, &tokc);
3532 ST_FUNC void unary(void)
3534 int n, t, align, size, r, sizeof_caller;
3535 CType type;
3536 Sym *s;
3537 AttributeDef ad;
3538 static int in_sizeof = 0;
3540 sizeof_caller = in_sizeof;
3541 in_sizeof = 0;
3542 /* XXX: GCC 2.95.3 does not generate a table although it should be
3543 better here */
3544 tok_next:
3545 switch(tok) {
3546 case TOK_EXTENSION:
3547 next();
3548 goto tok_next;
3549 case TOK_CINT:
3550 case TOK_CCHAR:
3551 case TOK_LCHAR:
3552 vpushi(tokc.i);
3553 next();
3554 break;
3555 case TOK_CUINT:
3556 vpush_tokc(VT_INT | VT_UNSIGNED);
3557 next();
3558 break;
3559 case TOK_CLLONG:
3560 vpush_tokc(VT_LLONG);
3561 next();
3562 break;
3563 case TOK_CULLONG:
3564 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3565 next();
3566 break;
3567 case TOK_CFLOAT:
3568 vpush_tokc(VT_FLOAT);
3569 next();
3570 break;
3571 case TOK_CDOUBLE:
3572 vpush_tokc(VT_DOUBLE);
3573 next();
3574 break;
3575 case TOK_CLDOUBLE:
3576 vpush_tokc(VT_LDOUBLE);
3577 next();
3578 break;
3579 case TOK___FUNCTION__:
3580 if (!gnu_ext)
3581 goto tok_identifier;
3582 /* fall thru */
3583 case TOK___FUNC__:
3585 void *ptr;
3586 int len;
3587 /* special function name identifier */
3588 len = strlen(funcname) + 1;
3589 /* generate char[len] type */
3590 type.t = VT_BYTE;
3591 mk_pointer(&type);
3592 type.t |= VT_ARRAY;
3593 type.ref->c = len;
3594 vpush_ref(&type, data_section, data_section->data_offset, len);
3595 ptr = section_ptr_add(data_section, len);
3596 memcpy(ptr, funcname, len);
3597 next();
3599 break;
3600 case TOK_LSTR:
3601 #ifdef TCC_TARGET_PE
3602 t = VT_SHORT | VT_UNSIGNED;
3603 #else
3604 t = VT_INT;
3605 #endif
3606 goto str_init;
3607 case TOK_STR:
3608 /* string parsing */
3609 t = VT_BYTE;
3610 str_init:
3611 if (tcc_state->warn_write_strings)
3612 t |= VT_CONSTANT;
3613 type.t = t;
3614 mk_pointer(&type);
3615 type.t |= VT_ARRAY;
3616 memset(&ad, 0, sizeof(AttributeDef));
3617 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3618 break;
3619 case '(':
3620 next();
3621 /* cast ? */
3622 if (parse_btype(&type, &ad)) {
3623 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3624 skip(')');
3625 /* check ISOC99 compound literal */
3626 if (tok == '{') {
3627 /* data is allocated locally by default */
3628 if (global_expr)
3629 r = VT_CONST;
3630 else
3631 r = VT_LOCAL;
3632 /* all except arrays are lvalues */
3633 if (!(type.t & VT_ARRAY))
3634 r |= lvalue_type(type.t);
3635 memset(&ad, 0, sizeof(AttributeDef));
3636 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3637 } else {
3638 if (sizeof_caller) {
3639 vpush(&type);
3640 return;
3642 unary();
3643 gen_cast(&type);
3645 } else if (tok == '{') {
3646 /* save all registers */
3647 save_regs(0);
3648 /* statement expression : we do not accept break/continue
3649 inside as GCC does */
3650 block(NULL, NULL, NULL, NULL, 0, 1);
3651 skip(')');
3652 } else {
3653 gexpr();
3654 skip(')');
3656 break;
3657 case '*':
3658 next();
3659 unary();
3660 indir();
3661 break;
3662 case '&':
3663 next();
3664 unary();
3665 /* functions names must be treated as function pointers,
3666 except for unary '&' and sizeof. Since we consider that
3667 functions are not lvalues, we only have to handle it
3668 there and in function calls. */
3669 /* arrays can also be used although they are not lvalues */
3670 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3671 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3672 test_lvalue();
3673 mk_pointer(&vtop->type);
3674 gaddrof();
3675 break;
3676 case '!':
3677 next();
3678 unary();
3679 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3680 CType boolean;
3681 boolean.t = VT_BOOL;
3682 gen_cast(&boolean);
3683 vtop->c.i = !vtop->c.i;
3684 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3685 vtop->c.i = vtop->c.i ^ 1;
3686 else {
3687 save_regs(1);
3688 vseti(VT_JMP, gvtst(1, 0));
3690 break;
3691 case '~':
3692 next();
3693 unary();
3694 vpushi(-1);
3695 gen_op('^');
3696 break;
3697 case '+':
3698 next();
3699 /* in order to force cast, we add zero */
3700 unary();
3701 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3702 tcc_error("pointer not accepted for unary plus");
3703 vpushi(0);
3704 gen_op('+');
3705 break;
3706 case TOK_SIZEOF:
3707 case TOK_ALIGNOF1:
3708 case TOK_ALIGNOF2:
3709 t = tok;
3710 next();
3711 in_sizeof++;
3712 unary_type(&type); // Perform a in_sizeof = 0;
3713 size = type_size(&type, &align);
3714 if (t == TOK_SIZEOF) {
3715 if (!(type.t & VT_VLA)) {
3716 if (size < 0)
3717 tcc_error("sizeof applied to an incomplete type");
3718 vpushs(size);
3719 } else {
3720 vla_runtime_type_size(&type, &align);
3722 } else {
3723 vpushs(align);
3725 vtop->type.t |= VT_UNSIGNED;
3726 break;
3728 case TOK_builtin_types_compatible_p:
3730 CType type1, type2;
3731 next();
3732 skip('(');
3733 parse_type(&type1);
3734 skip(',');
3735 parse_type(&type2);
3736 skip(')');
3737 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3738 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3739 vpushi(is_compatible_types(&type1, &type2));
3741 break;
3742 case TOK_builtin_constant_p:
3744 int saved_nocode_wanted, res;
3745 next();
3746 skip('(');
3747 saved_nocode_wanted = nocode_wanted;
3748 nocode_wanted = 1;
3749 gexpr();
3750 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3751 vpop();
3752 nocode_wanted = saved_nocode_wanted;
3753 skip(')');
3754 vpushi(res);
3756 break;
3757 case TOK_builtin_frame_address:
3759 int level;
3760 CType type;
3761 next();
3762 skip('(');
3763 if (tok != TOK_CINT || tokc.i < 0) {
3764 tcc_error("__builtin_frame_address only takes positive integers");
3766 level = tokc.i;
3767 next();
3768 skip(')');
3769 type.t = VT_VOID;
3770 mk_pointer(&type);
3771 vset(&type, VT_LOCAL, 0); /* local frame */
3772 while (level--) {
3773 mk_pointer(&vtop->type);
3774 indir(); /* -> parent frame */
3777 break;
3778 #ifdef TCC_TARGET_X86_64
3779 #ifdef TCC_TARGET_PE
3780 case TOK_builtin_va_start:
3782 next();
3783 skip('(');
3784 expr_eq();
3785 skip(',');
3786 expr_eq();
3787 skip(')');
3788 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
3789 tcc_error("__builtin_va_start expects a local variable");
3790 vtop->r &= ~(VT_LVAL | VT_REF);
3791 vtop->type = char_pointer_type;
3792 vstore();
3794 break;
3795 #else
3796 case TOK_builtin_va_arg_types:
3798 CType type;
3799 next();
3800 skip('(');
3801 parse_type(&type);
3802 skip(')');
3803 vpushi(classify_x86_64_va_arg(&type));
3805 break;
3806 #endif
3807 #endif
3808 case TOK_INC:
3809 case TOK_DEC:
3810 t = tok;
3811 next();
3812 unary();
3813 inc(0, t);
3814 break;
3815 case '-':
3816 next();
3817 unary();
3818 t = vtop->type.t & VT_BTYPE;
3819 /* handle (-)0.0 */
3820 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST &&
3821 is_float(t)) {
3822 if (t == VT_FLOAT)
3823 vtop->c.f = -vtop->c.f;
3824 else if (t == VT_DOUBLE)
3825 vtop->c.d = -vtop->c.d;
3826 else
3827 vtop->c.ld = -vtop->c.ld;
3828 } else {
3829 vpushi(0);
3830 vswap();
3831 gen_op('-');
3833 break;
3834 case TOK_LAND:
3835 if (!gnu_ext)
3836 goto tok_identifier;
3837 next();
3838 /* allow to take the address of a label */
3839 if (tok < TOK_UIDENT)
3840 expect("label identifier");
3841 s = label_find(tok);
3842 if (!s) {
3843 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3844 } else {
3845 if (s->r == LABEL_DECLARED)
3846 s->r = LABEL_FORWARD;
3848 if (!s->type.t) {
3849 s->type.t = VT_VOID;
3850 mk_pointer(&s->type);
3851 s->type.t |= VT_STATIC;
3853 vset(&s->type, VT_CONST | VT_SYM, 0);
3854 vtop->sym = s;
3855 next();
3856 break;
3858 // special qnan , snan and infinity values
3859 case TOK___NAN__:
3860 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3861 next();
3862 break;
3863 case TOK___SNAN__:
3864 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3865 next();
3866 break;
3867 case TOK___INF__:
3868 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3869 next();
3870 break;
3872 default:
3873 tok_identifier:
3874 t = tok;
3875 next();
3876 if (t < TOK_UIDENT)
3877 expect("identifier");
3878 s = sym_find(t);
3879 if (!s) {
3880 if (tok != '(')
3881 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
3882 /* for simple function calls, we tolerate undeclared
3883 external reference to int() function */
3884 if (tcc_state->warn_implicit_function_declaration)
3885 tcc_warning("implicit declaration of function '%s'",
3886 get_tok_str(t, NULL));
3887 s = external_global_sym(t, &func_old_type, 0);
3889 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3890 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3891 /* if referencing an inline function, then we generate a
3892 symbol to it if not already done. It will have the
3893 effect to generate code for it at the end of the
3894 compilation unit. Inline function as always
3895 generated in the text section. */
3896 if (!s->c)
3897 put_extern_sym(s, text_section, 0, 0);
3898 r = VT_SYM | VT_CONST;
3899 } else {
3900 r = s->r;
3902 vset(&s->type, r, s->c);
3903 /* if forward reference, we must point to s */
3904 if (vtop->r & VT_SYM) {
3905 vtop->sym = s;
3906 vtop->c.ul = 0;
3908 break;
3911 /* post operations */
3912 while (1) {
3913 if (tok == TOK_INC || tok == TOK_DEC) {
3914 inc(1, tok);
3915 next();
3916 } else if (tok == '.' || tok == TOK_ARROW) {
3917 int qualifiers;
3918 /* field */
3919 if (tok == TOK_ARROW)
3920 indir();
3921 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3922 test_lvalue();
3923 gaddrof();
3924 next();
3925 /* expect pointer on structure */
3926 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3927 expect("struct or union");
3928 s = vtop->type.ref;
3929 /* find field */
3930 tok |= SYM_FIELD;
3931 while ((s = s->next) != NULL) {
3932 if (s->v == tok)
3933 break;
3935 if (!s)
3936 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3937 /* add field offset to pointer */
3938 vtop->type = char_pointer_type; /* change type to 'char *' */
3939 vpushi(s->c);
3940 gen_op('+');
3941 /* change type to field type, and set to lvalue */
3942 vtop->type = s->type;
3943 vtop->type.t |= qualifiers;
3944 /* an array is never an lvalue */
3945 if (!(vtop->type.t & VT_ARRAY)) {
3946 vtop->r |= lvalue_type(vtop->type.t);
3947 #ifdef CONFIG_TCC_BCHECK
3948 /* if bound checking, the referenced pointer must be checked */
3949 if (tcc_state->do_bounds_check)
3950 vtop->r |= VT_MUSTBOUND;
3951 #endif
3953 next();
3954 } else if (tok == '[') {
3955 next();
3956 gexpr();
3957 gen_op('+');
3958 indir();
3959 skip(']');
3960 } else if (tok == '(') {
3961 SValue ret;
3962 Sym *sa;
3963 int nb_args, ret_nregs, ret_align;
3965 /* function call */
3966 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3967 /* pointer test (no array accepted) */
3968 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3969 vtop->type = *pointed_type(&vtop->type);
3970 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3971 goto error_func;
3972 } else {
3973 error_func:
3974 expect("function pointer");
3976 } else {
3977 vtop->r &= ~VT_LVAL; /* no lvalue */
3979 /* get return type */
3980 s = vtop->type.ref;
3981 next();
3982 sa = s->next; /* first parameter */
3983 nb_args = 0;
3984 ret.r2 = VT_CONST;
3985 /* compute first implicit argument if a structure is returned */
3986 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3987 ret_nregs = gfunc_sret(&s->type, &ret.type, &ret_align);
3988 if (!ret_nregs) {
3989 /* get some space for the returned structure */
3990 size = type_size(&s->type, &align);
3991 loc = (loc - size) & -align;
3992 ret.type = s->type;
3993 ret.r = VT_LOCAL | VT_LVAL;
3994 /* pass it as 'int' to avoid structure arg passing
3995 problems */
3996 vseti(VT_LOCAL, loc);
3997 ret.c = vtop->c;
3998 nb_args++;
4000 } else {
4001 ret_nregs = 1;
4002 ret.type = s->type;
4005 if (ret_nregs) {
4006 /* return in register */
4007 if (is_float(ret.type.t)) {
4008 ret.r = reg_fret(ret.type.t);
4009 #ifdef TCC_TARGET_X86_64
4010 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4011 ret.r2 = REG_QRET;
4012 #endif
4013 } else {
4014 #ifdef TCC_TARGET_X86_64
4015 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4016 #else
4017 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4018 #endif
4019 ret.r2 = REG_LRET;
4020 ret.r = REG_IRET;
4022 ret.c.i = 0;
4024 if (tok != ')') {
4025 for(;;) {
4026 expr_eq();
4027 gfunc_param_typed(s, sa);
4028 nb_args++;
4029 if (sa)
4030 sa = sa->next;
4031 if (tok == ')')
4032 break;
4033 skip(',');
4036 if (sa)
4037 tcc_error("too few arguments to function");
4038 skip(')');
4039 if (!nocode_wanted) {
4040 gfunc_call(nb_args);
4041 } else {
4042 vtop -= (nb_args + 1);
4045 /* return value */
4046 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4047 vsetc(&ret.type, r, &ret.c);
4048 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4051 /* handle packed struct return */
4052 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4053 int addr, offset;
4055 size = type_size(&s->type, &align);
4056 loc = (loc - size) & -align;
4057 addr = loc;
4058 offset = 0;
4059 for (;;) {
4060 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4061 vswap();
4062 vstore();
4063 vtop--;
4064 if (--ret_nregs == 0)
4065 break;
4066 /* XXX: compatible with arm only: ret_align == register_size */
4067 offset += ret_align;
4069 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4071 } else {
4072 break;
4077 ST_FUNC void expr_prod(void)
4079 int t;
4081 unary();
4082 while (tok == '*' || tok == '/' || tok == '%') {
4083 t = tok;
4084 next();
4085 unary();
4086 gen_op(t);
4090 ST_FUNC void expr_sum(void)
4092 int t;
4094 expr_prod();
4095 while (tok == '+' || tok == '-') {
4096 t = tok;
4097 next();
4098 expr_prod();
4099 gen_op(t);
4103 static void expr_shift(void)
4105 int t;
4107 expr_sum();
4108 while (tok == TOK_SHL || tok == TOK_SAR) {
4109 t = tok;
4110 next();
4111 expr_sum();
4112 gen_op(t);
4116 static void expr_cmp(void)
4118 int t;
4120 expr_shift();
4121 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4122 tok == TOK_ULT || tok == TOK_UGE) {
4123 t = tok;
4124 next();
4125 expr_shift();
4126 gen_op(t);
4130 static void expr_cmpeq(void)
4132 int t;
4134 expr_cmp();
4135 while (tok == TOK_EQ || tok == TOK_NE) {
4136 t = tok;
4137 next();
4138 expr_cmp();
4139 gen_op(t);
4143 static void expr_and(void)
4145 expr_cmpeq();
4146 while (tok == '&') {
4147 next();
4148 expr_cmpeq();
4149 gen_op('&');
4153 static void expr_xor(void)
4155 expr_and();
4156 while (tok == '^') {
4157 next();
4158 expr_and();
4159 gen_op('^');
4163 static void expr_or(void)
4165 expr_xor();
4166 while (tok == '|') {
4167 next();
4168 expr_xor();
4169 gen_op('|');
4173 /* XXX: fix this mess */
4174 static void expr_land_const(void)
4176 expr_or();
4177 while (tok == TOK_LAND) {
4178 next();
4179 expr_or();
4180 gen_op(TOK_LAND);
4184 /* XXX: fix this mess */
4185 static void expr_lor_const(void)
4187 expr_land_const();
4188 while (tok == TOK_LOR) {
4189 next();
4190 expr_land_const();
4191 gen_op(TOK_LOR);
4195 /* only used if non constant */
4196 static void expr_land(void)
4198 int t;
4200 expr_or();
4201 if (tok == TOK_LAND) {
4202 t = 0;
4203 save_regs(1);
4204 for(;;) {
4205 t = gvtst(1, t);
4206 if (tok != TOK_LAND) {
4207 vseti(VT_JMPI, t);
4208 break;
4210 next();
4211 expr_or();
4216 static void expr_lor(void)
4218 int t;
4220 expr_land();
4221 if (tok == TOK_LOR) {
4222 t = 0;
4223 save_regs(1);
4224 for(;;) {
4225 t = gvtst(0, t);
4226 if (tok != TOK_LOR) {
4227 vseti(VT_JMP, t);
4228 break;
4230 next();
4231 expr_land();
4236 /* XXX: better constant handling */
4237 static void expr_cond(void)
4239 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4240 SValue sv;
4241 CType type, type1, type2;
4243 if (const_wanted) {
4244 expr_lor_const();
4245 if (tok == '?') {
4246 CType boolean;
4247 int c;
4248 boolean.t = VT_BOOL;
4249 vdup();
4250 gen_cast(&boolean);
4251 c = vtop->c.i;
4252 vpop();
4253 next();
4254 if (tok != ':' || !gnu_ext) {
4255 vpop();
4256 gexpr();
4258 if (!c)
4259 vpop();
4260 skip(':');
4261 expr_cond();
4262 if (c)
4263 vpop();
4265 } else {
4266 expr_lor();
4267 if (tok == '?') {
4268 next();
4269 if (vtop != vstack) {
4270 /* needed to avoid having different registers saved in
4271 each branch */
4272 if (is_float(vtop->type.t)) {
4273 rc = RC_FLOAT;
4274 #ifdef TCC_TARGET_X86_64
4275 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4276 rc = RC_ST0;
4278 #endif
4280 else
4281 rc = RC_INT;
4282 gv(rc);
4283 save_regs(1);
4285 if (tok == ':' && gnu_ext) {
4286 gv_dup();
4287 tt = gvtst(1, 0);
4288 } else {
4289 tt = gvtst(1, 0);
4290 gexpr();
4292 type1 = vtop->type;
4293 sv = *vtop; /* save value to handle it later */
4294 vtop--; /* no vpop so that FP stack is not flushed */
4295 skip(':');
4296 u = gjmp(0);
4297 gsym(tt);
4298 expr_cond();
4299 type2 = vtop->type;
4301 t1 = type1.t;
4302 bt1 = t1 & VT_BTYPE;
4303 t2 = type2.t;
4304 bt2 = t2 & VT_BTYPE;
4305 /* cast operands to correct type according to ISOC rules */
4306 if (is_float(bt1) || is_float(bt2)) {
4307 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4308 type.t = VT_LDOUBLE;
4309 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4310 type.t = VT_DOUBLE;
4311 } else {
4312 type.t = VT_FLOAT;
4314 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4315 /* cast to biggest op */
4316 type.t = VT_LLONG;
4317 /* convert to unsigned if it does not fit in a long long */
4318 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4319 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4320 type.t |= VT_UNSIGNED;
4321 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4322 /* If one is a null ptr constant the result type
4323 is the other. */
4324 if (is_null_pointer (vtop))
4325 type = type1;
4326 else if (is_null_pointer (&sv))
4327 type = type2;
4328 /* XXX: test pointer compatibility, C99 has more elaborate
4329 rules here. */
4330 else
4331 type = type1;
4332 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4333 /* XXX: test function pointer compatibility */
4334 type = bt1 == VT_FUNC ? type1 : type2;
4335 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4336 /* XXX: test structure compatibility */
4337 type = bt1 == VT_STRUCT ? type1 : type2;
4338 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4339 /* NOTE: as an extension, we accept void on only one side */
4340 type.t = VT_VOID;
4341 } else {
4342 /* integer operations */
4343 type.t = VT_INT;
4344 /* convert to unsigned if it does not fit in an integer */
4345 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4346 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4347 type.t |= VT_UNSIGNED;
4350 /* now we convert second operand */
4351 gen_cast(&type);
4352 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4353 gaddrof();
4354 rc = RC_INT;
4355 if (is_float(type.t)) {
4356 rc = RC_FLOAT;
4357 #ifdef TCC_TARGET_X86_64
4358 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4359 rc = RC_ST0;
4361 #endif
4362 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4363 /* for long longs, we use fixed registers to avoid having
4364 to handle a complicated move */
4365 rc = RC_IRET;
4368 r2 = gv(rc);
4369 /* this is horrible, but we must also convert first
4370 operand */
4371 tt = gjmp(0);
4372 gsym(u);
4373 /* put again first value and cast it */
4374 *vtop = sv;
4375 gen_cast(&type);
4376 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4377 gaddrof();
4378 r1 = gv(rc);
4379 move_reg(r2, r1, type.t);
4380 vtop->r = r2;
4381 gsym(tt);
4386 static void expr_eq(void)
4388 int t;
4390 expr_cond();
4391 if (tok == '=' ||
4392 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4393 tok == TOK_A_XOR || tok == TOK_A_OR ||
4394 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4395 test_lvalue();
4396 t = tok;
4397 next();
4398 if (t == '=') {
4399 expr_eq();
4400 } else {
4401 vdup();
4402 expr_eq();
4403 gen_op(t & 0x7f);
4405 vstore();
4409 ST_FUNC void gexpr(void)
4411 while (1) {
4412 expr_eq();
4413 if (tok != ',')
4414 break;
4415 vpop();
4416 next();
4420 /* parse an expression and return its type without any side effect. */
4421 static void expr_type(CType *type)
4423 int saved_nocode_wanted;
4425 saved_nocode_wanted = nocode_wanted;
4426 nocode_wanted = 1;
4427 gexpr();
4428 *type = vtop->type;
4429 vpop();
4430 nocode_wanted = saved_nocode_wanted;
4433 /* parse a unary expression and return its type without any side
4434 effect. */
4435 static void unary_type(CType *type)
4437 int a;
4439 a = nocode_wanted;
4440 nocode_wanted = 1;
4441 unary();
4442 *type = vtop->type;
4443 vpop();
4444 nocode_wanted = a;
4447 /* parse a constant expression and return value in vtop. */
4448 static void expr_const1(void)
4450 int a;
4451 a = const_wanted;
4452 const_wanted = 1;
4453 expr_cond();
4454 const_wanted = a;
4457 /* parse an integer constant and return its value. */
4458 ST_FUNC int expr_const(void)
4460 int c;
4461 expr_const1();
4462 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4463 expect("constant expression");
4464 c = vtop->c.i;
4465 vpop();
4466 return c;
4469 /* return the label token if current token is a label, otherwise
4470 return zero */
4471 static int is_label(void)
4473 int last_tok;
4475 /* fast test first */
4476 if (tok < TOK_UIDENT)
4477 return 0;
4478 /* no need to save tokc because tok is an identifier */
4479 last_tok = tok;
4480 next();
4481 if (tok == ':') {
4482 next();
4483 return last_tok;
4484 } else {
4485 unget_tok(last_tok);
4486 return 0;
4490 static void label_or_decl(int l)
4492 int last_tok;
4494 /* fast test first */
4495 if (tok >= TOK_UIDENT)
4497 /* no need to save tokc because tok is an identifier */
4498 last_tok = tok;
4499 next();
4500 if (tok == ':') {
4501 unget_tok(last_tok);
4502 return;
4504 unget_tok(last_tok);
4506 decl(l);
4509 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4510 int case_reg, int is_expr)
4512 int a, b, c, d;
4513 Sym *s, *frame_bottom;
4515 /* generate line number info */
4516 if (tcc_state->do_debug &&
4517 (last_line_num != file->line_num || last_ind != ind)) {
4518 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4519 last_ind = ind;
4520 last_line_num = file->line_num;
4523 if (is_expr) {
4524 /* default return value is (void) */
4525 vpushi(0);
4526 vtop->type.t = VT_VOID;
4529 if (tok == TOK_IF) {
4530 /* if test */
4531 next();
4532 skip('(');
4533 gexpr();
4534 skip(')');
4535 a = gvtst(1, 0);
4536 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4537 c = tok;
4538 if (c == TOK_ELSE) {
4539 next();
4540 d = gjmp(0);
4541 gsym(a);
4542 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4543 gsym(d); /* patch else jmp */
4544 } else
4545 gsym(a);
4546 } else if (tok == TOK_WHILE) {
4547 next();
4548 d = ind;
4549 skip('(');
4550 gexpr();
4551 skip(')');
4552 a = gvtst(1, 0);
4553 b = 0;
4554 block(&a, &b, case_sym, def_sym, case_reg, 0);
4555 gjmp_addr(d);
4556 gsym(a);
4557 gsym_addr(b, d);
4558 } else if (tok == '{') {
4559 Sym *llabel;
4560 int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
4562 next();
4563 /* record local declaration stack position */
4564 s = local_stack;
4565 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4566 frame_bottom->next = scope_stack_bottom;
4567 scope_stack_bottom = frame_bottom;
4568 llabel = local_label_stack;
4570 /* save VLA state */
4571 block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4572 if (saved_vla_sp_loc != &vla_sp_root_loc)
4573 vla_sp_loc = &block_vla_sp_loc;
4575 saved_vla_flags = vla_flags;
4576 vla_flags |= VLA_NEED_NEW_FRAME;
4578 /* handle local labels declarations */
4579 if (tok == TOK_LABEL) {
4580 next();
4581 for(;;) {
4582 if (tok < TOK_UIDENT)
4583 expect("label identifier");
4584 label_push(&local_label_stack, tok, LABEL_DECLARED);
4585 next();
4586 if (tok == ',') {
4587 next();
4588 } else {
4589 skip(';');
4590 break;
4594 while (tok != '}') {
4595 label_or_decl(VT_LOCAL);
4596 if (tok != '}') {
4597 if (is_expr)
4598 vpop();
4599 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4602 /* pop locally defined labels */
4603 label_pop(&local_label_stack, llabel);
4604 if(is_expr) {
4605 /* XXX: this solution makes only valgrind happy...
4606 triggered by gcc.c-torture/execute/20000917-1.c */
4607 Sym *p;
4608 switch(vtop->type.t & VT_BTYPE) {
4609 case VT_PTR:
4610 case VT_STRUCT:
4611 case VT_ENUM:
4612 case VT_FUNC:
4613 for(p=vtop->type.ref;p;p=p->prev)
4614 if(p->prev==s)
4615 tcc_error("unsupported expression type");
4618 /* pop locally defined symbols */
4619 scope_stack_bottom = scope_stack_bottom->next;
4620 sym_pop(&local_stack, s);
4622 /* Pop VLA frames and restore stack pointer if required */
4623 if (saved_vla_sp_loc != &vla_sp_root_loc)
4624 *saved_vla_sp_loc = block_vla_sp_loc;
4625 if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
4626 vla_sp_loc = saved_vla_sp_loc;
4627 gen_vla_sp_restore(*vla_sp_loc);
4629 vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
4631 next();
4632 } else if (tok == TOK_RETURN) {
4633 next();
4634 if (tok != ';') {
4635 gexpr();
4636 gen_assign_cast(&func_vt);
4637 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4638 CType type, ret_type;
4639 int ret_align, ret_nregs;
4640 ret_nregs = gfunc_sret(&func_vt, &ret_type, &ret_align);
4641 if (0 == ret_nregs) {
4642 /* if returning structure, must copy it to implicit
4643 first pointer arg location */
4644 type = func_vt;
4645 mk_pointer(&type);
4646 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4647 indir();
4648 vswap();
4649 /* copy structure value to pointer */
4650 vstore();
4651 } else {
4652 /* returning structure packed into registers */
4653 int r, size, addr, align;
4654 size = type_size(&func_vt,&align);
4655 if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))
4656 && (align & (ret_align-1))) {
4657 loc = (loc - size) & -align;
4658 addr = loc;
4659 type = func_vt;
4660 vset(&type, VT_LOCAL | VT_LVAL, addr);
4661 vswap();
4662 vstore();
4663 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
4665 vtop->type = ret_type;
4666 if (is_float(ret_type.t))
4667 r = rc_fret(ret_type.t);
4668 else
4669 r = RC_IRET;
4671 for (;;) {
4672 gv(r);
4673 if (--ret_nregs == 0)
4674 break;
4675 /* We assume that when a structure is returned in multiple
4676 registers, their classes are consecutive values of the
4677 suite s(n) = 2^n */
4678 r <<= 1;
4679 /* XXX: compatible with arm only: ret_align == register_size */
4680 vtop->c.i += ret_align;
4681 vtop->r = VT_LOCAL | VT_LVAL;
4684 } else if (is_float(func_vt.t)) {
4685 gv(rc_fret(func_vt.t));
4686 } else {
4687 gv(RC_IRET);
4689 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4691 skip(';');
4692 rsym = gjmp(rsym); /* jmp */
4693 } else if (tok == TOK_BREAK) {
4694 /* compute jump */
4695 if (!bsym)
4696 tcc_error("cannot break");
4697 *bsym = gjmp(*bsym);
4698 next();
4699 skip(';');
4700 } else if (tok == TOK_CONTINUE) {
4701 /* compute jump */
4702 if (!csym)
4703 tcc_error("cannot continue");
4704 *csym = gjmp(*csym);
4705 next();
4706 skip(';');
4707 } else if (tok == TOK_FOR) {
4708 int e;
4709 next();
4710 skip('(');
4711 s = local_stack;
4712 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4713 frame_bottom->next = scope_stack_bottom;
4714 scope_stack_bottom = frame_bottom;
4715 if (tok != ';') {
4716 /* c99 for-loop init decl? */
4717 if (!decl0(VT_LOCAL, 1)) {
4718 /* no, regular for-loop init expr */
4719 gexpr();
4720 vpop();
4723 skip(';');
4724 d = ind;
4725 c = ind;
4726 a = 0;
4727 b = 0;
4728 if (tok != ';') {
4729 gexpr();
4730 a = gvtst(1, 0);
4732 skip(';');
4733 if (tok != ')') {
4734 e = gjmp(0);
4735 c = ind;
4736 gexpr();
4737 vpop();
4738 gjmp_addr(d);
4739 gsym(e);
4741 skip(')');
4742 block(&a, &b, case_sym, def_sym, case_reg, 0);
4743 gjmp_addr(c);
4744 gsym(a);
4745 gsym_addr(b, c);
4746 scope_stack_bottom = scope_stack_bottom->next;
4747 sym_pop(&local_stack, s);
4748 } else
4749 if (tok == TOK_DO) {
4750 next();
4751 a = 0;
4752 b = 0;
4753 d = ind;
4754 block(&a, &b, case_sym, def_sym, case_reg, 0);
4755 skip(TOK_WHILE);
4756 skip('(');
4757 gsym(b);
4758 gexpr();
4759 c = gvtst(0, 0);
4760 gsym_addr(c, d);
4761 skip(')');
4762 gsym(a);
4763 skip(';');
4764 } else
4765 if (tok == TOK_SWITCH) {
4766 next();
4767 skip('(');
4768 gexpr();
4769 /* XXX: other types than integer */
4770 case_reg = gv(RC_INT);
4771 vpop();
4772 skip(')');
4773 a = 0;
4774 b = gjmp(0); /* jump to first case */
4775 c = 0;
4776 block(&a, csym, &b, &c, case_reg, 0);
4777 /* if no default, jmp after switch */
4778 if (c == 0)
4779 c = ind;
4780 /* default label */
4781 gsym_addr(b, c);
4782 /* break label */
4783 gsym(a);
4784 } else
4785 if (tok == TOK_CASE) {
4786 int v1, v2;
4787 if (!case_sym)
4788 expect("switch");
4789 next();
4790 v1 = expr_const();
4791 v2 = v1;
4792 if (gnu_ext && tok == TOK_DOTS) {
4793 next();
4794 v2 = expr_const();
4795 if (v2 < v1)
4796 tcc_warning("empty case range");
4798 /* since a case is like a label, we must skip it with a jmp */
4799 b = gjmp(0);
4800 gsym(*case_sym);
4801 vseti(case_reg, 0);
4802 vpushi(v1);
4803 if (v1 == v2) {
4804 gen_op(TOK_EQ);
4805 *case_sym = gtst(1, 0);
4806 } else {
4807 gen_op(TOK_GE);
4808 *case_sym = gtst(1, 0);
4809 vseti(case_reg, 0);
4810 vpushi(v2);
4811 gen_op(TOK_LE);
4812 *case_sym = gtst(1, *case_sym);
4814 gsym(b);
4815 skip(':');
4816 is_expr = 0;
4817 goto block_after_label;
4818 } else
4819 if (tok == TOK_DEFAULT) {
4820 next();
4821 skip(':');
4822 if (!def_sym)
4823 expect("switch");
4824 if (*def_sym)
4825 tcc_error("too many 'default'");
4826 *def_sym = ind;
4827 is_expr = 0;
4828 goto block_after_label;
4829 } else
4830 if (tok == TOK_GOTO) {
4831 next();
4832 if (tok == '*' && gnu_ext) {
4833 /* computed goto */
4834 next();
4835 gexpr();
4836 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4837 expect("pointer");
4838 ggoto();
4839 } else if (tok >= TOK_UIDENT) {
4840 s = label_find(tok);
4841 /* put forward definition if needed */
4842 if (!s) {
4843 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4844 } else {
4845 if (s->r == LABEL_DECLARED)
4846 s->r = LABEL_FORWARD;
4848 /* label already defined */
4849 if (vla_flags & VLA_IN_SCOPE) {
4850 /* If VLAs are in use, save the current stack pointer and
4851 reset the stack pointer to what it was at function entry
4852 (label will restore stack pointer in inner scopes) */
4853 vla_sp_save();
4854 gen_vla_sp_restore(vla_sp_root_loc);
4856 if (s->r & LABEL_FORWARD)
4857 s->jnext = gjmp(s->jnext);
4858 else
4859 gjmp_addr(s->jnext);
4860 next();
4861 } else {
4862 expect("label identifier");
4864 skip(';');
4865 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4866 asm_instr();
4867 } else {
4868 b = is_label();
4869 if (b) {
4870 /* label case */
4871 if (vla_flags & VLA_IN_SCOPE) {
4872 /* save/restore stack pointer across label
4873 this is a no-op when combined with the load immediately
4874 after the label unless we arrive via goto */
4875 vla_sp_save();
4877 s = label_find(b);
4878 if (s) {
4879 if (s->r == LABEL_DEFINED)
4880 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4881 gsym(s->jnext);
4882 s->r = LABEL_DEFINED;
4883 } else {
4884 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4886 s->jnext = ind;
4887 if (vla_flags & VLA_IN_SCOPE) {
4888 gen_vla_sp_restore(*vla_sp_loc);
4889 vla_flags |= VLA_NEED_NEW_FRAME;
4891 /* we accept this, but it is a mistake */
4892 block_after_label:
4893 if (tok == '}') {
4894 tcc_warning("deprecated use of label at end of compound statement");
4895 } else {
4896 if (is_expr)
4897 vpop();
4898 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4900 } else {
4901 /* expression case */
4902 if (tok != ';') {
4903 if (is_expr) {
4904 vpop();
4905 gexpr();
4906 } else {
4907 gexpr();
4908 vpop();
4911 skip(';');
4916 /* t is the array or struct type. c is the array or struct
4917 address. cur_index/cur_field is the pointer to the current
4918 value. 'size_only' is true if only size info is needed (only used
4919 in arrays) */
4920 static void decl_designator(CType *type, Section *sec, unsigned long c,
4921 int *cur_index, Sym **cur_field,
4922 int size_only)
4924 Sym *s, *f;
4925 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4926 CType type1;
4928 notfirst = 0;
4929 elem_size = 0;
4930 nb_elems = 1;
4931 if (gnu_ext && (l = is_label()) != 0)
4932 goto struct_field;
4933 while (tok == '[' || tok == '.') {
4934 if (tok == '[') {
4935 if (!(type->t & VT_ARRAY))
4936 expect("array type");
4937 s = type->ref;
4938 next();
4939 index = expr_const();
4940 if (index < 0 || (s->c >= 0 && index >= s->c))
4941 expect("invalid index");
4942 if (tok == TOK_DOTS && gnu_ext) {
4943 next();
4944 index_last = expr_const();
4945 if (index_last < 0 ||
4946 (s->c >= 0 && index_last >= s->c) ||
4947 index_last < index)
4948 expect("invalid index");
4949 } else {
4950 index_last = index;
4952 skip(']');
4953 if (!notfirst)
4954 *cur_index = index_last;
4955 type = pointed_type(type);
4956 elem_size = type_size(type, &align);
4957 c += index * elem_size;
4958 /* NOTE: we only support ranges for last designator */
4959 nb_elems = index_last - index + 1;
4960 if (nb_elems != 1) {
4961 notfirst = 1;
4962 break;
4964 } else {
4965 next();
4966 l = tok;
4967 next();
4968 struct_field:
4969 if ((type->t & VT_BTYPE) != VT_STRUCT)
4970 expect("struct/union type");
4971 s = type->ref;
4972 l |= SYM_FIELD;
4973 f = s->next;
4974 while (f) {
4975 if (f->v == l)
4976 break;
4977 f = f->next;
4979 if (!f)
4980 expect("field");
4981 if (!notfirst)
4982 *cur_field = f;
4983 /* XXX: fix this mess by using explicit storage field */
4984 type1 = f->type;
4985 type1.t |= (type->t & ~VT_TYPE);
4986 type = &type1;
4987 c += f->c;
4989 notfirst = 1;
4991 if (notfirst) {
4992 if (tok == '=') {
4993 next();
4994 } else {
4995 if (!gnu_ext)
4996 expect("=");
4998 } else {
4999 if (type->t & VT_ARRAY) {
5000 index = *cur_index;
5001 type = pointed_type(type);
5002 c += index * type_size(type, &align);
5003 } else {
5004 f = *cur_field;
5005 if (!f)
5006 tcc_error("too many field init");
5007 /* XXX: fix this mess by using explicit storage field */
5008 type1 = f->type;
5009 type1.t |= (type->t & ~VT_TYPE);
5010 type = &type1;
5011 c += f->c;
5014 decl_initializer(type, sec, c, 0, size_only);
5016 /* XXX: make it more general */
5017 if (!size_only && nb_elems > 1) {
5018 unsigned long c_end;
5019 uint8_t *src, *dst;
5020 int i;
5022 if (!sec)
5023 tcc_error("range init not supported yet for dynamic storage");
5024 c_end = c + nb_elems * elem_size;
5025 if (c_end > sec->data_allocated)
5026 section_realloc(sec, c_end);
5027 src = sec->data + c;
5028 dst = src;
5029 for(i = 1; i < nb_elems; i++) {
5030 dst += elem_size;
5031 memcpy(dst, src, elem_size);
5036 #define EXPR_VAL 0
5037 #define EXPR_CONST 1
5038 #define EXPR_ANY 2
5040 /* store a value or an expression directly in global data or in local array */
5041 static void init_putv(CType *type, Section *sec, unsigned long c,
5042 int v, int expr_type)
5044 int saved_global_expr, bt, bit_pos, bit_size;
5045 void *ptr;
5046 unsigned long long bit_mask;
5047 CType dtype;
5049 switch(expr_type) {
5050 case EXPR_VAL:
5051 vpushi(v);
5052 break;
5053 case EXPR_CONST:
5054 /* compound literals must be allocated globally in this case */
5055 saved_global_expr = global_expr;
5056 global_expr = 1;
5057 expr_const1();
5058 global_expr = saved_global_expr;
5059 /* NOTE: symbols are accepted */
5060 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5061 tcc_error("initializer element is not constant");
5062 break;
5063 case EXPR_ANY:
5064 expr_eq();
5065 break;
5068 dtype = *type;
5069 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5071 if (sec) {
5072 /* XXX: not portable */
5073 /* XXX: generate error if incorrect relocation */
5074 gen_assign_cast(&dtype);
5075 bt = type->t & VT_BTYPE;
5076 /* we'll write at most 12 bytes */
5077 if (c + 12 > sec->data_allocated) {
5078 section_realloc(sec, c + 12);
5080 ptr = sec->data + c;
5081 /* XXX: make code faster ? */
5082 if (!(type->t & VT_BITFIELD)) {
5083 bit_pos = 0;
5084 bit_size = 32;
5085 bit_mask = -1LL;
5086 } else {
5087 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5088 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5089 bit_mask = (1LL << bit_size) - 1;
5091 if ((vtop->r & VT_SYM) &&
5092 (bt == VT_BYTE ||
5093 bt == VT_SHORT ||
5094 bt == VT_DOUBLE ||
5095 bt == VT_LDOUBLE ||
5096 bt == VT_LLONG ||
5097 (bt == VT_INT && bit_size != 32)))
5098 tcc_error("initializer element is not computable at load time");
5099 switch(bt) {
5100 case VT_BOOL:
5101 vtop->c.i = (vtop->c.i != 0);
5102 case VT_BYTE:
5103 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5104 break;
5105 case VT_SHORT:
5106 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5107 break;
5108 case VT_DOUBLE:
5109 *(double *)ptr = vtop->c.d;
5110 break;
5111 case VT_LDOUBLE:
5112 *(long double *)ptr = vtop->c.ld;
5113 break;
5114 case VT_LLONG:
5115 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
5116 break;
5117 default:
5118 if (vtop->r & VT_SYM) {
5119 greloc(sec, vtop->sym, c, R_DATA_PTR);
5121 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5122 break;
5124 vtop--;
5125 } else {
5126 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5127 vswap();
5128 vstore();
5129 vpop();
5133 /* put zeros for variable based init */
5134 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5136 if (sec) {
5137 /* nothing to do because globals are already set to zero */
5138 } else {
5139 vpush_global_sym(&func_old_type, TOK_memset);
5140 vseti(VT_LOCAL, c);
5141 vpushi(0);
5142 vpushs(size);
5143 gfunc_call(3);
5147 /* 't' contains the type and storage info. 'c' is the offset of the
5148 object in section 'sec'. If 'sec' is NULL, it means stack based
5149 allocation. 'first' is true if array '{' must be read (multi
5150 dimension implicit array init handling). 'size_only' is true if
5151 size only evaluation is wanted (only for arrays). */
5152 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5153 int first, int size_only)
5155 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5156 int size1, align1, expr_type;
5157 Sym *s, *f;
5158 CType *t1;
5160 if (type->t & VT_VLA) {
5161 int a;
5163 /* save current stack pointer */
5164 if (vla_flags & VLA_NEED_NEW_FRAME) {
5165 vla_sp_save();
5166 vla_flags = VLA_IN_SCOPE;
5167 vla_sp_loc = &vla_sp_loc_tmp;
5170 vla_runtime_type_size(type, &a);
5171 gen_vla_alloc(type, a);
5172 vset(type, VT_LOCAL|VT_LVAL, c);
5173 vswap();
5174 vstore();
5175 vpop();
5176 } else if (type->t & VT_ARRAY) {
5177 s = type->ref;
5178 n = s->c;
5179 array_length = 0;
5180 t1 = pointed_type(type);
5181 size1 = type_size(t1, &align1);
5183 no_oblock = 1;
5184 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5185 tok == '{') {
5186 if (tok != '{')
5187 tcc_error("character array initializer must be a literal,"
5188 " optionally enclosed in braces");
5189 skip('{');
5190 no_oblock = 0;
5193 /* only parse strings here if correct type (otherwise: handle
5194 them as ((w)char *) expressions */
5195 if ((tok == TOK_LSTR &&
5196 #ifdef TCC_TARGET_PE
5197 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5198 #else
5199 (t1->t & VT_BTYPE) == VT_INT
5200 #endif
5201 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5202 while (tok == TOK_STR || tok == TOK_LSTR) {
5203 int cstr_len, ch;
5204 CString *cstr;
5206 cstr = tokc.cstr;
5207 /* compute maximum number of chars wanted */
5208 if (tok == TOK_STR)
5209 cstr_len = cstr->size;
5210 else
5211 cstr_len = cstr->size / sizeof(nwchar_t);
5212 cstr_len--;
5213 nb = cstr_len;
5214 if (n >= 0 && nb > (n - array_length))
5215 nb = n - array_length;
5216 if (!size_only) {
5217 if (cstr_len > nb)
5218 tcc_warning("initializer-string for array is too long");
5219 /* in order to go faster for common case (char
5220 string in global variable, we handle it
5221 specifically */
5222 if (sec && tok == TOK_STR && size1 == 1) {
5223 memcpy(sec->data + c + array_length, cstr->data, nb);
5224 } else {
5225 for(i=0;i<nb;i++) {
5226 if (tok == TOK_STR)
5227 ch = ((unsigned char *)cstr->data)[i];
5228 else
5229 ch = ((nwchar_t *)cstr->data)[i];
5230 init_putv(t1, sec, c + (array_length + i) * size1,
5231 ch, EXPR_VAL);
5235 array_length += nb;
5236 next();
5238 /* only add trailing zero if enough storage (no
5239 warning in this case since it is standard) */
5240 if (n < 0 || array_length < n) {
5241 if (!size_only) {
5242 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5244 array_length++;
5246 } else {
5247 index = 0;
5248 while (tok != '}') {
5249 decl_designator(type, sec, c, &index, NULL, size_only);
5250 if (n >= 0 && index >= n)
5251 tcc_error("index too large");
5252 /* must put zero in holes (note that doing it that way
5253 ensures that it even works with designators) */
5254 if (!size_only && array_length < index) {
5255 init_putz(t1, sec, c + array_length * size1,
5256 (index - array_length) * size1);
5258 index++;
5259 if (index > array_length)
5260 array_length = index;
5261 /* special test for multi dimensional arrays (may not
5262 be strictly correct if designators are used at the
5263 same time) */
5264 if (index >= n && no_oblock)
5265 break;
5266 if (tok == '}')
5267 break;
5268 skip(',');
5271 if (!no_oblock)
5272 skip('}');
5273 /* put zeros at the end */
5274 if (!size_only && n >= 0 && array_length < n) {
5275 init_putz(t1, sec, c + array_length * size1,
5276 (n - array_length) * size1);
5278 /* patch type size if needed */
5279 if (n < 0)
5280 s->c = array_length;
5281 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5282 (sec || !first || tok == '{')) {
5283 int par_count;
5285 /* NOTE: the previous test is a specific case for automatic
5286 struct/union init */
5287 /* XXX: union needs only one init */
5289 /* XXX: this test is incorrect for local initializers
5290 beginning with ( without {. It would be much more difficult
5291 to do it correctly (ideally, the expression parser should
5292 be used in all cases) */
5293 par_count = 0;
5294 if (tok == '(') {
5295 AttributeDef ad1;
5296 CType type1;
5297 next();
5298 while (tok == '(') {
5299 par_count++;
5300 next();
5302 if (!parse_btype(&type1, &ad1))
5303 expect("cast");
5304 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5305 #if 0
5306 if (!is_assignable_types(type, &type1))
5307 tcc_error("invalid type for cast");
5308 #endif
5309 skip(')');
5311 no_oblock = 1;
5312 if (first || tok == '{') {
5313 skip('{');
5314 no_oblock = 0;
5316 s = type->ref;
5317 f = s->next;
5318 array_length = 0;
5319 index = 0;
5320 n = s->c;
5321 while (tok != '}') {
5322 decl_designator(type, sec, c, NULL, &f, size_only);
5323 index = f->c;
5324 if (!size_only && array_length < index) {
5325 init_putz(type, sec, c + array_length,
5326 index - array_length);
5328 index = index + type_size(&f->type, &align1);
5329 if (index > array_length)
5330 array_length = index;
5332 /* gr: skip fields from same union - ugly. */
5333 while (f->next) {
5334 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5335 /* test for same offset */
5336 if (f->next->c != f->c)
5337 break;
5338 /* if yes, test for bitfield shift */
5339 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5340 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5341 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5342 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5343 if (bit_pos_1 != bit_pos_2)
5344 break;
5346 f = f->next;
5349 f = f->next;
5350 if (no_oblock && f == NULL)
5351 break;
5352 if (tok == '}')
5353 break;
5354 skip(',');
5356 /* put zeros at the end */
5357 if (!size_only && array_length < n) {
5358 init_putz(type, sec, c + array_length,
5359 n - array_length);
5361 if (!no_oblock)
5362 skip('}');
5363 while (par_count) {
5364 skip(')');
5365 par_count--;
5367 } else if (tok == '{') {
5368 next();
5369 decl_initializer(type, sec, c, first, size_only);
5370 skip('}');
5371 } else if (size_only) {
5372 /* just skip expression */
5373 parlevel = parlevel1 = 0;
5374 while ((parlevel > 0 || parlevel1 > 0 ||
5375 (tok != '}' && tok != ',')) && tok != -1) {
5376 if (tok == '(')
5377 parlevel++;
5378 else if (tok == ')')
5379 parlevel--;
5380 else if (tok == '{')
5381 parlevel1++;
5382 else if (tok == '}')
5383 parlevel1--;
5384 next();
5386 } else {
5387 /* currently, we always use constant expression for globals
5388 (may change for scripting case) */
5389 expr_type = EXPR_CONST;
5390 if (!sec)
5391 expr_type = EXPR_ANY;
5392 init_putv(type, sec, c, 0, expr_type);
5396 /* parse an initializer for type 't' if 'has_init' is non zero, and
5397 allocate space in local or global data space ('r' is either
5398 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5399 variable 'v' with an associated name represented by 'asm_label' of
5400 scope 'scope' is declared before initializers are parsed. If 'v' is
5401 zero, then a reference to the new object is put in the value stack.
5402 If 'has_init' is 2, a special parsing is done to handle string
5403 constants. */
5404 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5405 int has_init, int v, char *asm_label,
5406 int scope)
5408 int size, align, addr, data_offset;
5409 int level;
5410 ParseState saved_parse_state = {0};
5411 TokenString init_str;
5412 Section *sec;
5413 Sym *flexible_array;
5415 flexible_array = NULL;
5416 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5417 Sym *field = type->ref->next;
5418 if (field) {
5419 while (field->next)
5420 field = field->next;
5421 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5422 flexible_array = field;
5426 size = type_size(type, &align);
5427 /* If unknown size, we must evaluate it before
5428 evaluating initializers because
5429 initializers can generate global data too
5430 (e.g. string pointers or ISOC99 compound
5431 literals). It also simplifies local
5432 initializers handling */
5433 tok_str_new(&init_str);
5434 if (size < 0 || (flexible_array && has_init)) {
5435 if (!has_init)
5436 tcc_error("unknown type size");
5437 /* get all init string */
5438 if (has_init == 2) {
5439 /* only get strings */
5440 while (tok == TOK_STR || tok == TOK_LSTR) {
5441 tok_str_add_tok(&init_str);
5442 next();
5444 } else {
5445 level = 0;
5446 while (level > 0 || (tok != ',' && tok != ';')) {
5447 if (tok < 0)
5448 tcc_error("unexpected end of file in initializer");
5449 tok_str_add_tok(&init_str);
5450 if (tok == '{')
5451 level++;
5452 else if (tok == '}') {
5453 level--;
5454 if (level <= 0) {
5455 next();
5456 break;
5459 next();
5462 tok_str_add(&init_str, -1);
5463 tok_str_add(&init_str, 0);
5465 /* compute size */
5466 save_parse_state(&saved_parse_state);
5468 macro_ptr = init_str.str;
5469 next();
5470 decl_initializer(type, NULL, 0, 1, 1);
5471 /* prepare second initializer parsing */
5472 macro_ptr = init_str.str;
5473 next();
5475 /* if still unknown size, error */
5476 size = type_size(type, &align);
5477 if (size < 0)
5478 tcc_error("unknown type size");
5480 if (flexible_array)
5481 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5482 /* take into account specified alignment if bigger */
5483 if (ad->aligned) {
5484 if (ad->aligned > align)
5485 align = ad->aligned;
5486 } else if (ad->packed) {
5487 align = 1;
5489 if ((r & VT_VALMASK) == VT_LOCAL) {
5490 sec = NULL;
5491 #ifdef CONFIG_TCC_BCHECK
5492 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5493 loc--;
5495 #endif
5496 loc = (loc - size) & -align;
5497 addr = loc;
5498 #ifdef CONFIG_TCC_BCHECK
5499 /* handles bounds */
5500 /* XXX: currently, since we do only one pass, we cannot track
5501 '&' operators, so we add only arrays */
5502 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5503 unsigned long *bounds_ptr;
5504 /* add padding between regions */
5505 loc--;
5506 /* then add local bound info */
5507 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5508 bounds_ptr[0] = addr;
5509 bounds_ptr[1] = size;
5511 #endif
5512 if (v) {
5513 /* local variable */
5514 sym_push(v, type, r, addr);
5515 } else {
5516 /* push local reference */
5517 vset(type, r, addr);
5519 } else {
5520 Sym *sym;
5522 sym = NULL;
5523 if (v && scope == VT_CONST) {
5524 /* see if the symbol was already defined */
5525 sym = sym_find(v);
5526 if (sym) {
5527 if (!is_compatible_types(&sym->type, type))
5528 tcc_error("incompatible types for redefinition of '%s'",
5529 get_tok_str(v, NULL));
5530 if (sym->type.t & VT_EXTERN) {
5531 /* if the variable is extern, it was not allocated */
5532 sym->type.t &= ~VT_EXTERN;
5533 /* set array size if it was ommited in extern
5534 declaration */
5535 if ((sym->type.t & VT_ARRAY) &&
5536 sym->type.ref->c < 0 &&
5537 type->ref->c >= 0)
5538 sym->type.ref->c = type->ref->c;
5539 } else {
5540 /* we accept several definitions of the same
5541 global variable. this is tricky, because we
5542 must play with the SHN_COMMON type of the symbol */
5543 /* XXX: should check if the variable was already
5544 initialized. It is incorrect to initialized it
5545 twice */
5546 /* no init data, we won't add more to the symbol */
5547 if (!has_init)
5548 goto no_alloc;
5553 /* allocate symbol in corresponding section */
5554 sec = ad->section;
5555 if (!sec) {
5556 if (has_init)
5557 sec = data_section;
5558 else if (tcc_state->nocommon)
5559 sec = bss_section;
5561 if (sec) {
5562 data_offset = sec->data_offset;
5563 data_offset = (data_offset + align - 1) & -align;
5564 addr = data_offset;
5565 /* very important to increment global pointer at this time
5566 because initializers themselves can create new initializers */
5567 data_offset += size;
5568 #ifdef CONFIG_TCC_BCHECK
5569 /* add padding if bound check */
5570 if (tcc_state->do_bounds_check)
5571 data_offset++;
5572 #endif
5573 sec->data_offset = data_offset;
5574 /* allocate section space to put the data */
5575 if (sec->sh_type != SHT_NOBITS &&
5576 data_offset > sec->data_allocated)
5577 section_realloc(sec, data_offset);
5578 /* align section if needed */
5579 if (align > sec->sh_addralign)
5580 sec->sh_addralign = align;
5581 } else {
5582 addr = 0; /* avoid warning */
5585 if (v) {
5586 if (scope != VT_CONST || !sym) {
5587 sym = sym_push(v, type, r | VT_SYM, 0);
5588 sym->asm_label = asm_label;
5590 /* update symbol definition */
5591 if (sec) {
5592 put_extern_sym(sym, sec, addr, size);
5593 } else {
5594 ElfW(Sym) *esym;
5595 /* put a common area */
5596 put_extern_sym(sym, NULL, align, size);
5597 /* XXX: find a nicer way */
5598 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5599 esym->st_shndx = SHN_COMMON;
5601 } else {
5602 CValue cval;
5604 /* push global reference */
5605 sym = get_sym_ref(type, sec, addr, size);
5606 cval.ul = 0;
5607 vsetc(type, VT_CONST | VT_SYM, &cval);
5608 vtop->sym = sym;
5610 /* patch symbol weakness */
5611 if (type->t & VT_WEAK)
5612 weaken_symbol(sym);
5613 #ifdef CONFIG_TCC_BCHECK
5614 /* handles bounds now because the symbol must be defined
5615 before for the relocation */
5616 if (tcc_state->do_bounds_check) {
5617 unsigned long *bounds_ptr;
5619 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5620 /* then add global bound info */
5621 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5622 bounds_ptr[0] = 0; /* relocated */
5623 bounds_ptr[1] = size;
5625 #endif
5627 if (has_init || (type->t & VT_VLA)) {
5628 decl_initializer(type, sec, addr, 1, 0);
5629 /* restore parse state if needed */
5630 if (init_str.str) {
5631 tok_str_free(init_str.str);
5632 restore_parse_state(&saved_parse_state);
5634 /* patch flexible array member size back to -1, */
5635 /* for possible subsequent similar declarations */
5636 if (flexible_array)
5637 flexible_array->type.ref->c = -1;
5639 no_alloc: ;
5642 static void put_func_debug(Sym *sym)
5644 char buf[512];
5646 /* stabs info */
5647 /* XXX: we put here a dummy type */
5648 snprintf(buf, sizeof(buf), "%s:%c1",
5649 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5650 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5651 cur_text_section, sym->c);
5652 /* //gr gdb wants a line at the function */
5653 put_stabn(N_SLINE, 0, file->line_num, 0);
5654 last_ind = 0;
5655 last_line_num = 0;
5658 /* parse an old style function declaration list */
5659 /* XXX: check multiple parameter */
5660 static void func_decl_list(Sym *func_sym)
5662 AttributeDef ad;
5663 int v;
5664 Sym *s;
5665 CType btype, type;
5667 /* parse each declaration */
5668 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5669 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5670 if (!parse_btype(&btype, &ad))
5671 expect("declaration list");
5672 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5673 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5674 tok == ';') {
5675 /* we accept no variable after */
5676 } else {
5677 for(;;) {
5678 type = btype;
5679 type_decl(&type, &ad, &v, TYPE_DIRECT);
5680 /* find parameter in function parameter list */
5681 s = func_sym->next;
5682 while (s != NULL) {
5683 if ((s->v & ~SYM_FIELD) == v)
5684 goto found;
5685 s = s->next;
5687 tcc_error("declaration for parameter '%s' but no such parameter",
5688 get_tok_str(v, NULL));
5689 found:
5690 /* check that no storage specifier except 'register' was given */
5691 if (type.t & VT_STORAGE)
5692 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5693 convert_parameter_type(&type);
5694 /* we can add the type (NOTE: it could be local to the function) */
5695 s->type = type;
5696 /* accept other parameters */
5697 if (tok == ',')
5698 next();
5699 else
5700 break;
5703 skip(';');
5707 /* parse a function defined by symbol 'sym' and generate its code in
5708 'cur_text_section' */
5709 static void gen_function(Sym *sym)
5711 int saved_nocode_wanted = nocode_wanted;
5712 nocode_wanted = 0;
5713 ind = cur_text_section->data_offset;
5714 /* NOTE: we patch the symbol size later */
5715 put_extern_sym(sym, cur_text_section, ind, 0);
5716 funcname = get_tok_str(sym->v, NULL);
5717 func_ind = ind;
5718 /* Initialize VLA state */
5719 vla_sp_loc = &vla_sp_root_loc;
5720 vla_flags = VLA_NEED_NEW_FRAME;
5721 /* put debug symbol */
5722 if (tcc_state->do_debug)
5723 put_func_debug(sym);
5724 /* push a dummy symbol to enable local sym storage */
5725 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5726 gfunc_prolog(&sym->type);
5727 rsym = 0;
5728 block(NULL, NULL, NULL, NULL, 0, 0);
5729 gsym(rsym);
5730 gfunc_epilog();
5731 cur_text_section->data_offset = ind;
5732 label_pop(&global_label_stack, NULL);
5733 /* reset local stack */
5734 scope_stack_bottom = NULL;
5735 sym_pop(&local_stack, NULL);
5736 /* end of function */
5737 /* patch symbol size */
5738 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5739 ind - func_ind;
5740 /* patch symbol weakness (this definition overrules any prototype) */
5741 if (sym->type.t & VT_WEAK)
5742 weaken_symbol(sym);
5743 if (tcc_state->do_debug) {
5744 put_stabn(N_FUN, 0, 0, ind - func_ind);
5746 /* It's better to crash than to generate wrong code */
5747 cur_text_section = NULL;
5748 funcname = ""; /* for safety */
5749 func_vt.t = VT_VOID; /* for safety */
5750 ind = 0; /* for safety */
5751 nocode_wanted = saved_nocode_wanted;
5754 ST_FUNC void gen_inline_functions(void)
5756 Sym *sym;
5757 int *str, inline_generated, i;
5758 struct InlineFunc *fn;
5760 /* iterate while inline function are referenced */
5761 for(;;) {
5762 inline_generated = 0;
5763 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5764 fn = tcc_state->inline_fns[i];
5765 sym = fn->sym;
5766 if (sym && sym->c) {
5767 /* the function was used: generate its code and
5768 convert it to a normal function */
5769 str = fn->token_str;
5770 fn->sym = NULL;
5771 if (file)
5772 pstrcpy(file->filename, sizeof file->filename, fn->filename);
5773 sym->r = VT_SYM | VT_CONST;
5774 sym->type.t &= ~VT_INLINE;
5776 macro_ptr = str;
5777 next();
5778 cur_text_section = text_section;
5779 gen_function(sym);
5780 macro_ptr = NULL; /* fail safe */
5782 inline_generated = 1;
5785 if (!inline_generated)
5786 break;
5788 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5789 fn = tcc_state->inline_fns[i];
5790 str = fn->token_str;
5791 tok_str_free(str);
5793 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5796 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5797 static int decl0(int l, int is_for_loop_init)
5799 int v, has_init, r;
5800 CType type, btype;
5801 Sym *sym;
5802 AttributeDef ad;
5804 while (1) {
5805 if (!parse_btype(&btype, &ad)) {
5806 if (is_for_loop_init)
5807 return 0;
5808 /* skip redundant ';' */
5809 /* XXX: find more elegant solution */
5810 if (tok == ';') {
5811 next();
5812 continue;
5814 if (l == VT_CONST &&
5815 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5816 /* global asm block */
5817 asm_global_instr();
5818 continue;
5820 /* special test for old K&R protos without explicit int
5821 type. Only accepted when defining global data */
5822 if (l == VT_LOCAL || tok < TOK_DEFINE)
5823 break;
5824 btype.t = VT_INT;
5826 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5827 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5828 tok == ';') {
5829 /* we accept no variable after */
5830 next();
5831 continue;
5833 while (1) { /* iterate thru each declaration */
5834 char *asm_label; // associated asm label
5835 type = btype;
5836 type_decl(&type, &ad, &v, TYPE_DIRECT);
5837 #if 0
5839 char buf[500];
5840 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5841 printf("type = '%s'\n", buf);
5843 #endif
5844 if ((type.t & VT_BTYPE) == VT_FUNC) {
5845 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5846 tcc_error("function without file scope cannot be static");
5848 /* if old style function prototype, we accept a
5849 declaration list */
5850 sym = type.ref;
5851 if (sym->c == FUNC_OLD)
5852 func_decl_list(sym);
5855 asm_label = NULL;
5856 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5857 CString astr;
5859 asm_label_instr(&astr);
5860 asm_label = tcc_strdup(astr.data);
5861 cstr_free(&astr);
5863 /* parse one last attribute list, after asm label */
5864 parse_attribute(&ad);
5867 if (ad.weak)
5868 type.t |= VT_WEAK;
5869 #ifdef TCC_TARGET_PE
5870 if (ad.func_import)
5871 type.t |= VT_IMPORT;
5872 if (ad.func_export)
5873 type.t |= VT_EXPORT;
5874 #endif
5875 if (tok == '{') {
5876 if (l == VT_LOCAL)
5877 tcc_error("cannot use local functions");
5878 if ((type.t & VT_BTYPE) != VT_FUNC)
5879 expect("function definition");
5881 /* reject abstract declarators in function definition */
5882 sym = type.ref;
5883 while ((sym = sym->next) != NULL)
5884 if (!(sym->v & ~SYM_FIELD))
5885 expect("identifier");
5887 /* XXX: cannot do better now: convert extern line to static inline */
5888 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5889 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5891 sym = sym_find(v);
5892 if (sym) {
5893 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5894 goto func_error1;
5896 r = sym->type.ref->r;
5898 if (!FUNC_PROTO(r))
5899 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
5901 /* use func_call from prototype if not defined */
5902 if (FUNC_CALL(r) != FUNC_CDECL
5903 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5904 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5906 /* use export from prototype */
5907 if (FUNC_EXPORT(r))
5908 FUNC_EXPORT(type.ref->r) = 1;
5910 /* use static from prototype */
5911 if (sym->type.t & VT_STATIC)
5912 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5914 if (!is_compatible_types(&sym->type, &type)) {
5915 func_error1:
5916 tcc_error("incompatible types for redefinition of '%s'",
5917 get_tok_str(v, NULL));
5919 FUNC_PROTO(type.ref->r) = 0;
5920 /* if symbol is already defined, then put complete type */
5921 sym->type = type;
5922 } else {
5923 /* put function symbol */
5924 sym = global_identifier_push(v, type.t, 0);
5925 sym->type.ref = type.ref;
5928 /* static inline functions are just recorded as a kind
5929 of macro. Their code will be emitted at the end of
5930 the compilation unit only if they are used */
5931 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5932 (VT_INLINE | VT_STATIC)) {
5933 TokenString func_str;
5934 int block_level;
5935 struct InlineFunc *fn;
5936 const char *filename;
5938 tok_str_new(&func_str);
5940 block_level = 0;
5941 for(;;) {
5942 int t;
5943 if (tok == TOK_EOF)
5944 tcc_error("unexpected end of file");
5945 tok_str_add_tok(&func_str);
5946 t = tok;
5947 next();
5948 if (t == '{') {
5949 block_level++;
5950 } else if (t == '}') {
5951 block_level--;
5952 if (block_level == 0)
5953 break;
5956 tok_str_add(&func_str, -1);
5957 tok_str_add(&func_str, 0);
5958 filename = file ? file->filename : "";
5959 fn = tcc_malloc(sizeof *fn + strlen(filename));
5960 strcpy(fn->filename, filename);
5961 fn->sym = sym;
5962 fn->token_str = func_str.str;
5963 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5965 } else {
5966 /* compute text section */
5967 cur_text_section = ad.section;
5968 if (!cur_text_section)
5969 cur_text_section = text_section;
5970 sym->r = VT_SYM | VT_CONST;
5971 gen_function(sym);
5973 break;
5974 } else {
5975 if (btype.t & VT_TYPEDEF) {
5976 /* save typedefed type */
5977 /* XXX: test storage specifiers ? */
5978 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5979 sym->type.t |= VT_TYPEDEF;
5980 } else {
5981 r = 0;
5982 if ((type.t & VT_BTYPE) == VT_FUNC) {
5983 /* external function definition */
5984 /* specific case for func_call attribute */
5985 ad.func_proto = 1;
5986 type.ref->r = INT_ATTR(&ad);
5987 } else if (!(type.t & VT_ARRAY)) {
5988 /* not lvalue if array */
5989 r |= lvalue_type(type.t);
5991 has_init = (tok == '=');
5992 if (has_init && (type.t & VT_VLA))
5993 tcc_error("Variable length array cannot be initialized");
5994 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5995 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5996 !has_init && l == VT_CONST && type.ref->c < 0)) {
5997 /* external variable or function */
5998 /* NOTE: as GCC, uninitialized global static
5999 arrays of null size are considered as
6000 extern */
6001 sym = external_sym(v, &type, r, asm_label);
6003 if (type.t & VT_WEAK)
6004 weaken_symbol(sym);
6006 if (ad.alias_target) {
6007 Section tsec;
6008 Elf32_Sym *esym;
6009 Sym *alias_target;
6011 alias_target = sym_find(ad.alias_target);
6012 if (!alias_target || !alias_target->c)
6013 tcc_error("unsupported forward __alias__ attribute");
6014 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6015 tsec.sh_num = esym->st_shndx;
6016 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6018 } else {
6019 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6020 if (type.t & VT_STATIC)
6021 r |= VT_CONST;
6022 else
6023 r |= l;
6024 if (has_init)
6025 next();
6026 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
6029 if (tok != ',') {
6030 if (is_for_loop_init)
6031 return 1;
6032 skip(';');
6033 break;
6035 next();
6037 ad.aligned = 0;
6040 return 0;
6043 ST_FUNC void decl(int l)
6045 decl0(l, 0);