x86-64: use r8/r9 as generic integer registers
[tinycc.git] / tccgen.c
blob363e6f9729ee8552a2565b656792eb8c87459a7e
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /********************************************************/
24 /* global variables */
26 /* loc : local variable index
27 ind : output code index
28 rsym: return symbol
29 anon_sym: anonymous symbol index
31 ST_DATA int rsym, anon_sym, ind, loc;
33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
34 ST_DATA Section *cur_text_section; /* current section where function code is generated */
35 #ifdef CONFIG_TCC_ASM
36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
37 #endif
38 #ifdef CONFIG_TCC_BCHECK
39 /* bound check related sections */
40 ST_DATA Section *bounds_section; /* contains global data bound description */
41 ST_DATA Section *lbounds_section; /* contains local data bound description */
42 #endif
43 /* symbol sections */
44 ST_DATA Section *symtab_section, *strtab_section;
45 /* debug sections */
46 ST_DATA Section *stab_section, *stabstr_section;
47 ST_DATA Sym *sym_free_first;
48 ST_DATA void **sym_pools;
49 ST_DATA int nb_sym_pools;
51 ST_DATA Sym *global_stack;
52 ST_DATA Sym *local_stack;
53 ST_DATA Sym *define_stack;
54 ST_DATA Sym *global_label_stack;
55 ST_DATA Sym *local_label_stack;
57 ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
59 ST_DATA int const_wanted; /* true if constant wanted */
60 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
61 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
62 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
63 ST_DATA int func_vc;
64 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
65 ST_DATA char *funcname;
67 ST_DATA CType char_pointer_type, func_old_type, int_type;
69 /* ------------------------------------------------------------------------- */
70 static void gen_cast(CType *type);
71 static inline CType *pointed_type(CType *type);
72 static int is_compatible_types(CType *type1, CType *type2);
73 static int parse_btype(CType *type, AttributeDef *ad);
74 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
75 static void parse_expr_type(CType *type);
76 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
77 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
78 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
79 static void expr_eq(void);
80 static void unary_type(CType *type);
81 static int is_compatible_parameter_types(CType *type1, CType *type2);
82 static void expr_type(CType *type);
84 ST_INLN int is_float(int t)
86 int bt;
87 bt = t & VT_BTYPE;
88 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
91 ST_FUNC void test_lvalue(void)
93 if (!(vtop->r & VT_LVAL))
94 expect("lvalue");
97 /* ------------------------------------------------------------------------- */
98 /* symbol allocator */
99 static Sym *__sym_malloc(void)
101 Sym *sym_pool, *sym, *last_sym;
102 int i;
104 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
105 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
107 last_sym = sym_free_first;
108 sym = sym_pool;
109 for(i = 0; i < SYM_POOL_NB; i++) {
110 sym->next = last_sym;
111 last_sym = sym;
112 sym++;
114 sym_free_first = last_sym;
115 return last_sym;
118 static inline Sym *sym_malloc(void)
120 Sym *sym;
121 sym = sym_free_first;
122 if (!sym)
123 sym = __sym_malloc();
124 sym_free_first = sym->next;
125 return sym;
128 ST_INLN void sym_free(Sym *sym)
130 sym->next = sym_free_first;
131 sym_free_first = sym;
134 /* push, without hashing */
135 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
137 Sym *s;
138 s = sym_malloc();
139 s->v = v;
140 s->type.t = t;
141 s->type.ref = NULL;
142 #ifdef _WIN64
143 s->d = NULL;
144 #endif
145 s->c = c;
146 s->next = NULL;
147 /* add in stack */
148 s->prev = *ps;
149 *ps = s;
150 return s;
153 /* find a symbol and return its associated structure. 's' is the top
154 of the symbol stack */
155 ST_FUNC Sym *sym_find2(Sym *s, int v)
157 while (s) {
158 if (s->v == v)
159 return s;
160 s = s->prev;
162 return NULL;
165 /* structure lookup */
166 ST_INLN Sym *struct_find(int v)
168 v -= TOK_IDENT;
169 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
170 return NULL;
171 return table_ident[v]->sym_struct;
174 /* find an identifier */
175 ST_INLN Sym *sym_find(int v)
177 v -= TOK_IDENT;
178 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
179 return NULL;
180 return table_ident[v]->sym_identifier;
183 /* push a given symbol on the symbol stack */
184 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
186 Sym *s, **ps;
187 TokenSym *ts;
189 if (local_stack)
190 ps = &local_stack;
191 else
192 ps = &global_stack;
193 s = sym_push2(ps, v, type->t, c);
194 s->type.ref = type->ref;
195 s->r = r;
196 /* don't record fields or anonymous symbols */
197 /* XXX: simplify */
198 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
199 /* record symbol in token array */
200 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
201 if (v & SYM_STRUCT)
202 ps = &ts->sym_struct;
203 else
204 ps = &ts->sym_identifier;
205 s->prev_tok = *ps;
206 *ps = s;
208 return s;
211 /* push a global identifier */
212 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
214 Sym *s, **ps;
215 s = sym_push2(&global_stack, v, t, c);
216 /* don't record anonymous symbol */
217 if (v < SYM_FIRST_ANOM) {
218 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
219 /* modify the top most local identifier, so that
220 sym_identifier will point to 's' when popped */
221 while (*ps != NULL)
222 ps = &(*ps)->prev_tok;
223 s->prev_tok = NULL;
224 *ps = s;
226 return s;
229 /* pop symbols until top reaches 'b' */
230 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
232 Sym *s, *ss, **ps;
233 TokenSym *ts;
234 int v;
236 s = *ptop;
237 while(s != b) {
238 ss = s->prev;
239 v = s->v;
240 /* remove symbol in token array */
241 /* XXX: simplify */
242 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
243 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
244 if (v & SYM_STRUCT)
245 ps = &ts->sym_struct;
246 else
247 ps = &ts->sym_identifier;
248 *ps = s->prev_tok;
250 sym_free(s);
251 s = ss;
253 *ptop = b;
256 /* ------------------------------------------------------------------------- */
258 ST_FUNC void swap(int *p, int *q)
260 int t;
261 t = *p;
262 *p = *q;
263 *q = t;
266 static void vsetc(CType *type, int r, CValue *vc)
268 int v;
270 if (vtop >= vstack + (VSTACK_SIZE - 1))
271 error("memory full");
272 /* cannot let cpu flags if other instruction are generated. Also
273 avoid leaving VT_JMP anywhere except on the top of the stack
274 because it would complicate the code generator. */
275 if (vtop >= vstack) {
276 v = vtop->r & VT_VALMASK;
277 if (v == VT_CMP || (v & ~1) == VT_JMP)
278 gv(RC_INT);
280 vtop++;
281 vtop->type = *type;
282 vtop->r = r;
283 vtop->r2 = VT_CONST;
284 vtop->c = *vc;
287 /* push integer constant */
288 ST_FUNC void vpushi(int v)
290 CValue cval;
291 cval.i = v;
292 vsetc(&int_type, VT_CONST, &cval);
295 /* push long long constant */
296 static void vpushll(long long v)
298 CValue cval;
299 CType ctype;
300 ctype.t = VT_LLONG;
301 ctype.ref = 0;
302 cval.ull = v;
303 vsetc(&ctype, VT_CONST, &cval);
306 /* Return a static symbol pointing to a section */
307 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
309 int v;
310 Sym *sym;
312 v = anon_sym++;
313 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
314 sym->type.ref = type->ref;
315 sym->r = VT_CONST | VT_SYM;
316 put_extern_sym(sym, sec, offset, size);
317 return sym;
320 /* push a reference to a section offset by adding a dummy symbol */
321 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
323 CValue cval;
325 cval.ul = 0;
326 vsetc(type, VT_CONST | VT_SYM, &cval);
327 vtop->sym = get_sym_ref(type, sec, offset, size);
330 /* define a new external reference to a symbol 'v' of type 'u' */
331 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
333 Sym *s;
335 s = sym_find(v);
336 if (!s) {
337 /* push forward reference */
338 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
339 s->type.ref = type->ref;
340 s->r = r | VT_CONST | VT_SYM;
342 return s;
345 /* define a new external reference to a symbol 'v' of type 'u' */
346 static Sym *external_sym(int v, CType *type, int r)
348 Sym *s;
350 s = sym_find(v);
351 if (!s) {
352 /* push forward reference */
353 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
354 s->type.t |= VT_EXTERN;
355 } else if (s->type.ref == func_old_type.ref) {
356 s->type.ref = type->ref;
357 s->r = r | VT_CONST | VT_SYM;
358 s->type.t |= VT_EXTERN;
359 } else if (!is_compatible_types(&s->type, type)) {
360 error("incompatible types for redefinition of '%s'",
361 get_tok_str(v, NULL));
363 return s;
366 /* push a reference to global symbol v */
367 static void vpush_global_sym(CType *type, int v)
369 Sym *sym;
370 CValue cval;
372 sym = external_global_sym(v, type, 0);
373 cval.ul = 0;
374 vsetc(type, VT_CONST | VT_SYM, &cval);
375 vtop->sym = sym;
378 ST_FUNC void vset(CType *type, int r, int v)
380 CValue cval;
382 cval.i = v;
383 vsetc(type, r, &cval);
386 static void vseti(int r, int v)
388 CType type;
389 type.t = VT_INT;
390 type.ref = 0;
391 vset(&type, r, v);
394 ST_FUNC void vswap(void)
396 SValue tmp;
398 tmp = vtop[0];
399 vtop[0] = vtop[-1];
400 vtop[-1] = tmp;
403 ST_FUNC void vpushv(SValue *v)
405 if (vtop >= vstack + (VSTACK_SIZE - 1))
406 error("memory full");
407 vtop++;
408 *vtop = *v;
411 static void vdup(void)
413 vpushv(vtop);
416 /* save r to the memory stack, and mark it as being free */
417 ST_FUNC void save_reg(int r)
419 int l, saved, size, align;
420 SValue *p, sv;
421 CType *type;
423 /* modify all stack values */
424 saved = 0;
425 l = 0;
426 for(p=vstack;p<=vtop;p++) {
427 if ((p->r & VT_VALMASK) == r ||
428 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
429 /* must save value on stack if not already done */
430 if (!saved) {
431 /* NOTE: must reload 'r' because r might be equal to r2 */
432 r = p->r & VT_VALMASK;
433 /* store register in the stack */
434 type = &p->type;
435 if ((p->r & VT_LVAL) ||
436 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
437 #ifdef TCC_TARGET_X86_64
438 type = &char_pointer_type;
439 #else
440 type = &int_type;
441 #endif
442 size = type_size(type, &align);
443 loc = (loc - size) & -align;
444 sv.type.t = type->t;
445 sv.r = VT_LOCAL | VT_LVAL;
446 sv.c.ul = loc;
447 store(r, &sv);
448 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
449 /* x86 specific: need to pop fp register ST0 if saved */
450 if (r == TREG_ST0) {
451 o(0xd8dd); /* fstp %st(0) */
453 #endif
454 #ifndef TCC_TARGET_X86_64
455 /* special long long case */
456 if ((type->t & VT_BTYPE) == VT_LLONG) {
457 sv.c.ul += 4;
458 store(p->r2, &sv);
460 #endif
461 l = loc;
462 saved = 1;
464 /* mark that stack entry as being saved on the stack */
465 if (p->r & VT_LVAL) {
466 /* also clear the bounded flag because the
467 relocation address of the function was stored in
468 p->c.ul */
469 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
470 } else {
471 p->r = lvalue_type(p->type.t) | VT_LOCAL;
473 p->r2 = VT_CONST;
474 p->c.ul = l;
479 #ifdef TCC_TARGET_ARM
480 /* find a register of class 'rc2' with at most one reference on stack.
481 * If none, call get_reg(rc) */
482 ST_FUNC int get_reg_ex(int rc, int rc2)
484 int r;
485 SValue *p;
487 for(r=0;r<NB_REGS;r++) {
488 if (reg_classes[r] & rc2) {
489 int n;
490 n=0;
491 for(p = vstack; p <= vtop; p++) {
492 if ((p->r & VT_VALMASK) == r ||
493 (p->r2 & VT_VALMASK) == r)
494 n++;
496 if (n <= 1)
497 return r;
500 return get_reg(rc);
502 #endif
504 /* find a free register of class 'rc'. If none, save one register */
505 ST_FUNC int get_reg(int rc)
507 int r;
508 SValue *p;
510 /* find a free register */
511 for(r=0;r<NB_REGS;r++) {
512 if (reg_classes[r] & rc) {
513 for(p=vstack;p<=vtop;p++) {
514 if ((p->r & VT_VALMASK) == r ||
515 (p->r2 & VT_VALMASK) == r)
516 goto notfound;
518 return r;
520 notfound: ;
523 /* no register left : free the first one on the stack (VERY
524 IMPORTANT to start from the bottom to ensure that we don't
525 spill registers used in gen_opi()) */
526 for(p=vstack;p<=vtop;p++) {
527 r = p->r & VT_VALMASK;
528 if (r < VT_CONST && (reg_classes[r] & rc))
529 goto save_found;
530 /* also look at second register (if long long) */
531 r = p->r2 & VT_VALMASK;
532 if (r < VT_CONST && (reg_classes[r] & rc)) {
533 save_found:
534 save_reg(r);
535 return r;
538 /* Should never comes here */
539 return -1;
542 /* save registers up to (vtop - n) stack entry */
543 ST_FUNC void save_regs(int n)
545 int r;
546 SValue *p, *p1;
547 p1 = vtop - n;
548 for(p = vstack;p <= p1; p++) {
549 r = p->r & VT_VALMASK;
550 if (r < VT_CONST) {
551 save_reg(r);
556 /* move register 's' to 'r', and flush previous value of r to memory
557 if needed */
558 static void move_reg(int r, int s)
560 SValue sv;
562 if (r != s) {
563 save_reg(r);
564 sv.type.t = VT_INT;
565 sv.r = s;
566 sv.c.ul = 0;
567 load(r, &sv);
571 /* get address of vtop (vtop MUST BE an lvalue) */
572 static void gaddrof(void)
574 vtop->r &= ~VT_LVAL;
575 /* tricky: if saved lvalue, then we can go back to lvalue */
576 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
577 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
580 #ifdef CONFIG_TCC_BCHECK
581 /* generate lvalue bound code */
582 static void gbound(void)
584 int lval_type;
585 CType type1;
587 vtop->r &= ~VT_MUSTBOUND;
588 /* if lvalue, then use checking code before dereferencing */
589 if (vtop->r & VT_LVAL) {
590 /* if not VT_BOUNDED value, then make one */
591 if (!(vtop->r & VT_BOUNDED)) {
592 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
593 /* must save type because we must set it to int to get pointer */
594 type1 = vtop->type;
595 vtop->type.t = VT_INT;
596 gaddrof();
597 vpushi(0);
598 gen_bounded_ptr_add();
599 vtop->r |= lval_type;
600 vtop->type = type1;
602 /* then check for dereferencing */
603 gen_bounded_ptr_deref();
606 #endif
608 /* store vtop a register belonging to class 'rc'. lvalues are
609 converted to values. Cannot be used if cannot be converted to
610 register value (such as structures). */
611 ST_FUNC int gv(int rc)
613 int r, rc2, bit_pos, bit_size, size, align, i;
615 /* NOTE: get_reg can modify vstack[] */
616 if (vtop->type.t & VT_BITFIELD) {
617 CType type;
618 int bits = 32;
619 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
620 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
621 /* remove bit field info to avoid loops */
622 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
623 /* cast to int to propagate signedness in following ops */
624 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
625 type.t = VT_LLONG;
626 bits = 64;
627 } else
628 type.t = VT_INT;
629 if((vtop->type.t & VT_UNSIGNED) ||
630 (vtop->type.t & VT_BTYPE) == VT_BOOL)
631 type.t |= VT_UNSIGNED;
632 gen_cast(&type);
633 /* generate shifts */
634 vpushi(bits - (bit_pos + bit_size));
635 gen_op(TOK_SHL);
636 vpushi(bits - bit_size);
637 /* NOTE: transformed to SHR if unsigned */
638 gen_op(TOK_SAR);
639 r = gv(rc);
640 } else {
641 if (is_float(vtop->type.t) &&
642 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
643 Sym *sym;
644 int *ptr;
645 unsigned long offset;
646 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
647 CValue check;
648 #endif
650 /* XXX: unify with initializers handling ? */
651 /* CPUs usually cannot use float constants, so we store them
652 generically in data segment */
653 size = type_size(&vtop->type, &align);
654 offset = (data_section->data_offset + align - 1) & -align;
655 data_section->data_offset = offset;
656 /* XXX: not portable yet */
657 #if defined(__i386__) || defined(__x86_64__)
658 /* Zero pad x87 tenbyte long doubles */
659 if (size == LDOUBLE_SIZE)
660 vtop->c.tab[2] &= 0xffff;
661 #endif
662 ptr = section_ptr_add(data_section, size);
663 size = size >> 2;
664 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
665 check.d = 1;
666 if(check.tab[0])
667 for(i=0;i<size;i++)
668 ptr[i] = vtop->c.tab[size-1-i];
669 else
670 #endif
671 for(i=0;i<size;i++)
672 ptr[i] = vtop->c.tab[i];
673 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
674 vtop->r |= VT_LVAL | VT_SYM;
675 vtop->sym = sym;
676 vtop->c.ul = 0;
678 #ifdef CONFIG_TCC_BCHECK
679 if (vtop->r & VT_MUSTBOUND)
680 gbound();
681 #endif
683 r = vtop->r & VT_VALMASK;
684 rc2 = RC_INT;
685 if (rc == RC_IRET)
686 rc2 = RC_LRET;
687 /* need to reload if:
688 - constant
689 - lvalue (need to dereference pointer)
690 - already a register, but not in the right class */
691 if (r >= VT_CONST
692 || (vtop->r & VT_LVAL)
693 || !(reg_classes[r] & rc)
694 #ifndef TCC_TARGET_X86_64
695 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
696 #endif
699 r = get_reg(rc);
700 #ifndef TCC_TARGET_X86_64
701 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
702 int r2;
703 unsigned long long ll;
704 /* two register type load : expand to two words
705 temporarily */
706 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
707 /* load constant */
708 ll = vtop->c.ull;
709 vtop->c.ui = ll; /* first word */
710 load(r, vtop);
711 vtop->r = r; /* save register value */
712 vpushi(ll >> 32); /* second word */
713 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
714 (vtop->r & VT_LVAL)) {
715 /* We do not want to modifier the long long
716 pointer here, so the safest (and less
717 efficient) is to save all the other registers
718 in the stack. XXX: totally inefficient. */
719 save_regs(1);
720 /* load from memory */
721 load(r, vtop);
722 vdup();
723 vtop[-1].r = r; /* save register value */
724 /* increment pointer to get second word */
725 vtop->type.t = VT_INT;
726 gaddrof();
727 vpushi(4);
728 gen_op('+');
729 vtop->r |= VT_LVAL;
730 } else {
731 /* move registers */
732 load(r, vtop);
733 vdup();
734 vtop[-1].r = r; /* save register value */
735 vtop->r = vtop[-1].r2;
737 /* allocate second register */
738 r2 = get_reg(rc2);
739 load(r2, vtop);
740 vpop();
741 /* write second register */
742 vtop->r2 = r2;
743 } else
744 #endif
745 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
746 int t1, t;
747 /* lvalue of scalar type : need to use lvalue type
748 because of possible cast */
749 t = vtop->type.t;
750 t1 = t;
751 /* compute memory access type */
752 if (vtop->r & VT_LVAL_BYTE)
753 t = VT_BYTE;
754 else if (vtop->r & VT_LVAL_SHORT)
755 t = VT_SHORT;
756 if (vtop->r & VT_LVAL_UNSIGNED)
757 t |= VT_UNSIGNED;
758 vtop->type.t = t;
759 load(r, vtop);
760 /* restore wanted type */
761 vtop->type.t = t1;
762 } else {
763 /* one register type load */
764 load(r, vtop);
767 vtop->r = r;
768 #ifdef TCC_TARGET_C67
769 /* uses register pairs for doubles */
770 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
771 vtop->r2 = r+1;
772 #endif
774 return r;
777 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
778 ST_FUNC void gv2(int rc1, int rc2)
780 int v;
782 /* generate more generic register first. But VT_JMP or VT_CMP
783 values must be generated first in all cases to avoid possible
784 reload errors */
785 v = vtop[0].r & VT_VALMASK;
786 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
787 vswap();
788 gv(rc1);
789 vswap();
790 gv(rc2);
791 /* test if reload is needed for first register */
792 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
793 vswap();
794 gv(rc1);
795 vswap();
797 } else {
798 gv(rc2);
799 vswap();
800 gv(rc1);
801 vswap();
802 /* test if reload is needed for first register */
803 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
804 gv(rc2);
809 /* wrapper around RC_FRET to return a register by type */
810 static int rc_fret(int t)
812 #ifdef TCC_TARGET_X86_64
813 if (t == VT_LDOUBLE) {
814 return RC_ST0;
816 #endif
817 return RC_FRET;
820 /* wrapper around REG_FRET to return a register by type */
821 static int reg_fret(int t)
823 #ifdef TCC_TARGET_X86_64
824 if (t == VT_LDOUBLE) {
825 return TREG_ST0;
827 #endif
828 return REG_FRET;
831 /* expand long long on stack in two int registers */
832 static void lexpand(void)
834 int u;
836 u = vtop->type.t & VT_UNSIGNED;
837 gv(RC_INT);
838 vdup();
839 vtop[0].r = vtop[-1].r2;
840 vtop[0].r2 = VT_CONST;
841 vtop[-1].r2 = VT_CONST;
842 vtop[0].type.t = VT_INT | u;
843 vtop[-1].type.t = VT_INT | u;
846 #ifdef TCC_TARGET_ARM
847 /* expand long long on stack */
848 ST_FUNC void lexpand_nr(void)
850 int u,v;
852 u = vtop->type.t & VT_UNSIGNED;
853 vdup();
854 vtop->r2 = VT_CONST;
855 vtop->type.t = VT_INT | u;
856 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
857 if (v == VT_CONST) {
858 vtop[-1].c.ui = vtop->c.ull;
859 vtop->c.ui = vtop->c.ull >> 32;
860 vtop->r = VT_CONST;
861 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
862 vtop->c.ui += 4;
863 vtop->r = vtop[-1].r;
864 } else if (v > VT_CONST) {
865 vtop--;
866 lexpand();
867 } else
868 vtop->r = vtop[-1].r2;
869 vtop[-1].r2 = VT_CONST;
870 vtop[-1].type.t = VT_INT | u;
872 #endif
874 /* build a long long from two ints */
875 static void lbuild(int t)
877 gv2(RC_INT, RC_INT);
878 vtop[-1].r2 = vtop[0].r;
879 vtop[-1].type.t = t;
880 vpop();
883 /* rotate n first stack elements to the bottom
884 I1 ... In -> I2 ... In I1 [top is right]
886 static void vrotb(int n)
888 int i;
889 SValue tmp;
891 tmp = vtop[-n + 1];
892 for(i=-n+1;i!=0;i++)
893 vtop[i] = vtop[i+1];
894 vtop[0] = tmp;
897 /* rotate n first stack elements to the top
898 I1 ... In -> In I1 ... I(n-1) [top is right]
900 static void vrott(int n)
902 int i;
903 SValue tmp;
905 tmp = vtop[0];
906 for(i = 0;i < n - 1; i++)
907 vtop[-i] = vtop[-i - 1];
908 vtop[-n + 1] = tmp;
911 #ifdef TCC_TARGET_ARM
912 /* like vrott but in other direction
913 In ... I1 -> I(n-1) ... I1 In [top is right]
915 void vnrott(int n)
917 int i;
918 SValue tmp;
920 tmp = vtop[-n + 1];
921 for(i = n - 1; i > 0; i--)
922 vtop[-i] = vtop[-i + 1];
923 vtop[0] = tmp;
925 #endif
927 /* pop stack value */
928 ST_FUNC void vpop(void)
930 int v;
931 v = vtop->r & VT_VALMASK;
932 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
933 /* for x86, we need to pop the FP stack */
934 if (v == TREG_ST0 && !nocode_wanted) {
935 o(0xd8dd); /* fstp %st(0) */
936 } else
937 #endif
938 if (v == VT_JMP || v == VT_JMPI) {
939 /* need to put correct jump if && or || without test */
940 gsym(vtop->c.ul);
942 vtop--;
945 /* convert stack entry to register and duplicate its value in another
946 register */
947 static void gv_dup(void)
949 int rc, t, r, r1;
950 SValue sv;
952 t = vtop->type.t;
953 if ((t & VT_BTYPE) == VT_LLONG) {
954 lexpand();
955 gv_dup();
956 vswap();
957 vrotb(3);
958 gv_dup();
959 vrotb(4);
960 /* stack: H L L1 H1 */
961 lbuild(t);
962 vrotb(3);
963 vrotb(3);
964 vswap();
965 lbuild(t);
966 vswap();
967 } else {
968 /* duplicate value */
969 rc = RC_INT;
970 sv.type.t = VT_INT;
971 if (is_float(t)) {
972 rc = RC_FLOAT;
973 #ifdef TCC_TARGET_X86_64
974 if ((t & VT_BTYPE) == VT_LDOUBLE) {
975 rc = RC_ST0;
977 #endif
978 sv.type.t = t;
980 r = gv(rc);
981 r1 = get_reg(rc);
982 sv.r = r;
983 sv.c.ul = 0;
984 load(r1, &sv); /* move r to r1 */
985 vdup();
986 /* duplicates value */
987 if (r != r1)
988 vtop->r = r1;
992 #ifndef TCC_TARGET_X86_64
993 /* generate CPU independent (unsigned) long long operations */
994 static void gen_opl(int op)
996 int t, a, b, op1, c, i;
997 int func;
998 unsigned short reg_iret = REG_IRET;
999 unsigned short reg_lret = REG_LRET;
1000 SValue tmp;
1002 switch(op) {
1003 case '/':
1004 case TOK_PDIV:
1005 func = TOK___divdi3;
1006 goto gen_func;
1007 case TOK_UDIV:
1008 func = TOK___udivdi3;
1009 goto gen_func;
1010 case '%':
1011 func = TOK___moddi3;
1012 goto gen_mod_func;
1013 case TOK_UMOD:
1014 func = TOK___umoddi3;
1015 gen_mod_func:
1016 #ifdef TCC_ARM_EABI
1017 reg_iret = TREG_R2;
1018 reg_lret = TREG_R3;
1019 #endif
1020 gen_func:
1021 /* call generic long long function */
1022 vpush_global_sym(&func_old_type, func);
1023 vrott(3);
1024 gfunc_call(2);
1025 vpushi(0);
1026 vtop->r = reg_iret;
1027 vtop->r2 = reg_lret;
1028 break;
1029 case '^':
1030 case '&':
1031 case '|':
1032 case '*':
1033 case '+':
1034 case '-':
1035 t = vtop->type.t;
1036 vswap();
1037 lexpand();
1038 vrotb(3);
1039 lexpand();
1040 /* stack: L1 H1 L2 H2 */
1041 tmp = vtop[0];
1042 vtop[0] = vtop[-3];
1043 vtop[-3] = tmp;
1044 tmp = vtop[-2];
1045 vtop[-2] = vtop[-3];
1046 vtop[-3] = tmp;
1047 vswap();
1048 /* stack: H1 H2 L1 L2 */
1049 if (op == '*') {
1050 vpushv(vtop - 1);
1051 vpushv(vtop - 1);
1052 gen_op(TOK_UMULL);
1053 lexpand();
1054 /* stack: H1 H2 L1 L2 ML MH */
1055 for(i=0;i<4;i++)
1056 vrotb(6);
1057 /* stack: ML MH H1 H2 L1 L2 */
1058 tmp = vtop[0];
1059 vtop[0] = vtop[-2];
1060 vtop[-2] = tmp;
1061 /* stack: ML MH H1 L2 H2 L1 */
1062 gen_op('*');
1063 vrotb(3);
1064 vrotb(3);
1065 gen_op('*');
1066 /* stack: ML MH M1 M2 */
1067 gen_op('+');
1068 gen_op('+');
1069 } else if (op == '+' || op == '-') {
1070 /* XXX: add non carry method too (for MIPS or alpha) */
1071 if (op == '+')
1072 op1 = TOK_ADDC1;
1073 else
1074 op1 = TOK_SUBC1;
1075 gen_op(op1);
1076 /* stack: H1 H2 (L1 op L2) */
1077 vrotb(3);
1078 vrotb(3);
1079 gen_op(op1 + 1); /* TOK_xxxC2 */
1080 } else {
1081 gen_op(op);
1082 /* stack: H1 H2 (L1 op L2) */
1083 vrotb(3);
1084 vrotb(3);
1085 /* stack: (L1 op L2) H1 H2 */
1086 gen_op(op);
1087 /* stack: (L1 op L2) (H1 op H2) */
1089 /* stack: L H */
1090 lbuild(t);
1091 break;
1092 case TOK_SAR:
1093 case TOK_SHR:
1094 case TOK_SHL:
1095 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1096 t = vtop[-1].type.t;
1097 vswap();
1098 lexpand();
1099 vrotb(3);
1100 /* stack: L H shift */
1101 c = (int)vtop->c.i;
1102 /* constant: simpler */
1103 /* NOTE: all comments are for SHL. the other cases are
1104 done by swaping words */
1105 vpop();
1106 if (op != TOK_SHL)
1107 vswap();
1108 if (c >= 32) {
1109 /* stack: L H */
1110 vpop();
1111 if (c > 32) {
1112 vpushi(c - 32);
1113 gen_op(op);
1115 if (op != TOK_SAR) {
1116 vpushi(0);
1117 } else {
1118 gv_dup();
1119 vpushi(31);
1120 gen_op(TOK_SAR);
1122 vswap();
1123 } else {
1124 vswap();
1125 gv_dup();
1126 /* stack: H L L */
1127 vpushi(c);
1128 gen_op(op);
1129 vswap();
1130 vpushi(32 - c);
1131 if (op == TOK_SHL)
1132 gen_op(TOK_SHR);
1133 else
1134 gen_op(TOK_SHL);
1135 vrotb(3);
1136 /* stack: L L H */
1137 vpushi(c);
1138 if (op == TOK_SHL)
1139 gen_op(TOK_SHL);
1140 else
1141 gen_op(TOK_SHR);
1142 gen_op('|');
1144 if (op != TOK_SHL)
1145 vswap();
1146 lbuild(t);
1147 } else {
1148 /* XXX: should provide a faster fallback on x86 ? */
1149 switch(op) {
1150 case TOK_SAR:
1151 func = TOK___ashrdi3;
1152 goto gen_func;
1153 case TOK_SHR:
1154 func = TOK___lshrdi3;
1155 goto gen_func;
1156 case TOK_SHL:
1157 func = TOK___ashldi3;
1158 goto gen_func;
1161 break;
1162 default:
1163 /* compare operations */
1164 t = vtop->type.t;
1165 vswap();
1166 lexpand();
1167 vrotb(3);
1168 lexpand();
1169 /* stack: L1 H1 L2 H2 */
1170 tmp = vtop[-1];
1171 vtop[-1] = vtop[-2];
1172 vtop[-2] = tmp;
1173 /* stack: L1 L2 H1 H2 */
1174 /* compare high */
1175 op1 = op;
1176 /* when values are equal, we need to compare low words. since
1177 the jump is inverted, we invert the test too. */
1178 if (op1 == TOK_LT)
1179 op1 = TOK_LE;
1180 else if (op1 == TOK_GT)
1181 op1 = TOK_GE;
1182 else if (op1 == TOK_ULT)
1183 op1 = TOK_ULE;
1184 else if (op1 == TOK_UGT)
1185 op1 = TOK_UGE;
1186 a = 0;
1187 b = 0;
1188 gen_op(op1);
1189 if (op1 != TOK_NE) {
1190 a = gtst(1, 0);
1192 if (op != TOK_EQ) {
1193 /* generate non equal test */
1194 /* XXX: NOT PORTABLE yet */
1195 if (a == 0) {
1196 b = gtst(0, 0);
1197 } else {
1198 #if defined(TCC_TARGET_I386)
1199 b = psym(0x850f, 0);
1200 #elif defined(TCC_TARGET_ARM)
1201 b = ind;
1202 o(0x1A000000 | encbranch(ind, 0, 1));
1203 #elif defined(TCC_TARGET_C67)
1204 error("not implemented");
1205 #else
1206 #error not supported
1207 #endif
1210 /* compare low. Always unsigned */
1211 op1 = op;
1212 if (op1 == TOK_LT)
1213 op1 = TOK_ULT;
1214 else if (op1 == TOK_LE)
1215 op1 = TOK_ULE;
1216 else if (op1 == TOK_GT)
1217 op1 = TOK_UGT;
1218 else if (op1 == TOK_GE)
1219 op1 = TOK_UGE;
1220 gen_op(op1);
1221 a = gtst(1, a);
1222 gsym(b);
1223 vseti(VT_JMPI, a);
1224 break;
1227 #endif
1229 /* handle integer constant optimizations and various machine
1230 independent opt */
1231 static void gen_opic(int op)
1233 int c1, c2, t1, t2, n;
1234 SValue *v1, *v2;
1235 long long l1, l2;
1236 typedef unsigned long long U;
1238 v1 = vtop - 1;
1239 v2 = vtop;
1240 t1 = v1->type.t & VT_BTYPE;
1241 t2 = v2->type.t & VT_BTYPE;
1243 if (t1 == VT_LLONG)
1244 l1 = v1->c.ll;
1245 else if (v1->type.t & VT_UNSIGNED)
1246 l1 = v1->c.ui;
1247 else
1248 l1 = v1->c.i;
1250 if (t2 == VT_LLONG)
1251 l2 = v2->c.ll;
1252 else if (v2->type.t & VT_UNSIGNED)
1253 l2 = v2->c.ui;
1254 else
1255 l2 = v2->c.i;
1257 /* currently, we cannot do computations with forward symbols */
1258 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1259 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1260 if (c1 && c2) {
1261 switch(op) {
1262 case '+': l1 += l2; break;
1263 case '-': l1 -= l2; break;
1264 case '&': l1 &= l2; break;
1265 case '^': l1 ^= l2; break;
1266 case '|': l1 |= l2; break;
1267 case '*': l1 *= l2; break;
1269 case TOK_PDIV:
1270 case '/':
1271 case '%':
1272 case TOK_UDIV:
1273 case TOK_UMOD:
1274 /* if division by zero, generate explicit division */
1275 if (l2 == 0) {
1276 if (const_wanted)
1277 error("division by zero in constant");
1278 goto general_case;
1280 switch(op) {
1281 default: l1 /= l2; break;
1282 case '%': l1 %= l2; break;
1283 case TOK_UDIV: l1 = (U)l1 / l2; break;
1284 case TOK_UMOD: l1 = (U)l1 % l2; break;
1286 break;
1287 case TOK_SHL: l1 <<= l2; break;
1288 case TOK_SHR: l1 = (U)l1 >> l2; break;
1289 case TOK_SAR: l1 >>= l2; break;
1290 /* tests */
1291 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1292 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1293 case TOK_EQ: l1 = l1 == l2; break;
1294 case TOK_NE: l1 = l1 != l2; break;
1295 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1296 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1297 case TOK_LT: l1 = l1 < l2; break;
1298 case TOK_GE: l1 = l1 >= l2; break;
1299 case TOK_LE: l1 = l1 <= l2; break;
1300 case TOK_GT: l1 = l1 > l2; break;
1301 /* logical */
1302 case TOK_LAND: l1 = l1 && l2; break;
1303 case TOK_LOR: l1 = l1 || l2; break;
1304 default:
1305 goto general_case;
1307 v1->c.ll = l1;
1308 vtop--;
1309 } else {
1310 /* if commutative ops, put c2 as constant */
1311 if (c1 && (op == '+' || op == '&' || op == '^' ||
1312 op == '|' || op == '*')) {
1313 vswap();
1314 c2 = c1; //c = c1, c1 = c2, c2 = c;
1315 l2 = l1; //l = l1, l1 = l2, l2 = l;
1317 /* Filter out NOP operations like x*1, x-0, x&-1... */
1318 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1319 op == TOK_PDIV) &&
1320 l2 == 1) ||
1321 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1322 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1323 l2 == 0) ||
1324 (op == '&' &&
1325 l2 == -1))) {
1326 /* nothing to do */
1327 vtop--;
1328 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1329 /* try to use shifts instead of muls or divs */
1330 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1331 n = -1;
1332 while (l2) {
1333 l2 >>= 1;
1334 n++;
1336 vtop->c.ll = n;
1337 if (op == '*')
1338 op = TOK_SHL;
1339 else if (op == TOK_PDIV)
1340 op = TOK_SAR;
1341 else
1342 op = TOK_SHR;
1344 goto general_case;
1345 } else if (c2 && (op == '+' || op == '-') &&
1346 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM)
1347 && !(vtop[-1].sym->type.t & VT_IMPORT))
1349 (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1350 /* symbol + constant case */
1351 if (op == '-')
1352 l2 = -l2;
1353 vtop--;
1354 vtop->c.ll += l2;
1355 } else {
1356 general_case:
1357 if (!nocode_wanted) {
1358 /* call low level op generator */
1359 if (t1 == VT_LLONG || t2 == VT_LLONG)
1360 gen_opl(op);
1361 else
1362 gen_opi(op);
1363 } else {
1364 vtop--;
1370 /* generate a floating point operation with constant propagation */
1371 static void gen_opif(int op)
1373 int c1, c2;
1374 SValue *v1, *v2;
1375 long double f1, f2;
1377 v1 = vtop - 1;
1378 v2 = vtop;
1379 /* currently, we cannot do computations with forward symbols */
1380 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1381 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1382 if (c1 && c2) {
1383 if (v1->type.t == VT_FLOAT) {
1384 f1 = v1->c.f;
1385 f2 = v2->c.f;
1386 } else if (v1->type.t == VT_DOUBLE) {
1387 f1 = v1->c.d;
1388 f2 = v2->c.d;
1389 } else {
1390 f1 = v1->c.ld;
1391 f2 = v2->c.ld;
1394 /* NOTE: we only do constant propagation if finite number (not
1395 NaN or infinity) (ANSI spec) */
1396 if (!ieee_finite(f1) || !ieee_finite(f2))
1397 goto general_case;
1399 switch(op) {
1400 case '+': f1 += f2; break;
1401 case '-': f1 -= f2; break;
1402 case '*': f1 *= f2; break;
1403 case '/':
1404 if (f2 == 0.0) {
1405 if (const_wanted)
1406 error("division by zero in constant");
1407 goto general_case;
1409 f1 /= f2;
1410 break;
1411 /* XXX: also handles tests ? */
1412 default:
1413 goto general_case;
1415 /* XXX: overflow test ? */
1416 if (v1->type.t == VT_FLOAT) {
1417 v1->c.f = f1;
1418 } else if (v1->type.t == VT_DOUBLE) {
1419 v1->c.d = f1;
1420 } else {
1421 v1->c.ld = f1;
1423 vtop--;
1424 } else {
1425 general_case:
1426 if (!nocode_wanted) {
1427 gen_opf(op);
1428 } else {
1429 vtop--;
1434 static int pointed_size(CType *type)
1436 int align;
1437 return type_size(pointed_type(type), &align);
1440 static inline int is_null_pointer(SValue *p)
1442 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1443 return 0;
1444 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1445 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1448 static inline int is_integer_btype(int bt)
1450 return (bt == VT_BYTE || bt == VT_SHORT ||
1451 bt == VT_INT || bt == VT_LLONG);
1454 /* check types for comparison or substraction of pointers */
1455 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1457 CType *type1, *type2, tmp_type1, tmp_type2;
1458 int bt1, bt2;
1460 /* null pointers are accepted for all comparisons as gcc */
1461 if (is_null_pointer(p1) || is_null_pointer(p2))
1462 return;
1463 type1 = &p1->type;
1464 type2 = &p2->type;
1465 bt1 = type1->t & VT_BTYPE;
1466 bt2 = type2->t & VT_BTYPE;
1467 /* accept comparison between pointer and integer with a warning */
1468 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1469 if (op != TOK_LOR && op != TOK_LAND )
1470 warning("comparison between pointer and integer");
1471 return;
1474 /* both must be pointers or implicit function pointers */
1475 if (bt1 == VT_PTR) {
1476 type1 = pointed_type(type1);
1477 } else if (bt1 != VT_FUNC)
1478 goto invalid_operands;
1480 if (bt2 == VT_PTR) {
1481 type2 = pointed_type(type2);
1482 } else if (bt2 != VT_FUNC) {
1483 invalid_operands:
1484 error("invalid operands to binary %s", get_tok_str(op, NULL));
1486 if ((type1->t & VT_BTYPE) == VT_VOID ||
1487 (type2->t & VT_BTYPE) == VT_VOID)
1488 return;
1489 tmp_type1 = *type1;
1490 tmp_type2 = *type2;
1491 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1492 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1493 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1494 /* gcc-like error if '-' is used */
1495 if (op == '-')
1496 goto invalid_operands;
1497 else
1498 warning("comparison of distinct pointer types lacks a cast");
1502 /* generic gen_op: handles types problems */
1503 ST_FUNC void gen_op(int op)
1505 int u, t1, t2, bt1, bt2, t;
1506 CType type1;
1508 t1 = vtop[-1].type.t;
1509 t2 = vtop[0].type.t;
1510 bt1 = t1 & VT_BTYPE;
1511 bt2 = t2 & VT_BTYPE;
1513 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1514 /* at least one operand is a pointer */
1515 /* relationnal op: must be both pointers */
1516 if (op >= TOK_ULT && op <= TOK_LOR) {
1517 check_comparison_pointer_types(vtop - 1, vtop, op);
1518 /* pointers are handled are unsigned */
1519 #ifdef TCC_TARGET_X86_64
1520 t = VT_LLONG | VT_UNSIGNED;
1521 #else
1522 t = VT_INT | VT_UNSIGNED;
1523 #endif
1524 goto std_op;
1526 /* if both pointers, then it must be the '-' op */
1527 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1528 if (op != '-')
1529 error("cannot use pointers here");
1530 check_comparison_pointer_types(vtop - 1, vtop, op);
1531 /* XXX: check that types are compatible */
1532 u = pointed_size(&vtop[-1].type);
1533 gen_opic(op);
1534 /* set to integer type */
1535 #ifdef TCC_TARGET_X86_64
1536 vtop->type.t = VT_LLONG;
1537 #else
1538 vtop->type.t = VT_INT;
1539 #endif
1540 vpushi(u);
1541 gen_op(TOK_PDIV);
1542 } else {
1543 /* exactly one pointer : must be '+' or '-'. */
1544 if (op != '-' && op != '+')
1545 error("cannot use pointers here");
1546 /* Put pointer as first operand */
1547 if (bt2 == VT_PTR) {
1548 vswap();
1549 swap(&t1, &t2);
1551 type1 = vtop[-1].type;
1552 type1.t &= ~VT_ARRAY;
1553 #ifdef TCC_TARGET_X86_64
1554 vpushll(pointed_size(&vtop[-1].type));
1555 #else
1556 /* XXX: cast to int ? (long long case) */
1557 vpushi(pointed_size(&vtop[-1].type));
1558 #endif
1559 gen_op('*');
1560 #ifdef CONFIG_TCC_BCHECK
1561 /* if evaluating constant expression, no code should be
1562 generated, so no bound check */
1563 if (tcc_state->do_bounds_check && !const_wanted) {
1564 /* if bounded pointers, we generate a special code to
1565 test bounds */
1566 if (op == '-') {
1567 vpushi(0);
1568 vswap();
1569 gen_op('-');
1571 gen_bounded_ptr_add();
1572 } else
1573 #endif
1575 gen_opic(op);
1577 /* put again type if gen_opic() swaped operands */
1578 vtop->type = type1;
1580 } else if (is_float(bt1) || is_float(bt2)) {
1581 /* compute bigger type and do implicit casts */
1582 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1583 t = VT_LDOUBLE;
1584 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1585 t = VT_DOUBLE;
1586 } else {
1587 t = VT_FLOAT;
1589 /* floats can only be used for a few operations */
1590 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1591 (op < TOK_ULT || op > TOK_GT))
1592 error("invalid operands for binary operation");
1593 goto std_op;
1594 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1595 /* cast to biggest op */
1596 t = VT_LLONG;
1597 /* convert to unsigned if it does not fit in a long long */
1598 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1599 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1600 t |= VT_UNSIGNED;
1601 goto std_op;
1602 } else {
1603 /* integer operations */
1604 t = VT_INT;
1605 /* convert to unsigned if it does not fit in an integer */
1606 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1607 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1608 t |= VT_UNSIGNED;
1609 std_op:
1610 /* XXX: currently, some unsigned operations are explicit, so
1611 we modify them here */
1612 if (t & VT_UNSIGNED) {
1613 if (op == TOK_SAR)
1614 op = TOK_SHR;
1615 else if (op == '/')
1616 op = TOK_UDIV;
1617 else if (op == '%')
1618 op = TOK_UMOD;
1619 else if (op == TOK_LT)
1620 op = TOK_ULT;
1621 else if (op == TOK_GT)
1622 op = TOK_UGT;
1623 else if (op == TOK_LE)
1624 op = TOK_ULE;
1625 else if (op == TOK_GE)
1626 op = TOK_UGE;
1628 vswap();
1629 type1.t = t;
1630 gen_cast(&type1);
1631 vswap();
1632 /* special case for shifts and long long: we keep the shift as
1633 an integer */
1634 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1635 type1.t = VT_INT;
1636 gen_cast(&type1);
1637 if (is_float(t))
1638 gen_opif(op);
1639 else
1640 gen_opic(op);
1641 if (op >= TOK_ULT && op <= TOK_GT) {
1642 /* relationnal op: the result is an int */
1643 vtop->type.t = VT_INT;
1644 } else {
1645 vtop->type.t = t;
1650 #ifndef TCC_TARGET_ARM
1651 /* generic itof for unsigned long long case */
1652 static void gen_cvt_itof1(int t)
1654 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1655 (VT_LLONG | VT_UNSIGNED)) {
1657 if (t == VT_FLOAT)
1658 vpush_global_sym(&func_old_type, TOK___floatundisf);
1659 #if LDOUBLE_SIZE != 8
1660 else if (t == VT_LDOUBLE)
1661 vpush_global_sym(&func_old_type, TOK___floatundixf);
1662 #endif
1663 else
1664 vpush_global_sym(&func_old_type, TOK___floatundidf);
1665 vrott(2);
1666 gfunc_call(1);
1667 vpushi(0);
1668 vtop->r = reg_fret(t);
1669 } else {
1670 gen_cvt_itof(t);
1673 #endif
1675 /* generic ftoi for unsigned long long case */
1676 static void gen_cvt_ftoi1(int t)
1678 int st;
1680 if (t == (VT_LLONG | VT_UNSIGNED)) {
1681 /* not handled natively */
1682 st = vtop->type.t & VT_BTYPE;
1683 if (st == VT_FLOAT)
1684 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1685 #if LDOUBLE_SIZE != 8
1686 else if (st == VT_LDOUBLE)
1687 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1688 #endif
1689 else
1690 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1691 vrott(2);
1692 gfunc_call(1);
1693 vpushi(0);
1694 vtop->r = REG_IRET;
1695 vtop->r2 = REG_LRET;
1696 } else {
1697 gen_cvt_ftoi(t);
1701 /* force char or short cast */
1702 static void force_charshort_cast(int t)
1704 int bits, dbt;
1705 dbt = t & VT_BTYPE;
1706 /* XXX: add optimization if lvalue : just change type and offset */
1707 if (dbt == VT_BYTE)
1708 bits = 8;
1709 else
1710 bits = 16;
1711 if (t & VT_UNSIGNED) {
1712 vpushi((1 << bits) - 1);
1713 gen_op('&');
1714 } else {
1715 bits = 32 - bits;
1716 vpushi(bits);
1717 gen_op(TOK_SHL);
1718 /* result must be signed or the SAR is converted to an SHL
1719 This was not the case when "t" was a signed short
1720 and the last value on the stack was an unsigned int */
1721 vtop->type.t &= ~VT_UNSIGNED;
1722 vpushi(bits);
1723 gen_op(TOK_SAR);
1727 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1728 static void gen_cast(CType *type)
1730 int sbt, dbt, sf, df, c, p;
1732 /* special delayed cast for char/short */
1733 /* XXX: in some cases (multiple cascaded casts), it may still
1734 be incorrect */
1735 if (vtop->r & VT_MUSTCAST) {
1736 vtop->r &= ~VT_MUSTCAST;
1737 force_charshort_cast(vtop->type.t);
1740 /* bitfields first get cast to ints */
1741 if (vtop->type.t & VT_BITFIELD) {
1742 gv(RC_INT);
1745 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1746 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1748 if (sbt != dbt) {
1749 sf = is_float(sbt);
1750 df = is_float(dbt);
1751 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1752 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1753 if (c) {
1754 /* constant case: we can do it now */
1755 /* XXX: in ISOC, cannot do it if error in convert */
1756 if (sbt == VT_FLOAT)
1757 vtop->c.ld = vtop->c.f;
1758 else if (sbt == VT_DOUBLE)
1759 vtop->c.ld = vtop->c.d;
1761 if (df) {
1762 if ((sbt & VT_BTYPE) == VT_LLONG) {
1763 if (sbt & VT_UNSIGNED)
1764 vtop->c.ld = vtop->c.ull;
1765 else
1766 vtop->c.ld = vtop->c.ll;
1767 } else if(!sf) {
1768 if (sbt & VT_UNSIGNED)
1769 vtop->c.ld = vtop->c.ui;
1770 else
1771 vtop->c.ld = vtop->c.i;
1774 if (dbt == VT_FLOAT)
1775 vtop->c.f = (float)vtop->c.ld;
1776 else if (dbt == VT_DOUBLE)
1777 vtop->c.d = (double)vtop->c.ld;
1778 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1779 vtop->c.ull = (unsigned long long)vtop->c.ld;
1780 } else if (sf && dbt == VT_BOOL) {
1781 vtop->c.i = (vtop->c.ld != 0);
1782 } else {
1783 if(sf)
1784 vtop->c.ll = (long long)vtop->c.ld;
1785 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1786 vtop->c.ll = vtop->c.ull;
1787 else if (sbt & VT_UNSIGNED)
1788 vtop->c.ll = vtop->c.ui;
1789 #ifdef TCC_TARGET_X86_64
1790 else if (sbt == VT_PTR)
1792 #endif
1793 else if (sbt != VT_LLONG)
1794 vtop->c.ll = vtop->c.i;
1796 if (dbt == (VT_LLONG|VT_UNSIGNED))
1797 vtop->c.ull = vtop->c.ll;
1798 else if (dbt == VT_BOOL)
1799 vtop->c.i = (vtop->c.ll != 0);
1800 else if (dbt != VT_LLONG) {
1801 int s = 0;
1802 if ((dbt & VT_BTYPE) == VT_BYTE)
1803 s = 24;
1804 else if ((dbt & VT_BTYPE) == VT_SHORT)
1805 s = 16;
1807 if(dbt & VT_UNSIGNED)
1808 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1809 else
1810 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1813 } else if (p && dbt == VT_BOOL) {
1814 vtop->r = VT_CONST;
1815 vtop->c.i = 1;
1816 } else if (!nocode_wanted) {
1817 /* non constant case: generate code */
1818 if (sf && df) {
1819 /* convert from fp to fp */
1820 gen_cvt_ftof(dbt);
1821 } else if (df) {
1822 /* convert int to fp */
1823 gen_cvt_itof1(dbt);
1824 } else if (sf) {
1825 /* convert fp to int */
1826 if (dbt == VT_BOOL) {
1827 vpushi(0);
1828 gen_op(TOK_NE);
1829 } else {
1830 /* we handle char/short/etc... with generic code */
1831 if (dbt != (VT_INT | VT_UNSIGNED) &&
1832 dbt != (VT_LLONG | VT_UNSIGNED) &&
1833 dbt != VT_LLONG)
1834 dbt = VT_INT;
1835 gen_cvt_ftoi1(dbt);
1836 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1837 /* additional cast for char/short... */
1838 vtop->type.t = dbt;
1839 gen_cast(type);
1842 #ifndef TCC_TARGET_X86_64
1843 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1844 if ((sbt & VT_BTYPE) != VT_LLONG) {
1845 /* scalar to long long */
1846 /* machine independent conversion */
1847 gv(RC_INT);
1848 /* generate high word */
1849 if (sbt == (VT_INT | VT_UNSIGNED)) {
1850 vpushi(0);
1851 gv(RC_INT);
1852 } else {
1853 if (sbt == VT_PTR) {
1854 /* cast from pointer to int before we apply
1855 shift operation, which pointers don't support*/
1856 gen_cast(&int_type);
1858 gv_dup();
1859 vpushi(31);
1860 gen_op(TOK_SAR);
1862 /* patch second register */
1863 vtop[-1].r2 = vtop->r;
1864 vpop();
1866 #else
1867 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1868 (dbt & VT_BTYPE) == VT_PTR) {
1869 /* XXX: not sure if this is perfect... need more tests */
1870 if ((sbt & VT_BTYPE) != VT_LLONG) {
1871 int r = gv(RC_INT);
1872 if (sbt != (VT_INT | VT_UNSIGNED) &&
1873 sbt != VT_PTR && sbt != VT_FUNC) {
1874 /* x86_64 specific: movslq */
1875 o(0x6348);
1876 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1879 #endif
1880 } else if (dbt == VT_BOOL) {
1881 /* scalar to bool */
1882 vpushi(0);
1883 gen_op(TOK_NE);
1884 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1885 (dbt & VT_BTYPE) == VT_SHORT) {
1886 if (sbt == VT_PTR) {
1887 vtop->type.t = VT_INT;
1888 warning("nonportable conversion from pointer to char/short");
1890 force_charshort_cast(dbt);
1891 } else if ((dbt & VT_BTYPE) == VT_INT) {
1892 /* scalar to int */
1893 if (sbt == VT_LLONG) {
1894 /* from long long: just take low order word */
1895 lexpand();
1896 vpop();
1898 /* if lvalue and single word type, nothing to do because
1899 the lvalue already contains the real type size (see
1900 VT_LVAL_xxx constants) */
1903 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1904 /* if we are casting between pointer types,
1905 we must update the VT_LVAL_xxx size */
1906 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1907 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1909 vtop->type = *type;
1912 /* return type size. Put alignment at 'a' */
1913 ST_FUNC int type_size(CType *type, int *a)
1915 Sym *s;
1916 int bt;
1918 bt = type->t & VT_BTYPE;
1919 if (bt == VT_STRUCT) {
1920 /* struct/union */
1921 s = type->ref;
1922 *a = s->r;
1923 return s->c;
1924 } else if (bt == VT_PTR) {
1925 if (type->t & VT_ARRAY) {
1926 int ts;
1928 s = type->ref;
1929 ts = type_size(&s->type, a);
1931 if (ts < 0 && s->c < 0)
1932 ts = -ts;
1934 return ts * s->c;
1935 } else {
1936 *a = PTR_SIZE;
1937 return PTR_SIZE;
1939 } else if (bt == VT_LDOUBLE) {
1940 *a = LDOUBLE_ALIGN;
1941 return LDOUBLE_SIZE;
1942 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
1943 #ifdef TCC_TARGET_I386
1944 #ifdef TCC_TARGET_PE
1945 *a = 8;
1946 #else
1947 *a = 4;
1948 #endif
1949 #elif defined(TCC_TARGET_ARM)
1950 #ifdef TCC_ARM_EABI
1951 *a = 8;
1952 #else
1953 *a = 4;
1954 #endif
1955 #else
1956 *a = 8;
1957 #endif
1958 return 8;
1959 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
1960 *a = 4;
1961 return 4;
1962 } else if (bt == VT_SHORT) {
1963 *a = 2;
1964 return 2;
1965 } else {
1966 /* char, void, function, _Bool */
1967 *a = 1;
1968 return 1;
1972 /* return the pointed type of t */
1973 static inline CType *pointed_type(CType *type)
1975 return &type->ref->type;
1978 /* modify type so that its it is a pointer to type. */
1979 ST_FUNC void mk_pointer(CType *type)
1981 Sym *s;
1982 s = sym_push(SYM_FIELD, type, 0, -1);
1983 type->t = VT_PTR | (type->t & ~VT_TYPE);
1984 type->ref = s;
1987 /* compare function types. OLD functions match any new functions */
1988 static int is_compatible_func(CType *type1, CType *type2)
1990 Sym *s1, *s2;
1992 s1 = type1->ref;
1993 s2 = type2->ref;
1994 if (!is_compatible_types(&s1->type, &s2->type))
1995 return 0;
1996 /* check func_call */
1997 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
1998 return 0;
1999 /* XXX: not complete */
2000 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2001 return 1;
2002 if (s1->c != s2->c)
2003 return 0;
2004 while (s1 != NULL) {
2005 if (s2 == NULL)
2006 return 0;
2007 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2008 return 0;
2009 s1 = s1->next;
2010 s2 = s2->next;
2012 if (s2)
2013 return 0;
2014 return 1;
2017 /* return true if type1 and type2 are the same. If unqualified is
2018 true, qualifiers on the types are ignored.
2020 - enums are not checked as gcc __builtin_types_compatible_p ()
2022 static int compare_types(CType *type1, CType *type2, int unqualified)
2024 int bt1, t1, t2;
2026 t1 = type1->t & VT_TYPE;
2027 t2 = type2->t & VT_TYPE;
2028 if (unqualified) {
2029 /* strip qualifiers before comparing */
2030 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2031 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2033 /* XXX: bitfields ? */
2034 if (t1 != t2)
2035 return 0;
2036 /* test more complicated cases */
2037 bt1 = t1 & VT_BTYPE;
2038 if (bt1 == VT_PTR) {
2039 type1 = pointed_type(type1);
2040 type2 = pointed_type(type2);
2041 return is_compatible_types(type1, type2);
2042 } else if (bt1 == VT_STRUCT) {
2043 return (type1->ref == type2->ref);
2044 } else if (bt1 == VT_FUNC) {
2045 return is_compatible_func(type1, type2);
2046 } else {
2047 return 1;
2051 /* return true if type1 and type2 are exactly the same (including
2052 qualifiers).
2054 static int is_compatible_types(CType *type1, CType *type2)
2056 return compare_types(type1,type2,0);
2059 /* return true if type1 and type2 are the same (ignoring qualifiers).
2061 static int is_compatible_parameter_types(CType *type1, CType *type2)
2063 return compare_types(type1,type2,1);
2066 /* print a type. If 'varstr' is not NULL, then the variable is also
2067 printed in the type */
2068 /* XXX: union */
2069 /* XXX: add array and function pointers */
2070 static void type_to_str(char *buf, int buf_size,
2071 CType *type, const char *varstr)
2073 int bt, v, t;
2074 Sym *s, *sa;
2075 char buf1[256];
2076 const char *tstr;
2078 t = type->t & VT_TYPE;
2079 bt = t & VT_BTYPE;
2080 buf[0] = '\0';
2081 if (t & VT_CONSTANT)
2082 pstrcat(buf, buf_size, "const ");
2083 if (t & VT_VOLATILE)
2084 pstrcat(buf, buf_size, "volatile ");
2085 if (t & VT_UNSIGNED)
2086 pstrcat(buf, buf_size, "unsigned ");
2087 switch(bt) {
2088 case VT_VOID:
2089 tstr = "void";
2090 goto add_tstr;
2091 case VT_BOOL:
2092 tstr = "_Bool";
2093 goto add_tstr;
2094 case VT_BYTE:
2095 tstr = "char";
2096 goto add_tstr;
2097 case VT_SHORT:
2098 tstr = "short";
2099 goto add_tstr;
2100 case VT_INT:
2101 tstr = "int";
2102 goto add_tstr;
2103 case VT_LONG:
2104 tstr = "long";
2105 goto add_tstr;
2106 case VT_LLONG:
2107 tstr = "long long";
2108 goto add_tstr;
2109 case VT_FLOAT:
2110 tstr = "float";
2111 goto add_tstr;
2112 case VT_DOUBLE:
2113 tstr = "double";
2114 goto add_tstr;
2115 case VT_LDOUBLE:
2116 tstr = "long double";
2117 add_tstr:
2118 pstrcat(buf, buf_size, tstr);
2119 break;
2120 case VT_ENUM:
2121 case VT_STRUCT:
2122 if (bt == VT_STRUCT)
2123 tstr = "struct ";
2124 else
2125 tstr = "enum ";
2126 pstrcat(buf, buf_size, tstr);
2127 v = type->ref->v & ~SYM_STRUCT;
2128 if (v >= SYM_FIRST_ANOM)
2129 pstrcat(buf, buf_size, "<anonymous>");
2130 else
2131 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2132 break;
2133 case VT_FUNC:
2134 s = type->ref;
2135 type_to_str(buf, buf_size, &s->type, varstr);
2136 pstrcat(buf, buf_size, "(");
2137 sa = s->next;
2138 while (sa != NULL) {
2139 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2140 pstrcat(buf, buf_size, buf1);
2141 sa = sa->next;
2142 if (sa)
2143 pstrcat(buf, buf_size, ", ");
2145 pstrcat(buf, buf_size, ")");
2146 goto no_var;
2147 case VT_PTR:
2148 s = type->ref;
2149 pstrcpy(buf1, sizeof(buf1), "*");
2150 if (varstr)
2151 pstrcat(buf1, sizeof(buf1), varstr);
2152 type_to_str(buf, buf_size, &s->type, buf1);
2153 goto no_var;
2155 if (varstr) {
2156 pstrcat(buf, buf_size, " ");
2157 pstrcat(buf, buf_size, varstr);
2159 no_var: ;
2162 /* verify type compatibility to store vtop in 'dt' type, and generate
2163 casts if needed. */
2164 static void gen_assign_cast(CType *dt)
2166 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2167 char buf1[256], buf2[256];
2168 int dbt, sbt;
2170 st = &vtop->type; /* source type */
2171 dbt = dt->t & VT_BTYPE;
2172 sbt = st->t & VT_BTYPE;
2173 if (dt->t & VT_CONSTANT)
2174 warning("assignment of read-only location");
2175 switch(dbt) {
2176 case VT_PTR:
2177 /* special cases for pointers */
2178 /* '0' can also be a pointer */
2179 if (is_null_pointer(vtop))
2180 goto type_ok;
2181 /* accept implicit pointer to integer cast with warning */
2182 if (is_integer_btype(sbt)) {
2183 warning("assignment makes pointer from integer without a cast");
2184 goto type_ok;
2186 type1 = pointed_type(dt);
2187 /* a function is implicitely a function pointer */
2188 if (sbt == VT_FUNC) {
2189 if ((type1->t & VT_BTYPE) != VT_VOID &&
2190 !is_compatible_types(pointed_type(dt), st))
2191 warning("assignment from incompatible pointer type");
2192 goto type_ok;
2194 if (sbt != VT_PTR)
2195 goto error;
2196 type2 = pointed_type(st);
2197 if ((type1->t & VT_BTYPE) == VT_VOID ||
2198 (type2->t & VT_BTYPE) == VT_VOID) {
2199 /* void * can match anything */
2200 } else {
2201 /* exact type match, except for unsigned */
2202 tmp_type1 = *type1;
2203 tmp_type2 = *type2;
2204 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2205 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2206 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2207 warning("assignment from incompatible pointer type");
2209 /* check const and volatile */
2210 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2211 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2212 warning("assignment discards qualifiers from pointer target type");
2213 break;
2214 case VT_BYTE:
2215 case VT_SHORT:
2216 case VT_INT:
2217 case VT_LLONG:
2218 if (sbt == VT_PTR || sbt == VT_FUNC) {
2219 warning("assignment makes integer from pointer without a cast");
2221 /* XXX: more tests */
2222 break;
2223 case VT_STRUCT:
2224 tmp_type1 = *dt;
2225 tmp_type2 = *st;
2226 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2227 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2228 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2229 error:
2230 type_to_str(buf1, sizeof(buf1), st, NULL);
2231 type_to_str(buf2, sizeof(buf2), dt, NULL);
2232 error("cannot cast '%s' to '%s'", buf1, buf2);
2234 break;
2236 type_ok:
2237 gen_cast(dt);
2240 /* store vtop in lvalue pushed on stack */
2241 ST_FUNC void vstore(void)
2243 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2245 ft = vtop[-1].type.t;
2246 sbt = vtop->type.t & VT_BTYPE;
2247 dbt = ft & VT_BTYPE;
2248 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2249 (sbt == VT_INT && dbt == VT_SHORT)) {
2250 /* optimize char/short casts */
2251 delayed_cast = VT_MUSTCAST;
2252 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2253 /* XXX: factorize */
2254 if (ft & VT_CONSTANT)
2255 warning("assignment of read-only location");
2256 } else {
2257 delayed_cast = 0;
2258 if (!(ft & VT_BITFIELD))
2259 gen_assign_cast(&vtop[-1].type);
2262 if (sbt == VT_STRUCT) {
2263 /* if structure, only generate pointer */
2264 /* structure assignment : generate memcpy */
2265 /* XXX: optimize if small size */
2266 if (!nocode_wanted) {
2267 size = type_size(&vtop->type, &align);
2269 /* destination */
2270 vswap();
2271 vtop->type.t = VT_PTR;
2272 gaddrof();
2274 /* address of memcpy() */
2275 #ifdef TCC_ARM_EABI
2276 if(!(align & 7))
2277 vpush_global_sym(&func_old_type, TOK_memcpy8);
2278 else if(!(align & 3))
2279 vpush_global_sym(&func_old_type, TOK_memcpy4);
2280 else
2281 #endif
2282 vpush_global_sym(&func_old_type, TOK_memcpy);
2284 vswap();
2285 /* source */
2286 vpushv(vtop - 2);
2287 vtop->type.t = VT_PTR;
2288 gaddrof();
2289 /* type size */
2290 vpushi(size);
2291 gfunc_call(3);
2292 } else {
2293 vswap();
2294 vpop();
2296 /* leave source on stack */
2297 } else if (ft & VT_BITFIELD) {
2298 /* bitfield store handling */
2299 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2300 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2301 /* remove bit field info to avoid loops */
2302 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2304 /* duplicate source into other register */
2305 gv_dup();
2306 vswap();
2307 vrott(3);
2309 if((ft & VT_BTYPE) == VT_BOOL) {
2310 gen_cast(&vtop[-1].type);
2311 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2314 /* duplicate destination */
2315 vdup();
2316 vtop[-1] = vtop[-2];
2318 /* mask and shift source */
2319 if((ft & VT_BTYPE) != VT_BOOL) {
2320 if((ft & VT_BTYPE) == VT_LLONG) {
2321 vpushll((1ULL << bit_size) - 1ULL);
2322 } else {
2323 vpushi((1 << bit_size) - 1);
2325 gen_op('&');
2327 vpushi(bit_pos);
2328 gen_op(TOK_SHL);
2329 /* load destination, mask and or with source */
2330 vswap();
2331 if((ft & VT_BTYPE) == VT_LLONG) {
2332 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2333 } else {
2334 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2336 gen_op('&');
2337 gen_op('|');
2338 /* store result */
2339 vstore();
2341 /* pop off shifted source from "duplicate source..." above */
2342 vpop();
2344 } else {
2345 #ifdef CONFIG_TCC_BCHECK
2346 /* bound check case */
2347 if (vtop[-1].r & VT_MUSTBOUND) {
2348 vswap();
2349 gbound();
2350 vswap();
2352 #endif
2353 if (!nocode_wanted) {
2354 rc = RC_INT;
2355 if (is_float(ft)) {
2356 rc = RC_FLOAT;
2357 #ifdef TCC_TARGET_X86_64
2358 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2359 rc = RC_ST0;
2361 #endif
2363 r = gv(rc); /* generate value */
2364 /* if lvalue was saved on stack, must read it */
2365 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2366 SValue sv;
2367 t = get_reg(RC_INT);
2368 #ifdef TCC_TARGET_X86_64
2369 sv.type.t = VT_PTR;
2370 #else
2371 sv.type.t = VT_INT;
2372 #endif
2373 sv.r = VT_LOCAL | VT_LVAL;
2374 sv.c.ul = vtop[-1].c.ul;
2375 load(t, &sv);
2376 vtop[-1].r = t | VT_LVAL;
2378 store(r, vtop - 1);
2379 #ifndef TCC_TARGET_X86_64
2380 /* two word case handling : store second register at word + 4 */
2381 if ((ft & VT_BTYPE) == VT_LLONG) {
2382 vswap();
2383 /* convert to int to increment easily */
2384 vtop->type.t = VT_INT;
2385 gaddrof();
2386 vpushi(4);
2387 gen_op('+');
2388 vtop->r |= VT_LVAL;
2389 vswap();
2390 /* XXX: it works because r2 is spilled last ! */
2391 store(vtop->r2, vtop - 1);
2393 #endif
2395 vswap();
2396 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2397 vtop->r |= delayed_cast;
2401 /* post defines POST/PRE add. c is the token ++ or -- */
2402 ST_FUNC void inc(int post, int c)
2404 test_lvalue();
2405 vdup(); /* save lvalue */
2406 if (post) {
2407 gv_dup(); /* duplicate value */
2408 vrotb(3);
2409 vrotb(3);
2411 /* add constant */
2412 vpushi(c - TOK_MID);
2413 gen_op('+');
2414 vstore(); /* store value */
2415 if (post)
2416 vpop(); /* if post op, return saved value */
2419 /* Parse GNUC __attribute__ extension. Currently, the following
2420 extensions are recognized:
2421 - aligned(n) : set data/function alignment.
2422 - packed : force data alignment to 1
2423 - section(x) : generate data/code in this section.
2424 - unused : currently ignored, but may be used someday.
2425 - regparm(n) : pass function parameters in registers (i386 only)
2427 static void parse_attribute(AttributeDef *ad)
2429 int t, n;
2431 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2432 next();
2433 skip('(');
2434 skip('(');
2435 while (tok != ')') {
2436 if (tok < TOK_IDENT)
2437 expect("attribute name");
2438 t = tok;
2439 next();
2440 switch(t) {
2441 case TOK_SECTION1:
2442 case TOK_SECTION2:
2443 skip('(');
2444 if (tok != TOK_STR)
2445 expect("section name");
2446 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2447 next();
2448 skip(')');
2449 break;
2450 case TOK_ALIGNED1:
2451 case TOK_ALIGNED2:
2452 if (tok == '(') {
2453 next();
2454 n = expr_const();
2455 if (n <= 0 || (n & (n - 1)) != 0)
2456 error("alignment must be a positive power of two");
2457 skip(')');
2458 } else {
2459 n = MAX_ALIGN;
2461 ad->aligned = n;
2462 break;
2463 case TOK_PACKED1:
2464 case TOK_PACKED2:
2465 ad->packed = 1;
2466 break;
2467 case TOK_UNUSED1:
2468 case TOK_UNUSED2:
2469 /* currently, no need to handle it because tcc does not
2470 track unused objects */
2471 break;
2472 case TOK_NORETURN1:
2473 case TOK_NORETURN2:
2474 /* currently, no need to handle it because tcc does not
2475 track unused objects */
2476 break;
2477 case TOK_CDECL1:
2478 case TOK_CDECL2:
2479 case TOK_CDECL3:
2480 ad->func_call = FUNC_CDECL;
2481 break;
2482 case TOK_STDCALL1:
2483 case TOK_STDCALL2:
2484 case TOK_STDCALL3:
2485 ad->func_call = FUNC_STDCALL;
2486 break;
2487 #ifdef TCC_TARGET_I386
2488 case TOK_REGPARM1:
2489 case TOK_REGPARM2:
2490 skip('(');
2491 n = expr_const();
2492 if (n > 3)
2493 n = 3;
2494 else if (n < 0)
2495 n = 0;
2496 if (n > 0)
2497 ad->func_call = FUNC_FASTCALL1 + n - 1;
2498 skip(')');
2499 break;
2500 case TOK_FASTCALL1:
2501 case TOK_FASTCALL2:
2502 case TOK_FASTCALL3:
2503 ad->func_call = FUNC_FASTCALLW;
2504 break;
2505 #endif
2506 case TOK_DLLEXPORT:
2507 ad->func_export = 1;
2508 break;
2509 case TOK_DLLIMPORT:
2510 ad->func_import = 1;
2511 break;
2512 default:
2513 if (tcc_state->warn_unsupported)
2514 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2515 /* skip parameters */
2516 if (tok == '(') {
2517 int parenthesis = 0;
2518 do {
2519 if (tok == '(')
2520 parenthesis++;
2521 else if (tok == ')')
2522 parenthesis--;
2523 next();
2524 } while (parenthesis && tok != -1);
2526 break;
2528 if (tok != ',')
2529 break;
2530 next();
2532 skip(')');
2533 skip(')');
2537 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2538 static void struct_decl(CType *type, int u)
2540 int a, v, size, align, maxalign, c, offset;
2541 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2542 Sym *s, *ss, *ass, **ps;
2543 AttributeDef ad;
2544 CType type1, btype;
2546 a = tok; /* save decl type */
2547 next();
2548 if (tok != '{') {
2549 v = tok;
2550 next();
2551 /* struct already defined ? return it */
2552 if (v < TOK_IDENT)
2553 expect("struct/union/enum name");
2554 s = struct_find(v);
2555 if (s) {
2556 if (s->type.t != a)
2557 error("invalid type");
2558 goto do_decl;
2560 } else {
2561 v = anon_sym++;
2563 type1.t = a;
2564 /* we put an undefined size for struct/union */
2565 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2566 s->r = 0; /* default alignment is zero as gcc */
2567 /* put struct/union/enum name in type */
2568 do_decl:
2569 type->t = u;
2570 type->ref = s;
2572 if (tok == '{') {
2573 next();
2574 if (s->c != -1)
2575 error("struct/union/enum already defined");
2576 /* cannot be empty */
2577 c = 0;
2578 /* non empty enums are not allowed */
2579 if (a == TOK_ENUM) {
2580 for(;;) {
2581 v = tok;
2582 if (v < TOK_UIDENT)
2583 expect("identifier");
2584 next();
2585 if (tok == '=') {
2586 next();
2587 c = expr_const();
2589 /* enum symbols have static storage */
2590 ss = sym_push(v, &int_type, VT_CONST, c);
2591 ss->type.t |= VT_STATIC;
2592 if (tok != ',')
2593 break;
2594 next();
2595 c++;
2596 /* NOTE: we accept a trailing comma */
2597 if (tok == '}')
2598 break;
2600 skip('}');
2601 } else {
2602 maxalign = 1;
2603 ps = &s->next;
2604 prevbt = VT_INT;
2605 bit_pos = 0;
2606 offset = 0;
2607 while (tok != '}') {
2608 parse_btype(&btype, &ad);
2609 while (1) {
2610 bit_size = -1;
2611 v = 0;
2612 type1 = btype;
2613 if (tok != ':') {
2614 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2615 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2616 expect("identifier");
2617 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2618 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2619 error("invalid type for '%s'",
2620 get_tok_str(v, NULL));
2622 if (tok == ':') {
2623 next();
2624 bit_size = expr_const();
2625 /* XXX: handle v = 0 case for messages */
2626 if (bit_size < 0)
2627 error("negative width in bit-field '%s'",
2628 get_tok_str(v, NULL));
2629 if (v && bit_size == 0)
2630 error("zero width for bit-field '%s'",
2631 get_tok_str(v, NULL));
2633 size = type_size(&type1, &align);
2634 if (ad.aligned) {
2635 if (align < ad.aligned)
2636 align = ad.aligned;
2637 } else if (ad.packed) {
2638 align = 1;
2639 } else if (*tcc_state->pack_stack_ptr) {
2640 if (align > *tcc_state->pack_stack_ptr)
2641 align = *tcc_state->pack_stack_ptr;
2643 lbit_pos = 0;
2644 if (bit_size >= 0) {
2645 bt = type1.t & VT_BTYPE;
2646 if (bt != VT_INT &&
2647 bt != VT_BYTE &&
2648 bt != VT_SHORT &&
2649 bt != VT_BOOL &&
2650 bt != VT_ENUM &&
2651 bt != VT_LLONG)
2652 error("bitfields must have scalar type");
2653 bsize = size * 8;
2654 if (bit_size > bsize) {
2655 error("width of '%s' exceeds its type",
2656 get_tok_str(v, NULL));
2657 } else if (bit_size == bsize) {
2658 /* no need for bit fields */
2659 bit_pos = 0;
2660 } else if (bit_size == 0) {
2661 /* XXX: what to do if only padding in a
2662 structure ? */
2663 /* zero size: means to pad */
2664 bit_pos = 0;
2665 } else {
2666 /* we do not have enough room ?
2667 did the type change?
2668 is it a union? */
2669 if ((bit_pos + bit_size) > bsize ||
2670 bt != prevbt || a == TOK_UNION)
2671 bit_pos = 0;
2672 lbit_pos = bit_pos;
2673 /* XXX: handle LSB first */
2674 type1.t |= VT_BITFIELD |
2675 (bit_pos << VT_STRUCT_SHIFT) |
2676 (bit_size << (VT_STRUCT_SHIFT + 6));
2677 bit_pos += bit_size;
2679 prevbt = bt;
2680 } else {
2681 bit_pos = 0;
2683 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2684 /* add new memory data only if starting
2685 bit field */
2686 if (lbit_pos == 0) {
2687 if (a == TOK_STRUCT) {
2688 c = (c + align - 1) & -align;
2689 offset = c;
2690 if (size > 0)
2691 c += size;
2692 } else {
2693 offset = 0;
2694 if (size > c)
2695 c = size;
2697 if (align > maxalign)
2698 maxalign = align;
2700 #if 0
2701 printf("add field %s offset=%d",
2702 get_tok_str(v, NULL), offset);
2703 if (type1.t & VT_BITFIELD) {
2704 printf(" pos=%d size=%d",
2705 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2706 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2708 printf("\n");
2709 #endif
2711 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2712 ass = type1.ref;
2713 while ((ass = ass->next) != NULL) {
2714 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2715 *ps = ss;
2716 ps = &ss->next;
2718 } else if (v) {
2719 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2720 *ps = ss;
2721 ps = &ss->next;
2723 if (tok == ';' || tok == TOK_EOF)
2724 break;
2725 skip(',');
2727 skip(';');
2729 skip('}');
2730 /* store size and alignment */
2731 s->c = (c + maxalign - 1) & -maxalign;
2732 s->r = maxalign;
2737 /* return 0 if no type declaration. otherwise, return the basic type
2738 and skip it.
2740 static int parse_btype(CType *type, AttributeDef *ad)
2742 int t, u, type_found, typespec_found, typedef_found;
2743 Sym *s;
2744 CType type1;
2746 memset(ad, 0, sizeof(AttributeDef));
2747 type_found = 0;
2748 typespec_found = 0;
2749 typedef_found = 0;
2750 t = 0;
2751 while(1) {
2752 switch(tok) {
2753 case TOK_EXTENSION:
2754 /* currently, we really ignore extension */
2755 next();
2756 continue;
2758 /* basic types */
2759 case TOK_CHAR:
2760 u = VT_BYTE;
2761 basic_type:
2762 next();
2763 basic_type1:
2764 if ((t & VT_BTYPE) != 0)
2765 error("too many basic types");
2766 t |= u;
2767 typespec_found = 1;
2768 break;
2769 case TOK_VOID:
2770 u = VT_VOID;
2771 goto basic_type;
2772 case TOK_SHORT:
2773 u = VT_SHORT;
2774 goto basic_type;
2775 case TOK_INT:
2776 next();
2777 typespec_found = 1;
2778 break;
2779 case TOK_LONG:
2780 next();
2781 if ((t & VT_BTYPE) == VT_DOUBLE) {
2782 #ifndef TCC_TARGET_PE
2783 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2784 #endif
2785 } else if ((t & VT_BTYPE) == VT_LONG) {
2786 t = (t & ~VT_BTYPE) | VT_LLONG;
2787 } else {
2788 u = VT_LONG;
2789 goto basic_type1;
2791 break;
2792 case TOK_BOOL:
2793 u = VT_BOOL;
2794 goto basic_type;
2795 case TOK_FLOAT:
2796 u = VT_FLOAT;
2797 goto basic_type;
2798 case TOK_DOUBLE:
2799 next();
2800 if ((t & VT_BTYPE) == VT_LONG) {
2801 #ifdef TCC_TARGET_PE
2802 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2803 #else
2804 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2805 #endif
2806 } else {
2807 u = VT_DOUBLE;
2808 goto basic_type1;
2810 break;
2811 case TOK_ENUM:
2812 struct_decl(&type1, VT_ENUM);
2813 basic_type2:
2814 u = type1.t;
2815 type->ref = type1.ref;
2816 goto basic_type1;
2817 case TOK_STRUCT:
2818 case TOK_UNION:
2819 struct_decl(&type1, VT_STRUCT);
2820 goto basic_type2;
2822 /* type modifiers */
2823 case TOK_CONST1:
2824 case TOK_CONST2:
2825 case TOK_CONST3:
2826 t |= VT_CONSTANT;
2827 next();
2828 break;
2829 case TOK_VOLATILE1:
2830 case TOK_VOLATILE2:
2831 case TOK_VOLATILE3:
2832 t |= VT_VOLATILE;
2833 next();
2834 break;
2835 case TOK_SIGNED1:
2836 case TOK_SIGNED2:
2837 case TOK_SIGNED3:
2838 typespec_found = 1;
2839 t |= VT_SIGNED;
2840 next();
2841 break;
2842 case TOK_REGISTER:
2843 case TOK_AUTO:
2844 case TOK_RESTRICT1:
2845 case TOK_RESTRICT2:
2846 case TOK_RESTRICT3:
2847 next();
2848 break;
2849 case TOK_UNSIGNED:
2850 t |= VT_UNSIGNED;
2851 next();
2852 typespec_found = 1;
2853 break;
2855 /* storage */
2856 case TOK_EXTERN:
2857 t |= VT_EXTERN;
2858 next();
2859 break;
2860 case TOK_STATIC:
2861 t |= VT_STATIC;
2862 next();
2863 break;
2864 case TOK_TYPEDEF:
2865 t |= VT_TYPEDEF;
2866 next();
2867 break;
2868 case TOK_INLINE1:
2869 case TOK_INLINE2:
2870 case TOK_INLINE3:
2871 t |= VT_INLINE;
2872 next();
2873 break;
2875 /* GNUC attribute */
2876 case TOK_ATTRIBUTE1:
2877 case TOK_ATTRIBUTE2:
2878 parse_attribute(ad);
2879 break;
2880 /* GNUC typeof */
2881 case TOK_TYPEOF1:
2882 case TOK_TYPEOF2:
2883 case TOK_TYPEOF3:
2884 next();
2885 parse_expr_type(&type1);
2886 goto basic_type2;
2887 default:
2888 if (typespec_found || typedef_found)
2889 goto the_end;
2890 s = sym_find(tok);
2891 if (!s || !(s->type.t & VT_TYPEDEF))
2892 goto the_end;
2893 typedef_found = 1;
2894 t |= (s->type.t & ~VT_TYPEDEF);
2895 type->ref = s->type.ref;
2896 if (s->r) {
2897 /* get attributes from typedef */
2898 if (0 == ad->aligned)
2899 ad->aligned = FUNC_ALIGN(s->r);
2900 if (0 == ad->func_call)
2901 ad->func_call = FUNC_CALL(s->r);
2902 ad->packed |= FUNC_PACKED(s->r);
2904 next();
2905 typespec_found = 1;
2906 break;
2908 type_found = 1;
2910 the_end:
2911 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
2912 error("signed and unsigned modifier");
2913 if (tcc_state->char_is_unsigned) {
2914 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
2915 t |= VT_UNSIGNED;
2917 t &= ~VT_SIGNED;
2919 /* long is never used as type */
2920 if ((t & VT_BTYPE) == VT_LONG)
2921 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
2922 t = (t & ~VT_BTYPE) | VT_INT;
2923 #else
2924 t = (t & ~VT_BTYPE) | VT_LLONG;
2925 #endif
2926 type->t = t;
2927 return type_found;
2930 /* convert a function parameter type (array to pointer and function to
2931 function pointer) */
2932 static inline void convert_parameter_type(CType *pt)
2934 /* remove const and volatile qualifiers (XXX: const could be used
2935 to indicate a const function parameter */
2936 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
2937 /* array must be transformed to pointer according to ANSI C */
2938 pt->t &= ~VT_ARRAY;
2939 if ((pt->t & VT_BTYPE) == VT_FUNC) {
2940 mk_pointer(pt);
2944 static void post_type(CType *type, AttributeDef *ad)
2946 int n, l, t1, arg_size, align;
2947 Sym **plast, *s, *first;
2948 AttributeDef ad1;
2949 CType pt;
2951 if (tok == '(') {
2952 /* function declaration */
2953 next();
2954 l = 0;
2955 first = NULL;
2956 plast = &first;
2957 arg_size = 0;
2958 if (tok != ')') {
2959 for(;;) {
2960 /* read param name and compute offset */
2961 if (l != FUNC_OLD) {
2962 if (!parse_btype(&pt, &ad1)) {
2963 if (l) {
2964 error("invalid type");
2965 } else {
2966 l = FUNC_OLD;
2967 goto old_proto;
2970 l = FUNC_NEW;
2971 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
2972 break;
2973 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
2974 if ((pt.t & VT_BTYPE) == VT_VOID)
2975 error("parameter declared as void");
2976 arg_size += (type_size(&pt, &align) + 3) & ~3;
2977 } else {
2978 old_proto:
2979 n = tok;
2980 if (n < TOK_UIDENT)
2981 expect("identifier");
2982 pt.t = VT_INT;
2983 next();
2985 convert_parameter_type(&pt);
2986 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
2987 *plast = s;
2988 plast = &s->next;
2989 if (tok == ')')
2990 break;
2991 skip(',');
2992 if (l == FUNC_NEW && tok == TOK_DOTS) {
2993 l = FUNC_ELLIPSIS;
2994 next();
2995 break;
2999 /* if no parameters, then old type prototype */
3000 if (l == 0)
3001 l = FUNC_OLD;
3002 skip(')');
3003 t1 = type->t & VT_STORAGE;
3004 /* NOTE: const is ignored in returned type as it has a special
3005 meaning in gcc / C++ */
3006 type->t &= ~(VT_STORAGE | VT_CONSTANT);
3007 post_type(type, ad);
3008 /* we push a anonymous symbol which will contain the function prototype */
3009 ad->func_args = arg_size;
3010 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3011 s->next = first;
3012 type->t = t1 | VT_FUNC;
3013 type->ref = s;
3014 } else if (tok == '[') {
3015 /* array definition */
3016 next();
3017 if (tok == TOK_RESTRICT1)
3018 next();
3019 n = -1;
3020 if (tok != ']') {
3021 n = expr_const();
3022 if (n < 0)
3023 error("invalid array size");
3025 skip(']');
3026 /* parse next post type */
3027 t1 = type->t & VT_STORAGE;
3028 type->t &= ~VT_STORAGE;
3029 post_type(type, ad);
3031 /* we push a anonymous symbol which will contain the array
3032 element type */
3033 s = sym_push(SYM_FIELD, type, 0, n);
3034 type->t = t1 | VT_ARRAY | VT_PTR;
3035 type->ref = s;
3039 /* Parse a type declaration (except basic type), and return the type
3040 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3041 expected. 'type' should contain the basic type. 'ad' is the
3042 attribute definition of the basic type. It can be modified by
3043 type_decl().
3045 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3047 Sym *s;
3048 CType type1, *type2;
3049 int qualifiers;
3051 while (tok == '*') {
3052 qualifiers = 0;
3053 redo:
3054 next();
3055 switch(tok) {
3056 case TOK_CONST1:
3057 case TOK_CONST2:
3058 case TOK_CONST3:
3059 qualifiers |= VT_CONSTANT;
3060 goto redo;
3061 case TOK_VOLATILE1:
3062 case TOK_VOLATILE2:
3063 case TOK_VOLATILE3:
3064 qualifiers |= VT_VOLATILE;
3065 goto redo;
3066 case TOK_RESTRICT1:
3067 case TOK_RESTRICT2:
3068 case TOK_RESTRICT3:
3069 goto redo;
3071 mk_pointer(type);
3072 type->t |= qualifiers;
3075 /* XXX: clarify attribute handling */
3076 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3077 parse_attribute(ad);
3079 /* recursive type */
3080 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3081 type1.t = 0; /* XXX: same as int */
3082 if (tok == '(') {
3083 next();
3084 /* XXX: this is not correct to modify 'ad' at this point, but
3085 the syntax is not clear */
3086 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3087 parse_attribute(ad);
3088 type_decl(&type1, ad, v, td);
3089 skip(')');
3090 } else {
3091 /* type identifier */
3092 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3093 *v = tok;
3094 next();
3095 } else {
3096 if (!(td & TYPE_ABSTRACT))
3097 expect("identifier");
3098 *v = 0;
3101 post_type(type, ad);
3102 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3103 parse_attribute(ad);
3104 if (!type1.t)
3105 return;
3106 /* append type at the end of type1 */
3107 type2 = &type1;
3108 for(;;) {
3109 s = type2->ref;
3110 type2 = &s->type;
3111 if (!type2->t) {
3112 *type2 = *type;
3113 break;
3116 *type = type1;
3119 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3120 ST_FUNC int lvalue_type(int t)
3122 int bt, r;
3123 r = VT_LVAL;
3124 bt = t & VT_BTYPE;
3125 if (bt == VT_BYTE || bt == VT_BOOL)
3126 r |= VT_LVAL_BYTE;
3127 else if (bt == VT_SHORT)
3128 r |= VT_LVAL_SHORT;
3129 else
3130 return r;
3131 if (t & VT_UNSIGNED)
3132 r |= VT_LVAL_UNSIGNED;
3133 return r;
3136 /* indirection with full error checking and bound check */
3137 ST_FUNC void indir(void)
3139 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3140 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3141 return;
3142 expect("pointer");
3144 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3145 gv(RC_INT);
3146 vtop->type = *pointed_type(&vtop->type);
3147 /* Arrays and functions are never lvalues */
3148 if (!(vtop->type.t & VT_ARRAY)
3149 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3150 vtop->r |= lvalue_type(vtop->type.t);
3151 /* if bound checking, the referenced pointer must be checked */
3152 #ifdef CONFIG_TCC_BCHECK
3153 if (tcc_state->do_bounds_check)
3154 vtop->r |= VT_MUSTBOUND;
3155 #endif
3159 /* pass a parameter to a function and do type checking and casting */
3160 static void gfunc_param_typed(Sym *func, Sym *arg)
3162 int func_type;
3163 CType type;
3165 func_type = func->c;
3166 if (func_type == FUNC_OLD ||
3167 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3168 /* default casting : only need to convert float to double */
3169 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3170 type.t = VT_DOUBLE;
3171 gen_cast(&type);
3173 } else if (arg == NULL) {
3174 error("too many arguments to function");
3175 } else {
3176 type = arg->type;
3177 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3178 gen_assign_cast(&type);
3182 /* parse an expression of the form '(type)' or '(expr)' and return its
3183 type */
3184 static void parse_expr_type(CType *type)
3186 int n;
3187 AttributeDef ad;
3189 skip('(');
3190 if (parse_btype(type, &ad)) {
3191 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3192 } else {
3193 expr_type(type);
3195 skip(')');
3198 static void parse_type(CType *type)
3200 AttributeDef ad;
3201 int n;
3203 if (!parse_btype(type, &ad)) {
3204 expect("type");
3206 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3209 static void vpush_tokc(int t)
3211 CType type;
3212 type.t = t;
3213 type.ref = 0;
3214 vsetc(&type, VT_CONST, &tokc);
3217 ST_FUNC void unary(void)
3219 int n, t, align, size, r;
3220 CType type;
3221 Sym *s;
3222 AttributeDef ad;
3224 /* XXX: GCC 2.95.3 does not generate a table although it should be
3225 better here */
3226 tok_next:
3227 switch(tok) {
3228 case TOK_EXTENSION:
3229 next();
3230 goto tok_next;
3231 case TOK_CINT:
3232 case TOK_CCHAR:
3233 case TOK_LCHAR:
3234 vpushi(tokc.i);
3235 next();
3236 break;
3237 case TOK_CUINT:
3238 vpush_tokc(VT_INT | VT_UNSIGNED);
3239 next();
3240 break;
3241 case TOK_CLLONG:
3242 vpush_tokc(VT_LLONG);
3243 next();
3244 break;
3245 case TOK_CULLONG:
3246 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3247 next();
3248 break;
3249 case TOK_CFLOAT:
3250 vpush_tokc(VT_FLOAT);
3251 next();
3252 break;
3253 case TOK_CDOUBLE:
3254 vpush_tokc(VT_DOUBLE);
3255 next();
3256 break;
3257 case TOK_CLDOUBLE:
3258 vpush_tokc(VT_LDOUBLE);
3259 next();
3260 break;
3261 case TOK___FUNCTION__:
3262 if (!gnu_ext)
3263 goto tok_identifier;
3264 /* fall thru */
3265 case TOK___FUNC__:
3267 void *ptr;
3268 int len;
3269 /* special function name identifier */
3270 len = strlen(funcname) + 1;
3271 /* generate char[len] type */
3272 type.t = VT_BYTE;
3273 mk_pointer(&type);
3274 type.t |= VT_ARRAY;
3275 type.ref->c = len;
3276 vpush_ref(&type, data_section, data_section->data_offset, len);
3277 ptr = section_ptr_add(data_section, len);
3278 memcpy(ptr, funcname, len);
3279 next();
3281 break;
3282 case TOK_LSTR:
3283 #ifdef TCC_TARGET_PE
3284 t = VT_SHORT | VT_UNSIGNED;
3285 #else
3286 t = VT_INT;
3287 #endif
3288 goto str_init;
3289 case TOK_STR:
3290 /* string parsing */
3291 t = VT_BYTE;
3292 str_init:
3293 if (tcc_state->warn_write_strings)
3294 t |= VT_CONSTANT;
3295 type.t = t;
3296 mk_pointer(&type);
3297 type.t |= VT_ARRAY;
3298 memset(&ad, 0, sizeof(AttributeDef));
3299 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3300 break;
3301 case '(':
3302 next();
3303 /* cast ? */
3304 if (parse_btype(&type, &ad)) {
3305 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3306 skip(')');
3307 /* check ISOC99 compound literal */
3308 if (tok == '{') {
3309 /* data is allocated locally by default */
3310 if (global_expr)
3311 r = VT_CONST;
3312 else
3313 r = VT_LOCAL;
3314 /* all except arrays are lvalues */
3315 if (!(type.t & VT_ARRAY))
3316 r |= lvalue_type(type.t);
3317 memset(&ad, 0, sizeof(AttributeDef));
3318 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3319 } else {
3320 unary();
3321 gen_cast(&type);
3323 } else if (tok == '{') {
3324 /* save all registers */
3325 save_regs(0);
3326 /* statement expression : we do not accept break/continue
3327 inside as GCC does */
3328 block(NULL, NULL, NULL, NULL, 0, 1);
3329 skip(')');
3330 } else {
3331 gexpr();
3332 skip(')');
3334 break;
3335 case '*':
3336 next();
3337 unary();
3338 indir();
3339 break;
3340 case '&':
3341 next();
3342 unary();
3343 /* functions names must be treated as function pointers,
3344 except for unary '&' and sizeof. Since we consider that
3345 functions are not lvalues, we only have to handle it
3346 there and in function calls. */
3347 /* arrays can also be used although they are not lvalues */
3348 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3349 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3350 test_lvalue();
3351 mk_pointer(&vtop->type);
3352 gaddrof();
3353 break;
3354 case '!':
3355 next();
3356 unary();
3357 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3358 CType boolean;
3359 boolean.t = VT_BOOL;
3360 gen_cast(&boolean);
3361 vtop->c.i = !vtop->c.i;
3362 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3363 vtop->c.i = vtop->c.i ^ 1;
3364 else {
3365 save_regs(1);
3366 vseti(VT_JMP, gtst(1, 0));
3368 break;
3369 case '~':
3370 next();
3371 unary();
3372 vpushi(-1);
3373 gen_op('^');
3374 break;
3375 case '+':
3376 next();
3377 /* in order to force cast, we add zero */
3378 unary();
3379 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3380 error("pointer not accepted for unary plus");
3381 vpushi(0);
3382 gen_op('+');
3383 break;
3384 case TOK_SIZEOF:
3385 case TOK_ALIGNOF1:
3386 case TOK_ALIGNOF2:
3387 t = tok;
3388 next();
3389 if (tok == '(') {
3390 parse_expr_type(&type);
3391 } else {
3392 unary_type(&type);
3394 size = type_size(&type, &align);
3395 if (t == TOK_SIZEOF) {
3396 if (size < 0)
3397 error("sizeof applied to an incomplete type");
3398 vpushi(size);
3399 } else {
3400 vpushi(align);
3402 vtop->type.t |= VT_UNSIGNED;
3403 break;
3405 case TOK_builtin_types_compatible_p:
3407 CType type1, type2;
3408 next();
3409 skip('(');
3410 parse_type(&type1);
3411 skip(',');
3412 parse_type(&type2);
3413 skip(')');
3414 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3415 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3416 vpushi(is_compatible_types(&type1, &type2));
3418 break;
3419 case TOK_builtin_constant_p:
3421 int saved_nocode_wanted, res;
3422 next();
3423 skip('(');
3424 saved_nocode_wanted = nocode_wanted;
3425 nocode_wanted = 1;
3426 gexpr();
3427 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3428 vpop();
3429 nocode_wanted = saved_nocode_wanted;
3430 skip(')');
3431 vpushi(res);
3433 break;
3434 case TOK_builtin_frame_address:
3436 CType type;
3437 next();
3438 skip('(');
3439 if (tok != TOK_CINT) {
3440 error("__builtin_frame_address only takes integers");
3442 if (tokc.i != 0) {
3443 error("TCC only supports __builtin_frame_address(0)");
3445 next();
3446 skip(')');
3447 type.t = VT_VOID;
3448 mk_pointer(&type);
3449 vset(&type, VT_LOCAL, 0);
3451 break;
3452 #ifdef TCC_TARGET_X86_64
3453 case TOK_builtin_malloc:
3454 tok = TOK_malloc;
3455 goto tok_identifier;
3456 case TOK_builtin_free:
3457 tok = TOK_free;
3458 goto tok_identifier;
3459 #endif
3460 case TOK_INC:
3461 case TOK_DEC:
3462 t = tok;
3463 next();
3464 unary();
3465 inc(0, t);
3466 break;
3467 case '-':
3468 next();
3469 vpushi(0);
3470 unary();
3471 gen_op('-');
3472 break;
3473 case TOK_LAND:
3474 if (!gnu_ext)
3475 goto tok_identifier;
3476 next();
3477 /* allow to take the address of a label */
3478 if (tok < TOK_UIDENT)
3479 expect("label identifier");
3480 s = label_find(tok);
3481 if (!s) {
3482 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3483 } else {
3484 if (s->r == LABEL_DECLARED)
3485 s->r = LABEL_FORWARD;
3487 if (!s->type.t) {
3488 s->type.t = VT_VOID;
3489 mk_pointer(&s->type);
3490 s->type.t |= VT_STATIC;
3492 vset(&s->type, VT_CONST | VT_SYM, 0);
3493 vtop->sym = s;
3494 next();
3495 break;
3496 default:
3497 tok_identifier:
3498 t = tok;
3499 next();
3500 if (t < TOK_UIDENT)
3501 expect("identifier");
3502 s = sym_find(t);
3503 if (!s) {
3504 if (tok != '(')
3505 error("'%s' undeclared", get_tok_str(t, NULL));
3506 /* for simple function calls, we tolerate undeclared
3507 external reference to int() function */
3508 if (tcc_state->warn_implicit_function_declaration)
3509 warning("implicit declaration of function '%s'",
3510 get_tok_str(t, NULL));
3511 s = external_global_sym(t, &func_old_type, 0);
3513 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3514 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3515 /* if referencing an inline function, then we generate a
3516 symbol to it if not already done. It will have the
3517 effect to generate code for it at the end of the
3518 compilation unit. Inline function as always
3519 generated in the text section. */
3520 if (!s->c)
3521 put_extern_sym(s, text_section, 0, 0);
3522 r = VT_SYM | VT_CONST;
3523 } else {
3524 r = s->r;
3526 vset(&s->type, r, s->c);
3527 /* if forward reference, we must point to s */
3528 if (vtop->r & VT_SYM) {
3529 vtop->sym = s;
3530 vtop->c.ul = 0;
3532 break;
3535 /* post operations */
3536 while (1) {
3537 if (tok == TOK_INC || tok == TOK_DEC) {
3538 inc(1, tok);
3539 next();
3540 } else if (tok == '.' || tok == TOK_ARROW) {
3541 int qualifiers;
3542 /* field */
3543 if (tok == TOK_ARROW)
3544 indir();
3545 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3546 test_lvalue();
3547 gaddrof();
3548 next();
3549 /* expect pointer on structure */
3550 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3551 expect("struct or union");
3552 s = vtop->type.ref;
3553 /* find field */
3554 tok |= SYM_FIELD;
3555 while ((s = s->next) != NULL) {
3556 if (s->v == tok)
3557 break;
3559 if (!s)
3560 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3561 /* add field offset to pointer */
3562 vtop->type = char_pointer_type; /* change type to 'char *' */
3563 vpushi(s->c);
3564 gen_op('+');
3565 /* change type to field type, and set to lvalue */
3566 vtop->type = s->type;
3567 vtop->type.t |= qualifiers;
3568 /* an array is never an lvalue */
3569 if (!(vtop->type.t & VT_ARRAY)) {
3570 vtop->r |= lvalue_type(vtop->type.t);
3571 #ifdef CONFIG_TCC_BCHECK
3572 /* if bound checking, the referenced pointer must be checked */
3573 if (tcc_state->do_bounds_check)
3574 vtop->r |= VT_MUSTBOUND;
3575 #endif
3577 next();
3578 } else if (tok == '[') {
3579 next();
3580 gexpr();
3581 gen_op('+');
3582 indir();
3583 skip(']');
3584 } else if (tok == '(') {
3585 SValue ret;
3586 Sym *sa;
3587 int nb_args;
3589 /* function call */
3590 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3591 /* pointer test (no array accepted) */
3592 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3593 vtop->type = *pointed_type(&vtop->type);
3594 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3595 goto error_func;
3596 } else {
3597 error_func:
3598 expect("function pointer");
3600 } else {
3601 vtop->r &= ~VT_LVAL; /* no lvalue */
3603 /* get return type */
3604 s = vtop->type.ref;
3605 next();
3606 sa = s->next; /* first parameter */
3607 nb_args = 0;
3608 ret.r2 = VT_CONST;
3609 /* compute first implicit argument if a structure is returned */
3610 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3611 /* get some space for the returned structure */
3612 size = type_size(&s->type, &align);
3613 loc = (loc - size) & -align;
3614 ret.type = s->type;
3615 ret.r = VT_LOCAL | VT_LVAL;
3616 /* pass it as 'int' to avoid structure arg passing
3617 problems */
3618 vseti(VT_LOCAL, loc);
3619 ret.c = vtop->c;
3620 nb_args++;
3621 } else {
3622 ret.type = s->type;
3623 /* return in register */
3624 if (is_float(ret.type.t)) {
3625 ret.r = reg_fret(ret.type.t);
3626 } else {
3627 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3628 ret.r2 = REG_LRET;
3629 ret.r = REG_IRET;
3631 ret.c.i = 0;
3633 if (tok != ')') {
3634 for(;;) {
3635 expr_eq();
3636 gfunc_param_typed(s, sa);
3637 nb_args++;
3638 if (sa)
3639 sa = sa->next;
3640 if (tok == ')')
3641 break;
3642 skip(',');
3645 if (sa)
3646 error("too few arguments to function");
3647 skip(')');
3648 if (!nocode_wanted) {
3649 gfunc_call(nb_args);
3650 } else {
3651 vtop -= (nb_args + 1);
3653 /* return value */
3654 vsetc(&ret.type, ret.r, &ret.c);
3655 vtop->r2 = ret.r2;
3656 } else {
3657 break;
3662 static void uneq(void)
3664 int t;
3666 unary();
3667 if (tok == '=' ||
3668 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
3669 tok == TOK_A_XOR || tok == TOK_A_OR ||
3670 tok == TOK_A_SHL || tok == TOK_A_SAR) {
3671 test_lvalue();
3672 t = tok;
3673 next();
3674 if (t == '=') {
3675 expr_eq();
3676 } else {
3677 vdup();
3678 expr_eq();
3679 gen_op(t & 0x7f);
3681 vstore();
3685 ST_FUNC void expr_prod(void)
3687 int t;
3689 uneq();
3690 while (tok == '*' || tok == '/' || tok == '%') {
3691 t = tok;
3692 next();
3693 uneq();
3694 gen_op(t);
3698 ST_FUNC void expr_sum(void)
3700 int t;
3702 expr_prod();
3703 while (tok == '+' || tok == '-') {
3704 t = tok;
3705 next();
3706 expr_prod();
3707 gen_op(t);
3711 static void expr_shift(void)
3713 int t;
3715 expr_sum();
3716 while (tok == TOK_SHL || tok == TOK_SAR) {
3717 t = tok;
3718 next();
3719 expr_sum();
3720 gen_op(t);
3724 static void expr_cmp(void)
3726 int t;
3728 expr_shift();
3729 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3730 tok == TOK_ULT || tok == TOK_UGE) {
3731 t = tok;
3732 next();
3733 expr_shift();
3734 gen_op(t);
3738 static void expr_cmpeq(void)
3740 int t;
3742 expr_cmp();
3743 while (tok == TOK_EQ || tok == TOK_NE) {
3744 t = tok;
3745 next();
3746 expr_cmp();
3747 gen_op(t);
3751 static void expr_and(void)
3753 expr_cmpeq();
3754 while (tok == '&') {
3755 next();
3756 expr_cmpeq();
3757 gen_op('&');
3761 static void expr_xor(void)
3763 expr_and();
3764 while (tok == '^') {
3765 next();
3766 expr_and();
3767 gen_op('^');
3771 static void expr_or(void)
3773 expr_xor();
3774 while (tok == '|') {
3775 next();
3776 expr_xor();
3777 gen_op('|');
3781 /* XXX: fix this mess */
3782 static void expr_land_const(void)
3784 expr_or();
3785 while (tok == TOK_LAND) {
3786 next();
3787 expr_or();
3788 gen_op(TOK_LAND);
3792 /* XXX: fix this mess */
3793 static void expr_lor_const(void)
3795 expr_land_const();
3796 while (tok == TOK_LOR) {
3797 next();
3798 expr_land_const();
3799 gen_op(TOK_LOR);
3803 /* only used if non constant */
3804 static void expr_land(void)
3806 int t;
3808 expr_or();
3809 if (tok == TOK_LAND) {
3810 t = 0;
3811 save_regs(1);
3812 for(;;) {
3813 t = gtst(1, t);
3814 if (tok != TOK_LAND) {
3815 vseti(VT_JMPI, t);
3816 break;
3818 next();
3819 expr_or();
3824 static void expr_lor(void)
3826 int t;
3828 expr_land();
3829 if (tok == TOK_LOR) {
3830 t = 0;
3831 save_regs(1);
3832 for(;;) {
3833 t = gtst(0, t);
3834 if (tok != TOK_LOR) {
3835 vseti(VT_JMP, t);
3836 break;
3838 next();
3839 expr_land();
3844 /* XXX: better constant handling */
3845 static void expr_eq(void)
3847 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
3848 SValue sv;
3849 CType type, type1, type2;
3851 if (const_wanted) {
3852 expr_lor_const();
3853 if (tok == '?') {
3854 CType boolean;
3855 int c;
3856 boolean.t = VT_BOOL;
3857 vdup();
3858 gen_cast(&boolean);
3859 c = vtop->c.i;
3860 vpop();
3861 next();
3862 if (tok != ':' || !gnu_ext) {
3863 vpop();
3864 gexpr();
3866 if (!c)
3867 vpop();
3868 skip(':');
3869 expr_eq();
3870 if (c)
3871 vpop();
3873 } else {
3874 expr_lor();
3875 if (tok == '?') {
3876 next();
3877 if (vtop != vstack) {
3878 /* needed to avoid having different registers saved in
3879 each branch */
3880 if (is_float(vtop->type.t)) {
3881 rc = RC_FLOAT;
3882 #ifdef TCC_TARGET_X86_64
3883 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
3884 rc = RC_ST0;
3886 #endif
3888 else
3889 rc = RC_INT;
3890 gv(rc);
3891 save_regs(1);
3893 if (tok == ':' && gnu_ext) {
3894 gv_dup();
3895 tt = gtst(1, 0);
3896 } else {
3897 tt = gtst(1, 0);
3898 gexpr();
3900 type1 = vtop->type;
3901 sv = *vtop; /* save value to handle it later */
3902 vtop--; /* no vpop so that FP stack is not flushed */
3903 skip(':');
3904 u = gjmp(0);
3905 gsym(tt);
3906 expr_eq();
3907 type2 = vtop->type;
3909 t1 = type1.t;
3910 bt1 = t1 & VT_BTYPE;
3911 t2 = type2.t;
3912 bt2 = t2 & VT_BTYPE;
3913 /* cast operands to correct type according to ISOC rules */
3914 if (is_float(bt1) || is_float(bt2)) {
3915 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3916 type.t = VT_LDOUBLE;
3917 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3918 type.t = VT_DOUBLE;
3919 } else {
3920 type.t = VT_FLOAT;
3922 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3923 /* cast to biggest op */
3924 type.t = VT_LLONG;
3925 /* convert to unsigned if it does not fit in a long long */
3926 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3927 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3928 type.t |= VT_UNSIGNED;
3929 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3930 /* XXX: test pointer compatibility */
3931 type = type1;
3932 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
3933 /* XXX: test function pointer compatibility */
3934 type = type1;
3935 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3936 /* XXX: test structure compatibility */
3937 type = type1;
3938 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
3939 /* NOTE: as an extension, we accept void on only one side */
3940 type.t = VT_VOID;
3941 } else {
3942 /* integer operations */
3943 type.t = VT_INT;
3944 /* convert to unsigned if it does not fit in an integer */
3945 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3946 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3947 type.t |= VT_UNSIGNED;
3950 /* now we convert second operand */
3951 gen_cast(&type);
3952 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
3953 gaddrof();
3954 rc = RC_INT;
3955 if (is_float(type.t)) {
3956 rc = RC_FLOAT;
3957 #ifdef TCC_TARGET_X86_64
3958 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
3959 rc = RC_ST0;
3961 #endif
3962 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
3963 /* for long longs, we use fixed registers to avoid having
3964 to handle a complicated move */
3965 rc = RC_IRET;
3968 r2 = gv(rc);
3969 /* this is horrible, but we must also convert first
3970 operand */
3971 tt = gjmp(0);
3972 gsym(u);
3973 /* put again first value and cast it */
3974 *vtop = sv;
3975 gen_cast(&type);
3976 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
3977 gaddrof();
3978 r1 = gv(rc);
3979 move_reg(r2, r1);
3980 vtop->r = r2;
3981 gsym(tt);
3986 ST_FUNC void gexpr(void)
3988 while (1) {
3989 expr_eq();
3990 if (tok != ',')
3991 break;
3992 vpop();
3993 next();
3997 /* parse an expression and return its type without any side effect. */
3998 static void expr_type(CType *type)
4000 int saved_nocode_wanted;
4002 saved_nocode_wanted = nocode_wanted;
4003 nocode_wanted = 1;
4004 gexpr();
4005 *type = vtop->type;
4006 vpop();
4007 nocode_wanted = saved_nocode_wanted;
4010 /* parse a unary expression and return its type without any side
4011 effect. */
4012 static void unary_type(CType *type)
4014 int a;
4016 a = nocode_wanted;
4017 nocode_wanted = 1;
4018 unary();
4019 *type = vtop->type;
4020 vpop();
4021 nocode_wanted = a;
4024 /* parse a constant expression and return value in vtop. */
4025 static void expr_const1(void)
4027 int a;
4028 a = const_wanted;
4029 const_wanted = 1;
4030 expr_eq();
4031 const_wanted = a;
4034 /* parse an integer constant and return its value. */
4035 ST_FUNC int expr_const(void)
4037 int c;
4038 expr_const1();
4039 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4040 expect("constant expression");
4041 c = vtop->c.i;
4042 vpop();
4043 return c;
4046 /* return the label token if current token is a label, otherwise
4047 return zero */
4048 static int is_label(void)
4050 int last_tok;
4052 /* fast test first */
4053 if (tok < TOK_UIDENT)
4054 return 0;
4055 /* no need to save tokc because tok is an identifier */
4056 last_tok = tok;
4057 next();
4058 if (tok == ':') {
4059 next();
4060 return last_tok;
4061 } else {
4062 unget_tok(last_tok);
4063 return 0;
4067 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4068 int case_reg, int is_expr)
4070 int a, b, c, d;
4071 Sym *s;
4073 /* generate line number info */
4074 if (tcc_state->do_debug &&
4075 (last_line_num != file->line_num || last_ind != ind)) {
4076 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4077 last_ind = ind;
4078 last_line_num = file->line_num;
4081 if (is_expr) {
4082 /* default return value is (void) */
4083 vpushi(0);
4084 vtop->type.t = VT_VOID;
4087 if (tok == TOK_IF) {
4088 /* if test */
4089 next();
4090 skip('(');
4091 gexpr();
4092 skip(')');
4093 a = gtst(1, 0);
4094 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4095 c = tok;
4096 if (c == TOK_ELSE) {
4097 next();
4098 d = gjmp(0);
4099 gsym(a);
4100 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4101 gsym(d); /* patch else jmp */
4102 } else
4103 gsym(a);
4104 } else if (tok == TOK_WHILE) {
4105 next();
4106 d = ind;
4107 skip('(');
4108 gexpr();
4109 skip(')');
4110 a = gtst(1, 0);
4111 b = 0;
4112 block(&a, &b, case_sym, def_sym, case_reg, 0);
4113 gjmp_addr(d);
4114 gsym(a);
4115 gsym_addr(b, d);
4116 } else if (tok == '{') {
4117 Sym *llabel;
4119 next();
4120 /* record local declaration stack position */
4121 s = local_stack;
4122 llabel = local_label_stack;
4123 /* handle local labels declarations */
4124 if (tok == TOK_LABEL) {
4125 next();
4126 for(;;) {
4127 if (tok < TOK_UIDENT)
4128 expect("label identifier");
4129 label_push(&local_label_stack, tok, LABEL_DECLARED);
4130 next();
4131 if (tok == ',') {
4132 next();
4133 } else {
4134 skip(';');
4135 break;
4139 while (tok != '}') {
4140 decl(VT_LOCAL);
4141 if (tok != '}') {
4142 if (is_expr)
4143 vpop();
4144 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4147 /* pop locally defined labels */
4148 label_pop(&local_label_stack, llabel);
4149 /* pop locally defined symbols */
4150 if(is_expr) {
4151 /* XXX: this solution makes only valgrind happy...
4152 triggered by gcc.c-torture/execute/20000917-1.c */
4153 Sym *p;
4154 switch(vtop->type.t & VT_BTYPE) {
4155 case VT_PTR:
4156 case VT_STRUCT:
4157 case VT_ENUM:
4158 case VT_FUNC:
4159 for(p=vtop->type.ref;p;p=p->prev)
4160 if(p->prev==s)
4161 error("unsupported expression type");
4164 sym_pop(&local_stack, s);
4165 next();
4166 } else if (tok == TOK_RETURN) {
4167 next();
4168 if (tok != ';') {
4169 gexpr();
4170 gen_assign_cast(&func_vt);
4171 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4172 CType type;
4173 /* if returning structure, must copy it to implicit
4174 first pointer arg location */
4175 #ifdef TCC_ARM_EABI
4176 int align, size;
4177 size = type_size(&func_vt,&align);
4178 if(size <= 4)
4180 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4181 && (align & 3))
4183 int addr;
4184 loc = (loc - size) & -4;
4185 addr = loc;
4186 type = func_vt;
4187 vset(&type, VT_LOCAL | VT_LVAL, addr);
4188 vswap();
4189 vstore();
4190 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4192 vtop->type = int_type;
4193 gv(RC_IRET);
4194 } else {
4195 #endif
4196 type = func_vt;
4197 mk_pointer(&type);
4198 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4199 indir();
4200 vswap();
4201 /* copy structure value to pointer */
4202 vstore();
4203 #ifdef TCC_ARM_EABI
4205 #endif
4206 } else if (is_float(func_vt.t)) {
4207 gv(rc_fret(func_vt.t));
4208 } else {
4209 gv(RC_IRET);
4211 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4213 skip(';');
4214 rsym = gjmp(rsym); /* jmp */
4215 } else if (tok == TOK_BREAK) {
4216 /* compute jump */
4217 if (!bsym)
4218 error("cannot break");
4219 *bsym = gjmp(*bsym);
4220 next();
4221 skip(';');
4222 } else if (tok == TOK_CONTINUE) {
4223 /* compute jump */
4224 if (!csym)
4225 error("cannot continue");
4226 *csym = gjmp(*csym);
4227 next();
4228 skip(';');
4229 } else if (tok == TOK_FOR) {
4230 int e;
4231 next();
4232 skip('(');
4233 if (tok != ';') {
4234 gexpr();
4235 vpop();
4237 skip(';');
4238 d = ind;
4239 c = ind;
4240 a = 0;
4241 b = 0;
4242 if (tok != ';') {
4243 gexpr();
4244 a = gtst(1, 0);
4246 skip(';');
4247 if (tok != ')') {
4248 e = gjmp(0);
4249 c = ind;
4250 gexpr();
4251 vpop();
4252 gjmp_addr(d);
4253 gsym(e);
4255 skip(')');
4256 block(&a, &b, case_sym, def_sym, case_reg, 0);
4257 gjmp_addr(c);
4258 gsym(a);
4259 gsym_addr(b, c);
4260 } else
4261 if (tok == TOK_DO) {
4262 next();
4263 a = 0;
4264 b = 0;
4265 d = ind;
4266 block(&a, &b, case_sym, def_sym, case_reg, 0);
4267 skip(TOK_WHILE);
4268 skip('(');
4269 gsym(b);
4270 gexpr();
4271 c = gtst(0, 0);
4272 gsym_addr(c, d);
4273 skip(')');
4274 gsym(a);
4275 skip(';');
4276 } else
4277 if (tok == TOK_SWITCH) {
4278 next();
4279 skip('(');
4280 gexpr();
4281 /* XXX: other types than integer */
4282 case_reg = gv(RC_INT);
4283 vpop();
4284 skip(')');
4285 a = 0;
4286 b = gjmp(0); /* jump to first case */
4287 c = 0;
4288 block(&a, csym, &b, &c, case_reg, 0);
4289 /* if no default, jmp after switch */
4290 if (c == 0)
4291 c = ind;
4292 /* default label */
4293 gsym_addr(b, c);
4294 /* break label */
4295 gsym(a);
4296 } else
4297 if (tok == TOK_CASE) {
4298 int v1, v2;
4299 if (!case_sym)
4300 expect("switch");
4301 next();
4302 v1 = expr_const();
4303 v2 = v1;
4304 if (gnu_ext && tok == TOK_DOTS) {
4305 next();
4306 v2 = expr_const();
4307 if (v2 < v1)
4308 warning("empty case range");
4310 /* since a case is like a label, we must skip it with a jmp */
4311 b = gjmp(0);
4312 gsym(*case_sym);
4313 vseti(case_reg, 0);
4314 vpushi(v1);
4315 if (v1 == v2) {
4316 gen_op(TOK_EQ);
4317 *case_sym = gtst(1, 0);
4318 } else {
4319 gen_op(TOK_GE);
4320 *case_sym = gtst(1, 0);
4321 vseti(case_reg, 0);
4322 vpushi(v2);
4323 gen_op(TOK_LE);
4324 *case_sym = gtst(1, *case_sym);
4326 gsym(b);
4327 skip(':');
4328 is_expr = 0;
4329 goto block_after_label;
4330 } else
4331 if (tok == TOK_DEFAULT) {
4332 next();
4333 skip(':');
4334 if (!def_sym)
4335 expect("switch");
4336 if (*def_sym)
4337 error("too many 'default'");
4338 *def_sym = ind;
4339 is_expr = 0;
4340 goto block_after_label;
4341 } else
4342 if (tok == TOK_GOTO) {
4343 next();
4344 if (tok == '*' && gnu_ext) {
4345 /* computed goto */
4346 next();
4347 gexpr();
4348 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4349 expect("pointer");
4350 ggoto();
4351 } else if (tok >= TOK_UIDENT) {
4352 s = label_find(tok);
4353 /* put forward definition if needed */
4354 if (!s) {
4355 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4356 } else {
4357 if (s->r == LABEL_DECLARED)
4358 s->r = LABEL_FORWARD;
4360 /* label already defined */
4361 if (s->r & LABEL_FORWARD)
4362 s->jnext = gjmp(s->jnext);
4363 else
4364 gjmp_addr(s->jnext);
4365 next();
4366 } else {
4367 expect("label identifier");
4369 skip(';');
4370 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4371 asm_instr();
4372 } else {
4373 b = is_label();
4374 if (b) {
4375 /* label case */
4376 s = label_find(b);
4377 if (s) {
4378 if (s->r == LABEL_DEFINED)
4379 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4380 gsym(s->jnext);
4381 s->r = LABEL_DEFINED;
4382 } else {
4383 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4385 s->jnext = ind;
4386 /* we accept this, but it is a mistake */
4387 block_after_label:
4388 if (tok == '}') {
4389 warning("deprecated use of label at end of compound statement");
4390 } else {
4391 if (is_expr)
4392 vpop();
4393 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4395 } else {
4396 /* expression case */
4397 if (tok != ';') {
4398 if (is_expr) {
4399 vpop();
4400 gexpr();
4401 } else {
4402 gexpr();
4403 vpop();
4406 skip(';');
4411 /* t is the array or struct type. c is the array or struct
4412 address. cur_index/cur_field is the pointer to the current
4413 value. 'size_only' is true if only size info is needed (only used
4414 in arrays) */
4415 static void decl_designator(CType *type, Section *sec, unsigned long c,
4416 int *cur_index, Sym **cur_field,
4417 int size_only)
4419 Sym *s, *f;
4420 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4421 CType type1;
4423 notfirst = 0;
4424 elem_size = 0;
4425 nb_elems = 1;
4426 if (gnu_ext && (l = is_label()) != 0)
4427 goto struct_field;
4428 while (tok == '[' || tok == '.') {
4429 if (tok == '[') {
4430 if (!(type->t & VT_ARRAY))
4431 expect("array type");
4432 s = type->ref;
4433 next();
4434 index = expr_const();
4435 if (index < 0 || (s->c >= 0 && index >= s->c))
4436 expect("invalid index");
4437 if (tok == TOK_DOTS && gnu_ext) {
4438 next();
4439 index_last = expr_const();
4440 if (index_last < 0 ||
4441 (s->c >= 0 && index_last >= s->c) ||
4442 index_last < index)
4443 expect("invalid index");
4444 } else {
4445 index_last = index;
4447 skip(']');
4448 if (!notfirst)
4449 *cur_index = index_last;
4450 type = pointed_type(type);
4451 elem_size = type_size(type, &align);
4452 c += index * elem_size;
4453 /* NOTE: we only support ranges for last designator */
4454 nb_elems = index_last - index + 1;
4455 if (nb_elems != 1) {
4456 notfirst = 1;
4457 break;
4459 } else {
4460 next();
4461 l = tok;
4462 next();
4463 struct_field:
4464 if ((type->t & VT_BTYPE) != VT_STRUCT)
4465 expect("struct/union type");
4466 s = type->ref;
4467 l |= SYM_FIELD;
4468 f = s->next;
4469 while (f) {
4470 if (f->v == l)
4471 break;
4472 f = f->next;
4474 if (!f)
4475 expect("field");
4476 if (!notfirst)
4477 *cur_field = f;
4478 /* XXX: fix this mess by using explicit storage field */
4479 type1 = f->type;
4480 type1.t |= (type->t & ~VT_TYPE);
4481 type = &type1;
4482 c += f->c;
4484 notfirst = 1;
4486 if (notfirst) {
4487 if (tok == '=') {
4488 next();
4489 } else {
4490 if (!gnu_ext)
4491 expect("=");
4493 } else {
4494 if (type->t & VT_ARRAY) {
4495 index = *cur_index;
4496 type = pointed_type(type);
4497 c += index * type_size(type, &align);
4498 } else {
4499 f = *cur_field;
4500 if (!f)
4501 error("too many field init");
4502 /* XXX: fix this mess by using explicit storage field */
4503 type1 = f->type;
4504 type1.t |= (type->t & ~VT_TYPE);
4505 type = &type1;
4506 c += f->c;
4509 decl_initializer(type, sec, c, 0, size_only);
4511 /* XXX: make it more general */
4512 if (!size_only && nb_elems > 1) {
4513 unsigned long c_end;
4514 uint8_t *src, *dst;
4515 int i;
4517 if (!sec)
4518 error("range init not supported yet for dynamic storage");
4519 c_end = c + nb_elems * elem_size;
4520 if (c_end > sec->data_allocated)
4521 section_realloc(sec, c_end);
4522 src = sec->data + c;
4523 dst = src;
4524 for(i = 1; i < nb_elems; i++) {
4525 dst += elem_size;
4526 memcpy(dst, src, elem_size);
4531 #define EXPR_VAL 0
4532 #define EXPR_CONST 1
4533 #define EXPR_ANY 2
4535 /* store a value or an expression directly in global data or in local array */
4536 static void init_putv(CType *type, Section *sec, unsigned long c,
4537 int v, int expr_type)
4539 int saved_global_expr, bt, bit_pos, bit_size;
4540 void *ptr;
4541 unsigned long long bit_mask;
4542 CType dtype;
4544 switch(expr_type) {
4545 case EXPR_VAL:
4546 vpushi(v);
4547 break;
4548 case EXPR_CONST:
4549 /* compound literals must be allocated globally in this case */
4550 saved_global_expr = global_expr;
4551 global_expr = 1;
4552 expr_const1();
4553 global_expr = saved_global_expr;
4554 /* NOTE: symbols are accepted */
4555 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4556 error("initializer element is not constant");
4557 break;
4558 case EXPR_ANY:
4559 expr_eq();
4560 break;
4563 dtype = *type;
4564 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4566 if (sec) {
4567 /* XXX: not portable */
4568 /* XXX: generate error if incorrect relocation */
4569 gen_assign_cast(&dtype);
4570 bt = type->t & VT_BTYPE;
4571 /* we'll write at most 12 bytes */
4572 if (c + 12 > sec->data_allocated) {
4573 section_realloc(sec, c + 12);
4575 ptr = sec->data + c;
4576 /* XXX: make code faster ? */
4577 if (!(type->t & VT_BITFIELD)) {
4578 bit_pos = 0;
4579 bit_size = 32;
4580 bit_mask = -1LL;
4581 } else {
4582 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4583 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4584 bit_mask = (1LL << bit_size) - 1;
4586 if ((vtop->r & VT_SYM) &&
4587 (bt == VT_BYTE ||
4588 bt == VT_SHORT ||
4589 bt == VT_DOUBLE ||
4590 bt == VT_LDOUBLE ||
4591 bt == VT_LLONG ||
4592 (bt == VT_INT && bit_size != 32)))
4593 error("initializer element is not computable at load time");
4594 switch(bt) {
4595 case VT_BOOL:
4596 vtop->c.i = (vtop->c.i != 0);
4597 case VT_BYTE:
4598 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4599 break;
4600 case VT_SHORT:
4601 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4602 break;
4603 case VT_DOUBLE:
4604 *(double *)ptr = vtop->c.d;
4605 break;
4606 case VT_LDOUBLE:
4607 *(long double *)ptr = vtop->c.ld;
4608 break;
4609 case VT_LLONG:
4610 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4611 break;
4612 default:
4613 if (vtop->r & VT_SYM) {
4614 greloc(sec, vtop->sym, c, R_DATA_PTR);
4616 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4617 break;
4619 vtop--;
4620 } else {
4621 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4622 vswap();
4623 vstore();
4624 vpop();
4628 /* put zeros for variable based init */
4629 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4631 if (sec) {
4632 /* nothing to do because globals are already set to zero */
4633 } else {
4634 vpush_global_sym(&func_old_type, TOK_memset);
4635 vseti(VT_LOCAL, c);
4636 vpushi(0);
4637 vpushi(size);
4638 gfunc_call(3);
4642 /* 't' contains the type and storage info. 'c' is the offset of the
4643 object in section 'sec'. If 'sec' is NULL, it means stack based
4644 allocation. 'first' is true if array '{' must be read (multi
4645 dimension implicit array init handling). 'size_only' is true if
4646 size only evaluation is wanted (only for arrays). */
4647 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4648 int first, int size_only)
4650 int index, array_length, n, no_oblock, nb, parlevel, i;
4651 int size1, align1, expr_type;
4652 Sym *s, *f;
4653 CType *t1;
4655 if (type->t & VT_ARRAY) {
4656 s = type->ref;
4657 n = s->c;
4658 array_length = 0;
4659 t1 = pointed_type(type);
4660 size1 = type_size(t1, &align1);
4662 no_oblock = 1;
4663 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4664 tok == '{') {
4665 skip('{');
4666 no_oblock = 0;
4669 /* only parse strings here if correct type (otherwise: handle
4670 them as ((w)char *) expressions */
4671 if ((tok == TOK_LSTR &&
4672 #ifdef TCC_TARGET_PE
4673 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4674 #else
4675 (t1->t & VT_BTYPE) == VT_INT
4676 #endif
4677 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4678 while (tok == TOK_STR || tok == TOK_LSTR) {
4679 int cstr_len, ch;
4680 CString *cstr;
4682 cstr = tokc.cstr;
4683 /* compute maximum number of chars wanted */
4684 if (tok == TOK_STR)
4685 cstr_len = cstr->size;
4686 else
4687 cstr_len = cstr->size / sizeof(nwchar_t);
4688 cstr_len--;
4689 nb = cstr_len;
4690 if (n >= 0 && nb > (n - array_length))
4691 nb = n - array_length;
4692 if (!size_only) {
4693 if (cstr_len > nb)
4694 warning("initializer-string for array is too long");
4695 /* in order to go faster for common case (char
4696 string in global variable, we handle it
4697 specifically */
4698 if (sec && tok == TOK_STR && size1 == 1) {
4699 memcpy(sec->data + c + array_length, cstr->data, nb);
4700 } else {
4701 for(i=0;i<nb;i++) {
4702 if (tok == TOK_STR)
4703 ch = ((unsigned char *)cstr->data)[i];
4704 else
4705 ch = ((nwchar_t *)cstr->data)[i];
4706 init_putv(t1, sec, c + (array_length + i) * size1,
4707 ch, EXPR_VAL);
4711 array_length += nb;
4712 next();
4714 /* only add trailing zero if enough storage (no
4715 warning in this case since it is standard) */
4716 if (n < 0 || array_length < n) {
4717 if (!size_only) {
4718 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4720 array_length++;
4722 } else {
4723 index = 0;
4724 while (tok != '}') {
4725 decl_designator(type, sec, c, &index, NULL, size_only);
4726 if (n >= 0 && index >= n)
4727 error("index too large");
4728 /* must put zero in holes (note that doing it that way
4729 ensures that it even works with designators) */
4730 if (!size_only && array_length < index) {
4731 init_putz(t1, sec, c + array_length * size1,
4732 (index - array_length) * size1);
4734 index++;
4735 if (index > array_length)
4736 array_length = index;
4737 /* special test for multi dimensional arrays (may not
4738 be strictly correct if designators are used at the
4739 same time) */
4740 if (index >= n && no_oblock)
4741 break;
4742 if (tok == '}')
4743 break;
4744 skip(',');
4747 if (!no_oblock)
4748 skip('}');
4749 /* put zeros at the end */
4750 if (!size_only && n >= 0 && array_length < n) {
4751 init_putz(t1, sec, c + array_length * size1,
4752 (n - array_length) * size1);
4754 /* patch type size if needed */
4755 if (n < 0)
4756 s->c = array_length;
4757 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4758 (sec || !first || tok == '{')) {
4759 int par_count;
4761 /* NOTE: the previous test is a specific case for automatic
4762 struct/union init */
4763 /* XXX: union needs only one init */
4765 /* XXX: this test is incorrect for local initializers
4766 beginning with ( without {. It would be much more difficult
4767 to do it correctly (ideally, the expression parser should
4768 be used in all cases) */
4769 par_count = 0;
4770 if (tok == '(') {
4771 AttributeDef ad1;
4772 CType type1;
4773 next();
4774 while (tok == '(') {
4775 par_count++;
4776 next();
4778 if (!parse_btype(&type1, &ad1))
4779 expect("cast");
4780 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4781 #if 0
4782 if (!is_assignable_types(type, &type1))
4783 error("invalid type for cast");
4784 #endif
4785 skip(')');
4787 no_oblock = 1;
4788 if (first || tok == '{') {
4789 skip('{');
4790 no_oblock = 0;
4792 s = type->ref;
4793 f = s->next;
4794 array_length = 0;
4795 index = 0;
4796 n = s->c;
4797 while (tok != '}') {
4798 decl_designator(type, sec, c, NULL, &f, size_only);
4799 index = f->c;
4800 if (!size_only && array_length < index) {
4801 init_putz(type, sec, c + array_length,
4802 index - array_length);
4804 index = index + type_size(&f->type, &align1);
4805 if (index > array_length)
4806 array_length = index;
4808 /* gr: skip fields from same union - ugly. */
4809 while (f->next) {
4810 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
4811 /* test for same offset */
4812 if (f->next->c != f->c)
4813 break;
4814 /* if yes, test for bitfield shift */
4815 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
4816 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4817 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4818 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
4819 if (bit_pos_1 != bit_pos_2)
4820 break;
4822 f = f->next;
4825 f = f->next;
4826 if (no_oblock && f == NULL)
4827 break;
4828 if (tok == '}')
4829 break;
4830 skip(',');
4832 /* put zeros at the end */
4833 if (!size_only && array_length < n) {
4834 init_putz(type, sec, c + array_length,
4835 n - array_length);
4837 if (!no_oblock)
4838 skip('}');
4839 while (par_count) {
4840 skip(')');
4841 par_count--;
4843 } else if (tok == '{') {
4844 next();
4845 decl_initializer(type, sec, c, first, size_only);
4846 skip('}');
4847 } else if (size_only) {
4848 /* just skip expression */
4849 parlevel = 0;
4850 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4851 tok != -1) {
4852 if (tok == '(')
4853 parlevel++;
4854 else if (tok == ')')
4855 parlevel--;
4856 next();
4858 } else {
4859 /* currently, we always use constant expression for globals
4860 (may change for scripting case) */
4861 expr_type = EXPR_CONST;
4862 if (!sec)
4863 expr_type = EXPR_ANY;
4864 init_putv(type, sec, c, 0, expr_type);
4868 /* parse an initializer for type 't' if 'has_init' is non zero, and
4869 allocate space in local or global data space ('r' is either
4870 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
4871 variable 'v' of scope 'scope' is declared before initializers are
4872 parsed. If 'v' is zero, then a reference to the new object is put
4873 in the value stack. If 'has_init' is 2, a special parsing is done
4874 to handle string constants. */
4875 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
4876 int has_init, int v, int scope)
4878 int size, align, addr, data_offset;
4879 int level;
4880 ParseState saved_parse_state = {0};
4881 TokenString init_str;
4882 Section *sec;
4884 size = type_size(type, &align);
4885 /* If unknown size, we must evaluate it before
4886 evaluating initializers because
4887 initializers can generate global data too
4888 (e.g. string pointers or ISOC99 compound
4889 literals). It also simplifies local
4890 initializers handling */
4891 tok_str_new(&init_str);
4892 if (size < 0) {
4893 if (!has_init)
4894 error("unknown type size");
4895 /* get all init string */
4896 if (has_init == 2) {
4897 /* only get strings */
4898 while (tok == TOK_STR || tok == TOK_LSTR) {
4899 tok_str_add_tok(&init_str);
4900 next();
4902 } else {
4903 level = 0;
4904 while (level > 0 || (tok != ',' && tok != ';')) {
4905 if (tok < 0)
4906 error("unexpected end of file in initializer");
4907 tok_str_add_tok(&init_str);
4908 if (tok == '{')
4909 level++;
4910 else if (tok == '}') {
4911 level--;
4912 if (level <= 0) {
4913 next();
4914 break;
4917 next();
4920 tok_str_add(&init_str, -1);
4921 tok_str_add(&init_str, 0);
4923 /* compute size */
4924 save_parse_state(&saved_parse_state);
4926 macro_ptr = init_str.str;
4927 next();
4928 decl_initializer(type, NULL, 0, 1, 1);
4929 /* prepare second initializer parsing */
4930 macro_ptr = init_str.str;
4931 next();
4933 /* if still unknown size, error */
4934 size = type_size(type, &align);
4935 if (size < 0)
4936 error("unknown type size");
4938 /* take into account specified alignment if bigger */
4939 if (ad->aligned) {
4940 if (ad->aligned > align)
4941 align = ad->aligned;
4942 } else if (ad->packed) {
4943 align = 1;
4945 if ((r & VT_VALMASK) == VT_LOCAL) {
4946 sec = NULL;
4947 #ifdef CONFIG_TCC_BCHECK
4948 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
4949 loc--;
4950 #endif
4951 loc = (loc - size) & -align;
4952 addr = loc;
4953 #ifdef CONFIG_TCC_BCHECK
4954 /* handles bounds */
4955 /* XXX: currently, since we do only one pass, we cannot track
4956 '&' operators, so we add only arrays */
4957 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
4958 unsigned long *bounds_ptr;
4959 /* add padding between regions */
4960 loc--;
4961 /* then add local bound info */
4962 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
4963 bounds_ptr[0] = addr;
4964 bounds_ptr[1] = size;
4966 #endif
4967 if (v) {
4968 /* local variable */
4969 sym_push(v, type, r, addr);
4970 } else {
4971 /* push local reference */
4972 vset(type, r, addr);
4974 } else {
4975 Sym *sym;
4977 sym = NULL;
4978 if (v && scope == VT_CONST) {
4979 /* see if the symbol was already defined */
4980 sym = sym_find(v);
4981 if (sym) {
4982 if (!is_compatible_types(&sym->type, type))
4983 error("incompatible types for redefinition of '%s'",
4984 get_tok_str(v, NULL));
4985 if (sym->type.t & VT_EXTERN) {
4986 /* if the variable is extern, it was not allocated */
4987 sym->type.t &= ~VT_EXTERN;
4988 /* set array size if it was ommited in extern
4989 declaration */
4990 if ((sym->type.t & VT_ARRAY) &&
4991 sym->type.ref->c < 0 &&
4992 type->ref->c >= 0)
4993 sym->type.ref->c = type->ref->c;
4994 } else {
4995 /* we accept several definitions of the same
4996 global variable. this is tricky, because we
4997 must play with the SHN_COMMON type of the symbol */
4998 /* XXX: should check if the variable was already
4999 initialized. It is incorrect to initialized it
5000 twice */
5001 /* no init data, we won't add more to the symbol */
5002 if (!has_init)
5003 goto no_alloc;
5008 /* allocate symbol in corresponding section */
5009 sec = ad->section;
5010 if (!sec) {
5011 if (has_init)
5012 sec = data_section;
5013 else if (tcc_state->nocommon)
5014 sec = bss_section;
5016 if (sec) {
5017 data_offset = sec->data_offset;
5018 data_offset = (data_offset + align - 1) & -align;
5019 addr = data_offset;
5020 /* very important to increment global pointer at this time
5021 because initializers themselves can create new initializers */
5022 data_offset += size;
5023 #ifdef CONFIG_TCC_BCHECK
5024 /* add padding if bound check */
5025 if (tcc_state->do_bounds_check)
5026 data_offset++;
5027 #endif
5028 sec->data_offset = data_offset;
5029 /* allocate section space to put the data */
5030 if (sec->sh_type != SHT_NOBITS &&
5031 data_offset > sec->data_allocated)
5032 section_realloc(sec, data_offset);
5033 /* align section if needed */
5034 if (align > sec->sh_addralign)
5035 sec->sh_addralign = align;
5036 } else {
5037 addr = 0; /* avoid warning */
5040 if (v) {
5041 if (scope != VT_CONST || !sym) {
5042 sym = sym_push(v, type, r | VT_SYM, 0);
5044 /* update symbol definition */
5045 if (sec) {
5046 put_extern_sym(sym, sec, addr, size);
5047 } else {
5048 ElfW(Sym) *esym;
5049 /* put a common area */
5050 put_extern_sym(sym, NULL, align, size);
5051 /* XXX: find a nicer way */
5052 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5053 esym->st_shndx = SHN_COMMON;
5055 } else {
5056 CValue cval;
5058 /* push global reference */
5059 sym = get_sym_ref(type, sec, addr, size);
5060 cval.ul = 0;
5061 vsetc(type, VT_CONST | VT_SYM, &cval);
5062 vtop->sym = sym;
5064 #ifdef CONFIG_TCC_BCHECK
5065 /* handles bounds now because the symbol must be defined
5066 before for the relocation */
5067 if (tcc_state->do_bounds_check) {
5068 unsigned long *bounds_ptr;
5070 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5071 /* then add global bound info */
5072 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5073 bounds_ptr[0] = 0; /* relocated */
5074 bounds_ptr[1] = size;
5076 #endif
5078 if (has_init) {
5079 decl_initializer(type, sec, addr, 1, 0);
5080 /* restore parse state if needed */
5081 if (init_str.str) {
5082 tok_str_free(init_str.str);
5083 restore_parse_state(&saved_parse_state);
5086 no_alloc: ;
5089 static void put_func_debug(Sym *sym)
5091 char buf[512];
5093 /* stabs info */
5094 /* XXX: we put here a dummy type */
5095 snprintf(buf, sizeof(buf), "%s:%c1",
5096 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5097 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5098 cur_text_section, sym->c);
5099 /* //gr gdb wants a line at the function */
5100 put_stabn(N_SLINE, 0, file->line_num, 0);
5101 last_ind = 0;
5102 last_line_num = 0;
5105 /* parse an old style function declaration list */
5106 /* XXX: check multiple parameter */
5107 static void func_decl_list(Sym *func_sym)
5109 AttributeDef ad;
5110 int v;
5111 Sym *s;
5112 CType btype, type;
5114 /* parse each declaration */
5115 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
5116 if (!parse_btype(&btype, &ad))
5117 expect("declaration list");
5118 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5119 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5120 tok == ';') {
5121 /* we accept no variable after */
5122 } else {
5123 for(;;) {
5124 type = btype;
5125 type_decl(&type, &ad, &v, TYPE_DIRECT);
5126 /* find parameter in function parameter list */
5127 s = func_sym->next;
5128 while (s != NULL) {
5129 if ((s->v & ~SYM_FIELD) == v)
5130 goto found;
5131 s = s->next;
5133 error("declaration for parameter '%s' but no such parameter",
5134 get_tok_str(v, NULL));
5135 found:
5136 /* check that no storage specifier except 'register' was given */
5137 if (type.t & VT_STORAGE)
5138 error("storage class specified for '%s'", get_tok_str(v, NULL));
5139 convert_parameter_type(&type);
5140 /* we can add the type (NOTE: it could be local to the function) */
5141 s->type = type;
5142 /* accept other parameters */
5143 if (tok == ',')
5144 next();
5145 else
5146 break;
5149 skip(';');
5153 /* parse a function defined by symbol 'sym' and generate its code in
5154 'cur_text_section' */
5155 static void gen_function(Sym *sym)
5157 int saved_nocode_wanted = nocode_wanted;
5158 nocode_wanted = 0;
5159 ind = cur_text_section->data_offset;
5160 /* NOTE: we patch the symbol size later */
5161 put_extern_sym(sym, cur_text_section, ind, 0);
5162 funcname = get_tok_str(sym->v, NULL);
5163 func_ind = ind;
5164 /* put debug symbol */
5165 if (tcc_state->do_debug)
5166 put_func_debug(sym);
5167 /* push a dummy symbol to enable local sym storage */
5168 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5169 gfunc_prolog(&sym->type);
5170 rsym = 0;
5171 block(NULL, NULL, NULL, NULL, 0, 0);
5172 gsym(rsym);
5173 gfunc_epilog();
5174 cur_text_section->data_offset = ind;
5175 label_pop(&global_label_stack, NULL);
5176 sym_pop(&local_stack, NULL); /* reset local stack */
5177 /* end of function */
5178 /* patch symbol size */
5179 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5180 ind - func_ind;
5181 if (tcc_state->do_debug) {
5182 put_stabn(N_FUN, 0, 0, ind - func_ind);
5184 /* It's better to crash than to generate wrong code */
5185 cur_text_section = NULL;
5186 funcname = ""; /* for safety */
5187 func_vt.t = VT_VOID; /* for safety */
5188 ind = 0; /* for safety */
5189 nocode_wanted = saved_nocode_wanted;
5192 ST_FUNC void gen_inline_functions(void)
5194 Sym *sym;
5195 int *str, inline_generated, i;
5196 struct InlineFunc *fn;
5198 /* iterate while inline function are referenced */
5199 for(;;) {
5200 inline_generated = 0;
5201 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5202 fn = tcc_state->inline_fns[i];
5203 sym = fn->sym;
5204 if (sym && sym->c) {
5205 /* the function was used: generate its code and
5206 convert it to a normal function */
5207 str = fn->token_str;
5208 fn->sym = NULL;
5209 if (file)
5210 strcpy(file->filename, fn->filename);
5211 sym->r = VT_SYM | VT_CONST;
5212 sym->type.t &= ~VT_INLINE;
5214 macro_ptr = str;
5215 next();
5216 cur_text_section = text_section;
5217 gen_function(sym);
5218 macro_ptr = NULL; /* fail safe */
5220 inline_generated = 1;
5223 if (!inline_generated)
5224 break;
5226 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5227 fn = tcc_state->inline_fns[i];
5228 str = fn->token_str;
5229 tok_str_free(str);
5231 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5234 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5235 ST_FUNC void decl(int l)
5237 int v, has_init, r;
5238 CType type, btype;
5239 Sym *sym;
5240 AttributeDef ad;
5242 while (1) {
5243 if (!parse_btype(&btype, &ad)) {
5244 /* skip redundant ';' */
5245 /* XXX: find more elegant solution */
5246 if (tok == ';') {
5247 next();
5248 continue;
5250 if (l == VT_CONST &&
5251 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5252 /* global asm block */
5253 asm_global_instr();
5254 continue;
5256 /* special test for old K&R protos without explicit int
5257 type. Only accepted when defining global data */
5258 if (l == VT_LOCAL || tok < TOK_DEFINE)
5259 break;
5260 btype.t = VT_INT;
5262 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5263 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5264 tok == ';') {
5265 /* we accept no variable after */
5266 next();
5267 continue;
5269 while (1) { /* iterate thru each declaration */
5270 type = btype;
5271 type_decl(&type, &ad, &v, TYPE_DIRECT);
5272 #if 0
5274 char buf[500];
5275 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5276 printf("type = '%s'\n", buf);
5278 #endif
5279 if ((type.t & VT_BTYPE) == VT_FUNC) {
5280 /* if old style function prototype, we accept a
5281 declaration list */
5282 sym = type.ref;
5283 if (sym->c == FUNC_OLD)
5284 func_decl_list(sym);
5287 if (tok == '{') {
5288 if (l == VT_LOCAL)
5289 error("cannot use local functions");
5290 if ((type.t & VT_BTYPE) != VT_FUNC)
5291 expect("function definition");
5293 /* reject abstract declarators in function definition */
5294 sym = type.ref;
5295 while ((sym = sym->next) != NULL)
5296 if (!(sym->v & ~SYM_FIELD))
5297 expect("identifier");
5299 /* XXX: cannot do better now: convert extern line to static inline */
5300 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5301 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5303 sym = sym_find(v);
5304 if (sym) {
5305 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5306 goto func_error1;
5308 r = sym->type.ref->r;
5309 /* use func_call from prototype if not defined */
5310 if (FUNC_CALL(r) != FUNC_CDECL
5311 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5312 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5314 /* use export from prototype */
5315 if (FUNC_EXPORT(r))
5316 FUNC_EXPORT(type.ref->r) = 1;
5318 /* use static from prototype */
5319 if (sym->type.t & VT_STATIC)
5320 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5322 if (!is_compatible_types(&sym->type, &type)) {
5323 func_error1:
5324 error("incompatible types for redefinition of '%s'",
5325 get_tok_str(v, NULL));
5327 /* if symbol is already defined, then put complete type */
5328 sym->type = type;
5329 } else {
5330 /* put function symbol */
5331 sym = global_identifier_push(v, type.t, 0);
5332 sym->type.ref = type.ref;
5335 /* static inline functions are just recorded as a kind
5336 of macro. Their code will be emitted at the end of
5337 the compilation unit only if they are used */
5338 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5339 (VT_INLINE | VT_STATIC)) {
5340 TokenString func_str;
5341 int block_level;
5342 struct InlineFunc *fn;
5343 const char *filename;
5345 tok_str_new(&func_str);
5347 block_level = 0;
5348 for(;;) {
5349 int t;
5350 if (tok == TOK_EOF)
5351 error("unexpected end of file");
5352 tok_str_add_tok(&func_str);
5353 t = tok;
5354 next();
5355 if (t == '{') {
5356 block_level++;
5357 } else if (t == '}') {
5358 block_level--;
5359 if (block_level == 0)
5360 break;
5363 tok_str_add(&func_str, -1);
5364 tok_str_add(&func_str, 0);
5365 filename = file ? file->filename : "";
5366 fn = tcc_malloc(sizeof *fn + strlen(filename));
5367 strcpy(fn->filename, filename);
5368 fn->sym = sym;
5369 fn->token_str = func_str.str;
5370 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5372 } else {
5373 /* compute text section */
5374 cur_text_section = ad.section;
5375 if (!cur_text_section)
5376 cur_text_section = text_section;
5377 sym->r = VT_SYM | VT_CONST;
5378 gen_function(sym);
5380 break;
5381 } else {
5382 if (btype.t & VT_TYPEDEF) {
5383 /* save typedefed type */
5384 /* XXX: test storage specifiers ? */
5385 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5386 sym->type.t |= VT_TYPEDEF;
5387 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
5388 /* external function definition */
5389 /* specific case for func_call attribute */
5390 type.ref->r = INT_ATTR(&ad);
5391 external_sym(v, &type, 0);
5392 } else {
5393 /* not lvalue if array */
5394 r = 0;
5395 if (!(type.t & VT_ARRAY))
5396 r |= lvalue_type(type.t);
5397 has_init = (tok == '=');
5398 if ((btype.t & VT_EXTERN) ||
5399 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5400 !has_init && l == VT_CONST && type.ref->c < 0)) {
5401 /* external variable */
5402 /* NOTE: as GCC, uninitialized global static
5403 arrays of null size are considered as
5404 extern */
5405 #ifdef TCC_TARGET_PE
5406 if (ad.func_import)
5407 type.t |= VT_IMPORT;
5408 #endif
5409 external_sym(v, &type, r);
5410 } else {
5411 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5412 if (type.t & VT_STATIC)
5413 r |= VT_CONST;
5414 else
5415 r |= l;
5416 if (has_init)
5417 next();
5418 #ifdef TCC_TARGET_PE
5419 if (ad.func_export)
5420 type.t |= VT_EXPORT;
5421 #endif
5422 decl_initializer_alloc(&type, &ad, r,
5423 has_init, v, l);
5426 if (tok != ',') {
5427 skip(';');
5428 break;
5430 next();