Correctly support all unary expression with sizeof
[tinycc.git] / tccgen.c
blob8af8f6913600421071ecb401fb5ae124fc0e9d63
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 constant of type "type" with useless value */
288 void vpush(CType *type)
290 CValue cval;
291 vsetc(type, VT_CONST, &cval);
294 /* push integer constant */
295 ST_FUNC void vpushi(int v)
297 CValue cval;
298 cval.i = v;
299 vsetc(&int_type, VT_CONST, &cval);
302 /* push long long constant */
303 static void vpushll(long long v)
305 CValue cval;
306 CType ctype;
307 ctype.t = VT_LLONG;
308 ctype.ref = 0;
309 cval.ull = v;
310 vsetc(&ctype, VT_CONST, &cval);
313 /* Return a static symbol pointing to a section */
314 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
316 int v;
317 Sym *sym;
319 v = anon_sym++;
320 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
321 sym->type.ref = type->ref;
322 sym->r = VT_CONST | VT_SYM;
323 put_extern_sym(sym, sec, offset, size);
324 return sym;
327 /* push a reference to a section offset by adding a dummy symbol */
328 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
330 CValue cval;
332 cval.ul = 0;
333 vsetc(type, VT_CONST | VT_SYM, &cval);
334 vtop->sym = get_sym_ref(type, sec, offset, size);
337 /* define a new external reference to a symbol 'v' of type 'u' */
338 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
340 Sym *s;
342 s = sym_find(v);
343 if (!s) {
344 /* push forward reference */
345 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
346 s->type.ref = type->ref;
347 s->r = r | VT_CONST | VT_SYM;
349 return s;
352 /* define a new external reference to a symbol 'v' of type 'u' */
353 static Sym *external_sym(int v, CType *type, int r)
355 Sym *s;
357 s = sym_find(v);
358 if (!s) {
359 /* push forward reference */
360 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
361 s->type.t |= VT_EXTERN;
362 } else if (s->type.ref == func_old_type.ref) {
363 s->type.ref = type->ref;
364 s->r = r | VT_CONST | VT_SYM;
365 s->type.t |= VT_EXTERN;
366 } else if (!is_compatible_types(&s->type, type)) {
367 error("incompatible types for redefinition of '%s'",
368 get_tok_str(v, NULL));
370 return s;
373 /* push a reference to global symbol v */
374 ST_FUNC void vpush_global_sym(CType *type, int v)
376 Sym *sym;
377 CValue cval;
379 sym = external_global_sym(v, type, 0);
380 cval.ul = 0;
381 vsetc(type, VT_CONST | VT_SYM, &cval);
382 vtop->sym = sym;
385 ST_FUNC void vset(CType *type, int r, int v)
387 CValue cval;
389 cval.i = v;
390 vsetc(type, r, &cval);
393 static void vseti(int r, int v)
395 CType type;
396 type.t = VT_INT;
397 type.ref = 0;
398 vset(&type, r, v);
401 ST_FUNC void vswap(void)
403 SValue tmp;
405 tmp = vtop[0];
406 vtop[0] = vtop[-1];
407 vtop[-1] = tmp;
410 ST_FUNC void vpushv(SValue *v)
412 if (vtop >= vstack + (VSTACK_SIZE - 1))
413 error("memory full");
414 vtop++;
415 *vtop = *v;
418 static void vdup(void)
420 vpushv(vtop);
423 /* save r to the memory stack, and mark it as being free */
424 ST_FUNC void save_reg(int r)
426 int l, saved, size, align;
427 SValue *p, sv;
428 CType *type;
430 /* modify all stack values */
431 saved = 0;
432 l = 0;
433 for(p=vstack;p<=vtop;p++) {
434 if ((p->r & VT_VALMASK) == r ||
435 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
436 /* must save value on stack if not already done */
437 if (!saved) {
438 /* NOTE: must reload 'r' because r might be equal to r2 */
439 r = p->r & VT_VALMASK;
440 /* store register in the stack */
441 type = &p->type;
442 if ((p->r & VT_LVAL) ||
443 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
444 #ifdef TCC_TARGET_X86_64
445 type = &char_pointer_type;
446 #else
447 type = &int_type;
448 #endif
449 size = type_size(type, &align);
450 loc = (loc - size) & -align;
451 sv.type.t = type->t;
452 sv.r = VT_LOCAL | VT_LVAL;
453 sv.c.ul = loc;
454 store(r, &sv);
455 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
456 /* x86 specific: need to pop fp register ST0 if saved */
457 if (r == TREG_ST0) {
458 o(0xd8dd); /* fstp %st(0) */
460 #endif
461 #ifndef TCC_TARGET_X86_64
462 /* special long long case */
463 if ((type->t & VT_BTYPE) == VT_LLONG) {
464 sv.c.ul += 4;
465 store(p->r2, &sv);
467 #endif
468 l = loc;
469 saved = 1;
471 /* mark that stack entry as being saved on the stack */
472 if (p->r & VT_LVAL) {
473 /* also clear the bounded flag because the
474 relocation address of the function was stored in
475 p->c.ul */
476 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
477 } else {
478 p->r = lvalue_type(p->type.t) | VT_LOCAL;
480 p->r2 = VT_CONST;
481 p->c.ul = l;
486 #ifdef TCC_TARGET_ARM
487 /* find a register of class 'rc2' with at most one reference on stack.
488 * If none, call get_reg(rc) */
489 ST_FUNC int get_reg_ex(int rc, int rc2)
491 int r;
492 SValue *p;
494 for(r=0;r<NB_REGS;r++) {
495 if (reg_classes[r] & rc2) {
496 int n;
497 n=0;
498 for(p = vstack; p <= vtop; p++) {
499 if ((p->r & VT_VALMASK) == r ||
500 (p->r2 & VT_VALMASK) == r)
501 n++;
503 if (n <= 1)
504 return r;
507 return get_reg(rc);
509 #endif
511 /* find a free register of class 'rc'. If none, save one register */
512 ST_FUNC int get_reg(int rc)
514 int r;
515 SValue *p;
517 /* find a free register */
518 for(r=0;r<NB_REGS;r++) {
519 if (reg_classes[r] & rc) {
520 for(p=vstack;p<=vtop;p++) {
521 if ((p->r & VT_VALMASK) == r ||
522 (p->r2 & VT_VALMASK) == r)
523 goto notfound;
525 return r;
527 notfound: ;
530 /* no register left : free the first one on the stack (VERY
531 IMPORTANT to start from the bottom to ensure that we don't
532 spill registers used in gen_opi()) */
533 for(p=vstack;p<=vtop;p++) {
534 r = p->r & VT_VALMASK;
535 if (r < VT_CONST && (reg_classes[r] & rc))
536 goto save_found;
537 /* also look at second register (if long long) */
538 r = p->r2 & VT_VALMASK;
539 if (r < VT_CONST && (reg_classes[r] & rc)) {
540 save_found:
541 save_reg(r);
542 return r;
545 /* Should never comes here */
546 return -1;
549 /* save registers up to (vtop - n) stack entry */
550 ST_FUNC void save_regs(int n)
552 int r;
553 SValue *p, *p1;
554 p1 = vtop - n;
555 for(p = vstack;p <= p1; p++) {
556 r = p->r & VT_VALMASK;
557 if (r < VT_CONST) {
558 save_reg(r);
563 /* move register 's' to 'r', and flush previous value of r to memory
564 if needed */
565 static void move_reg(int r, int s)
567 SValue sv;
569 if (r != s) {
570 save_reg(r);
571 sv.type.t = VT_INT;
572 sv.r = s;
573 sv.c.ul = 0;
574 load(r, &sv);
578 /* get address of vtop (vtop MUST BE an lvalue) */
579 static void gaddrof(void)
581 vtop->r &= ~VT_LVAL;
582 /* tricky: if saved lvalue, then we can go back to lvalue */
583 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
584 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
587 #ifdef CONFIG_TCC_BCHECK
588 /* generate lvalue bound code */
589 static void gbound(void)
591 int lval_type;
592 CType type1;
594 vtop->r &= ~VT_MUSTBOUND;
595 /* if lvalue, then use checking code before dereferencing */
596 if (vtop->r & VT_LVAL) {
597 /* if not VT_BOUNDED value, then make one */
598 if (!(vtop->r & VT_BOUNDED)) {
599 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
600 /* must save type because we must set it to int to get pointer */
601 type1 = vtop->type;
602 vtop->type.t = VT_INT;
603 gaddrof();
604 vpushi(0);
605 gen_bounded_ptr_add();
606 vtop->r |= lval_type;
607 vtop->type = type1;
609 /* then check for dereferencing */
610 gen_bounded_ptr_deref();
613 #endif
615 /* store vtop a register belonging to class 'rc'. lvalues are
616 converted to values. Cannot be used if cannot be converted to
617 register value (such as structures). */
618 ST_FUNC int gv(int rc)
620 int r, rc2, bit_pos, bit_size, size, align, i;
622 /* NOTE: get_reg can modify vstack[] */
623 if (vtop->type.t & VT_BITFIELD) {
624 CType type;
625 int bits = 32;
626 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
627 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
628 /* remove bit field info to avoid loops */
629 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
630 /* cast to int to propagate signedness in following ops */
631 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
632 type.t = VT_LLONG;
633 bits = 64;
634 } else
635 type.t = VT_INT;
636 if((vtop->type.t & VT_UNSIGNED) ||
637 (vtop->type.t & VT_BTYPE) == VT_BOOL)
638 type.t |= VT_UNSIGNED;
639 gen_cast(&type);
640 /* generate shifts */
641 vpushi(bits - (bit_pos + bit_size));
642 gen_op(TOK_SHL);
643 vpushi(bits - bit_size);
644 /* NOTE: transformed to SHR if unsigned */
645 gen_op(TOK_SAR);
646 r = gv(rc);
647 } else {
648 if (is_float(vtop->type.t) &&
649 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
650 Sym *sym;
651 int *ptr;
652 unsigned long offset;
653 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
654 CValue check;
655 #endif
657 /* XXX: unify with initializers handling ? */
658 /* CPUs usually cannot use float constants, so we store them
659 generically in data segment */
660 size = type_size(&vtop->type, &align);
661 offset = (data_section->data_offset + align - 1) & -align;
662 data_section->data_offset = offset;
663 /* XXX: not portable yet */
664 #if defined(__i386__) || defined(__x86_64__)
665 /* Zero pad x87 tenbyte long doubles */
666 if (size == LDOUBLE_SIZE)
667 vtop->c.tab[2] &= 0xffff;
668 #endif
669 ptr = section_ptr_add(data_section, size);
670 size = size >> 2;
671 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
672 check.d = 1;
673 if(check.tab[0])
674 for(i=0;i<size;i++)
675 ptr[i] = vtop->c.tab[size-1-i];
676 else
677 #endif
678 for(i=0;i<size;i++)
679 ptr[i] = vtop->c.tab[i];
680 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
681 vtop->r |= VT_LVAL | VT_SYM;
682 vtop->sym = sym;
683 vtop->c.ul = 0;
685 #ifdef CONFIG_TCC_BCHECK
686 if (vtop->r & VT_MUSTBOUND)
687 gbound();
688 #endif
690 r = vtop->r & VT_VALMASK;
691 rc2 = RC_INT;
692 if (rc == RC_IRET)
693 rc2 = RC_LRET;
694 /* need to reload if:
695 - constant
696 - lvalue (need to dereference pointer)
697 - already a register, but not in the right class */
698 if (r >= VT_CONST
699 || (vtop->r & VT_LVAL)
700 || !(reg_classes[r] & rc)
701 #ifndef TCC_TARGET_X86_64
702 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
703 #endif
706 r = get_reg(rc);
707 #ifndef TCC_TARGET_X86_64
708 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
709 int r2;
710 unsigned long long ll;
711 /* two register type load : expand to two words
712 temporarily */
713 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
714 /* load constant */
715 ll = vtop->c.ull;
716 vtop->c.ui = ll; /* first word */
717 load(r, vtop);
718 vtop->r = r; /* save register value */
719 vpushi(ll >> 32); /* second word */
720 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
721 (vtop->r & VT_LVAL)) {
722 /* We do not want to modifier the long long
723 pointer here, so the safest (and less
724 efficient) is to save all the other registers
725 in the stack. XXX: totally inefficient. */
726 save_regs(1);
727 /* load from memory */
728 load(r, vtop);
729 vdup();
730 vtop[-1].r = r; /* save register value */
731 /* increment pointer to get second word */
732 vtop->type.t = VT_INT;
733 gaddrof();
734 vpushi(4);
735 gen_op('+');
736 vtop->r |= VT_LVAL;
737 } else {
738 /* move registers */
739 load(r, vtop);
740 vdup();
741 vtop[-1].r = r; /* save register value */
742 vtop->r = vtop[-1].r2;
744 /* allocate second register */
745 r2 = get_reg(rc2);
746 load(r2, vtop);
747 vpop();
748 /* write second register */
749 vtop->r2 = r2;
750 } else
751 #endif
752 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
753 int t1, t;
754 /* lvalue of scalar type : need to use lvalue type
755 because of possible cast */
756 t = vtop->type.t;
757 t1 = t;
758 /* compute memory access type */
759 if (vtop->r & VT_LVAL_BYTE)
760 t = VT_BYTE;
761 else if (vtop->r & VT_LVAL_SHORT)
762 t = VT_SHORT;
763 if (vtop->r & VT_LVAL_UNSIGNED)
764 t |= VT_UNSIGNED;
765 vtop->type.t = t;
766 load(r, vtop);
767 /* restore wanted type */
768 vtop->type.t = t1;
769 } else {
770 /* one register type load */
771 load(r, vtop);
774 vtop->r = r;
775 #ifdef TCC_TARGET_C67
776 /* uses register pairs for doubles */
777 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
778 vtop->r2 = r+1;
779 #endif
781 return r;
784 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
785 ST_FUNC void gv2(int rc1, int rc2)
787 int v;
789 /* generate more generic register first. But VT_JMP or VT_CMP
790 values must be generated first in all cases to avoid possible
791 reload errors */
792 v = vtop[0].r & VT_VALMASK;
793 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
794 vswap();
795 gv(rc1);
796 vswap();
797 gv(rc2);
798 /* test if reload is needed for first register */
799 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
800 vswap();
801 gv(rc1);
802 vswap();
804 } else {
805 gv(rc2);
806 vswap();
807 gv(rc1);
808 vswap();
809 /* test if reload is needed for first register */
810 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
811 gv(rc2);
816 /* wrapper around RC_FRET to return a register by type */
817 static int rc_fret(int t)
819 #ifdef TCC_TARGET_X86_64
820 if (t == VT_LDOUBLE) {
821 return RC_ST0;
823 #endif
824 return RC_FRET;
827 /* wrapper around REG_FRET to return a register by type */
828 static int reg_fret(int t)
830 #ifdef TCC_TARGET_X86_64
831 if (t == VT_LDOUBLE) {
832 return TREG_ST0;
834 #endif
835 return REG_FRET;
838 /* expand long long on stack in two int registers */
839 static void lexpand(void)
841 int u;
843 u = vtop->type.t & VT_UNSIGNED;
844 gv(RC_INT);
845 vdup();
846 vtop[0].r = vtop[-1].r2;
847 vtop[0].r2 = VT_CONST;
848 vtop[-1].r2 = VT_CONST;
849 vtop[0].type.t = VT_INT | u;
850 vtop[-1].type.t = VT_INT | u;
853 #ifdef TCC_TARGET_ARM
854 /* expand long long on stack */
855 ST_FUNC void lexpand_nr(void)
857 int u,v;
859 u = vtop->type.t & VT_UNSIGNED;
860 vdup();
861 vtop->r2 = VT_CONST;
862 vtop->type.t = VT_INT | u;
863 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
864 if (v == VT_CONST) {
865 vtop[-1].c.ui = vtop->c.ull;
866 vtop->c.ui = vtop->c.ull >> 32;
867 vtop->r = VT_CONST;
868 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
869 vtop->c.ui += 4;
870 vtop->r = vtop[-1].r;
871 } else if (v > VT_CONST) {
872 vtop--;
873 lexpand();
874 } else
875 vtop->r = vtop[-1].r2;
876 vtop[-1].r2 = VT_CONST;
877 vtop[-1].type.t = VT_INT | u;
879 #endif
881 /* build a long long from two ints */
882 static void lbuild(int t)
884 gv2(RC_INT, RC_INT);
885 vtop[-1].r2 = vtop[0].r;
886 vtop[-1].type.t = t;
887 vpop();
890 /* rotate n first stack elements to the bottom
891 I1 ... In -> I2 ... In I1 [top is right]
893 static void vrotb(int n)
895 int i;
896 SValue tmp;
898 tmp = vtop[-n + 1];
899 for(i=-n+1;i!=0;i++)
900 vtop[i] = vtop[i+1];
901 vtop[0] = tmp;
904 /* rotate n first stack elements to the top
905 I1 ... In -> In I1 ... I(n-1) [top is right]
907 ST_FUNC void vrott(int n)
909 int i;
910 SValue tmp;
912 tmp = vtop[0];
913 for(i = 0;i < n - 1; i++)
914 vtop[-i] = vtop[-i - 1];
915 vtop[-n + 1] = tmp;
918 #ifdef TCC_TARGET_ARM
919 /* like vrott but in other direction
920 In ... I1 -> I(n-1) ... I1 In [top is right]
922 ST_FUNC void vnrott(int n)
924 int i;
925 SValue tmp;
927 tmp = vtop[-n + 1];
928 for(i = n - 1; i > 0; i--)
929 vtop[-i] = vtop[-i + 1];
930 vtop[0] = tmp;
932 #endif
934 /* pop stack value */
935 ST_FUNC void vpop(void)
937 int v;
938 v = vtop->r & VT_VALMASK;
939 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
940 /* for x86, we need to pop the FP stack */
941 if (v == TREG_ST0 && !nocode_wanted) {
942 o(0xd8dd); /* fstp %st(0) */
943 } else
944 #endif
945 if (v == VT_JMP || v == VT_JMPI) {
946 /* need to put correct jump if && or || without test */
947 gsym(vtop->c.ul);
949 vtop--;
952 /* convert stack entry to register and duplicate its value in another
953 register */
954 static void gv_dup(void)
956 int rc, t, r, r1;
957 SValue sv;
959 t = vtop->type.t;
960 if ((t & VT_BTYPE) == VT_LLONG) {
961 lexpand();
962 gv_dup();
963 vswap();
964 vrotb(3);
965 gv_dup();
966 vrotb(4);
967 /* stack: H L L1 H1 */
968 lbuild(t);
969 vrotb(3);
970 vrotb(3);
971 vswap();
972 lbuild(t);
973 vswap();
974 } else {
975 /* duplicate value */
976 rc = RC_INT;
977 sv.type.t = VT_INT;
978 if (is_float(t)) {
979 rc = RC_FLOAT;
980 #ifdef TCC_TARGET_X86_64
981 if ((t & VT_BTYPE) == VT_LDOUBLE) {
982 rc = RC_ST0;
984 #endif
985 sv.type.t = t;
987 r = gv(rc);
988 r1 = get_reg(rc);
989 sv.r = r;
990 sv.c.ul = 0;
991 load(r1, &sv); /* move r to r1 */
992 vdup();
993 /* duplicates value */
994 if (r != r1)
995 vtop->r = r1;
999 #ifndef TCC_TARGET_X86_64
1000 /* generate CPU independent (unsigned) long long operations */
1001 static void gen_opl(int op)
1003 int t, a, b, op1, c, i;
1004 int func;
1005 unsigned short reg_iret = REG_IRET;
1006 unsigned short reg_lret = REG_LRET;
1007 SValue tmp;
1009 switch(op) {
1010 case '/':
1011 case TOK_PDIV:
1012 func = TOK___divdi3;
1013 goto gen_func;
1014 case TOK_UDIV:
1015 func = TOK___udivdi3;
1016 goto gen_func;
1017 case '%':
1018 func = TOK___moddi3;
1019 goto gen_mod_func;
1020 case TOK_UMOD:
1021 func = TOK___umoddi3;
1022 gen_mod_func:
1023 #ifdef TCC_ARM_EABI
1024 reg_iret = TREG_R2;
1025 reg_lret = TREG_R3;
1026 #endif
1027 gen_func:
1028 /* call generic long long function */
1029 vpush_global_sym(&func_old_type, func);
1030 vrott(3);
1031 gfunc_call(2);
1032 vpushi(0);
1033 vtop->r = reg_iret;
1034 vtop->r2 = reg_lret;
1035 break;
1036 case '^':
1037 case '&':
1038 case '|':
1039 case '*':
1040 case '+':
1041 case '-':
1042 t = vtop->type.t;
1043 vswap();
1044 lexpand();
1045 vrotb(3);
1046 lexpand();
1047 /* stack: L1 H1 L2 H2 */
1048 tmp = vtop[0];
1049 vtop[0] = vtop[-3];
1050 vtop[-3] = tmp;
1051 tmp = vtop[-2];
1052 vtop[-2] = vtop[-3];
1053 vtop[-3] = tmp;
1054 vswap();
1055 /* stack: H1 H2 L1 L2 */
1056 if (op == '*') {
1057 vpushv(vtop - 1);
1058 vpushv(vtop - 1);
1059 gen_op(TOK_UMULL);
1060 lexpand();
1061 /* stack: H1 H2 L1 L2 ML MH */
1062 for(i=0;i<4;i++)
1063 vrotb(6);
1064 /* stack: ML MH H1 H2 L1 L2 */
1065 tmp = vtop[0];
1066 vtop[0] = vtop[-2];
1067 vtop[-2] = tmp;
1068 /* stack: ML MH H1 L2 H2 L1 */
1069 gen_op('*');
1070 vrotb(3);
1071 vrotb(3);
1072 gen_op('*');
1073 /* stack: ML MH M1 M2 */
1074 gen_op('+');
1075 gen_op('+');
1076 } else if (op == '+' || op == '-') {
1077 /* XXX: add non carry method too (for MIPS or alpha) */
1078 if (op == '+')
1079 op1 = TOK_ADDC1;
1080 else
1081 op1 = TOK_SUBC1;
1082 gen_op(op1);
1083 /* stack: H1 H2 (L1 op L2) */
1084 vrotb(3);
1085 vrotb(3);
1086 gen_op(op1 + 1); /* TOK_xxxC2 */
1087 } else {
1088 gen_op(op);
1089 /* stack: H1 H2 (L1 op L2) */
1090 vrotb(3);
1091 vrotb(3);
1092 /* stack: (L1 op L2) H1 H2 */
1093 gen_op(op);
1094 /* stack: (L1 op L2) (H1 op H2) */
1096 /* stack: L H */
1097 lbuild(t);
1098 break;
1099 case TOK_SAR:
1100 case TOK_SHR:
1101 case TOK_SHL:
1102 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1103 t = vtop[-1].type.t;
1104 vswap();
1105 lexpand();
1106 vrotb(3);
1107 /* stack: L H shift */
1108 c = (int)vtop->c.i;
1109 /* constant: simpler */
1110 /* NOTE: all comments are for SHL. the other cases are
1111 done by swaping words */
1112 vpop();
1113 if (op != TOK_SHL)
1114 vswap();
1115 if (c >= 32) {
1116 /* stack: L H */
1117 vpop();
1118 if (c > 32) {
1119 vpushi(c - 32);
1120 gen_op(op);
1122 if (op != TOK_SAR) {
1123 vpushi(0);
1124 } else {
1125 gv_dup();
1126 vpushi(31);
1127 gen_op(TOK_SAR);
1129 vswap();
1130 } else {
1131 vswap();
1132 gv_dup();
1133 /* stack: H L L */
1134 vpushi(c);
1135 gen_op(op);
1136 vswap();
1137 vpushi(32 - c);
1138 if (op == TOK_SHL)
1139 gen_op(TOK_SHR);
1140 else
1141 gen_op(TOK_SHL);
1142 vrotb(3);
1143 /* stack: L L H */
1144 vpushi(c);
1145 if (op == TOK_SHL)
1146 gen_op(TOK_SHL);
1147 else
1148 gen_op(TOK_SHR);
1149 gen_op('|');
1151 if (op != TOK_SHL)
1152 vswap();
1153 lbuild(t);
1154 } else {
1155 /* XXX: should provide a faster fallback on x86 ? */
1156 switch(op) {
1157 case TOK_SAR:
1158 func = TOK___ashrdi3;
1159 goto gen_func;
1160 case TOK_SHR:
1161 func = TOK___lshrdi3;
1162 goto gen_func;
1163 case TOK_SHL:
1164 func = TOK___ashldi3;
1165 goto gen_func;
1168 break;
1169 default:
1170 /* compare operations */
1171 t = vtop->type.t;
1172 vswap();
1173 lexpand();
1174 vrotb(3);
1175 lexpand();
1176 /* stack: L1 H1 L2 H2 */
1177 tmp = vtop[-1];
1178 vtop[-1] = vtop[-2];
1179 vtop[-2] = tmp;
1180 /* stack: L1 L2 H1 H2 */
1181 /* compare high */
1182 op1 = op;
1183 /* when values are equal, we need to compare low words. since
1184 the jump is inverted, we invert the test too. */
1185 if (op1 == TOK_LT)
1186 op1 = TOK_LE;
1187 else if (op1 == TOK_GT)
1188 op1 = TOK_GE;
1189 else if (op1 == TOK_ULT)
1190 op1 = TOK_ULE;
1191 else if (op1 == TOK_UGT)
1192 op1 = TOK_UGE;
1193 a = 0;
1194 b = 0;
1195 gen_op(op1);
1196 if (op1 != TOK_NE) {
1197 a = gtst(1, 0);
1199 if (op != TOK_EQ) {
1200 /* generate non equal test */
1201 /* XXX: NOT PORTABLE yet */
1202 if (a == 0) {
1203 b = gtst(0, 0);
1204 } else {
1205 #if defined(TCC_TARGET_I386)
1206 b = psym(0x850f, 0);
1207 #elif defined(TCC_TARGET_ARM)
1208 b = ind;
1209 o(0x1A000000 | encbranch(ind, 0, 1));
1210 #elif defined(TCC_TARGET_C67)
1211 error("not implemented");
1212 #else
1213 #error not supported
1214 #endif
1217 /* compare low. Always unsigned */
1218 op1 = op;
1219 if (op1 == TOK_LT)
1220 op1 = TOK_ULT;
1221 else if (op1 == TOK_LE)
1222 op1 = TOK_ULE;
1223 else if (op1 == TOK_GT)
1224 op1 = TOK_UGT;
1225 else if (op1 == TOK_GE)
1226 op1 = TOK_UGE;
1227 gen_op(op1);
1228 a = gtst(1, a);
1229 gsym(b);
1230 vseti(VT_JMPI, a);
1231 break;
1234 #endif
1236 /* handle integer constant optimizations and various machine
1237 independent opt */
1238 static void gen_opic(int op)
1240 int c1, c2, t1, t2, n;
1241 SValue *v1, *v2;
1242 long long l1, l2;
1243 typedef unsigned long long U;
1245 v1 = vtop - 1;
1246 v2 = vtop;
1247 t1 = v1->type.t & VT_BTYPE;
1248 t2 = v2->type.t & VT_BTYPE;
1250 if (t1 == VT_LLONG)
1251 l1 = v1->c.ll;
1252 else if (v1->type.t & VT_UNSIGNED)
1253 l1 = v1->c.ui;
1254 else
1255 l1 = v1->c.i;
1257 if (t2 == VT_LLONG)
1258 l2 = v2->c.ll;
1259 else if (v2->type.t & VT_UNSIGNED)
1260 l2 = v2->c.ui;
1261 else
1262 l2 = v2->c.i;
1264 /* currently, we cannot do computations with forward symbols */
1265 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1266 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1267 if (c1 && c2) {
1268 switch(op) {
1269 case '+': l1 += l2; break;
1270 case '-': l1 -= l2; break;
1271 case '&': l1 &= l2; break;
1272 case '^': l1 ^= l2; break;
1273 case '|': l1 |= l2; break;
1274 case '*': l1 *= l2; break;
1276 case TOK_PDIV:
1277 case '/':
1278 case '%':
1279 case TOK_UDIV:
1280 case TOK_UMOD:
1281 /* if division by zero, generate explicit division */
1282 if (l2 == 0) {
1283 if (const_wanted)
1284 error("division by zero in constant");
1285 goto general_case;
1287 switch(op) {
1288 default: l1 /= l2; break;
1289 case '%': l1 %= l2; break;
1290 case TOK_UDIV: l1 = (U)l1 / l2; break;
1291 case TOK_UMOD: l1 = (U)l1 % l2; break;
1293 break;
1294 case TOK_SHL: l1 <<= l2; break;
1295 case TOK_SHR: l1 = (U)l1 >> l2; break;
1296 case TOK_SAR: l1 >>= l2; break;
1297 /* tests */
1298 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1299 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1300 case TOK_EQ: l1 = l1 == l2; break;
1301 case TOK_NE: l1 = l1 != l2; break;
1302 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1303 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1304 case TOK_LT: l1 = l1 < l2; break;
1305 case TOK_GE: l1 = l1 >= l2; break;
1306 case TOK_LE: l1 = l1 <= l2; break;
1307 case TOK_GT: l1 = l1 > l2; break;
1308 /* logical */
1309 case TOK_LAND: l1 = l1 && l2; break;
1310 case TOK_LOR: l1 = l1 || l2; break;
1311 default:
1312 goto general_case;
1314 v1->c.ll = l1;
1315 vtop--;
1316 } else {
1317 /* if commutative ops, put c2 as constant */
1318 if (c1 && (op == '+' || op == '&' || op == '^' ||
1319 op == '|' || op == '*')) {
1320 vswap();
1321 c2 = c1; //c = c1, c1 = c2, c2 = c;
1322 l2 = l1; //l = l1, l1 = l2, l2 = l;
1324 /* Filter out NOP operations like x*1, x-0, x&-1... */
1325 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1326 op == TOK_PDIV) &&
1327 l2 == 1) ||
1328 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1329 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1330 l2 == 0) ||
1331 (op == '&' &&
1332 l2 == -1))) {
1333 /* nothing to do */
1334 vtop--;
1335 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1336 /* try to use shifts instead of muls or divs */
1337 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1338 n = -1;
1339 while (l2) {
1340 l2 >>= 1;
1341 n++;
1343 vtop->c.ll = n;
1344 if (op == '*')
1345 op = TOK_SHL;
1346 else if (op == TOK_PDIV)
1347 op = TOK_SAR;
1348 else
1349 op = TOK_SHR;
1351 goto general_case;
1352 } else if (c2 && (op == '+' || op == '-') &&
1353 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1354 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1355 /* symbol + constant case */
1356 if (op == '-')
1357 l2 = -l2;
1358 vtop--;
1359 vtop->c.ll += l2;
1360 } else {
1361 general_case:
1362 if (!nocode_wanted) {
1363 /* call low level op generator */
1364 if (t1 == VT_LLONG || t2 == VT_LLONG)
1365 gen_opl(op);
1366 else
1367 gen_opi(op);
1368 } else {
1369 vtop--;
1375 /* generate a floating point operation with constant propagation */
1376 static void gen_opif(int op)
1378 int c1, c2;
1379 SValue *v1, *v2;
1380 long double f1, f2;
1382 v1 = vtop - 1;
1383 v2 = vtop;
1384 /* currently, we cannot do computations with forward symbols */
1385 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1386 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1387 if (c1 && c2) {
1388 if (v1->type.t == VT_FLOAT) {
1389 f1 = v1->c.f;
1390 f2 = v2->c.f;
1391 } else if (v1->type.t == VT_DOUBLE) {
1392 f1 = v1->c.d;
1393 f2 = v2->c.d;
1394 } else {
1395 f1 = v1->c.ld;
1396 f2 = v2->c.ld;
1399 /* NOTE: we only do constant propagation if finite number (not
1400 NaN or infinity) (ANSI spec) */
1401 if (!ieee_finite(f1) || !ieee_finite(f2))
1402 goto general_case;
1404 switch(op) {
1405 case '+': f1 += f2; break;
1406 case '-': f1 -= f2; break;
1407 case '*': f1 *= f2; break;
1408 case '/':
1409 if (f2 == 0.0) {
1410 if (const_wanted)
1411 error("division by zero in constant");
1412 goto general_case;
1414 f1 /= f2;
1415 break;
1416 /* XXX: also handles tests ? */
1417 default:
1418 goto general_case;
1420 /* XXX: overflow test ? */
1421 if (v1->type.t == VT_FLOAT) {
1422 v1->c.f = f1;
1423 } else if (v1->type.t == VT_DOUBLE) {
1424 v1->c.d = f1;
1425 } else {
1426 v1->c.ld = f1;
1428 vtop--;
1429 } else {
1430 general_case:
1431 if (!nocode_wanted) {
1432 gen_opf(op);
1433 } else {
1434 vtop--;
1439 static int pointed_size(CType *type)
1441 int align;
1442 return type_size(pointed_type(type), &align);
1445 static inline int is_null_pointer(SValue *p)
1447 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1448 return 0;
1449 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1450 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
1453 static inline int is_integer_btype(int bt)
1455 return (bt == VT_BYTE || bt == VT_SHORT ||
1456 bt == VT_INT || bt == VT_LLONG);
1459 /* check types for comparison or substraction of pointers */
1460 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1462 CType *type1, *type2, tmp_type1, tmp_type2;
1463 int bt1, bt2;
1465 /* null pointers are accepted for all comparisons as gcc */
1466 if (is_null_pointer(p1) || is_null_pointer(p2))
1467 return;
1468 type1 = &p1->type;
1469 type2 = &p2->type;
1470 bt1 = type1->t & VT_BTYPE;
1471 bt2 = type2->t & VT_BTYPE;
1472 /* accept comparison between pointer and integer with a warning */
1473 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1474 if (op != TOK_LOR && op != TOK_LAND )
1475 warning("comparison between pointer and integer");
1476 return;
1479 /* both must be pointers or implicit function pointers */
1480 if (bt1 == VT_PTR) {
1481 type1 = pointed_type(type1);
1482 } else if (bt1 != VT_FUNC)
1483 goto invalid_operands;
1485 if (bt2 == VT_PTR) {
1486 type2 = pointed_type(type2);
1487 } else if (bt2 != VT_FUNC) {
1488 invalid_operands:
1489 error("invalid operands to binary %s", get_tok_str(op, NULL));
1491 if ((type1->t & VT_BTYPE) == VT_VOID ||
1492 (type2->t & VT_BTYPE) == VT_VOID)
1493 return;
1494 tmp_type1 = *type1;
1495 tmp_type2 = *type2;
1496 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1497 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1498 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1499 /* gcc-like error if '-' is used */
1500 if (op == '-')
1501 goto invalid_operands;
1502 else
1503 warning("comparison of distinct pointer types lacks a cast");
1507 /* generic gen_op: handles types problems */
1508 ST_FUNC void gen_op(int op)
1510 int u, t1, t2, bt1, bt2, t;
1511 CType type1;
1513 t1 = vtop[-1].type.t;
1514 t2 = vtop[0].type.t;
1515 bt1 = t1 & VT_BTYPE;
1516 bt2 = t2 & VT_BTYPE;
1518 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1519 /* at least one operand is a pointer */
1520 /* relationnal op: must be both pointers */
1521 if (op >= TOK_ULT && op <= TOK_LOR) {
1522 check_comparison_pointer_types(vtop - 1, vtop, op);
1523 /* pointers are handled are unsigned */
1524 #ifdef TCC_TARGET_X86_64
1525 t = VT_LLONG | VT_UNSIGNED;
1526 #else
1527 t = VT_INT | VT_UNSIGNED;
1528 #endif
1529 goto std_op;
1531 /* if both pointers, then it must be the '-' op */
1532 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1533 if (op != '-')
1534 error("cannot use pointers here");
1535 check_comparison_pointer_types(vtop - 1, vtop, op);
1536 /* XXX: check that types are compatible */
1537 u = pointed_size(&vtop[-1].type);
1538 gen_opic(op);
1539 /* set to integer type */
1540 #ifdef TCC_TARGET_X86_64
1541 vtop->type.t = VT_LLONG;
1542 #else
1543 vtop->type.t = VT_INT;
1544 #endif
1545 vpushi(u);
1546 gen_op(TOK_PDIV);
1547 } else {
1548 /* exactly one pointer : must be '+' or '-'. */
1549 if (op != '-' && op != '+')
1550 error("cannot use pointers here");
1551 /* Put pointer as first operand */
1552 if (bt2 == VT_PTR) {
1553 vswap();
1554 swap(&t1, &t2);
1556 type1 = vtop[-1].type;
1557 type1.t &= ~VT_ARRAY;
1558 u = pointed_size(&vtop[-1].type);
1559 if (u < 0)
1560 error("unknown array element size");
1561 #ifdef TCC_TARGET_X86_64
1562 vpushll(u);
1563 #else
1564 /* XXX: cast to int ? (long long case) */
1565 vpushi(u);
1566 #endif
1567 gen_op('*');
1568 #ifdef CONFIG_TCC_BCHECK
1569 /* if evaluating constant expression, no code should be
1570 generated, so no bound check */
1571 if (tcc_state->do_bounds_check && !const_wanted) {
1572 /* if bounded pointers, we generate a special code to
1573 test bounds */
1574 if (op == '-') {
1575 vpushi(0);
1576 vswap();
1577 gen_op('-');
1579 gen_bounded_ptr_add();
1580 } else
1581 #endif
1583 gen_opic(op);
1585 /* put again type if gen_opic() swaped operands */
1586 vtop->type = type1;
1588 } else if (is_float(bt1) || is_float(bt2)) {
1589 /* compute bigger type and do implicit casts */
1590 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1591 t = VT_LDOUBLE;
1592 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1593 t = VT_DOUBLE;
1594 } else {
1595 t = VT_FLOAT;
1597 /* floats can only be used for a few operations */
1598 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1599 (op < TOK_ULT || op > TOK_GT))
1600 error("invalid operands for binary operation");
1601 goto std_op;
1602 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1603 /* cast to biggest op */
1604 t = VT_LLONG;
1605 /* convert to unsigned if it does not fit in a long long */
1606 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1607 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1608 t |= VT_UNSIGNED;
1609 goto std_op;
1610 } else {
1611 /* integer operations */
1612 t = VT_INT;
1613 /* convert to unsigned if it does not fit in an integer */
1614 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1615 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1616 t |= VT_UNSIGNED;
1617 std_op:
1618 /* XXX: currently, some unsigned operations are explicit, so
1619 we modify them here */
1620 if (t & VT_UNSIGNED) {
1621 if (op == TOK_SAR)
1622 op = TOK_SHR;
1623 else if (op == '/')
1624 op = TOK_UDIV;
1625 else if (op == '%')
1626 op = TOK_UMOD;
1627 else if (op == TOK_LT)
1628 op = TOK_ULT;
1629 else if (op == TOK_GT)
1630 op = TOK_UGT;
1631 else if (op == TOK_LE)
1632 op = TOK_ULE;
1633 else if (op == TOK_GE)
1634 op = TOK_UGE;
1636 vswap();
1637 type1.t = t;
1638 gen_cast(&type1);
1639 vswap();
1640 /* special case for shifts and long long: we keep the shift as
1641 an integer */
1642 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1643 type1.t = VT_INT;
1644 gen_cast(&type1);
1645 if (is_float(t))
1646 gen_opif(op);
1647 else
1648 gen_opic(op);
1649 if (op >= TOK_ULT && op <= TOK_GT) {
1650 /* relationnal op: the result is an int */
1651 vtop->type.t = VT_INT;
1652 } else {
1653 vtop->type.t = t;
1658 #ifndef TCC_TARGET_ARM
1659 /* generic itof for unsigned long long case */
1660 static void gen_cvt_itof1(int t)
1662 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1663 (VT_LLONG | VT_UNSIGNED)) {
1665 if (t == VT_FLOAT)
1666 vpush_global_sym(&func_old_type, TOK___floatundisf);
1667 #if LDOUBLE_SIZE != 8
1668 else if (t == VT_LDOUBLE)
1669 vpush_global_sym(&func_old_type, TOK___floatundixf);
1670 #endif
1671 else
1672 vpush_global_sym(&func_old_type, TOK___floatundidf);
1673 vrott(2);
1674 gfunc_call(1);
1675 vpushi(0);
1676 vtop->r = reg_fret(t);
1677 } else {
1678 gen_cvt_itof(t);
1681 #endif
1683 /* generic ftoi for unsigned long long case */
1684 static void gen_cvt_ftoi1(int t)
1686 int st;
1688 if (t == (VT_LLONG | VT_UNSIGNED)) {
1689 /* not handled natively */
1690 st = vtop->type.t & VT_BTYPE;
1691 if (st == VT_FLOAT)
1692 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1693 #if LDOUBLE_SIZE != 8
1694 else if (st == VT_LDOUBLE)
1695 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1696 #endif
1697 else
1698 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1699 vrott(2);
1700 gfunc_call(1);
1701 vpushi(0);
1702 vtop->r = REG_IRET;
1703 vtop->r2 = REG_LRET;
1704 } else {
1705 gen_cvt_ftoi(t);
1709 /* force char or short cast */
1710 static void force_charshort_cast(int t)
1712 int bits, dbt;
1713 dbt = t & VT_BTYPE;
1714 /* XXX: add optimization if lvalue : just change type and offset */
1715 if (dbt == VT_BYTE)
1716 bits = 8;
1717 else
1718 bits = 16;
1719 if (t & VT_UNSIGNED) {
1720 vpushi((1 << bits) - 1);
1721 gen_op('&');
1722 } else {
1723 bits = 32 - bits;
1724 vpushi(bits);
1725 gen_op(TOK_SHL);
1726 /* result must be signed or the SAR is converted to an SHL
1727 This was not the case when "t" was a signed short
1728 and the last value on the stack was an unsigned int */
1729 vtop->type.t &= ~VT_UNSIGNED;
1730 vpushi(bits);
1731 gen_op(TOK_SAR);
1735 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1736 static void gen_cast(CType *type)
1738 int sbt, dbt, sf, df, c, p;
1740 /* special delayed cast for char/short */
1741 /* XXX: in some cases (multiple cascaded casts), it may still
1742 be incorrect */
1743 if (vtop->r & VT_MUSTCAST) {
1744 vtop->r &= ~VT_MUSTCAST;
1745 force_charshort_cast(vtop->type.t);
1748 /* bitfields first get cast to ints */
1749 if (vtop->type.t & VT_BITFIELD) {
1750 gv(RC_INT);
1753 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1754 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1756 if (sbt != dbt) {
1757 sf = is_float(sbt);
1758 df = is_float(dbt);
1759 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1760 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1761 if (c) {
1762 /* constant case: we can do it now */
1763 /* XXX: in ISOC, cannot do it if error in convert */
1764 if (sbt == VT_FLOAT)
1765 vtop->c.ld = vtop->c.f;
1766 else if (sbt == VT_DOUBLE)
1767 vtop->c.ld = vtop->c.d;
1769 if (df) {
1770 if ((sbt & VT_BTYPE) == VT_LLONG) {
1771 if (sbt & VT_UNSIGNED)
1772 vtop->c.ld = vtop->c.ull;
1773 else
1774 vtop->c.ld = vtop->c.ll;
1775 } else if(!sf) {
1776 if (sbt & VT_UNSIGNED)
1777 vtop->c.ld = vtop->c.ui;
1778 else
1779 vtop->c.ld = vtop->c.i;
1782 if (dbt == VT_FLOAT)
1783 vtop->c.f = (float)vtop->c.ld;
1784 else if (dbt == VT_DOUBLE)
1785 vtop->c.d = (double)vtop->c.ld;
1786 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1787 vtop->c.ull = (unsigned long long)vtop->c.ld;
1788 } else if (sf && dbt == VT_BOOL) {
1789 vtop->c.i = (vtop->c.ld != 0);
1790 } else {
1791 if(sf)
1792 vtop->c.ll = (long long)vtop->c.ld;
1793 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1794 vtop->c.ll = vtop->c.ull;
1795 else if (sbt & VT_UNSIGNED)
1796 vtop->c.ll = vtop->c.ui;
1797 #ifdef TCC_TARGET_X86_64
1798 else if (sbt == VT_PTR)
1800 #endif
1801 else if (sbt != VT_LLONG)
1802 vtop->c.ll = vtop->c.i;
1804 if (dbt == (VT_LLONG|VT_UNSIGNED))
1805 vtop->c.ull = vtop->c.ll;
1806 else if (dbt == VT_BOOL)
1807 vtop->c.i = (vtop->c.ll != 0);
1808 else if (dbt != VT_LLONG) {
1809 int s = 0;
1810 if ((dbt & VT_BTYPE) == VT_BYTE)
1811 s = 24;
1812 else if ((dbt & VT_BTYPE) == VT_SHORT)
1813 s = 16;
1815 if(dbt & VT_UNSIGNED)
1816 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1817 else
1818 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1821 } else if (p && dbt == VT_BOOL) {
1822 vtop->r = VT_CONST;
1823 vtop->c.i = 1;
1824 } else if (!nocode_wanted) {
1825 /* non constant case: generate code */
1826 if (sf && df) {
1827 /* convert from fp to fp */
1828 gen_cvt_ftof(dbt);
1829 } else if (df) {
1830 /* convert int to fp */
1831 gen_cvt_itof1(dbt);
1832 } else if (sf) {
1833 /* convert fp to int */
1834 if (dbt == VT_BOOL) {
1835 vpushi(0);
1836 gen_op(TOK_NE);
1837 } else {
1838 /* we handle char/short/etc... with generic code */
1839 if (dbt != (VT_INT | VT_UNSIGNED) &&
1840 dbt != (VT_LLONG | VT_UNSIGNED) &&
1841 dbt != VT_LLONG)
1842 dbt = VT_INT;
1843 gen_cvt_ftoi1(dbt);
1844 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1845 /* additional cast for char/short... */
1846 vtop->type.t = dbt;
1847 gen_cast(type);
1850 #ifndef TCC_TARGET_X86_64
1851 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1852 if ((sbt & VT_BTYPE) != VT_LLONG) {
1853 /* scalar to long long */
1854 /* machine independent conversion */
1855 gv(RC_INT);
1856 /* generate high word */
1857 if (sbt == (VT_INT | VT_UNSIGNED)) {
1858 vpushi(0);
1859 gv(RC_INT);
1860 } else {
1861 if (sbt == VT_PTR) {
1862 /* cast from pointer to int before we apply
1863 shift operation, which pointers don't support*/
1864 gen_cast(&int_type);
1866 gv_dup();
1867 vpushi(31);
1868 gen_op(TOK_SAR);
1870 /* patch second register */
1871 vtop[-1].r2 = vtop->r;
1872 vpop();
1874 #else
1875 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1876 (dbt & VT_BTYPE) == VT_PTR) {
1877 /* XXX: not sure if this is perfect... need more tests */
1878 if ((sbt & VT_BTYPE) != VT_LLONG) {
1879 int r = gv(RC_INT);
1880 if (sbt != (VT_INT | VT_UNSIGNED) &&
1881 sbt != VT_PTR && sbt != VT_FUNC) {
1882 /* x86_64 specific: movslq */
1883 o(0x6348);
1884 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1887 #endif
1888 } else if (dbt == VT_BOOL) {
1889 /* scalar to bool */
1890 vpushi(0);
1891 gen_op(TOK_NE);
1892 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1893 (dbt & VT_BTYPE) == VT_SHORT) {
1894 if (sbt == VT_PTR) {
1895 vtop->type.t = VT_INT;
1896 warning("nonportable conversion from pointer to char/short");
1898 force_charshort_cast(dbt);
1899 } else if ((dbt & VT_BTYPE) == VT_INT) {
1900 /* scalar to int */
1901 if (sbt == VT_LLONG) {
1902 /* from long long: just take low order word */
1903 lexpand();
1904 vpop();
1906 /* if lvalue and single word type, nothing to do because
1907 the lvalue already contains the real type size (see
1908 VT_LVAL_xxx constants) */
1911 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
1912 /* if we are casting between pointer types,
1913 we must update the VT_LVAL_xxx size */
1914 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1915 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
1917 vtop->type = *type;
1920 /* return type size. Put alignment at 'a' */
1921 ST_FUNC int type_size(CType *type, int *a)
1923 Sym *s;
1924 int bt;
1926 bt = type->t & VT_BTYPE;
1927 if (bt == VT_STRUCT) {
1928 /* struct/union */
1929 s = type->ref;
1930 *a = s->r;
1931 return s->c;
1932 } else if (bt == VT_PTR) {
1933 if (type->t & VT_ARRAY) {
1934 int ts;
1936 s = type->ref;
1937 ts = type_size(&s->type, a);
1939 if (ts < 0 && s->c < 0)
1940 ts = -ts;
1942 return ts * s->c;
1943 } else {
1944 *a = PTR_SIZE;
1945 return PTR_SIZE;
1947 } else if (bt == VT_LDOUBLE) {
1948 *a = LDOUBLE_ALIGN;
1949 return LDOUBLE_SIZE;
1950 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
1951 #ifdef TCC_TARGET_I386
1952 #ifdef TCC_TARGET_PE
1953 *a = 8;
1954 #else
1955 *a = 4;
1956 #endif
1957 #elif defined(TCC_TARGET_ARM)
1958 #ifdef TCC_ARM_EABI
1959 *a = 8;
1960 #else
1961 *a = 4;
1962 #endif
1963 #else
1964 *a = 8;
1965 #endif
1966 return 8;
1967 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
1968 *a = 4;
1969 return 4;
1970 } else if (bt == VT_SHORT) {
1971 *a = 2;
1972 return 2;
1973 } else {
1974 /* char, void, function, _Bool */
1975 *a = 1;
1976 return 1;
1980 /* return the pointed type of t */
1981 static inline CType *pointed_type(CType *type)
1983 return &type->ref->type;
1986 /* modify type so that its it is a pointer to type. */
1987 ST_FUNC void mk_pointer(CType *type)
1989 Sym *s;
1990 s = sym_push(SYM_FIELD, type, 0, -1);
1991 type->t = VT_PTR | (type->t & ~VT_TYPE);
1992 type->ref = s;
1995 /* compare function types. OLD functions match any new functions */
1996 static int is_compatible_func(CType *type1, CType *type2)
1998 Sym *s1, *s2;
2000 s1 = type1->ref;
2001 s2 = type2->ref;
2002 if (!is_compatible_types(&s1->type, &s2->type))
2003 return 0;
2004 /* check func_call */
2005 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2006 return 0;
2007 /* XXX: not complete */
2008 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2009 return 1;
2010 if (s1->c != s2->c)
2011 return 0;
2012 while (s1 != NULL) {
2013 if (s2 == NULL)
2014 return 0;
2015 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2016 return 0;
2017 s1 = s1->next;
2018 s2 = s2->next;
2020 if (s2)
2021 return 0;
2022 return 1;
2025 /* return true if type1 and type2 are the same. If unqualified is
2026 true, qualifiers on the types are ignored.
2028 - enums are not checked as gcc __builtin_types_compatible_p ()
2030 static int compare_types(CType *type1, CType *type2, int unqualified)
2032 int bt1, t1, t2;
2034 t1 = type1->t & VT_TYPE;
2035 t2 = type2->t & VT_TYPE;
2036 if (unqualified) {
2037 /* strip qualifiers before comparing */
2038 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2039 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2041 /* XXX: bitfields ? */
2042 if (t1 != t2)
2043 return 0;
2044 /* test more complicated cases */
2045 bt1 = t1 & VT_BTYPE;
2046 if (bt1 == VT_PTR) {
2047 type1 = pointed_type(type1);
2048 type2 = pointed_type(type2);
2049 return is_compatible_types(type1, type2);
2050 } else if (bt1 == VT_STRUCT) {
2051 return (type1->ref == type2->ref);
2052 } else if (bt1 == VT_FUNC) {
2053 return is_compatible_func(type1, type2);
2054 } else {
2055 return 1;
2059 /* return true if type1 and type2 are exactly the same (including
2060 qualifiers).
2062 static int is_compatible_types(CType *type1, CType *type2)
2064 return compare_types(type1,type2,0);
2067 /* return true if type1 and type2 are the same (ignoring qualifiers).
2069 static int is_compatible_parameter_types(CType *type1, CType *type2)
2071 return compare_types(type1,type2,1);
2074 /* print a type. If 'varstr' is not NULL, then the variable is also
2075 printed in the type */
2076 /* XXX: union */
2077 /* XXX: add array and function pointers */
2078 static void type_to_str(char *buf, int buf_size,
2079 CType *type, const char *varstr)
2081 int bt, v, t;
2082 Sym *s, *sa;
2083 char buf1[256];
2084 const char *tstr;
2086 t = type->t & VT_TYPE;
2087 bt = t & VT_BTYPE;
2088 buf[0] = '\0';
2089 if (t & VT_CONSTANT)
2090 pstrcat(buf, buf_size, "const ");
2091 if (t & VT_VOLATILE)
2092 pstrcat(buf, buf_size, "volatile ");
2093 if (t & VT_UNSIGNED)
2094 pstrcat(buf, buf_size, "unsigned ");
2095 switch(bt) {
2096 case VT_VOID:
2097 tstr = "void";
2098 goto add_tstr;
2099 case VT_BOOL:
2100 tstr = "_Bool";
2101 goto add_tstr;
2102 case VT_BYTE:
2103 tstr = "char";
2104 goto add_tstr;
2105 case VT_SHORT:
2106 tstr = "short";
2107 goto add_tstr;
2108 case VT_INT:
2109 tstr = "int";
2110 goto add_tstr;
2111 case VT_LONG:
2112 tstr = "long";
2113 goto add_tstr;
2114 case VT_LLONG:
2115 tstr = "long long";
2116 goto add_tstr;
2117 case VT_FLOAT:
2118 tstr = "float";
2119 goto add_tstr;
2120 case VT_DOUBLE:
2121 tstr = "double";
2122 goto add_tstr;
2123 case VT_LDOUBLE:
2124 tstr = "long double";
2125 add_tstr:
2126 pstrcat(buf, buf_size, tstr);
2127 break;
2128 case VT_ENUM:
2129 case VT_STRUCT:
2130 if (bt == VT_STRUCT)
2131 tstr = "struct ";
2132 else
2133 tstr = "enum ";
2134 pstrcat(buf, buf_size, tstr);
2135 v = type->ref->v & ~SYM_STRUCT;
2136 if (v >= SYM_FIRST_ANOM)
2137 pstrcat(buf, buf_size, "<anonymous>");
2138 else
2139 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2140 break;
2141 case VT_FUNC:
2142 s = type->ref;
2143 type_to_str(buf, buf_size, &s->type, varstr);
2144 pstrcat(buf, buf_size, "(");
2145 sa = s->next;
2146 while (sa != NULL) {
2147 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2148 pstrcat(buf, buf_size, buf1);
2149 sa = sa->next;
2150 if (sa)
2151 pstrcat(buf, buf_size, ", ");
2153 pstrcat(buf, buf_size, ")");
2154 goto no_var;
2155 case VT_PTR:
2156 s = type->ref;
2157 pstrcpy(buf1, sizeof(buf1), "*");
2158 if (varstr)
2159 pstrcat(buf1, sizeof(buf1), varstr);
2160 type_to_str(buf, buf_size, &s->type, buf1);
2161 goto no_var;
2163 if (varstr) {
2164 pstrcat(buf, buf_size, " ");
2165 pstrcat(buf, buf_size, varstr);
2167 no_var: ;
2170 /* verify type compatibility to store vtop in 'dt' type, and generate
2171 casts if needed. */
2172 static void gen_assign_cast(CType *dt)
2174 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2175 char buf1[256], buf2[256];
2176 int dbt, sbt;
2178 st = &vtop->type; /* source type */
2179 dbt = dt->t & VT_BTYPE;
2180 sbt = st->t & VT_BTYPE;
2181 if (dt->t & VT_CONSTANT)
2182 warning("assignment of read-only location");
2183 switch(dbt) {
2184 case VT_PTR:
2185 /* special cases for pointers */
2186 /* '0' can also be a pointer */
2187 if (is_null_pointer(vtop))
2188 goto type_ok;
2189 /* accept implicit pointer to integer cast with warning */
2190 if (is_integer_btype(sbt)) {
2191 warning("assignment makes pointer from integer without a cast");
2192 goto type_ok;
2194 type1 = pointed_type(dt);
2195 /* a function is implicitely a function pointer */
2196 if (sbt == VT_FUNC) {
2197 if ((type1->t & VT_BTYPE) != VT_VOID &&
2198 !is_compatible_types(pointed_type(dt), st))
2199 warning("assignment from incompatible pointer type");
2200 goto type_ok;
2202 if (sbt != VT_PTR)
2203 goto error;
2204 type2 = pointed_type(st);
2205 if ((type1->t & VT_BTYPE) == VT_VOID ||
2206 (type2->t & VT_BTYPE) == VT_VOID) {
2207 /* void * can match anything */
2208 } else {
2209 /* exact type match, except for unsigned */
2210 tmp_type1 = *type1;
2211 tmp_type2 = *type2;
2212 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2213 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2214 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2215 warning("assignment from incompatible pointer type");
2217 /* check const and volatile */
2218 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2219 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2220 warning("assignment discards qualifiers from pointer target type");
2221 break;
2222 case VT_BYTE:
2223 case VT_SHORT:
2224 case VT_INT:
2225 case VT_LLONG:
2226 if (sbt == VT_PTR || sbt == VT_FUNC) {
2227 warning("assignment makes integer from pointer without a cast");
2229 /* XXX: more tests */
2230 break;
2231 case VT_STRUCT:
2232 tmp_type1 = *dt;
2233 tmp_type2 = *st;
2234 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2235 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2236 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2237 error:
2238 type_to_str(buf1, sizeof(buf1), st, NULL);
2239 type_to_str(buf2, sizeof(buf2), dt, NULL);
2240 error("cannot cast '%s' to '%s'", buf1, buf2);
2242 break;
2244 type_ok:
2245 gen_cast(dt);
2248 /* store vtop in lvalue pushed on stack */
2249 ST_FUNC void vstore(void)
2251 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2253 ft = vtop[-1].type.t;
2254 sbt = vtop->type.t & VT_BTYPE;
2255 dbt = ft & VT_BTYPE;
2256 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2257 (sbt == VT_INT && dbt == VT_SHORT)) {
2258 /* optimize char/short casts */
2259 delayed_cast = VT_MUSTCAST;
2260 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2261 /* XXX: factorize */
2262 if (ft & VT_CONSTANT)
2263 warning("assignment of read-only location");
2264 } else {
2265 delayed_cast = 0;
2266 if (!(ft & VT_BITFIELD))
2267 gen_assign_cast(&vtop[-1].type);
2270 if (sbt == VT_STRUCT) {
2271 /* if structure, only generate pointer */
2272 /* structure assignment : generate memcpy */
2273 /* XXX: optimize if small size */
2274 if (!nocode_wanted) {
2275 size = type_size(&vtop->type, &align);
2277 /* destination */
2278 vswap();
2279 vtop->type.t = VT_PTR;
2280 gaddrof();
2282 /* address of memcpy() */
2283 #ifdef TCC_ARM_EABI
2284 if(!(align & 7))
2285 vpush_global_sym(&func_old_type, TOK_memcpy8);
2286 else if(!(align & 3))
2287 vpush_global_sym(&func_old_type, TOK_memcpy4);
2288 else
2289 #endif
2290 vpush_global_sym(&func_old_type, TOK_memcpy);
2292 vswap();
2293 /* source */
2294 vpushv(vtop - 2);
2295 vtop->type.t = VT_PTR;
2296 gaddrof();
2297 /* type size */
2298 vpushi(size);
2299 gfunc_call(3);
2300 } else {
2301 vswap();
2302 vpop();
2304 /* leave source on stack */
2305 } else if (ft & VT_BITFIELD) {
2306 /* bitfield store handling */
2307 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2308 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2309 /* remove bit field info to avoid loops */
2310 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2312 /* duplicate source into other register */
2313 gv_dup();
2314 vswap();
2315 vrott(3);
2317 if((ft & VT_BTYPE) == VT_BOOL) {
2318 gen_cast(&vtop[-1].type);
2319 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2322 /* duplicate destination */
2323 vdup();
2324 vtop[-1] = vtop[-2];
2326 /* mask and shift source */
2327 if((ft & VT_BTYPE) != VT_BOOL) {
2328 if((ft & VT_BTYPE) == VT_LLONG) {
2329 vpushll((1ULL << bit_size) - 1ULL);
2330 } else {
2331 vpushi((1 << bit_size) - 1);
2333 gen_op('&');
2335 vpushi(bit_pos);
2336 gen_op(TOK_SHL);
2337 /* load destination, mask and or with source */
2338 vswap();
2339 if((ft & VT_BTYPE) == VT_LLONG) {
2340 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2341 } else {
2342 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2344 gen_op('&');
2345 gen_op('|');
2346 /* store result */
2347 vstore();
2349 /* pop off shifted source from "duplicate source..." above */
2350 vpop();
2352 } else {
2353 #ifdef CONFIG_TCC_BCHECK
2354 /* bound check case */
2355 if (vtop[-1].r & VT_MUSTBOUND) {
2356 vswap();
2357 gbound();
2358 vswap();
2360 #endif
2361 if (!nocode_wanted) {
2362 rc = RC_INT;
2363 if (is_float(ft)) {
2364 rc = RC_FLOAT;
2365 #ifdef TCC_TARGET_X86_64
2366 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2367 rc = RC_ST0;
2369 #endif
2371 r = gv(rc); /* generate value */
2372 /* if lvalue was saved on stack, must read it */
2373 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2374 SValue sv;
2375 t = get_reg(RC_INT);
2376 #ifdef TCC_TARGET_X86_64
2377 sv.type.t = VT_PTR;
2378 #else
2379 sv.type.t = VT_INT;
2380 #endif
2381 sv.r = VT_LOCAL | VT_LVAL;
2382 sv.c.ul = vtop[-1].c.ul;
2383 load(t, &sv);
2384 vtop[-1].r = t | VT_LVAL;
2386 store(r, vtop - 1);
2387 #ifndef TCC_TARGET_X86_64
2388 /* two word case handling : store second register at word + 4 */
2389 if ((ft & VT_BTYPE) == VT_LLONG) {
2390 vswap();
2391 /* convert to int to increment easily */
2392 vtop->type.t = VT_INT;
2393 gaddrof();
2394 vpushi(4);
2395 gen_op('+');
2396 vtop->r |= VT_LVAL;
2397 vswap();
2398 /* XXX: it works because r2 is spilled last ! */
2399 store(vtop->r2, vtop - 1);
2401 #endif
2403 vswap();
2404 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2405 vtop->r |= delayed_cast;
2409 /* post defines POST/PRE add. c is the token ++ or -- */
2410 ST_FUNC void inc(int post, int c)
2412 test_lvalue();
2413 vdup(); /* save lvalue */
2414 if (post) {
2415 gv_dup(); /* duplicate value */
2416 vrotb(3);
2417 vrotb(3);
2419 /* add constant */
2420 vpushi(c - TOK_MID);
2421 gen_op('+');
2422 vstore(); /* store value */
2423 if (post)
2424 vpop(); /* if post op, return saved value */
2427 /* Parse GNUC __attribute__ extension. Currently, the following
2428 extensions are recognized:
2429 - aligned(n) : set data/function alignment.
2430 - packed : force data alignment to 1
2431 - section(x) : generate data/code in this section.
2432 - unused : currently ignored, but may be used someday.
2433 - regparm(n) : pass function parameters in registers (i386 only)
2435 static void parse_attribute(AttributeDef *ad)
2437 int t, n;
2439 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2440 next();
2441 skip('(');
2442 skip('(');
2443 while (tok != ')') {
2444 if (tok < TOK_IDENT)
2445 expect("attribute name");
2446 t = tok;
2447 next();
2448 switch(t) {
2449 case TOK_SECTION1:
2450 case TOK_SECTION2:
2451 skip('(');
2452 if (tok != TOK_STR)
2453 expect("section name");
2454 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2455 next();
2456 skip(')');
2457 break;
2458 case TOK_ALIGNED1:
2459 case TOK_ALIGNED2:
2460 if (tok == '(') {
2461 next();
2462 n = expr_const();
2463 if (n <= 0 || (n & (n - 1)) != 0)
2464 error("alignment must be a positive power of two");
2465 skip(')');
2466 } else {
2467 n = MAX_ALIGN;
2469 ad->aligned = n;
2470 break;
2471 case TOK_PACKED1:
2472 case TOK_PACKED2:
2473 ad->packed = 1;
2474 break;
2475 case TOK_WEAK1:
2476 case TOK_WEAK2:
2477 ad->weak = 1;
2478 break;
2479 case TOK_UNUSED1:
2480 case TOK_UNUSED2:
2481 /* currently, no need to handle it because tcc does not
2482 track unused objects */
2483 break;
2484 case TOK_NORETURN1:
2485 case TOK_NORETURN2:
2486 /* currently, no need to handle it because tcc does not
2487 track unused objects */
2488 break;
2489 case TOK_CDECL1:
2490 case TOK_CDECL2:
2491 case TOK_CDECL3:
2492 ad->func_call = FUNC_CDECL;
2493 break;
2494 case TOK_STDCALL1:
2495 case TOK_STDCALL2:
2496 case TOK_STDCALL3:
2497 ad->func_call = FUNC_STDCALL;
2498 break;
2499 #ifdef TCC_TARGET_I386
2500 case TOK_REGPARM1:
2501 case TOK_REGPARM2:
2502 skip('(');
2503 n = expr_const();
2504 if (n > 3)
2505 n = 3;
2506 else if (n < 0)
2507 n = 0;
2508 if (n > 0)
2509 ad->func_call = FUNC_FASTCALL1 + n - 1;
2510 skip(')');
2511 break;
2512 case TOK_FASTCALL1:
2513 case TOK_FASTCALL2:
2514 case TOK_FASTCALL3:
2515 ad->func_call = FUNC_FASTCALLW;
2516 break;
2517 #endif
2518 case TOK_MODE:
2519 skip('(');
2520 switch(tok) {
2521 case TOK_MODE_DI:
2522 ad->mode = VT_LLONG + 1;
2523 break;
2524 case TOK_MODE_HI:
2525 ad->mode = VT_SHORT + 1;
2526 break;
2527 case TOK_MODE_SI:
2528 ad->mode = VT_INT + 1;
2529 break;
2530 default:
2531 warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2532 break;
2534 next();
2535 skip(')');
2536 break;
2537 case TOK_DLLEXPORT:
2538 ad->func_export = 1;
2539 break;
2540 case TOK_DLLIMPORT:
2541 ad->func_import = 1;
2542 break;
2543 default:
2544 if (tcc_state->warn_unsupported)
2545 warning("'%s' attribute ignored", get_tok_str(t, NULL));
2546 /* skip parameters */
2547 if (tok == '(') {
2548 int parenthesis = 0;
2549 do {
2550 if (tok == '(')
2551 parenthesis++;
2552 else if (tok == ')')
2553 parenthesis--;
2554 next();
2555 } while (parenthesis && tok != -1);
2557 break;
2559 if (tok != ',')
2560 break;
2561 next();
2563 skip(')');
2564 skip(')');
2568 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2569 static void struct_decl(CType *type, int u)
2571 int a, v, size, align, maxalign, c, offset;
2572 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2573 Sym *s, *ss, *ass, **ps;
2574 AttributeDef ad;
2575 CType type1, btype;
2577 a = tok; /* save decl type */
2578 next();
2579 if (tok != '{') {
2580 v = tok;
2581 next();
2582 /* struct already defined ? return it */
2583 if (v < TOK_IDENT)
2584 expect("struct/union/enum name");
2585 s = struct_find(v);
2586 if (s) {
2587 if (s->type.t != a)
2588 error("invalid type");
2589 goto do_decl;
2591 } else {
2592 v = anon_sym++;
2594 type1.t = a;
2595 /* we put an undefined size for struct/union */
2596 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2597 s->r = 0; /* default alignment is zero as gcc */
2598 /* put struct/union/enum name in type */
2599 do_decl:
2600 type->t = u;
2601 type->ref = s;
2603 if (tok == '{') {
2604 next();
2605 if (s->c != -1)
2606 error("struct/union/enum already defined");
2607 /* cannot be empty */
2608 c = 0;
2609 /* non empty enums are not allowed */
2610 if (a == TOK_ENUM) {
2611 for(;;) {
2612 v = tok;
2613 if (v < TOK_UIDENT)
2614 expect("identifier");
2615 next();
2616 if (tok == '=') {
2617 next();
2618 c = expr_const();
2620 /* enum symbols have static storage */
2621 ss = sym_push(v, &int_type, VT_CONST, c);
2622 ss->type.t |= VT_STATIC;
2623 if (tok != ',')
2624 break;
2625 next();
2626 c++;
2627 /* NOTE: we accept a trailing comma */
2628 if (tok == '}')
2629 break;
2631 skip('}');
2632 } else {
2633 maxalign = 1;
2634 ps = &s->next;
2635 prevbt = VT_INT;
2636 bit_pos = 0;
2637 offset = 0;
2638 while (tok != '}') {
2639 parse_btype(&btype, &ad);
2640 while (1) {
2641 bit_size = -1;
2642 v = 0;
2643 type1 = btype;
2644 if (tok != ':') {
2645 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2646 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2647 expect("identifier");
2648 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2649 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2650 error("invalid type for '%s'",
2651 get_tok_str(v, NULL));
2653 if (tok == ':') {
2654 next();
2655 bit_size = expr_const();
2656 /* XXX: handle v = 0 case for messages */
2657 if (bit_size < 0)
2658 error("negative width in bit-field '%s'",
2659 get_tok_str(v, NULL));
2660 if (v && bit_size == 0)
2661 error("zero width for bit-field '%s'",
2662 get_tok_str(v, NULL));
2664 size = type_size(&type1, &align);
2665 if (ad.aligned) {
2666 if (align < ad.aligned)
2667 align = ad.aligned;
2668 } else if (ad.packed) {
2669 align = 1;
2670 } else if (*tcc_state->pack_stack_ptr) {
2671 if (align > *tcc_state->pack_stack_ptr)
2672 align = *tcc_state->pack_stack_ptr;
2674 lbit_pos = 0;
2675 if (bit_size >= 0) {
2676 bt = type1.t & VT_BTYPE;
2677 if (bt != VT_INT &&
2678 bt != VT_BYTE &&
2679 bt != VT_SHORT &&
2680 bt != VT_BOOL &&
2681 bt != VT_ENUM &&
2682 bt != VT_LLONG)
2683 error("bitfields must have scalar type");
2684 bsize = size * 8;
2685 if (bit_size > bsize) {
2686 error("width of '%s' exceeds its type",
2687 get_tok_str(v, NULL));
2688 } else if (bit_size == bsize) {
2689 /* no need for bit fields */
2690 bit_pos = 0;
2691 } else if (bit_size == 0) {
2692 /* XXX: what to do if only padding in a
2693 structure ? */
2694 /* zero size: means to pad */
2695 bit_pos = 0;
2696 } else {
2697 /* we do not have enough room ?
2698 did the type change?
2699 is it a union? */
2700 if ((bit_pos + bit_size) > bsize ||
2701 bt != prevbt || a == TOK_UNION)
2702 bit_pos = 0;
2703 lbit_pos = bit_pos;
2704 /* XXX: handle LSB first */
2705 type1.t |= VT_BITFIELD |
2706 (bit_pos << VT_STRUCT_SHIFT) |
2707 (bit_size << (VT_STRUCT_SHIFT + 6));
2708 bit_pos += bit_size;
2710 prevbt = bt;
2711 } else {
2712 bit_pos = 0;
2714 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2715 /* add new memory data only if starting
2716 bit field */
2717 if (lbit_pos == 0) {
2718 if (a == TOK_STRUCT) {
2719 c = (c + align - 1) & -align;
2720 offset = c;
2721 if (size > 0)
2722 c += size;
2723 } else {
2724 offset = 0;
2725 if (size > c)
2726 c = size;
2728 if (align > maxalign)
2729 maxalign = align;
2731 #if 0
2732 printf("add field %s offset=%d",
2733 get_tok_str(v, NULL), offset);
2734 if (type1.t & VT_BITFIELD) {
2735 printf(" pos=%d size=%d",
2736 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2737 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2739 printf("\n");
2740 #endif
2742 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2743 ass = type1.ref;
2744 while ((ass = ass->next) != NULL) {
2745 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2746 *ps = ss;
2747 ps = &ss->next;
2749 } else if (v) {
2750 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2751 *ps = ss;
2752 ps = &ss->next;
2754 if (tok == ';' || tok == TOK_EOF)
2755 break;
2756 skip(',');
2758 skip(';');
2760 skip('}');
2761 /* store size and alignment */
2762 s->c = (c + maxalign - 1) & -maxalign;
2763 s->r = maxalign;
2768 /* return 0 if no type declaration. otherwise, return the basic type
2769 and skip it.
2771 static int parse_btype(CType *type, AttributeDef *ad)
2773 int t, u, type_found, typespec_found, typedef_found;
2774 Sym *s;
2775 CType type1;
2777 memset(ad, 0, sizeof(AttributeDef));
2778 type_found = 0;
2779 typespec_found = 0;
2780 typedef_found = 0;
2781 t = 0;
2782 while(1) {
2783 switch(tok) {
2784 case TOK_EXTENSION:
2785 /* currently, we really ignore extension */
2786 next();
2787 continue;
2789 /* basic types */
2790 case TOK_CHAR:
2791 u = VT_BYTE;
2792 basic_type:
2793 next();
2794 basic_type1:
2795 if ((t & VT_BTYPE) != 0)
2796 error("too many basic types");
2797 t |= u;
2798 typespec_found = 1;
2799 break;
2800 case TOK_VOID:
2801 u = VT_VOID;
2802 goto basic_type;
2803 case TOK_SHORT:
2804 u = VT_SHORT;
2805 goto basic_type;
2806 case TOK_INT:
2807 next();
2808 typespec_found = 1;
2809 break;
2810 case TOK_LONG:
2811 next();
2812 if ((t & VT_BTYPE) == VT_DOUBLE) {
2813 #ifndef TCC_TARGET_PE
2814 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2815 #endif
2816 } else if ((t & VT_BTYPE) == VT_LONG) {
2817 t = (t & ~VT_BTYPE) | VT_LLONG;
2818 } else {
2819 u = VT_LONG;
2820 goto basic_type1;
2822 break;
2823 case TOK_BOOL:
2824 u = VT_BOOL;
2825 goto basic_type;
2826 case TOK_FLOAT:
2827 u = VT_FLOAT;
2828 goto basic_type;
2829 case TOK_DOUBLE:
2830 next();
2831 if ((t & VT_BTYPE) == VT_LONG) {
2832 #ifdef TCC_TARGET_PE
2833 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2834 #else
2835 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2836 #endif
2837 } else {
2838 u = VT_DOUBLE;
2839 goto basic_type1;
2841 break;
2842 case TOK_ENUM:
2843 struct_decl(&type1, VT_ENUM);
2844 basic_type2:
2845 u = type1.t;
2846 type->ref = type1.ref;
2847 goto basic_type1;
2848 case TOK_STRUCT:
2849 case TOK_UNION:
2850 struct_decl(&type1, VT_STRUCT);
2851 goto basic_type2;
2853 /* type modifiers */
2854 case TOK_CONST1:
2855 case TOK_CONST2:
2856 case TOK_CONST3:
2857 t |= VT_CONSTANT;
2858 next();
2859 break;
2860 case TOK_VOLATILE1:
2861 case TOK_VOLATILE2:
2862 case TOK_VOLATILE3:
2863 t |= VT_VOLATILE;
2864 next();
2865 break;
2866 case TOK_SIGNED1:
2867 case TOK_SIGNED2:
2868 case TOK_SIGNED3:
2869 typespec_found = 1;
2870 t |= VT_SIGNED;
2871 next();
2872 break;
2873 case TOK_REGISTER:
2874 case TOK_AUTO:
2875 case TOK_RESTRICT1:
2876 case TOK_RESTRICT2:
2877 case TOK_RESTRICT3:
2878 next();
2879 break;
2880 case TOK_UNSIGNED:
2881 t |= VT_UNSIGNED;
2882 next();
2883 typespec_found = 1;
2884 break;
2886 /* storage */
2887 case TOK_EXTERN:
2888 t |= VT_EXTERN;
2889 next();
2890 break;
2891 case TOK_STATIC:
2892 t |= VT_STATIC;
2893 next();
2894 break;
2895 case TOK_TYPEDEF:
2896 t |= VT_TYPEDEF;
2897 next();
2898 break;
2899 case TOK_INLINE1:
2900 case TOK_INLINE2:
2901 case TOK_INLINE3:
2902 t |= VT_INLINE;
2903 next();
2904 break;
2906 /* GNUC attribute */
2907 case TOK_ATTRIBUTE1:
2908 case TOK_ATTRIBUTE2:
2909 parse_attribute(ad);
2910 if (ad->mode) {
2911 u = ad->mode -1;
2912 t = (t & ~VT_BTYPE) | u;
2914 break;
2915 /* GNUC typeof */
2916 case TOK_TYPEOF1:
2917 case TOK_TYPEOF2:
2918 case TOK_TYPEOF3:
2919 next();
2920 parse_expr_type(&type1);
2921 goto basic_type2;
2922 default:
2923 if (typespec_found || typedef_found)
2924 goto the_end;
2925 s = sym_find(tok);
2926 if (!s || !(s->type.t & VT_TYPEDEF))
2927 goto the_end;
2928 typedef_found = 1;
2929 t |= (s->type.t & ~VT_TYPEDEF);
2930 type->ref = s->type.ref;
2931 if (s->r) {
2932 /* get attributes from typedef */
2933 if (0 == ad->aligned)
2934 ad->aligned = FUNC_ALIGN(s->r);
2935 if (0 == ad->func_call)
2936 ad->func_call = FUNC_CALL(s->r);
2937 ad->packed |= FUNC_PACKED(s->r);
2939 next();
2940 typespec_found = 1;
2941 break;
2943 type_found = 1;
2945 the_end:
2946 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
2947 error("signed and unsigned modifier");
2948 if (tcc_state->char_is_unsigned) {
2949 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
2950 t |= VT_UNSIGNED;
2952 t &= ~VT_SIGNED;
2954 /* long is never used as type */
2955 if ((t & VT_BTYPE) == VT_LONG)
2956 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
2957 t = (t & ~VT_BTYPE) | VT_INT;
2958 #else
2959 t = (t & ~VT_BTYPE) | VT_LLONG;
2960 #endif
2961 type->t = t;
2962 return type_found;
2965 /* convert a function parameter type (array to pointer and function to
2966 function pointer) */
2967 static inline void convert_parameter_type(CType *pt)
2969 /* remove const and volatile qualifiers (XXX: const could be used
2970 to indicate a const function parameter */
2971 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
2972 /* array must be transformed to pointer according to ANSI C */
2973 pt->t &= ~VT_ARRAY;
2974 if ((pt->t & VT_BTYPE) == VT_FUNC) {
2975 mk_pointer(pt);
2979 static void post_type(CType *type, AttributeDef *ad)
2981 int n, l, t1, arg_size, align;
2982 Sym **plast, *s, *first;
2983 AttributeDef ad1;
2984 CType pt;
2986 if (tok == '(') {
2987 /* function declaration */
2988 next();
2989 l = 0;
2990 first = NULL;
2991 plast = &first;
2992 arg_size = 0;
2993 if (tok != ')') {
2994 for(;;) {
2995 /* read param name and compute offset */
2996 if (l != FUNC_OLD) {
2997 if (!parse_btype(&pt, &ad1)) {
2998 if (l) {
2999 error("invalid type");
3000 } else {
3001 l = FUNC_OLD;
3002 goto old_proto;
3005 l = FUNC_NEW;
3006 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3007 break;
3008 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3009 if ((pt.t & VT_BTYPE) == VT_VOID)
3010 error("parameter declared as void");
3011 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3012 } else {
3013 old_proto:
3014 n = tok;
3015 if (n < TOK_UIDENT)
3016 expect("identifier");
3017 pt.t = VT_INT;
3018 next();
3020 convert_parameter_type(&pt);
3021 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3022 *plast = s;
3023 plast = &s->next;
3024 if (tok == ')')
3025 break;
3026 skip(',');
3027 if (l == FUNC_NEW && tok == TOK_DOTS) {
3028 l = FUNC_ELLIPSIS;
3029 next();
3030 break;
3034 /* if no parameters, then old type prototype */
3035 if (l == 0)
3036 l = FUNC_OLD;
3037 skip(')');
3038 t1 = type->t & VT_STORAGE;
3039 /* NOTE: const is ignored in returned type as it has a special
3040 meaning in gcc / C++ */
3041 type->t &= ~(VT_STORAGE | VT_CONSTANT);
3042 post_type(type, ad);
3043 /* we push a anonymous symbol which will contain the function prototype */
3044 ad->func_args = arg_size;
3045 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3046 s->next = first;
3047 type->t = t1 | VT_FUNC;
3048 type->ref = s;
3049 } else if (tok == '[') {
3050 /* array definition */
3051 next();
3052 if (tok == TOK_RESTRICT1)
3053 next();
3054 n = -1;
3055 if (tok != ']') {
3056 n = expr_const();
3057 if (n < 0)
3058 error("invalid array size");
3060 skip(']');
3061 /* parse next post type */
3062 t1 = type->t & VT_STORAGE;
3063 type->t &= ~VT_STORAGE;
3064 post_type(type, ad);
3066 /* we push a anonymous symbol which will contain the array
3067 element type */
3068 s = sym_push(SYM_FIELD, type, 0, n);
3069 type->t = t1 | VT_ARRAY | VT_PTR;
3070 type->ref = s;
3074 /* Parse a type declaration (except basic type), and return the type
3075 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3076 expected. 'type' should contain the basic type. 'ad' is the
3077 attribute definition of the basic type. It can be modified by
3078 type_decl().
3080 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3082 Sym *s;
3083 CType type1, *type2;
3084 int qualifiers;
3086 while (tok == '*') {
3087 qualifiers = 0;
3088 redo:
3089 next();
3090 switch(tok) {
3091 case TOK_CONST1:
3092 case TOK_CONST2:
3093 case TOK_CONST3:
3094 qualifiers |= VT_CONSTANT;
3095 goto redo;
3096 case TOK_VOLATILE1:
3097 case TOK_VOLATILE2:
3098 case TOK_VOLATILE3:
3099 qualifiers |= VT_VOLATILE;
3100 goto redo;
3101 case TOK_RESTRICT1:
3102 case TOK_RESTRICT2:
3103 case TOK_RESTRICT3:
3104 goto redo;
3106 mk_pointer(type);
3107 type->t |= qualifiers;
3110 /* XXX: clarify attribute handling */
3111 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3112 parse_attribute(ad);
3114 /* recursive type */
3115 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3116 type1.t = 0; /* XXX: same as int */
3117 if (tok == '(') {
3118 next();
3119 /* XXX: this is not correct to modify 'ad' at this point, but
3120 the syntax is not clear */
3121 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3122 parse_attribute(ad);
3123 type_decl(&type1, ad, v, td);
3124 skip(')');
3125 } else {
3126 /* type identifier */
3127 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3128 *v = tok;
3129 next();
3130 } else {
3131 if (!(td & TYPE_ABSTRACT))
3132 expect("identifier");
3133 *v = 0;
3136 post_type(type, ad);
3137 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3138 parse_attribute(ad);
3139 if (!type1.t)
3140 return;
3141 /* append type at the end of type1 */
3142 type2 = &type1;
3143 for(;;) {
3144 s = type2->ref;
3145 type2 = &s->type;
3146 if (!type2->t) {
3147 *type2 = *type;
3148 break;
3151 *type = type1;
3154 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3155 ST_FUNC int lvalue_type(int t)
3157 int bt, r;
3158 r = VT_LVAL;
3159 bt = t & VT_BTYPE;
3160 if (bt == VT_BYTE || bt == VT_BOOL)
3161 r |= VT_LVAL_BYTE;
3162 else if (bt == VT_SHORT)
3163 r |= VT_LVAL_SHORT;
3164 else
3165 return r;
3166 if (t & VT_UNSIGNED)
3167 r |= VT_LVAL_UNSIGNED;
3168 return r;
3171 /* indirection with full error checking and bound check */
3172 ST_FUNC void indir(void)
3174 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3175 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3176 return;
3177 expect("pointer");
3179 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3180 gv(RC_INT);
3181 vtop->type = *pointed_type(&vtop->type);
3182 /* Arrays and functions are never lvalues */
3183 if (!(vtop->type.t & VT_ARRAY)
3184 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3185 vtop->r |= lvalue_type(vtop->type.t);
3186 /* if bound checking, the referenced pointer must be checked */
3187 #ifdef CONFIG_TCC_BCHECK
3188 if (tcc_state->do_bounds_check)
3189 vtop->r |= VT_MUSTBOUND;
3190 #endif
3194 /* pass a parameter to a function and do type checking and casting */
3195 static void gfunc_param_typed(Sym *func, Sym *arg)
3197 int func_type;
3198 CType type;
3200 func_type = func->c;
3201 if (func_type == FUNC_OLD ||
3202 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3203 /* default casting : only need to convert float to double */
3204 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3205 type.t = VT_DOUBLE;
3206 gen_cast(&type);
3208 } else if (arg == NULL) {
3209 error("too many arguments to function");
3210 } else {
3211 type = arg->type;
3212 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3213 gen_assign_cast(&type);
3217 /* parse an expression of the form '(type)' or '(expr)' and return its
3218 type */
3219 static void parse_expr_type(CType *type)
3221 int n;
3222 AttributeDef ad;
3224 skip('(');
3225 if (parse_btype(type, &ad)) {
3226 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3227 } else {
3228 expr_type(type);
3230 skip(')');
3233 static void parse_type(CType *type)
3235 AttributeDef ad;
3236 int n;
3238 if (!parse_btype(type, &ad)) {
3239 expect("type");
3241 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3244 static void vpush_tokc(int t)
3246 CType type;
3247 type.t = t;
3248 type.ref = 0;
3249 vsetc(&type, VT_CONST, &tokc);
3252 ST_FUNC void unary(void)
3254 int n, t, align, size, r, sizeof_caller;
3255 CType type;
3256 Sym *s;
3257 AttributeDef ad;
3258 static int in_sizeof = 0;
3260 sizeof_caller = in_sizeof;
3261 in_sizeof = 0;
3262 /* XXX: GCC 2.95.3 does not generate a table although it should be
3263 better here */
3264 tok_next:
3265 switch(tok) {
3266 case TOK_EXTENSION:
3267 next();
3268 goto tok_next;
3269 case TOK_CINT:
3270 case TOK_CCHAR:
3271 case TOK_LCHAR:
3272 vpushi(tokc.i);
3273 next();
3274 break;
3275 case TOK_CUINT:
3276 vpush_tokc(VT_INT | VT_UNSIGNED);
3277 next();
3278 break;
3279 case TOK_CLLONG:
3280 vpush_tokc(VT_LLONG);
3281 next();
3282 break;
3283 case TOK_CULLONG:
3284 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3285 next();
3286 break;
3287 case TOK_CFLOAT:
3288 vpush_tokc(VT_FLOAT);
3289 next();
3290 break;
3291 case TOK_CDOUBLE:
3292 vpush_tokc(VT_DOUBLE);
3293 next();
3294 break;
3295 case TOK_CLDOUBLE:
3296 vpush_tokc(VT_LDOUBLE);
3297 next();
3298 break;
3299 case TOK___FUNCTION__:
3300 if (!gnu_ext)
3301 goto tok_identifier;
3302 /* fall thru */
3303 case TOK___FUNC__:
3305 void *ptr;
3306 int len;
3307 /* special function name identifier */
3308 len = strlen(funcname) + 1;
3309 /* generate char[len] type */
3310 type.t = VT_BYTE;
3311 mk_pointer(&type);
3312 type.t |= VT_ARRAY;
3313 type.ref->c = len;
3314 vpush_ref(&type, data_section, data_section->data_offset, len);
3315 ptr = section_ptr_add(data_section, len);
3316 memcpy(ptr, funcname, len);
3317 next();
3319 break;
3320 case TOK_LSTR:
3321 #ifdef TCC_TARGET_PE
3322 t = VT_SHORT | VT_UNSIGNED;
3323 #else
3324 t = VT_INT;
3325 #endif
3326 goto str_init;
3327 case TOK_STR:
3328 /* string parsing */
3329 t = VT_BYTE;
3330 str_init:
3331 if (tcc_state->warn_write_strings)
3332 t |= VT_CONSTANT;
3333 type.t = t;
3334 mk_pointer(&type);
3335 type.t |= VT_ARRAY;
3336 memset(&ad, 0, sizeof(AttributeDef));
3337 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3338 break;
3339 case '(':
3340 next();
3341 /* cast ? */
3342 if (parse_btype(&type, &ad)) {
3343 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3344 skip(')');
3345 /* check ISOC99 compound literal */
3346 if (tok == '{') {
3347 /* data is allocated locally by default */
3348 if (global_expr)
3349 r = VT_CONST;
3350 else
3351 r = VT_LOCAL;
3352 /* all except arrays are lvalues */
3353 if (!(type.t & VT_ARRAY))
3354 r |= lvalue_type(type.t);
3355 memset(&ad, 0, sizeof(AttributeDef));
3356 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3357 } else {
3358 if (sizeof_caller) {
3359 vpush(&type);
3360 return;
3362 unary();
3363 gen_cast(&type);
3365 } else if (tok == '{') {
3366 /* save all registers */
3367 save_regs(0);
3368 /* statement expression : we do not accept break/continue
3369 inside as GCC does */
3370 block(NULL, NULL, NULL, NULL, 0, 1);
3371 skip(')');
3372 } else {
3373 gexpr();
3374 skip(')');
3376 break;
3377 case '*':
3378 next();
3379 unary();
3380 indir();
3381 break;
3382 case '&':
3383 next();
3384 unary();
3385 /* functions names must be treated as function pointers,
3386 except for unary '&' and sizeof. Since we consider that
3387 functions are not lvalues, we only have to handle it
3388 there and in function calls. */
3389 /* arrays can also be used although they are not lvalues */
3390 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3391 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3392 test_lvalue();
3393 mk_pointer(&vtop->type);
3394 gaddrof();
3395 break;
3396 case '!':
3397 next();
3398 unary();
3399 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3400 CType boolean;
3401 boolean.t = VT_BOOL;
3402 gen_cast(&boolean);
3403 vtop->c.i = !vtop->c.i;
3404 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3405 vtop->c.i = vtop->c.i ^ 1;
3406 else {
3407 save_regs(1);
3408 vseti(VT_JMP, gtst(1, 0));
3410 break;
3411 case '~':
3412 next();
3413 unary();
3414 vpushi(-1);
3415 gen_op('^');
3416 break;
3417 case '+':
3418 next();
3419 /* in order to force cast, we add zero */
3420 unary();
3421 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3422 error("pointer not accepted for unary plus");
3423 vpushi(0);
3424 gen_op('+');
3425 break;
3426 case TOK_SIZEOF:
3427 case TOK_ALIGNOF1:
3428 case TOK_ALIGNOF2:
3429 t = tok;
3430 next();
3431 in_sizeof++;
3432 unary_type(&type); // Perform a in_sizeof = 0;
3433 size = type_size(&type, &align);
3434 if (t == TOK_SIZEOF) {
3435 if (size < 0)
3436 error("sizeof applied to an incomplete type");
3437 vpushi(size);
3438 } else {
3439 vpushi(align);
3441 vtop->type.t |= VT_UNSIGNED;
3442 break;
3444 case TOK_builtin_types_compatible_p:
3446 CType type1, type2;
3447 next();
3448 skip('(');
3449 parse_type(&type1);
3450 skip(',');
3451 parse_type(&type2);
3452 skip(')');
3453 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3454 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3455 vpushi(is_compatible_types(&type1, &type2));
3457 break;
3458 case TOK_builtin_constant_p:
3460 int saved_nocode_wanted, res;
3461 next();
3462 skip('(');
3463 saved_nocode_wanted = nocode_wanted;
3464 nocode_wanted = 1;
3465 gexpr();
3466 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3467 vpop();
3468 nocode_wanted = saved_nocode_wanted;
3469 skip(')');
3470 vpushi(res);
3472 break;
3473 case TOK_builtin_frame_address:
3475 CType type;
3476 next();
3477 skip('(');
3478 if (tok != TOK_CINT) {
3479 error("__builtin_frame_address only takes integers");
3481 if (tokc.i != 0) {
3482 error("TCC only supports __builtin_frame_address(0)");
3484 next();
3485 skip(')');
3486 type.t = VT_VOID;
3487 mk_pointer(&type);
3488 vset(&type, VT_LOCAL, 0);
3490 break;
3491 #ifdef TCC_TARGET_X86_64
3492 case TOK_builtin_malloc:
3493 tok = TOK_malloc;
3494 goto tok_identifier;
3495 case TOK_builtin_free:
3496 tok = TOK_free;
3497 goto tok_identifier;
3498 #endif
3499 case TOK_INC:
3500 case TOK_DEC:
3501 t = tok;
3502 next();
3503 unary();
3504 inc(0, t);
3505 break;
3506 case '-':
3507 next();
3508 vpushi(0);
3509 unary();
3510 gen_op('-');
3511 break;
3512 case TOK_LAND:
3513 if (!gnu_ext)
3514 goto tok_identifier;
3515 next();
3516 /* allow to take the address of a label */
3517 if (tok < TOK_UIDENT)
3518 expect("label identifier");
3519 s = label_find(tok);
3520 if (!s) {
3521 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3522 } else {
3523 if (s->r == LABEL_DECLARED)
3524 s->r = LABEL_FORWARD;
3526 if (!s->type.t) {
3527 s->type.t = VT_VOID;
3528 mk_pointer(&s->type);
3529 s->type.t |= VT_STATIC;
3531 vset(&s->type, VT_CONST | VT_SYM, 0);
3532 vtop->sym = s;
3533 next();
3534 break;
3535 default:
3536 tok_identifier:
3537 t = tok;
3538 next();
3539 if (t < TOK_UIDENT)
3540 expect("identifier");
3541 s = sym_find(t);
3542 if (!s) {
3543 if (tok != '(')
3544 error("'%s' undeclared", get_tok_str(t, NULL));
3545 /* for simple function calls, we tolerate undeclared
3546 external reference to int() function */
3547 if (tcc_state->warn_implicit_function_declaration)
3548 warning("implicit declaration of function '%s'",
3549 get_tok_str(t, NULL));
3550 s = external_global_sym(t, &func_old_type, 0);
3552 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3553 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3554 /* if referencing an inline function, then we generate a
3555 symbol to it if not already done. It will have the
3556 effect to generate code for it at the end of the
3557 compilation unit. Inline function as always
3558 generated in the text section. */
3559 if (!s->c)
3560 put_extern_sym(s, text_section, 0, 0);
3561 r = VT_SYM | VT_CONST;
3562 } else {
3563 r = s->r;
3565 vset(&s->type, r, s->c);
3566 /* if forward reference, we must point to s */
3567 if (vtop->r & VT_SYM) {
3568 vtop->sym = s;
3569 vtop->c.ul = 0;
3571 break;
3574 /* post operations */
3575 while (1) {
3576 if (tok == TOK_INC || tok == TOK_DEC) {
3577 inc(1, tok);
3578 next();
3579 } else if (tok == '.' || tok == TOK_ARROW) {
3580 int qualifiers;
3581 /* field */
3582 if (tok == TOK_ARROW)
3583 indir();
3584 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3585 test_lvalue();
3586 gaddrof();
3587 next();
3588 /* expect pointer on structure */
3589 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3590 expect("struct or union");
3591 s = vtop->type.ref;
3592 /* find field */
3593 tok |= SYM_FIELD;
3594 while ((s = s->next) != NULL) {
3595 if (s->v == tok)
3596 break;
3598 if (!s)
3599 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3600 /* add field offset to pointer */
3601 vtop->type = char_pointer_type; /* change type to 'char *' */
3602 vpushi(s->c);
3603 gen_op('+');
3604 /* change type to field type, and set to lvalue */
3605 vtop->type = s->type;
3606 vtop->type.t |= qualifiers;
3607 /* an array is never an lvalue */
3608 if (!(vtop->type.t & VT_ARRAY)) {
3609 vtop->r |= lvalue_type(vtop->type.t);
3610 #ifdef CONFIG_TCC_BCHECK
3611 /* if bound checking, the referenced pointer must be checked */
3612 if (tcc_state->do_bounds_check)
3613 vtop->r |= VT_MUSTBOUND;
3614 #endif
3616 next();
3617 } else if (tok == '[') {
3618 next();
3619 gexpr();
3620 gen_op('+');
3621 indir();
3622 skip(']');
3623 } else if (tok == '(') {
3624 SValue ret;
3625 Sym *sa;
3626 int nb_args;
3628 /* function call */
3629 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3630 /* pointer test (no array accepted) */
3631 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3632 vtop->type = *pointed_type(&vtop->type);
3633 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3634 goto error_func;
3635 } else {
3636 error_func:
3637 expect("function pointer");
3639 } else {
3640 vtop->r &= ~VT_LVAL; /* no lvalue */
3642 /* get return type */
3643 s = vtop->type.ref;
3644 next();
3645 sa = s->next; /* first parameter */
3646 nb_args = 0;
3647 ret.r2 = VT_CONST;
3648 /* compute first implicit argument if a structure is returned */
3649 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3650 /* get some space for the returned structure */
3651 size = type_size(&s->type, &align);
3652 loc = (loc - size) & -align;
3653 ret.type = s->type;
3654 ret.r = VT_LOCAL | VT_LVAL;
3655 /* pass it as 'int' to avoid structure arg passing
3656 problems */
3657 vseti(VT_LOCAL, loc);
3658 ret.c = vtop->c;
3659 nb_args++;
3660 } else {
3661 ret.type = s->type;
3662 /* return in register */
3663 if (is_float(ret.type.t)) {
3664 ret.r = reg_fret(ret.type.t);
3665 } else {
3666 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3667 ret.r2 = REG_LRET;
3668 ret.r = REG_IRET;
3670 ret.c.i = 0;
3672 if (tok != ')') {
3673 for(;;) {
3674 expr_eq();
3675 gfunc_param_typed(s, sa);
3676 nb_args++;
3677 if (sa)
3678 sa = sa->next;
3679 if (tok == ')')
3680 break;
3681 skip(',');
3684 if (sa)
3685 error("too few arguments to function");
3686 skip(')');
3687 if (!nocode_wanted) {
3688 gfunc_call(nb_args);
3689 } else {
3690 vtop -= (nb_args + 1);
3692 /* return value */
3693 vsetc(&ret.type, ret.r, &ret.c);
3694 vtop->r2 = ret.r2;
3695 } else {
3696 break;
3701 static void uneq(void)
3703 int t;
3705 unary();
3706 if (tok == '=' ||
3707 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
3708 tok == TOK_A_XOR || tok == TOK_A_OR ||
3709 tok == TOK_A_SHL || tok == TOK_A_SAR) {
3710 test_lvalue();
3711 t = tok;
3712 next();
3713 if (t == '=') {
3714 expr_eq();
3715 } else {
3716 vdup();
3717 expr_eq();
3718 gen_op(t & 0x7f);
3720 vstore();
3724 ST_FUNC void expr_prod(void)
3726 int t;
3728 uneq();
3729 while (tok == '*' || tok == '/' || tok == '%') {
3730 t = tok;
3731 next();
3732 uneq();
3733 gen_op(t);
3737 ST_FUNC void expr_sum(void)
3739 int t;
3741 expr_prod();
3742 while (tok == '+' || tok == '-') {
3743 t = tok;
3744 next();
3745 expr_prod();
3746 gen_op(t);
3750 static void expr_shift(void)
3752 int t;
3754 expr_sum();
3755 while (tok == TOK_SHL || tok == TOK_SAR) {
3756 t = tok;
3757 next();
3758 expr_sum();
3759 gen_op(t);
3763 static void expr_cmp(void)
3765 int t;
3767 expr_shift();
3768 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3769 tok == TOK_ULT || tok == TOK_UGE) {
3770 t = tok;
3771 next();
3772 expr_shift();
3773 gen_op(t);
3777 static void expr_cmpeq(void)
3779 int t;
3781 expr_cmp();
3782 while (tok == TOK_EQ || tok == TOK_NE) {
3783 t = tok;
3784 next();
3785 expr_cmp();
3786 gen_op(t);
3790 static void expr_and(void)
3792 expr_cmpeq();
3793 while (tok == '&') {
3794 next();
3795 expr_cmpeq();
3796 gen_op('&');
3800 static void expr_xor(void)
3802 expr_and();
3803 while (tok == '^') {
3804 next();
3805 expr_and();
3806 gen_op('^');
3810 static void expr_or(void)
3812 expr_xor();
3813 while (tok == '|') {
3814 next();
3815 expr_xor();
3816 gen_op('|');
3820 /* XXX: fix this mess */
3821 static void expr_land_const(void)
3823 expr_or();
3824 while (tok == TOK_LAND) {
3825 next();
3826 expr_or();
3827 gen_op(TOK_LAND);
3831 /* XXX: fix this mess */
3832 static void expr_lor_const(void)
3834 expr_land_const();
3835 while (tok == TOK_LOR) {
3836 next();
3837 expr_land_const();
3838 gen_op(TOK_LOR);
3842 /* only used if non constant */
3843 static void expr_land(void)
3845 int t;
3847 expr_or();
3848 if (tok == TOK_LAND) {
3849 t = 0;
3850 save_regs(1);
3851 for(;;) {
3852 t = gtst(1, t);
3853 if (tok != TOK_LAND) {
3854 vseti(VT_JMPI, t);
3855 break;
3857 next();
3858 expr_or();
3863 static void expr_lor(void)
3865 int t;
3867 expr_land();
3868 if (tok == TOK_LOR) {
3869 t = 0;
3870 save_regs(1);
3871 for(;;) {
3872 t = gtst(0, t);
3873 if (tok != TOK_LOR) {
3874 vseti(VT_JMP, t);
3875 break;
3877 next();
3878 expr_land();
3883 /* XXX: better constant handling */
3884 static void expr_eq(void)
3886 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
3887 SValue sv;
3888 CType type, type1, type2;
3890 if (const_wanted) {
3891 expr_lor_const();
3892 if (tok == '?') {
3893 CType boolean;
3894 int c;
3895 boolean.t = VT_BOOL;
3896 vdup();
3897 gen_cast(&boolean);
3898 c = vtop->c.i;
3899 vpop();
3900 next();
3901 if (tok != ':' || !gnu_ext) {
3902 vpop();
3903 gexpr();
3905 if (!c)
3906 vpop();
3907 skip(':');
3908 expr_eq();
3909 if (c)
3910 vpop();
3912 } else {
3913 expr_lor();
3914 if (tok == '?') {
3915 next();
3916 if (vtop != vstack) {
3917 /* needed to avoid having different registers saved in
3918 each branch */
3919 if (is_float(vtop->type.t)) {
3920 rc = RC_FLOAT;
3921 #ifdef TCC_TARGET_X86_64
3922 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
3923 rc = RC_ST0;
3925 #endif
3927 else
3928 rc = RC_INT;
3929 gv(rc);
3930 save_regs(1);
3932 if (tok == ':' && gnu_ext) {
3933 gv_dup();
3934 tt = gtst(1, 0);
3935 } else {
3936 tt = gtst(1, 0);
3937 gexpr();
3939 type1 = vtop->type;
3940 sv = *vtop; /* save value to handle it later */
3941 vtop--; /* no vpop so that FP stack is not flushed */
3942 skip(':');
3943 u = gjmp(0);
3944 gsym(tt);
3945 expr_eq();
3946 type2 = vtop->type;
3948 t1 = type1.t;
3949 bt1 = t1 & VT_BTYPE;
3950 t2 = type2.t;
3951 bt2 = t2 & VT_BTYPE;
3952 /* cast operands to correct type according to ISOC rules */
3953 if (is_float(bt1) || is_float(bt2)) {
3954 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3955 type.t = VT_LDOUBLE;
3956 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3957 type.t = VT_DOUBLE;
3958 } else {
3959 type.t = VT_FLOAT;
3961 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3962 /* cast to biggest op */
3963 type.t = VT_LLONG;
3964 /* convert to unsigned if it does not fit in a long long */
3965 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3966 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3967 type.t |= VT_UNSIGNED;
3968 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3969 /* XXX: test pointer compatibility */
3970 type = type1;
3971 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
3972 /* XXX: test function pointer compatibility */
3973 type = type1;
3974 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3975 /* XXX: test structure compatibility */
3976 type = type1;
3977 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
3978 /* NOTE: as an extension, we accept void on only one side */
3979 type.t = VT_VOID;
3980 } else {
3981 /* integer operations */
3982 type.t = VT_INT;
3983 /* convert to unsigned if it does not fit in an integer */
3984 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3985 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3986 type.t |= VT_UNSIGNED;
3989 /* now we convert second operand */
3990 gen_cast(&type);
3991 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
3992 gaddrof();
3993 rc = RC_INT;
3994 if (is_float(type.t)) {
3995 rc = RC_FLOAT;
3996 #ifdef TCC_TARGET_X86_64
3997 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
3998 rc = RC_ST0;
4000 #endif
4001 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4002 /* for long longs, we use fixed registers to avoid having
4003 to handle a complicated move */
4004 rc = RC_IRET;
4007 r2 = gv(rc);
4008 /* this is horrible, but we must also convert first
4009 operand */
4010 tt = gjmp(0);
4011 gsym(u);
4012 /* put again first value and cast it */
4013 *vtop = sv;
4014 gen_cast(&type);
4015 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4016 gaddrof();
4017 r1 = gv(rc);
4018 move_reg(r2, r1);
4019 vtop->r = r2;
4020 gsym(tt);
4025 ST_FUNC void gexpr(void)
4027 while (1) {
4028 expr_eq();
4029 if (tok != ',')
4030 break;
4031 vpop();
4032 next();
4036 /* parse an expression and return its type without any side effect. */
4037 static void expr_type(CType *type)
4039 int saved_nocode_wanted;
4041 saved_nocode_wanted = nocode_wanted;
4042 nocode_wanted = 1;
4043 gexpr();
4044 *type = vtop->type;
4045 vpop();
4046 nocode_wanted = saved_nocode_wanted;
4049 /* parse a unary expression and return its type without any side
4050 effect. */
4051 static void unary_type(CType *type)
4053 int a;
4054 void *vtop_saved;
4056 a = nocode_wanted;
4057 nocode_wanted = 1;
4058 vtop_saved = vtop;
4059 unary();
4060 *type = vtop->type;
4061 vpop();
4062 nocode_wanted = a;
4065 /* parse a constant expression and return value in vtop. */
4066 static void expr_const1(void)
4068 int a;
4069 a = const_wanted;
4070 const_wanted = 1;
4071 expr_eq();
4072 const_wanted = a;
4075 /* parse an integer constant and return its value. */
4076 ST_FUNC int expr_const(void)
4078 int c;
4079 expr_const1();
4080 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4081 expect("constant expression");
4082 c = vtop->c.i;
4083 vpop();
4084 return c;
4087 /* return the label token if current token is a label, otherwise
4088 return zero */
4089 static int is_label(void)
4091 int last_tok;
4093 /* fast test first */
4094 if (tok < TOK_UIDENT)
4095 return 0;
4096 /* no need to save tokc because tok is an identifier */
4097 last_tok = tok;
4098 next();
4099 if (tok == ':') {
4100 next();
4101 return last_tok;
4102 } else {
4103 unget_tok(last_tok);
4104 return 0;
4108 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4109 int case_reg, int is_expr)
4111 int a, b, c, d;
4112 Sym *s;
4114 /* generate line number info */
4115 if (tcc_state->do_debug &&
4116 (last_line_num != file->line_num || last_ind != ind)) {
4117 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4118 last_ind = ind;
4119 last_line_num = file->line_num;
4122 if (is_expr) {
4123 /* default return value is (void) */
4124 vpushi(0);
4125 vtop->type.t = VT_VOID;
4128 if (tok == TOK_IF) {
4129 /* if test */
4130 next();
4131 skip('(');
4132 gexpr();
4133 skip(')');
4134 a = gtst(1, 0);
4135 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4136 c = tok;
4137 if (c == TOK_ELSE) {
4138 next();
4139 d = gjmp(0);
4140 gsym(a);
4141 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4142 gsym(d); /* patch else jmp */
4143 } else
4144 gsym(a);
4145 } else if (tok == TOK_WHILE) {
4146 next();
4147 d = ind;
4148 skip('(');
4149 gexpr();
4150 skip(')');
4151 a = gtst(1, 0);
4152 b = 0;
4153 block(&a, &b, case_sym, def_sym, case_reg, 0);
4154 gjmp_addr(d);
4155 gsym(a);
4156 gsym_addr(b, d);
4157 } else if (tok == '{') {
4158 Sym *llabel;
4160 next();
4161 /* record local declaration stack position */
4162 s = local_stack;
4163 llabel = local_label_stack;
4164 /* handle local labels declarations */
4165 if (tok == TOK_LABEL) {
4166 next();
4167 for(;;) {
4168 if (tok < TOK_UIDENT)
4169 expect("label identifier");
4170 label_push(&local_label_stack, tok, LABEL_DECLARED);
4171 next();
4172 if (tok == ',') {
4173 next();
4174 } else {
4175 skip(';');
4176 break;
4180 while (tok != '}') {
4181 decl(VT_LOCAL);
4182 if (tok != '}') {
4183 if (is_expr)
4184 vpop();
4185 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4188 /* pop locally defined labels */
4189 label_pop(&local_label_stack, llabel);
4190 /* pop locally defined symbols */
4191 if(is_expr) {
4192 /* XXX: this solution makes only valgrind happy...
4193 triggered by gcc.c-torture/execute/20000917-1.c */
4194 Sym *p;
4195 switch(vtop->type.t & VT_BTYPE) {
4196 case VT_PTR:
4197 case VT_STRUCT:
4198 case VT_ENUM:
4199 case VT_FUNC:
4200 for(p=vtop->type.ref;p;p=p->prev)
4201 if(p->prev==s)
4202 error("unsupported expression type");
4205 sym_pop(&local_stack, s);
4206 next();
4207 } else if (tok == TOK_RETURN) {
4208 next();
4209 if (tok != ';') {
4210 gexpr();
4211 gen_assign_cast(&func_vt);
4212 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4213 CType type;
4214 /* if returning structure, must copy it to implicit
4215 first pointer arg location */
4216 #ifdef TCC_ARM_EABI
4217 int align, size;
4218 size = type_size(&func_vt,&align);
4219 if(size <= 4)
4221 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4222 && (align & 3))
4224 int addr;
4225 loc = (loc - size) & -4;
4226 addr = loc;
4227 type = func_vt;
4228 vset(&type, VT_LOCAL | VT_LVAL, addr);
4229 vswap();
4230 vstore();
4231 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4233 vtop->type = int_type;
4234 gv(RC_IRET);
4235 } else {
4236 #endif
4237 type = func_vt;
4238 mk_pointer(&type);
4239 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4240 indir();
4241 vswap();
4242 /* copy structure value to pointer */
4243 vstore();
4244 #ifdef TCC_ARM_EABI
4246 #endif
4247 } else if (is_float(func_vt.t)) {
4248 gv(rc_fret(func_vt.t));
4249 } else {
4250 gv(RC_IRET);
4252 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4254 skip(';');
4255 rsym = gjmp(rsym); /* jmp */
4256 } else if (tok == TOK_BREAK) {
4257 /* compute jump */
4258 if (!bsym)
4259 error("cannot break");
4260 *bsym = gjmp(*bsym);
4261 next();
4262 skip(';');
4263 } else if (tok == TOK_CONTINUE) {
4264 /* compute jump */
4265 if (!csym)
4266 error("cannot continue");
4267 *csym = gjmp(*csym);
4268 next();
4269 skip(';');
4270 } else if (tok == TOK_FOR) {
4271 int e;
4272 next();
4273 skip('(');
4274 if (tok != ';') {
4275 gexpr();
4276 vpop();
4278 skip(';');
4279 d = ind;
4280 c = ind;
4281 a = 0;
4282 b = 0;
4283 if (tok != ';') {
4284 gexpr();
4285 a = gtst(1, 0);
4287 skip(';');
4288 if (tok != ')') {
4289 e = gjmp(0);
4290 c = ind;
4291 gexpr();
4292 vpop();
4293 gjmp_addr(d);
4294 gsym(e);
4296 skip(')');
4297 block(&a, &b, case_sym, def_sym, case_reg, 0);
4298 gjmp_addr(c);
4299 gsym(a);
4300 gsym_addr(b, c);
4301 } else
4302 if (tok == TOK_DO) {
4303 next();
4304 a = 0;
4305 b = 0;
4306 d = ind;
4307 block(&a, &b, case_sym, def_sym, case_reg, 0);
4308 skip(TOK_WHILE);
4309 skip('(');
4310 gsym(b);
4311 gexpr();
4312 c = gtst(0, 0);
4313 gsym_addr(c, d);
4314 skip(')');
4315 gsym(a);
4316 skip(';');
4317 } else
4318 if (tok == TOK_SWITCH) {
4319 next();
4320 skip('(');
4321 gexpr();
4322 /* XXX: other types than integer */
4323 case_reg = gv(RC_INT);
4324 vpop();
4325 skip(')');
4326 a = 0;
4327 b = gjmp(0); /* jump to first case */
4328 c = 0;
4329 block(&a, csym, &b, &c, case_reg, 0);
4330 /* if no default, jmp after switch */
4331 if (c == 0)
4332 c = ind;
4333 /* default label */
4334 gsym_addr(b, c);
4335 /* break label */
4336 gsym(a);
4337 } else
4338 if (tok == TOK_CASE) {
4339 int v1, v2;
4340 if (!case_sym)
4341 expect("switch");
4342 next();
4343 v1 = expr_const();
4344 v2 = v1;
4345 if (gnu_ext && tok == TOK_DOTS) {
4346 next();
4347 v2 = expr_const();
4348 if (v2 < v1)
4349 warning("empty case range");
4351 /* since a case is like a label, we must skip it with a jmp */
4352 b = gjmp(0);
4353 gsym(*case_sym);
4354 vseti(case_reg, 0);
4355 vpushi(v1);
4356 if (v1 == v2) {
4357 gen_op(TOK_EQ);
4358 *case_sym = gtst(1, 0);
4359 } else {
4360 gen_op(TOK_GE);
4361 *case_sym = gtst(1, 0);
4362 vseti(case_reg, 0);
4363 vpushi(v2);
4364 gen_op(TOK_LE);
4365 *case_sym = gtst(1, *case_sym);
4367 gsym(b);
4368 skip(':');
4369 is_expr = 0;
4370 goto block_after_label;
4371 } else
4372 if (tok == TOK_DEFAULT) {
4373 next();
4374 skip(':');
4375 if (!def_sym)
4376 expect("switch");
4377 if (*def_sym)
4378 error("too many 'default'");
4379 *def_sym = ind;
4380 is_expr = 0;
4381 goto block_after_label;
4382 } else
4383 if (tok == TOK_GOTO) {
4384 next();
4385 if (tok == '*' && gnu_ext) {
4386 /* computed goto */
4387 next();
4388 gexpr();
4389 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4390 expect("pointer");
4391 ggoto();
4392 } else if (tok >= TOK_UIDENT) {
4393 s = label_find(tok);
4394 /* put forward definition if needed */
4395 if (!s) {
4396 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4397 } else {
4398 if (s->r == LABEL_DECLARED)
4399 s->r = LABEL_FORWARD;
4401 /* label already defined */
4402 if (s->r & LABEL_FORWARD)
4403 s->jnext = gjmp(s->jnext);
4404 else
4405 gjmp_addr(s->jnext);
4406 next();
4407 } else {
4408 expect("label identifier");
4410 skip(';');
4411 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4412 asm_instr();
4413 } else {
4414 b = is_label();
4415 if (b) {
4416 /* label case */
4417 s = label_find(b);
4418 if (s) {
4419 if (s->r == LABEL_DEFINED)
4420 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4421 gsym(s->jnext);
4422 s->r = LABEL_DEFINED;
4423 } else {
4424 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4426 s->jnext = ind;
4427 /* we accept this, but it is a mistake */
4428 block_after_label:
4429 if (tok == '}') {
4430 warning("deprecated use of label at end of compound statement");
4431 } else {
4432 if (is_expr)
4433 vpop();
4434 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4436 } else {
4437 /* expression case */
4438 if (tok != ';') {
4439 if (is_expr) {
4440 vpop();
4441 gexpr();
4442 } else {
4443 gexpr();
4444 vpop();
4447 skip(';');
4452 /* t is the array or struct type. c is the array or struct
4453 address. cur_index/cur_field is the pointer to the current
4454 value. 'size_only' is true if only size info is needed (only used
4455 in arrays) */
4456 static void decl_designator(CType *type, Section *sec, unsigned long c,
4457 int *cur_index, Sym **cur_field,
4458 int size_only)
4460 Sym *s, *f;
4461 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4462 CType type1;
4464 notfirst = 0;
4465 elem_size = 0;
4466 nb_elems = 1;
4467 if (gnu_ext && (l = is_label()) != 0)
4468 goto struct_field;
4469 while (tok == '[' || tok == '.') {
4470 if (tok == '[') {
4471 if (!(type->t & VT_ARRAY))
4472 expect("array type");
4473 s = type->ref;
4474 next();
4475 index = expr_const();
4476 if (index < 0 || (s->c >= 0 && index >= s->c))
4477 expect("invalid index");
4478 if (tok == TOK_DOTS && gnu_ext) {
4479 next();
4480 index_last = expr_const();
4481 if (index_last < 0 ||
4482 (s->c >= 0 && index_last >= s->c) ||
4483 index_last < index)
4484 expect("invalid index");
4485 } else {
4486 index_last = index;
4488 skip(']');
4489 if (!notfirst)
4490 *cur_index = index_last;
4491 type = pointed_type(type);
4492 elem_size = type_size(type, &align);
4493 c += index * elem_size;
4494 /* NOTE: we only support ranges for last designator */
4495 nb_elems = index_last - index + 1;
4496 if (nb_elems != 1) {
4497 notfirst = 1;
4498 break;
4500 } else {
4501 next();
4502 l = tok;
4503 next();
4504 struct_field:
4505 if ((type->t & VT_BTYPE) != VT_STRUCT)
4506 expect("struct/union type");
4507 s = type->ref;
4508 l |= SYM_FIELD;
4509 f = s->next;
4510 while (f) {
4511 if (f->v == l)
4512 break;
4513 f = f->next;
4515 if (!f)
4516 expect("field");
4517 if (!notfirst)
4518 *cur_field = f;
4519 /* XXX: fix this mess by using explicit storage field */
4520 type1 = f->type;
4521 type1.t |= (type->t & ~VT_TYPE);
4522 type = &type1;
4523 c += f->c;
4525 notfirst = 1;
4527 if (notfirst) {
4528 if (tok == '=') {
4529 next();
4530 } else {
4531 if (!gnu_ext)
4532 expect("=");
4534 } else {
4535 if (type->t & VT_ARRAY) {
4536 index = *cur_index;
4537 type = pointed_type(type);
4538 c += index * type_size(type, &align);
4539 } else {
4540 f = *cur_field;
4541 if (!f)
4542 error("too many field init");
4543 /* XXX: fix this mess by using explicit storage field */
4544 type1 = f->type;
4545 type1.t |= (type->t & ~VT_TYPE);
4546 type = &type1;
4547 c += f->c;
4550 decl_initializer(type, sec, c, 0, size_only);
4552 /* XXX: make it more general */
4553 if (!size_only && nb_elems > 1) {
4554 unsigned long c_end;
4555 uint8_t *src, *dst;
4556 int i;
4558 if (!sec)
4559 error("range init not supported yet for dynamic storage");
4560 c_end = c + nb_elems * elem_size;
4561 if (c_end > sec->data_allocated)
4562 section_realloc(sec, c_end);
4563 src = sec->data + c;
4564 dst = src;
4565 for(i = 1; i < nb_elems; i++) {
4566 dst += elem_size;
4567 memcpy(dst, src, elem_size);
4572 #define EXPR_VAL 0
4573 #define EXPR_CONST 1
4574 #define EXPR_ANY 2
4576 /* store a value or an expression directly in global data or in local array */
4577 static void init_putv(CType *type, Section *sec, unsigned long c,
4578 int v, int expr_type)
4580 int saved_global_expr, bt, bit_pos, bit_size;
4581 void *ptr;
4582 unsigned long long bit_mask;
4583 CType dtype;
4585 switch(expr_type) {
4586 case EXPR_VAL:
4587 vpushi(v);
4588 break;
4589 case EXPR_CONST:
4590 /* compound literals must be allocated globally in this case */
4591 saved_global_expr = global_expr;
4592 global_expr = 1;
4593 expr_const1();
4594 global_expr = saved_global_expr;
4595 /* NOTE: symbols are accepted */
4596 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4597 error("initializer element is not constant");
4598 break;
4599 case EXPR_ANY:
4600 expr_eq();
4601 break;
4604 dtype = *type;
4605 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4607 if (sec) {
4608 /* XXX: not portable */
4609 /* XXX: generate error if incorrect relocation */
4610 gen_assign_cast(&dtype);
4611 bt = type->t & VT_BTYPE;
4612 /* we'll write at most 12 bytes */
4613 if (c + 12 > sec->data_allocated) {
4614 section_realloc(sec, c + 12);
4616 ptr = sec->data + c;
4617 /* XXX: make code faster ? */
4618 if (!(type->t & VT_BITFIELD)) {
4619 bit_pos = 0;
4620 bit_size = 32;
4621 bit_mask = -1LL;
4622 } else {
4623 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4624 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4625 bit_mask = (1LL << bit_size) - 1;
4627 if ((vtop->r & VT_SYM) &&
4628 (bt == VT_BYTE ||
4629 bt == VT_SHORT ||
4630 bt == VT_DOUBLE ||
4631 bt == VT_LDOUBLE ||
4632 bt == VT_LLONG ||
4633 (bt == VT_INT && bit_size != 32)))
4634 error("initializer element is not computable at load time");
4635 switch(bt) {
4636 case VT_BOOL:
4637 vtop->c.i = (vtop->c.i != 0);
4638 case VT_BYTE:
4639 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4640 break;
4641 case VT_SHORT:
4642 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4643 break;
4644 case VT_DOUBLE:
4645 *(double *)ptr = vtop->c.d;
4646 break;
4647 case VT_LDOUBLE:
4648 *(long double *)ptr = vtop->c.ld;
4649 break;
4650 case VT_LLONG:
4651 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4652 break;
4653 default:
4654 if (vtop->r & VT_SYM) {
4655 greloc(sec, vtop->sym, c, R_DATA_PTR);
4657 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4658 break;
4660 vtop--;
4661 } else {
4662 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4663 vswap();
4664 vstore();
4665 vpop();
4669 /* put zeros for variable based init */
4670 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4672 if (sec) {
4673 /* nothing to do because globals are already set to zero */
4674 } else {
4675 vpush_global_sym(&func_old_type, TOK_memset);
4676 vseti(VT_LOCAL, c);
4677 vpushi(0);
4678 vpushi(size);
4679 gfunc_call(3);
4683 /* 't' contains the type and storage info. 'c' is the offset of the
4684 object in section 'sec'. If 'sec' is NULL, it means stack based
4685 allocation. 'first' is true if array '{' must be read (multi
4686 dimension implicit array init handling). 'size_only' is true if
4687 size only evaluation is wanted (only for arrays). */
4688 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4689 int first, int size_only)
4691 int index, array_length, n, no_oblock, nb, parlevel, i;
4692 int size1, align1, expr_type;
4693 Sym *s, *f;
4694 CType *t1;
4696 if (type->t & VT_ARRAY) {
4697 s = type->ref;
4698 n = s->c;
4699 array_length = 0;
4700 t1 = pointed_type(type);
4701 size1 = type_size(t1, &align1);
4703 no_oblock = 1;
4704 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4705 tok == '{') {
4706 if (tok != '{')
4707 error("character array initializer must be a literal,"
4708 " optionally enclosed in braces");
4709 skip('{');
4710 no_oblock = 0;
4713 /* only parse strings here if correct type (otherwise: handle
4714 them as ((w)char *) expressions */
4715 if ((tok == TOK_LSTR &&
4716 #ifdef TCC_TARGET_PE
4717 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4718 #else
4719 (t1->t & VT_BTYPE) == VT_INT
4720 #endif
4721 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4722 while (tok == TOK_STR || tok == TOK_LSTR) {
4723 int cstr_len, ch;
4724 CString *cstr;
4726 cstr = tokc.cstr;
4727 /* compute maximum number of chars wanted */
4728 if (tok == TOK_STR)
4729 cstr_len = cstr->size;
4730 else
4731 cstr_len = cstr->size / sizeof(nwchar_t);
4732 cstr_len--;
4733 nb = cstr_len;
4734 if (n >= 0 && nb > (n - array_length))
4735 nb = n - array_length;
4736 if (!size_only) {
4737 if (cstr_len > nb)
4738 warning("initializer-string for array is too long");
4739 /* in order to go faster for common case (char
4740 string in global variable, we handle it
4741 specifically */
4742 if (sec && tok == TOK_STR && size1 == 1) {
4743 memcpy(sec->data + c + array_length, cstr->data, nb);
4744 } else {
4745 for(i=0;i<nb;i++) {
4746 if (tok == TOK_STR)
4747 ch = ((unsigned char *)cstr->data)[i];
4748 else
4749 ch = ((nwchar_t *)cstr->data)[i];
4750 init_putv(t1, sec, c + (array_length + i) * size1,
4751 ch, EXPR_VAL);
4755 array_length += nb;
4756 next();
4758 /* only add trailing zero if enough storage (no
4759 warning in this case since it is standard) */
4760 if (n < 0 || array_length < n) {
4761 if (!size_only) {
4762 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4764 array_length++;
4766 } else {
4767 index = 0;
4768 while (tok != '}') {
4769 decl_designator(type, sec, c, &index, NULL, size_only);
4770 if (n >= 0 && index >= n)
4771 error("index too large");
4772 /* must put zero in holes (note that doing it that way
4773 ensures that it even works with designators) */
4774 if (!size_only && array_length < index) {
4775 init_putz(t1, sec, c + array_length * size1,
4776 (index - array_length) * size1);
4778 index++;
4779 if (index > array_length)
4780 array_length = index;
4781 /* special test for multi dimensional arrays (may not
4782 be strictly correct if designators are used at the
4783 same time) */
4784 if (index >= n && no_oblock)
4785 break;
4786 if (tok == '}')
4787 break;
4788 skip(',');
4791 if (!no_oblock)
4792 skip('}');
4793 /* put zeros at the end */
4794 if (!size_only && n >= 0 && array_length < n) {
4795 init_putz(t1, sec, c + array_length * size1,
4796 (n - array_length) * size1);
4798 /* patch type size if needed */
4799 if (n < 0)
4800 s->c = array_length;
4801 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4802 (sec || !first || tok == '{')) {
4803 int par_count;
4805 /* NOTE: the previous test is a specific case for automatic
4806 struct/union init */
4807 /* XXX: union needs only one init */
4809 /* XXX: this test is incorrect for local initializers
4810 beginning with ( without {. It would be much more difficult
4811 to do it correctly (ideally, the expression parser should
4812 be used in all cases) */
4813 par_count = 0;
4814 if (tok == '(') {
4815 AttributeDef ad1;
4816 CType type1;
4817 next();
4818 while (tok == '(') {
4819 par_count++;
4820 next();
4822 if (!parse_btype(&type1, &ad1))
4823 expect("cast");
4824 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4825 #if 0
4826 if (!is_assignable_types(type, &type1))
4827 error("invalid type for cast");
4828 #endif
4829 skip(')');
4831 no_oblock = 1;
4832 if (first || tok == '{') {
4833 skip('{');
4834 no_oblock = 0;
4836 s = type->ref;
4837 f = s->next;
4838 array_length = 0;
4839 index = 0;
4840 n = s->c;
4841 while (tok != '}') {
4842 decl_designator(type, sec, c, NULL, &f, size_only);
4843 index = f->c;
4844 if (!size_only && array_length < index) {
4845 init_putz(type, sec, c + array_length,
4846 index - array_length);
4848 index = index + type_size(&f->type, &align1);
4849 if (index > array_length)
4850 array_length = index;
4852 /* gr: skip fields from same union - ugly. */
4853 while (f->next) {
4854 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
4855 /* test for same offset */
4856 if (f->next->c != f->c)
4857 break;
4858 /* if yes, test for bitfield shift */
4859 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
4860 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4861 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4862 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
4863 if (bit_pos_1 != bit_pos_2)
4864 break;
4866 f = f->next;
4869 f = f->next;
4870 if (no_oblock && f == NULL)
4871 break;
4872 if (tok == '}')
4873 break;
4874 skip(',');
4876 /* put zeros at the end */
4877 if (!size_only && array_length < n) {
4878 init_putz(type, sec, c + array_length,
4879 n - array_length);
4881 if (!no_oblock)
4882 skip('}');
4883 while (par_count) {
4884 skip(')');
4885 par_count--;
4887 } else if (tok == '{') {
4888 next();
4889 decl_initializer(type, sec, c, first, size_only);
4890 skip('}');
4891 } else if (size_only) {
4892 /* just skip expression */
4893 parlevel = 0;
4894 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4895 tok != -1) {
4896 if (tok == '(')
4897 parlevel++;
4898 else if (tok == ')')
4899 parlevel--;
4900 next();
4902 } else {
4903 /* currently, we always use constant expression for globals
4904 (may change for scripting case) */
4905 expr_type = EXPR_CONST;
4906 if (!sec)
4907 expr_type = EXPR_ANY;
4908 init_putv(type, sec, c, 0, expr_type);
4912 /* parse an initializer for type 't' if 'has_init' is non zero, and
4913 allocate space in local or global data space ('r' is either
4914 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
4915 variable 'v' of scope 'scope' is declared before initializers are
4916 parsed. If 'v' is zero, then a reference to the new object is put
4917 in the value stack. If 'has_init' is 2, a special parsing is done
4918 to handle string constants. */
4919 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
4920 int has_init, int v, int scope)
4922 int size, align, addr, data_offset;
4923 int level;
4924 ParseState saved_parse_state = {0};
4925 TokenString init_str;
4926 Section *sec;
4928 size = type_size(type, &align);
4929 /* If unknown size, we must evaluate it before
4930 evaluating initializers because
4931 initializers can generate global data too
4932 (e.g. string pointers or ISOC99 compound
4933 literals). It also simplifies local
4934 initializers handling */
4935 tok_str_new(&init_str);
4936 if (size < 0) {
4937 if (!has_init)
4938 error("unknown type size");
4939 /* get all init string */
4940 if (has_init == 2) {
4941 /* only get strings */
4942 while (tok == TOK_STR || tok == TOK_LSTR) {
4943 tok_str_add_tok(&init_str);
4944 next();
4946 } else {
4947 level = 0;
4948 while (level > 0 || (tok != ',' && tok != ';')) {
4949 if (tok < 0)
4950 error("unexpected end of file in initializer");
4951 tok_str_add_tok(&init_str);
4952 if (tok == '{')
4953 level++;
4954 else if (tok == '}') {
4955 level--;
4956 if (level <= 0) {
4957 next();
4958 break;
4961 next();
4964 tok_str_add(&init_str, -1);
4965 tok_str_add(&init_str, 0);
4967 /* compute size */
4968 save_parse_state(&saved_parse_state);
4970 macro_ptr = init_str.str;
4971 next();
4972 decl_initializer(type, NULL, 0, 1, 1);
4973 /* prepare second initializer parsing */
4974 macro_ptr = init_str.str;
4975 next();
4977 /* if still unknown size, error */
4978 size = type_size(type, &align);
4979 if (size < 0)
4980 error("unknown type size");
4982 /* take into account specified alignment if bigger */
4983 if (ad->aligned) {
4984 if (ad->aligned > align)
4985 align = ad->aligned;
4986 } else if (ad->packed) {
4987 align = 1;
4989 if ((r & VT_VALMASK) == VT_LOCAL) {
4990 sec = NULL;
4991 #ifdef CONFIG_TCC_BCHECK
4992 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
4993 loc--;
4994 #endif
4995 loc = (loc - size) & -align;
4996 addr = loc;
4997 #ifdef CONFIG_TCC_BCHECK
4998 /* handles bounds */
4999 /* XXX: currently, since we do only one pass, we cannot track
5000 '&' operators, so we add only arrays */
5001 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5002 unsigned long *bounds_ptr;
5003 /* add padding between regions */
5004 loc--;
5005 /* then add local bound info */
5006 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5007 bounds_ptr[0] = addr;
5008 bounds_ptr[1] = size;
5010 #endif
5011 if (v) {
5012 /* local variable */
5013 sym_push(v, type, r, addr);
5014 } else {
5015 /* push local reference */
5016 vset(type, r, addr);
5018 } else {
5019 Sym *sym;
5021 sym = NULL;
5022 if (v && scope == VT_CONST) {
5023 /* see if the symbol was already defined */
5024 sym = sym_find(v);
5025 if (sym) {
5026 if (!is_compatible_types(&sym->type, type))
5027 error("incompatible types for redefinition of '%s'",
5028 get_tok_str(v, NULL));
5029 if (sym->type.t & VT_EXTERN) {
5030 /* if the variable is extern, it was not allocated */
5031 sym->type.t &= ~VT_EXTERN;
5032 /* set array size if it was ommited in extern
5033 declaration */
5034 if ((sym->type.t & VT_ARRAY) &&
5035 sym->type.ref->c < 0 &&
5036 type->ref->c >= 0)
5037 sym->type.ref->c = type->ref->c;
5038 } else {
5039 /* we accept several definitions of the same
5040 global variable. this is tricky, because we
5041 must play with the SHN_COMMON type of the symbol */
5042 /* XXX: should check if the variable was already
5043 initialized. It is incorrect to initialized it
5044 twice */
5045 /* no init data, we won't add more to the symbol */
5046 if (!has_init)
5047 goto no_alloc;
5052 /* allocate symbol in corresponding section */
5053 sec = ad->section;
5054 if (!sec) {
5055 if (has_init)
5056 sec = data_section;
5057 else if (tcc_state->nocommon)
5058 sec = bss_section;
5060 if (sec) {
5061 data_offset = sec->data_offset;
5062 data_offset = (data_offset + align - 1) & -align;
5063 addr = data_offset;
5064 /* very important to increment global pointer at this time
5065 because initializers themselves can create new initializers */
5066 data_offset += size;
5067 #ifdef CONFIG_TCC_BCHECK
5068 /* add padding if bound check */
5069 if (tcc_state->do_bounds_check)
5070 data_offset++;
5071 #endif
5072 sec->data_offset = data_offset;
5073 /* allocate section space to put the data */
5074 if (sec->sh_type != SHT_NOBITS &&
5075 data_offset > sec->data_allocated)
5076 section_realloc(sec, data_offset);
5077 /* align section if needed */
5078 if (align > sec->sh_addralign)
5079 sec->sh_addralign = align;
5080 } else {
5081 addr = 0; /* avoid warning */
5084 if (v) {
5085 if (scope != VT_CONST || !sym) {
5086 sym = sym_push(v, type, r | VT_SYM, 0);
5088 /* update symbol definition */
5089 if (sec) {
5090 put_extern_sym(sym, sec, addr, size);
5091 } else {
5092 ElfW(Sym) *esym;
5093 /* put a common area */
5094 put_extern_sym(sym, NULL, align, size);
5095 /* XXX: find a nicer way */
5096 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5097 esym->st_shndx = SHN_COMMON;
5099 } else {
5100 CValue cval;
5102 /* push global reference */
5103 sym = get_sym_ref(type, sec, addr, size);
5104 cval.ul = 0;
5105 vsetc(type, VT_CONST | VT_SYM, &cval);
5106 vtop->sym = sym;
5108 #ifdef CONFIG_TCC_BCHECK
5109 /* handles bounds now because the symbol must be defined
5110 before for the relocation */
5111 if (tcc_state->do_bounds_check) {
5112 unsigned long *bounds_ptr;
5114 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5115 /* then add global bound info */
5116 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5117 bounds_ptr[0] = 0; /* relocated */
5118 bounds_ptr[1] = size;
5120 #endif
5122 if (has_init) {
5123 decl_initializer(type, sec, addr, 1, 0);
5124 /* restore parse state if needed */
5125 if (init_str.str) {
5126 tok_str_free(init_str.str);
5127 restore_parse_state(&saved_parse_state);
5130 no_alloc: ;
5133 static void put_func_debug(Sym *sym)
5135 char buf[512];
5137 /* stabs info */
5138 /* XXX: we put here a dummy type */
5139 snprintf(buf, sizeof(buf), "%s:%c1",
5140 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5141 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5142 cur_text_section, sym->c);
5143 /* //gr gdb wants a line at the function */
5144 put_stabn(N_SLINE, 0, file->line_num, 0);
5145 last_ind = 0;
5146 last_line_num = 0;
5149 /* parse an old style function declaration list */
5150 /* XXX: check multiple parameter */
5151 static void func_decl_list(Sym *func_sym)
5153 AttributeDef ad;
5154 int v;
5155 Sym *s;
5156 CType btype, type;
5158 /* parse each declaration */
5159 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
5160 if (!parse_btype(&btype, &ad))
5161 expect("declaration list");
5162 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5163 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5164 tok == ';') {
5165 /* we accept no variable after */
5166 } else {
5167 for(;;) {
5168 type = btype;
5169 type_decl(&type, &ad, &v, TYPE_DIRECT);
5170 /* find parameter in function parameter list */
5171 s = func_sym->next;
5172 while (s != NULL) {
5173 if ((s->v & ~SYM_FIELD) == v)
5174 goto found;
5175 s = s->next;
5177 error("declaration for parameter '%s' but no such parameter",
5178 get_tok_str(v, NULL));
5179 found:
5180 /* check that no storage specifier except 'register' was given */
5181 if (type.t & VT_STORAGE)
5182 error("storage class specified for '%s'", get_tok_str(v, NULL));
5183 convert_parameter_type(&type);
5184 /* we can add the type (NOTE: it could be local to the function) */
5185 s->type = type;
5186 /* accept other parameters */
5187 if (tok == ',')
5188 next();
5189 else
5190 break;
5193 skip(';');
5197 /* parse a function defined by symbol 'sym' and generate its code in
5198 'cur_text_section' */
5199 static void gen_function(Sym *sym)
5201 int saved_nocode_wanted = nocode_wanted;
5202 nocode_wanted = 0;
5203 ind = cur_text_section->data_offset;
5204 /* NOTE: we patch the symbol size later */
5205 put_extern_sym(sym, cur_text_section, ind, 0);
5206 funcname = get_tok_str(sym->v, NULL);
5207 func_ind = ind;
5208 /* put debug symbol */
5209 if (tcc_state->do_debug)
5210 put_func_debug(sym);
5211 /* push a dummy symbol to enable local sym storage */
5212 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5213 gfunc_prolog(&sym->type);
5214 rsym = 0;
5215 block(NULL, NULL, NULL, NULL, 0, 0);
5216 gsym(rsym);
5217 gfunc_epilog();
5218 cur_text_section->data_offset = ind;
5219 label_pop(&global_label_stack, NULL);
5220 sym_pop(&local_stack, NULL); /* reset local stack */
5221 /* end of function */
5222 /* patch symbol size */
5223 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5224 ind - func_ind;
5225 if (tcc_state->do_debug) {
5226 put_stabn(N_FUN, 0, 0, ind - func_ind);
5228 /* It's better to crash than to generate wrong code */
5229 cur_text_section = NULL;
5230 funcname = ""; /* for safety */
5231 func_vt.t = VT_VOID; /* for safety */
5232 ind = 0; /* for safety */
5233 nocode_wanted = saved_nocode_wanted;
5236 ST_FUNC void gen_inline_functions(void)
5238 Sym *sym;
5239 int *str, inline_generated, i;
5240 struct InlineFunc *fn;
5242 /* iterate while inline function are referenced */
5243 for(;;) {
5244 inline_generated = 0;
5245 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5246 fn = tcc_state->inline_fns[i];
5247 sym = fn->sym;
5248 if (sym && sym->c) {
5249 /* the function was used: generate its code and
5250 convert it to a normal function */
5251 str = fn->token_str;
5252 fn->sym = NULL;
5253 if (file)
5254 strcpy(file->filename, fn->filename);
5255 sym->r = VT_SYM | VT_CONST;
5256 sym->type.t &= ~VT_INLINE;
5258 macro_ptr = str;
5259 next();
5260 cur_text_section = text_section;
5261 gen_function(sym);
5262 macro_ptr = NULL; /* fail safe */
5264 inline_generated = 1;
5267 if (!inline_generated)
5268 break;
5270 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5271 fn = tcc_state->inline_fns[i];
5272 str = fn->token_str;
5273 tok_str_free(str);
5275 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5278 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5279 ST_FUNC void decl(int l)
5281 int v, has_init, r;
5282 CType type, btype;
5283 Sym *sym;
5284 AttributeDef ad;
5286 while (1) {
5287 if (!parse_btype(&btype, &ad)) {
5288 /* skip redundant ';' */
5289 /* XXX: find more elegant solution */
5290 if (tok == ';') {
5291 next();
5292 continue;
5294 if (l == VT_CONST &&
5295 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5296 /* global asm block */
5297 asm_global_instr();
5298 continue;
5300 /* special test for old K&R protos without explicit int
5301 type. Only accepted when defining global data */
5302 if (l == VT_LOCAL || tok < TOK_DEFINE)
5303 break;
5304 btype.t = VT_INT;
5306 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5307 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5308 tok == ';') {
5309 /* we accept no variable after */
5310 next();
5311 continue;
5313 while (1) { /* iterate thru each declaration */
5314 type = btype;
5315 type_decl(&type, &ad, &v, TYPE_DIRECT);
5316 #if 0
5318 char buf[500];
5319 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5320 printf("type = '%s'\n", buf);
5322 #endif
5323 if ((type.t & VT_BTYPE) == VT_FUNC) {
5324 /* if old style function prototype, we accept a
5325 declaration list */
5326 sym = type.ref;
5327 if (sym->c == FUNC_OLD)
5328 func_decl_list(sym);
5331 #ifdef TCC_TARGET_PE
5332 if (ad.func_import)
5333 type.t |= VT_IMPORT;
5334 if (ad.func_export)
5335 type.t |= VT_EXPORT;
5336 #endif
5337 if (tok == '{') {
5338 if (l == VT_LOCAL)
5339 error("cannot use local functions");
5340 if ((type.t & VT_BTYPE) != VT_FUNC)
5341 expect("function definition");
5343 /* reject abstract declarators in function definition */
5344 sym = type.ref;
5345 while ((sym = sym->next) != NULL)
5346 if (!(sym->v & ~SYM_FIELD))
5347 expect("identifier");
5349 /* XXX: cannot do better now: convert extern line to static inline */
5350 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5351 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5353 sym = sym_find(v);
5354 if (sym) {
5355 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5356 goto func_error1;
5358 r = sym->type.ref->r;
5359 /* use func_call from prototype if not defined */
5360 if (FUNC_CALL(r) != FUNC_CDECL
5361 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5362 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5364 /* use export from prototype */
5365 if (FUNC_EXPORT(r))
5366 FUNC_EXPORT(type.ref->r) = 1;
5368 /* use static from prototype */
5369 if (sym->type.t & VT_STATIC)
5370 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5372 if (!is_compatible_types(&sym->type, &type)) {
5373 func_error1:
5374 error("incompatible types for redefinition of '%s'",
5375 get_tok_str(v, NULL));
5377 /* if symbol is already defined, then put complete type */
5378 sym->type = type;
5379 } else {
5380 /* put function symbol */
5381 sym = global_identifier_push(v, type.t, 0);
5382 sym->type.ref = type.ref;
5385 /* static inline functions are just recorded as a kind
5386 of macro. Their code will be emitted at the end of
5387 the compilation unit only if they are used */
5388 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5389 (VT_INLINE | VT_STATIC)) {
5390 TokenString func_str;
5391 int block_level;
5392 struct InlineFunc *fn;
5393 const char *filename;
5395 tok_str_new(&func_str);
5397 block_level = 0;
5398 for(;;) {
5399 int t;
5400 if (tok == TOK_EOF)
5401 error("unexpected end of file");
5402 tok_str_add_tok(&func_str);
5403 t = tok;
5404 next();
5405 if (t == '{') {
5406 block_level++;
5407 } else if (t == '}') {
5408 block_level--;
5409 if (block_level == 0)
5410 break;
5413 tok_str_add(&func_str, -1);
5414 tok_str_add(&func_str, 0);
5415 filename = file ? file->filename : "";
5416 fn = tcc_malloc(sizeof *fn + strlen(filename));
5417 strcpy(fn->filename, filename);
5418 fn->sym = sym;
5419 fn->token_str = func_str.str;
5420 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5422 } else {
5423 /* compute text section */
5424 cur_text_section = ad.section;
5425 if (!cur_text_section)
5426 cur_text_section = text_section;
5427 sym->r = VT_SYM | VT_CONST;
5428 gen_function(sym);
5430 break;
5431 } else {
5432 if (btype.t & VT_TYPEDEF) {
5433 /* save typedefed type */
5434 /* XXX: test storage specifiers ? */
5435 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5436 sym->type.t |= VT_TYPEDEF;
5437 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
5438 Sym *fn;
5439 /* external function definition */
5440 /* specific case for func_call attribute */
5441 type.ref->r = INT_ATTR(&ad);
5442 fn = external_sym(v, &type, 0);
5444 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5445 char target[256];
5447 *target = 0;
5448 next();
5449 skip('(');
5450 /* Part 1: __USER_LABEL_PREFIX__ (user defined) */
5451 if (tok == TOK_STR)
5452 pstrcat(target, sizeof(target), tokc.cstr->data);
5453 else
5454 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5456 next();
5457 /* Part 2: api name */
5458 if (tok == TOK_STR)
5459 pstrcat(target, sizeof(target), tokc.cstr->data);
5460 else
5461 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5463 next();
5464 skip(')');
5465 if (tcc_state->warn_unsupported)
5466 warning("ignoring redirection from %s to %s\n", get_tok_str(v, NULL), target);
5468 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
5469 parse_attribute((AttributeDef *) &fn->type.ref->r);
5471 } else {
5472 /* not lvalue if array */
5473 r = 0;
5474 if (!(type.t & VT_ARRAY))
5475 r |= lvalue_type(type.t);
5476 has_init = (tok == '=');
5477 if ((btype.t & VT_EXTERN) ||
5478 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5479 !has_init && l == VT_CONST && type.ref->c < 0)) {
5480 /* external variable */
5481 /* NOTE: as GCC, uninitialized global static
5482 arrays of null size are considered as
5483 extern */
5484 external_sym(v, &type, r);
5485 } else {
5486 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5487 if (type.t & VT_STATIC)
5488 r |= VT_CONST;
5489 else
5490 r |= l;
5491 if (has_init)
5492 next();
5493 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
5496 if (tok != ',') {
5497 skip(';');
5498 break;
5500 next();