Fix error logic for undefined reference in library
[tinycc.git] / tccgen.c
blobd06402450c27a09d12109f86c66c12d0883ef70d
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 Sym *sym_free_first;
34 ST_DATA void **sym_pools;
35 ST_DATA int nb_sym_pools;
37 ST_DATA Sym *global_stack;
38 ST_DATA Sym *local_stack;
39 ST_DATA Sym *define_stack;
40 ST_DATA Sym *global_label_stack;
41 ST_DATA Sym *local_label_stack;
42 static int local_scope;
43 static int in_sizeof;
44 static int section_sym;
46 ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
47 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
48 ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
50 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
52 ST_DATA int const_wanted; /* true if constant wanted */
53 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
54 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
55 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
56 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
57 ST_DATA int func_vc;
58 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
59 ST_DATA const char *funcname;
61 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
63 ST_DATA struct switch_t {
64 struct case_t {
65 int v1, v2, sym;
66 } **p; int n; /* list of case ranges */
67 int def_sym; /* default symbol */
68 } *cur_switch; /* current switch */
70 /* ------------------------------------------------------------------------- */
71 static void gen_cast(CType *type);
72 static inline CType *pointed_type(CType *type);
73 static int is_compatible_types(CType *type1, CType *type2);
74 static int parse_btype(CType *type, AttributeDef *ad);
75 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
76 static void parse_expr_type(CType *type);
77 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
78 static void block(int *bsym, int *csym, int is_expr);
79 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
80 static int decl0(int l, int is_for_loop_init);
81 static void expr_eq(void);
82 static void expr_lor_const(void);
83 static void unary_type(CType *type);
84 static void vla_runtime_type_size(CType *type, int *a);
85 static void vla_sp_restore(void);
86 static void vla_sp_restore_root(void);
87 static int is_compatible_parameter_types(CType *type1, CType *type2);
88 static void expr_type(CType *type);
89 ST_FUNC void vpush64(int ty, unsigned long long v);
90 ST_FUNC void vpush(CType *type);
91 ST_FUNC int gvtst(int inv, int t);
92 ST_FUNC int is_btype_size(int bt);
93 static void gen_inline_functions(TCCState *s);
95 ST_INLN int is_float(int t)
97 int bt;
98 bt = t & VT_BTYPE;
99 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
102 /* we use our own 'finite' function to avoid potential problems with
103 non standard math libs */
104 /* XXX: endianness dependent */
105 ST_FUNC int ieee_finite(double d)
107 int p[4];
108 memcpy(p, &d, sizeof(double));
109 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
112 ST_FUNC void test_lvalue(void)
114 if (!(vtop->r & VT_LVAL))
115 expect("lvalue");
118 ST_FUNC void check_vstack(void)
120 if (pvtop != vtop)
121 tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
124 /* ------------------------------------------------------------------------- */
125 /* vstack debugging aid */
127 #if 0
128 void pv (const char *lbl, int a, int b)
130 int i;
131 for (i = a; i < a + b; ++i) {
132 SValue *p = &vtop[-i];
133 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
134 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
137 #endif
139 /* ------------------------------------------------------------------------- */
140 ST_FUNC void tccgen_start(TCCState *s1)
142 cur_text_section = NULL;
143 funcname = "";
144 anon_sym = SYM_FIRST_ANOM;
145 section_sym = 0;
146 nocode_wanted = 1;
148 /* define some often used types */
149 int_type.t = VT_INT;
150 char_pointer_type.t = VT_BYTE;
151 mk_pointer(&char_pointer_type);
152 #if PTR_SIZE == 4
153 size_type.t = VT_INT;
154 #else
155 size_type.t = VT_LLONG;
156 #endif
157 func_old_type.t = VT_FUNC;
158 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
160 if (s1->do_debug) {
161 char buf[512];
163 /* file info: full path + filename */
164 section_sym = put_elf_sym(symtab_section, 0, 0,
165 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
166 text_section->sh_num, NULL);
167 getcwd(buf, sizeof(buf));
168 #ifdef _WIN32
169 normalize_slashes(buf);
170 #endif
171 pstrcat(buf, sizeof(buf), "/");
172 put_stabs_r(buf, N_SO, 0, 0,
173 text_section->data_offset, text_section, section_sym);
174 put_stabs_r(file->filename, N_SO, 0, 0,
175 text_section->data_offset, text_section, section_sym);
177 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
178 symbols can be safely used */
179 put_elf_sym(symtab_section, 0, 0,
180 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
181 SHN_ABS, file->filename);
183 #ifdef TCC_TARGET_ARM
184 arm_init(s1);
185 #endif
188 ST_FUNC void tccgen_end(TCCState *s1)
190 gen_inline_functions(s1);
191 check_vstack();
192 /* end of translation unit info */
193 if (s1->do_debug) {
194 put_stabs_r(NULL, N_SO, 0, 0,
195 text_section->data_offset, text_section, section_sym);
199 /* ------------------------------------------------------------------------- */
200 /* update sym->c so that it points to an external symbol in section
201 'section' with value 'value' */
203 ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
204 addr_t value, unsigned long size,
205 int can_add_underscore)
207 int sym_type, sym_bind, sh_num, info, other;
208 ElfW(Sym) *esym;
209 const char *name;
210 char buf1[256];
212 #ifdef CONFIG_TCC_BCHECK
213 char buf[32];
214 #endif
216 if (section == NULL)
217 sh_num = SHN_UNDEF;
218 else if (section == SECTION_ABS)
219 sh_num = SHN_ABS;
220 else
221 sh_num = section->sh_num;
223 if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
224 sym_type = STT_FUNC;
225 } else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
226 sym_type = STT_NOTYPE;
227 } else {
228 sym_type = STT_OBJECT;
231 if (sym->type.t & VT_STATIC)
232 sym_bind = STB_LOCAL;
233 else {
234 if (sym->type.t & VT_WEAK)
235 sym_bind = STB_WEAK;
236 else
237 sym_bind = STB_GLOBAL;
240 if (!sym->c) {
241 name = get_tok_str(sym->v, NULL);
242 #ifdef CONFIG_TCC_BCHECK
243 if (tcc_state->do_bounds_check) {
244 /* XXX: avoid doing that for statics ? */
245 /* if bound checking is activated, we change some function
246 names by adding the "__bound" prefix */
247 switch(sym->v) {
248 #ifdef TCC_TARGET_PE
249 /* XXX: we rely only on malloc hooks */
250 case TOK_malloc:
251 case TOK_free:
252 case TOK_realloc:
253 case TOK_memalign:
254 case TOK_calloc:
255 #endif
256 case TOK_memcpy:
257 case TOK_memmove:
258 case TOK_memset:
259 case TOK_strlen:
260 case TOK_strcpy:
261 case TOK_alloca:
262 strcpy(buf, "__bound_");
263 strcat(buf, name);
264 name = buf;
265 break;
268 #endif
269 other = 0;
271 #ifdef TCC_TARGET_PE
272 if (sym->type.t & VT_EXPORT)
273 other |= ST_PE_EXPORT;
274 if (sym_type == STT_FUNC && sym->type.ref) {
275 Sym *ref = sym->type.ref;
276 if (ref->a.func_export)
277 other |= ST_PE_EXPORT;
278 if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) {
279 sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE);
280 name = buf1;
281 other |= ST_PE_STDCALL;
282 can_add_underscore = 0;
284 } else {
285 if (find_elf_sym(tcc_state->dynsymtab_section, name))
286 other |= ST_PE_IMPORT;
287 if (sym->type.t & VT_IMPORT)
288 other |= ST_PE_IMPORT;
290 #else
291 if (! (sym->type.t & VT_STATIC))
292 other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT;
293 #endif
294 if (tcc_state->leading_underscore && can_add_underscore) {
295 buf1[0] = '_';
296 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
297 name = buf1;
299 if (sym->asm_label) {
300 name = get_tok_str(sym->asm_label, NULL);
302 info = ELFW(ST_INFO)(sym_bind, sym_type);
303 sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
304 } else {
305 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
306 esym->st_value = value;
307 esym->st_size = size;
308 esym->st_shndx = sh_num;
312 ST_FUNC void put_extern_sym(Sym *sym, Section *section,
313 addr_t value, unsigned long size)
315 put_extern_sym2(sym, section, value, size, 1);
318 /* add a new relocation entry to symbol 'sym' in section 's' */
319 ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
320 addr_t addend)
322 int c = 0;
323 if (sym) {
324 if (0 == sym->c)
325 put_extern_sym(sym, NULL, 0, 0);
326 c = sym->c;
328 /* now we can add ELF relocation info */
329 put_elf_reloca(symtab_section, s, offset, type, c, addend);
332 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
334 greloca(s, sym, offset, type, 0);
337 /* ------------------------------------------------------------------------- */
338 /* symbol allocator */
339 static Sym *__sym_malloc(void)
341 Sym *sym_pool, *sym, *last_sym;
342 int i;
344 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
345 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
347 last_sym = sym_free_first;
348 sym = sym_pool;
349 for(i = 0; i < SYM_POOL_NB; i++) {
350 sym->next = last_sym;
351 last_sym = sym;
352 sym++;
354 sym_free_first = last_sym;
355 return last_sym;
358 static inline Sym *sym_malloc(void)
360 Sym *sym;
361 sym = sym_free_first;
362 if (!sym)
363 sym = __sym_malloc();
364 sym_free_first = sym->next;
365 return sym;
368 ST_INLN void sym_free(Sym *sym)
370 sym->next = sym_free_first;
371 sym_free_first = sym;
374 /* push, without hashing */
375 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
377 Sym *s;
379 s = sym_malloc();
380 s->asm_label = 0;
381 s->v = v;
382 s->type.t = t;
383 s->type.ref = NULL;
384 #ifdef _WIN64
385 s->d = NULL;
386 #endif
387 s->c = c;
388 s->next = NULL;
389 /* add in stack */
390 s->prev = *ps;
391 *ps = s;
392 return s;
395 /* find a symbol and return its associated structure. 's' is the top
396 of the symbol stack */
397 ST_FUNC Sym *sym_find2(Sym *s, int v)
399 while (s) {
400 if (s->v == v)
401 return s;
402 else if (s->v == -1)
403 return NULL;
404 s = s->prev;
406 return NULL;
409 /* structure lookup */
410 ST_INLN Sym *struct_find(int v)
412 v -= TOK_IDENT;
413 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
414 return NULL;
415 return table_ident[v]->sym_struct;
418 /* find an identifier */
419 ST_INLN Sym *sym_find(int v)
421 v -= TOK_IDENT;
422 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
423 return NULL;
424 return table_ident[v]->sym_identifier;
427 /* push a given symbol on the symbol stack */
428 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
430 Sym *s, **ps;
431 TokenSym *ts;
433 if (local_stack)
434 ps = &local_stack;
435 else
436 ps = &global_stack;
437 s = sym_push2(ps, v, type->t, c);
438 s->type.ref = type->ref;
439 s->r = r;
440 /* don't record fields or anonymous symbols */
441 /* XXX: simplify */
442 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
443 /* record symbol in token array */
444 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
445 if (v & SYM_STRUCT)
446 ps = &ts->sym_struct;
447 else
448 ps = &ts->sym_identifier;
449 s->prev_tok = *ps;
450 *ps = s;
451 s->scope = local_scope;
452 if (s->prev_tok && s->prev_tok->scope == s->scope)
453 tcc_error("redeclaration of '%s'",
454 get_tok_str(v & ~SYM_STRUCT, NULL));
456 return s;
459 /* push a global identifier */
460 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
462 Sym *s, **ps;
463 s = sym_push2(&global_stack, v, t, c);
464 /* don't record anonymous symbol */
465 if (v < SYM_FIRST_ANOM) {
466 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
467 /* modify the top most local identifier, so that
468 sym_identifier will point to 's' when popped */
469 while (*ps != NULL)
470 ps = &(*ps)->prev_tok;
471 s->prev_tok = NULL;
472 *ps = s;
474 return s;
477 /* pop symbols until top reaches 'b' */
478 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
480 Sym *s, *ss, **ps;
481 TokenSym *ts;
482 int v;
484 s = *ptop;
485 while(s != b) {
486 ss = s->prev;
487 v = s->v;
488 /* remove symbol in token array */
489 /* XXX: simplify */
490 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
491 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
492 if (v & SYM_STRUCT)
493 ps = &ts->sym_struct;
494 else
495 ps = &ts->sym_identifier;
496 *ps = s->prev_tok;
498 sym_free(s);
499 s = ss;
501 *ptop = b;
504 static void weaken_symbol(Sym *sym)
506 sym->type.t |= VT_WEAK;
507 if (sym->c > 0) {
508 int esym_type;
509 ElfW(Sym) *esym;
511 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
512 esym_type = ELFW(ST_TYPE)(esym->st_info);
513 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
517 static void apply_visibility(Sym *sym, CType *type)
519 int vis = sym->type.t & VT_VIS_MASK;
520 int vis2 = type->t & VT_VIS_MASK;
521 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
522 vis = vis2;
523 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
525 else
526 vis = (vis < vis2) ? vis : vis2;
527 sym->type.t &= ~VT_VIS_MASK;
528 sym->type.t |= vis;
530 if (sym->c > 0) {
531 ElfW(Sym) *esym;
533 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
534 vis >>= VT_VIS_SHIFT;
535 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
539 /* ------------------------------------------------------------------------- */
541 ST_FUNC void swap(int *p, int *q)
543 int t;
544 t = *p;
545 *p = *q;
546 *q = t;
549 static void vsetc(CType *type, int r, CValue *vc)
551 int v;
553 if (vtop >= vstack + (VSTACK_SIZE - 1))
554 tcc_error("memory full (vstack)");
555 /* cannot let cpu flags if other instruction are generated. Also
556 avoid leaving VT_JMP anywhere except on the top of the stack
557 because it would complicate the code generator. */
558 if (vtop >= vstack) {
559 v = vtop->r & VT_VALMASK;
560 if (v == VT_CMP || (v & ~1) == VT_JMP)
561 gv(RC_INT);
563 vtop++;
564 vtop->type = *type;
565 vtop->r = r;
566 vtop->r2 = VT_CONST;
567 vtop->c = *vc;
570 /* push constant of type "type" with useless value */
571 ST_FUNC void vpush(CType *type)
573 CValue cval;
574 vsetc(type, VT_CONST, &cval);
577 /* push integer constant */
578 ST_FUNC void vpushi(int v)
580 CValue cval;
581 cval.i = v;
582 vsetc(&int_type, VT_CONST, &cval);
585 /* push a pointer sized constant */
586 static void vpushs(addr_t v)
588 CValue cval;
589 cval.i = v;
590 vsetc(&size_type, VT_CONST, &cval);
593 /* push arbitrary 64bit constant */
594 ST_FUNC void vpush64(int ty, unsigned long long v)
596 CValue cval;
597 CType ctype;
598 ctype.t = ty;
599 ctype.ref = NULL;
600 cval.i = v;
601 vsetc(&ctype, VT_CONST, &cval);
604 /* push long long constant */
605 static inline void vpushll(long long v)
607 vpush64(VT_LLONG, v);
610 /* push a symbol value of TYPE */
611 static inline void vpushsym(CType *type, Sym *sym)
613 CValue cval;
614 cval.i = 0;
615 vsetc(type, VT_CONST | VT_SYM, &cval);
616 vtop->sym = sym;
619 /* Return a static symbol pointing to a section */
620 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
622 int v;
623 Sym *sym;
625 v = anon_sym++;
626 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
627 sym->type.ref = type->ref;
628 sym->r = VT_CONST | VT_SYM;
629 put_extern_sym(sym, sec, offset, size);
630 return sym;
633 /* push a reference to a section offset by adding a dummy symbol */
634 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
636 vpushsym(type, get_sym_ref(type, sec, offset, size));
639 /* define a new external reference to a symbol 'v' of type 'u' */
640 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
642 Sym *s;
644 s = sym_find(v);
645 if (!s) {
646 /* push forward reference */
647 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
648 s->type.ref = type->ref;
649 s->r = r | VT_CONST | VT_SYM;
651 return s;
654 /* define a new external reference to a symbol 'v' */
655 static Sym *external_sym(int v, CType *type, int r)
657 Sym *s;
659 s = sym_find(v);
660 if (!s) {
661 /* push forward reference */
662 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
663 s->type.t |= VT_EXTERN;
664 } else if (s->type.ref == func_old_type.ref) {
665 s->type.ref = type->ref;
666 s->r = r | VT_CONST | VT_SYM;
667 s->type.t |= VT_EXTERN;
668 } else if (!is_compatible_types(&s->type, type)) {
669 tcc_error("incompatible types for redefinition of '%s'",
670 get_tok_str(v, NULL));
672 /* Merge some storage attributes. */
673 if (type->t & VT_WEAK)
674 weaken_symbol(s);
676 if (type->t & VT_VIS_MASK)
677 apply_visibility(s, type);
679 return s;
682 /* push a reference to global symbol v */
683 ST_FUNC void vpush_global_sym(CType *type, int v)
685 vpushsym(type, external_global_sym(v, type, 0));
688 ST_FUNC void vset(CType *type, int r, int v)
690 CValue cval;
692 cval.i = v;
693 vsetc(type, r, &cval);
696 static void vseti(int r, int v)
698 CType type;
699 type.t = VT_INT;
700 type.ref = 0;
701 vset(&type, r, v);
704 ST_FUNC void vswap(void)
706 SValue tmp;
707 /* cannot let cpu flags if other instruction are generated. Also
708 avoid leaving VT_JMP anywhere except on the top of the stack
709 because it would complicate the code generator. */
710 if (vtop >= vstack) {
711 int v = vtop->r & VT_VALMASK;
712 if (v == VT_CMP || (v & ~1) == VT_JMP)
713 gv(RC_INT);
715 tmp = vtop[0];
716 vtop[0] = vtop[-1];
717 vtop[-1] = tmp;
719 /* XXX: +2% overall speed possible with optimized memswap
721 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
725 ST_FUNC void vpushv(SValue *v)
727 if (vtop >= vstack + (VSTACK_SIZE - 1))
728 tcc_error("memory full (vstack)");
729 vtop++;
730 *vtop = *v;
733 static void vdup(void)
735 vpushv(vtop);
738 /* save registers up to (vtop - n) stack entry */
739 ST_FUNC void save_regs(int n)
741 SValue *p, *p1;
742 for(p = vstack, p1 = vtop - n; p <= p1; p++)
743 save_reg(p->r);
746 /* save r to the memory stack, and mark it as being free */
747 ST_FUNC void save_reg(int r)
749 save_reg_upstack(r, 0);
752 /* save r to the memory stack, and mark it as being free,
753 if seen up to (vtop - n) stack entry */
754 ST_FUNC void save_reg_upstack(int r, int n)
756 int l, saved, size, align;
757 SValue *p, *p1, sv;
758 CType *type;
760 if ((r &= VT_VALMASK) >= VT_CONST)
761 return;
763 /* modify all stack values */
764 saved = 0;
765 l = 0;
766 for(p = vstack, p1 = vtop - n; p <= p1; p++) {
767 if ((p->r & VT_VALMASK) == r ||
768 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
769 /* must save value on stack if not already done */
770 if (!saved) {
771 /* NOTE: must reload 'r' because r might be equal to r2 */
772 r = p->r & VT_VALMASK;
773 /* store register in the stack */
774 type = &p->type;
775 if ((p->r & VT_LVAL) ||
776 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
777 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
778 type = &char_pointer_type;
779 #else
780 type = &int_type;
781 #endif
782 size = type_size(type, &align);
783 loc = (loc - size) & -align;
784 sv.type.t = type->t;
785 sv.r = VT_LOCAL | VT_LVAL;
786 sv.c.i = loc;
787 store(r, &sv);
788 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
789 /* x86 specific: need to pop fp register ST0 if saved */
790 if (r == TREG_ST0) {
791 o(0xd8dd); /* fstp %st(0) */
793 #endif
794 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
795 /* special long long case */
796 if ((type->t & VT_BTYPE) == VT_LLONG) {
797 sv.c.i += 4;
798 store(p->r2, &sv);
800 #endif
801 l = loc;
802 saved = 1;
804 /* mark that stack entry as being saved on the stack */
805 if (p->r & VT_LVAL) {
806 /* also clear the bounded flag because the
807 relocation address of the function was stored in
808 p->c.i */
809 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
810 } else {
811 p->r = lvalue_type(p->type.t) | VT_LOCAL;
813 p->r2 = VT_CONST;
814 p->c.i = l;
819 #ifdef TCC_TARGET_ARM
820 /* find a register of class 'rc2' with at most one reference on stack.
821 * If none, call get_reg(rc) */
822 ST_FUNC int get_reg_ex(int rc, int rc2)
824 int r;
825 SValue *p;
827 for(r=0;r<NB_REGS;r++) {
828 if (reg_classes[r] & rc2) {
829 int n;
830 n=0;
831 for(p = vstack; p <= vtop; p++) {
832 if ((p->r & VT_VALMASK) == r ||
833 (p->r2 & VT_VALMASK) == r)
834 n++;
836 if (n <= 1)
837 return r;
840 return get_reg(rc);
842 #endif
844 /* find a free register of class 'rc'. If none, save one register */
845 ST_FUNC int get_reg(int rc)
847 int r;
848 SValue *p;
850 /* find a free register */
851 for(r=0;r<NB_REGS;r++) {
852 if (reg_classes[r] & rc) {
853 for(p=vstack;p<=vtop;p++) {
854 if ((p->r & VT_VALMASK) == r ||
855 (p->r2 & VT_VALMASK) == r)
856 goto notfound;
858 return r;
860 notfound: ;
863 /* no register left : free the first one on the stack (VERY
864 IMPORTANT to start from the bottom to ensure that we don't
865 spill registers used in gen_opi()) */
866 for(p=vstack;p<=vtop;p++) {
867 /* look at second register (if long long) */
868 r = p->r2 & VT_VALMASK;
869 if (r < VT_CONST && (reg_classes[r] & rc))
870 goto save_found;
871 r = p->r & VT_VALMASK;
872 if (r < VT_CONST && (reg_classes[r] & rc)) {
873 save_found:
874 save_reg(r);
875 return r;
878 /* Should never comes here */
879 return -1;
882 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
883 if needed */
884 static void move_reg(int r, int s, int t)
886 SValue sv;
888 if (r != s) {
889 save_reg(r);
890 sv.type.t = t;
891 sv.type.ref = NULL;
892 sv.r = s;
893 sv.c.i = 0;
894 load(r, &sv);
898 /* get address of vtop (vtop MUST BE an lvalue) */
899 ST_FUNC void gaddrof(void)
901 if (vtop->r & VT_REF && !nocode_wanted)
902 gv(RC_INT);
903 vtop->r &= ~VT_LVAL;
904 /* tricky: if saved lvalue, then we can go back to lvalue */
905 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
906 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
911 #ifdef CONFIG_TCC_BCHECK
912 /* generate lvalue bound code */
913 static void gbound(void)
915 int lval_type;
916 CType type1;
918 vtop->r &= ~VT_MUSTBOUND;
919 /* if lvalue, then use checking code before dereferencing */
920 if (vtop->r & VT_LVAL) {
921 /* if not VT_BOUNDED value, then make one */
922 if (!(vtop->r & VT_BOUNDED)) {
923 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
924 /* must save type because we must set it to int to get pointer */
925 type1 = vtop->type;
926 vtop->type.t = VT_PTR;
927 gaddrof();
928 vpushi(0);
929 gen_bounded_ptr_add();
930 vtop->r |= lval_type;
931 vtop->type = type1;
933 /* then check for dereferencing */
934 gen_bounded_ptr_deref();
937 #endif
939 /* store vtop a register belonging to class 'rc'. lvalues are
940 converted to values. Cannot be used if cannot be converted to
941 register value (such as structures). */
942 ST_FUNC int gv(int rc)
944 int r, bit_pos, bit_size, size, align, i;
945 int rc2;
947 /* NOTE: get_reg can modify vstack[] */
948 if (vtop->type.t & VT_BITFIELD) {
949 CType type;
950 int bits = 32;
951 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
952 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
953 /* remove bit field info to avoid loops */
954 vtop->type.t &= ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
955 /* cast to int to propagate signedness in following ops */
956 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
957 type.t = VT_LLONG;
958 bits = 64;
959 } else
960 type.t = VT_INT;
961 if((vtop->type.t & VT_UNSIGNED) ||
962 (vtop->type.t & VT_BTYPE) == VT_BOOL)
963 type.t |= VT_UNSIGNED;
964 gen_cast(&type);
965 /* generate shifts */
966 vpushi(bits - (bit_pos + bit_size));
967 gen_op(TOK_SHL);
968 vpushi(bits - bit_size);
969 /* NOTE: transformed to SHR if unsigned */
970 gen_op(TOK_SAR);
971 r = gv(rc);
972 } else {
973 if (is_float(vtop->type.t) &&
974 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
975 Sym *sym;
976 int *ptr;
977 unsigned long offset;
978 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
979 CValue check;
980 #endif
982 /* XXX: unify with initializers handling ? */
983 /* CPUs usually cannot use float constants, so we store them
984 generically in data segment */
985 size = type_size(&vtop->type, &align);
986 offset = (data_section->data_offset + align - 1) & -align;
987 data_section->data_offset = offset;
988 /* XXX: not portable yet */
989 #if defined(__i386__) || defined(__x86_64__)
990 /* Zero pad x87 tenbyte long doubles */
991 if (size == LDOUBLE_SIZE) {
992 vtop->c.tab[2] &= 0xffff;
993 #if LDOUBLE_SIZE == 16
994 vtop->c.tab[3] = 0;
995 #endif
997 #endif
998 ptr = section_ptr_add(data_section, size);
999 size = size >> 2;
1000 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
1001 check.d = 1;
1002 if(check.tab[0])
1003 for(i=0;i<size;i++)
1004 ptr[i] = vtop->c.tab[size-1-i];
1005 else
1006 #endif
1007 for(i=0;i<size;i++)
1008 ptr[i] = vtop->c.tab[i];
1009 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
1010 vtop->r |= VT_LVAL | VT_SYM;
1011 vtop->sym = sym;
1012 vtop->c.i = 0;
1014 #ifdef CONFIG_TCC_BCHECK
1015 if (vtop->r & VT_MUSTBOUND)
1016 gbound();
1017 #endif
1019 r = vtop->r & VT_VALMASK;
1020 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
1021 #ifndef TCC_TARGET_ARM64
1022 if (rc == RC_IRET)
1023 rc2 = RC_LRET;
1024 #ifdef TCC_TARGET_X86_64
1025 else if (rc == RC_FRET)
1026 rc2 = RC_QRET;
1027 #endif
1028 #endif
1030 /* need to reload if:
1031 - constant
1032 - lvalue (need to dereference pointer)
1033 - already a register, but not in the right class */
1034 if (r >= VT_CONST
1035 || (vtop->r & VT_LVAL)
1036 || !(reg_classes[r] & rc)
1037 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1038 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
1039 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
1040 #else
1041 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
1042 #endif
1045 r = get_reg(rc);
1046 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1047 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
1048 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
1049 #else
1050 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
1051 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
1052 unsigned long long ll;
1053 #endif
1054 int r2, original_type;
1055 original_type = vtop->type.t;
1056 /* two register type load : expand to two words
1057 temporarily */
1058 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1059 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1060 /* load constant */
1061 ll = vtop->c.i;
1062 vtop->c.i = ll; /* first word */
1063 load(r, vtop);
1064 vtop->r = r; /* save register value */
1065 vpushi(ll >> 32); /* second word */
1066 } else
1067 #endif
1068 if (vtop->r & VT_LVAL) {
1069 /* We do not want to modifier the long long
1070 pointer here, so the safest (and less
1071 efficient) is to save all the other registers
1072 in the stack. XXX: totally inefficient. */
1073 #if 0
1074 save_regs(1);
1075 #else
1076 /* lvalue_save: save only if used further down the stack */
1077 save_reg_upstack(vtop->r, 1);
1078 #endif
1079 /* load from memory */
1080 vtop->type.t = load_type;
1081 load(r, vtop);
1082 vdup();
1083 vtop[-1].r = r; /* save register value */
1084 /* increment pointer to get second word */
1085 vtop->type.t = addr_type;
1086 gaddrof();
1087 vpushi(load_size);
1088 gen_op('+');
1089 vtop->r |= VT_LVAL;
1090 vtop->type.t = load_type;
1091 } else {
1092 /* move registers */
1093 load(r, vtop);
1094 vdup();
1095 vtop[-1].r = r; /* save register value */
1096 vtop->r = vtop[-1].r2;
1098 /* Allocate second register. Here we rely on the fact that
1099 get_reg() tries first to free r2 of an SValue. */
1100 r2 = get_reg(rc2);
1101 load(r2, vtop);
1102 vpop();
1103 /* write second register */
1104 vtop->r2 = r2;
1105 vtop->type.t = original_type;
1106 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
1107 int t1, t;
1108 /* lvalue of scalar type : need to use lvalue type
1109 because of possible cast */
1110 t = vtop->type.t;
1111 t1 = t;
1112 /* compute memory access type */
1113 if (vtop->r & VT_REF)
1114 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1115 t = VT_PTR;
1116 #else
1117 t = VT_INT;
1118 #endif
1119 else if (vtop->r & VT_LVAL_BYTE)
1120 t = VT_BYTE;
1121 else if (vtop->r & VT_LVAL_SHORT)
1122 t = VT_SHORT;
1123 if (vtop->r & VT_LVAL_UNSIGNED)
1124 t |= VT_UNSIGNED;
1125 vtop->type.t = t;
1126 load(r, vtop);
1127 /* restore wanted type */
1128 vtop->type.t = t1;
1129 } else {
1130 /* one register type load */
1131 load(r, vtop);
1134 vtop->r = r;
1135 #ifdef TCC_TARGET_C67
1136 /* uses register pairs for doubles */
1137 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
1138 vtop->r2 = r+1;
1139 #endif
1141 return r;
1144 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
1145 ST_FUNC void gv2(int rc1, int rc2)
1147 int v;
1149 /* generate more generic register first. But VT_JMP or VT_CMP
1150 values must be generated first in all cases to avoid possible
1151 reload errors */
1152 v = vtop[0].r & VT_VALMASK;
1153 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
1154 vswap();
1155 gv(rc1);
1156 vswap();
1157 gv(rc2);
1158 /* test if reload is needed for first register */
1159 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1160 vswap();
1161 gv(rc1);
1162 vswap();
1164 } else {
1165 gv(rc2);
1166 vswap();
1167 gv(rc1);
1168 vswap();
1169 /* test if reload is needed for first register */
1170 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
1171 gv(rc2);
1176 #ifndef TCC_TARGET_ARM64
1177 /* wrapper around RC_FRET to return a register by type */
1178 static int rc_fret(int t)
1180 #ifdef TCC_TARGET_X86_64
1181 if (t == VT_LDOUBLE) {
1182 return RC_ST0;
1184 #endif
1185 return RC_FRET;
1187 #endif
1189 /* wrapper around REG_FRET to return a register by type */
1190 static int reg_fret(int t)
1192 #ifdef TCC_TARGET_X86_64
1193 if (t == VT_LDOUBLE) {
1194 return TREG_ST0;
1196 #endif
1197 return REG_FRET;
1200 /* expand 64bit on stack in two ints */
1201 static void lexpand(void)
1203 int u, v;
1204 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1205 v = vtop->r & (VT_VALMASK | VT_LVAL);
1206 if (v == VT_CONST) {
1207 vdup();
1208 vtop[0].c.i >>= 32;
1209 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1210 vdup();
1211 vtop[0].c.i += 4;
1212 } else {
1213 gv(RC_INT);
1214 vdup();
1215 vtop[0].r = vtop[-1].r2;
1216 vtop[0].r2 = vtop[-1].r2 = VT_CONST;
1218 vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
1221 #ifdef TCC_TARGET_ARM
1222 /* expand long long on stack */
1223 ST_FUNC void lexpand_nr(void)
1225 int u,v;
1227 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1228 vdup();
1229 vtop->r2 = VT_CONST;
1230 vtop->type.t = VT_INT | u;
1231 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1232 if (v == VT_CONST) {
1233 vtop[-1].c.i = vtop->c.i;
1234 vtop->c.i = vtop->c.i >> 32;
1235 vtop->r = VT_CONST;
1236 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1237 vtop->c.i += 4;
1238 vtop->r = vtop[-1].r;
1239 } else if (v > VT_CONST) {
1240 vtop--;
1241 lexpand();
1242 } else
1243 vtop->r = vtop[-1].r2;
1244 vtop[-1].r2 = VT_CONST;
1245 vtop[-1].type.t = VT_INT | u;
1247 #endif
1249 #if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
1250 /* build a long long from two ints */
1251 static void lbuild(int t)
1253 gv2(RC_INT, RC_INT);
1254 vtop[-1].r2 = vtop[0].r;
1255 vtop[-1].type.t = t;
1256 vpop();
1258 #endif
1260 /* rotate n first stack elements to the bottom
1261 I1 ... In -> I2 ... In I1 [top is right]
1263 ST_FUNC void vrotb(int n)
1265 int i;
1266 SValue tmp;
1268 tmp = vtop[-n + 1];
1269 for(i=-n+1;i!=0;i++)
1270 vtop[i] = vtop[i+1];
1271 vtop[0] = tmp;
1274 /* rotate the n elements before entry e towards the top
1275 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1277 ST_FUNC void vrote(SValue *e, int n)
1279 int i;
1280 SValue tmp;
1282 tmp = *e;
1283 for(i = 0;i < n - 1; i++)
1284 e[-i] = e[-i - 1];
1285 e[-n + 1] = tmp;
1288 /* rotate n first stack elements to the top
1289 I1 ... In -> In I1 ... I(n-1) [top is right]
1291 ST_FUNC void vrott(int n)
1293 vrote(vtop, n);
1296 /* pop stack value */
1297 ST_FUNC void vpop(void)
1299 int v;
1300 v = vtop->r & VT_VALMASK;
1301 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1302 /* for x86, we need to pop the FP stack */
1303 if (v == TREG_ST0 && !nocode_wanted) {
1304 o(0xd8dd); /* fstp %st(0) */
1305 } else
1306 #endif
1307 if (v == VT_JMP || v == VT_JMPI) {
1308 /* need to put correct jump if && or || without test */
1309 gsym(vtop->c.i);
1311 vtop--;
1314 /* convert stack entry to register and duplicate its value in another
1315 register */
1316 static void gv_dup(void)
1318 int rc, t, r, r1;
1319 SValue sv;
1321 t = vtop->type.t;
1322 #if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
1323 if ((t & VT_BTYPE) == VT_LLONG) {
1324 lexpand();
1325 gv_dup();
1326 vswap();
1327 vrotb(3);
1328 gv_dup();
1329 vrotb(4);
1330 /* stack: H L L1 H1 */
1331 lbuild(t);
1332 vrotb(3);
1333 vrotb(3);
1334 vswap();
1335 lbuild(t);
1336 vswap();
1337 } else
1338 #endif
1340 /* duplicate value */
1341 rc = RC_INT;
1342 sv.type.t = VT_INT;
1343 if (is_float(t)) {
1344 rc = RC_FLOAT;
1345 #ifdef TCC_TARGET_X86_64
1346 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1347 rc = RC_ST0;
1349 #endif
1350 sv.type.t = t;
1352 r = gv(rc);
1353 r1 = get_reg(rc);
1354 sv.r = r;
1355 sv.c.i = 0;
1356 load(r1, &sv); /* move r to r1 */
1357 vdup();
1358 /* duplicates value */
1359 if (r != r1)
1360 vtop->r = r1;
1364 /* Generate value test
1366 * Generate a test for any value (jump, comparison and integers) */
1367 ST_FUNC int gvtst(int inv, int t)
1369 int v = vtop->r & VT_VALMASK;
1370 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1371 vpushi(0);
1372 gen_op(TOK_NE);
1374 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1375 /* constant jmp optimization */
1376 if ((vtop->c.i != 0) != inv)
1377 t = gjmp(t);
1378 vtop--;
1379 return t;
1381 return gtst(inv, t);
1384 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1385 /* generate CPU independent (unsigned) long long operations */
1386 static void gen_opl(int op)
1388 int t, a, b, op1, c, i;
1389 int func;
1390 unsigned short reg_iret = REG_IRET;
1391 unsigned short reg_lret = REG_LRET;
1392 SValue tmp;
1394 switch(op) {
1395 case '/':
1396 case TOK_PDIV:
1397 func = TOK___divdi3;
1398 goto gen_func;
1399 case TOK_UDIV:
1400 func = TOK___udivdi3;
1401 goto gen_func;
1402 case '%':
1403 func = TOK___moddi3;
1404 goto gen_mod_func;
1405 case TOK_UMOD:
1406 func = TOK___umoddi3;
1407 gen_mod_func:
1408 #ifdef TCC_ARM_EABI
1409 reg_iret = TREG_R2;
1410 reg_lret = TREG_R3;
1411 #endif
1412 gen_func:
1413 /* call generic long long function */
1414 vpush_global_sym(&func_old_type, func);
1415 vrott(3);
1416 gfunc_call(2);
1417 vpushi(0);
1418 vtop->r = reg_iret;
1419 vtop->r2 = reg_lret;
1420 break;
1421 case '^':
1422 case '&':
1423 case '|':
1424 case '*':
1425 case '+':
1426 case '-':
1427 //pv("gen_opl A",0,2);
1428 t = vtop->type.t;
1429 vswap();
1430 lexpand();
1431 vrotb(3);
1432 lexpand();
1433 /* stack: L1 H1 L2 H2 */
1434 tmp = vtop[0];
1435 vtop[0] = vtop[-3];
1436 vtop[-3] = tmp;
1437 tmp = vtop[-2];
1438 vtop[-2] = vtop[-3];
1439 vtop[-3] = tmp;
1440 vswap();
1441 /* stack: H1 H2 L1 L2 */
1442 //pv("gen_opl B",0,4);
1443 if (op == '*') {
1444 vpushv(vtop - 1);
1445 vpushv(vtop - 1);
1446 gen_op(TOK_UMULL);
1447 lexpand();
1448 /* stack: H1 H2 L1 L2 ML MH */
1449 for(i=0;i<4;i++)
1450 vrotb(6);
1451 /* stack: ML MH H1 H2 L1 L2 */
1452 tmp = vtop[0];
1453 vtop[0] = vtop[-2];
1454 vtop[-2] = tmp;
1455 /* stack: ML MH H1 L2 H2 L1 */
1456 gen_op('*');
1457 vrotb(3);
1458 vrotb(3);
1459 gen_op('*');
1460 /* stack: ML MH M1 M2 */
1461 gen_op('+');
1462 gen_op('+');
1463 } else if (op == '+' || op == '-') {
1464 /* XXX: add non carry method too (for MIPS or alpha) */
1465 if (op == '+')
1466 op1 = TOK_ADDC1;
1467 else
1468 op1 = TOK_SUBC1;
1469 gen_op(op1);
1470 /* stack: H1 H2 (L1 op L2) */
1471 vrotb(3);
1472 vrotb(3);
1473 gen_op(op1 + 1); /* TOK_xxxC2 */
1474 } else {
1475 gen_op(op);
1476 /* stack: H1 H2 (L1 op L2) */
1477 vrotb(3);
1478 vrotb(3);
1479 /* stack: (L1 op L2) H1 H2 */
1480 gen_op(op);
1481 /* stack: (L1 op L2) (H1 op H2) */
1483 /* stack: L H */
1484 lbuild(t);
1485 break;
1486 case TOK_SAR:
1487 case TOK_SHR:
1488 case TOK_SHL:
1489 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1490 t = vtop[-1].type.t;
1491 vswap();
1492 lexpand();
1493 vrotb(3);
1494 /* stack: L H shift */
1495 c = (int)vtop->c.i;
1496 /* constant: simpler */
1497 /* NOTE: all comments are for SHL. the other cases are
1498 done by swaping words */
1499 vpop();
1500 if (op != TOK_SHL)
1501 vswap();
1502 if (c >= 32) {
1503 /* stack: L H */
1504 vpop();
1505 if (c > 32) {
1506 vpushi(c - 32);
1507 gen_op(op);
1509 if (op != TOK_SAR) {
1510 vpushi(0);
1511 } else {
1512 gv_dup();
1513 vpushi(31);
1514 gen_op(TOK_SAR);
1516 vswap();
1517 } else {
1518 vswap();
1519 gv_dup();
1520 /* stack: H L L */
1521 vpushi(c);
1522 gen_op(op);
1523 vswap();
1524 vpushi(32 - c);
1525 if (op == TOK_SHL)
1526 gen_op(TOK_SHR);
1527 else
1528 gen_op(TOK_SHL);
1529 vrotb(3);
1530 /* stack: L L H */
1531 vpushi(c);
1532 if (op == TOK_SHL)
1533 gen_op(TOK_SHL);
1534 else
1535 gen_op(TOK_SHR);
1536 gen_op('|');
1538 if (op != TOK_SHL)
1539 vswap();
1540 lbuild(t);
1541 } else {
1542 /* XXX: should provide a faster fallback on x86 ? */
1543 switch(op) {
1544 case TOK_SAR:
1545 func = TOK___ashrdi3;
1546 goto gen_func;
1547 case TOK_SHR:
1548 func = TOK___lshrdi3;
1549 goto gen_func;
1550 case TOK_SHL:
1551 func = TOK___ashldi3;
1552 goto gen_func;
1555 break;
1556 default:
1557 /* compare operations */
1558 t = vtop->type.t;
1559 vswap();
1560 lexpand();
1561 vrotb(3);
1562 lexpand();
1563 /* stack: L1 H1 L2 H2 */
1564 tmp = vtop[-1];
1565 vtop[-1] = vtop[-2];
1566 vtop[-2] = tmp;
1567 /* stack: L1 L2 H1 H2 */
1568 /* compare high */
1569 op1 = op;
1570 /* when values are equal, we need to compare low words. since
1571 the jump is inverted, we invert the test too. */
1572 if (op1 == TOK_LT)
1573 op1 = TOK_LE;
1574 else if (op1 == TOK_GT)
1575 op1 = TOK_GE;
1576 else if (op1 == TOK_ULT)
1577 op1 = TOK_ULE;
1578 else if (op1 == TOK_UGT)
1579 op1 = TOK_UGE;
1580 a = 0;
1581 b = 0;
1582 gen_op(op1);
1583 if (op1 != TOK_NE) {
1584 a = gvtst(1, 0);
1586 if (op != TOK_EQ) {
1587 /* generate non equal test */
1588 /* XXX: NOT PORTABLE yet */
1589 if (a == 0) {
1590 b = gvtst(0, 0);
1591 } else {
1592 #if defined(TCC_TARGET_I386)
1593 b = psym(0x850f, 0);
1594 #elif defined(TCC_TARGET_ARM)
1595 b = ind;
1596 o(0x1A000000 | encbranch(ind, 0, 1));
1597 #elif defined(TCC_TARGET_C67) || defined(TCC_TARGET_ARM64)
1598 tcc_error("not implemented");
1599 #else
1600 #error not supported
1601 #endif
1604 /* compare low. Always unsigned */
1605 op1 = op;
1606 if (op1 == TOK_LT)
1607 op1 = TOK_ULT;
1608 else if (op1 == TOK_LE)
1609 op1 = TOK_ULE;
1610 else if (op1 == TOK_GT)
1611 op1 = TOK_UGT;
1612 else if (op1 == TOK_GE)
1613 op1 = TOK_UGE;
1614 gen_op(op1);
1615 a = gvtst(1, a);
1616 gsym(b);
1617 vseti(VT_JMPI, a);
1618 break;
1621 #endif
1623 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
1625 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
1626 return (a ^ b) >> 63 ? -x : x;
1629 static int gen_opic_lt(uint64_t a, uint64_t b)
1631 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
1634 /* handle integer constant optimizations and various machine
1635 independent opt */
1636 static void gen_opic(int op)
1638 SValue *v1 = vtop - 1;
1639 SValue *v2 = vtop;
1640 int t1 = v1->type.t & VT_BTYPE;
1641 int t2 = v2->type.t & VT_BTYPE;
1642 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1643 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1644 uint64_t l1 = c1 ? v1->c.i : 0;
1645 uint64_t l2 = c2 ? v2->c.i : 0;
1646 int shm = (t1 == VT_LLONG) ? 63 : 31;
1648 if (t1 != VT_LLONG)
1649 l1 = ((uint32_t)l1 |
1650 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
1651 if (t2 != VT_LLONG)
1652 l2 = ((uint32_t)l2 |
1653 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
1655 if (c1 && c2) {
1656 switch(op) {
1657 case '+': l1 += l2; break;
1658 case '-': l1 -= l2; break;
1659 case '&': l1 &= l2; break;
1660 case '^': l1 ^= l2; break;
1661 case '|': l1 |= l2; break;
1662 case '*': l1 *= l2; break;
1664 case TOK_PDIV:
1665 case '/':
1666 case '%':
1667 case TOK_UDIV:
1668 case TOK_UMOD:
1669 /* if division by zero, generate explicit division */
1670 if (l2 == 0) {
1671 if (const_wanted)
1672 tcc_error("division by zero in constant");
1673 goto general_case;
1675 switch(op) {
1676 default: l1 = gen_opic_sdiv(l1, l2); break;
1677 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
1678 case TOK_UDIV: l1 = l1 / l2; break;
1679 case TOK_UMOD: l1 = l1 % l2; break;
1681 break;
1682 case TOK_SHL: l1 <<= (l2 & shm); break;
1683 case TOK_SHR: l1 >>= (l2 & shm); break;
1684 case TOK_SAR:
1685 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
1686 break;
1687 /* tests */
1688 case TOK_ULT: l1 = l1 < l2; break;
1689 case TOK_UGE: l1 = l1 >= l2; break;
1690 case TOK_EQ: l1 = l1 == l2; break;
1691 case TOK_NE: l1 = l1 != l2; break;
1692 case TOK_ULE: l1 = l1 <= l2; break;
1693 case TOK_UGT: l1 = l1 > l2; break;
1694 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
1695 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
1696 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
1697 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
1698 /* logical */
1699 case TOK_LAND: l1 = l1 && l2; break;
1700 case TOK_LOR: l1 = l1 || l2; break;
1701 default:
1702 goto general_case;
1704 v1->c.i = l1;
1705 vtop--;
1706 } else {
1707 /* if commutative ops, put c2 as constant */
1708 if (c1 && (op == '+' || op == '&' || op == '^' ||
1709 op == '|' || op == '*')) {
1710 vswap();
1711 c2 = c1; //c = c1, c1 = c2, c2 = c;
1712 l2 = l1; //l = l1, l1 = l2, l2 = l;
1714 if (!const_wanted &&
1715 c1 && ((l1 == 0 &&
1716 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
1717 (l1 == -1 && op == TOK_SAR))) {
1718 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
1719 vtop--;
1720 } else if (!const_wanted &&
1721 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
1722 (l2 == -1 && op == '|') ||
1723 (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
1724 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
1725 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
1726 if (l2 == 1)
1727 vtop->c.i = 0;
1728 vswap();
1729 vtop--;
1730 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1731 op == TOK_PDIV) &&
1732 l2 == 1) ||
1733 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1734 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1735 l2 == 0) ||
1736 (op == '&' &&
1737 l2 == -1))) {
1738 /* filter out NOP operations like x*1, x-0, x&-1... */
1739 vtop--;
1740 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1741 /* try to use shifts instead of muls or divs */
1742 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1743 int n = -1;
1744 while (l2) {
1745 l2 >>= 1;
1746 n++;
1748 vtop->c.i = n;
1749 if (op == '*')
1750 op = TOK_SHL;
1751 else if (op == TOK_PDIV)
1752 op = TOK_SAR;
1753 else
1754 op = TOK_SHR;
1756 goto general_case;
1757 } else if (c2 && (op == '+' || op == '-') &&
1758 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1759 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1760 /* symbol + constant case */
1761 if (op == '-')
1762 l2 = -l2;
1763 vtop--;
1764 vtop->c.i += l2;
1765 } else {
1766 general_case:
1767 if (!nocode_wanted) {
1768 /* call low level op generator */
1769 if (t1 == VT_LLONG || t2 == VT_LLONG ||
1770 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
1771 gen_opl(op);
1772 else
1773 gen_opi(op);
1774 } else {
1775 vtop--;
1781 /* generate a floating point operation with constant propagation */
1782 static void gen_opif(int op)
1784 int c1, c2;
1785 SValue *v1, *v2;
1786 long double f1, f2;
1788 v1 = vtop - 1;
1789 v2 = vtop;
1790 /* currently, we cannot do computations with forward symbols */
1791 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1792 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1793 if (c1 && c2) {
1794 if (v1->type.t == VT_FLOAT) {
1795 f1 = v1->c.f;
1796 f2 = v2->c.f;
1797 } else if (v1->type.t == VT_DOUBLE) {
1798 f1 = v1->c.d;
1799 f2 = v2->c.d;
1800 } else {
1801 f1 = v1->c.ld;
1802 f2 = v2->c.ld;
1805 /* NOTE: we only do constant propagation if finite number (not
1806 NaN or infinity) (ANSI spec) */
1807 if (!ieee_finite(f1) || !ieee_finite(f2))
1808 goto general_case;
1810 switch(op) {
1811 case '+': f1 += f2; break;
1812 case '-': f1 -= f2; break;
1813 case '*': f1 *= f2; break;
1814 case '/':
1815 if (f2 == 0.0) {
1816 if (const_wanted)
1817 tcc_error("division by zero in constant");
1818 goto general_case;
1820 f1 /= f2;
1821 break;
1822 /* XXX: also handles tests ? */
1823 default:
1824 goto general_case;
1826 /* XXX: overflow test ? */
1827 if (v1->type.t == VT_FLOAT) {
1828 v1->c.f = f1;
1829 } else if (v1->type.t == VT_DOUBLE) {
1830 v1->c.d = f1;
1831 } else {
1832 v1->c.ld = f1;
1834 vtop--;
1835 } else {
1836 general_case:
1837 if (!nocode_wanted) {
1838 gen_opf(op);
1839 } else {
1840 vtop--;
1845 static int pointed_size(CType *type)
1847 int align;
1848 return type_size(pointed_type(type), &align);
1851 static void vla_runtime_pointed_size(CType *type)
1853 int align;
1854 vla_runtime_type_size(pointed_type(type), &align);
1857 static inline int is_null_pointer(SValue *p)
1859 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1860 return 0;
1861 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
1862 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
1863 ((p->type.t & VT_BTYPE) == VT_PTR &&
1864 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
1867 static inline int is_integer_btype(int bt)
1869 return (bt == VT_BYTE || bt == VT_SHORT ||
1870 bt == VT_INT || bt == VT_LLONG);
1873 /* check types for comparison or subtraction of pointers */
1874 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1876 CType *type1, *type2, tmp_type1, tmp_type2;
1877 int bt1, bt2;
1879 /* null pointers are accepted for all comparisons as gcc */
1880 if (is_null_pointer(p1) || is_null_pointer(p2))
1881 return;
1882 type1 = &p1->type;
1883 type2 = &p2->type;
1884 bt1 = type1->t & VT_BTYPE;
1885 bt2 = type2->t & VT_BTYPE;
1886 /* accept comparison between pointer and integer with a warning */
1887 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1888 if (op != TOK_LOR && op != TOK_LAND )
1889 tcc_warning("comparison between pointer and integer");
1890 return;
1893 /* both must be pointers or implicit function pointers */
1894 if (bt1 == VT_PTR) {
1895 type1 = pointed_type(type1);
1896 } else if (bt1 != VT_FUNC)
1897 goto invalid_operands;
1899 if (bt2 == VT_PTR) {
1900 type2 = pointed_type(type2);
1901 } else if (bt2 != VT_FUNC) {
1902 invalid_operands:
1903 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1905 if ((type1->t & VT_BTYPE) == VT_VOID ||
1906 (type2->t & VT_BTYPE) == VT_VOID)
1907 return;
1908 tmp_type1 = *type1;
1909 tmp_type2 = *type2;
1910 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1911 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1912 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1913 /* gcc-like error if '-' is used */
1914 if (op == '-')
1915 goto invalid_operands;
1916 else
1917 tcc_warning("comparison of distinct pointer types lacks a cast");
1921 /* generic gen_op: handles types problems */
1922 ST_FUNC void gen_op(int op)
1924 int u, t1, t2, bt1, bt2, t;
1925 CType type1;
1927 t1 = vtop[-1].type.t;
1928 t2 = vtop[0].type.t;
1929 bt1 = t1 & VT_BTYPE;
1930 bt2 = t2 & VT_BTYPE;
1932 if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1933 tcc_error("operation on a struct");
1934 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
1935 /* at least one operand is a pointer */
1936 /* relationnal op: must be both pointers */
1937 if (op >= TOK_ULT && op <= TOK_LOR) {
1938 check_comparison_pointer_types(vtop - 1, vtop, op);
1939 /* pointers are handled are unsigned */
1940 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1941 t = VT_LLONG | VT_UNSIGNED;
1942 #else
1943 t = VT_INT | VT_UNSIGNED;
1944 #endif
1945 goto std_op;
1947 /* if both pointers, then it must be the '-' op */
1948 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1949 if (op != '-')
1950 tcc_error("cannot use pointers here");
1951 check_comparison_pointer_types(vtop - 1, vtop, op);
1952 /* XXX: check that types are compatible */
1953 if (vtop[-1].type.t & VT_VLA) {
1954 vla_runtime_pointed_size(&vtop[-1].type);
1955 } else {
1956 vpushi(pointed_size(&vtop[-1].type));
1958 vrott(3);
1959 gen_opic(op);
1960 /* set to integer type */
1961 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1962 vtop->type.t = VT_LLONG;
1963 #else
1964 vtop->type.t = VT_INT;
1965 #endif
1966 vswap();
1967 gen_op(TOK_PDIV);
1968 } else {
1969 /* exactly one pointer : must be '+' or '-'. */
1970 if (op != '-' && op != '+')
1971 tcc_error("cannot use pointers here");
1972 /* Put pointer as first operand */
1973 if (bt2 == VT_PTR) {
1974 vswap();
1975 swap(&t1, &t2);
1977 #if PTR_SIZE == 4
1978 if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
1979 /* XXX: truncate here because gen_opl can't handle ptr + long long */
1980 gen_cast(&int_type);
1981 #endif
1982 type1 = vtop[-1].type;
1983 type1.t &= ~VT_ARRAY;
1984 if (vtop[-1].type.t & VT_VLA)
1985 vla_runtime_pointed_size(&vtop[-1].type);
1986 else {
1987 u = pointed_size(&vtop[-1].type);
1988 if (u < 0)
1989 tcc_error("unknown array element size");
1990 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1991 vpushll(u);
1992 #else
1993 /* XXX: cast to int ? (long long case) */
1994 vpushi(u);
1995 #endif
1997 gen_op('*');
1998 #if 0
1999 /* #ifdef CONFIG_TCC_BCHECK
2000 The main reason to removing this code:
2001 #include <stdio.h>
2002 int main ()
2004 int v[10];
2005 int i = 10;
2006 int j = 9;
2007 fprintf(stderr, "v+i-j = %p\n", v+i-j);
2008 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
2010 When this code is on. then the output looks like
2011 v+i-j = 0xfffffffe
2012 v+(i-j) = 0xbff84000
2014 /* if evaluating constant expression, no code should be
2015 generated, so no bound check */
2016 if (tcc_state->do_bounds_check && !const_wanted) {
2017 /* if bounded pointers, we generate a special code to
2018 test bounds */
2019 if (op == '-') {
2020 vpushi(0);
2021 vswap();
2022 gen_op('-');
2024 gen_bounded_ptr_add();
2025 } else
2026 #endif
2028 gen_opic(op);
2030 /* put again type if gen_opic() swaped operands */
2031 vtop->type = type1;
2033 } else if (is_float(bt1) || is_float(bt2)) {
2034 /* compute bigger type and do implicit casts */
2035 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
2036 t = VT_LDOUBLE;
2037 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
2038 t = VT_DOUBLE;
2039 } else {
2040 t = VT_FLOAT;
2042 /* floats can only be used for a few operations */
2043 if (op != '+' && op != '-' && op != '*' && op != '/' &&
2044 (op < TOK_ULT || op > TOK_GT))
2045 tcc_error("invalid operands for binary operation");
2046 goto std_op;
2047 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
2048 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
2049 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
2050 t |= VT_UNSIGNED;
2051 goto std_op;
2052 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
2053 /* cast to biggest op */
2054 t = VT_LLONG;
2055 /* convert to unsigned if it does not fit in a long long */
2056 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
2057 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
2058 t |= VT_UNSIGNED;
2059 goto std_op;
2060 } else {
2061 /* integer operations */
2062 t = VT_INT;
2063 /* convert to unsigned if it does not fit in an integer */
2064 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
2065 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
2066 t |= VT_UNSIGNED;
2067 std_op:
2068 /* XXX: currently, some unsigned operations are explicit, so
2069 we modify them here */
2070 if (t & VT_UNSIGNED) {
2071 if (op == TOK_SAR)
2072 op = TOK_SHR;
2073 else if (op == '/')
2074 op = TOK_UDIV;
2075 else if (op == '%')
2076 op = TOK_UMOD;
2077 else if (op == TOK_LT)
2078 op = TOK_ULT;
2079 else if (op == TOK_GT)
2080 op = TOK_UGT;
2081 else if (op == TOK_LE)
2082 op = TOK_ULE;
2083 else if (op == TOK_GE)
2084 op = TOK_UGE;
2086 vswap();
2087 type1.t = t;
2088 gen_cast(&type1);
2089 vswap();
2090 /* special case for shifts and long long: we keep the shift as
2091 an integer */
2092 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
2093 type1.t = VT_INT;
2094 gen_cast(&type1);
2095 if (is_float(t))
2096 gen_opif(op);
2097 else
2098 gen_opic(op);
2099 if (op >= TOK_ULT && op <= TOK_GT) {
2100 /* relationnal op: the result is an int */
2101 vtop->type.t = VT_INT;
2102 } else {
2103 vtop->type.t = t;
2106 // Make sure that we have converted to an rvalue:
2107 if (vtop->r & VT_LVAL && !nocode_wanted)
2108 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
2111 #ifndef TCC_TARGET_ARM
2112 /* generic itof for unsigned long long case */
2113 static void gen_cvt_itof1(int t)
2115 #ifdef TCC_TARGET_ARM64
2116 gen_cvt_itof(t);
2117 #else
2118 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
2119 (VT_LLONG | VT_UNSIGNED)) {
2121 if (t == VT_FLOAT)
2122 vpush_global_sym(&func_old_type, TOK___floatundisf);
2123 #if LDOUBLE_SIZE != 8
2124 else if (t == VT_LDOUBLE)
2125 vpush_global_sym(&func_old_type, TOK___floatundixf);
2126 #endif
2127 else
2128 vpush_global_sym(&func_old_type, TOK___floatundidf);
2129 vrott(2);
2130 gfunc_call(1);
2131 vpushi(0);
2132 vtop->r = reg_fret(t);
2133 } else {
2134 gen_cvt_itof(t);
2136 #endif
2138 #endif
2140 /* generic ftoi for unsigned long long case */
2141 static void gen_cvt_ftoi1(int t)
2143 #ifdef TCC_TARGET_ARM64
2144 gen_cvt_ftoi(t);
2145 #else
2146 int st;
2148 if (t == (VT_LLONG | VT_UNSIGNED)) {
2149 /* not handled natively */
2150 st = vtop->type.t & VT_BTYPE;
2151 if (st == VT_FLOAT)
2152 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
2153 #if LDOUBLE_SIZE != 8
2154 else if (st == VT_LDOUBLE)
2155 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
2156 #endif
2157 else
2158 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
2159 vrott(2);
2160 gfunc_call(1);
2161 vpushi(0);
2162 vtop->r = REG_IRET;
2163 vtop->r2 = REG_LRET;
2164 } else {
2165 gen_cvt_ftoi(t);
2167 #endif
2170 /* force char or short cast */
2171 static void force_charshort_cast(int t)
2173 int bits, dbt;
2174 dbt = t & VT_BTYPE;
2175 /* XXX: add optimization if lvalue : just change type and offset */
2176 if (dbt == VT_BYTE)
2177 bits = 8;
2178 else
2179 bits = 16;
2180 if (t & VT_UNSIGNED) {
2181 vpushi((1 << bits) - 1);
2182 gen_op('&');
2183 } else {
2184 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
2185 bits = 64 - bits;
2186 else
2187 bits = 32 - bits;
2188 vpushi(bits);
2189 gen_op(TOK_SHL);
2190 /* result must be signed or the SAR is converted to an SHL
2191 This was not the case when "t" was a signed short
2192 and the last value on the stack was an unsigned int */
2193 vtop->type.t &= ~VT_UNSIGNED;
2194 vpushi(bits);
2195 gen_op(TOK_SAR);
2199 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
2200 static void gen_cast(CType *type)
2202 int sbt, dbt, sf, df, c, p;
2204 /* special delayed cast for char/short */
2205 /* XXX: in some cases (multiple cascaded casts), it may still
2206 be incorrect */
2207 if (vtop->r & VT_MUSTCAST) {
2208 vtop->r &= ~VT_MUSTCAST;
2209 force_charshort_cast(vtop->type.t);
2212 /* bitfields first get cast to ints */
2213 if (vtop->type.t & VT_BITFIELD && !nocode_wanted) {
2214 gv(RC_INT);
2217 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
2218 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
2220 if (sbt != dbt) {
2221 sf = is_float(sbt);
2222 df = is_float(dbt);
2223 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2224 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
2225 if (c) {
2226 /* constant case: we can do it now */
2227 /* XXX: in ISOC, cannot do it if error in convert */
2228 if (sbt == VT_FLOAT)
2229 vtop->c.ld = vtop->c.f;
2230 else if (sbt == VT_DOUBLE)
2231 vtop->c.ld = vtop->c.d;
2233 if (df) {
2234 if ((sbt & VT_BTYPE) == VT_LLONG) {
2235 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
2236 vtop->c.ld = vtop->c.i;
2237 else
2238 vtop->c.ld = -(long double)-vtop->c.i;
2239 } else if(!sf) {
2240 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
2241 vtop->c.ld = (uint32_t)vtop->c.i;
2242 else
2243 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
2246 if (dbt == VT_FLOAT)
2247 vtop->c.f = (float)vtop->c.ld;
2248 else if (dbt == VT_DOUBLE)
2249 vtop->c.d = (double)vtop->c.ld;
2250 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
2251 vtop->c.i = vtop->c.ld;
2252 } else if (sf && dbt == VT_BOOL) {
2253 vtop->c.i = (vtop->c.ld != 0);
2254 } else {
2255 if(sf)
2256 vtop->c.i = vtop->c.ld;
2257 else if (sbt == (VT_LLONG|VT_UNSIGNED))
2259 else if (sbt & VT_UNSIGNED)
2260 vtop->c.i = (uint32_t)vtop->c.i;
2261 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2262 else if (sbt == VT_PTR)
2264 #endif
2265 else if (sbt != VT_LLONG)
2266 vtop->c.i = ((uint32_t)vtop->c.i |
2267 -(vtop->c.i & 0x80000000));
2269 if (dbt == (VT_LLONG|VT_UNSIGNED))
2271 else if (dbt == VT_BOOL)
2272 vtop->c.i = (vtop->c.i != 0);
2273 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2274 else if (dbt == VT_PTR)
2276 #endif
2277 else if (dbt != VT_LLONG) {
2278 uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
2279 (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
2280 0xffffffff);
2281 vtop->c.i &= m;
2282 if (!(dbt & VT_UNSIGNED))
2283 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
2286 } else if (p && dbt == VT_BOOL) {
2287 vtop->r = VT_CONST;
2288 vtop->c.i = 1;
2289 } else if (!nocode_wanted) {
2290 /* non constant case: generate code */
2291 if (sf && df) {
2292 /* convert from fp to fp */
2293 gen_cvt_ftof(dbt);
2294 } else if (df) {
2295 /* convert int to fp */
2296 gen_cvt_itof1(dbt);
2297 } else if (sf) {
2298 /* convert fp to int */
2299 if (dbt == VT_BOOL) {
2300 vpushi(0);
2301 gen_op(TOK_NE);
2302 } else {
2303 /* we handle char/short/etc... with generic code */
2304 if (dbt != (VT_INT | VT_UNSIGNED) &&
2305 dbt != (VT_LLONG | VT_UNSIGNED) &&
2306 dbt != VT_LLONG)
2307 dbt = VT_INT;
2308 gen_cvt_ftoi1(dbt);
2309 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2310 /* additional cast for char/short... */
2311 vtop->type.t = dbt;
2312 gen_cast(type);
2315 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
2316 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2317 if ((sbt & VT_BTYPE) != VT_LLONG) {
2318 /* scalar to long long */
2319 /* machine independent conversion */
2320 gv(RC_INT);
2321 /* generate high word */
2322 if (sbt == (VT_INT | VT_UNSIGNED)) {
2323 vpushi(0);
2324 gv(RC_INT);
2325 } else {
2326 if (sbt == VT_PTR) {
2327 /* cast from pointer to int before we apply
2328 shift operation, which pointers don't support*/
2329 gen_cast(&int_type);
2331 gv_dup();
2332 vpushi(31);
2333 gen_op(TOK_SAR);
2335 /* patch second register */
2336 vtop[-1].r2 = vtop->r;
2337 vpop();
2339 #else
2340 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2341 (dbt & VT_BTYPE) == VT_PTR ||
2342 (dbt & VT_BTYPE) == VT_FUNC) {
2343 if ((sbt & VT_BTYPE) != VT_LLONG &&
2344 (sbt & VT_BTYPE) != VT_PTR &&
2345 (sbt & VT_BTYPE) != VT_FUNC) {
2346 /* need to convert from 32bit to 64bit */
2347 gv(RC_INT);
2348 if (sbt != (VT_INT | VT_UNSIGNED)) {
2349 #if defined(TCC_TARGET_ARM64)
2350 gen_cvt_sxtw();
2351 #elif defined(TCC_TARGET_X86_64)
2352 int r = gv(RC_INT);
2353 /* x86_64 specific: movslq */
2354 o(0x6348);
2355 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2356 #else
2357 #error
2358 #endif
2361 #endif
2362 } else if (dbt == VT_BOOL) {
2363 /* scalar to bool */
2364 vpushi(0);
2365 gen_op(TOK_NE);
2366 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2367 (dbt & VT_BTYPE) == VT_SHORT) {
2368 if (sbt == VT_PTR) {
2369 vtop->type.t = VT_INT;
2370 tcc_warning("nonportable conversion from pointer to char/short");
2372 force_charshort_cast(dbt);
2373 } else if ((dbt & VT_BTYPE) == VT_INT) {
2374 /* scalar to int */
2375 if ((sbt & VT_BTYPE) == VT_LLONG) {
2376 /* from long long: just take low order word */
2377 lexpand();
2378 vpop();
2380 /* if lvalue and single word type, nothing to do because
2381 the lvalue already contains the real type size (see
2382 VT_LVAL_xxx constants) */
2385 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2386 /* if we are casting between pointer types,
2387 we must update the VT_LVAL_xxx size */
2388 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2389 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2391 vtop->type = *type;
2394 /* return type size as known at compile time. Put alignment at 'a' */
2395 ST_FUNC int type_size(CType *type, int *a)
2397 Sym *s;
2398 int bt;
2400 bt = type->t & VT_BTYPE;
2401 if (bt == VT_STRUCT) {
2402 /* struct/union */
2403 s = type->ref;
2404 *a = s->r;
2405 return s->c;
2406 } else if (bt == VT_PTR) {
2407 if (type->t & VT_ARRAY) {
2408 int ts;
2410 s = type->ref;
2411 ts = type_size(&s->type, a);
2413 if (ts < 0 && s->c < 0)
2414 ts = -ts;
2416 return ts * s->c;
2417 } else {
2418 *a = PTR_SIZE;
2419 return PTR_SIZE;
2421 } else if (bt == VT_LDOUBLE) {
2422 *a = LDOUBLE_ALIGN;
2423 return LDOUBLE_SIZE;
2424 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2425 #ifdef TCC_TARGET_I386
2426 #ifdef TCC_TARGET_PE
2427 *a = 8;
2428 #else
2429 *a = 4;
2430 #endif
2431 #elif defined(TCC_TARGET_ARM)
2432 #ifdef TCC_ARM_EABI
2433 *a = 8;
2434 #else
2435 *a = 4;
2436 #endif
2437 #else
2438 *a = 8;
2439 #endif
2440 return 8;
2441 } else if (bt == VT_INT || bt == VT_FLOAT) {
2442 *a = 4;
2443 return 4;
2444 } else if (bt == VT_SHORT) {
2445 *a = 2;
2446 return 2;
2447 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2448 *a = 8;
2449 return 16;
2450 } else if (bt == VT_ENUM) {
2451 *a = 4;
2452 /* Enums might be incomplete, so don't just return '4' here. */
2453 return type->ref->c;
2454 } else {
2455 /* char, void, function, _Bool */
2456 *a = 1;
2457 return 1;
2461 /* push type size as known at runtime time on top of value stack. Put
2462 alignment at 'a' */
2463 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2465 if (type->t & VT_VLA) {
2466 type_size(&type->ref->type, a);
2467 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2468 } else {
2469 vpushi(type_size(type, a));
2473 static void vla_sp_restore(void) {
2474 if (vlas_in_scope) {
2475 gen_vla_sp_restore(vla_sp_loc);
2479 static void vla_sp_restore_root(void) {
2480 if (vlas_in_scope) {
2481 gen_vla_sp_restore(vla_sp_root_loc);
2485 /* return the pointed type of t */
2486 static inline CType *pointed_type(CType *type)
2488 return &type->ref->type;
2491 /* modify type so that its it is a pointer to type. */
2492 ST_FUNC void mk_pointer(CType *type)
2494 Sym *s;
2495 s = sym_push(SYM_FIELD, type, 0, -1);
2496 type->t = VT_PTR | (type->t & ~VT_TYPE);
2497 type->ref = s;
2500 /* compare function types. OLD functions match any new functions */
2501 static int is_compatible_func(CType *type1, CType *type2)
2503 Sym *s1, *s2;
2505 s1 = type1->ref;
2506 s2 = type2->ref;
2507 if (!is_compatible_types(&s1->type, &s2->type))
2508 return 0;
2509 /* check func_call */
2510 if (s1->a.func_call != s2->a.func_call)
2511 return 0;
2512 /* XXX: not complete */
2513 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2514 return 1;
2515 if (s1->c != s2->c)
2516 return 0;
2517 while (s1 != NULL) {
2518 if (s2 == NULL)
2519 return 0;
2520 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2521 return 0;
2522 s1 = s1->next;
2523 s2 = s2->next;
2525 if (s2)
2526 return 0;
2527 return 1;
2530 /* return true if type1 and type2 are the same. If unqualified is
2531 true, qualifiers on the types are ignored.
2533 - enums are not checked as gcc __builtin_types_compatible_p ()
2535 static int compare_types(CType *type1, CType *type2, int unqualified)
2537 int bt1, t1, t2;
2539 t1 = type1->t & VT_TYPE;
2540 t2 = type2->t & VT_TYPE;
2541 if (unqualified) {
2542 /* strip qualifiers before comparing */
2543 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2544 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2546 /* Default Vs explicit signedness only matters for char */
2547 if ((t1 & VT_BTYPE) != VT_BYTE) {
2548 t1 &= ~VT_DEFSIGN;
2549 t2 &= ~VT_DEFSIGN;
2551 /* XXX: bitfields ? */
2552 if (t1 != t2)
2553 return 0;
2554 /* test more complicated cases */
2555 bt1 = t1 & VT_BTYPE;
2556 if (bt1 == VT_PTR) {
2557 type1 = pointed_type(type1);
2558 type2 = pointed_type(type2);
2559 return is_compatible_types(type1, type2);
2560 } else if (bt1 == VT_STRUCT) {
2561 return (type1->ref == type2->ref);
2562 } else if (bt1 == VT_FUNC) {
2563 return is_compatible_func(type1, type2);
2564 } else {
2565 return 1;
2569 /* return true if type1 and type2 are exactly the same (including
2570 qualifiers).
2572 static int is_compatible_types(CType *type1, CType *type2)
2574 return compare_types(type1,type2,0);
2577 /* return true if type1 and type2 are the same (ignoring qualifiers).
2579 static int is_compatible_parameter_types(CType *type1, CType *type2)
2581 return compare_types(type1,type2,1);
2584 /* print a type. If 'varstr' is not NULL, then the variable is also
2585 printed in the type */
2586 /* XXX: union */
2587 /* XXX: add array and function pointers */
2588 static void type_to_str(char *buf, int buf_size,
2589 CType *type, const char *varstr)
2591 int bt, v, t;
2592 Sym *s, *sa;
2593 char buf1[256];
2594 const char *tstr;
2596 t = type->t & VT_TYPE;
2597 bt = t & VT_BTYPE;
2598 buf[0] = '\0';
2599 if (t & VT_CONSTANT)
2600 pstrcat(buf, buf_size, "const ");
2601 if (t & VT_VOLATILE)
2602 pstrcat(buf, buf_size, "volatile ");
2603 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2604 pstrcat(buf, buf_size, "unsigned ");
2605 else if (t & VT_DEFSIGN)
2606 pstrcat(buf, buf_size, "signed ");
2607 switch(bt) {
2608 case VT_VOID:
2609 tstr = "void";
2610 goto add_tstr;
2611 case VT_BOOL:
2612 tstr = "_Bool";
2613 goto add_tstr;
2614 case VT_BYTE:
2615 tstr = "char";
2616 goto add_tstr;
2617 case VT_SHORT:
2618 tstr = "short";
2619 goto add_tstr;
2620 case VT_INT:
2621 tstr = "int";
2622 goto add_tstr;
2623 case VT_LONG:
2624 tstr = "long";
2625 goto add_tstr;
2626 case VT_LLONG:
2627 tstr = "long long";
2628 goto add_tstr;
2629 case VT_FLOAT:
2630 tstr = "float";
2631 goto add_tstr;
2632 case VT_DOUBLE:
2633 tstr = "double";
2634 goto add_tstr;
2635 case VT_LDOUBLE:
2636 tstr = "long double";
2637 add_tstr:
2638 pstrcat(buf, buf_size, tstr);
2639 break;
2640 case VT_ENUM:
2641 case VT_STRUCT:
2642 if (bt == VT_STRUCT)
2643 tstr = "struct ";
2644 else
2645 tstr = "enum ";
2646 pstrcat(buf, buf_size, tstr);
2647 v = type->ref->v & ~SYM_STRUCT;
2648 if (v >= SYM_FIRST_ANOM)
2649 pstrcat(buf, buf_size, "<anonymous>");
2650 else
2651 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2652 break;
2653 case VT_FUNC:
2654 s = type->ref;
2655 type_to_str(buf, buf_size, &s->type, varstr);
2656 pstrcat(buf, buf_size, "(");
2657 sa = s->next;
2658 while (sa != NULL) {
2659 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2660 pstrcat(buf, buf_size, buf1);
2661 sa = sa->next;
2662 if (sa)
2663 pstrcat(buf, buf_size, ", ");
2665 pstrcat(buf, buf_size, ")");
2666 goto no_var;
2667 case VT_PTR:
2668 s = type->ref;
2669 if (t & VT_ARRAY) {
2670 snprintf(buf1, sizeof(buf1), "%s[%ld]", varstr ? varstr : "", s->c);
2671 type_to_str(buf, buf_size, &s->type, buf1);
2672 goto no_var;
2674 pstrcpy(buf1, sizeof(buf1), "*");
2675 if (t & VT_CONSTANT)
2676 pstrcat(buf1, buf_size, "const ");
2677 if (t & VT_VOLATILE)
2678 pstrcat(buf1, buf_size, "volatile ");
2679 if (varstr)
2680 pstrcat(buf1, sizeof(buf1), varstr);
2681 type_to_str(buf, buf_size, &s->type, buf1);
2682 goto no_var;
2684 if (varstr) {
2685 pstrcat(buf, buf_size, " ");
2686 pstrcat(buf, buf_size, varstr);
2688 no_var: ;
2691 /* verify type compatibility to store vtop in 'dt' type, and generate
2692 casts if needed. */
2693 static void gen_assign_cast(CType *dt)
2695 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2696 char buf1[256], buf2[256];
2697 int dbt, sbt;
2699 st = &vtop->type; /* source type */
2700 dbt = dt->t & VT_BTYPE;
2701 sbt = st->t & VT_BTYPE;
2702 if (sbt == VT_VOID || dbt == VT_VOID) {
2703 if (sbt == VT_VOID && dbt == VT_VOID)
2704 ; /*
2705 It is Ok if both are void
2706 A test program:
2707 void func1() {}
2708 void func2() {
2709 return func1();
2711 gcc accepts this program
2713 else
2714 tcc_error("cannot cast from/to void");
2716 if (dt->t & VT_CONSTANT)
2717 tcc_warning("assignment of read-only location");
2718 switch(dbt) {
2719 case VT_PTR:
2720 /* special cases for pointers */
2721 /* '0' can also be a pointer */
2722 if (is_null_pointer(vtop))
2723 goto type_ok;
2724 /* accept implicit pointer to integer cast with warning */
2725 if (is_integer_btype(sbt)) {
2726 tcc_warning("assignment makes pointer from integer without a cast");
2727 goto type_ok;
2729 type1 = pointed_type(dt);
2730 /* a function is implicitely a function pointer */
2731 if (sbt == VT_FUNC) {
2732 if ((type1->t & VT_BTYPE) != VT_VOID &&
2733 !is_compatible_types(pointed_type(dt), st))
2734 tcc_warning("assignment from incompatible pointer type");
2735 goto type_ok;
2737 if (sbt != VT_PTR)
2738 goto error;
2739 type2 = pointed_type(st);
2740 if ((type1->t & VT_BTYPE) == VT_VOID ||
2741 (type2->t & VT_BTYPE) == VT_VOID) {
2742 /* void * can match anything */
2743 } else {
2744 /* exact type match, except for unsigned */
2745 tmp_type1 = *type1;
2746 tmp_type2 = *type2;
2747 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2748 VT_VOLATILE);
2749 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2750 VT_VOLATILE);
2751 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2752 tcc_warning("assignment from incompatible pointer type");
2754 /* check const and volatile */
2755 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2756 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2757 tcc_warning("assignment discards qualifiers from pointer target type");
2758 break;
2759 case VT_BYTE:
2760 case VT_SHORT:
2761 case VT_INT:
2762 case VT_LLONG:
2763 if (sbt == VT_PTR || sbt == VT_FUNC) {
2764 tcc_warning("assignment makes integer from pointer without a cast");
2765 } else if (sbt == VT_STRUCT) {
2766 goto case_VT_STRUCT;
2768 /* XXX: more tests */
2769 break;
2770 case VT_STRUCT:
2771 case_VT_STRUCT:
2772 tmp_type1 = *dt;
2773 tmp_type2 = *st;
2774 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2775 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2776 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2777 error:
2778 type_to_str(buf1, sizeof(buf1), st, NULL);
2779 type_to_str(buf2, sizeof(buf2), dt, NULL);
2780 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2782 break;
2784 type_ok:
2785 gen_cast(dt);
2788 /* store vtop in lvalue pushed on stack */
2789 ST_FUNC void vstore(void)
2791 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2793 ft = vtop[-1].type.t;
2794 sbt = vtop->type.t & VT_BTYPE;
2795 dbt = ft & VT_BTYPE;
2796 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2797 (sbt == VT_INT && dbt == VT_SHORT))
2798 && !(vtop->type.t & VT_BITFIELD)) {
2799 /* optimize char/short casts */
2800 delayed_cast = VT_MUSTCAST;
2801 vtop->type.t = (ft & VT_TYPE & ~VT_BITFIELD &
2802 ((1 << VT_STRUCT_SHIFT) - 1));
2803 /* XXX: factorize */
2804 if (ft & VT_CONSTANT)
2805 tcc_warning("assignment of read-only location");
2806 } else {
2807 delayed_cast = 0;
2808 if (!(ft & VT_BITFIELD))
2809 gen_assign_cast(&vtop[-1].type);
2812 if (sbt == VT_STRUCT) {
2813 /* if structure, only generate pointer */
2814 /* structure assignment : generate memcpy */
2815 /* XXX: optimize if small size */
2816 if (!nocode_wanted) {
2817 size = type_size(&vtop->type, &align);
2819 /* destination */
2820 vswap();
2821 vtop->type.t = VT_PTR;
2822 gaddrof();
2824 /* address of memcpy() */
2825 #ifdef TCC_ARM_EABI
2826 if(!(align & 7))
2827 vpush_global_sym(&func_old_type, TOK_memcpy8);
2828 else if(!(align & 3))
2829 vpush_global_sym(&func_old_type, TOK_memcpy4);
2830 else
2831 #endif
2832 /* Use memmove, rather than memcpy, as dest and src may be same: */
2833 vpush_global_sym(&func_old_type, TOK_memmove);
2835 vswap();
2836 /* source */
2837 vpushv(vtop - 2);
2838 vtop->type.t = VT_PTR;
2839 gaddrof();
2840 /* type size */
2841 vpushi(size);
2842 gfunc_call(3);
2843 } else {
2844 vswap();
2845 vpop();
2847 /* leave source on stack */
2848 } else if (ft & VT_BITFIELD) {
2849 /* bitfield store handling */
2851 /* save lvalue as expression result (example: s.b = s.a = n;) */
2852 vdup(), vtop[-1] = vtop[-2];
2854 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2855 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2856 /* remove bit field info to avoid loops */
2857 vtop[-1].type.t = ft & ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
2859 if((ft & VT_BTYPE) == VT_BOOL) {
2860 gen_cast(&vtop[-1].type);
2861 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2864 /* duplicate destination */
2865 vdup();
2866 vtop[-1] = vtop[-2];
2868 /* mask and shift source */
2869 if((ft & VT_BTYPE) != VT_BOOL) {
2870 if((ft & VT_BTYPE) == VT_LLONG) {
2871 vpushll((1ULL << bit_size) - 1ULL);
2872 } else {
2873 vpushi((1 << bit_size) - 1);
2875 gen_op('&');
2877 vpushi(bit_pos);
2878 gen_op(TOK_SHL);
2879 /* load destination, mask and or with source */
2880 vswap();
2881 if((ft & VT_BTYPE) == VT_LLONG) {
2882 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2883 } else {
2884 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2886 gen_op('&');
2887 gen_op('|');
2888 /* store result */
2889 vstore();
2890 /* ... and discard */
2891 vpop();
2893 } else {
2894 if (!nocode_wanted) {
2895 #ifdef CONFIG_TCC_BCHECK
2896 /* bound check case */
2897 if (vtop[-1].r & VT_MUSTBOUND) {
2898 vswap();
2899 gbound();
2900 vswap();
2902 #endif
2903 rc = RC_INT;
2904 if (is_float(ft)) {
2905 rc = RC_FLOAT;
2906 #ifdef TCC_TARGET_X86_64
2907 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2908 rc = RC_ST0;
2909 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2910 rc = RC_FRET;
2912 #endif
2914 r = gv(rc); /* generate value */
2915 /* if lvalue was saved on stack, must read it */
2916 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2917 SValue sv;
2918 t = get_reg(RC_INT);
2919 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2920 sv.type.t = VT_PTR;
2921 #else
2922 sv.type.t = VT_INT;
2923 #endif
2924 sv.r = VT_LOCAL | VT_LVAL;
2925 sv.c.i = vtop[-1].c.i;
2926 load(t, &sv);
2927 vtop[-1].r = t | VT_LVAL;
2929 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2930 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2931 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2932 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2933 #else
2934 if ((ft & VT_BTYPE) == VT_LLONG) {
2935 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2936 #endif
2937 vtop[-1].type.t = load_type;
2938 store(r, vtop - 1);
2939 vswap();
2940 /* convert to int to increment easily */
2941 vtop->type.t = addr_type;
2942 gaddrof();
2943 vpushi(load_size);
2944 gen_op('+');
2945 vtop->r |= VT_LVAL;
2946 vswap();
2947 vtop[-1].type.t = load_type;
2948 /* XXX: it works because r2 is spilled last ! */
2949 store(vtop->r2, vtop - 1);
2950 } else {
2951 store(r, vtop - 1);
2954 vswap();
2955 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2956 vtop->r |= delayed_cast;
2960 /* post defines POST/PRE add. c is the token ++ or -- */
2961 ST_FUNC void inc(int post, int c)
2963 test_lvalue();
2964 vdup(); /* save lvalue */
2965 if (post) {
2966 if (!nocode_wanted)
2967 gv_dup(); /* duplicate value */
2968 else
2969 vdup(); /* duplicate value */
2970 vrotb(3);
2971 vrotb(3);
2973 /* add constant */
2974 vpushi(c - TOK_MID);
2975 gen_op('+');
2976 vstore(); /* store value */
2977 if (post)
2978 vpop(); /* if post op, return saved value */
2981 /* Parse GNUC __attribute__ extension. Currently, the following
2982 extensions are recognized:
2983 - aligned(n) : set data/function alignment.
2984 - packed : force data alignment to 1
2985 - section(x) : generate data/code in this section.
2986 - unused : currently ignored, but may be used someday.
2987 - regparm(n) : pass function parameters in registers (i386 only)
2989 static void parse_attribute(AttributeDef *ad)
2991 int t, n;
2993 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2994 next();
2995 skip('(');
2996 skip('(');
2997 while (tok != ')') {
2998 if (tok < TOK_IDENT)
2999 expect("attribute name");
3000 t = tok;
3001 next();
3002 switch(t) {
3003 case TOK_SECTION1:
3004 case TOK_SECTION2:
3005 skip('(');
3006 if (tok != TOK_STR)
3007 expect("section name");
3008 ad->section = find_section(tcc_state, (char *)tokc.str.data);
3009 next();
3010 skip(')');
3011 break;
3012 case TOK_ALIAS1:
3013 case TOK_ALIAS2:
3014 skip('(');
3015 if (tok != TOK_STR)
3016 expect("alias(\"target\")");
3017 ad->alias_target = /* save string as token, for later */
3018 tok_alloc((char*)tokc.str.data, tokc.str.size-1)->tok;
3019 next();
3020 skip(')');
3021 break;
3022 case TOK_VISIBILITY1:
3023 case TOK_VISIBILITY2:
3024 skip('(');
3025 if (tok != TOK_STR)
3026 expect("visibility(\"default|hidden|internal|protected\")");
3027 if (!strcmp (tokc.str.data, "default"))
3028 ad->a.visibility = STV_DEFAULT;
3029 else if (!strcmp (tokc.str.data, "hidden"))
3030 ad->a.visibility = STV_HIDDEN;
3031 else if (!strcmp (tokc.str.data, "internal"))
3032 ad->a.visibility = STV_INTERNAL;
3033 else if (!strcmp (tokc.str.data, "protected"))
3034 ad->a.visibility = STV_PROTECTED;
3035 else
3036 expect("visibility(\"default|hidden|internal|protected\")");
3037 next();
3038 skip(')');
3039 break;
3040 case TOK_ALIGNED1:
3041 case TOK_ALIGNED2:
3042 if (tok == '(') {
3043 next();
3044 n = expr_const();
3045 if (n <= 0 || (n & (n - 1)) != 0)
3046 tcc_error("alignment must be a positive power of two");
3047 skip(')');
3048 } else {
3049 n = MAX_ALIGN;
3051 ad->a.aligned = n;
3052 break;
3053 case TOK_PACKED1:
3054 case TOK_PACKED2:
3055 ad->a.packed = 1;
3056 break;
3057 case TOK_WEAK1:
3058 case TOK_WEAK2:
3059 ad->a.weak = 1;
3060 break;
3061 case TOK_UNUSED1:
3062 case TOK_UNUSED2:
3063 /* currently, no need to handle it because tcc does not
3064 track unused objects */
3065 break;
3066 case TOK_NORETURN1:
3067 case TOK_NORETURN2:
3068 /* currently, no need to handle it because tcc does not
3069 track unused objects */
3070 break;
3071 case TOK_CDECL1:
3072 case TOK_CDECL2:
3073 case TOK_CDECL3:
3074 ad->a.func_call = FUNC_CDECL;
3075 break;
3076 case TOK_STDCALL1:
3077 case TOK_STDCALL2:
3078 case TOK_STDCALL3:
3079 ad->a.func_call = FUNC_STDCALL;
3080 break;
3081 #ifdef TCC_TARGET_I386
3082 case TOK_REGPARM1:
3083 case TOK_REGPARM2:
3084 skip('(');
3085 n = expr_const();
3086 if (n > 3)
3087 n = 3;
3088 else if (n < 0)
3089 n = 0;
3090 if (n > 0)
3091 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
3092 skip(')');
3093 break;
3094 case TOK_FASTCALL1:
3095 case TOK_FASTCALL2:
3096 case TOK_FASTCALL3:
3097 ad->a.func_call = FUNC_FASTCALLW;
3098 break;
3099 #endif
3100 case TOK_MODE:
3101 skip('(');
3102 switch(tok) {
3103 case TOK_MODE_DI:
3104 ad->a.mode = VT_LLONG + 1;
3105 break;
3106 case TOK_MODE_QI:
3107 ad->a.mode = VT_BYTE + 1;
3108 break;
3109 case TOK_MODE_HI:
3110 ad->a.mode = VT_SHORT + 1;
3111 break;
3112 case TOK_MODE_SI:
3113 case TOK_MODE_word:
3114 ad->a.mode = VT_INT + 1;
3115 break;
3116 default:
3117 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
3118 break;
3120 next();
3121 skip(')');
3122 break;
3123 case TOK_DLLEXPORT:
3124 ad->a.func_export = 1;
3125 break;
3126 case TOK_DLLIMPORT:
3127 ad->a.func_import = 1;
3128 break;
3129 default:
3130 if (tcc_state->warn_unsupported)
3131 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
3132 /* skip parameters */
3133 if (tok == '(') {
3134 int parenthesis = 0;
3135 do {
3136 if (tok == '(')
3137 parenthesis++;
3138 else if (tok == ')')
3139 parenthesis--;
3140 next();
3141 } while (parenthesis && tok != -1);
3143 break;
3145 if (tok != ',')
3146 break;
3147 next();
3149 skip(')');
3150 skip(')');
3154 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
3155 static void struct_decl(CType *type, AttributeDef *ad, int u)
3157 int a, v, size, align, maxalign, c, offset, flexible, extra_bytes;
3158 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
3159 Sym *s, *ss, *ass, **ps;
3160 AttributeDef ad1;
3161 CType type1, btype;
3163 a = tok; /* save decl type */
3164 next();
3165 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
3166 parse_attribute(ad);
3167 next();
3169 if (tok != '{') {
3170 v = tok;
3171 next();
3172 /* struct already defined ? return it */
3173 if (v < TOK_IDENT)
3174 expect("struct/union/enum name");
3175 s = struct_find(v);
3176 if (s && (s->scope == local_scope || (tok != '{' && tok != ';'))) {
3177 if (s->type.t != a)
3178 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
3179 goto do_decl;
3181 } else {
3182 v = anon_sym++;
3184 type1.t = a;
3185 type1.ref = NULL;
3186 /* we put an undefined size for struct/union */
3187 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
3188 s->r = 0; /* default alignment is zero as gcc */
3189 /* put struct/union/enum name in type */
3190 do_decl:
3191 type->t = u;
3192 type->ref = s;
3194 if (tok == '{') {
3195 next();
3196 if (s->c != -1)
3197 tcc_error("struct/union/enum already defined");
3198 /* cannot be empty */
3199 c = 0;
3200 /* non empty enums are not allowed */
3201 if (a == TOK_ENUM) {
3202 for(;;) {
3203 v = tok;
3204 if (v < TOK_UIDENT)
3205 expect("identifier");
3206 ss = sym_find(v);
3207 if (ss && !local_stack)
3208 tcc_error("redefinition of enumerator '%s'",
3209 get_tok_str(v, NULL));
3210 next();
3211 if (tok == '=') {
3212 next();
3213 c = expr_const();
3215 /* enum symbols have static storage */
3216 ss = sym_push(v, &int_type, VT_CONST, c);
3217 ss->type.t |= VT_STATIC;
3218 if (tok != ',')
3219 break;
3220 next();
3221 c++;
3222 /* NOTE: we accept a trailing comma */
3223 if (tok == '}')
3224 break;
3226 s->c = type_size(&int_type, &align);
3227 skip('}');
3228 } else {
3229 maxalign = 1;
3230 ps = &s->next;
3231 prevbt = VT_INT;
3232 bit_pos = 0;
3233 offset = 0;
3234 flexible = 0;
3235 while (tok != '}') {
3236 parse_btype(&btype, &ad1);
3237 while (1) {
3238 extra_bytes = 0;
3239 if (flexible)
3240 tcc_error("flexible array member '%s' not at the end of struct",
3241 get_tok_str(v, NULL));
3242 bit_size = -1;
3243 v = 0;
3244 type1 = btype;
3245 if (tok != ':') {
3246 type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT);
3247 if (v == 0) {
3248 if ((type1.t & VT_BTYPE) != VT_STRUCT)
3249 expect("identifier");
3250 else {
3251 int v = btype.ref->v;
3252 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
3253 if (tcc_state->ms_extensions == 0)
3254 expect("identifier");
3258 if (type_size(&type1, &align) < 0) {
3259 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
3260 flexible = 1;
3261 else
3262 tcc_error("field '%s' has incomplete type",
3263 get_tok_str(v, NULL));
3265 if ((type1.t & VT_BTYPE) == VT_FUNC ||
3266 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
3267 tcc_error("invalid type for '%s'",
3268 get_tok_str(v, NULL));
3270 if (tok == ':') {
3271 next();
3272 bit_size = expr_const();
3273 /* XXX: handle v = 0 case for messages */
3274 if (bit_size < 0)
3275 tcc_error("negative width in bit-field '%s'",
3276 get_tok_str(v, NULL));
3277 if (v && bit_size == 0)
3278 tcc_error("zero width for bit-field '%s'",
3279 get_tok_str(v, NULL));
3281 size = type_size(&type1, &align);
3282 if (ad1.a.aligned) {
3283 if (align < ad1.a.aligned)
3284 align = ad1.a.aligned;
3285 } else if (ad1.a.packed) {
3286 align = 1;
3287 } else if (*tcc_state->pack_stack_ptr) {
3288 if (align > *tcc_state->pack_stack_ptr)
3289 align = *tcc_state->pack_stack_ptr;
3291 lbit_pos = 0;
3292 if (bit_size >= 0) {
3293 bt = type1.t & VT_BTYPE;
3294 if (bt != VT_INT &&
3295 bt != VT_BYTE &&
3296 bt != VT_SHORT &&
3297 bt != VT_BOOL &&
3298 bt != VT_ENUM &&
3299 bt != VT_LLONG)
3300 tcc_error("bitfields must have scalar type");
3301 bsize = size * 8;
3302 if (bit_size > bsize) {
3303 tcc_error("width of '%s' exceeds its type",
3304 get_tok_str(v, NULL));
3305 } else if (bit_size == bsize) {
3306 /* no need for bit fields */
3307 bit_pos = 0;
3308 } else if (bit_size == 0) {
3309 /* XXX: what to do if only padding in a
3310 structure ? */
3311 /* zero size: means to pad */
3312 bit_pos = 0;
3313 } else {
3314 /* if type change, union, or will overrun
3315 * allignment slot, start at a newly
3316 * alligned slot */
3317 if ((bit_pos + bit_size) > bsize ||
3318 bt != prevbt || a == TOK_UNION)
3319 bit_pos = 0;
3320 lbit_pos = bit_pos;
3321 /* XXX: handle LSB first */
3322 type1.t |= VT_BITFIELD |
3323 (bit_pos << VT_STRUCT_SHIFT) |
3324 (bit_size << (VT_STRUCT_SHIFT + 6));
3325 bit_pos += bit_size;
3326 /* without ms-bitfields, allocate the
3327 * minimum number of bytes necessary,
3328 * adding single bytes as needed */
3329 if (!tcc_state->ms_bitfields) {
3330 if (lbit_pos == 0)
3331 /* minimum bytes for new bitfield */
3332 size = (bit_size + 7) / 8;
3333 else {
3334 /* enough spare bits already allocated? */
3335 bit_size = (lbit_pos - 1) % 8 + 1 + bit_size;
3336 if (bit_size > 8) /* doesn't fit */
3337 extra_bytes = (bit_size - 1) / 8;
3341 prevbt = bt;
3342 } else {
3343 bit_pos = 0;
3345 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3346 /* add new memory data only if starting bit
3347 field or adding bytes to existing bit field */
3348 if (extra_bytes) c += extra_bytes;
3349 else if (lbit_pos == 0) {
3350 if (a == TOK_STRUCT) {
3351 c = (c + align - 1) & -align;
3352 offset = c;
3353 if (size > 0)
3354 c += size;
3355 } else {
3356 offset = 0;
3357 if (size > c)
3358 c = size;
3360 if (align > maxalign)
3361 maxalign = align;
3363 #if 0
3364 printf("add field %s offset=%d",
3365 get_tok_str(v, NULL), offset);
3366 if (type1.t & VT_BITFIELD) {
3367 printf(" pos=%d size=%d",
3368 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3369 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3371 printf("\n");
3372 #endif
3374 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3375 ass = type1.ref;
3376 while ((ass = ass->next) != NULL) {
3377 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3378 *ps = ss;
3379 ps = &ss->next;
3381 } else if (v) {
3382 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3383 *ps = ss;
3384 ps = &ss->next;
3386 if (tok == ';' || tok == TOK_EOF)
3387 break;
3388 skip(',');
3390 skip(';');
3392 skip('}');
3393 /* store size and alignment */
3394 s->c = (c + maxalign - 1) & -maxalign;
3395 s->r = maxalign;
3400 /* return 1 if basic type is a type size (short, long, long long) */
3401 ST_FUNC int is_btype_size(int bt)
3403 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3406 /* Add type qualifiers to a type. If the type is an array then the qualifiers
3407 are added to the element type, copied because it could be a typedef. */
3408 static void parse_btype_qualify(CType *type, int qualifiers)
3410 while (type->t & VT_ARRAY) {
3411 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
3412 type = &type->ref->type;
3414 type->t |= qualifiers;
3417 /* return 0 if no type declaration. otherwise, return the basic type
3418 and skip it.
3420 static int parse_btype(CType *type, AttributeDef *ad)
3422 int t, u, bt_size, complete, type_found, typespec_found;
3423 Sym *s;
3424 CType type1;
3426 memset(ad, 0, sizeof(AttributeDef));
3427 complete = 0;
3428 type_found = 0;
3429 typespec_found = 0;
3430 t = 0;
3431 while(1) {
3432 switch(tok) {
3433 case TOK_EXTENSION:
3434 /* currently, we really ignore extension */
3435 next();
3436 continue;
3438 /* basic types */
3439 case TOK_CHAR:
3440 u = VT_BYTE;
3441 basic_type:
3442 next();
3443 basic_type1:
3444 if (complete)
3445 tcc_error("too many basic types");
3446 t |= u;
3447 bt_size = is_btype_size (u & VT_BTYPE);
3448 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3449 complete = 1;
3450 typespec_found = 1;
3451 break;
3452 case TOK_VOID:
3453 u = VT_VOID;
3454 goto basic_type;
3455 case TOK_SHORT:
3456 u = VT_SHORT;
3457 goto basic_type;
3458 case TOK_INT:
3459 u = VT_INT;
3460 goto basic_type;
3461 case TOK_LONG:
3462 next();
3463 if ((t & VT_BTYPE) == VT_DOUBLE) {
3464 #ifndef TCC_TARGET_PE
3465 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3466 #endif
3467 } else if ((t & VT_BTYPE) == VT_LONG) {
3468 t = (t & ~VT_BTYPE) | VT_LLONG;
3469 } else {
3470 u = VT_LONG;
3471 goto basic_type1;
3473 break;
3474 #ifdef TCC_TARGET_ARM64
3475 case TOK_UINT128:
3476 /* GCC's __uint128_t appears in some Linux header files. Make it a
3477 synonym for long double to get the size and alignment right. */
3478 u = VT_LDOUBLE;
3479 goto basic_type;
3480 #endif
3481 case TOK_BOOL:
3482 u = VT_BOOL;
3483 goto basic_type;
3484 case TOK_FLOAT:
3485 u = VT_FLOAT;
3486 goto basic_type;
3487 case TOK_DOUBLE:
3488 next();
3489 if ((t & VT_BTYPE) == VT_LONG) {
3490 #ifdef TCC_TARGET_PE
3491 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3492 #else
3493 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3494 #endif
3495 } else {
3496 u = VT_DOUBLE;
3497 goto basic_type1;
3499 break;
3500 case TOK_ENUM:
3501 struct_decl(&type1, ad, VT_ENUM);
3502 basic_type2:
3503 u = type1.t;
3504 type->ref = type1.ref;
3505 goto basic_type1;
3506 case TOK_STRUCT:
3507 case TOK_UNION:
3508 struct_decl(&type1, ad, VT_STRUCT);
3509 goto basic_type2;
3511 /* type modifiers */
3512 case TOK_CONST1:
3513 case TOK_CONST2:
3514 case TOK_CONST3:
3515 type->t = t;
3516 parse_btype_qualify(type, VT_CONSTANT);
3517 t = type->t;
3518 next();
3519 break;
3520 case TOK_VOLATILE1:
3521 case TOK_VOLATILE2:
3522 case TOK_VOLATILE3:
3523 type->t = t;
3524 parse_btype_qualify(type, VT_VOLATILE);
3525 t = type->t;
3526 next();
3527 break;
3528 case TOK_SIGNED1:
3529 case TOK_SIGNED2:
3530 case TOK_SIGNED3:
3531 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3532 tcc_error("signed and unsigned modifier");
3533 typespec_found = 1;
3534 t |= VT_DEFSIGN;
3535 next();
3536 break;
3537 case TOK_REGISTER:
3538 case TOK_AUTO:
3539 case TOK_RESTRICT1:
3540 case TOK_RESTRICT2:
3541 case TOK_RESTRICT3:
3542 next();
3543 break;
3544 case TOK_UNSIGNED:
3545 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3546 tcc_error("signed and unsigned modifier");
3547 t |= VT_DEFSIGN | VT_UNSIGNED;
3548 next();
3549 typespec_found = 1;
3550 break;
3552 /* storage */
3553 case TOK_EXTERN:
3554 t |= VT_EXTERN;
3555 next();
3556 break;
3557 case TOK_STATIC:
3558 t |= VT_STATIC;
3559 next();
3560 break;
3561 case TOK_TYPEDEF:
3562 t |= VT_TYPEDEF;
3563 next();
3564 break;
3565 case TOK_INLINE1:
3566 case TOK_INLINE2:
3567 case TOK_INLINE3:
3568 t |= VT_INLINE;
3569 next();
3570 break;
3572 /* GNUC attribute */
3573 case TOK_ATTRIBUTE1:
3574 case TOK_ATTRIBUTE2:
3575 parse_attribute(ad);
3576 if (ad->a.mode) {
3577 u = ad->a.mode -1;
3578 t = (t & ~VT_BTYPE) | u;
3580 break;
3581 /* GNUC typeof */
3582 case TOK_TYPEOF1:
3583 case TOK_TYPEOF2:
3584 case TOK_TYPEOF3:
3585 next();
3586 parse_expr_type(&type1);
3587 /* remove all storage modifiers except typedef */
3588 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3589 goto basic_type2;
3590 default:
3591 if (typespec_found)
3592 goto the_end;
3593 s = sym_find(tok);
3594 if (!s || !(s->type.t & VT_TYPEDEF))
3595 goto the_end;
3597 type->t = ((s->type.t & ~VT_TYPEDEF) |
3598 (t & ~(VT_CONSTANT | VT_VOLATILE)));
3599 type->ref = s->type.ref;
3600 if (t & (VT_CONSTANT | VT_VOLATILE))
3601 parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE));
3602 t = type->t;
3604 if (s->r) {
3605 /* get attributes from typedef */
3606 if (0 == ad->a.aligned)
3607 ad->a.aligned = s->a.aligned;
3608 if (0 == ad->a.func_call)
3609 ad->a.func_call = s->a.func_call;
3610 ad->a.packed |= s->a.packed;
3612 next();
3613 typespec_found = 1;
3614 break;
3616 type_found = 1;
3618 the_end:
3619 if (tcc_state->char_is_unsigned) {
3620 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3621 t |= VT_UNSIGNED;
3624 /* long is never used as type */
3625 if ((t & VT_BTYPE) == VT_LONG)
3626 #if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \
3627 defined TCC_TARGET_PE
3628 t = (t & ~VT_BTYPE) | VT_INT;
3629 #else
3630 t = (t & ~VT_BTYPE) | VT_LLONG;
3631 #endif
3632 type->t = t;
3633 return type_found;
3636 /* convert a function parameter type (array to pointer and function to
3637 function pointer) */
3638 static inline void convert_parameter_type(CType *pt)
3640 /* remove const and volatile qualifiers (XXX: const could be used
3641 to indicate a const function parameter */
3642 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3643 /* array must be transformed to pointer according to ANSI C */
3644 pt->t &= ~VT_ARRAY;
3645 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3646 mk_pointer(pt);
3650 ST_FUNC void parse_asm_str(CString *astr)
3652 skip('(');
3653 /* read the string */
3654 if (tok != TOK_STR)
3655 expect("string constant");
3656 cstr_new(astr);
3657 while (tok == TOK_STR) {
3658 /* XXX: add \0 handling too ? */
3659 cstr_cat(astr, tokc.str.data, -1);
3660 next();
3662 cstr_ccat(astr, '\0');
3665 /* Parse an asm label and return the token */
3666 static int asm_label_instr(void)
3668 int v;
3669 CString astr;
3671 next();
3672 parse_asm_str(&astr);
3673 skip(')');
3674 #ifdef ASM_DEBUG
3675 printf("asm_alias: \"%s\"\n", (char *)astr.data);
3676 #endif
3677 v = tok_alloc(astr.data, astr.size - 1)->tok;
3678 cstr_free(&astr);
3679 return v;
3682 static void post_type(CType *type, AttributeDef *ad)
3684 int n, l, t1, arg_size, align;
3685 Sym **plast, *s, *first;
3686 AttributeDef ad1;
3687 CType pt;
3689 if (tok == '(') {
3690 /* function declaration */
3691 next();
3692 l = 0;
3693 first = NULL;
3694 plast = &first;
3695 arg_size = 0;
3696 if (tok != ')') {
3697 for(;;) {
3698 /* read param name and compute offset */
3699 if (l != FUNC_OLD) {
3700 if (!parse_btype(&pt, &ad1)) {
3701 if (l) {
3702 tcc_error("invalid type");
3703 } else {
3704 l = FUNC_OLD;
3705 goto old_proto;
3708 l = FUNC_NEW;
3709 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3710 break;
3711 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3712 if ((pt.t & VT_BTYPE) == VT_VOID)
3713 tcc_error("parameter declared as void");
3714 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3715 } else {
3716 old_proto:
3717 n = tok;
3718 if (n < TOK_UIDENT)
3719 expect("identifier");
3720 pt.t = VT_INT;
3721 next();
3723 convert_parameter_type(&pt);
3724 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3725 *plast = s;
3726 plast = &s->next;
3727 if (tok == ')')
3728 break;
3729 skip(',');
3730 if (l == FUNC_NEW && tok == TOK_DOTS) {
3731 l = FUNC_ELLIPSIS;
3732 next();
3733 break;
3737 /* if no parameters, then old type prototype */
3738 if (l == 0)
3739 l = FUNC_OLD;
3740 skip(')');
3741 /* NOTE: const is ignored in returned type as it has a special
3742 meaning in gcc / C++ */
3743 type->t &= ~VT_CONSTANT;
3744 /* some ancient pre-K&R C allows a function to return an array
3745 and the array brackets to be put after the arguments, such
3746 that "int c()[]" means something like "int[] c()" */
3747 if (tok == '[') {
3748 next();
3749 skip(']'); /* only handle simple "[]" */
3750 type->t |= VT_PTR;
3752 /* we push a anonymous symbol which will contain the function prototype */
3753 ad->a.func_args = arg_size;
3754 s = sym_push(SYM_FIELD, type, 0, l);
3755 s->a = ad->a;
3756 s->next = first;
3757 type->t = VT_FUNC;
3758 type->ref = s;
3759 } else if (tok == '[') {
3760 /* array definition */
3761 next();
3762 if (tok == TOK_RESTRICT1)
3763 next();
3764 n = -1;
3765 t1 = 0;
3766 if (tok != ']') {
3767 if (!local_stack || nocode_wanted)
3768 vpushi(expr_const());
3769 else gexpr();
3770 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3771 n = vtop->c.i;
3772 if (n < 0)
3773 tcc_error("invalid array size");
3774 } else {
3775 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3776 tcc_error("size of variable length array should be an integer");
3777 t1 = VT_VLA;
3780 skip(']');
3781 /* parse next post type */
3782 post_type(type, ad);
3783 if (type->t == VT_FUNC)
3784 tcc_error("declaration of an array of functions");
3785 t1 |= type->t & VT_VLA;
3787 if (t1 & VT_VLA) {
3788 loc -= type_size(&int_type, &align);
3789 loc &= -align;
3790 n = loc;
3792 vla_runtime_type_size(type, &align);
3793 gen_op('*');
3794 vset(&int_type, VT_LOCAL|VT_LVAL, n);
3795 vswap();
3796 vstore();
3798 if (n != -1)
3799 vpop();
3801 /* we push an anonymous symbol which will contain the array
3802 element type */
3803 s = sym_push(SYM_FIELD, type, 0, n);
3804 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3805 type->ref = s;
3809 /* Parse a type declaration (except basic type), and return the type
3810 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3811 expected. 'type' should contain the basic type. 'ad' is the
3812 attribute definition of the basic type. It can be modified by
3813 type_decl().
3815 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3817 Sym *s;
3818 CType type1, *type2;
3819 int qualifiers, storage;
3821 while (tok == '*') {
3822 qualifiers = 0;
3823 redo:
3824 next();
3825 switch(tok) {
3826 case TOK_CONST1:
3827 case TOK_CONST2:
3828 case TOK_CONST3:
3829 qualifiers |= VT_CONSTANT;
3830 goto redo;
3831 case TOK_VOLATILE1:
3832 case TOK_VOLATILE2:
3833 case TOK_VOLATILE3:
3834 qualifiers |= VT_VOLATILE;
3835 goto redo;
3836 case TOK_RESTRICT1:
3837 case TOK_RESTRICT2:
3838 case TOK_RESTRICT3:
3839 goto redo;
3841 mk_pointer(type);
3842 type->t |= qualifiers;
3845 /* XXX: clarify attribute handling */
3846 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3847 parse_attribute(ad);
3849 /* recursive type */
3850 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3851 type1.t = 0; /* XXX: same as int */
3852 if (tok == '(') {
3853 next();
3854 /* XXX: this is not correct to modify 'ad' at this point, but
3855 the syntax is not clear */
3856 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3857 parse_attribute(ad);
3858 type_decl(&type1, ad, v, td);
3859 skip(')');
3860 } else {
3861 /* type identifier */
3862 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3863 *v = tok;
3864 next();
3865 } else {
3866 if (!(td & TYPE_ABSTRACT))
3867 expect("identifier");
3868 *v = 0;
3871 storage = type->t & VT_STORAGE;
3872 type->t &= ~VT_STORAGE;
3873 if (storage & VT_STATIC) {
3874 int saved_nocode_wanted = nocode_wanted;
3875 nocode_wanted = 1;
3876 post_type(type, ad);
3877 nocode_wanted = saved_nocode_wanted;
3878 } else
3879 post_type(type, ad);
3880 type->t |= storage;
3881 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3882 parse_attribute(ad);
3884 if (!type1.t)
3885 return;
3886 /* append type at the end of type1 */
3887 type2 = &type1;
3888 for(;;) {
3889 s = type2->ref;
3890 type2 = &s->type;
3891 if (!type2->t) {
3892 *type2 = *type;
3893 break;
3896 *type = type1;
3899 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3900 ST_FUNC int lvalue_type(int t)
3902 int bt, r;
3903 r = VT_LVAL;
3904 bt = t & VT_BTYPE;
3905 if (bt == VT_BYTE || bt == VT_BOOL)
3906 r |= VT_LVAL_BYTE;
3907 else if (bt == VT_SHORT)
3908 r |= VT_LVAL_SHORT;
3909 else
3910 return r;
3911 if (t & VT_UNSIGNED)
3912 r |= VT_LVAL_UNSIGNED;
3913 return r;
3916 /* indirection with full error checking and bound check */
3917 ST_FUNC void indir(void)
3919 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3920 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3921 return;
3922 expect("pointer");
3924 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3925 gv(RC_INT);
3926 vtop->type = *pointed_type(&vtop->type);
3927 /* Arrays and functions are never lvalues */
3928 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3929 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3930 vtop->r |= lvalue_type(vtop->type.t);
3931 /* if bound checking, the referenced pointer must be checked */
3932 #ifdef CONFIG_TCC_BCHECK
3933 if (tcc_state->do_bounds_check)
3934 vtop->r |= VT_MUSTBOUND;
3935 #endif
3939 /* pass a parameter to a function and do type checking and casting */
3940 static void gfunc_param_typed(Sym *func, Sym *arg)
3942 int func_type;
3943 CType type;
3945 func_type = func->c;
3946 if (func_type == FUNC_OLD ||
3947 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3948 /* default casting : only need to convert float to double */
3949 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3950 type.t = VT_DOUBLE;
3951 gen_cast(&type);
3952 } else if (vtop->type.t & VT_BITFIELD) {
3953 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3954 gen_cast(&type);
3956 } else if (arg == NULL) {
3957 tcc_error("too many arguments to function");
3958 } else {
3959 type = arg->type;
3960 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3961 gen_assign_cast(&type);
3965 /* parse an expression of the form '(type)' or '(expr)' and return its
3966 type */
3967 static void parse_expr_type(CType *type)
3969 int n;
3970 AttributeDef ad;
3972 skip('(');
3973 if (parse_btype(type, &ad)) {
3974 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3975 } else {
3976 expr_type(type);
3978 skip(')');
3981 static void parse_type(CType *type)
3983 AttributeDef ad;
3984 int n;
3986 if (!parse_btype(type, &ad)) {
3987 expect("type");
3989 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3992 static void vpush_tokc(int t)
3994 CType type;
3995 type.t = t;
3996 type.ref = 0;
3997 vsetc(&type, VT_CONST, &tokc);
4000 ST_FUNC void unary(void)
4002 int n, t, align, size, r, sizeof_caller;
4003 CType type;
4004 Sym *s;
4005 AttributeDef ad;
4007 sizeof_caller = in_sizeof;
4008 in_sizeof = 0;
4009 /* XXX: GCC 2.95.3 does not generate a table although it should be
4010 better here */
4011 tok_next:
4012 switch(tok) {
4013 case TOK_EXTENSION:
4014 next();
4015 goto tok_next;
4016 case TOK_CINT:
4017 case TOK_CCHAR:
4018 case TOK_LCHAR:
4019 vpushi(tokc.i);
4020 next();
4021 break;
4022 case TOK_CUINT:
4023 vpush_tokc(VT_INT | VT_UNSIGNED);
4024 next();
4025 break;
4026 case TOK_CLLONG:
4027 vpush_tokc(VT_LLONG);
4028 next();
4029 break;
4030 case TOK_CULLONG:
4031 vpush_tokc(VT_LLONG | VT_UNSIGNED);
4032 next();
4033 break;
4034 case TOK_CFLOAT:
4035 vpush_tokc(VT_FLOAT);
4036 next();
4037 break;
4038 case TOK_CDOUBLE:
4039 vpush_tokc(VT_DOUBLE);
4040 next();
4041 break;
4042 case TOK_CLDOUBLE:
4043 vpush_tokc(VT_LDOUBLE);
4044 next();
4045 break;
4046 case TOK___FUNCTION__:
4047 if (!gnu_ext)
4048 goto tok_identifier;
4049 /* fall thru */
4050 case TOK___FUNC__:
4052 void *ptr;
4053 int len;
4054 /* special function name identifier */
4055 len = strlen(funcname) + 1;
4056 /* generate char[len] type */
4057 type.t = VT_BYTE;
4058 mk_pointer(&type);
4059 type.t |= VT_ARRAY;
4060 type.ref->c = len;
4061 vpush_ref(&type, data_section, data_section->data_offset, len);
4062 ptr = section_ptr_add(data_section, len);
4063 memcpy(ptr, funcname, len);
4064 next();
4066 break;
4067 case TOK_LSTR:
4068 #ifdef TCC_TARGET_PE
4069 t = VT_SHORT | VT_UNSIGNED;
4070 #else
4071 t = VT_INT;
4072 #endif
4073 goto str_init;
4074 case TOK_STR:
4075 /* string parsing */
4076 t = VT_BYTE;
4077 str_init:
4078 if (tcc_state->warn_write_strings)
4079 t |= VT_CONSTANT;
4080 type.t = t;
4081 mk_pointer(&type);
4082 type.t |= VT_ARRAY;
4083 memset(&ad, 0, sizeof(AttributeDef));
4084 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
4085 break;
4086 case '(':
4087 next();
4088 /* cast ? */
4089 if (parse_btype(&type, &ad)) {
4090 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
4091 skip(')');
4092 /* check ISOC99 compound literal */
4093 if (tok == '{') {
4094 /* data is allocated locally by default */
4095 if (global_expr)
4096 r = VT_CONST;
4097 else
4098 r = VT_LOCAL;
4099 /* all except arrays are lvalues */
4100 if (!(type.t & VT_ARRAY))
4101 r |= lvalue_type(type.t);
4102 memset(&ad, 0, sizeof(AttributeDef));
4103 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
4104 } else {
4105 if (sizeof_caller) {
4106 vpush(&type);
4107 return;
4109 unary();
4110 gen_cast(&type);
4112 } else if (tok == '{') {
4113 if (const_wanted)
4114 tcc_error("expected constant");
4115 /* save all registers */
4116 if (!nocode_wanted)
4117 save_regs(0);
4118 /* statement expression : we do not accept break/continue
4119 inside as GCC does */
4120 block(NULL, NULL, 1);
4121 skip(')');
4122 } else {
4123 gexpr();
4124 skip(')');
4126 break;
4127 case '*':
4128 next();
4129 unary();
4130 indir();
4131 break;
4132 case '&':
4133 next();
4134 unary();
4135 /* functions names must be treated as function pointers,
4136 except for unary '&' and sizeof. Since we consider that
4137 functions are not lvalues, we only have to handle it
4138 there and in function calls. */
4139 /* arrays can also be used although they are not lvalues */
4140 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
4141 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
4142 test_lvalue();
4143 mk_pointer(&vtop->type);
4144 gaddrof();
4145 break;
4146 case '!':
4147 next();
4148 unary();
4149 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4150 CType boolean;
4151 boolean.t = VT_BOOL;
4152 gen_cast(&boolean);
4153 vtop->c.i = !vtop->c.i;
4154 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
4155 vtop->c.i ^= 1;
4156 else {
4157 save_regs(1);
4158 vseti(VT_JMP, gvtst(1, 0));
4160 break;
4161 case '~':
4162 next();
4163 unary();
4164 vpushi(-1);
4165 gen_op('^');
4166 break;
4167 case '+':
4168 next();
4169 unary();
4170 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
4171 tcc_error("pointer not accepted for unary plus");
4172 /* In order to force cast, we add zero, except for floating point
4173 where we really need an noop (otherwise -0.0 will be transformed
4174 into +0.0). */
4175 if (!is_float(vtop->type.t)) {
4176 vpushi(0);
4177 gen_op('+');
4179 break;
4180 case TOK_SIZEOF:
4181 case TOK_ALIGNOF1:
4182 case TOK_ALIGNOF2:
4183 t = tok;
4184 next();
4185 in_sizeof++;
4186 unary_type(&type); // Perform a in_sizeof = 0;
4187 size = type_size(&type, &align);
4188 if (t == TOK_SIZEOF) {
4189 if (!(type.t & VT_VLA)) {
4190 if (size < 0)
4191 tcc_error("sizeof applied to an incomplete type");
4192 vpushs(size);
4193 } else {
4194 vla_runtime_type_size(&type, &align);
4196 } else {
4197 vpushs(align);
4199 vtop->type.t |= VT_UNSIGNED;
4200 break;
4202 case TOK_builtin_expect:
4204 /* __builtin_expect is a no-op for now */
4205 int saved_nocode_wanted;
4206 next();
4207 skip('(');
4208 expr_eq();
4209 skip(',');
4210 saved_nocode_wanted = nocode_wanted;
4211 nocode_wanted = 1;
4212 expr_lor_const();
4213 vpop();
4214 nocode_wanted = saved_nocode_wanted;
4215 skip(')');
4217 break;
4218 case TOK_builtin_types_compatible_p:
4220 CType type1, type2;
4221 next();
4222 skip('(');
4223 parse_type(&type1);
4224 skip(',');
4225 parse_type(&type2);
4226 skip(')');
4227 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
4228 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
4229 vpushi(is_compatible_types(&type1, &type2));
4231 break;
4232 case TOK_builtin_constant_p:
4234 int saved_nocode_wanted, res;
4235 next();
4236 skip('(');
4237 saved_nocode_wanted = nocode_wanted;
4238 nocode_wanted = 1;
4239 gexpr();
4240 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4241 vpop();
4242 nocode_wanted = saved_nocode_wanted;
4243 skip(')');
4244 vpushi(res);
4246 break;
4247 case TOK_builtin_frame_address:
4248 case TOK_builtin_return_address:
4250 int tok1 = tok;
4251 int level;
4252 CType type;
4253 next();
4254 skip('(');
4255 if (tok != TOK_CINT) {
4256 tcc_error("%s only takes positive integers",
4257 tok1 == TOK_builtin_return_address ?
4258 "__builtin_return_address" :
4259 "__builtin_frame_address");
4261 level = (uint32_t)tokc.i;
4262 next();
4263 skip(')');
4264 type.t = VT_VOID;
4265 mk_pointer(&type);
4266 vset(&type, VT_LOCAL, 0); /* local frame */
4267 while (level--) {
4268 mk_pointer(&vtop->type);
4269 indir(); /* -> parent frame */
4271 if (tok1 == TOK_builtin_return_address) {
4272 // assume return address is just above frame pointer on stack
4273 vpushi(PTR_SIZE);
4274 gen_op('+');
4275 mk_pointer(&vtop->type);
4276 indir();
4279 break;
4280 #ifdef TCC_TARGET_X86_64
4281 #ifdef TCC_TARGET_PE
4282 case TOK_builtin_va_start:
4284 next();
4285 skip('(');
4286 expr_eq();
4287 skip(',');
4288 expr_eq();
4289 skip(')');
4290 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
4291 tcc_error("__builtin_va_start expects a local variable");
4292 vtop->r &= ~(VT_LVAL | VT_REF);
4293 vtop->type = char_pointer_type;
4294 vtop->c.i += 8;
4295 vstore();
4297 break;
4298 #else
4299 case TOK_builtin_va_arg_types:
4301 CType type;
4302 next();
4303 skip('(');
4304 parse_type(&type);
4305 skip(')');
4306 vpushi(classify_x86_64_va_arg(&type));
4308 break;
4309 #endif
4310 #endif
4312 #ifdef TCC_TARGET_ARM64
4313 case TOK___va_start: {
4314 if (nocode_wanted)
4315 tcc_error("statement in global scope");
4316 next();
4317 skip('(');
4318 expr_eq();
4319 skip(',');
4320 expr_eq();
4321 skip(')');
4322 //xx check types
4323 gen_va_start();
4324 vpushi(0);
4325 vtop->type.t = VT_VOID;
4326 break;
4328 case TOK___va_arg: {
4329 CType type;
4330 if (nocode_wanted)
4331 tcc_error("statement in global scope");
4332 next();
4333 skip('(');
4334 expr_eq();
4335 skip(',');
4336 parse_type(&type);
4337 skip(')');
4338 //xx check types
4339 gen_va_arg(&type);
4340 vtop->type = type;
4341 break;
4343 case TOK___arm64_clear_cache: {
4344 next();
4345 skip('(');
4346 expr_eq();
4347 skip(',');
4348 expr_eq();
4349 skip(')');
4350 gen_clear_cache();
4351 vpushi(0);
4352 vtop->type.t = VT_VOID;
4353 break;
4355 #endif
4356 /* pre operations */
4357 case TOK_INC:
4358 case TOK_DEC:
4359 t = tok;
4360 next();
4361 unary();
4362 inc(0, t);
4363 break;
4364 case '-':
4365 next();
4366 unary();
4367 t = vtop->type.t & VT_BTYPE;
4368 if (is_float(t)) {
4369 /* In IEEE negate(x) isn't subtract(0,x), but rather
4370 subtract(-0, x). */
4371 vpush(&vtop->type);
4372 if (t == VT_FLOAT)
4373 vtop->c.f = -0.0f;
4374 else if (t == VT_DOUBLE)
4375 vtop->c.d = -0.0;
4376 else
4377 vtop->c.ld = -0.0;
4378 } else
4379 vpushi(0);
4380 vswap();
4381 gen_op('-');
4382 break;
4383 case TOK_LAND:
4384 if (!gnu_ext)
4385 goto tok_identifier;
4386 next();
4387 /* allow to take the address of a label */
4388 if (tok < TOK_UIDENT)
4389 expect("label identifier");
4390 s = label_find(tok);
4391 if (!s) {
4392 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4393 } else {
4394 if (s->r == LABEL_DECLARED)
4395 s->r = LABEL_FORWARD;
4397 if (!s->type.t) {
4398 s->type.t = VT_VOID;
4399 mk_pointer(&s->type);
4400 s->type.t |= VT_STATIC;
4402 vpushsym(&s->type, s);
4403 next();
4404 break;
4406 // special qnan , snan and infinity values
4407 case TOK___NAN__:
4408 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
4409 next();
4410 break;
4411 case TOK___SNAN__:
4412 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
4413 next();
4414 break;
4415 case TOK___INF__:
4416 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
4417 next();
4418 break;
4420 default:
4421 tok_identifier:
4422 t = tok;
4423 next();
4424 if (t < TOK_UIDENT)
4425 expect("identifier");
4426 s = sym_find(t);
4427 if (!s) {
4428 const char *name = get_tok_str(t, NULL);
4429 if (tok != '(')
4430 tcc_error("'%s' undeclared", name);
4431 /* for simple function calls, we tolerate undeclared
4432 external reference to int() function */
4433 if (tcc_state->warn_implicit_function_declaration
4434 #ifdef TCC_TARGET_PE
4435 /* people must be warned about using undeclared WINAPI functions
4436 (which usually start with uppercase letter) */
4437 || (name[0] >= 'A' && name[0] <= 'Z')
4438 #endif
4440 tcc_warning("implicit declaration of function '%s'", name);
4441 s = external_global_sym(t, &func_old_type, 0);
4443 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
4444 (VT_STATIC | VT_INLINE | VT_FUNC)) {
4445 /* if referencing an inline function, then we generate a
4446 symbol to it if not already done. It will have the
4447 effect to generate code for it at the end of the
4448 compilation unit. Inline function as always
4449 generated in the text section. */
4450 if (!s->c)
4451 put_extern_sym(s, text_section, 0, 0);
4452 r = VT_SYM | VT_CONST;
4453 } else {
4454 r = s->r;
4456 vset(&s->type, r, s->c);
4457 /* if forward reference, we must point to s */
4458 if (vtop->r & VT_SYM) {
4459 vtop->sym = s;
4460 vtop->c.i = 0;
4462 break;
4465 /* post operations */
4466 while (1) {
4467 if (tok == TOK_INC || tok == TOK_DEC) {
4468 inc(1, tok);
4469 next();
4470 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
4471 int qualifiers;
4472 /* field */
4473 if (tok == TOK_ARROW)
4474 indir();
4475 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4476 test_lvalue();
4477 gaddrof();
4478 /* expect pointer on structure */
4479 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4480 expect("struct or union");
4481 if (tok == TOK_CDOUBLE)
4482 expect("field name");
4483 next();
4484 if (tok == TOK_CINT || tok == TOK_CUINT)
4485 expect("field name");
4486 s = vtop->type.ref;
4487 /* find field */
4488 tok |= SYM_FIELD;
4489 while ((s = s->next) != NULL) {
4490 if (s->v == tok)
4491 break;
4493 if (!s)
4494 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
4495 /* add field offset to pointer */
4496 vtop->type = char_pointer_type; /* change type to 'char *' */
4497 vpushi(s->c);
4498 gen_op('+');
4499 /* change type to field type, and set to lvalue */
4500 vtop->type = s->type;
4501 vtop->type.t |= qualifiers;
4502 /* an array is never an lvalue */
4503 if (!(vtop->type.t & VT_ARRAY)) {
4504 vtop->r |= lvalue_type(vtop->type.t);
4505 #ifdef CONFIG_TCC_BCHECK
4506 /* if bound checking, the referenced pointer must be checked */
4507 if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL)
4508 vtop->r |= VT_MUSTBOUND;
4509 #endif
4511 next();
4512 } else if (tok == '[') {
4513 next();
4514 gexpr();
4515 gen_op('+');
4516 indir();
4517 skip(']');
4518 } else if (tok == '(') {
4519 SValue ret;
4520 Sym *sa;
4521 int nb_args, ret_nregs, ret_align, regsize, variadic;
4523 /* function call */
4524 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4525 /* pointer test (no array accepted) */
4526 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4527 vtop->type = *pointed_type(&vtop->type);
4528 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4529 goto error_func;
4530 } else {
4531 error_func:
4532 expect("function pointer");
4534 } else {
4535 vtop->r &= ~VT_LVAL; /* no lvalue */
4537 /* get return type */
4538 s = vtop->type.ref;
4539 next();
4540 sa = s->next; /* first parameter */
4541 nb_args = 0;
4542 ret.r2 = VT_CONST;
4543 /* compute first implicit argument if a structure is returned */
4544 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4545 variadic = (s->c == FUNC_ELLIPSIS);
4546 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4547 &ret_align, &regsize);
4548 if (!ret_nregs) {
4549 /* get some space for the returned structure */
4550 size = type_size(&s->type, &align);
4551 #ifdef TCC_TARGET_ARM64
4552 /* On arm64, a small struct is return in registers.
4553 It is much easier to write it to memory if we know
4554 that we are allowed to write some extra bytes, so
4555 round the allocated space up to a power of 2: */
4556 if (size < 16)
4557 while (size & (size - 1))
4558 size = (size | (size - 1)) + 1;
4559 #endif
4560 loc = (loc - size) & -align;
4561 ret.type = s->type;
4562 ret.r = VT_LOCAL | VT_LVAL;
4563 /* pass it as 'int' to avoid structure arg passing
4564 problems */
4565 vseti(VT_LOCAL, loc);
4566 ret.c = vtop->c;
4567 nb_args++;
4569 } else {
4570 ret_nregs = 1;
4571 ret.type = s->type;
4574 if (ret_nregs) {
4575 /* return in register */
4576 if (is_float(ret.type.t)) {
4577 ret.r = reg_fret(ret.type.t);
4578 #ifdef TCC_TARGET_X86_64
4579 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4580 ret.r2 = REG_QRET;
4581 #endif
4582 } else {
4583 #ifndef TCC_TARGET_ARM64
4584 #ifdef TCC_TARGET_X86_64
4585 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4586 #else
4587 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4588 #endif
4589 ret.r2 = REG_LRET;
4590 #endif
4591 ret.r = REG_IRET;
4593 ret.c.i = 0;
4595 if (tok != ')') {
4596 for(;;) {
4597 expr_eq();
4598 gfunc_param_typed(s, sa);
4599 nb_args++;
4600 if (sa)
4601 sa = sa->next;
4602 if (tok == ')')
4603 break;
4604 skip(',');
4607 if (sa)
4608 tcc_error("too few arguments to function");
4609 skip(')');
4610 if (!nocode_wanted) {
4611 gfunc_call(nb_args);
4612 } else {
4613 vtop -= (nb_args + 1);
4616 /* return value */
4617 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4618 vsetc(&ret.type, r, &ret.c);
4619 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4622 /* handle packed struct return */
4623 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4624 int addr, offset;
4626 size = type_size(&s->type, &align);
4627 /* We're writing whole regs often, make sure there's enough
4628 space. Assume register size is power of 2. */
4629 if (regsize > align)
4630 align = regsize;
4631 loc = (loc - size) & -align;
4632 addr = loc;
4633 offset = 0;
4634 for (;;) {
4635 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4636 vswap();
4637 vstore();
4638 vtop--;
4639 if (--ret_nregs == 0)
4640 break;
4641 offset += regsize;
4643 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4645 } else {
4646 break;
4651 ST_FUNC void expr_prod(void)
4653 int t;
4655 unary();
4656 while (tok == '*' || tok == '/' || tok == '%') {
4657 t = tok;
4658 next();
4659 unary();
4660 gen_op(t);
4664 ST_FUNC void expr_sum(void)
4666 int t;
4668 expr_prod();
4669 while (tok == '+' || tok == '-') {
4670 t = tok;
4671 next();
4672 expr_prod();
4673 gen_op(t);
4677 static void expr_shift(void)
4679 int t;
4681 expr_sum();
4682 while (tok == TOK_SHL || tok == TOK_SAR) {
4683 t = tok;
4684 next();
4685 expr_sum();
4686 gen_op(t);
4690 static void expr_cmp(void)
4692 int t;
4694 expr_shift();
4695 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4696 tok == TOK_ULT || tok == TOK_UGE) {
4697 t = tok;
4698 next();
4699 expr_shift();
4700 gen_op(t);
4704 static void expr_cmpeq(void)
4706 int t;
4708 expr_cmp();
4709 while (tok == TOK_EQ || tok == TOK_NE) {
4710 t = tok;
4711 next();
4712 expr_cmp();
4713 gen_op(t);
4717 static void expr_and(void)
4719 expr_cmpeq();
4720 while (tok == '&') {
4721 next();
4722 expr_cmpeq();
4723 gen_op('&');
4727 static void expr_xor(void)
4729 expr_and();
4730 while (tok == '^') {
4731 next();
4732 expr_and();
4733 gen_op('^');
4737 static void expr_or(void)
4739 expr_xor();
4740 while (tok == '|') {
4741 next();
4742 expr_xor();
4743 gen_op('|');
4747 /* XXX: fix this mess */
4748 static void expr_land_const(void)
4750 expr_or();
4751 while (tok == TOK_LAND) {
4752 next();
4753 expr_or();
4754 gen_op(TOK_LAND);
4757 static void expr_lor_const(void)
4759 expr_land_const();
4760 while (tok == TOK_LOR) {
4761 next();
4762 expr_land_const();
4763 gen_op(TOK_LOR);
4767 static void expr_land(void)
4769 expr_or();
4770 if (tok == TOK_LAND) {
4771 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4772 CType ctb, cti;
4773 ctb.t = VT_BOOL;
4774 cti.t = VT_INT;
4775 next();
4776 gen_cast(&ctb);
4777 if (vtop->c.i) {
4778 vpop();
4779 expr_land();
4780 gen_cast(&ctb);
4781 } else {
4782 int saved_nocode_wanted = nocode_wanted;
4783 nocode_wanted = 1;
4784 expr_land();
4785 vpop();
4786 nocode_wanted = saved_nocode_wanted;
4788 gen_cast(&cti);
4789 } else {
4790 int t = 0;
4791 save_regs(1);
4792 for(;;) {
4793 t = gvtst(1, t);
4794 if (tok != TOK_LAND) {
4795 vseti(VT_JMPI, t);
4796 break;
4798 next();
4799 expr_or();
4805 static void expr_lor(void)
4807 expr_land();
4808 if (tok == TOK_LOR) {
4809 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4810 CType ctb, cti;
4811 ctb.t = VT_BOOL;
4812 cti.t = VT_INT;
4813 next();
4814 gen_cast(&ctb);
4815 if (vtop->c.i) {
4816 int saved_nocode_wanted = nocode_wanted;
4817 nocode_wanted = 1;
4818 expr_lor();
4819 vpop();
4820 nocode_wanted = saved_nocode_wanted;
4821 } else {
4822 vpop();
4823 expr_lor();
4824 gen_cast(&ctb);
4826 gen_cast(&cti);
4827 } else {
4828 int t = 0;
4829 save_regs(1);
4830 for(;;) {
4831 t = gvtst(0, t);
4832 if (tok != TOK_LOR) {
4833 vseti(VT_JMP, t);
4834 break;
4836 next();
4837 expr_land();
4843 static void expr_cond(void)
4845 int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv;
4846 SValue sv;
4847 CType type, type1, type2;
4849 expr_lor();
4850 if (tok == '?') {
4851 next();
4852 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4853 int saved_nocode_wanted = nocode_wanted;
4854 CType boolean;
4855 int c;
4856 boolean.t = VT_BOOL;
4857 vdup();
4858 gen_cast(&boolean);
4859 c = vtop->c.i;
4860 vpop();
4861 if (c) {
4862 if (tok != ':' || !gnu_ext) {
4863 vpop();
4864 gexpr();
4866 skip(':');
4867 nocode_wanted = 1;
4868 expr_cond();
4869 vpop();
4870 nocode_wanted = saved_nocode_wanted;
4871 } else {
4872 vpop();
4873 if (tok != ':' || !gnu_ext) {
4874 nocode_wanted = 1;
4875 gexpr();
4876 vpop();
4877 nocode_wanted = saved_nocode_wanted;
4879 skip(':');
4880 expr_cond();
4883 else {
4884 if (vtop != vstack) {
4885 /* needed to avoid having different registers saved in
4886 each branch */
4887 if (is_float(vtop->type.t)) {
4888 rc = RC_FLOAT;
4889 #ifdef TCC_TARGET_X86_64
4890 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4891 rc = RC_ST0;
4893 #endif
4895 else
4896 rc = RC_INT;
4897 gv(rc);
4898 save_regs(1);
4900 if (tok == ':' && gnu_ext) {
4901 gv_dup();
4902 tt = gvtst(1, 0);
4903 } else {
4904 tt = gvtst(1, 0);
4905 gexpr();
4907 type1 = vtop->type;
4908 sv = *vtop; /* save value to handle it later */
4909 vtop--; /* no vpop so that FP stack is not flushed */
4910 skip(':');
4911 u = gjmp(0);
4912 gsym(tt);
4913 expr_cond();
4914 type2 = vtop->type;
4916 t1 = type1.t;
4917 bt1 = t1 & VT_BTYPE;
4918 t2 = type2.t;
4919 bt2 = t2 & VT_BTYPE;
4920 /* cast operands to correct type according to ISOC rules */
4921 if (is_float(bt1) || is_float(bt2)) {
4922 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4923 type.t = VT_LDOUBLE;
4924 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4925 type.t = VT_DOUBLE;
4926 } else {
4927 type.t = VT_FLOAT;
4929 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4930 /* cast to biggest op */
4931 type.t = VT_LLONG;
4932 /* convert to unsigned if it does not fit in a long long */
4933 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4934 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4935 type.t |= VT_UNSIGNED;
4936 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4937 /* If one is a null ptr constant the result type
4938 is the other. */
4939 if (is_null_pointer (vtop))
4940 type = type1;
4941 else if (is_null_pointer (&sv))
4942 type = type2;
4943 /* XXX: test pointer compatibility, C99 has more elaborate
4944 rules here. */
4945 else
4946 type = type1;
4947 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4948 /* XXX: test function pointer compatibility */
4949 type = bt1 == VT_FUNC ? type1 : type2;
4950 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4951 /* XXX: test structure compatibility */
4952 type = bt1 == VT_STRUCT ? type1 : type2;
4953 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4954 /* NOTE: as an extension, we accept void on only one side */
4955 type.t = VT_VOID;
4956 } else {
4957 /* integer operations */
4958 type.t = VT_INT;
4959 /* convert to unsigned if it does not fit in an integer */
4960 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4961 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4962 type.t |= VT_UNSIGNED;
4964 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
4965 that `(expr ? a : b).mem` does not error with "lvalue expected" */
4966 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
4968 /* now we convert second operand */
4969 gen_cast(&type);
4970 if (islv) {
4971 mk_pointer(&vtop->type);
4972 gaddrof();
4974 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4975 gaddrof();
4976 rc = RC_INT;
4977 if (is_float(type.t)) {
4978 rc = RC_FLOAT;
4979 #ifdef TCC_TARGET_X86_64
4980 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4981 rc = RC_ST0;
4983 #endif
4984 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4985 /* for long longs, we use fixed registers to avoid having
4986 to handle a complicated move */
4987 rc = RC_IRET;
4990 r2 = gv(rc);
4991 /* this is horrible, but we must also convert first
4992 operand */
4993 tt = gjmp(0);
4994 gsym(u);
4995 /* put again first value and cast it */
4996 *vtop = sv;
4997 gen_cast(&type);
4998 if (islv) {
4999 mk_pointer(&vtop->type);
5000 gaddrof();
5002 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
5003 gaddrof();
5004 r1 = gv(rc);
5005 move_reg(r2, r1, type.t);
5006 vtop->r = r2;
5007 gsym(tt);
5008 if (islv)
5009 indir();
5014 static void expr_eq(void)
5016 int t;
5018 expr_cond();
5019 if (tok == '=' ||
5020 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5021 tok == TOK_A_XOR || tok == TOK_A_OR ||
5022 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5023 test_lvalue();
5024 t = tok;
5025 next();
5026 if (t == '=') {
5027 expr_eq();
5028 } else {
5029 vdup();
5030 expr_eq();
5031 gen_op(t & 0x7f);
5033 vstore();
5037 ST_FUNC void gexpr(void)
5039 while (1) {
5040 expr_eq();
5041 if (tok != ',')
5042 break;
5043 vpop();
5044 next();
5048 /* parse an expression and return its type without any side effect. */
5049 static void expr_type(CType *type)
5051 int saved_nocode_wanted;
5053 saved_nocode_wanted = nocode_wanted;
5054 nocode_wanted = 1;
5055 gexpr();
5056 *type = vtop->type;
5057 vpop();
5058 nocode_wanted = saved_nocode_wanted;
5061 /* parse a unary expression and return its type without any side
5062 effect. */
5063 static void unary_type(CType *type)
5065 int a;
5067 a = nocode_wanted;
5068 nocode_wanted = 1;
5069 unary();
5070 *type = vtop->type;
5071 vpop();
5072 nocode_wanted = a;
5075 /* parse a constant expression and return value in vtop. */
5076 static void expr_const1(void)
5078 int a;
5079 a = const_wanted;
5080 const_wanted = 1;
5081 expr_cond();
5082 const_wanted = a;
5085 /* parse an integer constant and return its value. */
5086 ST_FUNC int expr_const(void)
5088 int c;
5089 expr_const1();
5090 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5091 expect("constant expression");
5092 c = vtop->c.i;
5093 vpop();
5094 return c;
5097 /* return the label token if current token is a label, otherwise
5098 return zero */
5099 static int is_label(void)
5101 int last_tok;
5103 /* fast test first */
5104 if (tok < TOK_UIDENT)
5105 return 0;
5106 /* no need to save tokc because tok is an identifier */
5107 last_tok = tok;
5108 next();
5109 if (tok == ':') {
5110 next();
5111 return last_tok;
5112 } else {
5113 unget_tok(last_tok);
5114 return 0;
5118 static void label_or_decl(int l)
5120 int last_tok;
5122 /* fast test first */
5123 if (tok >= TOK_UIDENT)
5125 /* no need to save tokc because tok is an identifier */
5126 last_tok = tok;
5127 next();
5128 if (tok == ':') {
5129 unget_tok(last_tok);
5130 return;
5132 unget_tok(last_tok);
5134 decl(l);
5137 static int case_cmp(const void *pa, const void *pb)
5139 int a = (*(struct case_t**) pa)->v1;
5140 int b = (*(struct case_t**) pb)->v1;
5141 return a < b ? -1 : a > b;
5144 static int gcase(struct case_t **base, int len, int case_reg, int *bsym)
5146 struct case_t *p;
5147 int e;
5148 while (len > 4) {
5149 /* binary search */
5150 p = base[len/2];
5151 vseti(case_reg, 0);
5152 vdup();
5153 vpushi(p->v2);
5154 gen_op(TOK_LE);
5155 e = gtst(1, 0);
5156 case_reg = gv(RC_INT);
5157 vpop();
5158 vseti(case_reg, 0);
5159 vdup();
5160 vpushi(p->v1);
5161 gen_op(TOK_GE);
5162 gtst_addr(0, p->sym); /* v1 <= x <= v2 */
5163 case_reg = gv(RC_INT);
5164 vpop();
5165 /* x < v1 */
5166 case_reg = gcase(base, len/2, case_reg, bsym);
5167 if (cur_switch->def_sym)
5168 gjmp_addr(cur_switch->def_sym);
5169 else
5170 *bsym = gjmp(*bsym);
5171 /* x > v2 */
5172 gsym(e);
5173 e = len/2 + 1;
5174 base += e; len -= e;
5176 /* linear scan */
5177 while (len--) {
5178 p = *base++;
5179 vseti(case_reg, 0);
5180 vdup();
5181 vpushi(p->v2);
5182 if (p->v1 == p->v2) {
5183 gen_op(TOK_EQ);
5184 gtst_addr(0, p->sym);
5185 } else {
5186 gen_op(TOK_LE);
5187 e = gtst(1, 0);
5188 case_reg = gv(RC_INT);
5189 vpop();
5190 vseti(case_reg, 0);
5191 vdup();
5192 vpushi(p->v1);
5193 gen_op(TOK_GE);
5194 gtst_addr(0, p->sym);
5195 gsym(e);
5197 case_reg = gv(RC_INT);
5198 vpop();
5200 return case_reg;
5203 static void block(int *bsym, int *csym, int is_expr)
5205 int a, b, c, d;
5206 Sym *s;
5208 /* generate line number info */
5209 if (tcc_state->do_debug &&
5210 (last_line_num != file->line_num || last_ind != ind)) {
5211 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5212 last_ind = ind;
5213 last_line_num = file->line_num;
5216 if (is_expr) {
5217 /* default return value is (void) */
5218 vpushi(0);
5219 vtop->type.t = VT_VOID;
5222 if (tok == TOK_IF) {
5223 /* if test */
5224 next();
5225 skip('(');
5226 gexpr();
5227 skip(')');
5228 a = gvtst(1, 0);
5229 block(bsym, csym, 0);
5230 c = tok;
5231 if (c == TOK_ELSE) {
5232 next();
5233 d = gjmp(0);
5234 gsym(a);
5235 block(bsym, csym, 0);
5236 gsym(d); /* patch else jmp */
5237 } else
5238 gsym(a);
5239 } else if (tok == TOK_WHILE) {
5240 next();
5241 d = ind;
5242 vla_sp_restore();
5243 skip('(');
5244 gexpr();
5245 skip(')');
5246 a = gvtst(1, 0);
5247 b = 0;
5248 ++local_scope;
5249 block(&a, &b, 0);
5250 --local_scope;
5251 if(!nocode_wanted)
5252 gjmp_addr(d);
5253 gsym(a);
5254 gsym_addr(b, d);
5255 } else if (tok == '{') {
5256 Sym *llabel;
5257 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
5259 next();
5260 /* record local declaration stack position */
5261 s = local_stack;
5262 llabel = local_label_stack;
5263 ++local_scope;
5265 /* handle local labels declarations */
5266 if (tok == TOK_LABEL) {
5267 next();
5268 for(;;) {
5269 if (tok < TOK_UIDENT)
5270 expect("label identifier");
5271 label_push(&local_label_stack, tok, LABEL_DECLARED);
5272 next();
5273 if (tok == ',') {
5274 next();
5275 } else {
5276 skip(';');
5277 break;
5281 while (tok != '}') {
5282 label_or_decl(VT_LOCAL);
5283 if (tok != '}') {
5284 if (is_expr)
5285 vpop();
5286 block(bsym, csym, is_expr);
5289 /* pop locally defined labels */
5290 label_pop(&local_label_stack, llabel);
5291 if(is_expr) {
5292 /* XXX: this solution makes only valgrind happy...
5293 triggered by gcc.c-torture/execute/20000917-1.c */
5294 Sym *p;
5295 switch(vtop->type.t & VT_BTYPE) {
5296 /* case VT_PTR: */
5297 /* this breaks a compilation of the linux kernel v2.4.26 */
5298 /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
5299 /* Look a commit a80acab: Display error on statement expressions with complex return type */
5300 /* A pointer is not a complex return type */
5301 case VT_STRUCT:
5302 case VT_ENUM:
5303 case VT_FUNC:
5304 for(p=vtop->type.ref;p;p=p->prev)
5305 if(p->prev==s)
5306 tcc_error("unsupported expression type");
5309 /* pop locally defined symbols */
5310 --local_scope;
5311 sym_pop(&local_stack, s);
5313 /* Pop VLA frames and restore stack pointer if required */
5314 if (vlas_in_scope > saved_vlas_in_scope) {
5315 vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
5316 vla_sp_restore();
5318 vlas_in_scope = saved_vlas_in_scope;
5320 next();
5321 } else if (tok == TOK_RETURN) {
5322 next();
5323 if (tok != ';') {
5324 gexpr();
5325 gen_assign_cast(&func_vt);
5326 #ifdef TCC_TARGET_ARM64
5327 // Perhaps it would be better to use this for all backends:
5328 greturn();
5329 #else
5330 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
5331 CType type, ret_type;
5332 int ret_align, ret_nregs, regsize;
5333 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
5334 &ret_align, &regsize);
5335 if (0 == ret_nregs) {
5336 /* if returning structure, must copy it to implicit
5337 first pointer arg location */
5338 type = func_vt;
5339 mk_pointer(&type);
5340 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
5341 indir();
5342 vswap();
5343 /* copy structure value to pointer */
5344 vstore();
5345 } else {
5346 /* returning structure packed into registers */
5347 int r, size, addr, align;
5348 size = type_size(&func_vt,&align);
5349 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
5350 (vtop->c.i & (ret_align-1)))
5351 && (align & (ret_align-1))) {
5352 loc = (loc - size) & -ret_align;
5353 addr = loc;
5354 type = func_vt;
5355 vset(&type, VT_LOCAL | VT_LVAL, addr);
5356 vswap();
5357 vstore();
5358 vpop();
5359 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
5361 vtop->type = ret_type;
5362 if (is_float(ret_type.t))
5363 r = rc_fret(ret_type.t);
5364 else
5365 r = RC_IRET;
5367 if (ret_nregs == 1)
5368 gv(r);
5369 else {
5370 for (;;) {
5371 vdup();
5372 gv(r);
5373 vpop();
5374 if (--ret_nregs == 0)
5375 break;
5376 /* We assume that when a structure is returned in multiple
5377 registers, their classes are consecutive values of the
5378 suite s(n) = 2^n */
5379 r <<= 1;
5380 vtop->c.i += regsize;
5384 } else if (is_float(func_vt.t)) {
5385 gv(rc_fret(func_vt.t));
5386 } else {
5387 gv(RC_IRET);
5389 #endif
5390 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5392 skip(';');
5393 /* jump unless last stmt in top-level block */
5394 if (tok != '}' || local_scope != 1)
5395 rsym = gjmp(rsym);
5396 } else if (tok == TOK_BREAK) {
5397 /* compute jump */
5398 if (!bsym)
5399 tcc_error("cannot break");
5400 *bsym = gjmp(*bsym);
5401 next();
5402 skip(';');
5403 } else if (tok == TOK_CONTINUE) {
5404 /* compute jump */
5405 if (!csym)
5406 tcc_error("cannot continue");
5407 vla_sp_restore_root();
5408 *csym = gjmp(*csym);
5409 next();
5410 skip(';');
5411 } else if (tok == TOK_FOR) {
5412 int e;
5413 next();
5414 skip('(');
5415 s = local_stack;
5416 ++local_scope;
5417 if (tok != ';') {
5418 /* c99 for-loop init decl? */
5419 if (!decl0(VT_LOCAL, 1)) {
5420 /* no, regular for-loop init expr */
5421 gexpr();
5422 vpop();
5425 skip(';');
5426 d = ind;
5427 c = ind;
5428 vla_sp_restore();
5429 a = 0;
5430 b = 0;
5431 if (tok != ';') {
5432 gexpr();
5433 a = gvtst(1, 0);
5435 skip(';');
5436 if (tok != ')') {
5437 e = gjmp(0);
5438 c = ind;
5439 vla_sp_restore();
5440 gexpr();
5441 vpop();
5442 gjmp_addr(d);
5443 gsym(e);
5445 skip(')');
5446 block(&a, &b, 0);
5447 if(!nocode_wanted)
5448 gjmp_addr(c);
5449 gsym(a);
5450 gsym_addr(b, c);
5451 --local_scope;
5452 sym_pop(&local_stack, s);
5454 } else
5455 if (tok == TOK_DO) {
5456 next();
5457 a = 0;
5458 b = 0;
5459 d = ind;
5460 vla_sp_restore();
5461 block(&a, &b, 0);
5462 skip(TOK_WHILE);
5463 skip('(');
5464 gsym(b);
5465 gexpr();
5466 c = gvtst(0, 0);
5467 gsym_addr(c, d);
5468 skip(')');
5469 gsym(a);
5470 skip(';');
5471 } else
5472 if (tok == TOK_SWITCH) {
5473 struct switch_t *saved, sw;
5474 next();
5475 skip('(');
5476 gexpr();
5477 /* XXX: other types than integer */
5478 c = gv(RC_INT);
5479 vpop();
5480 skip(')');
5481 a = 0;
5482 b = gjmp(0); /* jump to first case */
5483 sw.p = NULL; sw.n = 0; sw.def_sym = 0;
5484 saved = cur_switch;
5485 cur_switch = &sw;
5486 block(&a, csym, 0);
5487 a = gjmp(a); /* add implicit break */
5488 /* case lookup */
5489 gsym(b);
5490 qsort(sw.p, sw.n, sizeof(void*), case_cmp);
5491 for (b = 1; b < sw.n; b++)
5492 if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
5493 tcc_error("duplicate case value");
5494 gcase(sw.p, sw.n, c, &a);
5495 if (sw.def_sym)
5496 gjmp_addr(sw.def_sym);
5497 dynarray_reset(&sw.p, &sw.n);
5498 cur_switch = saved;
5499 /* break label */
5500 gsym(a);
5501 } else
5502 if (tok == TOK_CASE) {
5503 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
5504 if (!cur_switch)
5505 expect("switch");
5506 next();
5507 cr->v1 = cr->v2 = expr_const();
5508 if (gnu_ext && tok == TOK_DOTS) {
5509 next();
5510 cr->v2 = expr_const();
5511 if (cr->v2 < cr->v1)
5512 tcc_warning("empty case range");
5514 cr->sym = ind;
5515 dynarray_add((void***) &cur_switch->p, &cur_switch->n, cr);
5516 skip(':');
5517 is_expr = 0;
5518 goto block_after_label;
5519 } else
5520 if (tok == TOK_DEFAULT) {
5521 next();
5522 skip(':');
5523 if (!cur_switch)
5524 expect("switch");
5525 if (cur_switch->def_sym)
5526 tcc_error("too many 'default'");
5527 cur_switch->def_sym = ind;
5528 is_expr = 0;
5529 goto block_after_label;
5530 } else
5531 if (tok == TOK_GOTO) {
5532 next();
5533 if (tok == '*' && gnu_ext) {
5534 /* computed goto */
5535 next();
5536 gexpr();
5537 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5538 expect("pointer");
5539 ggoto();
5540 } else if (tok >= TOK_UIDENT) {
5541 s = label_find(tok);
5542 /* put forward definition if needed */
5543 if (!s) {
5544 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5545 } else {
5546 if (s->r == LABEL_DECLARED)
5547 s->r = LABEL_FORWARD;
5549 vla_sp_restore_root();
5550 if (s->r & LABEL_FORWARD)
5551 s->jnext = gjmp(s->jnext);
5552 else
5553 gjmp_addr(s->jnext);
5554 next();
5555 } else {
5556 expect("label identifier");
5558 skip(';');
5559 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
5560 asm_instr();
5561 } else {
5562 b = is_label();
5563 if (b) {
5564 /* label case */
5565 s = label_find(b);
5566 if (s) {
5567 if (s->r == LABEL_DEFINED)
5568 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
5569 gsym(s->jnext);
5570 s->r = LABEL_DEFINED;
5571 } else {
5572 s = label_push(&global_label_stack, b, LABEL_DEFINED);
5574 s->jnext = ind;
5575 vla_sp_restore();
5576 /* we accept this, but it is a mistake */
5577 block_after_label:
5578 if (tok == '}') {
5579 tcc_warning("deprecated use of label at end of compound statement");
5580 } else {
5581 if (is_expr)
5582 vpop();
5583 block(bsym, csym, is_expr);
5585 } else {
5586 /* expression case */
5587 if (tok != ';') {
5588 if (is_expr) {
5589 vpop();
5590 gexpr();
5591 } else {
5592 gexpr();
5593 vpop();
5596 skip(';');
5601 /* t is the array or struct type. c is the array or struct
5602 address. cur_index/cur_field is the pointer to the current
5603 value. 'size_only' is true if only size info is needed (only used
5604 in arrays) */
5605 static void decl_designator(CType *type, Section *sec, unsigned long c,
5606 int *cur_index, Sym **cur_field,
5607 int size_only)
5609 Sym *s, *f;
5610 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5611 CType type1;
5613 notfirst = 0;
5614 elem_size = 0;
5615 nb_elems = 1;
5616 if (gnu_ext && (l = is_label()) != 0)
5617 goto struct_field;
5618 while (tok == '[' || tok == '.') {
5619 if (tok == '[') {
5620 if (!(type->t & VT_ARRAY))
5621 expect("array type");
5622 s = type->ref;
5623 next();
5624 index = expr_const();
5625 if (index < 0 || (s->c >= 0 && index >= s->c))
5626 expect("invalid index");
5627 if (tok == TOK_DOTS && gnu_ext) {
5628 next();
5629 index_last = expr_const();
5630 if (index_last < 0 ||
5631 (s->c >= 0 && index_last >= s->c) ||
5632 index_last < index)
5633 expect("invalid index");
5634 } else {
5635 index_last = index;
5637 skip(']');
5638 if (!notfirst)
5639 *cur_index = index_last;
5640 type = pointed_type(type);
5641 elem_size = type_size(type, &align);
5642 c += index * elem_size;
5643 /* NOTE: we only support ranges for last designator */
5644 nb_elems = index_last - index + 1;
5645 if (nb_elems != 1) {
5646 notfirst = 1;
5647 break;
5649 } else {
5650 next();
5651 l = tok;
5652 next();
5653 struct_field:
5654 if ((type->t & VT_BTYPE) != VT_STRUCT)
5655 expect("struct/union type");
5656 s = type->ref;
5657 l |= SYM_FIELD;
5658 f = s->next;
5659 while (f) {
5660 if (f->v == l)
5661 break;
5662 f = f->next;
5664 if (!f)
5665 expect("field");
5666 if (!notfirst)
5667 *cur_field = f;
5668 /* XXX: fix this mess by using explicit storage field */
5669 type1 = f->type;
5670 type1.t |= (type->t & ~VT_TYPE);
5671 type = &type1;
5672 c += f->c;
5674 notfirst = 1;
5676 if (notfirst) {
5677 if (tok == '=') {
5678 next();
5679 } else {
5680 if (!gnu_ext)
5681 expect("=");
5683 } else {
5684 if (type->t & VT_ARRAY) {
5685 index = *cur_index;
5686 type = pointed_type(type);
5687 c += index * type_size(type, &align);
5688 } else {
5689 f = *cur_field;
5690 if (!f)
5691 tcc_error("too many field init");
5692 /* XXX: fix this mess by using explicit storage field */
5693 type1 = f->type;
5694 type1.t |= (type->t & ~VT_TYPE);
5695 type = &type1;
5696 c += f->c;
5699 decl_initializer(type, sec, c, 0, size_only);
5701 /* XXX: make it more general */
5702 if (!size_only && nb_elems > 1) {
5703 unsigned long c_end;
5704 uint8_t *src, *dst;
5705 int i;
5707 if (!sec)
5708 tcc_error("range init not supported yet for dynamic storage");
5709 c_end = c + nb_elems * elem_size;
5710 if (c_end > sec->data_allocated)
5711 section_realloc(sec, c_end);
5712 src = sec->data + c;
5713 dst = src;
5714 for(i = 1; i < nb_elems; i++) {
5715 dst += elem_size;
5716 memcpy(dst, src, elem_size);
5721 #define EXPR_VAL 0
5722 #define EXPR_CONST 1
5723 #define EXPR_ANY 2
5725 /* store a value or an expression directly in global data or in local array */
5726 static void init_putv(CType *type, Section *sec, unsigned long c,
5727 int v, int expr_type)
5729 int saved_global_expr, bt, bit_pos, bit_size;
5730 void *ptr;
5731 unsigned long long bit_mask;
5732 CType dtype;
5734 switch(expr_type) {
5735 case EXPR_VAL:
5736 vpushi(v);
5737 break;
5738 case EXPR_CONST:
5739 /* compound literals must be allocated globally in this case */
5740 saved_global_expr = global_expr;
5741 global_expr = 1;
5742 expr_const1();
5743 global_expr = saved_global_expr;
5744 /* NOTE: symbols are accepted */
5745 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5746 tcc_error("initializer element is not constant");
5747 break;
5748 case EXPR_ANY:
5749 expr_eq();
5750 break;
5753 dtype = *type;
5754 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5756 if (sec) {
5757 /* XXX: not portable */
5758 /* XXX: generate error if incorrect relocation */
5759 gen_assign_cast(&dtype);
5760 bt = type->t & VT_BTYPE;
5761 /* we'll write at most 16 bytes */
5762 if (c + 16 > sec->data_allocated) {
5763 section_realloc(sec, c + 16);
5765 ptr = sec->data + c;
5766 /* XXX: make code faster ? */
5767 if (!(type->t & VT_BITFIELD)) {
5768 bit_pos = 0;
5769 bit_size = 32;
5770 bit_mask = -1LL;
5771 } else {
5772 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5773 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5774 bit_mask = (1LL << bit_size) - 1;
5776 if ((vtop->r & VT_SYM) &&
5777 (bt == VT_BYTE ||
5778 bt == VT_SHORT ||
5779 bt == VT_DOUBLE ||
5780 bt == VT_LDOUBLE ||
5781 bt == VT_LLONG ||
5782 (bt == VT_INT && bit_size != 32)))
5783 tcc_error("initializer element is not computable at load time");
5784 switch(bt) {
5785 /* XXX: when cross-compiling we assume that each type has the
5786 same representation on host and target, which is likely to
5787 be wrong in the case of long double */
5788 case VT_BOOL:
5789 vtop->c.i = (vtop->c.i != 0);
5790 case VT_BYTE:
5791 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5792 break;
5793 case VT_SHORT:
5794 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5795 break;
5796 case VT_DOUBLE:
5797 *(double *)ptr = vtop->c.d;
5798 break;
5799 case VT_LDOUBLE:
5800 if (sizeof(long double) == LDOUBLE_SIZE)
5801 *(long double *)ptr = vtop->c.ld;
5802 else if (sizeof(double) == LDOUBLE_SIZE)
5803 *(double *)ptr = vtop->c.ld;
5804 else
5805 tcc_error("can't cross compile long double constants");
5806 break;
5807 case VT_LLONG:
5808 *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5809 break;
5810 case VT_PTR: {
5811 addr_t val = (vtop->c.i & bit_mask) << bit_pos;
5812 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5813 if (vtop->r & VT_SYM)
5814 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5815 else
5816 *(addr_t *)ptr |= val;
5817 #else
5818 if (vtop->r & VT_SYM)
5819 greloc(sec, vtop->sym, c, R_DATA_PTR);
5820 *(addr_t *)ptr |= val;
5821 #endif
5822 break;
5824 default: {
5825 int val = (vtop->c.i & bit_mask) << bit_pos;
5826 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5827 if (vtop->r & VT_SYM)
5828 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5829 else
5830 *(int *)ptr |= val;
5831 #else
5832 if (vtop->r & VT_SYM)
5833 greloc(sec, vtop->sym, c, R_DATA_PTR);
5834 *(int *)ptr |= val;
5835 #endif
5836 break;
5839 vtop--;
5840 } else {
5841 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5842 vswap();
5843 vstore();
5844 vpop();
5848 /* put zeros for variable based init */
5849 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5851 if (sec) {
5852 /* nothing to do because globals are already set to zero */
5853 } else {
5854 vpush_global_sym(&func_old_type, TOK_memset);
5855 vseti(VT_LOCAL, c);
5856 #ifdef TCC_TARGET_ARM
5857 vpushs(size);
5858 vpushi(0);
5859 #else
5860 vpushi(0);
5861 vpushs(size);
5862 #endif
5863 gfunc_call(3);
5867 /* 't' contains the type and storage info. 'c' is the offset of the
5868 object in section 'sec'. If 'sec' is NULL, it means stack based
5869 allocation. 'first' is true if array '{' must be read (multi
5870 dimension implicit array init handling). 'size_only' is true if
5871 size only evaluation is wanted (only for arrays). */
5872 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5873 int first, int size_only)
5875 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5876 int size1, align1, expr_type;
5877 Sym *s, *f;
5878 CType *t1;
5880 if (type->t & VT_VLA) {
5881 int a;
5883 /* save current stack pointer */
5884 if (vlas_in_scope == 0) {
5885 if (vla_sp_root_loc == -1)
5886 vla_sp_root_loc = (loc -= PTR_SIZE);
5887 gen_vla_sp_save(vla_sp_root_loc);
5890 vla_runtime_type_size(type, &a);
5891 gen_vla_alloc(type, a);
5892 gen_vla_sp_save(c);
5893 vla_sp_loc = c;
5894 vlas_in_scope++;
5895 } else if (type->t & VT_ARRAY) {
5896 s = type->ref;
5897 n = s->c;
5898 array_length = 0;
5899 t1 = pointed_type(type);
5900 size1 = type_size(t1, &align1);
5902 no_oblock = 1;
5903 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5904 tok == '{') {
5905 if (tok != '{')
5906 tcc_error("character array initializer must be a literal,"
5907 " optionally enclosed in braces");
5908 skip('{');
5909 no_oblock = 0;
5912 /* only parse strings here if correct type (otherwise: handle
5913 them as ((w)char *) expressions */
5914 if ((tok == TOK_LSTR &&
5915 #ifdef TCC_TARGET_PE
5916 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5917 #else
5918 (t1->t & VT_BTYPE) == VT_INT
5919 #endif
5920 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5921 while (tok == TOK_STR || tok == TOK_LSTR) {
5922 int cstr_len, ch;
5924 /* compute maximum number of chars wanted */
5925 if (tok == TOK_STR)
5926 cstr_len = tokc.str.size;
5927 else
5928 cstr_len = tokc.str.size / sizeof(nwchar_t);
5929 cstr_len--;
5930 nb = cstr_len;
5931 if (n >= 0 && nb > (n - array_length))
5932 nb = n - array_length;
5933 if (!size_only) {
5934 if (cstr_len > nb)
5935 tcc_warning("initializer-string for array is too long");
5936 /* in order to go faster for common case (char
5937 string in global variable, we handle it
5938 specifically */
5939 if (sec && tok == TOK_STR && size1 == 1) {
5940 memcpy(sec->data + c + array_length, tokc.str.data, nb);
5941 } else {
5942 for(i=0;i<nb;i++) {
5943 if (tok == TOK_STR)
5944 ch = ((unsigned char *)tokc.str.data)[i];
5945 else
5946 ch = ((nwchar_t *)tokc.str.data)[i];
5947 init_putv(t1, sec, c + (array_length + i) * size1,
5948 ch, EXPR_VAL);
5952 array_length += nb;
5953 next();
5955 /* only add trailing zero if enough storage (no
5956 warning in this case since it is standard) */
5957 if (n < 0 || array_length < n) {
5958 if (!size_only) {
5959 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5961 array_length++;
5963 } else {
5964 index = 0;
5965 while (tok != '}') {
5966 decl_designator(type, sec, c, &index, NULL, size_only);
5967 if (n >= 0 && index >= n)
5968 tcc_error("index too large");
5969 /* must put zero in holes (note that doing it that way
5970 ensures that it even works with designators) */
5971 if (!size_only && array_length < index) {
5972 init_putz(t1, sec, c + array_length * size1,
5973 (index - array_length) * size1);
5975 index++;
5976 if (index > array_length)
5977 array_length = index;
5978 /* special test for multi dimensional arrays (may not
5979 be strictly correct if designators are used at the
5980 same time) */
5981 if (index >= n && no_oblock)
5982 break;
5983 if (tok == '}')
5984 break;
5985 skip(',');
5988 if (!no_oblock)
5989 skip('}');
5990 /* put zeros at the end */
5991 if (!size_only && n >= 0 && array_length < n) {
5992 init_putz(t1, sec, c + array_length * size1,
5993 (n - array_length) * size1);
5995 /* patch type size if needed */
5996 if (n < 0)
5997 s->c = array_length;
5998 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5999 (sec || !first || tok == '{')) {
6001 /* NOTE: the previous test is a specific case for automatic
6002 struct/union init */
6003 /* XXX: union needs only one init */
6005 int par_count = 0;
6006 if (tok == '(') {
6007 AttributeDef ad1;
6008 CType type1;
6009 next();
6010 if (tcc_state->old_struct_init_code) {
6011 /* an old version of struct initialization.
6012 It have a problems. But with a new version
6013 linux 2.4.26 can't load ramdisk.
6015 while (tok == '(') {
6016 par_count++;
6017 next();
6019 if (!parse_btype(&type1, &ad1))
6020 expect("cast");
6021 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
6022 #if 0
6023 if (!is_assignable_types(type, &type1))
6024 tcc_error("invalid type for cast");
6025 #endif
6026 skip(')');
6028 else
6030 if (tok != '(') {
6031 if (!parse_btype(&type1, &ad1))
6032 expect("cast");
6033 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
6034 #if 0
6035 if (!is_assignable_types(type, &type1))
6036 tcc_error("invalid type for cast");
6037 #endif
6038 skip(')');
6039 } else
6040 unget_tok(tok);
6044 no_oblock = 1;
6045 if (first || tok == '{') {
6046 skip('{');
6047 no_oblock = 0;
6049 s = type->ref;
6050 f = s->next;
6051 array_length = 0;
6052 index = 0;
6053 n = s->c;
6054 while (tok != '}') {
6055 decl_designator(type, sec, c, NULL, &f, size_only);
6056 index = f->c;
6057 if (!size_only && array_length < index) {
6058 init_putz(type, sec, c + array_length,
6059 index - array_length);
6061 index = index + type_size(&f->type, &align1);
6062 if (index > array_length)
6063 array_length = index;
6065 /* gr: skip fields from same union - ugly. */
6066 while (f->next) {
6067 int align = 0;
6068 int f_size = type_size(&f->type, &align);
6069 int f_type = (f->type.t & VT_BTYPE);
6071 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
6072 /* test for same offset */
6073 if (f->next->c != f->c)
6074 break;
6075 if ((f_type == VT_STRUCT) && (f_size == 0)) {
6077 Lets assume a structure of size 0 can't be a member of the union.
6078 This allow to compile the following code from a linux kernel v2.4.26
6079 typedef struct { } rwlock_t;
6080 struct fs_struct {
6081 int count;
6082 rwlock_t lock;
6083 int umask;
6085 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
6086 tcc-0.9.23 can succesfully compile this version of the kernel.
6087 gcc don't have problems with this code too.
6089 break;
6091 /* if yes, test for bitfield shift */
6092 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
6093 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
6094 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
6095 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
6096 if (bit_pos_1 != bit_pos_2)
6097 break;
6099 f = f->next;
6102 f = f->next;
6103 if (no_oblock && f == NULL)
6104 break;
6105 if (tok == '}')
6106 break;
6107 skip(',');
6109 /* put zeros at the end */
6110 if (!size_only && array_length < n) {
6111 init_putz(type, sec, c + array_length,
6112 n - array_length);
6114 if (!no_oblock)
6115 skip('}');
6116 while (par_count) {
6117 skip(')');
6118 par_count--;
6120 } else if (tok == '{') {
6121 next();
6122 decl_initializer(type, sec, c, first, size_only);
6123 skip('}');
6124 } else if (size_only) {
6125 /* just skip expression */
6126 parlevel = parlevel1 = 0;
6127 while ((parlevel > 0 || parlevel1 > 0 ||
6128 (tok != '}' && tok != ',')) && tok != -1) {
6129 if (tok == '(')
6130 parlevel++;
6131 else if (tok == ')') {
6132 if (parlevel == 0 && parlevel1 == 0)
6133 break;
6134 parlevel--;
6136 else if (tok == '{')
6137 parlevel1++;
6138 else if (tok == '}') {
6139 if (parlevel == 0 && parlevel1 == 0)
6140 break;
6141 parlevel1--;
6143 next();
6145 } else {
6146 /* currently, we always use constant expression for globals
6147 (may change for scripting case) */
6148 expr_type = EXPR_CONST;
6149 if (!sec)
6150 expr_type = EXPR_ANY;
6151 init_putv(type, sec, c, 0, expr_type);
6155 /* parse an initializer for type 't' if 'has_init' is non zero, and
6156 allocate space in local or global data space ('r' is either
6157 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6158 variable 'v' of scope 'scope' is declared before initializers
6159 are parsed. If 'v' is zero, then a reference to the new object
6160 is put in the value stack. If 'has_init' is 2, a special parsing
6161 is done to handle string constants. */
6162 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
6163 int has_init, int v, int scope)
6165 int size, align, addr, data_offset;
6166 int level;
6167 ParseState saved_parse_state = {0};
6168 TokenString *init_str = NULL;
6169 Section *sec;
6170 Sym *flexible_array;
6172 flexible_array = NULL;
6173 if ((type->t & VT_BTYPE) == VT_STRUCT) {
6174 Sym *field = type->ref->next;
6175 if (field) {
6176 while (field->next)
6177 field = field->next;
6178 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
6179 flexible_array = field;
6183 size = type_size(type, &align);
6184 /* If unknown size, we must evaluate it before
6185 evaluating initializers because
6186 initializers can generate global data too
6187 (e.g. string pointers or ISOC99 compound
6188 literals). It also simplifies local
6189 initializers handling */
6190 if (size < 0 || (flexible_array && has_init)) {
6191 if (!has_init)
6192 tcc_error("unknown type size");
6193 /* get all init string */
6194 init_str = tok_str_alloc();
6195 if (has_init == 2) {
6196 /* only get strings */
6197 while (tok == TOK_STR || tok == TOK_LSTR) {
6198 tok_str_add_tok(init_str);
6199 next();
6201 } else {
6202 level = 0;
6203 while (level > 0 || (tok != ',' && tok != ';')) {
6204 if (tok < 0)
6205 tcc_error("unexpected end of file in initializer");
6206 tok_str_add_tok(init_str);
6207 if (tok == '{')
6208 level++;
6209 else if (tok == '}') {
6210 level--;
6211 if (level <= 0) {
6212 next();
6213 break;
6216 next();
6219 tok_str_add(init_str, -1);
6220 tok_str_add(init_str, 0);
6222 /* compute size */
6223 save_parse_state(&saved_parse_state);
6225 begin_macro(init_str, 1);
6226 next();
6227 decl_initializer(type, NULL, 0, 1, 1);
6228 /* prepare second initializer parsing */
6229 macro_ptr = init_str->str;
6230 next();
6232 /* if still unknown size, error */
6233 size = type_size(type, &align);
6234 if (size < 0)
6235 tcc_error("unknown type size");
6237 /* If there's a flex member and it was used in the initializer
6238 adjust size. */
6239 if (flexible_array &&
6240 flexible_array->type.ref->c > 0)
6241 size += flexible_array->type.ref->c
6242 * pointed_size(&flexible_array->type);
6243 /* take into account specified alignment if bigger */
6244 if (ad->a.aligned) {
6245 if (ad->a.aligned > align)
6246 align = ad->a.aligned;
6247 } else if (ad->a.packed) {
6248 align = 1;
6250 if ((r & VT_VALMASK) == VT_LOCAL) {
6251 sec = NULL;
6252 #ifdef CONFIG_TCC_BCHECK
6253 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
6254 loc--;
6256 #endif
6257 loc = (loc - size) & -align;
6258 addr = loc;
6259 #ifdef CONFIG_TCC_BCHECK
6260 /* handles bounds */
6261 /* XXX: currently, since we do only one pass, we cannot track
6262 '&' operators, so we add only arrays */
6263 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
6264 addr_t *bounds_ptr;
6265 /* add padding between regions */
6266 loc--;
6267 /* then add local bound info */
6268 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
6269 bounds_ptr[0] = addr;
6270 bounds_ptr[1] = size;
6272 #endif
6273 if (v) {
6274 /* local variable */
6275 sym_push(v, type, r, addr);
6276 } else {
6277 /* push local reference */
6278 vset(type, r, addr);
6280 } else {
6281 Sym *sym;
6283 sym = NULL;
6284 if (v && scope == VT_CONST) {
6285 /* see if the symbol was already defined */
6286 sym = sym_find(v);
6287 if (sym) {
6288 if (!is_compatible_types(&sym->type, type))
6289 tcc_error("incompatible types for redefinition of '%s'",
6290 get_tok_str(v, NULL));
6291 if (sym->type.t & VT_EXTERN) {
6292 /* if the variable is extern, it was not allocated */
6293 sym->type.t &= ~VT_EXTERN;
6294 /* set array size if it was omitted in extern
6295 declaration */
6296 if ((sym->type.t & VT_ARRAY) &&
6297 sym->type.ref->c < 0 &&
6298 type->ref->c >= 0)
6299 sym->type.ref->c = type->ref->c;
6300 } else {
6301 /* we accept several definitions of the same
6302 global variable. this is tricky, because we
6303 must play with the SHN_COMMON type of the symbol */
6304 /* XXX: should check if the variable was already
6305 initialized. It is incorrect to initialized it
6306 twice */
6307 /* no init data, we won't add more to the symbol */
6308 if (!has_init)
6309 goto no_alloc;
6314 /* allocate symbol in corresponding section */
6315 sec = ad->section;
6316 if (!sec) {
6317 if (has_init)
6318 sec = data_section;
6319 else if (tcc_state->nocommon)
6320 sec = bss_section;
6322 if (sec) {
6323 data_offset = sec->data_offset;
6324 data_offset = (data_offset + align - 1) & -align;
6325 addr = data_offset;
6326 /* very important to increment global pointer at this time
6327 because initializers themselves can create new initializers */
6328 data_offset += size;
6329 #ifdef CONFIG_TCC_BCHECK
6330 /* add padding if bound check */
6331 if (tcc_state->do_bounds_check)
6332 data_offset++;
6333 #endif
6334 sec->data_offset = data_offset;
6335 /* allocate section space to put the data */
6336 if (sec->sh_type != SHT_NOBITS &&
6337 data_offset > sec->data_allocated)
6338 section_realloc(sec, data_offset);
6339 /* align section if needed */
6340 if (align > sec->sh_addralign)
6341 sec->sh_addralign = align;
6342 } else {
6343 addr = 0; /* avoid warning */
6346 if (v) {
6347 if (scope != VT_CONST || !sym) {
6348 sym = sym_push(v, type, r | VT_SYM, 0);
6349 sym->asm_label = ad->asm_label;
6351 /* update symbol definition */
6352 if (sec) {
6353 put_extern_sym(sym, sec, addr, size);
6354 } else {
6355 ElfW(Sym) *esym;
6356 /* put a common area */
6357 put_extern_sym(sym, NULL, align, size);
6358 /* XXX: find a nicer way */
6359 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
6360 esym->st_shndx = SHN_COMMON;
6362 } else {
6363 /* push global reference */
6364 sym = get_sym_ref(type, sec, addr, size);
6365 vpushsym(type, sym);
6367 /* patch symbol weakness */
6368 if (type->t & VT_WEAK)
6369 weaken_symbol(sym);
6370 apply_visibility(sym, type);
6371 #ifdef CONFIG_TCC_BCHECK
6372 /* handles bounds now because the symbol must be defined
6373 before for the relocation */
6374 if (tcc_state->do_bounds_check) {
6375 addr_t *bounds_ptr;
6377 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
6378 /* then add global bound info */
6379 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
6380 bounds_ptr[0] = 0; /* relocated */
6381 bounds_ptr[1] = size;
6383 #endif
6385 if (has_init || (type->t & VT_VLA)) {
6386 decl_initializer(type, sec, addr, 1, 0);
6387 /* patch flexible array member size back to -1, */
6388 /* for possible subsequent similar declarations */
6389 if (flexible_array)
6390 flexible_array->type.ref->c = -1;
6392 no_alloc: ;
6393 /* restore parse state if needed */
6394 if (init_str) {
6395 end_macro();
6396 restore_parse_state(&saved_parse_state);
6400 static void put_func_debug(Sym *sym)
6402 char buf[512];
6404 /* stabs info */
6405 /* XXX: we put here a dummy type */
6406 snprintf(buf, sizeof(buf), "%s:%c1",
6407 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
6408 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6409 cur_text_section, sym->c);
6410 /* //gr gdb wants a line at the function */
6411 put_stabn(N_SLINE, 0, file->line_num, 0);
6412 last_ind = 0;
6413 last_line_num = 0;
6416 /* parse an old style function declaration list */
6417 /* XXX: check multiple parameter */
6418 static void func_decl_list(Sym *func_sym)
6420 AttributeDef ad;
6421 int v;
6422 Sym *s;
6423 CType btype, type;
6425 /* parse each declaration */
6426 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
6427 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
6428 if (!parse_btype(&btype, &ad))
6429 expect("declaration list");
6430 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6431 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6432 tok == ';') {
6433 /* we accept no variable after */
6434 } else {
6435 for(;;) {
6436 type = btype;
6437 type_decl(&type, &ad, &v, TYPE_DIRECT);
6438 /* find parameter in function parameter list */
6439 s = func_sym->next;
6440 while (s != NULL) {
6441 if ((s->v & ~SYM_FIELD) == v)
6442 goto found;
6443 s = s->next;
6445 tcc_error("declaration for parameter '%s' but no such parameter",
6446 get_tok_str(v, NULL));
6447 found:
6448 /* check that no storage specifier except 'register' was given */
6449 if (type.t & VT_STORAGE)
6450 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
6451 convert_parameter_type(&type);
6452 /* we can add the type (NOTE: it could be local to the function) */
6453 s->type = type;
6454 /* accept other parameters */
6455 if (tok == ',')
6456 next();
6457 else
6458 break;
6461 skip(';');
6465 /* parse a function defined by symbol 'sym' and generate its code in
6466 'cur_text_section' */
6467 static void gen_function(Sym *sym)
6469 int saved_nocode_wanted = nocode_wanted;
6471 nocode_wanted = 0;
6472 ind = cur_text_section->data_offset;
6473 /* NOTE: we patch the symbol size later */
6474 put_extern_sym(sym, cur_text_section, ind, 0);
6475 funcname = get_tok_str(sym->v, NULL);
6476 func_ind = ind;
6477 /* Initialize VLA state */
6478 vla_sp_loc = -1;
6479 vla_sp_root_loc = -1;
6480 /* put debug symbol */
6481 if (tcc_state->do_debug)
6482 put_func_debug(sym);
6484 /* push a dummy symbol to enable local sym storage */
6485 sym_push2(&local_stack, SYM_FIELD, 0, 0);
6486 local_scope = 1; /* for function parameters */
6487 gfunc_prolog(&sym->type);
6488 local_scope = 0;
6490 rsym = 0;
6491 block(NULL, NULL, 0);
6492 gsym(rsym);
6493 gfunc_epilog();
6494 cur_text_section->data_offset = ind;
6495 label_pop(&global_label_stack, NULL);
6496 /* reset local stack */
6497 local_scope = 0;
6498 sym_pop(&local_stack, NULL);
6499 /* end of function */
6500 /* patch symbol size */
6501 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
6502 ind - func_ind;
6503 /* patch symbol weakness (this definition overrules any prototype) */
6504 if (sym->type.t & VT_WEAK)
6505 weaken_symbol(sym);
6506 apply_visibility(sym, &sym->type);
6507 if (tcc_state->do_debug) {
6508 put_stabn(N_FUN, 0, 0, ind - func_ind);
6510 /* It's better to crash than to generate wrong code */
6511 cur_text_section = NULL;
6512 funcname = ""; /* for safety */
6513 func_vt.t = VT_VOID; /* for safety */
6514 func_var = 0; /* for safety */
6515 ind = 0; /* for safety */
6516 nocode_wanted = saved_nocode_wanted;
6517 check_vstack();
6520 static void gen_inline_functions(TCCState *s)
6522 Sym *sym;
6523 int inline_generated, i, ln;
6524 struct InlineFunc *fn;
6526 ln = file->line_num;
6527 /* iterate while inline function are referenced */
6528 for(;;) {
6529 inline_generated = 0;
6530 for (i = 0; i < s->nb_inline_fns; ++i) {
6531 fn = s->inline_fns[i];
6532 sym = fn->sym;
6533 if (sym && sym->c) {
6534 /* the function was used: generate its code and
6535 convert it to a normal function */
6536 fn->sym = NULL;
6537 if (file)
6538 pstrcpy(file->filename, sizeof file->filename, fn->filename);
6539 sym->r = VT_SYM | VT_CONST;
6540 sym->type.t &= ~VT_INLINE;
6542 begin_macro(fn->func_str, 1);
6543 next();
6544 cur_text_section = text_section;
6545 gen_function(sym);
6546 end_macro();
6548 inline_generated = 1;
6551 if (!inline_generated)
6552 break;
6554 file->line_num = ln;
6557 ST_FUNC void free_inline_functions(TCCState *s)
6559 int i;
6560 /* free tokens of unused inline functions */
6561 for (i = 0; i < s->nb_inline_fns; ++i) {
6562 struct InlineFunc *fn = s->inline_fns[i];
6563 if (fn->sym)
6564 tok_str_free(fn->func_str);
6566 dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
6569 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6570 static int decl0(int l, int is_for_loop_init)
6572 int v, has_init, r;
6573 CType type, btype;
6574 Sym *sym;
6575 AttributeDef ad;
6577 while (1) {
6578 if (!parse_btype(&btype, &ad)) {
6579 if (is_for_loop_init)
6580 return 0;
6581 /* skip redundant ';' */
6582 /* XXX: find more elegant solution */
6583 if (tok == ';') {
6584 next();
6585 continue;
6587 if (l == VT_CONST &&
6588 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6589 /* global asm block */
6590 asm_global_instr();
6591 continue;
6593 /* special test for old K&R protos without explicit int
6594 type. Only accepted when defining global data */
6595 if (l == VT_LOCAL || tok < TOK_UIDENT)
6596 break;
6597 btype.t = VT_INT;
6599 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6600 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6601 tok == ';') {
6602 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
6603 int v = btype.ref->v;
6604 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
6605 tcc_warning("unnamed struct/union that defines no instances");
6607 next();
6608 continue;
6610 while (1) { /* iterate thru each declaration */
6611 type = btype;
6612 type_decl(&type, &ad, &v, TYPE_DIRECT);
6613 #if 0
6615 char buf[500];
6616 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6617 printf("type = '%s'\n", buf);
6619 #endif
6620 if ((type.t & VT_BTYPE) == VT_FUNC) {
6621 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
6622 tcc_error("function without file scope cannot be static");
6624 /* if old style function prototype, we accept a
6625 declaration list */
6626 sym = type.ref;
6627 if (sym->c == FUNC_OLD)
6628 func_decl_list(sym);
6631 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6632 ad.asm_label = asm_label_instr();
6633 /* parse one last attribute list, after asm label */
6634 parse_attribute(&ad);
6635 if (tok == '{')
6636 expect(";");
6639 if (ad.a.weak)
6640 type.t |= VT_WEAK;
6641 #ifdef TCC_TARGET_PE
6642 if (ad.a.func_import)
6643 type.t |= VT_IMPORT;
6644 if (ad.a.func_export)
6645 type.t |= VT_EXPORT;
6646 #endif
6647 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6649 if (tok == '{') {
6650 if (l == VT_LOCAL)
6651 tcc_error("cannot use local functions");
6652 if ((type.t & VT_BTYPE) != VT_FUNC)
6653 expect("function definition");
6655 /* reject abstract declarators in function definition */
6656 sym = type.ref;
6657 while ((sym = sym->next) != NULL)
6658 if (!(sym->v & ~SYM_FIELD))
6659 expect("identifier");
6661 /* XXX: cannot do better now: convert extern line to static inline */
6662 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6663 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6665 sym = sym_find(v);
6666 if (sym) {
6667 Sym *ref;
6668 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6669 goto func_error1;
6671 ref = sym->type.ref;
6672 if (0 == ref->a.func_proto)
6673 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6675 /* use func_call from prototype if not defined */
6676 if (ref->a.func_call != FUNC_CDECL
6677 && type.ref->a.func_call == FUNC_CDECL)
6678 type.ref->a.func_call = ref->a.func_call;
6680 /* use export from prototype */
6681 if (ref->a.func_export)
6682 type.ref->a.func_export = 1;
6684 /* use static from prototype */
6685 if (sym->type.t & VT_STATIC)
6686 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6688 /* If the definition has no visibility use the
6689 one from prototype. */
6690 if (! (type.t & VT_VIS_MASK))
6691 type.t |= sym->type.t & VT_VIS_MASK;
6693 if (!is_compatible_types(&sym->type, &type)) {
6694 func_error1:
6695 tcc_error("incompatible types for redefinition of '%s'",
6696 get_tok_str(v, NULL));
6698 type.ref->a.func_proto = 0;
6699 /* if symbol is already defined, then put complete type */
6700 sym->type = type;
6701 } else {
6702 /* put function symbol */
6703 sym = global_identifier_push(v, type.t, 0);
6704 sym->type.ref = type.ref;
6707 /* static inline functions are just recorded as a kind
6708 of macro. Their code will be emitted at the end of
6709 the compilation unit only if they are used */
6710 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6711 (VT_INLINE | VT_STATIC)) {
6712 int block_level;
6713 struct InlineFunc *fn;
6714 const char *filename;
6716 filename = file ? file->filename : "";
6717 fn = tcc_malloc(sizeof *fn + strlen(filename));
6718 strcpy(fn->filename, filename);
6719 fn->sym = sym;
6720 fn->func_str = tok_str_alloc();
6722 block_level = 0;
6723 for(;;) {
6724 int t;
6725 if (tok == TOK_EOF)
6726 tcc_error("unexpected end of file");
6727 tok_str_add_tok(fn->func_str);
6728 t = tok;
6729 next();
6730 if (t == '{') {
6731 block_level++;
6732 } else if (t == '}') {
6733 block_level--;
6734 if (block_level == 0)
6735 break;
6738 tok_str_add(fn->func_str, -1);
6739 tok_str_add(fn->func_str, 0);
6740 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6742 } else {
6743 /* compute text section */
6744 cur_text_section = ad.section;
6745 if (!cur_text_section)
6746 cur_text_section = text_section;
6747 sym->r = VT_SYM | VT_CONST;
6748 gen_function(sym);
6750 break;
6751 } else {
6752 if (btype.t & VT_TYPEDEF) {
6753 /* save typedefed type */
6754 /* XXX: test storage specifiers ? */
6755 sym = sym_find(v);
6756 if (sym && sym->scope == local_scope) {
6757 if (!is_compatible_types(&sym->type, &type)
6758 || !(sym->type.t & VT_TYPEDEF))
6759 tcc_error("incompatible redefinition of '%s'",
6760 get_tok_str(v, NULL));
6761 sym->type = type;
6762 } else {
6763 sym = sym_push(v, &type, 0, 0);
6765 sym->a = ad.a;
6766 sym->type.t |= VT_TYPEDEF;
6767 } else {
6768 r = 0;
6769 if ((type.t & VT_BTYPE) == VT_FUNC) {
6770 /* external function definition */
6771 /* specific case for func_call attribute */
6772 ad.a.func_proto = 1;
6773 type.ref->a = ad.a;
6774 } else if (!(type.t & VT_ARRAY)) {
6775 /* not lvalue if array */
6776 r |= lvalue_type(type.t);
6778 has_init = (tok == '=');
6779 if (has_init && (type.t & VT_VLA))
6780 tcc_error("Variable length array cannot be initialized");
6781 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6782 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6783 !has_init && l == VT_CONST && type.ref->c < 0)) {
6784 /* external variable or function */
6785 /* NOTE: as GCC, uninitialized global static
6786 arrays of null size are considered as
6787 extern */
6788 sym = external_sym(v, &type, r);
6789 sym->asm_label = ad.asm_label;
6791 if (ad.alias_target) {
6792 Section tsec;
6793 Elf32_Sym *esym;
6794 Sym *alias_target;
6796 alias_target = sym_find(ad.alias_target);
6797 if (!alias_target || !alias_target->c)
6798 tcc_error("unsupported forward __alias__ attribute");
6799 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6800 tsec.sh_num = esym->st_shndx;
6801 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6803 } else {
6804 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6805 if (type.t & VT_STATIC)
6806 r |= VT_CONST;
6807 else
6808 r |= l;
6809 if (has_init)
6810 next();
6811 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
6814 if (tok != ',') {
6815 if (is_for_loop_init)
6816 return 1;
6817 skip(';');
6818 break;
6820 next();
6822 ad.a.aligned = 0;
6825 return 0;
6828 ST_FUNC void decl(int l)
6830 decl0(l, 0);
6833 /* ------------------------------------------------------------------------- */