tccrun/win64: cleanup runtime function table
[tinycc.git] / tccgen.c
blobfdd86543f367069840f92fb714620b9079311a45
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;
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 if (flexible)
3239 tcc_error("flexible array member '%s' not at the end of struct",
3240 get_tok_str(v, NULL));
3241 bit_size = -1;
3242 v = 0;
3243 type1 = btype;
3244 if (tok != ':') {
3245 type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT);
3246 if (v == 0) {
3247 if ((type1.t & VT_BTYPE) != VT_STRUCT)
3248 expect("identifier");
3249 else {
3250 int v = btype.ref->v;
3251 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
3252 if (tcc_state->ms_extensions == 0)
3253 expect("identifier");
3257 if (type_size(&type1, &align) < 0) {
3258 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
3259 flexible = 1;
3260 else
3261 tcc_error("field '%s' has incomplete type",
3262 get_tok_str(v, NULL));
3264 if ((type1.t & VT_BTYPE) == VT_FUNC ||
3265 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
3266 tcc_error("invalid type for '%s'",
3267 get_tok_str(v, NULL));
3269 if (tok == ':') {
3270 next();
3271 bit_size = expr_const();
3272 /* XXX: handle v = 0 case for messages */
3273 if (bit_size < 0)
3274 tcc_error("negative width in bit-field '%s'",
3275 get_tok_str(v, NULL));
3276 if (v && bit_size == 0)
3277 tcc_error("zero width for bit-field '%s'",
3278 get_tok_str(v, NULL));
3280 size = type_size(&type1, &align);
3281 if (ad1.a.aligned) {
3282 if (align < ad1.a.aligned)
3283 align = ad1.a.aligned;
3284 } else if (ad1.a.packed) {
3285 align = 1;
3286 } else if (*tcc_state->pack_stack_ptr) {
3287 if (align > *tcc_state->pack_stack_ptr)
3288 align = *tcc_state->pack_stack_ptr;
3290 lbit_pos = 0;
3291 if (bit_size >= 0) {
3292 bt = type1.t & VT_BTYPE;
3293 if (bt != VT_INT &&
3294 bt != VT_BYTE &&
3295 bt != VT_SHORT &&
3296 bt != VT_BOOL &&
3297 bt != VT_ENUM &&
3298 bt != VT_LLONG)
3299 tcc_error("bitfields must have scalar type");
3300 bsize = size * 8;
3301 if (bit_size > bsize) {
3302 tcc_error("width of '%s' exceeds its type",
3303 get_tok_str(v, NULL));
3304 } else if (bit_size == bsize) {
3305 /* no need for bit fields */
3306 bit_pos = 0;
3307 } else if (bit_size == 0) {
3308 /* XXX: what to do if only padding in a
3309 structure ? */
3310 /* zero size: means to pad */
3311 bit_pos = 0;
3312 } else {
3313 /* we do not have enough room ?
3314 did the type change?
3315 is it a union? */
3316 if ((bit_pos + bit_size) > bsize ||
3317 bt != prevbt || a == TOK_UNION)
3318 bit_pos = 0;
3319 lbit_pos = bit_pos;
3320 /* XXX: handle LSB first */
3321 type1.t |= VT_BITFIELD |
3322 (bit_pos << VT_STRUCT_SHIFT) |
3323 (bit_size << (VT_STRUCT_SHIFT + 6));
3324 bit_pos += bit_size;
3326 prevbt = bt;
3327 } else {
3328 bit_pos = 0;
3330 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3331 /* add new memory data only if starting
3332 bit field */
3333 if (lbit_pos == 0) {
3334 if (a == TOK_STRUCT) {
3335 c = (c + align - 1) & -align;
3336 offset = c;
3337 if (size > 0)
3338 c += size;
3339 } else {
3340 offset = 0;
3341 if (size > c)
3342 c = size;
3344 if (align > maxalign)
3345 maxalign = align;
3347 #if 0
3348 printf("add field %s offset=%d",
3349 get_tok_str(v, NULL), offset);
3350 if (type1.t & VT_BITFIELD) {
3351 printf(" pos=%d size=%d",
3352 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3353 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3355 printf("\n");
3356 #endif
3358 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3359 ass = type1.ref;
3360 while ((ass = ass->next) != NULL) {
3361 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3362 *ps = ss;
3363 ps = &ss->next;
3365 } else if (v) {
3366 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3367 *ps = ss;
3368 ps = &ss->next;
3370 if (tok == ';' || tok == TOK_EOF)
3371 break;
3372 skip(',');
3374 skip(';');
3376 skip('}');
3377 /* store size and alignment */
3378 s->c = (c + maxalign - 1) & -maxalign;
3379 s->r = maxalign;
3384 /* return 1 if basic type is a type size (short, long, long long) */
3385 ST_FUNC int is_btype_size(int bt)
3387 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3390 /* Add type qualifiers to a type. If the type is an array then the qualifiers
3391 are added to the element type, copied because it could be a typedef. */
3392 static void parse_btype_qualify(CType *type, int qualifiers)
3394 while (type->t & VT_ARRAY) {
3395 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
3396 type = &type->ref->type;
3398 type->t |= qualifiers;
3401 /* return 0 if no type declaration. otherwise, return the basic type
3402 and skip it.
3404 static int parse_btype(CType *type, AttributeDef *ad)
3406 int t, u, bt_size, complete, type_found, typespec_found;
3407 Sym *s;
3408 CType type1;
3410 memset(ad, 0, sizeof(AttributeDef));
3411 complete = 0;
3412 type_found = 0;
3413 typespec_found = 0;
3414 t = 0;
3415 while(1) {
3416 switch(tok) {
3417 case TOK_EXTENSION:
3418 /* currently, we really ignore extension */
3419 next();
3420 continue;
3422 /* basic types */
3423 case TOK_CHAR:
3424 u = VT_BYTE;
3425 basic_type:
3426 next();
3427 basic_type1:
3428 if (complete)
3429 tcc_error("too many basic types");
3430 t |= u;
3431 bt_size = is_btype_size (u & VT_BTYPE);
3432 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3433 complete = 1;
3434 typespec_found = 1;
3435 break;
3436 case TOK_VOID:
3437 u = VT_VOID;
3438 goto basic_type;
3439 case TOK_SHORT:
3440 u = VT_SHORT;
3441 goto basic_type;
3442 case TOK_INT:
3443 u = VT_INT;
3444 goto basic_type;
3445 case TOK_LONG:
3446 next();
3447 if ((t & VT_BTYPE) == VT_DOUBLE) {
3448 #ifndef TCC_TARGET_PE
3449 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3450 #endif
3451 } else if ((t & VT_BTYPE) == VT_LONG) {
3452 t = (t & ~VT_BTYPE) | VT_LLONG;
3453 } else {
3454 u = VT_LONG;
3455 goto basic_type1;
3457 break;
3458 #ifdef TCC_TARGET_ARM64
3459 case TOK_UINT128:
3460 /* GCC's __uint128_t appears in some Linux header files. Make it a
3461 synonym for long double to get the size and alignment right. */
3462 u = VT_LDOUBLE;
3463 goto basic_type;
3464 #endif
3465 case TOK_BOOL:
3466 u = VT_BOOL;
3467 goto basic_type;
3468 case TOK_FLOAT:
3469 u = VT_FLOAT;
3470 goto basic_type;
3471 case TOK_DOUBLE:
3472 next();
3473 if ((t & VT_BTYPE) == VT_LONG) {
3474 #ifdef TCC_TARGET_PE
3475 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3476 #else
3477 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3478 #endif
3479 } else {
3480 u = VT_DOUBLE;
3481 goto basic_type1;
3483 break;
3484 case TOK_ENUM:
3485 struct_decl(&type1, ad, VT_ENUM);
3486 basic_type2:
3487 u = type1.t;
3488 type->ref = type1.ref;
3489 goto basic_type1;
3490 case TOK_STRUCT:
3491 case TOK_UNION:
3492 struct_decl(&type1, ad, VT_STRUCT);
3493 goto basic_type2;
3495 /* type modifiers */
3496 case TOK_CONST1:
3497 case TOK_CONST2:
3498 case TOK_CONST3:
3499 type->t = t;
3500 parse_btype_qualify(type, VT_CONSTANT);
3501 t = type->t;
3502 next();
3503 break;
3504 case TOK_VOLATILE1:
3505 case TOK_VOLATILE2:
3506 case TOK_VOLATILE3:
3507 type->t = t;
3508 parse_btype_qualify(type, VT_VOLATILE);
3509 t = type->t;
3510 next();
3511 break;
3512 case TOK_SIGNED1:
3513 case TOK_SIGNED2:
3514 case TOK_SIGNED3:
3515 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3516 tcc_error("signed and unsigned modifier");
3517 typespec_found = 1;
3518 t |= VT_DEFSIGN;
3519 next();
3520 break;
3521 case TOK_REGISTER:
3522 case TOK_AUTO:
3523 case TOK_RESTRICT1:
3524 case TOK_RESTRICT2:
3525 case TOK_RESTRICT3:
3526 next();
3527 break;
3528 case TOK_UNSIGNED:
3529 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3530 tcc_error("signed and unsigned modifier");
3531 t |= VT_DEFSIGN | VT_UNSIGNED;
3532 next();
3533 typespec_found = 1;
3534 break;
3536 /* storage */
3537 case TOK_EXTERN:
3538 t |= VT_EXTERN;
3539 next();
3540 break;
3541 case TOK_STATIC:
3542 t |= VT_STATIC;
3543 next();
3544 break;
3545 case TOK_TYPEDEF:
3546 t |= VT_TYPEDEF;
3547 next();
3548 break;
3549 case TOK_INLINE1:
3550 case TOK_INLINE2:
3551 case TOK_INLINE3:
3552 t |= VT_INLINE;
3553 next();
3554 break;
3556 /* GNUC attribute */
3557 case TOK_ATTRIBUTE1:
3558 case TOK_ATTRIBUTE2:
3559 parse_attribute(ad);
3560 if (ad->a.mode) {
3561 u = ad->a.mode -1;
3562 t = (t & ~VT_BTYPE) | u;
3564 break;
3565 /* GNUC typeof */
3566 case TOK_TYPEOF1:
3567 case TOK_TYPEOF2:
3568 case TOK_TYPEOF3:
3569 next();
3570 parse_expr_type(&type1);
3571 /* remove all storage modifiers except typedef */
3572 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3573 goto basic_type2;
3574 default:
3575 if (typespec_found)
3576 goto the_end;
3577 s = sym_find(tok);
3578 if (!s || !(s->type.t & VT_TYPEDEF))
3579 goto the_end;
3581 type->t = ((s->type.t & ~VT_TYPEDEF) |
3582 (t & ~(VT_CONSTANT | VT_VOLATILE)));
3583 type->ref = s->type.ref;
3584 if (t & (VT_CONSTANT | VT_VOLATILE))
3585 parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE));
3586 t = type->t;
3588 if (s->r) {
3589 /* get attributes from typedef */
3590 if (0 == ad->a.aligned)
3591 ad->a.aligned = s->a.aligned;
3592 if (0 == ad->a.func_call)
3593 ad->a.func_call = s->a.func_call;
3594 ad->a.packed |= s->a.packed;
3596 next();
3597 typespec_found = 1;
3598 break;
3600 type_found = 1;
3602 the_end:
3603 if (tcc_state->char_is_unsigned) {
3604 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3605 t |= VT_UNSIGNED;
3608 /* long is never used as type */
3609 if ((t & VT_BTYPE) == VT_LONG)
3610 #if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \
3611 defined TCC_TARGET_PE
3612 t = (t & ~VT_BTYPE) | VT_INT;
3613 #else
3614 t = (t & ~VT_BTYPE) | VT_LLONG;
3615 #endif
3616 type->t = t;
3617 return type_found;
3620 /* convert a function parameter type (array to pointer and function to
3621 function pointer) */
3622 static inline void convert_parameter_type(CType *pt)
3624 /* remove const and volatile qualifiers (XXX: const could be used
3625 to indicate a const function parameter */
3626 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3627 /* array must be transformed to pointer according to ANSI C */
3628 pt->t &= ~VT_ARRAY;
3629 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3630 mk_pointer(pt);
3634 ST_FUNC void parse_asm_str(CString *astr)
3636 skip('(');
3637 /* read the string */
3638 if (tok != TOK_STR)
3639 expect("string constant");
3640 cstr_new(astr);
3641 while (tok == TOK_STR) {
3642 /* XXX: add \0 handling too ? */
3643 cstr_cat(astr, tokc.str.data, -1);
3644 next();
3646 cstr_ccat(astr, '\0');
3649 /* Parse an asm label and return the token */
3650 static int asm_label_instr(void)
3652 int v;
3653 CString astr;
3655 next();
3656 parse_asm_str(&astr);
3657 skip(')');
3658 #ifdef ASM_DEBUG
3659 printf("asm_alias: \"%s\"\n", (char *)astr.data);
3660 #endif
3661 v = tok_alloc(astr.data, astr.size - 1)->tok;
3662 cstr_free(&astr);
3663 return v;
3666 static void post_type(CType *type, AttributeDef *ad)
3668 int n, l, t1, arg_size, align;
3669 Sym **plast, *s, *first;
3670 AttributeDef ad1;
3671 CType pt;
3673 if (tok == '(') {
3674 /* function declaration */
3675 next();
3676 l = 0;
3677 first = NULL;
3678 plast = &first;
3679 arg_size = 0;
3680 if (tok != ')') {
3681 for(;;) {
3682 /* read param name and compute offset */
3683 if (l != FUNC_OLD) {
3684 if (!parse_btype(&pt, &ad1)) {
3685 if (l) {
3686 tcc_error("invalid type");
3687 } else {
3688 l = FUNC_OLD;
3689 goto old_proto;
3692 l = FUNC_NEW;
3693 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3694 break;
3695 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3696 if ((pt.t & VT_BTYPE) == VT_VOID)
3697 tcc_error("parameter declared as void");
3698 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3699 } else {
3700 old_proto:
3701 n = tok;
3702 if (n < TOK_UIDENT)
3703 expect("identifier");
3704 pt.t = VT_INT;
3705 next();
3707 convert_parameter_type(&pt);
3708 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3709 *plast = s;
3710 plast = &s->next;
3711 if (tok == ')')
3712 break;
3713 skip(',');
3714 if (l == FUNC_NEW && tok == TOK_DOTS) {
3715 l = FUNC_ELLIPSIS;
3716 next();
3717 break;
3721 /* if no parameters, then old type prototype */
3722 if (l == 0)
3723 l = FUNC_OLD;
3724 skip(')');
3725 /* NOTE: const is ignored in returned type as it has a special
3726 meaning in gcc / C++ */
3727 type->t &= ~VT_CONSTANT;
3728 /* some ancient pre-K&R C allows a function to return an array
3729 and the array brackets to be put after the arguments, such
3730 that "int c()[]" means something like "int[] c()" */
3731 if (tok == '[') {
3732 next();
3733 skip(']'); /* only handle simple "[]" */
3734 type->t |= VT_PTR;
3736 /* we push a anonymous symbol which will contain the function prototype */
3737 ad->a.func_args = arg_size;
3738 s = sym_push(SYM_FIELD, type, 0, l);
3739 s->a = ad->a;
3740 s->next = first;
3741 type->t = VT_FUNC;
3742 type->ref = s;
3743 } else if (tok == '[') {
3744 /* array definition */
3745 next();
3746 if (tok == TOK_RESTRICT1)
3747 next();
3748 n = -1;
3749 t1 = 0;
3750 if (tok != ']') {
3751 if (!local_stack || nocode_wanted)
3752 vpushi(expr_const());
3753 else gexpr();
3754 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3755 n = vtop->c.i;
3756 if (n < 0)
3757 tcc_error("invalid array size");
3758 } else {
3759 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3760 tcc_error("size of variable length array should be an integer");
3761 t1 = VT_VLA;
3764 skip(']');
3765 /* parse next post type */
3766 post_type(type, ad);
3767 if (type->t == VT_FUNC)
3768 tcc_error("declaration of an array of functions");
3769 t1 |= type->t & VT_VLA;
3771 if (t1 & VT_VLA) {
3772 loc -= type_size(&int_type, &align);
3773 loc &= -align;
3774 n = loc;
3776 vla_runtime_type_size(type, &align);
3777 gen_op('*');
3778 vset(&int_type, VT_LOCAL|VT_LVAL, n);
3779 vswap();
3780 vstore();
3782 if (n != -1)
3783 vpop();
3785 /* we push an anonymous symbol which will contain the array
3786 element type */
3787 s = sym_push(SYM_FIELD, type, 0, n);
3788 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3789 type->ref = s;
3793 /* Parse a type declaration (except basic type), and return the type
3794 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3795 expected. 'type' should contain the basic type. 'ad' is the
3796 attribute definition of the basic type. It can be modified by
3797 type_decl().
3799 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3801 Sym *s;
3802 CType type1, *type2;
3803 int qualifiers, storage;
3805 while (tok == '*') {
3806 qualifiers = 0;
3807 redo:
3808 next();
3809 switch(tok) {
3810 case TOK_CONST1:
3811 case TOK_CONST2:
3812 case TOK_CONST3:
3813 qualifiers |= VT_CONSTANT;
3814 goto redo;
3815 case TOK_VOLATILE1:
3816 case TOK_VOLATILE2:
3817 case TOK_VOLATILE3:
3818 qualifiers |= VT_VOLATILE;
3819 goto redo;
3820 case TOK_RESTRICT1:
3821 case TOK_RESTRICT2:
3822 case TOK_RESTRICT3:
3823 goto redo;
3825 mk_pointer(type);
3826 type->t |= qualifiers;
3829 /* XXX: clarify attribute handling */
3830 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3831 parse_attribute(ad);
3833 /* recursive type */
3834 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3835 type1.t = 0; /* XXX: same as int */
3836 if (tok == '(') {
3837 next();
3838 /* XXX: this is not correct to modify 'ad' at this point, but
3839 the syntax is not clear */
3840 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3841 parse_attribute(ad);
3842 type_decl(&type1, ad, v, td);
3843 skip(')');
3844 } else {
3845 /* type identifier */
3846 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3847 *v = tok;
3848 next();
3849 } else {
3850 if (!(td & TYPE_ABSTRACT))
3851 expect("identifier");
3852 *v = 0;
3855 storage = type->t & VT_STORAGE;
3856 type->t &= ~VT_STORAGE;
3857 if (storage & VT_STATIC) {
3858 int saved_nocode_wanted = nocode_wanted;
3859 nocode_wanted = 1;
3860 post_type(type, ad);
3861 nocode_wanted = saved_nocode_wanted;
3862 } else
3863 post_type(type, ad);
3864 type->t |= storage;
3865 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3866 parse_attribute(ad);
3868 if (!type1.t)
3869 return;
3870 /* append type at the end of type1 */
3871 type2 = &type1;
3872 for(;;) {
3873 s = type2->ref;
3874 type2 = &s->type;
3875 if (!type2->t) {
3876 *type2 = *type;
3877 break;
3880 *type = type1;
3883 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3884 ST_FUNC int lvalue_type(int t)
3886 int bt, r;
3887 r = VT_LVAL;
3888 bt = t & VT_BTYPE;
3889 if (bt == VT_BYTE || bt == VT_BOOL)
3890 r |= VT_LVAL_BYTE;
3891 else if (bt == VT_SHORT)
3892 r |= VT_LVAL_SHORT;
3893 else
3894 return r;
3895 if (t & VT_UNSIGNED)
3896 r |= VT_LVAL_UNSIGNED;
3897 return r;
3900 /* indirection with full error checking and bound check */
3901 ST_FUNC void indir(void)
3903 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3904 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3905 return;
3906 expect("pointer");
3908 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3909 gv(RC_INT);
3910 vtop->type = *pointed_type(&vtop->type);
3911 /* Arrays and functions are never lvalues */
3912 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3913 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3914 vtop->r |= lvalue_type(vtop->type.t);
3915 /* if bound checking, the referenced pointer must be checked */
3916 #ifdef CONFIG_TCC_BCHECK
3917 if (tcc_state->do_bounds_check)
3918 vtop->r |= VT_MUSTBOUND;
3919 #endif
3923 /* pass a parameter to a function and do type checking and casting */
3924 static void gfunc_param_typed(Sym *func, Sym *arg)
3926 int func_type;
3927 CType type;
3929 func_type = func->c;
3930 if (func_type == FUNC_OLD ||
3931 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3932 /* default casting : only need to convert float to double */
3933 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3934 type.t = VT_DOUBLE;
3935 gen_cast(&type);
3936 } else if (vtop->type.t & VT_BITFIELD) {
3937 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3938 gen_cast(&type);
3940 } else if (arg == NULL) {
3941 tcc_error("too many arguments to function");
3942 } else {
3943 type = arg->type;
3944 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3945 gen_assign_cast(&type);
3949 /* parse an expression of the form '(type)' or '(expr)' and return its
3950 type */
3951 static void parse_expr_type(CType *type)
3953 int n;
3954 AttributeDef ad;
3956 skip('(');
3957 if (parse_btype(type, &ad)) {
3958 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3959 } else {
3960 expr_type(type);
3962 skip(')');
3965 static void parse_type(CType *type)
3967 AttributeDef ad;
3968 int n;
3970 if (!parse_btype(type, &ad)) {
3971 expect("type");
3973 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3976 static void vpush_tokc(int t)
3978 CType type;
3979 type.t = t;
3980 type.ref = 0;
3981 vsetc(&type, VT_CONST, &tokc);
3984 ST_FUNC void unary(void)
3986 int n, t, align, size, r, sizeof_caller;
3987 CType type;
3988 Sym *s;
3989 AttributeDef ad;
3991 sizeof_caller = in_sizeof;
3992 in_sizeof = 0;
3993 /* XXX: GCC 2.95.3 does not generate a table although it should be
3994 better here */
3995 tok_next:
3996 switch(tok) {
3997 case TOK_EXTENSION:
3998 next();
3999 goto tok_next;
4000 case TOK_CINT:
4001 case TOK_CCHAR:
4002 case TOK_LCHAR:
4003 vpushi(tokc.i);
4004 next();
4005 break;
4006 case TOK_CUINT:
4007 vpush_tokc(VT_INT | VT_UNSIGNED);
4008 next();
4009 break;
4010 case TOK_CLLONG:
4011 vpush_tokc(VT_LLONG);
4012 next();
4013 break;
4014 case TOK_CULLONG:
4015 vpush_tokc(VT_LLONG | VT_UNSIGNED);
4016 next();
4017 break;
4018 case TOK_CFLOAT:
4019 vpush_tokc(VT_FLOAT);
4020 next();
4021 break;
4022 case TOK_CDOUBLE:
4023 vpush_tokc(VT_DOUBLE);
4024 next();
4025 break;
4026 case TOK_CLDOUBLE:
4027 vpush_tokc(VT_LDOUBLE);
4028 next();
4029 break;
4030 case TOK___FUNCTION__:
4031 if (!gnu_ext)
4032 goto tok_identifier;
4033 /* fall thru */
4034 case TOK___FUNC__:
4036 void *ptr;
4037 int len;
4038 /* special function name identifier */
4039 len = strlen(funcname) + 1;
4040 /* generate char[len] type */
4041 type.t = VT_BYTE;
4042 mk_pointer(&type);
4043 type.t |= VT_ARRAY;
4044 type.ref->c = len;
4045 vpush_ref(&type, data_section, data_section->data_offset, len);
4046 ptr = section_ptr_add(data_section, len);
4047 memcpy(ptr, funcname, len);
4048 next();
4050 break;
4051 case TOK_LSTR:
4052 #ifdef TCC_TARGET_PE
4053 t = VT_SHORT | VT_UNSIGNED;
4054 #else
4055 t = VT_INT;
4056 #endif
4057 goto str_init;
4058 case TOK_STR:
4059 /* string parsing */
4060 t = VT_BYTE;
4061 str_init:
4062 if (tcc_state->warn_write_strings)
4063 t |= VT_CONSTANT;
4064 type.t = t;
4065 mk_pointer(&type);
4066 type.t |= VT_ARRAY;
4067 memset(&ad, 0, sizeof(AttributeDef));
4068 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
4069 break;
4070 case '(':
4071 next();
4072 /* cast ? */
4073 if (parse_btype(&type, &ad)) {
4074 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
4075 skip(')');
4076 /* check ISOC99 compound literal */
4077 if (tok == '{') {
4078 /* data is allocated locally by default */
4079 if (global_expr)
4080 r = VT_CONST;
4081 else
4082 r = VT_LOCAL;
4083 /* all except arrays are lvalues */
4084 if (!(type.t & VT_ARRAY))
4085 r |= lvalue_type(type.t);
4086 memset(&ad, 0, sizeof(AttributeDef));
4087 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
4088 } else {
4089 if (sizeof_caller) {
4090 vpush(&type);
4091 return;
4093 unary();
4094 gen_cast(&type);
4096 } else if (tok == '{') {
4097 if (const_wanted)
4098 tcc_error("expected constant");
4099 /* save all registers */
4100 if (!nocode_wanted)
4101 save_regs(0);
4102 /* statement expression : we do not accept break/continue
4103 inside as GCC does */
4104 block(NULL, NULL, 1);
4105 skip(')');
4106 } else {
4107 gexpr();
4108 skip(')');
4110 break;
4111 case '*':
4112 next();
4113 unary();
4114 indir();
4115 break;
4116 case '&':
4117 next();
4118 unary();
4119 /* functions names must be treated as function pointers,
4120 except for unary '&' and sizeof. Since we consider that
4121 functions are not lvalues, we only have to handle it
4122 there and in function calls. */
4123 /* arrays can also be used although they are not lvalues */
4124 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
4125 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
4126 test_lvalue();
4127 mk_pointer(&vtop->type);
4128 gaddrof();
4129 break;
4130 case '!':
4131 next();
4132 unary();
4133 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4134 CType boolean;
4135 boolean.t = VT_BOOL;
4136 gen_cast(&boolean);
4137 vtop->c.i = !vtop->c.i;
4138 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
4139 vtop->c.i ^= 1;
4140 else {
4141 save_regs(1);
4142 vseti(VT_JMP, gvtst(1, 0));
4144 break;
4145 case '~':
4146 next();
4147 unary();
4148 vpushi(-1);
4149 gen_op('^');
4150 break;
4151 case '+':
4152 next();
4153 unary();
4154 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
4155 tcc_error("pointer not accepted for unary plus");
4156 /* In order to force cast, we add zero, except for floating point
4157 where we really need an noop (otherwise -0.0 will be transformed
4158 into +0.0). */
4159 if (!is_float(vtop->type.t)) {
4160 vpushi(0);
4161 gen_op('+');
4163 break;
4164 case TOK_SIZEOF:
4165 case TOK_ALIGNOF1:
4166 case TOK_ALIGNOF2:
4167 t = tok;
4168 next();
4169 in_sizeof++;
4170 unary_type(&type); // Perform a in_sizeof = 0;
4171 size = type_size(&type, &align);
4172 if (t == TOK_SIZEOF) {
4173 if (!(type.t & VT_VLA)) {
4174 if (size < 0)
4175 tcc_error("sizeof applied to an incomplete type");
4176 vpushs(size);
4177 } else {
4178 vla_runtime_type_size(&type, &align);
4180 } else {
4181 vpushs(align);
4183 vtop->type.t |= VT_UNSIGNED;
4184 break;
4186 case TOK_builtin_expect:
4188 /* __builtin_expect is a no-op for now */
4189 int saved_nocode_wanted;
4190 next();
4191 skip('(');
4192 expr_eq();
4193 skip(',');
4194 saved_nocode_wanted = nocode_wanted;
4195 nocode_wanted = 1;
4196 expr_lor_const();
4197 vpop();
4198 nocode_wanted = saved_nocode_wanted;
4199 skip(')');
4201 break;
4202 case TOK_builtin_types_compatible_p:
4204 CType type1, type2;
4205 next();
4206 skip('(');
4207 parse_type(&type1);
4208 skip(',');
4209 parse_type(&type2);
4210 skip(')');
4211 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
4212 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
4213 vpushi(is_compatible_types(&type1, &type2));
4215 break;
4216 case TOK_builtin_constant_p:
4218 int saved_nocode_wanted, res;
4219 next();
4220 skip('(');
4221 saved_nocode_wanted = nocode_wanted;
4222 nocode_wanted = 1;
4223 gexpr();
4224 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4225 vpop();
4226 nocode_wanted = saved_nocode_wanted;
4227 skip(')');
4228 vpushi(res);
4230 break;
4231 case TOK_builtin_frame_address:
4232 case TOK_builtin_return_address:
4234 int tok1 = tok;
4235 int level;
4236 CType type;
4237 next();
4238 skip('(');
4239 if (tok != TOK_CINT) {
4240 tcc_error("%s only takes positive integers",
4241 tok1 == TOK_builtin_return_address ?
4242 "__builtin_return_address" :
4243 "__builtin_frame_address");
4245 level = (uint32_t)tokc.i;
4246 next();
4247 skip(')');
4248 type.t = VT_VOID;
4249 mk_pointer(&type);
4250 vset(&type, VT_LOCAL, 0); /* local frame */
4251 while (level--) {
4252 mk_pointer(&vtop->type);
4253 indir(); /* -> parent frame */
4255 if (tok1 == TOK_builtin_return_address) {
4256 // assume return address is just above frame pointer on stack
4257 vpushi(PTR_SIZE);
4258 gen_op('+');
4259 mk_pointer(&vtop->type);
4260 indir();
4263 break;
4264 #ifdef TCC_TARGET_X86_64
4265 #ifdef TCC_TARGET_PE
4266 case TOK_builtin_va_start:
4268 next();
4269 skip('(');
4270 expr_eq();
4271 skip(',');
4272 expr_eq();
4273 skip(')');
4274 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
4275 tcc_error("__builtin_va_start expects a local variable");
4276 vtop->r &= ~(VT_LVAL | VT_REF);
4277 vtop->type = char_pointer_type;
4278 vtop->c.i += 8;
4279 vstore();
4281 break;
4282 #else
4283 case TOK_builtin_va_arg_types:
4285 CType type;
4286 next();
4287 skip('(');
4288 parse_type(&type);
4289 skip(')');
4290 vpushi(classify_x86_64_va_arg(&type));
4292 break;
4293 #endif
4294 #endif
4296 #ifdef TCC_TARGET_ARM64
4297 case TOK___va_start: {
4298 if (nocode_wanted)
4299 tcc_error("statement in global scope");
4300 next();
4301 skip('(');
4302 expr_eq();
4303 skip(',');
4304 expr_eq();
4305 skip(')');
4306 //xx check types
4307 gen_va_start();
4308 vpushi(0);
4309 vtop->type.t = VT_VOID;
4310 break;
4312 case TOK___va_arg: {
4313 CType type;
4314 if (nocode_wanted)
4315 tcc_error("statement in global scope");
4316 next();
4317 skip('(');
4318 expr_eq();
4319 skip(',');
4320 parse_type(&type);
4321 skip(')');
4322 //xx check types
4323 gen_va_arg(&type);
4324 vtop->type = type;
4325 break;
4327 case TOK___arm64_clear_cache: {
4328 next();
4329 skip('(');
4330 expr_eq();
4331 skip(',');
4332 expr_eq();
4333 skip(')');
4334 gen_clear_cache();
4335 vpushi(0);
4336 vtop->type.t = VT_VOID;
4337 break;
4339 #endif
4340 /* pre operations */
4341 case TOK_INC:
4342 case TOK_DEC:
4343 t = tok;
4344 next();
4345 unary();
4346 inc(0, t);
4347 break;
4348 case '-':
4349 next();
4350 unary();
4351 t = vtop->type.t & VT_BTYPE;
4352 if (is_float(t)) {
4353 /* In IEEE negate(x) isn't subtract(0,x), but rather
4354 subtract(-0, x). */
4355 vpush(&vtop->type);
4356 if (t == VT_FLOAT)
4357 vtop->c.f = -0.0f;
4358 else if (t == VT_DOUBLE)
4359 vtop->c.d = -0.0;
4360 else
4361 vtop->c.ld = -0.0;
4362 } else
4363 vpushi(0);
4364 vswap();
4365 gen_op('-');
4366 break;
4367 case TOK_LAND:
4368 if (!gnu_ext)
4369 goto tok_identifier;
4370 next();
4371 /* allow to take the address of a label */
4372 if (tok < TOK_UIDENT)
4373 expect("label identifier");
4374 s = label_find(tok);
4375 if (!s) {
4376 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4377 } else {
4378 if (s->r == LABEL_DECLARED)
4379 s->r = LABEL_FORWARD;
4381 if (!s->type.t) {
4382 s->type.t = VT_VOID;
4383 mk_pointer(&s->type);
4384 s->type.t |= VT_STATIC;
4386 vpushsym(&s->type, s);
4387 next();
4388 break;
4390 // special qnan , snan and infinity values
4391 case TOK___NAN__:
4392 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
4393 next();
4394 break;
4395 case TOK___SNAN__:
4396 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
4397 next();
4398 break;
4399 case TOK___INF__:
4400 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
4401 next();
4402 break;
4404 default:
4405 tok_identifier:
4406 t = tok;
4407 next();
4408 if (t < TOK_UIDENT)
4409 expect("identifier");
4410 s = sym_find(t);
4411 if (!s) {
4412 const char *name = get_tok_str(t, NULL);
4413 if (tok != '(')
4414 tcc_error("'%s' undeclared", name);
4415 /* for simple function calls, we tolerate undeclared
4416 external reference to int() function */
4417 if (tcc_state->warn_implicit_function_declaration
4418 #ifdef TCC_TARGET_PE
4419 /* people must be warned about using undeclared WINAPI functions
4420 (which usually start with uppercase letter) */
4421 || (name[0] >= 'A' && name[0] <= 'Z')
4422 #endif
4424 tcc_warning("implicit declaration of function '%s'", name);
4425 s = external_global_sym(t, &func_old_type, 0);
4427 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
4428 (VT_STATIC | VT_INLINE | VT_FUNC)) {
4429 /* if referencing an inline function, then we generate a
4430 symbol to it if not already done. It will have the
4431 effect to generate code for it at the end of the
4432 compilation unit. Inline function as always
4433 generated in the text section. */
4434 if (!s->c)
4435 put_extern_sym(s, text_section, 0, 0);
4436 r = VT_SYM | VT_CONST;
4437 } else {
4438 r = s->r;
4440 vset(&s->type, r, s->c);
4441 /* if forward reference, we must point to s */
4442 if (vtop->r & VT_SYM) {
4443 vtop->sym = s;
4444 vtop->c.i = 0;
4446 break;
4449 /* post operations */
4450 while (1) {
4451 if (tok == TOK_INC || tok == TOK_DEC) {
4452 inc(1, tok);
4453 next();
4454 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
4455 int qualifiers;
4456 /* field */
4457 if (tok == TOK_ARROW)
4458 indir();
4459 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4460 test_lvalue();
4461 gaddrof();
4462 /* expect pointer on structure */
4463 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4464 expect("struct or union");
4465 if (tok == TOK_CDOUBLE)
4466 expect("field name");
4467 next();
4468 if (tok == TOK_CINT || tok == TOK_CUINT)
4469 expect("field name");
4470 s = vtop->type.ref;
4471 /* find field */
4472 tok |= SYM_FIELD;
4473 while ((s = s->next) != NULL) {
4474 if (s->v == tok)
4475 break;
4477 if (!s)
4478 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
4479 /* add field offset to pointer */
4480 vtop->type = char_pointer_type; /* change type to 'char *' */
4481 vpushi(s->c);
4482 gen_op('+');
4483 /* change type to field type, and set to lvalue */
4484 vtop->type = s->type;
4485 vtop->type.t |= qualifiers;
4486 /* an array is never an lvalue */
4487 if (!(vtop->type.t & VT_ARRAY)) {
4488 vtop->r |= lvalue_type(vtop->type.t);
4489 #ifdef CONFIG_TCC_BCHECK
4490 /* if bound checking, the referenced pointer must be checked */
4491 if (tcc_state->do_bounds_check)
4492 vtop->r |= VT_MUSTBOUND;
4493 #endif
4495 next();
4496 } else if (tok == '[') {
4497 next();
4498 gexpr();
4499 gen_op('+');
4500 indir();
4501 skip(']');
4502 } else if (tok == '(') {
4503 SValue ret;
4504 Sym *sa;
4505 int nb_args, ret_nregs, ret_align, regsize, variadic;
4507 /* function call */
4508 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4509 /* pointer test (no array accepted) */
4510 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4511 vtop->type = *pointed_type(&vtop->type);
4512 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4513 goto error_func;
4514 } else {
4515 error_func:
4516 expect("function pointer");
4518 } else {
4519 vtop->r &= ~VT_LVAL; /* no lvalue */
4521 /* get return type */
4522 s = vtop->type.ref;
4523 next();
4524 sa = s->next; /* first parameter */
4525 nb_args = 0;
4526 ret.r2 = VT_CONST;
4527 /* compute first implicit argument if a structure is returned */
4528 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4529 variadic = (s->c == FUNC_ELLIPSIS);
4530 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4531 &ret_align, &regsize);
4532 if (!ret_nregs) {
4533 /* get some space for the returned structure */
4534 size = type_size(&s->type, &align);
4535 #ifdef TCC_TARGET_ARM64
4536 /* On arm64, a small struct is return in registers.
4537 It is much easier to write it to memory if we know
4538 that we are allowed to write some extra bytes, so
4539 round the allocated space up to a power of 2: */
4540 if (size < 16)
4541 while (size & (size - 1))
4542 size = (size | (size - 1)) + 1;
4543 #endif
4544 loc = (loc - size) & -align;
4545 ret.type = s->type;
4546 ret.r = VT_LOCAL | VT_LVAL;
4547 /* pass it as 'int' to avoid structure arg passing
4548 problems */
4549 vseti(VT_LOCAL, loc);
4550 ret.c = vtop->c;
4551 nb_args++;
4553 } else {
4554 ret_nregs = 1;
4555 ret.type = s->type;
4558 if (ret_nregs) {
4559 /* return in register */
4560 if (is_float(ret.type.t)) {
4561 ret.r = reg_fret(ret.type.t);
4562 #ifdef TCC_TARGET_X86_64
4563 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4564 ret.r2 = REG_QRET;
4565 #endif
4566 } else {
4567 #ifndef TCC_TARGET_ARM64
4568 #ifdef TCC_TARGET_X86_64
4569 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4570 #else
4571 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4572 #endif
4573 ret.r2 = REG_LRET;
4574 #endif
4575 ret.r = REG_IRET;
4577 ret.c.i = 0;
4579 if (tok != ')') {
4580 for(;;) {
4581 expr_eq();
4582 gfunc_param_typed(s, sa);
4583 nb_args++;
4584 if (sa)
4585 sa = sa->next;
4586 if (tok == ')')
4587 break;
4588 skip(',');
4591 if (sa)
4592 tcc_error("too few arguments to function");
4593 skip(')');
4594 if (!nocode_wanted) {
4595 gfunc_call(nb_args);
4596 } else {
4597 vtop -= (nb_args + 1);
4600 /* return value */
4601 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4602 vsetc(&ret.type, r, &ret.c);
4603 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4606 /* handle packed struct return */
4607 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4608 int addr, offset;
4610 size = type_size(&s->type, &align);
4611 /* We're writing whole regs often, make sure there's enough
4612 space. Assume register size is power of 2. */
4613 if (regsize > align)
4614 align = regsize;
4615 loc = (loc - size) & -align;
4616 addr = loc;
4617 offset = 0;
4618 for (;;) {
4619 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4620 vswap();
4621 vstore();
4622 vtop--;
4623 if (--ret_nregs == 0)
4624 break;
4625 offset += regsize;
4627 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4629 } else {
4630 break;
4635 ST_FUNC void expr_prod(void)
4637 int t;
4639 unary();
4640 while (tok == '*' || tok == '/' || tok == '%') {
4641 t = tok;
4642 next();
4643 unary();
4644 gen_op(t);
4648 ST_FUNC void expr_sum(void)
4650 int t;
4652 expr_prod();
4653 while (tok == '+' || tok == '-') {
4654 t = tok;
4655 next();
4656 expr_prod();
4657 gen_op(t);
4661 static void expr_shift(void)
4663 int t;
4665 expr_sum();
4666 while (tok == TOK_SHL || tok == TOK_SAR) {
4667 t = tok;
4668 next();
4669 expr_sum();
4670 gen_op(t);
4674 static void expr_cmp(void)
4676 int t;
4678 expr_shift();
4679 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4680 tok == TOK_ULT || tok == TOK_UGE) {
4681 t = tok;
4682 next();
4683 expr_shift();
4684 gen_op(t);
4688 static void expr_cmpeq(void)
4690 int t;
4692 expr_cmp();
4693 while (tok == TOK_EQ || tok == TOK_NE) {
4694 t = tok;
4695 next();
4696 expr_cmp();
4697 gen_op(t);
4701 static void expr_and(void)
4703 expr_cmpeq();
4704 while (tok == '&') {
4705 next();
4706 expr_cmpeq();
4707 gen_op('&');
4711 static void expr_xor(void)
4713 expr_and();
4714 while (tok == '^') {
4715 next();
4716 expr_and();
4717 gen_op('^');
4721 static void expr_or(void)
4723 expr_xor();
4724 while (tok == '|') {
4725 next();
4726 expr_xor();
4727 gen_op('|');
4731 /* XXX: fix this mess */
4732 static void expr_land_const(void)
4734 expr_or();
4735 while (tok == TOK_LAND) {
4736 next();
4737 expr_or();
4738 gen_op(TOK_LAND);
4741 static void expr_lor_const(void)
4743 expr_land_const();
4744 while (tok == TOK_LOR) {
4745 next();
4746 expr_land_const();
4747 gen_op(TOK_LOR);
4751 static void expr_land(void)
4753 expr_or();
4754 if (tok == TOK_LAND) {
4755 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4756 CType ctb, cti;
4757 ctb.t = VT_BOOL;
4758 cti.t = VT_INT;
4759 next();
4760 gen_cast(&ctb);
4761 if (vtop->c.i) {
4762 vpop();
4763 expr_land();
4764 gen_cast(&ctb);
4765 } else {
4766 int saved_nocode_wanted = nocode_wanted;
4767 nocode_wanted = 1;
4768 expr_land();
4769 vpop();
4770 nocode_wanted = saved_nocode_wanted;
4772 gen_cast(&cti);
4773 } else {
4774 int t = 0;
4775 save_regs(1);
4776 for(;;) {
4777 t = gvtst(1, t);
4778 if (tok != TOK_LAND) {
4779 vseti(VT_JMPI, t);
4780 break;
4782 next();
4783 expr_or();
4789 static void expr_lor(void)
4791 expr_land();
4792 if (tok == TOK_LOR) {
4793 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4794 CType ctb, cti;
4795 ctb.t = VT_BOOL;
4796 cti.t = VT_INT;
4797 next();
4798 gen_cast(&ctb);
4799 if (vtop->c.i) {
4800 int saved_nocode_wanted = nocode_wanted;
4801 nocode_wanted = 1;
4802 expr_lor();
4803 vpop();
4804 nocode_wanted = saved_nocode_wanted;
4805 } else {
4806 vpop();
4807 expr_lor();
4808 gen_cast(&ctb);
4810 gen_cast(&cti);
4811 } else {
4812 int t = 0;
4813 save_regs(1);
4814 for(;;) {
4815 t = gvtst(0, t);
4816 if (tok != TOK_LOR) {
4817 vseti(VT_JMP, t);
4818 break;
4820 next();
4821 expr_land();
4827 static void expr_cond(void)
4829 int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv;
4830 SValue sv;
4831 CType type, type1, type2;
4833 expr_lor();
4834 if (tok == '?') {
4835 next();
4836 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4837 int saved_nocode_wanted = nocode_wanted;
4838 CType boolean;
4839 int c;
4840 boolean.t = VT_BOOL;
4841 vdup();
4842 gen_cast(&boolean);
4843 c = vtop->c.i;
4844 vpop();
4845 if (c) {
4846 if (tok != ':' || !gnu_ext) {
4847 vpop();
4848 gexpr();
4850 skip(':');
4851 nocode_wanted = 1;
4852 expr_cond();
4853 vpop();
4854 nocode_wanted = saved_nocode_wanted;
4855 } else {
4856 vpop();
4857 if (tok != ':' || !gnu_ext) {
4858 nocode_wanted = 1;
4859 gexpr();
4860 vpop();
4861 nocode_wanted = saved_nocode_wanted;
4863 skip(':');
4864 expr_cond();
4867 else {
4868 if (vtop != vstack) {
4869 /* needed to avoid having different registers saved in
4870 each branch */
4871 if (is_float(vtop->type.t)) {
4872 rc = RC_FLOAT;
4873 #ifdef TCC_TARGET_X86_64
4874 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4875 rc = RC_ST0;
4877 #endif
4879 else
4880 rc = RC_INT;
4881 gv(rc);
4882 save_regs(1);
4884 if (tok == ':' && gnu_ext) {
4885 gv_dup();
4886 tt = gvtst(1, 0);
4887 } else {
4888 tt = gvtst(1, 0);
4889 gexpr();
4891 type1 = vtop->type;
4892 sv = *vtop; /* save value to handle it later */
4893 vtop--; /* no vpop so that FP stack is not flushed */
4894 skip(':');
4895 u = gjmp(0);
4896 gsym(tt);
4897 expr_cond();
4898 type2 = vtop->type;
4900 t1 = type1.t;
4901 bt1 = t1 & VT_BTYPE;
4902 t2 = type2.t;
4903 bt2 = t2 & VT_BTYPE;
4904 /* cast operands to correct type according to ISOC rules */
4905 if (is_float(bt1) || is_float(bt2)) {
4906 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4907 type.t = VT_LDOUBLE;
4908 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4909 type.t = VT_DOUBLE;
4910 } else {
4911 type.t = VT_FLOAT;
4913 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4914 /* cast to biggest op */
4915 type.t = VT_LLONG;
4916 /* convert to unsigned if it does not fit in a long long */
4917 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4918 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4919 type.t |= VT_UNSIGNED;
4920 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4921 /* If one is a null ptr constant the result type
4922 is the other. */
4923 if (is_null_pointer (vtop))
4924 type = type1;
4925 else if (is_null_pointer (&sv))
4926 type = type2;
4927 /* XXX: test pointer compatibility, C99 has more elaborate
4928 rules here. */
4929 else
4930 type = type1;
4931 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4932 /* XXX: test function pointer compatibility */
4933 type = bt1 == VT_FUNC ? type1 : type2;
4934 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4935 /* XXX: test structure compatibility */
4936 type = bt1 == VT_STRUCT ? type1 : type2;
4937 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4938 /* NOTE: as an extension, we accept void on only one side */
4939 type.t = VT_VOID;
4940 } else {
4941 /* integer operations */
4942 type.t = VT_INT;
4943 /* convert to unsigned if it does not fit in an integer */
4944 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4945 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4946 type.t |= VT_UNSIGNED;
4948 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
4949 that `(expr ? a : b).mem` does not error with "lvalue expected" */
4950 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
4952 /* now we convert second operand */
4953 gen_cast(&type);
4954 if (islv) {
4955 mk_pointer(&vtop->type);
4956 gaddrof();
4958 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4959 gaddrof();
4960 rc = RC_INT;
4961 if (is_float(type.t)) {
4962 rc = RC_FLOAT;
4963 #ifdef TCC_TARGET_X86_64
4964 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4965 rc = RC_ST0;
4967 #endif
4968 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4969 /* for long longs, we use fixed registers to avoid having
4970 to handle a complicated move */
4971 rc = RC_IRET;
4974 r2 = gv(rc);
4975 /* this is horrible, but we must also convert first
4976 operand */
4977 tt = gjmp(0);
4978 gsym(u);
4979 /* put again first value and cast it */
4980 *vtop = sv;
4981 gen_cast(&type);
4982 if (islv) {
4983 mk_pointer(&vtop->type);
4984 gaddrof();
4986 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4987 gaddrof();
4988 r1 = gv(rc);
4989 move_reg(r2, r1, type.t);
4990 vtop->r = r2;
4991 gsym(tt);
4992 if (islv)
4993 indir();
4998 static void expr_eq(void)
5000 int t;
5002 expr_cond();
5003 if (tok == '=' ||
5004 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5005 tok == TOK_A_XOR || tok == TOK_A_OR ||
5006 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5007 test_lvalue();
5008 t = tok;
5009 next();
5010 if (t == '=') {
5011 expr_eq();
5012 } else {
5013 vdup();
5014 expr_eq();
5015 gen_op(t & 0x7f);
5017 vstore();
5021 ST_FUNC void gexpr(void)
5023 while (1) {
5024 expr_eq();
5025 if (tok != ',')
5026 break;
5027 vpop();
5028 next();
5032 /* parse an expression and return its type without any side effect. */
5033 static void expr_type(CType *type)
5035 int saved_nocode_wanted;
5037 saved_nocode_wanted = nocode_wanted;
5038 nocode_wanted = 1;
5039 gexpr();
5040 *type = vtop->type;
5041 vpop();
5042 nocode_wanted = saved_nocode_wanted;
5045 /* parse a unary expression and return its type without any side
5046 effect. */
5047 static void unary_type(CType *type)
5049 int a;
5051 a = nocode_wanted;
5052 nocode_wanted = 1;
5053 unary();
5054 *type = vtop->type;
5055 vpop();
5056 nocode_wanted = a;
5059 /* parse a constant expression and return value in vtop. */
5060 static void expr_const1(void)
5062 int a;
5063 a = const_wanted;
5064 const_wanted = 1;
5065 expr_cond();
5066 const_wanted = a;
5069 /* parse an integer constant and return its value. */
5070 ST_FUNC int expr_const(void)
5072 int c;
5073 expr_const1();
5074 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5075 expect("constant expression");
5076 c = vtop->c.i;
5077 vpop();
5078 return c;
5081 /* return the label token if current token is a label, otherwise
5082 return zero */
5083 static int is_label(void)
5085 int last_tok;
5087 /* fast test first */
5088 if (tok < TOK_UIDENT)
5089 return 0;
5090 /* no need to save tokc because tok is an identifier */
5091 last_tok = tok;
5092 next();
5093 if (tok == ':') {
5094 next();
5095 return last_tok;
5096 } else {
5097 unget_tok(last_tok);
5098 return 0;
5102 static void label_or_decl(int l)
5104 int last_tok;
5106 /* fast test first */
5107 if (tok >= TOK_UIDENT)
5109 /* no need to save tokc because tok is an identifier */
5110 last_tok = tok;
5111 next();
5112 if (tok == ':') {
5113 unget_tok(last_tok);
5114 return;
5116 unget_tok(last_tok);
5118 decl(l);
5121 static int case_cmp(const void *pa, const void *pb)
5123 int a = (*(struct case_t**) pa)->v1;
5124 int b = (*(struct case_t**) pb)->v1;
5125 return a < b ? -1 : a > b;
5128 static int gcase(struct case_t **base, int len, int case_reg, int *bsym)
5130 struct case_t *p;
5131 int e;
5132 while (len > 4) {
5133 /* binary search */
5134 p = base[len/2];
5135 vseti(case_reg, 0);
5136 vdup();
5137 vpushi(p->v2);
5138 gen_op(TOK_LE);
5139 e = gtst(1, 0);
5140 case_reg = gv(RC_INT);
5141 vpop();
5142 vseti(case_reg, 0);
5143 vdup();
5144 vpushi(p->v1);
5145 gen_op(TOK_GE);
5146 gtst_addr(0, p->sym); /* v1 <= x <= v2 */
5147 case_reg = gv(RC_INT);
5148 vpop();
5149 /* x < v1 */
5150 case_reg = gcase(base, len/2, case_reg, bsym);
5151 if (cur_switch->def_sym)
5152 gjmp_addr(cur_switch->def_sym);
5153 else
5154 *bsym = gjmp(*bsym);
5155 /* x > v2 */
5156 gsym(e);
5157 e = len/2 + 1;
5158 base += e; len -= e;
5160 /* linear scan */
5161 while (len--) {
5162 p = *base++;
5163 vseti(case_reg, 0);
5164 vdup();
5165 vpushi(p->v2);
5166 if (p->v1 == p->v2) {
5167 gen_op(TOK_EQ);
5168 gtst_addr(0, p->sym);
5169 } else {
5170 gen_op(TOK_LE);
5171 e = gtst(1, 0);
5172 case_reg = gv(RC_INT);
5173 vpop();
5174 vseti(case_reg, 0);
5175 vdup();
5176 vpushi(p->v1);
5177 gen_op(TOK_GE);
5178 gtst_addr(0, p->sym);
5179 gsym(e);
5181 case_reg = gv(RC_INT);
5182 vpop();
5184 return case_reg;
5187 static void block(int *bsym, int *csym, int is_expr)
5189 int a, b, c, d;
5190 Sym *s;
5192 /* generate line number info */
5193 if (tcc_state->do_debug &&
5194 (last_line_num != file->line_num || last_ind != ind)) {
5195 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5196 last_ind = ind;
5197 last_line_num = file->line_num;
5200 if (is_expr) {
5201 /* default return value is (void) */
5202 vpushi(0);
5203 vtop->type.t = VT_VOID;
5206 if (tok == TOK_IF) {
5207 /* if test */
5208 next();
5209 skip('(');
5210 gexpr();
5211 skip(')');
5212 a = gvtst(1, 0);
5213 block(bsym, csym, 0);
5214 c = tok;
5215 if (c == TOK_ELSE) {
5216 next();
5217 d = gjmp(0);
5218 gsym(a);
5219 block(bsym, csym, 0);
5220 gsym(d); /* patch else jmp */
5221 } else
5222 gsym(a);
5223 } else if (tok == TOK_WHILE) {
5224 next();
5225 d = ind;
5226 vla_sp_restore();
5227 skip('(');
5228 gexpr();
5229 skip(')');
5230 a = gvtst(1, 0);
5231 b = 0;
5232 ++local_scope;
5233 block(&a, &b, 0);
5234 --local_scope;
5235 if(!nocode_wanted)
5236 gjmp_addr(d);
5237 gsym(a);
5238 gsym_addr(b, d);
5239 } else if (tok == '{') {
5240 Sym *llabel;
5241 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
5243 next();
5244 /* record local declaration stack position */
5245 s = local_stack;
5246 llabel = local_label_stack;
5247 ++local_scope;
5249 /* handle local labels declarations */
5250 if (tok == TOK_LABEL) {
5251 next();
5252 for(;;) {
5253 if (tok < TOK_UIDENT)
5254 expect("label identifier");
5255 label_push(&local_label_stack, tok, LABEL_DECLARED);
5256 next();
5257 if (tok == ',') {
5258 next();
5259 } else {
5260 skip(';');
5261 break;
5265 while (tok != '}') {
5266 label_or_decl(VT_LOCAL);
5267 if (tok != '}') {
5268 if (is_expr)
5269 vpop();
5270 block(bsym, csym, is_expr);
5273 /* pop locally defined labels */
5274 label_pop(&local_label_stack, llabel);
5275 if(is_expr) {
5276 /* XXX: this solution makes only valgrind happy...
5277 triggered by gcc.c-torture/execute/20000917-1.c */
5278 Sym *p;
5279 switch(vtop->type.t & VT_BTYPE) {
5280 /* case VT_PTR: */
5281 /* this breaks a compilation of the linux kernel v2.4.26 */
5282 /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
5283 /* Look a commit a80acab: Display error on statement expressions with complex return type */
5284 /* A pointer is not a complex return type */
5285 case VT_STRUCT:
5286 case VT_ENUM:
5287 case VT_FUNC:
5288 for(p=vtop->type.ref;p;p=p->prev)
5289 if(p->prev==s)
5290 tcc_error("unsupported expression type");
5293 /* pop locally defined symbols */
5294 --local_scope;
5295 sym_pop(&local_stack, s);
5297 /* Pop VLA frames and restore stack pointer if required */
5298 if (vlas_in_scope > saved_vlas_in_scope) {
5299 vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
5300 vla_sp_restore();
5302 vlas_in_scope = saved_vlas_in_scope;
5304 next();
5305 } else if (tok == TOK_RETURN) {
5306 next();
5307 if (tok != ';') {
5308 gexpr();
5309 gen_assign_cast(&func_vt);
5310 #ifdef TCC_TARGET_ARM64
5311 // Perhaps it would be better to use this for all backends:
5312 greturn();
5313 #else
5314 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
5315 CType type, ret_type;
5316 int ret_align, ret_nregs, regsize;
5317 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
5318 &ret_align, &regsize);
5319 if (0 == ret_nregs) {
5320 /* if returning structure, must copy it to implicit
5321 first pointer arg location */
5322 type = func_vt;
5323 mk_pointer(&type);
5324 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
5325 indir();
5326 vswap();
5327 /* copy structure value to pointer */
5328 vstore();
5329 } else {
5330 /* returning structure packed into registers */
5331 int r, size, addr, align;
5332 size = type_size(&func_vt,&align);
5333 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
5334 (vtop->c.i & (ret_align-1)))
5335 && (align & (ret_align-1))) {
5336 loc = (loc - size) & -ret_align;
5337 addr = loc;
5338 type = func_vt;
5339 vset(&type, VT_LOCAL | VT_LVAL, addr);
5340 vswap();
5341 vstore();
5342 vpop();
5343 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
5345 vtop->type = ret_type;
5346 if (is_float(ret_type.t))
5347 r = rc_fret(ret_type.t);
5348 else
5349 r = RC_IRET;
5351 if (ret_nregs == 1)
5352 gv(r);
5353 else {
5354 for (;;) {
5355 vdup();
5356 gv(r);
5357 vpop();
5358 if (--ret_nregs == 0)
5359 break;
5360 /* We assume that when a structure is returned in multiple
5361 registers, their classes are consecutive values of the
5362 suite s(n) = 2^n */
5363 r <<= 1;
5364 vtop->c.i += regsize;
5368 } else if (is_float(func_vt.t)) {
5369 gv(rc_fret(func_vt.t));
5370 } else {
5371 gv(RC_IRET);
5373 #endif
5374 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5376 skip(';');
5377 /* jump unless last stmt in top-level block */
5378 if (tok != '}' || local_scope != 1)
5379 rsym = gjmp(rsym);
5380 } else if (tok == TOK_BREAK) {
5381 /* compute jump */
5382 if (!bsym)
5383 tcc_error("cannot break");
5384 *bsym = gjmp(*bsym);
5385 next();
5386 skip(';');
5387 } else if (tok == TOK_CONTINUE) {
5388 /* compute jump */
5389 if (!csym)
5390 tcc_error("cannot continue");
5391 vla_sp_restore_root();
5392 *csym = gjmp(*csym);
5393 next();
5394 skip(';');
5395 } else if (tok == TOK_FOR) {
5396 int e;
5397 next();
5398 skip('(');
5399 s = local_stack;
5400 ++local_scope;
5401 if (tok != ';') {
5402 /* c99 for-loop init decl? */
5403 if (!decl0(VT_LOCAL, 1)) {
5404 /* no, regular for-loop init expr */
5405 gexpr();
5406 vpop();
5409 skip(';');
5410 d = ind;
5411 c = ind;
5412 vla_sp_restore();
5413 a = 0;
5414 b = 0;
5415 if (tok != ';') {
5416 gexpr();
5417 a = gvtst(1, 0);
5419 skip(';');
5420 if (tok != ')') {
5421 e = gjmp(0);
5422 c = ind;
5423 vla_sp_restore();
5424 gexpr();
5425 vpop();
5426 gjmp_addr(d);
5427 gsym(e);
5429 skip(')');
5430 block(&a, &b, 0);
5431 if(!nocode_wanted)
5432 gjmp_addr(c);
5433 gsym(a);
5434 gsym_addr(b, c);
5435 --local_scope;
5436 sym_pop(&local_stack, s);
5438 } else
5439 if (tok == TOK_DO) {
5440 next();
5441 a = 0;
5442 b = 0;
5443 d = ind;
5444 vla_sp_restore();
5445 block(&a, &b, 0);
5446 skip(TOK_WHILE);
5447 skip('(');
5448 gsym(b);
5449 gexpr();
5450 c = gvtst(0, 0);
5451 gsym_addr(c, d);
5452 skip(')');
5453 gsym(a);
5454 skip(';');
5455 } else
5456 if (tok == TOK_SWITCH) {
5457 struct switch_t *saved, sw;
5458 next();
5459 skip('(');
5460 gexpr();
5461 /* XXX: other types than integer */
5462 c = gv(RC_INT);
5463 vpop();
5464 skip(')');
5465 a = 0;
5466 b = gjmp(0); /* jump to first case */
5467 sw.p = NULL; sw.n = 0; sw.def_sym = 0;
5468 saved = cur_switch;
5469 cur_switch = &sw;
5470 block(&a, csym, 0);
5471 a = gjmp(a); /* add implicit break */
5472 /* case lookup */
5473 gsym(b);
5474 qsort(sw.p, sw.n, sizeof(void*), case_cmp);
5475 for (b = 1; b < sw.n; b++)
5476 if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
5477 tcc_error("duplicate case value");
5478 gcase(sw.p, sw.n, c, &a);
5479 if (sw.def_sym)
5480 gjmp_addr(sw.def_sym);
5481 dynarray_reset(&sw.p, &sw.n);
5482 cur_switch = saved;
5483 /* break label */
5484 gsym(a);
5485 } else
5486 if (tok == TOK_CASE) {
5487 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
5488 if (!cur_switch)
5489 expect("switch");
5490 next();
5491 cr->v1 = cr->v2 = expr_const();
5492 if (gnu_ext && tok == TOK_DOTS) {
5493 next();
5494 cr->v2 = expr_const();
5495 if (cr->v2 < cr->v1)
5496 tcc_warning("empty case range");
5498 cr->sym = ind;
5499 dynarray_add((void***) &cur_switch->p, &cur_switch->n, cr);
5500 skip(':');
5501 is_expr = 0;
5502 goto block_after_label;
5503 } else
5504 if (tok == TOK_DEFAULT) {
5505 next();
5506 skip(':');
5507 if (!cur_switch)
5508 expect("switch");
5509 if (cur_switch->def_sym)
5510 tcc_error("too many 'default'");
5511 cur_switch->def_sym = ind;
5512 is_expr = 0;
5513 goto block_after_label;
5514 } else
5515 if (tok == TOK_GOTO) {
5516 next();
5517 if (tok == '*' && gnu_ext) {
5518 /* computed goto */
5519 next();
5520 gexpr();
5521 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5522 expect("pointer");
5523 ggoto();
5524 } else if (tok >= TOK_UIDENT) {
5525 s = label_find(tok);
5526 /* put forward definition if needed */
5527 if (!s) {
5528 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5529 } else {
5530 if (s->r == LABEL_DECLARED)
5531 s->r = LABEL_FORWARD;
5533 vla_sp_restore_root();
5534 if (s->r & LABEL_FORWARD)
5535 s->jnext = gjmp(s->jnext);
5536 else
5537 gjmp_addr(s->jnext);
5538 next();
5539 } else {
5540 expect("label identifier");
5542 skip(';');
5543 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
5544 asm_instr();
5545 } else {
5546 b = is_label();
5547 if (b) {
5548 /* label case */
5549 s = label_find(b);
5550 if (s) {
5551 if (s->r == LABEL_DEFINED)
5552 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
5553 gsym(s->jnext);
5554 s->r = LABEL_DEFINED;
5555 } else {
5556 s = label_push(&global_label_stack, b, LABEL_DEFINED);
5558 s->jnext = ind;
5559 vla_sp_restore();
5560 /* we accept this, but it is a mistake */
5561 block_after_label:
5562 if (tok == '}') {
5563 tcc_warning("deprecated use of label at end of compound statement");
5564 } else {
5565 if (is_expr)
5566 vpop();
5567 block(bsym, csym, is_expr);
5569 } else {
5570 /* expression case */
5571 if (tok != ';') {
5572 if (is_expr) {
5573 vpop();
5574 gexpr();
5575 } else {
5576 gexpr();
5577 vpop();
5580 skip(';');
5585 /* t is the array or struct type. c is the array or struct
5586 address. cur_index/cur_field is the pointer to the current
5587 value. 'size_only' is true if only size info is needed (only used
5588 in arrays) */
5589 static void decl_designator(CType *type, Section *sec, unsigned long c,
5590 int *cur_index, Sym **cur_field,
5591 int size_only)
5593 Sym *s, *f;
5594 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5595 CType type1;
5597 notfirst = 0;
5598 elem_size = 0;
5599 nb_elems = 1;
5600 if (gnu_ext && (l = is_label()) != 0)
5601 goto struct_field;
5602 while (tok == '[' || tok == '.') {
5603 if (tok == '[') {
5604 if (!(type->t & VT_ARRAY))
5605 expect("array type");
5606 s = type->ref;
5607 next();
5608 index = expr_const();
5609 if (index < 0 || (s->c >= 0 && index >= s->c))
5610 expect("invalid index");
5611 if (tok == TOK_DOTS && gnu_ext) {
5612 next();
5613 index_last = expr_const();
5614 if (index_last < 0 ||
5615 (s->c >= 0 && index_last >= s->c) ||
5616 index_last < index)
5617 expect("invalid index");
5618 } else {
5619 index_last = index;
5621 skip(']');
5622 if (!notfirst)
5623 *cur_index = index_last;
5624 type = pointed_type(type);
5625 elem_size = type_size(type, &align);
5626 c += index * elem_size;
5627 /* NOTE: we only support ranges for last designator */
5628 nb_elems = index_last - index + 1;
5629 if (nb_elems != 1) {
5630 notfirst = 1;
5631 break;
5633 } else {
5634 next();
5635 l = tok;
5636 next();
5637 struct_field:
5638 if ((type->t & VT_BTYPE) != VT_STRUCT)
5639 expect("struct/union type");
5640 s = type->ref;
5641 l |= SYM_FIELD;
5642 f = s->next;
5643 while (f) {
5644 if (f->v == l)
5645 break;
5646 f = f->next;
5648 if (!f)
5649 expect("field");
5650 if (!notfirst)
5651 *cur_field = f;
5652 /* XXX: fix this mess by using explicit storage field */
5653 type1 = f->type;
5654 type1.t |= (type->t & ~VT_TYPE);
5655 type = &type1;
5656 c += f->c;
5658 notfirst = 1;
5660 if (notfirst) {
5661 if (tok == '=') {
5662 next();
5663 } else {
5664 if (!gnu_ext)
5665 expect("=");
5667 } else {
5668 if (type->t & VT_ARRAY) {
5669 index = *cur_index;
5670 type = pointed_type(type);
5671 c += index * type_size(type, &align);
5672 } else {
5673 f = *cur_field;
5674 if (!f)
5675 tcc_error("too many field init");
5676 /* XXX: fix this mess by using explicit storage field */
5677 type1 = f->type;
5678 type1.t |= (type->t & ~VT_TYPE);
5679 type = &type1;
5680 c += f->c;
5683 decl_initializer(type, sec, c, 0, size_only);
5685 /* XXX: make it more general */
5686 if (!size_only && nb_elems > 1) {
5687 unsigned long c_end;
5688 uint8_t *src, *dst;
5689 int i;
5691 if (!sec)
5692 tcc_error("range init not supported yet for dynamic storage");
5693 c_end = c + nb_elems * elem_size;
5694 if (c_end > sec->data_allocated)
5695 section_realloc(sec, c_end);
5696 src = sec->data + c;
5697 dst = src;
5698 for(i = 1; i < nb_elems; i++) {
5699 dst += elem_size;
5700 memcpy(dst, src, elem_size);
5705 #define EXPR_VAL 0
5706 #define EXPR_CONST 1
5707 #define EXPR_ANY 2
5709 /* store a value or an expression directly in global data or in local array */
5710 static void init_putv(CType *type, Section *sec, unsigned long c,
5711 int v, int expr_type)
5713 int saved_global_expr, bt, bit_pos, bit_size;
5714 void *ptr;
5715 unsigned long long bit_mask;
5716 CType dtype;
5718 switch(expr_type) {
5719 case EXPR_VAL:
5720 vpushi(v);
5721 break;
5722 case EXPR_CONST:
5723 /* compound literals must be allocated globally in this case */
5724 saved_global_expr = global_expr;
5725 global_expr = 1;
5726 expr_const1();
5727 global_expr = saved_global_expr;
5728 /* NOTE: symbols are accepted */
5729 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5730 tcc_error("initializer element is not constant");
5731 break;
5732 case EXPR_ANY:
5733 expr_eq();
5734 break;
5737 dtype = *type;
5738 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5740 if (sec) {
5741 /* XXX: not portable */
5742 /* XXX: generate error if incorrect relocation */
5743 gen_assign_cast(&dtype);
5744 bt = type->t & VT_BTYPE;
5745 /* we'll write at most 16 bytes */
5746 if (c + 16 > sec->data_allocated) {
5747 section_realloc(sec, c + 16);
5749 ptr = sec->data + c;
5750 /* XXX: make code faster ? */
5751 if (!(type->t & VT_BITFIELD)) {
5752 bit_pos = 0;
5753 bit_size = 32;
5754 bit_mask = -1LL;
5755 } else {
5756 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5757 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5758 bit_mask = (1LL << bit_size) - 1;
5760 if ((vtop->r & VT_SYM) &&
5761 (bt == VT_BYTE ||
5762 bt == VT_SHORT ||
5763 bt == VT_DOUBLE ||
5764 bt == VT_LDOUBLE ||
5765 bt == VT_LLONG ||
5766 (bt == VT_INT && bit_size != 32)))
5767 tcc_error("initializer element is not computable at load time");
5768 switch(bt) {
5769 /* XXX: when cross-compiling we assume that each type has the
5770 same representation on host and target, which is likely to
5771 be wrong in the case of long double */
5772 case VT_BOOL:
5773 vtop->c.i = (vtop->c.i != 0);
5774 case VT_BYTE:
5775 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5776 break;
5777 case VT_SHORT:
5778 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5779 break;
5780 case VT_DOUBLE:
5781 *(double *)ptr = vtop->c.d;
5782 break;
5783 case VT_LDOUBLE:
5784 if (sizeof(long double) == LDOUBLE_SIZE)
5785 *(long double *)ptr = vtop->c.ld;
5786 else if (sizeof(double) == LDOUBLE_SIZE)
5787 *(double *)ptr = vtop->c.ld;
5788 else
5789 tcc_error("can't cross compile long double constants");
5790 break;
5791 case VT_LLONG:
5792 *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5793 break;
5794 case VT_PTR: {
5795 addr_t val = (vtop->c.i & bit_mask) << bit_pos;
5796 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5797 if (vtop->r & VT_SYM)
5798 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5799 else
5800 *(addr_t *)ptr |= val;
5801 #else
5802 if (vtop->r & VT_SYM)
5803 greloc(sec, vtop->sym, c, R_DATA_PTR);
5804 *(addr_t *)ptr |= val;
5805 #endif
5806 break;
5808 default: {
5809 int val = (vtop->c.i & bit_mask) << bit_pos;
5810 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5811 if (vtop->r & VT_SYM)
5812 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5813 else
5814 *(int *)ptr |= val;
5815 #else
5816 if (vtop->r & VT_SYM)
5817 greloc(sec, vtop->sym, c, R_DATA_PTR);
5818 *(int *)ptr |= val;
5819 #endif
5820 break;
5823 vtop--;
5824 } else {
5825 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5826 vswap();
5827 vstore();
5828 vpop();
5832 /* put zeros for variable based init */
5833 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5835 if (sec) {
5836 /* nothing to do because globals are already set to zero */
5837 } else {
5838 vpush_global_sym(&func_old_type, TOK_memset);
5839 vseti(VT_LOCAL, c);
5840 #ifdef TCC_TARGET_ARM
5841 vpushs(size);
5842 vpushi(0);
5843 #else
5844 vpushi(0);
5845 vpushs(size);
5846 #endif
5847 gfunc_call(3);
5851 /* 't' contains the type and storage info. 'c' is the offset of the
5852 object in section 'sec'. If 'sec' is NULL, it means stack based
5853 allocation. 'first' is true if array '{' must be read (multi
5854 dimension implicit array init handling). 'size_only' is true if
5855 size only evaluation is wanted (only for arrays). */
5856 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5857 int first, int size_only)
5859 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5860 int size1, align1, expr_type;
5861 Sym *s, *f;
5862 CType *t1;
5864 if (type->t & VT_VLA) {
5865 int a;
5867 /* save current stack pointer */
5868 if (vlas_in_scope == 0) {
5869 if (vla_sp_root_loc == -1)
5870 vla_sp_root_loc = (loc -= PTR_SIZE);
5871 gen_vla_sp_save(vla_sp_root_loc);
5874 vla_runtime_type_size(type, &a);
5875 gen_vla_alloc(type, a);
5876 gen_vla_sp_save(c);
5877 vla_sp_loc = c;
5878 vlas_in_scope++;
5879 } else if (type->t & VT_ARRAY) {
5880 s = type->ref;
5881 n = s->c;
5882 array_length = 0;
5883 t1 = pointed_type(type);
5884 size1 = type_size(t1, &align1);
5886 no_oblock = 1;
5887 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5888 tok == '{') {
5889 if (tok != '{')
5890 tcc_error("character array initializer must be a literal,"
5891 " optionally enclosed in braces");
5892 skip('{');
5893 no_oblock = 0;
5896 /* only parse strings here if correct type (otherwise: handle
5897 them as ((w)char *) expressions */
5898 if ((tok == TOK_LSTR &&
5899 #ifdef TCC_TARGET_PE
5900 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5901 #else
5902 (t1->t & VT_BTYPE) == VT_INT
5903 #endif
5904 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5905 while (tok == TOK_STR || tok == TOK_LSTR) {
5906 int cstr_len, ch;
5908 /* compute maximum number of chars wanted */
5909 if (tok == TOK_STR)
5910 cstr_len = tokc.str.size;
5911 else
5912 cstr_len = tokc.str.size / sizeof(nwchar_t);
5913 cstr_len--;
5914 nb = cstr_len;
5915 if (n >= 0 && nb > (n - array_length))
5916 nb = n - array_length;
5917 if (!size_only) {
5918 if (cstr_len > nb)
5919 tcc_warning("initializer-string for array is too long");
5920 /* in order to go faster for common case (char
5921 string in global variable, we handle it
5922 specifically */
5923 if (sec && tok == TOK_STR && size1 == 1) {
5924 memcpy(sec->data + c + array_length, tokc.str.data, nb);
5925 } else {
5926 for(i=0;i<nb;i++) {
5927 if (tok == TOK_STR)
5928 ch = ((unsigned char *)tokc.str.data)[i];
5929 else
5930 ch = ((nwchar_t *)tokc.str.data)[i];
5931 init_putv(t1, sec, c + (array_length + i) * size1,
5932 ch, EXPR_VAL);
5936 array_length += nb;
5937 next();
5939 /* only add trailing zero if enough storage (no
5940 warning in this case since it is standard) */
5941 if (n < 0 || array_length < n) {
5942 if (!size_only) {
5943 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5945 array_length++;
5947 } else {
5948 index = 0;
5949 while (tok != '}') {
5950 decl_designator(type, sec, c, &index, NULL, size_only);
5951 if (n >= 0 && index >= n)
5952 tcc_error("index too large");
5953 /* must put zero in holes (note that doing it that way
5954 ensures that it even works with designators) */
5955 if (!size_only && array_length < index) {
5956 init_putz(t1, sec, c + array_length * size1,
5957 (index - array_length) * size1);
5959 index++;
5960 if (index > array_length)
5961 array_length = index;
5962 /* special test for multi dimensional arrays (may not
5963 be strictly correct if designators are used at the
5964 same time) */
5965 if (index >= n && no_oblock)
5966 break;
5967 if (tok == '}')
5968 break;
5969 skip(',');
5972 if (!no_oblock)
5973 skip('}');
5974 /* put zeros at the end */
5975 if (!size_only && n >= 0 && array_length < n) {
5976 init_putz(t1, sec, c + array_length * size1,
5977 (n - array_length) * size1);
5979 /* patch type size if needed */
5980 if (n < 0)
5981 s->c = array_length;
5982 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5983 (sec || !first || tok == '{')) {
5985 /* NOTE: the previous test is a specific case for automatic
5986 struct/union init */
5987 /* XXX: union needs only one init */
5989 int par_count = 0;
5990 if (tok == '(') {
5991 AttributeDef ad1;
5992 CType type1;
5993 next();
5994 if (tcc_state->old_struct_init_code) {
5995 /* an old version of struct initialization.
5996 It have a problems. But with a new version
5997 linux 2.4.26 can't load ramdisk.
5999 while (tok == '(') {
6000 par_count++;
6001 next();
6003 if (!parse_btype(&type1, &ad1))
6004 expect("cast");
6005 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
6006 #if 0
6007 if (!is_assignable_types(type, &type1))
6008 tcc_error("invalid type for cast");
6009 #endif
6010 skip(')');
6012 else
6014 if (tok != '(') {
6015 if (!parse_btype(&type1, &ad1))
6016 expect("cast");
6017 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
6018 #if 0
6019 if (!is_assignable_types(type, &type1))
6020 tcc_error("invalid type for cast");
6021 #endif
6022 skip(')');
6023 } else
6024 unget_tok(tok);
6028 no_oblock = 1;
6029 if (first || tok == '{') {
6030 skip('{');
6031 no_oblock = 0;
6033 s = type->ref;
6034 f = s->next;
6035 array_length = 0;
6036 index = 0;
6037 n = s->c;
6038 while (tok != '}') {
6039 decl_designator(type, sec, c, NULL, &f, size_only);
6040 index = f->c;
6041 if (!size_only && array_length < index) {
6042 init_putz(type, sec, c + array_length,
6043 index - array_length);
6045 index = index + type_size(&f->type, &align1);
6046 if (index > array_length)
6047 array_length = index;
6049 /* gr: skip fields from same union - ugly. */
6050 while (f->next) {
6051 int align = 0;
6052 int f_size = type_size(&f->type, &align);
6053 int f_type = (f->type.t & VT_BTYPE);
6055 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
6056 /* test for same offset */
6057 if (f->next->c != f->c)
6058 break;
6059 if ((f_type == VT_STRUCT) && (f_size == 0)) {
6061 Lets assume a structure of size 0 can't be a member of the union.
6062 This allow to compile the following code from a linux kernel v2.4.26
6063 typedef struct { } rwlock_t;
6064 struct fs_struct {
6065 int count;
6066 rwlock_t lock;
6067 int umask;
6069 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
6070 tcc-0.9.23 can succesfully compile this version of the kernel.
6071 gcc don't have problems with this code too.
6073 break;
6075 /* if yes, test for bitfield shift */
6076 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
6077 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
6078 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
6079 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
6080 if (bit_pos_1 != bit_pos_2)
6081 break;
6083 f = f->next;
6086 f = f->next;
6087 if (no_oblock && f == NULL)
6088 break;
6089 if (tok == '}')
6090 break;
6091 skip(',');
6093 /* put zeros at the end */
6094 if (!size_only && array_length < n) {
6095 init_putz(type, sec, c + array_length,
6096 n - array_length);
6098 if (!no_oblock)
6099 skip('}');
6100 while (par_count) {
6101 skip(')');
6102 par_count--;
6104 } else if (tok == '{') {
6105 next();
6106 decl_initializer(type, sec, c, first, size_only);
6107 skip('}');
6108 } else if (size_only) {
6109 /* just skip expression */
6110 parlevel = parlevel1 = 0;
6111 while ((parlevel > 0 || parlevel1 > 0 ||
6112 (tok != '}' && tok != ',')) && tok != -1) {
6113 if (tok == '(')
6114 parlevel++;
6115 else if (tok == ')') {
6116 if (parlevel == 0 && parlevel1 == 0)
6117 break;
6118 parlevel--;
6120 else if (tok == '{')
6121 parlevel1++;
6122 else if (tok == '}') {
6123 if (parlevel == 0 && parlevel1 == 0)
6124 break;
6125 parlevel1--;
6127 next();
6129 } else {
6130 /* currently, we always use constant expression for globals
6131 (may change for scripting case) */
6132 expr_type = EXPR_CONST;
6133 if (!sec)
6134 expr_type = EXPR_ANY;
6135 init_putv(type, sec, c, 0, expr_type);
6139 /* parse an initializer for type 't' if 'has_init' is non zero, and
6140 allocate space in local or global data space ('r' is either
6141 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6142 variable 'v' of scope 'scope' is declared before initializers
6143 are parsed. If 'v' is zero, then a reference to the new object
6144 is put in the value stack. If 'has_init' is 2, a special parsing
6145 is done to handle string constants. */
6146 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
6147 int has_init, int v, int scope)
6149 int size, align, addr, data_offset;
6150 int level;
6151 ParseState saved_parse_state = {0};
6152 TokenString *init_str = NULL;
6153 Section *sec;
6154 Sym *flexible_array;
6156 flexible_array = NULL;
6157 if ((type->t & VT_BTYPE) == VT_STRUCT) {
6158 Sym *field = type->ref->next;
6159 if (field) {
6160 while (field->next)
6161 field = field->next;
6162 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
6163 flexible_array = field;
6167 size = type_size(type, &align);
6168 /* If unknown size, we must evaluate it before
6169 evaluating initializers because
6170 initializers can generate global data too
6171 (e.g. string pointers or ISOC99 compound
6172 literals). It also simplifies local
6173 initializers handling */
6174 if (size < 0 || (flexible_array && has_init)) {
6175 if (!has_init)
6176 tcc_error("unknown type size");
6177 /* get all init string */
6178 init_str = tok_str_alloc();
6179 if (has_init == 2) {
6180 /* only get strings */
6181 while (tok == TOK_STR || tok == TOK_LSTR) {
6182 tok_str_add_tok(init_str);
6183 next();
6185 } else {
6186 level = 0;
6187 while (level > 0 || (tok != ',' && tok != ';')) {
6188 if (tok < 0)
6189 tcc_error("unexpected end of file in initializer");
6190 tok_str_add_tok(init_str);
6191 if (tok == '{')
6192 level++;
6193 else if (tok == '}') {
6194 level--;
6195 if (level <= 0) {
6196 next();
6197 break;
6200 next();
6203 tok_str_add(init_str, -1);
6204 tok_str_add(init_str, 0);
6206 /* compute size */
6207 save_parse_state(&saved_parse_state);
6209 begin_macro(init_str, 1);
6210 next();
6211 decl_initializer(type, NULL, 0, 1, 1);
6212 /* prepare second initializer parsing */
6213 macro_ptr = init_str->str;
6214 next();
6216 /* if still unknown size, error */
6217 size = type_size(type, &align);
6218 if (size < 0)
6219 tcc_error("unknown type size");
6221 /* If there's a flex member and it was used in the initializer
6222 adjust size. */
6223 if (flexible_array &&
6224 flexible_array->type.ref->c > 0)
6225 size += flexible_array->type.ref->c
6226 * pointed_size(&flexible_array->type);
6227 /* take into account specified alignment if bigger */
6228 if (ad->a.aligned) {
6229 if (ad->a.aligned > align)
6230 align = ad->a.aligned;
6231 } else if (ad->a.packed) {
6232 align = 1;
6234 if ((r & VT_VALMASK) == VT_LOCAL) {
6235 sec = NULL;
6236 #ifdef CONFIG_TCC_BCHECK
6237 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
6238 loc--;
6240 #endif
6241 loc = (loc - size) & -align;
6242 addr = loc;
6243 #ifdef CONFIG_TCC_BCHECK
6244 /* handles bounds */
6245 /* XXX: currently, since we do only one pass, we cannot track
6246 '&' operators, so we add only arrays */
6247 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
6248 addr_t *bounds_ptr;
6249 /* add padding between regions */
6250 loc--;
6251 /* then add local bound info */
6252 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
6253 bounds_ptr[0] = addr;
6254 bounds_ptr[1] = size;
6256 #endif
6257 if (v) {
6258 /* local variable */
6259 sym_push(v, type, r, addr);
6260 } else {
6261 /* push local reference */
6262 vset(type, r, addr);
6264 } else {
6265 Sym *sym;
6267 sym = NULL;
6268 if (v && scope == VT_CONST) {
6269 /* see if the symbol was already defined */
6270 sym = sym_find(v);
6271 if (sym) {
6272 if (!is_compatible_types(&sym->type, type))
6273 tcc_error("incompatible types for redefinition of '%s'",
6274 get_tok_str(v, NULL));
6275 if (sym->type.t & VT_EXTERN) {
6276 /* if the variable is extern, it was not allocated */
6277 sym->type.t &= ~VT_EXTERN;
6278 /* set array size if it was omitted in extern
6279 declaration */
6280 if ((sym->type.t & VT_ARRAY) &&
6281 sym->type.ref->c < 0 &&
6282 type->ref->c >= 0)
6283 sym->type.ref->c = type->ref->c;
6284 } else {
6285 /* we accept several definitions of the same
6286 global variable. this is tricky, because we
6287 must play with the SHN_COMMON type of the symbol */
6288 /* XXX: should check if the variable was already
6289 initialized. It is incorrect to initialized it
6290 twice */
6291 /* no init data, we won't add more to the symbol */
6292 if (!has_init)
6293 goto no_alloc;
6298 /* allocate symbol in corresponding section */
6299 sec = ad->section;
6300 if (!sec) {
6301 if (has_init)
6302 sec = data_section;
6303 else if (tcc_state->nocommon)
6304 sec = bss_section;
6306 if (sec) {
6307 data_offset = sec->data_offset;
6308 data_offset = (data_offset + align - 1) & -align;
6309 addr = data_offset;
6310 /* very important to increment global pointer at this time
6311 because initializers themselves can create new initializers */
6312 data_offset += size;
6313 #ifdef CONFIG_TCC_BCHECK
6314 /* add padding if bound check */
6315 if (tcc_state->do_bounds_check)
6316 data_offset++;
6317 #endif
6318 sec->data_offset = data_offset;
6319 /* allocate section space to put the data */
6320 if (sec->sh_type != SHT_NOBITS &&
6321 data_offset > sec->data_allocated)
6322 section_realloc(sec, data_offset);
6323 /* align section if needed */
6324 if (align > sec->sh_addralign)
6325 sec->sh_addralign = align;
6326 } else {
6327 addr = 0; /* avoid warning */
6330 if (v) {
6331 if (scope != VT_CONST || !sym) {
6332 sym = sym_push(v, type, r | VT_SYM, 0);
6333 sym->asm_label = ad->asm_label;
6335 /* update symbol definition */
6336 if (sec) {
6337 put_extern_sym(sym, sec, addr, size);
6338 } else {
6339 ElfW(Sym) *esym;
6340 /* put a common area */
6341 put_extern_sym(sym, NULL, align, size);
6342 /* XXX: find a nicer way */
6343 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
6344 esym->st_shndx = SHN_COMMON;
6346 } else {
6347 /* push global reference */
6348 sym = get_sym_ref(type, sec, addr, size);
6349 vpushsym(type, sym);
6351 /* patch symbol weakness */
6352 if (type->t & VT_WEAK)
6353 weaken_symbol(sym);
6354 apply_visibility(sym, type);
6355 #ifdef CONFIG_TCC_BCHECK
6356 /* handles bounds now because the symbol must be defined
6357 before for the relocation */
6358 if (tcc_state->do_bounds_check) {
6359 addr_t *bounds_ptr;
6361 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
6362 /* then add global bound info */
6363 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
6364 bounds_ptr[0] = 0; /* relocated */
6365 bounds_ptr[1] = size;
6367 #endif
6369 if (has_init || (type->t & VT_VLA)) {
6370 decl_initializer(type, sec, addr, 1, 0);
6371 /* patch flexible array member size back to -1, */
6372 /* for possible subsequent similar declarations */
6373 if (flexible_array)
6374 flexible_array->type.ref->c = -1;
6376 no_alloc: ;
6377 /* restore parse state if needed */
6378 if (init_str) {
6379 end_macro();
6380 restore_parse_state(&saved_parse_state);
6384 static void put_func_debug(Sym *sym)
6386 char buf[512];
6388 /* stabs info */
6389 /* XXX: we put here a dummy type */
6390 snprintf(buf, sizeof(buf), "%s:%c1",
6391 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
6392 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6393 cur_text_section, sym->c);
6394 /* //gr gdb wants a line at the function */
6395 put_stabn(N_SLINE, 0, file->line_num, 0);
6396 last_ind = 0;
6397 last_line_num = 0;
6400 /* parse an old style function declaration list */
6401 /* XXX: check multiple parameter */
6402 static void func_decl_list(Sym *func_sym)
6404 AttributeDef ad;
6405 int v;
6406 Sym *s;
6407 CType btype, type;
6409 /* parse each declaration */
6410 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
6411 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
6412 if (!parse_btype(&btype, &ad))
6413 expect("declaration list");
6414 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6415 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6416 tok == ';') {
6417 /* we accept no variable after */
6418 } else {
6419 for(;;) {
6420 type = btype;
6421 type_decl(&type, &ad, &v, TYPE_DIRECT);
6422 /* find parameter in function parameter list */
6423 s = func_sym->next;
6424 while (s != NULL) {
6425 if ((s->v & ~SYM_FIELD) == v)
6426 goto found;
6427 s = s->next;
6429 tcc_error("declaration for parameter '%s' but no such parameter",
6430 get_tok_str(v, NULL));
6431 found:
6432 /* check that no storage specifier except 'register' was given */
6433 if (type.t & VT_STORAGE)
6434 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
6435 convert_parameter_type(&type);
6436 /* we can add the type (NOTE: it could be local to the function) */
6437 s->type = type;
6438 /* accept other parameters */
6439 if (tok == ',')
6440 next();
6441 else
6442 break;
6445 skip(';');
6449 /* parse a function defined by symbol 'sym' and generate its code in
6450 'cur_text_section' */
6451 static void gen_function(Sym *sym)
6453 int saved_nocode_wanted = nocode_wanted;
6455 nocode_wanted = 0;
6456 ind = cur_text_section->data_offset;
6457 /* NOTE: we patch the symbol size later */
6458 put_extern_sym(sym, cur_text_section, ind, 0);
6459 funcname = get_tok_str(sym->v, NULL);
6460 func_ind = ind;
6461 /* Initialize VLA state */
6462 vla_sp_loc = -1;
6463 vla_sp_root_loc = -1;
6464 /* put debug symbol */
6465 if (tcc_state->do_debug)
6466 put_func_debug(sym);
6468 /* push a dummy symbol to enable local sym storage */
6469 sym_push2(&local_stack, SYM_FIELD, 0, 0);
6470 local_scope = 1; /* for function parameters */
6471 gfunc_prolog(&sym->type);
6472 local_scope = 0;
6474 rsym = 0;
6475 block(NULL, NULL, 0);
6476 gsym(rsym);
6477 gfunc_epilog();
6478 cur_text_section->data_offset = ind;
6479 label_pop(&global_label_stack, NULL);
6480 /* reset local stack */
6481 local_scope = 0;
6482 sym_pop(&local_stack, NULL);
6483 /* end of function */
6484 /* patch symbol size */
6485 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
6486 ind - func_ind;
6487 /* patch symbol weakness (this definition overrules any prototype) */
6488 if (sym->type.t & VT_WEAK)
6489 weaken_symbol(sym);
6490 apply_visibility(sym, &sym->type);
6491 if (tcc_state->do_debug) {
6492 put_stabn(N_FUN, 0, 0, ind - func_ind);
6494 /* It's better to crash than to generate wrong code */
6495 cur_text_section = NULL;
6496 funcname = ""; /* for safety */
6497 func_vt.t = VT_VOID; /* for safety */
6498 func_var = 0; /* for safety */
6499 ind = 0; /* for safety */
6500 nocode_wanted = saved_nocode_wanted;
6501 check_vstack();
6504 static void gen_inline_functions(TCCState *s)
6506 Sym *sym;
6507 int inline_generated, i, ln;
6508 struct InlineFunc *fn;
6510 ln = file->line_num;
6511 /* iterate while inline function are referenced */
6512 for(;;) {
6513 inline_generated = 0;
6514 for (i = 0; i < s->nb_inline_fns; ++i) {
6515 fn = s->inline_fns[i];
6516 sym = fn->sym;
6517 if (sym && sym->c) {
6518 /* the function was used: generate its code and
6519 convert it to a normal function */
6520 fn->sym = NULL;
6521 if (file)
6522 pstrcpy(file->filename, sizeof file->filename, fn->filename);
6523 sym->r = VT_SYM | VT_CONST;
6524 sym->type.t &= ~VT_INLINE;
6526 begin_macro(&fn->func_str, 0);
6527 next();
6528 cur_text_section = text_section;
6529 gen_function(sym);
6530 end_macro();
6532 inline_generated = 1;
6535 if (!inline_generated)
6536 break;
6538 file->line_num = ln;
6541 ST_FUNC void free_inline_functions(TCCState *s)
6543 int i;
6544 /* free tokens of unused inline functions */
6545 for (i = 0; i < s->nb_inline_fns; ++i) {
6546 struct InlineFunc *fn = s->inline_fns[i];
6547 if (fn->sym)
6548 tok_str_free(fn->func_str.str);
6550 dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
6553 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6554 static int decl0(int l, int is_for_loop_init)
6556 int v, has_init, r;
6557 CType type, btype;
6558 Sym *sym;
6559 AttributeDef ad;
6561 while (1) {
6562 if (!parse_btype(&btype, &ad)) {
6563 if (is_for_loop_init)
6564 return 0;
6565 /* skip redundant ';' */
6566 /* XXX: find more elegant solution */
6567 if (tok == ';') {
6568 next();
6569 continue;
6571 if (l == VT_CONST &&
6572 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6573 /* global asm block */
6574 asm_global_instr();
6575 continue;
6577 /* special test for old K&R protos without explicit int
6578 type. Only accepted when defining global data */
6579 if (l == VT_LOCAL || tok < TOK_UIDENT)
6580 break;
6581 btype.t = VT_INT;
6583 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6584 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6585 tok == ';') {
6586 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
6587 int v = btype.ref->v;
6588 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
6589 tcc_warning("unnamed struct/union that defines no instances");
6591 next();
6592 continue;
6594 while (1) { /* iterate thru each declaration */
6595 type = btype;
6596 type_decl(&type, &ad, &v, TYPE_DIRECT);
6597 #if 0
6599 char buf[500];
6600 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6601 printf("type = '%s'\n", buf);
6603 #endif
6604 if ((type.t & VT_BTYPE) == VT_FUNC) {
6605 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
6606 tcc_error("function without file scope cannot be static");
6608 /* if old style function prototype, we accept a
6609 declaration list */
6610 sym = type.ref;
6611 if (sym->c == FUNC_OLD)
6612 func_decl_list(sym);
6615 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6616 ad.asm_label = asm_label_instr();
6617 /* parse one last attribute list, after asm label */
6618 parse_attribute(&ad);
6619 if (tok == '{')
6620 expect(";");
6623 if (ad.a.weak)
6624 type.t |= VT_WEAK;
6625 #ifdef TCC_TARGET_PE
6626 if (ad.a.func_import)
6627 type.t |= VT_IMPORT;
6628 if (ad.a.func_export)
6629 type.t |= VT_EXPORT;
6630 #endif
6631 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6633 if (tok == '{') {
6634 if (l == VT_LOCAL)
6635 tcc_error("cannot use local functions");
6636 if ((type.t & VT_BTYPE) != VT_FUNC)
6637 expect("function definition");
6639 /* reject abstract declarators in function definition */
6640 sym = type.ref;
6641 while ((sym = sym->next) != NULL)
6642 if (!(sym->v & ~SYM_FIELD))
6643 expect("identifier");
6645 /* XXX: cannot do better now: convert extern line to static inline */
6646 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6647 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6649 sym = sym_find(v);
6650 if (sym) {
6651 Sym *ref;
6652 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6653 goto func_error1;
6655 ref = sym->type.ref;
6656 if (0 == ref->a.func_proto)
6657 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6659 /* use func_call from prototype if not defined */
6660 if (ref->a.func_call != FUNC_CDECL
6661 && type.ref->a.func_call == FUNC_CDECL)
6662 type.ref->a.func_call = ref->a.func_call;
6664 /* use export from prototype */
6665 if (ref->a.func_export)
6666 type.ref->a.func_export = 1;
6668 /* use static from prototype */
6669 if (sym->type.t & VT_STATIC)
6670 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6672 /* If the definition has no visibility use the
6673 one from prototype. */
6674 if (! (type.t & VT_VIS_MASK))
6675 type.t |= sym->type.t & VT_VIS_MASK;
6677 if (!is_compatible_types(&sym->type, &type)) {
6678 func_error1:
6679 tcc_error("incompatible types for redefinition of '%s'",
6680 get_tok_str(v, NULL));
6682 type.ref->a.func_proto = 0;
6683 /* if symbol is already defined, then put complete type */
6684 sym->type = type;
6685 } else {
6686 /* put function symbol */
6687 sym = global_identifier_push(v, type.t, 0);
6688 sym->type.ref = type.ref;
6691 /* static inline functions are just recorded as a kind
6692 of macro. Their code will be emitted at the end of
6693 the compilation unit only if they are used */
6694 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6695 (VT_INLINE | VT_STATIC)) {
6696 int block_level;
6697 struct InlineFunc *fn;
6698 const char *filename;
6700 filename = file ? file->filename : "";
6701 fn = tcc_malloc(sizeof *fn + strlen(filename));
6702 strcpy(fn->filename, filename);
6703 fn->sym = sym;
6704 tok_str_new(&fn->func_str);
6706 block_level = 0;
6707 for(;;) {
6708 int t;
6709 if (tok == TOK_EOF)
6710 tcc_error("unexpected end of file");
6711 tok_str_add_tok(&fn->func_str);
6712 t = tok;
6713 next();
6714 if (t == '{') {
6715 block_level++;
6716 } else if (t == '}') {
6717 block_level--;
6718 if (block_level == 0)
6719 break;
6722 tok_str_add(&fn->func_str, -1);
6723 tok_str_add(&fn->func_str, 0);
6724 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6726 } else {
6727 /* compute text section */
6728 cur_text_section = ad.section;
6729 if (!cur_text_section)
6730 cur_text_section = text_section;
6731 sym->r = VT_SYM | VT_CONST;
6732 gen_function(sym);
6734 break;
6735 } else {
6736 if (btype.t & VT_TYPEDEF) {
6737 /* save typedefed type */
6738 /* XXX: test storage specifiers ? */
6739 sym = sym_find(v);
6740 if (sym && sym->scope == local_scope) {
6741 if (!is_compatible_types(&sym->type, &type)
6742 || !(sym->type.t & VT_TYPEDEF))
6743 tcc_error("incompatible redefinition of '%s'",
6744 get_tok_str(v, NULL));
6745 sym->type = type;
6746 } else {
6747 sym = sym_push(v, &type, 0, 0);
6749 sym->a = ad.a;
6750 sym->type.t |= VT_TYPEDEF;
6751 } else {
6752 r = 0;
6753 if ((type.t & VT_BTYPE) == VT_FUNC) {
6754 /* external function definition */
6755 /* specific case for func_call attribute */
6756 ad.a.func_proto = 1;
6757 type.ref->a = ad.a;
6758 } else if (!(type.t & VT_ARRAY)) {
6759 /* not lvalue if array */
6760 r |= lvalue_type(type.t);
6762 has_init = (tok == '=');
6763 if (has_init && (type.t & VT_VLA))
6764 tcc_error("Variable length array cannot be initialized");
6765 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6766 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6767 !has_init && l == VT_CONST && type.ref->c < 0)) {
6768 /* external variable or function */
6769 /* NOTE: as GCC, uninitialized global static
6770 arrays of null size are considered as
6771 extern */
6772 sym = external_sym(v, &type, r);
6773 sym->asm_label = ad.asm_label;
6775 if (ad.alias_target) {
6776 Section tsec;
6777 Elf32_Sym *esym;
6778 Sym *alias_target;
6780 alias_target = sym_find(ad.alias_target);
6781 if (!alias_target || !alias_target->c)
6782 tcc_error("unsupported forward __alias__ attribute");
6783 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6784 tsec.sh_num = esym->st_shndx;
6785 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6787 } else {
6788 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6789 if (type.t & VT_STATIC)
6790 r |= VT_CONST;
6791 else
6792 r |= l;
6793 if (has_init)
6794 next();
6795 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
6798 if (tok != ',') {
6799 if (is_for_loop_init)
6800 return 1;
6801 skip(';');
6802 break;
6804 next();
6806 ad.a.aligned = 0;
6809 return 0;
6812 ST_FUNC void decl(int l)
6814 decl0(l, 0);
6817 /* ------------------------------------------------------------------------- */