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