Delete unused vtop_saved variable in unary_type
[tinycc.git] / tccgen.c
blob6c8faa6b832d287848bca5dc71e73358f459fee4
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 if ((type->t & VT_STATIC) && local_stack) {
2989 error("Function without file scope cannot be static");
2991 next();
2992 l = 0;
2993 first = NULL;
2994 plast = &first;
2995 arg_size = 0;
2996 if (tok != ')') {
2997 for(;;) {
2998 /* read param name and compute offset */
2999 if (l != FUNC_OLD) {
3000 if (!parse_btype(&pt, &ad1)) {
3001 if (l) {
3002 error("invalid type");
3003 } else {
3004 l = FUNC_OLD;
3005 goto old_proto;
3008 l = FUNC_NEW;
3009 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3010 break;
3011 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3012 if ((pt.t & VT_BTYPE) == VT_VOID)
3013 error("parameter declared as void");
3014 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3015 } else {
3016 old_proto:
3017 n = tok;
3018 if (n < TOK_UIDENT)
3019 expect("identifier");
3020 pt.t = VT_INT;
3021 next();
3023 convert_parameter_type(&pt);
3024 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3025 *plast = s;
3026 plast = &s->next;
3027 if (tok == ')')
3028 break;
3029 skip(',');
3030 if (l == FUNC_NEW && tok == TOK_DOTS) {
3031 l = FUNC_ELLIPSIS;
3032 next();
3033 break;
3037 /* if no parameters, then old type prototype */
3038 if (l == 0)
3039 l = FUNC_OLD;
3040 skip(')');
3041 t1 = type->t & VT_STORAGE;
3042 /* NOTE: const is ignored in returned type as it has a special
3043 meaning in gcc / C++ */
3044 type->t &= ~(VT_STORAGE | VT_CONSTANT);
3045 post_type(type, ad);
3046 /* we push a anonymous symbol which will contain the function prototype */
3047 ad->func_args = arg_size;
3048 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3049 s->next = first;
3050 type->t = t1 | VT_FUNC;
3051 type->ref = s;
3052 } else if (tok == '[') {
3053 /* array definition */
3054 next();
3055 if (tok == TOK_RESTRICT1)
3056 next();
3057 n = -1;
3058 if (tok != ']') {
3059 n = expr_const();
3060 if (n < 0)
3061 error("invalid array size");
3063 skip(']');
3064 /* parse next post type */
3065 t1 = type->t & VT_STORAGE;
3066 type->t &= ~VT_STORAGE;
3067 post_type(type, ad);
3069 /* we push a anonymous symbol which will contain the array
3070 element type */
3071 s = sym_push(SYM_FIELD, type, 0, n);
3072 type->t = t1 | VT_ARRAY | VT_PTR;
3073 type->ref = s;
3077 /* Parse a type declaration (except basic type), and return the type
3078 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3079 expected. 'type' should contain the basic type. 'ad' is the
3080 attribute definition of the basic type. It can be modified by
3081 type_decl().
3083 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3085 Sym *s;
3086 CType type1, *type2;
3087 int qualifiers;
3089 while (tok == '*') {
3090 qualifiers = 0;
3091 redo:
3092 next();
3093 switch(tok) {
3094 case TOK_CONST1:
3095 case TOK_CONST2:
3096 case TOK_CONST3:
3097 qualifiers |= VT_CONSTANT;
3098 goto redo;
3099 case TOK_VOLATILE1:
3100 case TOK_VOLATILE2:
3101 case TOK_VOLATILE3:
3102 qualifiers |= VT_VOLATILE;
3103 goto redo;
3104 case TOK_RESTRICT1:
3105 case TOK_RESTRICT2:
3106 case TOK_RESTRICT3:
3107 goto redo;
3109 mk_pointer(type);
3110 type->t |= qualifiers;
3113 /* XXX: clarify attribute handling */
3114 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3115 parse_attribute(ad);
3117 /* recursive type */
3118 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3119 type1.t = 0; /* XXX: same as int */
3120 if (tok == '(') {
3121 next();
3122 /* XXX: this is not correct to modify 'ad' at this point, but
3123 the syntax is not clear */
3124 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3125 parse_attribute(ad);
3126 type_decl(&type1, ad, v, td);
3127 skip(')');
3128 } else {
3129 /* type identifier */
3130 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3131 *v = tok;
3132 next();
3133 } else {
3134 if (!(td & TYPE_ABSTRACT))
3135 expect("identifier");
3136 *v = 0;
3139 post_type(type, ad);
3140 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3141 parse_attribute(ad);
3142 if (!type1.t)
3143 return;
3144 /* append type at the end of type1 */
3145 type2 = &type1;
3146 for(;;) {
3147 s = type2->ref;
3148 type2 = &s->type;
3149 if (!type2->t) {
3150 *type2 = *type;
3151 break;
3154 *type = type1;
3157 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3158 ST_FUNC int lvalue_type(int t)
3160 int bt, r;
3161 r = VT_LVAL;
3162 bt = t & VT_BTYPE;
3163 if (bt == VT_BYTE || bt == VT_BOOL)
3164 r |= VT_LVAL_BYTE;
3165 else if (bt == VT_SHORT)
3166 r |= VT_LVAL_SHORT;
3167 else
3168 return r;
3169 if (t & VT_UNSIGNED)
3170 r |= VT_LVAL_UNSIGNED;
3171 return r;
3174 /* indirection with full error checking and bound check */
3175 ST_FUNC void indir(void)
3177 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3178 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3179 return;
3180 expect("pointer");
3182 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3183 gv(RC_INT);
3184 vtop->type = *pointed_type(&vtop->type);
3185 /* Arrays and functions are never lvalues */
3186 if (!(vtop->type.t & VT_ARRAY)
3187 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3188 vtop->r |= lvalue_type(vtop->type.t);
3189 /* if bound checking, the referenced pointer must be checked */
3190 #ifdef CONFIG_TCC_BCHECK
3191 if (tcc_state->do_bounds_check)
3192 vtop->r |= VT_MUSTBOUND;
3193 #endif
3197 /* pass a parameter to a function and do type checking and casting */
3198 static void gfunc_param_typed(Sym *func, Sym *arg)
3200 int func_type;
3201 CType type;
3203 func_type = func->c;
3204 if (func_type == FUNC_OLD ||
3205 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3206 /* default casting : only need to convert float to double */
3207 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3208 type.t = VT_DOUBLE;
3209 gen_cast(&type);
3211 } else if (arg == NULL) {
3212 error("too many arguments to function");
3213 } else {
3214 type = arg->type;
3215 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3216 gen_assign_cast(&type);
3220 /* parse an expression of the form '(type)' or '(expr)' and return its
3221 type */
3222 static void parse_expr_type(CType *type)
3224 int n;
3225 AttributeDef ad;
3227 skip('(');
3228 if (parse_btype(type, &ad)) {
3229 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3230 } else {
3231 expr_type(type);
3233 skip(')');
3236 static void parse_type(CType *type)
3238 AttributeDef ad;
3239 int n;
3241 if (!parse_btype(type, &ad)) {
3242 expect("type");
3244 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3247 static void vpush_tokc(int t)
3249 CType type;
3250 type.t = t;
3251 type.ref = 0;
3252 vsetc(&type, VT_CONST, &tokc);
3255 ST_FUNC void unary(void)
3257 int n, t, align, size, r, sizeof_caller;
3258 CType type;
3259 Sym *s;
3260 AttributeDef ad;
3261 static int in_sizeof = 0;
3263 sizeof_caller = in_sizeof;
3264 in_sizeof = 0;
3265 /* XXX: GCC 2.95.3 does not generate a table although it should be
3266 better here */
3267 tok_next:
3268 switch(tok) {
3269 case TOK_EXTENSION:
3270 next();
3271 goto tok_next;
3272 case TOK_CINT:
3273 case TOK_CCHAR:
3274 case TOK_LCHAR:
3275 vpushi(tokc.i);
3276 next();
3277 break;
3278 case TOK_CUINT:
3279 vpush_tokc(VT_INT | VT_UNSIGNED);
3280 next();
3281 break;
3282 case TOK_CLLONG:
3283 vpush_tokc(VT_LLONG);
3284 next();
3285 break;
3286 case TOK_CULLONG:
3287 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3288 next();
3289 break;
3290 case TOK_CFLOAT:
3291 vpush_tokc(VT_FLOAT);
3292 next();
3293 break;
3294 case TOK_CDOUBLE:
3295 vpush_tokc(VT_DOUBLE);
3296 next();
3297 break;
3298 case TOK_CLDOUBLE:
3299 vpush_tokc(VT_LDOUBLE);
3300 next();
3301 break;
3302 case TOK___FUNCTION__:
3303 if (!gnu_ext)
3304 goto tok_identifier;
3305 /* fall thru */
3306 case TOK___FUNC__:
3308 void *ptr;
3309 int len;
3310 /* special function name identifier */
3311 len = strlen(funcname) + 1;
3312 /* generate char[len] type */
3313 type.t = VT_BYTE;
3314 mk_pointer(&type);
3315 type.t |= VT_ARRAY;
3316 type.ref->c = len;
3317 vpush_ref(&type, data_section, data_section->data_offset, len);
3318 ptr = section_ptr_add(data_section, len);
3319 memcpy(ptr, funcname, len);
3320 next();
3322 break;
3323 case TOK_LSTR:
3324 #ifdef TCC_TARGET_PE
3325 t = VT_SHORT | VT_UNSIGNED;
3326 #else
3327 t = VT_INT;
3328 #endif
3329 goto str_init;
3330 case TOK_STR:
3331 /* string parsing */
3332 t = VT_BYTE;
3333 str_init:
3334 if (tcc_state->warn_write_strings)
3335 t |= VT_CONSTANT;
3336 type.t = t;
3337 mk_pointer(&type);
3338 type.t |= VT_ARRAY;
3339 memset(&ad, 0, sizeof(AttributeDef));
3340 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3341 break;
3342 case '(':
3343 next();
3344 /* cast ? */
3345 if (parse_btype(&type, &ad)) {
3346 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3347 skip(')');
3348 /* check ISOC99 compound literal */
3349 if (tok == '{') {
3350 /* data is allocated locally by default */
3351 if (global_expr)
3352 r = VT_CONST;
3353 else
3354 r = VT_LOCAL;
3355 /* all except arrays are lvalues */
3356 if (!(type.t & VT_ARRAY))
3357 r |= lvalue_type(type.t);
3358 memset(&ad, 0, sizeof(AttributeDef));
3359 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3360 } else {
3361 if (sizeof_caller) {
3362 vpush(&type);
3363 return;
3365 unary();
3366 gen_cast(&type);
3368 } else if (tok == '{') {
3369 /* save all registers */
3370 save_regs(0);
3371 /* statement expression : we do not accept break/continue
3372 inside as GCC does */
3373 block(NULL, NULL, NULL, NULL, 0, 1);
3374 skip(')');
3375 } else {
3376 gexpr();
3377 skip(')');
3379 break;
3380 case '*':
3381 next();
3382 unary();
3383 indir();
3384 break;
3385 case '&':
3386 next();
3387 unary();
3388 /* functions names must be treated as function pointers,
3389 except for unary '&' and sizeof. Since we consider that
3390 functions are not lvalues, we only have to handle it
3391 there and in function calls. */
3392 /* arrays can also be used although they are not lvalues */
3393 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3394 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3395 test_lvalue();
3396 mk_pointer(&vtop->type);
3397 gaddrof();
3398 break;
3399 case '!':
3400 next();
3401 unary();
3402 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3403 CType boolean;
3404 boolean.t = VT_BOOL;
3405 gen_cast(&boolean);
3406 vtop->c.i = !vtop->c.i;
3407 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3408 vtop->c.i = vtop->c.i ^ 1;
3409 else {
3410 save_regs(1);
3411 vseti(VT_JMP, gtst(1, 0));
3413 break;
3414 case '~':
3415 next();
3416 unary();
3417 vpushi(-1);
3418 gen_op('^');
3419 break;
3420 case '+':
3421 next();
3422 /* in order to force cast, we add zero */
3423 unary();
3424 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3425 error("pointer not accepted for unary plus");
3426 vpushi(0);
3427 gen_op('+');
3428 break;
3429 case TOK_SIZEOF:
3430 case TOK_ALIGNOF1:
3431 case TOK_ALIGNOF2:
3432 t = tok;
3433 next();
3434 in_sizeof++;
3435 unary_type(&type); // Perform a in_sizeof = 0;
3436 size = type_size(&type, &align);
3437 if (t == TOK_SIZEOF) {
3438 if (size < 0)
3439 error("sizeof applied to an incomplete type");
3440 vpushi(size);
3441 } else {
3442 vpushi(align);
3444 vtop->type.t |= VT_UNSIGNED;
3445 break;
3447 case TOK_builtin_types_compatible_p:
3449 CType type1, type2;
3450 next();
3451 skip('(');
3452 parse_type(&type1);
3453 skip(',');
3454 parse_type(&type2);
3455 skip(')');
3456 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3457 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3458 vpushi(is_compatible_types(&type1, &type2));
3460 break;
3461 case TOK_builtin_constant_p:
3463 int saved_nocode_wanted, res;
3464 next();
3465 skip('(');
3466 saved_nocode_wanted = nocode_wanted;
3467 nocode_wanted = 1;
3468 gexpr();
3469 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3470 vpop();
3471 nocode_wanted = saved_nocode_wanted;
3472 skip(')');
3473 vpushi(res);
3475 break;
3476 case TOK_builtin_frame_address:
3478 CType type;
3479 next();
3480 skip('(');
3481 if (tok != TOK_CINT) {
3482 error("__builtin_frame_address only takes integers");
3484 if (tokc.i != 0) {
3485 error("TCC only supports __builtin_frame_address(0)");
3487 next();
3488 skip(')');
3489 type.t = VT_VOID;
3490 mk_pointer(&type);
3491 vset(&type, VT_LOCAL, 0);
3493 break;
3494 #ifdef TCC_TARGET_X86_64
3495 case TOK_builtin_malloc:
3496 tok = TOK_malloc;
3497 goto tok_identifier;
3498 case TOK_builtin_free:
3499 tok = TOK_free;
3500 goto tok_identifier;
3501 #endif
3502 case TOK_INC:
3503 case TOK_DEC:
3504 t = tok;
3505 next();
3506 unary();
3507 inc(0, t);
3508 break;
3509 case '-':
3510 next();
3511 vpushi(0);
3512 unary();
3513 gen_op('-');
3514 break;
3515 case TOK_LAND:
3516 if (!gnu_ext)
3517 goto tok_identifier;
3518 next();
3519 /* allow to take the address of a label */
3520 if (tok < TOK_UIDENT)
3521 expect("label identifier");
3522 s = label_find(tok);
3523 if (!s) {
3524 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3525 } else {
3526 if (s->r == LABEL_DECLARED)
3527 s->r = LABEL_FORWARD;
3529 if (!s->type.t) {
3530 s->type.t = VT_VOID;
3531 mk_pointer(&s->type);
3532 s->type.t |= VT_STATIC;
3534 vset(&s->type, VT_CONST | VT_SYM, 0);
3535 vtop->sym = s;
3536 next();
3537 break;
3538 default:
3539 tok_identifier:
3540 t = tok;
3541 next();
3542 if (t < TOK_UIDENT)
3543 expect("identifier");
3544 s = sym_find(t);
3545 if (!s) {
3546 if (tok != '(')
3547 error("'%s' undeclared", get_tok_str(t, NULL));
3548 /* for simple function calls, we tolerate undeclared
3549 external reference to int() function */
3550 if (tcc_state->warn_implicit_function_declaration)
3551 warning("implicit declaration of function '%s'",
3552 get_tok_str(t, NULL));
3553 s = external_global_sym(t, &func_old_type, 0);
3555 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3556 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3557 /* if referencing an inline function, then we generate a
3558 symbol to it if not already done. It will have the
3559 effect to generate code for it at the end of the
3560 compilation unit. Inline function as always
3561 generated in the text section. */
3562 if (!s->c)
3563 put_extern_sym(s, text_section, 0, 0);
3564 r = VT_SYM | VT_CONST;
3565 } else {
3566 r = s->r;
3568 vset(&s->type, r, s->c);
3569 /* if forward reference, we must point to s */
3570 if (vtop->r & VT_SYM) {
3571 vtop->sym = s;
3572 vtop->c.ul = 0;
3574 break;
3577 /* post operations */
3578 while (1) {
3579 if (tok == TOK_INC || tok == TOK_DEC) {
3580 inc(1, tok);
3581 next();
3582 } else if (tok == '.' || tok == TOK_ARROW) {
3583 int qualifiers;
3584 /* field */
3585 if (tok == TOK_ARROW)
3586 indir();
3587 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3588 test_lvalue();
3589 gaddrof();
3590 next();
3591 /* expect pointer on structure */
3592 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3593 expect("struct or union");
3594 s = vtop->type.ref;
3595 /* find field */
3596 tok |= SYM_FIELD;
3597 while ((s = s->next) != NULL) {
3598 if (s->v == tok)
3599 break;
3601 if (!s)
3602 error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3603 /* add field offset to pointer */
3604 vtop->type = char_pointer_type; /* change type to 'char *' */
3605 vpushi(s->c);
3606 gen_op('+');
3607 /* change type to field type, and set to lvalue */
3608 vtop->type = s->type;
3609 vtop->type.t |= qualifiers;
3610 /* an array is never an lvalue */
3611 if (!(vtop->type.t & VT_ARRAY)) {
3612 vtop->r |= lvalue_type(vtop->type.t);
3613 #ifdef CONFIG_TCC_BCHECK
3614 /* if bound checking, the referenced pointer must be checked */
3615 if (tcc_state->do_bounds_check)
3616 vtop->r |= VT_MUSTBOUND;
3617 #endif
3619 next();
3620 } else if (tok == '[') {
3621 next();
3622 gexpr();
3623 gen_op('+');
3624 indir();
3625 skip(']');
3626 } else if (tok == '(') {
3627 SValue ret;
3628 Sym *sa;
3629 int nb_args;
3631 /* function call */
3632 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3633 /* pointer test (no array accepted) */
3634 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3635 vtop->type = *pointed_type(&vtop->type);
3636 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3637 goto error_func;
3638 } else {
3639 error_func:
3640 expect("function pointer");
3642 } else {
3643 vtop->r &= ~VT_LVAL; /* no lvalue */
3645 /* get return type */
3646 s = vtop->type.ref;
3647 next();
3648 sa = s->next; /* first parameter */
3649 nb_args = 0;
3650 ret.r2 = VT_CONST;
3651 /* compute first implicit argument if a structure is returned */
3652 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3653 /* get some space for the returned structure */
3654 size = type_size(&s->type, &align);
3655 loc = (loc - size) & -align;
3656 ret.type = s->type;
3657 ret.r = VT_LOCAL | VT_LVAL;
3658 /* pass it as 'int' to avoid structure arg passing
3659 problems */
3660 vseti(VT_LOCAL, loc);
3661 ret.c = vtop->c;
3662 nb_args++;
3663 } else {
3664 ret.type = s->type;
3665 /* return in register */
3666 if (is_float(ret.type.t)) {
3667 ret.r = reg_fret(ret.type.t);
3668 } else {
3669 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3670 ret.r2 = REG_LRET;
3671 ret.r = REG_IRET;
3673 ret.c.i = 0;
3675 if (tok != ')') {
3676 for(;;) {
3677 expr_eq();
3678 gfunc_param_typed(s, sa);
3679 nb_args++;
3680 if (sa)
3681 sa = sa->next;
3682 if (tok == ')')
3683 break;
3684 skip(',');
3687 if (sa)
3688 error("too few arguments to function");
3689 skip(')');
3690 if (!nocode_wanted) {
3691 gfunc_call(nb_args);
3692 } else {
3693 vtop -= (nb_args + 1);
3695 /* return value */
3696 vsetc(&ret.type, ret.r, &ret.c);
3697 vtop->r2 = ret.r2;
3698 } else {
3699 break;
3704 static void uneq(void)
3706 int t;
3708 unary();
3709 if (tok == '=' ||
3710 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
3711 tok == TOK_A_XOR || tok == TOK_A_OR ||
3712 tok == TOK_A_SHL || tok == TOK_A_SAR) {
3713 test_lvalue();
3714 t = tok;
3715 next();
3716 if (t == '=') {
3717 expr_eq();
3718 } else {
3719 vdup();
3720 expr_eq();
3721 gen_op(t & 0x7f);
3723 vstore();
3727 ST_FUNC void expr_prod(void)
3729 int t;
3731 uneq();
3732 while (tok == '*' || tok == '/' || tok == '%') {
3733 t = tok;
3734 next();
3735 uneq();
3736 gen_op(t);
3740 ST_FUNC void expr_sum(void)
3742 int t;
3744 expr_prod();
3745 while (tok == '+' || tok == '-') {
3746 t = tok;
3747 next();
3748 expr_prod();
3749 gen_op(t);
3753 static void expr_shift(void)
3755 int t;
3757 expr_sum();
3758 while (tok == TOK_SHL || tok == TOK_SAR) {
3759 t = tok;
3760 next();
3761 expr_sum();
3762 gen_op(t);
3766 static void expr_cmp(void)
3768 int t;
3770 expr_shift();
3771 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3772 tok == TOK_ULT || tok == TOK_UGE) {
3773 t = tok;
3774 next();
3775 expr_shift();
3776 gen_op(t);
3780 static void expr_cmpeq(void)
3782 int t;
3784 expr_cmp();
3785 while (tok == TOK_EQ || tok == TOK_NE) {
3786 t = tok;
3787 next();
3788 expr_cmp();
3789 gen_op(t);
3793 static void expr_and(void)
3795 expr_cmpeq();
3796 while (tok == '&') {
3797 next();
3798 expr_cmpeq();
3799 gen_op('&');
3803 static void expr_xor(void)
3805 expr_and();
3806 while (tok == '^') {
3807 next();
3808 expr_and();
3809 gen_op('^');
3813 static void expr_or(void)
3815 expr_xor();
3816 while (tok == '|') {
3817 next();
3818 expr_xor();
3819 gen_op('|');
3823 /* XXX: fix this mess */
3824 static void expr_land_const(void)
3826 expr_or();
3827 while (tok == TOK_LAND) {
3828 next();
3829 expr_or();
3830 gen_op(TOK_LAND);
3834 /* XXX: fix this mess */
3835 static void expr_lor_const(void)
3837 expr_land_const();
3838 while (tok == TOK_LOR) {
3839 next();
3840 expr_land_const();
3841 gen_op(TOK_LOR);
3845 /* only used if non constant */
3846 static void expr_land(void)
3848 int t;
3850 expr_or();
3851 if (tok == TOK_LAND) {
3852 t = 0;
3853 save_regs(1);
3854 for(;;) {
3855 t = gtst(1, t);
3856 if (tok != TOK_LAND) {
3857 vseti(VT_JMPI, t);
3858 break;
3860 next();
3861 expr_or();
3866 static void expr_lor(void)
3868 int t;
3870 expr_land();
3871 if (tok == TOK_LOR) {
3872 t = 0;
3873 save_regs(1);
3874 for(;;) {
3875 t = gtst(0, t);
3876 if (tok != TOK_LOR) {
3877 vseti(VT_JMP, t);
3878 break;
3880 next();
3881 expr_land();
3886 /* XXX: better constant handling */
3887 static void expr_eq(void)
3889 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
3890 SValue sv;
3891 CType type, type1, type2;
3893 if (const_wanted) {
3894 expr_lor_const();
3895 if (tok == '?') {
3896 CType boolean;
3897 int c;
3898 boolean.t = VT_BOOL;
3899 vdup();
3900 gen_cast(&boolean);
3901 c = vtop->c.i;
3902 vpop();
3903 next();
3904 if (tok != ':' || !gnu_ext) {
3905 vpop();
3906 gexpr();
3908 if (!c)
3909 vpop();
3910 skip(':');
3911 expr_eq();
3912 if (c)
3913 vpop();
3915 } else {
3916 expr_lor();
3917 if (tok == '?') {
3918 next();
3919 if (vtop != vstack) {
3920 /* needed to avoid having different registers saved in
3921 each branch */
3922 if (is_float(vtop->type.t)) {
3923 rc = RC_FLOAT;
3924 #ifdef TCC_TARGET_X86_64
3925 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
3926 rc = RC_ST0;
3928 #endif
3930 else
3931 rc = RC_INT;
3932 gv(rc);
3933 save_regs(1);
3935 if (tok == ':' && gnu_ext) {
3936 gv_dup();
3937 tt = gtst(1, 0);
3938 } else {
3939 tt = gtst(1, 0);
3940 gexpr();
3942 type1 = vtop->type;
3943 sv = *vtop; /* save value to handle it later */
3944 vtop--; /* no vpop so that FP stack is not flushed */
3945 skip(':');
3946 u = gjmp(0);
3947 gsym(tt);
3948 expr_eq();
3949 type2 = vtop->type;
3951 t1 = type1.t;
3952 bt1 = t1 & VT_BTYPE;
3953 t2 = type2.t;
3954 bt2 = t2 & VT_BTYPE;
3955 /* cast operands to correct type according to ISOC rules */
3956 if (is_float(bt1) || is_float(bt2)) {
3957 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3958 type.t = VT_LDOUBLE;
3959 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3960 type.t = VT_DOUBLE;
3961 } else {
3962 type.t = VT_FLOAT;
3964 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3965 /* cast to biggest op */
3966 type.t = VT_LLONG;
3967 /* convert to unsigned if it does not fit in a long long */
3968 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3969 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3970 type.t |= VT_UNSIGNED;
3971 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
3972 /* XXX: test pointer compatibility */
3973 type = type1;
3974 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
3975 /* XXX: test function pointer compatibility */
3976 type = type1;
3977 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3978 /* XXX: test structure compatibility */
3979 type = type1;
3980 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
3981 /* NOTE: as an extension, we accept void on only one side */
3982 type.t = VT_VOID;
3983 } else {
3984 /* integer operations */
3985 type.t = VT_INT;
3986 /* convert to unsigned if it does not fit in an integer */
3987 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3988 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3989 type.t |= VT_UNSIGNED;
3992 /* now we convert second operand */
3993 gen_cast(&type);
3994 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
3995 gaddrof();
3996 rc = RC_INT;
3997 if (is_float(type.t)) {
3998 rc = RC_FLOAT;
3999 #ifdef TCC_TARGET_X86_64
4000 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4001 rc = RC_ST0;
4003 #endif
4004 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4005 /* for long longs, we use fixed registers to avoid having
4006 to handle a complicated move */
4007 rc = RC_IRET;
4010 r2 = gv(rc);
4011 /* this is horrible, but we must also convert first
4012 operand */
4013 tt = gjmp(0);
4014 gsym(u);
4015 /* put again first value and cast it */
4016 *vtop = sv;
4017 gen_cast(&type);
4018 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4019 gaddrof();
4020 r1 = gv(rc);
4021 move_reg(r2, r1);
4022 vtop->r = r2;
4023 gsym(tt);
4028 ST_FUNC void gexpr(void)
4030 while (1) {
4031 expr_eq();
4032 if (tok != ',')
4033 break;
4034 vpop();
4035 next();
4039 /* parse an expression and return its type without any side effect. */
4040 static void expr_type(CType *type)
4042 int saved_nocode_wanted;
4044 saved_nocode_wanted = nocode_wanted;
4045 nocode_wanted = 1;
4046 gexpr();
4047 *type = vtop->type;
4048 vpop();
4049 nocode_wanted = saved_nocode_wanted;
4052 /* parse a unary expression and return its type without any side
4053 effect. */
4054 static void unary_type(CType *type)
4056 int a;
4058 a = nocode_wanted;
4059 nocode_wanted = 1;
4060 unary();
4061 *type = vtop->type;
4062 vpop();
4063 nocode_wanted = a;
4066 /* parse a constant expression and return value in vtop. */
4067 static void expr_const1(void)
4069 int a;
4070 a = const_wanted;
4071 const_wanted = 1;
4072 expr_eq();
4073 const_wanted = a;
4076 /* parse an integer constant and return its value. */
4077 ST_FUNC int expr_const(void)
4079 int c;
4080 expr_const1();
4081 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4082 expect("constant expression");
4083 c = vtop->c.i;
4084 vpop();
4085 return c;
4088 /* return the label token if current token is a label, otherwise
4089 return zero */
4090 static int is_label(void)
4092 int last_tok;
4094 /* fast test first */
4095 if (tok < TOK_UIDENT)
4096 return 0;
4097 /* no need to save tokc because tok is an identifier */
4098 last_tok = tok;
4099 next();
4100 if (tok == ':') {
4101 next();
4102 return last_tok;
4103 } else {
4104 unget_tok(last_tok);
4105 return 0;
4109 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4110 int case_reg, int is_expr)
4112 int a, b, c, d;
4113 Sym *s;
4115 /* generate line number info */
4116 if (tcc_state->do_debug &&
4117 (last_line_num != file->line_num || last_ind != ind)) {
4118 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4119 last_ind = ind;
4120 last_line_num = file->line_num;
4123 if (is_expr) {
4124 /* default return value is (void) */
4125 vpushi(0);
4126 vtop->type.t = VT_VOID;
4129 if (tok == TOK_IF) {
4130 /* if test */
4131 next();
4132 skip('(');
4133 gexpr();
4134 skip(')');
4135 a = gtst(1, 0);
4136 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4137 c = tok;
4138 if (c == TOK_ELSE) {
4139 next();
4140 d = gjmp(0);
4141 gsym(a);
4142 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4143 gsym(d); /* patch else jmp */
4144 } else
4145 gsym(a);
4146 } else if (tok == TOK_WHILE) {
4147 next();
4148 d = ind;
4149 skip('(');
4150 gexpr();
4151 skip(')');
4152 a = gtst(1, 0);
4153 b = 0;
4154 block(&a, &b, case_sym, def_sym, case_reg, 0);
4155 gjmp_addr(d);
4156 gsym(a);
4157 gsym_addr(b, d);
4158 } else if (tok == '{') {
4159 Sym *llabel;
4161 next();
4162 /* record local declaration stack position */
4163 s = local_stack;
4164 llabel = local_label_stack;
4165 /* handle local labels declarations */
4166 if (tok == TOK_LABEL) {
4167 next();
4168 for(;;) {
4169 if (tok < TOK_UIDENT)
4170 expect("label identifier");
4171 label_push(&local_label_stack, tok, LABEL_DECLARED);
4172 next();
4173 if (tok == ',') {
4174 next();
4175 } else {
4176 skip(';');
4177 break;
4181 while (tok != '}') {
4182 decl(VT_LOCAL);
4183 if (tok != '}') {
4184 if (is_expr)
4185 vpop();
4186 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4189 /* pop locally defined labels */
4190 label_pop(&local_label_stack, llabel);
4191 /* pop locally defined symbols */
4192 if(is_expr) {
4193 /* XXX: this solution makes only valgrind happy...
4194 triggered by gcc.c-torture/execute/20000917-1.c */
4195 Sym *p;
4196 switch(vtop->type.t & VT_BTYPE) {
4197 case VT_PTR:
4198 case VT_STRUCT:
4199 case VT_ENUM:
4200 case VT_FUNC:
4201 for(p=vtop->type.ref;p;p=p->prev)
4202 if(p->prev==s)
4203 error("unsupported expression type");
4206 sym_pop(&local_stack, s);
4207 next();
4208 } else if (tok == TOK_RETURN) {
4209 next();
4210 if (tok != ';') {
4211 gexpr();
4212 gen_assign_cast(&func_vt);
4213 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4214 CType type;
4215 /* if returning structure, must copy it to implicit
4216 first pointer arg location */
4217 #ifdef TCC_ARM_EABI
4218 int align, size;
4219 size = type_size(&func_vt,&align);
4220 if(size <= 4)
4222 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
4223 && (align & 3))
4225 int addr;
4226 loc = (loc - size) & -4;
4227 addr = loc;
4228 type = func_vt;
4229 vset(&type, VT_LOCAL | VT_LVAL, addr);
4230 vswap();
4231 vstore();
4232 vset(&int_type, VT_LOCAL | VT_LVAL, addr);
4234 vtop->type = int_type;
4235 gv(RC_IRET);
4236 } else {
4237 #endif
4238 type = func_vt;
4239 mk_pointer(&type);
4240 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4241 indir();
4242 vswap();
4243 /* copy structure value to pointer */
4244 vstore();
4245 #ifdef TCC_ARM_EABI
4247 #endif
4248 } else if (is_float(func_vt.t)) {
4249 gv(rc_fret(func_vt.t));
4250 } else {
4251 gv(RC_IRET);
4253 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4255 skip(';');
4256 rsym = gjmp(rsym); /* jmp */
4257 } else if (tok == TOK_BREAK) {
4258 /* compute jump */
4259 if (!bsym)
4260 error("cannot break");
4261 *bsym = gjmp(*bsym);
4262 next();
4263 skip(';');
4264 } else if (tok == TOK_CONTINUE) {
4265 /* compute jump */
4266 if (!csym)
4267 error("cannot continue");
4268 *csym = gjmp(*csym);
4269 next();
4270 skip(';');
4271 } else if (tok == TOK_FOR) {
4272 int e;
4273 next();
4274 skip('(');
4275 if (tok != ';') {
4276 gexpr();
4277 vpop();
4279 skip(';');
4280 d = ind;
4281 c = ind;
4282 a = 0;
4283 b = 0;
4284 if (tok != ';') {
4285 gexpr();
4286 a = gtst(1, 0);
4288 skip(';');
4289 if (tok != ')') {
4290 e = gjmp(0);
4291 c = ind;
4292 gexpr();
4293 vpop();
4294 gjmp_addr(d);
4295 gsym(e);
4297 skip(')');
4298 block(&a, &b, case_sym, def_sym, case_reg, 0);
4299 gjmp_addr(c);
4300 gsym(a);
4301 gsym_addr(b, c);
4302 } else
4303 if (tok == TOK_DO) {
4304 next();
4305 a = 0;
4306 b = 0;
4307 d = ind;
4308 block(&a, &b, case_sym, def_sym, case_reg, 0);
4309 skip(TOK_WHILE);
4310 skip('(');
4311 gsym(b);
4312 gexpr();
4313 c = gtst(0, 0);
4314 gsym_addr(c, d);
4315 skip(')');
4316 gsym(a);
4317 skip(';');
4318 } else
4319 if (tok == TOK_SWITCH) {
4320 next();
4321 skip('(');
4322 gexpr();
4323 /* XXX: other types than integer */
4324 case_reg = gv(RC_INT);
4325 vpop();
4326 skip(')');
4327 a = 0;
4328 b = gjmp(0); /* jump to first case */
4329 c = 0;
4330 block(&a, csym, &b, &c, case_reg, 0);
4331 /* if no default, jmp after switch */
4332 if (c == 0)
4333 c = ind;
4334 /* default label */
4335 gsym_addr(b, c);
4336 /* break label */
4337 gsym(a);
4338 } else
4339 if (tok == TOK_CASE) {
4340 int v1, v2;
4341 if (!case_sym)
4342 expect("switch");
4343 next();
4344 v1 = expr_const();
4345 v2 = v1;
4346 if (gnu_ext && tok == TOK_DOTS) {
4347 next();
4348 v2 = expr_const();
4349 if (v2 < v1)
4350 warning("empty case range");
4352 /* since a case is like a label, we must skip it with a jmp */
4353 b = gjmp(0);
4354 gsym(*case_sym);
4355 vseti(case_reg, 0);
4356 vpushi(v1);
4357 if (v1 == v2) {
4358 gen_op(TOK_EQ);
4359 *case_sym = gtst(1, 0);
4360 } else {
4361 gen_op(TOK_GE);
4362 *case_sym = gtst(1, 0);
4363 vseti(case_reg, 0);
4364 vpushi(v2);
4365 gen_op(TOK_LE);
4366 *case_sym = gtst(1, *case_sym);
4368 gsym(b);
4369 skip(':');
4370 is_expr = 0;
4371 goto block_after_label;
4372 } else
4373 if (tok == TOK_DEFAULT) {
4374 next();
4375 skip(':');
4376 if (!def_sym)
4377 expect("switch");
4378 if (*def_sym)
4379 error("too many 'default'");
4380 *def_sym = ind;
4381 is_expr = 0;
4382 goto block_after_label;
4383 } else
4384 if (tok == TOK_GOTO) {
4385 next();
4386 if (tok == '*' && gnu_ext) {
4387 /* computed goto */
4388 next();
4389 gexpr();
4390 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4391 expect("pointer");
4392 ggoto();
4393 } else if (tok >= TOK_UIDENT) {
4394 s = label_find(tok);
4395 /* put forward definition if needed */
4396 if (!s) {
4397 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4398 } else {
4399 if (s->r == LABEL_DECLARED)
4400 s->r = LABEL_FORWARD;
4402 /* label already defined */
4403 if (s->r & LABEL_FORWARD)
4404 s->jnext = gjmp(s->jnext);
4405 else
4406 gjmp_addr(s->jnext);
4407 next();
4408 } else {
4409 expect("label identifier");
4411 skip(';');
4412 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4413 asm_instr();
4414 } else {
4415 b = is_label();
4416 if (b) {
4417 /* label case */
4418 s = label_find(b);
4419 if (s) {
4420 if (s->r == LABEL_DEFINED)
4421 error("duplicate label '%s'", get_tok_str(s->v, NULL));
4422 gsym(s->jnext);
4423 s->r = LABEL_DEFINED;
4424 } else {
4425 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4427 s->jnext = ind;
4428 /* we accept this, but it is a mistake */
4429 block_after_label:
4430 if (tok == '}') {
4431 warning("deprecated use of label at end of compound statement");
4432 } else {
4433 if (is_expr)
4434 vpop();
4435 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4437 } else {
4438 /* expression case */
4439 if (tok != ';') {
4440 if (is_expr) {
4441 vpop();
4442 gexpr();
4443 } else {
4444 gexpr();
4445 vpop();
4448 skip(';');
4453 /* t is the array or struct type. c is the array or struct
4454 address. cur_index/cur_field is the pointer to the current
4455 value. 'size_only' is true if only size info is needed (only used
4456 in arrays) */
4457 static void decl_designator(CType *type, Section *sec, unsigned long c,
4458 int *cur_index, Sym **cur_field,
4459 int size_only)
4461 Sym *s, *f;
4462 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4463 CType type1;
4465 notfirst = 0;
4466 elem_size = 0;
4467 nb_elems = 1;
4468 if (gnu_ext && (l = is_label()) != 0)
4469 goto struct_field;
4470 while (tok == '[' || tok == '.') {
4471 if (tok == '[') {
4472 if (!(type->t & VT_ARRAY))
4473 expect("array type");
4474 s = type->ref;
4475 next();
4476 index = expr_const();
4477 if (index < 0 || (s->c >= 0 && index >= s->c))
4478 expect("invalid index");
4479 if (tok == TOK_DOTS && gnu_ext) {
4480 next();
4481 index_last = expr_const();
4482 if (index_last < 0 ||
4483 (s->c >= 0 && index_last >= s->c) ||
4484 index_last < index)
4485 expect("invalid index");
4486 } else {
4487 index_last = index;
4489 skip(']');
4490 if (!notfirst)
4491 *cur_index = index_last;
4492 type = pointed_type(type);
4493 elem_size = type_size(type, &align);
4494 c += index * elem_size;
4495 /* NOTE: we only support ranges for last designator */
4496 nb_elems = index_last - index + 1;
4497 if (nb_elems != 1) {
4498 notfirst = 1;
4499 break;
4501 } else {
4502 next();
4503 l = tok;
4504 next();
4505 struct_field:
4506 if ((type->t & VT_BTYPE) != VT_STRUCT)
4507 expect("struct/union type");
4508 s = type->ref;
4509 l |= SYM_FIELD;
4510 f = s->next;
4511 while (f) {
4512 if (f->v == l)
4513 break;
4514 f = f->next;
4516 if (!f)
4517 expect("field");
4518 if (!notfirst)
4519 *cur_field = f;
4520 /* XXX: fix this mess by using explicit storage field */
4521 type1 = f->type;
4522 type1.t |= (type->t & ~VT_TYPE);
4523 type = &type1;
4524 c += f->c;
4526 notfirst = 1;
4528 if (notfirst) {
4529 if (tok == '=') {
4530 next();
4531 } else {
4532 if (!gnu_ext)
4533 expect("=");
4535 } else {
4536 if (type->t & VT_ARRAY) {
4537 index = *cur_index;
4538 type = pointed_type(type);
4539 c += index * type_size(type, &align);
4540 } else {
4541 f = *cur_field;
4542 if (!f)
4543 error("too many field init");
4544 /* XXX: fix this mess by using explicit storage field */
4545 type1 = f->type;
4546 type1.t |= (type->t & ~VT_TYPE);
4547 type = &type1;
4548 c += f->c;
4551 decl_initializer(type, sec, c, 0, size_only);
4553 /* XXX: make it more general */
4554 if (!size_only && nb_elems > 1) {
4555 unsigned long c_end;
4556 uint8_t *src, *dst;
4557 int i;
4559 if (!sec)
4560 error("range init not supported yet for dynamic storage");
4561 c_end = c + nb_elems * elem_size;
4562 if (c_end > sec->data_allocated)
4563 section_realloc(sec, c_end);
4564 src = sec->data + c;
4565 dst = src;
4566 for(i = 1; i < nb_elems; i++) {
4567 dst += elem_size;
4568 memcpy(dst, src, elem_size);
4573 #define EXPR_VAL 0
4574 #define EXPR_CONST 1
4575 #define EXPR_ANY 2
4577 /* store a value or an expression directly in global data or in local array */
4578 static void init_putv(CType *type, Section *sec, unsigned long c,
4579 int v, int expr_type)
4581 int saved_global_expr, bt, bit_pos, bit_size;
4582 void *ptr;
4583 unsigned long long bit_mask;
4584 CType dtype;
4586 switch(expr_type) {
4587 case EXPR_VAL:
4588 vpushi(v);
4589 break;
4590 case EXPR_CONST:
4591 /* compound literals must be allocated globally in this case */
4592 saved_global_expr = global_expr;
4593 global_expr = 1;
4594 expr_const1();
4595 global_expr = saved_global_expr;
4596 /* NOTE: symbols are accepted */
4597 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4598 error("initializer element is not constant");
4599 break;
4600 case EXPR_ANY:
4601 expr_eq();
4602 break;
4605 dtype = *type;
4606 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4608 if (sec) {
4609 /* XXX: not portable */
4610 /* XXX: generate error if incorrect relocation */
4611 gen_assign_cast(&dtype);
4612 bt = type->t & VT_BTYPE;
4613 /* we'll write at most 12 bytes */
4614 if (c + 12 > sec->data_allocated) {
4615 section_realloc(sec, c + 12);
4617 ptr = sec->data + c;
4618 /* XXX: make code faster ? */
4619 if (!(type->t & VT_BITFIELD)) {
4620 bit_pos = 0;
4621 bit_size = 32;
4622 bit_mask = -1LL;
4623 } else {
4624 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4625 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4626 bit_mask = (1LL << bit_size) - 1;
4628 if ((vtop->r & VT_SYM) &&
4629 (bt == VT_BYTE ||
4630 bt == VT_SHORT ||
4631 bt == VT_DOUBLE ||
4632 bt == VT_LDOUBLE ||
4633 bt == VT_LLONG ||
4634 (bt == VT_INT && bit_size != 32)))
4635 error("initializer element is not computable at load time");
4636 switch(bt) {
4637 case VT_BOOL:
4638 vtop->c.i = (vtop->c.i != 0);
4639 case VT_BYTE:
4640 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4641 break;
4642 case VT_SHORT:
4643 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4644 break;
4645 case VT_DOUBLE:
4646 *(double *)ptr = vtop->c.d;
4647 break;
4648 case VT_LDOUBLE:
4649 *(long double *)ptr = vtop->c.ld;
4650 break;
4651 case VT_LLONG:
4652 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4653 break;
4654 default:
4655 if (vtop->r & VT_SYM) {
4656 greloc(sec, vtop->sym, c, R_DATA_PTR);
4658 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4659 break;
4661 vtop--;
4662 } else {
4663 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4664 vswap();
4665 vstore();
4666 vpop();
4670 /* put zeros for variable based init */
4671 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
4673 if (sec) {
4674 /* nothing to do because globals are already set to zero */
4675 } else {
4676 vpush_global_sym(&func_old_type, TOK_memset);
4677 vseti(VT_LOCAL, c);
4678 vpushi(0);
4679 vpushi(size);
4680 gfunc_call(3);
4684 /* 't' contains the type and storage info. 'c' is the offset of the
4685 object in section 'sec'. If 'sec' is NULL, it means stack based
4686 allocation. 'first' is true if array '{' must be read (multi
4687 dimension implicit array init handling). 'size_only' is true if
4688 size only evaluation is wanted (only for arrays). */
4689 static void decl_initializer(CType *type, Section *sec, unsigned long c,
4690 int first, int size_only)
4692 int index, array_length, n, no_oblock, nb, parlevel, i;
4693 int size1, align1, expr_type;
4694 Sym *s, *f;
4695 CType *t1;
4697 if (type->t & VT_ARRAY) {
4698 s = type->ref;
4699 n = s->c;
4700 array_length = 0;
4701 t1 = pointed_type(type);
4702 size1 = type_size(t1, &align1);
4704 no_oblock = 1;
4705 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
4706 tok == '{') {
4707 if (tok != '{')
4708 error("character array initializer must be a literal,"
4709 " optionally enclosed in braces");
4710 skip('{');
4711 no_oblock = 0;
4714 /* only parse strings here if correct type (otherwise: handle
4715 them as ((w)char *) expressions */
4716 if ((tok == TOK_LSTR &&
4717 #ifdef TCC_TARGET_PE
4718 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
4719 #else
4720 (t1->t & VT_BTYPE) == VT_INT
4721 #endif
4722 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
4723 while (tok == TOK_STR || tok == TOK_LSTR) {
4724 int cstr_len, ch;
4725 CString *cstr;
4727 cstr = tokc.cstr;
4728 /* compute maximum number of chars wanted */
4729 if (tok == TOK_STR)
4730 cstr_len = cstr->size;
4731 else
4732 cstr_len = cstr->size / sizeof(nwchar_t);
4733 cstr_len--;
4734 nb = cstr_len;
4735 if (n >= 0 && nb > (n - array_length))
4736 nb = n - array_length;
4737 if (!size_only) {
4738 if (cstr_len > nb)
4739 warning("initializer-string for array is too long");
4740 /* in order to go faster for common case (char
4741 string in global variable, we handle it
4742 specifically */
4743 if (sec && tok == TOK_STR && size1 == 1) {
4744 memcpy(sec->data + c + array_length, cstr->data, nb);
4745 } else {
4746 for(i=0;i<nb;i++) {
4747 if (tok == TOK_STR)
4748 ch = ((unsigned char *)cstr->data)[i];
4749 else
4750 ch = ((nwchar_t *)cstr->data)[i];
4751 init_putv(t1, sec, c + (array_length + i) * size1,
4752 ch, EXPR_VAL);
4756 array_length += nb;
4757 next();
4759 /* only add trailing zero if enough storage (no
4760 warning in this case since it is standard) */
4761 if (n < 0 || array_length < n) {
4762 if (!size_only) {
4763 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
4765 array_length++;
4767 } else {
4768 index = 0;
4769 while (tok != '}') {
4770 decl_designator(type, sec, c, &index, NULL, size_only);
4771 if (n >= 0 && index >= n)
4772 error("index too large");
4773 /* must put zero in holes (note that doing it that way
4774 ensures that it even works with designators) */
4775 if (!size_only && array_length < index) {
4776 init_putz(t1, sec, c + array_length * size1,
4777 (index - array_length) * size1);
4779 index++;
4780 if (index > array_length)
4781 array_length = index;
4782 /* special test for multi dimensional arrays (may not
4783 be strictly correct if designators are used at the
4784 same time) */
4785 if (index >= n && no_oblock)
4786 break;
4787 if (tok == '}')
4788 break;
4789 skip(',');
4792 if (!no_oblock)
4793 skip('}');
4794 /* put zeros at the end */
4795 if (!size_only && n >= 0 && array_length < n) {
4796 init_putz(t1, sec, c + array_length * size1,
4797 (n - array_length) * size1);
4799 /* patch type size if needed */
4800 if (n < 0)
4801 s->c = array_length;
4802 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
4803 (sec || !first || tok == '{')) {
4804 int par_count;
4806 /* NOTE: the previous test is a specific case for automatic
4807 struct/union init */
4808 /* XXX: union needs only one init */
4810 /* XXX: this test is incorrect for local initializers
4811 beginning with ( without {. It would be much more difficult
4812 to do it correctly (ideally, the expression parser should
4813 be used in all cases) */
4814 par_count = 0;
4815 if (tok == '(') {
4816 AttributeDef ad1;
4817 CType type1;
4818 next();
4819 while (tok == '(') {
4820 par_count++;
4821 next();
4823 if (!parse_btype(&type1, &ad1))
4824 expect("cast");
4825 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4826 #if 0
4827 if (!is_assignable_types(type, &type1))
4828 error("invalid type for cast");
4829 #endif
4830 skip(')');
4832 no_oblock = 1;
4833 if (first || tok == '{') {
4834 skip('{');
4835 no_oblock = 0;
4837 s = type->ref;
4838 f = s->next;
4839 array_length = 0;
4840 index = 0;
4841 n = s->c;
4842 while (tok != '}') {
4843 decl_designator(type, sec, c, NULL, &f, size_only);
4844 index = f->c;
4845 if (!size_only && array_length < index) {
4846 init_putz(type, sec, c + array_length,
4847 index - array_length);
4849 index = index + type_size(&f->type, &align1);
4850 if (index > array_length)
4851 array_length = index;
4853 /* gr: skip fields from same union - ugly. */
4854 while (f->next) {
4855 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
4856 /* test for same offset */
4857 if (f->next->c != f->c)
4858 break;
4859 /* if yes, test for bitfield shift */
4860 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
4861 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4862 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4863 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
4864 if (bit_pos_1 != bit_pos_2)
4865 break;
4867 f = f->next;
4870 f = f->next;
4871 if (no_oblock && f == NULL)
4872 break;
4873 if (tok == '}')
4874 break;
4875 skip(',');
4877 /* put zeros at the end */
4878 if (!size_only && array_length < n) {
4879 init_putz(type, sec, c + array_length,
4880 n - array_length);
4882 if (!no_oblock)
4883 skip('}');
4884 while (par_count) {
4885 skip(')');
4886 par_count--;
4888 } else if (tok == '{') {
4889 next();
4890 decl_initializer(type, sec, c, first, size_only);
4891 skip('}');
4892 } else if (size_only) {
4893 /* just skip expression */
4894 parlevel = 0;
4895 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
4896 tok != -1) {
4897 if (tok == '(')
4898 parlevel++;
4899 else if (tok == ')')
4900 parlevel--;
4901 next();
4903 } else {
4904 /* currently, we always use constant expression for globals
4905 (may change for scripting case) */
4906 expr_type = EXPR_CONST;
4907 if (!sec)
4908 expr_type = EXPR_ANY;
4909 init_putv(type, sec, c, 0, expr_type);
4913 /* parse an initializer for type 't' if 'has_init' is non zero, and
4914 allocate space in local or global data space ('r' is either
4915 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
4916 variable 'v' of scope 'scope' is declared before initializers are
4917 parsed. If 'v' is zero, then a reference to the new object is put
4918 in the value stack. If 'has_init' is 2, a special parsing is done
4919 to handle string constants. */
4920 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
4921 int has_init, int v, int scope)
4923 int size, align, addr, data_offset;
4924 int level;
4925 ParseState saved_parse_state = {0};
4926 TokenString init_str;
4927 Section *sec;
4929 size = type_size(type, &align);
4930 /* If unknown size, we must evaluate it before
4931 evaluating initializers because
4932 initializers can generate global data too
4933 (e.g. string pointers or ISOC99 compound
4934 literals). It also simplifies local
4935 initializers handling */
4936 tok_str_new(&init_str);
4937 if (size < 0) {
4938 if (!has_init)
4939 error("unknown type size");
4940 /* get all init string */
4941 if (has_init == 2) {
4942 /* only get strings */
4943 while (tok == TOK_STR || tok == TOK_LSTR) {
4944 tok_str_add_tok(&init_str);
4945 next();
4947 } else {
4948 level = 0;
4949 while (level > 0 || (tok != ',' && tok != ';')) {
4950 if (tok < 0)
4951 error("unexpected end of file in initializer");
4952 tok_str_add_tok(&init_str);
4953 if (tok == '{')
4954 level++;
4955 else if (tok == '}') {
4956 level--;
4957 if (level <= 0) {
4958 next();
4959 break;
4962 next();
4965 tok_str_add(&init_str, -1);
4966 tok_str_add(&init_str, 0);
4968 /* compute size */
4969 save_parse_state(&saved_parse_state);
4971 macro_ptr = init_str.str;
4972 next();
4973 decl_initializer(type, NULL, 0, 1, 1);
4974 /* prepare second initializer parsing */
4975 macro_ptr = init_str.str;
4976 next();
4978 /* if still unknown size, error */
4979 size = type_size(type, &align);
4980 if (size < 0)
4981 error("unknown type size");
4983 /* take into account specified alignment if bigger */
4984 if (ad->aligned) {
4985 if (ad->aligned > align)
4986 align = ad->aligned;
4987 } else if (ad->packed) {
4988 align = 1;
4990 if ((r & VT_VALMASK) == VT_LOCAL) {
4991 sec = NULL;
4992 #ifdef CONFIG_TCC_BCHECK
4993 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
4994 loc--;
4995 #endif
4996 loc = (loc - size) & -align;
4997 addr = loc;
4998 #ifdef CONFIG_TCC_BCHECK
4999 /* handles bounds */
5000 /* XXX: currently, since we do only one pass, we cannot track
5001 '&' operators, so we add only arrays */
5002 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5003 unsigned long *bounds_ptr;
5004 /* add padding between regions */
5005 loc--;
5006 /* then add local bound info */
5007 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5008 bounds_ptr[0] = addr;
5009 bounds_ptr[1] = size;
5011 #endif
5012 if (v) {
5013 /* local variable */
5014 sym_push(v, type, r, addr);
5015 } else {
5016 /* push local reference */
5017 vset(type, r, addr);
5019 } else {
5020 Sym *sym;
5022 sym = NULL;
5023 if (v && scope == VT_CONST) {
5024 /* see if the symbol was already defined */
5025 sym = sym_find(v);
5026 if (sym) {
5027 if (!is_compatible_types(&sym->type, type))
5028 error("incompatible types for redefinition of '%s'",
5029 get_tok_str(v, NULL));
5030 if (sym->type.t & VT_EXTERN) {
5031 /* if the variable is extern, it was not allocated */
5032 sym->type.t &= ~VT_EXTERN;
5033 /* set array size if it was ommited in extern
5034 declaration */
5035 if ((sym->type.t & VT_ARRAY) &&
5036 sym->type.ref->c < 0 &&
5037 type->ref->c >= 0)
5038 sym->type.ref->c = type->ref->c;
5039 } else {
5040 /* we accept several definitions of the same
5041 global variable. this is tricky, because we
5042 must play with the SHN_COMMON type of the symbol */
5043 /* XXX: should check if the variable was already
5044 initialized. It is incorrect to initialized it
5045 twice */
5046 /* no init data, we won't add more to the symbol */
5047 if (!has_init)
5048 goto no_alloc;
5053 /* allocate symbol in corresponding section */
5054 sec = ad->section;
5055 if (!sec) {
5056 if (has_init)
5057 sec = data_section;
5058 else if (tcc_state->nocommon)
5059 sec = bss_section;
5061 if (sec) {
5062 data_offset = sec->data_offset;
5063 data_offset = (data_offset + align - 1) & -align;
5064 addr = data_offset;
5065 /* very important to increment global pointer at this time
5066 because initializers themselves can create new initializers */
5067 data_offset += size;
5068 #ifdef CONFIG_TCC_BCHECK
5069 /* add padding if bound check */
5070 if (tcc_state->do_bounds_check)
5071 data_offset++;
5072 #endif
5073 sec->data_offset = data_offset;
5074 /* allocate section space to put the data */
5075 if (sec->sh_type != SHT_NOBITS &&
5076 data_offset > sec->data_allocated)
5077 section_realloc(sec, data_offset);
5078 /* align section if needed */
5079 if (align > sec->sh_addralign)
5080 sec->sh_addralign = align;
5081 } else {
5082 addr = 0; /* avoid warning */
5085 if (v) {
5086 if (scope != VT_CONST || !sym) {
5087 sym = sym_push(v, type, r | VT_SYM, 0);
5089 /* update symbol definition */
5090 if (sec) {
5091 put_extern_sym(sym, sec, addr, size);
5092 } else {
5093 ElfW(Sym) *esym;
5094 /* put a common area */
5095 put_extern_sym(sym, NULL, align, size);
5096 /* XXX: find a nicer way */
5097 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5098 esym->st_shndx = SHN_COMMON;
5100 } else {
5101 CValue cval;
5103 /* push global reference */
5104 sym = get_sym_ref(type, sec, addr, size);
5105 cval.ul = 0;
5106 vsetc(type, VT_CONST | VT_SYM, &cval);
5107 vtop->sym = sym;
5109 #ifdef CONFIG_TCC_BCHECK
5110 /* handles bounds now because the symbol must be defined
5111 before for the relocation */
5112 if (tcc_state->do_bounds_check) {
5113 unsigned long *bounds_ptr;
5115 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5116 /* then add global bound info */
5117 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5118 bounds_ptr[0] = 0; /* relocated */
5119 bounds_ptr[1] = size;
5121 #endif
5123 if (has_init) {
5124 decl_initializer(type, sec, addr, 1, 0);
5125 /* restore parse state if needed */
5126 if (init_str.str) {
5127 tok_str_free(init_str.str);
5128 restore_parse_state(&saved_parse_state);
5131 no_alloc: ;
5134 static void put_func_debug(Sym *sym)
5136 char buf[512];
5138 /* stabs info */
5139 /* XXX: we put here a dummy type */
5140 snprintf(buf, sizeof(buf), "%s:%c1",
5141 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5142 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5143 cur_text_section, sym->c);
5144 /* //gr gdb wants a line at the function */
5145 put_stabn(N_SLINE, 0, file->line_num, 0);
5146 last_ind = 0;
5147 last_line_num = 0;
5150 /* parse an old style function declaration list */
5151 /* XXX: check multiple parameter */
5152 static void func_decl_list(Sym *func_sym)
5154 AttributeDef ad;
5155 int v;
5156 Sym *s;
5157 CType btype, type;
5159 /* parse each declaration */
5160 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
5161 if (!parse_btype(&btype, &ad))
5162 expect("declaration list");
5163 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5164 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5165 tok == ';') {
5166 /* we accept no variable after */
5167 } else {
5168 for(;;) {
5169 type = btype;
5170 type_decl(&type, &ad, &v, TYPE_DIRECT);
5171 /* find parameter in function parameter list */
5172 s = func_sym->next;
5173 while (s != NULL) {
5174 if ((s->v & ~SYM_FIELD) == v)
5175 goto found;
5176 s = s->next;
5178 error("declaration for parameter '%s' but no such parameter",
5179 get_tok_str(v, NULL));
5180 found:
5181 /* check that no storage specifier except 'register' was given */
5182 if (type.t & VT_STORAGE)
5183 error("storage class specified for '%s'", get_tok_str(v, NULL));
5184 convert_parameter_type(&type);
5185 /* we can add the type (NOTE: it could be local to the function) */
5186 s->type = type;
5187 /* accept other parameters */
5188 if (tok == ',')
5189 next();
5190 else
5191 break;
5194 skip(';');
5198 /* parse a function defined by symbol 'sym' and generate its code in
5199 'cur_text_section' */
5200 static void gen_function(Sym *sym)
5202 int saved_nocode_wanted = nocode_wanted;
5203 nocode_wanted = 0;
5204 ind = cur_text_section->data_offset;
5205 /* NOTE: we patch the symbol size later */
5206 put_extern_sym(sym, cur_text_section, ind, 0);
5207 funcname = get_tok_str(sym->v, NULL);
5208 func_ind = ind;
5209 /* put debug symbol */
5210 if (tcc_state->do_debug)
5211 put_func_debug(sym);
5212 /* push a dummy symbol to enable local sym storage */
5213 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5214 gfunc_prolog(&sym->type);
5215 rsym = 0;
5216 block(NULL, NULL, NULL, NULL, 0, 0);
5217 gsym(rsym);
5218 gfunc_epilog();
5219 cur_text_section->data_offset = ind;
5220 label_pop(&global_label_stack, NULL);
5221 sym_pop(&local_stack, NULL); /* reset local stack */
5222 /* end of function */
5223 /* patch symbol size */
5224 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5225 ind - func_ind;
5226 if (tcc_state->do_debug) {
5227 put_stabn(N_FUN, 0, 0, ind - func_ind);
5229 /* It's better to crash than to generate wrong code */
5230 cur_text_section = NULL;
5231 funcname = ""; /* for safety */
5232 func_vt.t = VT_VOID; /* for safety */
5233 ind = 0; /* for safety */
5234 nocode_wanted = saved_nocode_wanted;
5237 ST_FUNC void gen_inline_functions(void)
5239 Sym *sym;
5240 int *str, inline_generated, i;
5241 struct InlineFunc *fn;
5243 /* iterate while inline function are referenced */
5244 for(;;) {
5245 inline_generated = 0;
5246 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5247 fn = tcc_state->inline_fns[i];
5248 sym = fn->sym;
5249 if (sym && sym->c) {
5250 /* the function was used: generate its code and
5251 convert it to a normal function */
5252 str = fn->token_str;
5253 fn->sym = NULL;
5254 if (file)
5255 strcpy(file->filename, fn->filename);
5256 sym->r = VT_SYM | VT_CONST;
5257 sym->type.t &= ~VT_INLINE;
5259 macro_ptr = str;
5260 next();
5261 cur_text_section = text_section;
5262 gen_function(sym);
5263 macro_ptr = NULL; /* fail safe */
5265 inline_generated = 1;
5268 if (!inline_generated)
5269 break;
5271 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5272 fn = tcc_state->inline_fns[i];
5273 str = fn->token_str;
5274 tok_str_free(str);
5276 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5279 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5280 ST_FUNC void decl(int l)
5282 int v, has_init, r;
5283 CType type, btype;
5284 Sym *sym;
5285 AttributeDef ad;
5287 while (1) {
5288 if (!parse_btype(&btype, &ad)) {
5289 /* skip redundant ';' */
5290 /* XXX: find more elegant solution */
5291 if (tok == ';') {
5292 next();
5293 continue;
5295 if (l == VT_CONST &&
5296 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5297 /* global asm block */
5298 asm_global_instr();
5299 continue;
5301 /* special test for old K&R protos without explicit int
5302 type. Only accepted when defining global data */
5303 if (l == VT_LOCAL || tok < TOK_DEFINE)
5304 break;
5305 btype.t = VT_INT;
5307 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5308 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5309 tok == ';') {
5310 /* we accept no variable after */
5311 next();
5312 continue;
5314 while (1) { /* iterate thru each declaration */
5315 type = btype;
5316 type_decl(&type, &ad, &v, TYPE_DIRECT);
5317 #if 0
5319 char buf[500];
5320 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5321 printf("type = '%s'\n", buf);
5323 #endif
5324 if ((type.t & VT_BTYPE) == VT_FUNC) {
5325 /* if old style function prototype, we accept a
5326 declaration list */
5327 sym = type.ref;
5328 if (sym->c == FUNC_OLD)
5329 func_decl_list(sym);
5332 #ifdef TCC_TARGET_PE
5333 if (ad.func_import)
5334 type.t |= VT_IMPORT;
5335 if (ad.func_export)
5336 type.t |= VT_EXPORT;
5337 #endif
5338 if (tok == '{') {
5339 if (l == VT_LOCAL)
5340 error("cannot use local functions");
5341 if ((type.t & VT_BTYPE) != VT_FUNC)
5342 expect("function definition");
5344 /* reject abstract declarators in function definition */
5345 sym = type.ref;
5346 while ((sym = sym->next) != NULL)
5347 if (!(sym->v & ~SYM_FIELD))
5348 expect("identifier");
5350 /* XXX: cannot do better now: convert extern line to static inline */
5351 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5352 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5354 sym = sym_find(v);
5355 if (sym) {
5356 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5357 goto func_error1;
5359 r = sym->type.ref->r;
5360 /* use func_call from prototype if not defined */
5361 if (FUNC_CALL(r) != FUNC_CDECL
5362 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5363 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5365 /* use export from prototype */
5366 if (FUNC_EXPORT(r))
5367 FUNC_EXPORT(type.ref->r) = 1;
5369 /* use static from prototype */
5370 if (sym->type.t & VT_STATIC)
5371 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5373 if (!is_compatible_types(&sym->type, &type)) {
5374 func_error1:
5375 error("incompatible types for redefinition of '%s'",
5376 get_tok_str(v, NULL));
5378 /* if symbol is already defined, then put complete type */
5379 sym->type = type;
5380 } else {
5381 /* put function symbol */
5382 sym = global_identifier_push(v, type.t, 0);
5383 sym->type.ref = type.ref;
5386 /* static inline functions are just recorded as a kind
5387 of macro. Their code will be emitted at the end of
5388 the compilation unit only if they are used */
5389 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5390 (VT_INLINE | VT_STATIC)) {
5391 TokenString func_str;
5392 int block_level;
5393 struct InlineFunc *fn;
5394 const char *filename;
5396 tok_str_new(&func_str);
5398 block_level = 0;
5399 for(;;) {
5400 int t;
5401 if (tok == TOK_EOF)
5402 error("unexpected end of file");
5403 tok_str_add_tok(&func_str);
5404 t = tok;
5405 next();
5406 if (t == '{') {
5407 block_level++;
5408 } else if (t == '}') {
5409 block_level--;
5410 if (block_level == 0)
5411 break;
5414 tok_str_add(&func_str, -1);
5415 tok_str_add(&func_str, 0);
5416 filename = file ? file->filename : "";
5417 fn = tcc_malloc(sizeof *fn + strlen(filename));
5418 strcpy(fn->filename, filename);
5419 fn->sym = sym;
5420 fn->token_str = func_str.str;
5421 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5423 } else {
5424 /* compute text section */
5425 cur_text_section = ad.section;
5426 if (!cur_text_section)
5427 cur_text_section = text_section;
5428 sym->r = VT_SYM | VT_CONST;
5429 gen_function(sym);
5431 break;
5432 } else {
5433 if (btype.t & VT_TYPEDEF) {
5434 /* save typedefed type */
5435 /* XXX: test storage specifiers ? */
5436 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5437 sym->type.t |= VT_TYPEDEF;
5438 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
5439 Sym *fn;
5440 /* external function definition */
5441 /* specific case for func_call attribute */
5442 type.ref->r = INT_ATTR(&ad);
5443 fn = external_sym(v, &type, 0);
5445 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5446 char target[256];
5448 *target = 0;
5449 next();
5450 skip('(');
5451 /* Part 1: __USER_LABEL_PREFIX__ (user defined) */
5452 if (tok == TOK_STR)
5453 pstrcat(target, sizeof(target), tokc.cstr->data);
5454 else
5455 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5457 next();
5458 /* Part 2: api name */
5459 if (tok == TOK_STR)
5460 pstrcat(target, sizeof(target), tokc.cstr->data);
5461 else
5462 pstrcat(target, sizeof(target), get_tok_str(tok, NULL));
5464 next();
5465 skip(')');
5466 if (tcc_state->warn_unsupported)
5467 warning("ignoring redirection from %s to %s\n", get_tok_str(v, NULL), target);
5469 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
5470 parse_attribute((AttributeDef *) &fn->type.ref->r);
5472 } else {
5473 /* not lvalue if array */
5474 r = 0;
5475 if (!(type.t & VT_ARRAY))
5476 r |= lvalue_type(type.t);
5477 has_init = (tok == '=');
5478 if ((btype.t & VT_EXTERN) ||
5479 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5480 !has_init && l == VT_CONST && type.ref->c < 0)) {
5481 /* external variable */
5482 /* NOTE: as GCC, uninitialized global static
5483 arrays of null size are considered as
5484 extern */
5485 external_sym(v, &type, r);
5486 } else {
5487 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5488 if (type.t & VT_STATIC)
5489 r |= VT_CONST;
5490 else
5491 r |= l;
5492 if (has_init)
5493 next();
5494 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
5497 if (tok != ',') {
5498 skip(';');
5499 break;
5501 next();