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