tccgen/32bits: fix unsigned long long -> int cast
[tinycc.git] / tccgen.c
blobf7f4d1764113e2e715076a2db02ffa81f0c9dcd1
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);
94 ST_INLN int is_float(int t)
96 int bt;
97 bt = t & VT_BTYPE;
98 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
101 /* we use our own 'finite' function to avoid potential problems with
102 non standard math libs */
103 /* XXX: endianness dependent */
104 ST_FUNC int ieee_finite(double d)
106 int p[4];
107 memcpy(p, &d, sizeof(double));
108 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
111 ST_FUNC void test_lvalue(void)
113 if (!(vtop->r & VT_LVAL))
114 expect("lvalue");
117 ST_FUNC void check_vstack(void)
119 if (pvtop != vtop)
120 tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
123 /* ------------------------------------------------------------------------- */
124 /* vstack debugging aid */
126 #if 0
127 void pv (const char *lbl, int a, int b)
129 int i;
130 for (i = a; i < a + b; ++i) {
131 SValue *p = &vtop[-i];
132 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
133 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
136 #endif
138 /* ------------------------------------------------------------------------- */
139 ST_FUNC void tccgen_start(TCCState *s1)
141 cur_text_section = NULL;
142 funcname = "";
143 anon_sym = SYM_FIRST_ANOM;
144 section_sym = 0;
145 nocode_wanted = 1;
147 /* define some often used types */
148 int_type.t = VT_INT;
149 char_pointer_type.t = VT_BYTE;
150 mk_pointer(&char_pointer_type);
151 #if PTR_SIZE == 4
152 size_type.t = VT_INT;
153 #else
154 size_type.t = VT_LLONG;
155 #endif
156 func_old_type.t = VT_FUNC;
157 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
159 if (s1->do_debug) {
160 char buf[512];
162 /* file info: full path + filename */
163 section_sym = put_elf_sym(symtab_section, 0, 0,
164 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
165 text_section->sh_num, NULL);
166 getcwd(buf, sizeof(buf));
167 #ifdef _WIN32
168 normalize_slashes(buf);
169 #endif
170 pstrcat(buf, sizeof(buf), "/");
171 put_stabs_r(buf, N_SO, 0, 0,
172 text_section->data_offset, text_section, section_sym);
173 put_stabs_r(file->filename, N_SO, 0, 0,
174 text_section->data_offset, text_section, section_sym);
176 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
177 symbols can be safely used */
178 put_elf_sym(symtab_section, 0, 0,
179 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
180 SHN_ABS, file->filename);
182 #ifdef TCC_TARGET_ARM
183 arm_init(s1);
184 #endif
186 #if 0
187 /* define 'void *alloca(unsigned int)' builtin function */
189 Sym *s1;
191 p = anon_sym++;
192 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
193 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
194 s1->next = NULL;
195 sym->next = s1;
196 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
198 #endif
201 ST_FUNC void tccgen_end(TCCState *s1)
203 check_vstack();
204 /* end of translation unit info */
205 if (s1->do_debug) {
206 put_stabs_r(NULL, N_SO, 0, 0,
207 text_section->data_offset, text_section, section_sym);
211 /* ------------------------------------------------------------------------- */
212 /* update sym->c so that it points to an external symbol in section
213 'section' with value 'value' */
215 ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
216 addr_t value, unsigned long size,
217 int can_add_underscore)
219 int sym_type, sym_bind, sh_num, info, other;
220 ElfW(Sym) *esym;
221 const char *name;
222 char buf1[256];
224 #ifdef CONFIG_TCC_BCHECK
225 char buf[32];
226 #endif
228 if (section == NULL)
229 sh_num = SHN_UNDEF;
230 else if (section == SECTION_ABS)
231 sh_num = SHN_ABS;
232 else
233 sh_num = section->sh_num;
235 if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
236 sym_type = STT_FUNC;
237 } else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
238 sym_type = STT_NOTYPE;
239 } else {
240 sym_type = STT_OBJECT;
243 if (sym->type.t & VT_STATIC)
244 sym_bind = STB_LOCAL;
245 else {
246 if (sym->type.t & VT_WEAK)
247 sym_bind = STB_WEAK;
248 else
249 sym_bind = STB_GLOBAL;
252 if (!sym->c) {
253 name = get_tok_str(sym->v, NULL);
254 #ifdef CONFIG_TCC_BCHECK
255 if (tcc_state->do_bounds_check) {
256 /* XXX: avoid doing that for statics ? */
257 /* if bound checking is activated, we change some function
258 names by adding the "__bound" prefix */
259 switch(sym->v) {
260 #ifdef TCC_TARGET_PE
261 /* XXX: we rely only on malloc hooks */
262 case TOK_malloc:
263 case TOK_free:
264 case TOK_realloc:
265 case TOK_memalign:
266 case TOK_calloc:
267 #endif
268 case TOK_memcpy:
269 case TOK_memmove:
270 case TOK_memset:
271 case TOK_strlen:
272 case TOK_strcpy:
273 case TOK_alloca:
274 strcpy(buf, "__bound_");
275 strcat(buf, name);
276 name = buf;
277 break;
280 #endif
281 other = 0;
283 #ifdef TCC_TARGET_PE
284 if (sym->type.t & VT_EXPORT)
285 other |= ST_PE_EXPORT;
286 if (sym_type == STT_FUNC && sym->type.ref) {
287 Sym *ref = sym->type.ref;
288 if (ref->a.func_export)
289 other |= ST_PE_EXPORT;
290 if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) {
291 sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE);
292 name = buf1;
293 other |= ST_PE_STDCALL;
294 can_add_underscore = 0;
296 } else {
297 if (find_elf_sym(tcc_state->dynsymtab_section, name))
298 other |= ST_PE_IMPORT;
299 if (sym->type.t & VT_IMPORT)
300 other |= ST_PE_IMPORT;
302 #else
303 if (! (sym->type.t & VT_STATIC))
304 other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT;
305 #endif
306 if (tcc_state->leading_underscore && can_add_underscore) {
307 buf1[0] = '_';
308 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
309 name = buf1;
311 if (sym->asm_label) {
312 name = get_tok_str(sym->asm_label, NULL);
314 info = ELFW(ST_INFO)(sym_bind, sym_type);
315 sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
316 } else {
317 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
318 esym->st_value = value;
319 esym->st_size = size;
320 esym->st_shndx = sh_num;
324 ST_FUNC void put_extern_sym(Sym *sym, Section *section,
325 addr_t value, unsigned long size)
327 put_extern_sym2(sym, section, value, size, 1);
330 /* add a new relocation entry to symbol 'sym' in section 's' */
331 ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
332 addr_t addend)
334 int c = 0;
335 if (sym) {
336 if (0 == sym->c)
337 put_extern_sym(sym, NULL, 0, 0);
338 c = sym->c;
340 /* now we can add ELF relocation info */
341 put_elf_reloca(symtab_section, s, offset, type, c, addend);
344 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
346 greloca(s, sym, offset, type, 0);
349 /* ------------------------------------------------------------------------- */
350 /* symbol allocator */
351 static Sym *__sym_malloc(void)
353 Sym *sym_pool, *sym, *last_sym;
354 int i;
356 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
357 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
359 last_sym = sym_free_first;
360 sym = sym_pool;
361 for(i = 0; i < SYM_POOL_NB; i++) {
362 sym->next = last_sym;
363 last_sym = sym;
364 sym++;
366 sym_free_first = last_sym;
367 return last_sym;
370 static inline Sym *sym_malloc(void)
372 Sym *sym;
373 sym = sym_free_first;
374 if (!sym)
375 sym = __sym_malloc();
376 sym_free_first = sym->next;
377 return sym;
380 ST_INLN void sym_free(Sym *sym)
382 sym->next = sym_free_first;
383 sym_free_first = sym;
386 /* push, without hashing */
387 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
389 Sym *s;
391 s = sym_malloc();
392 s->asm_label = 0;
393 s->v = v;
394 s->type.t = t;
395 s->type.ref = NULL;
396 #ifdef _WIN64
397 s->d = NULL;
398 #endif
399 s->c = c;
400 s->next = NULL;
401 /* add in stack */
402 s->prev = *ps;
403 *ps = s;
404 return s;
407 /* find a symbol and return its associated structure. 's' is the top
408 of the symbol stack */
409 ST_FUNC Sym *sym_find2(Sym *s, int v)
411 while (s) {
412 if (s->v == v)
413 return s;
414 else if (s->v == -1)
415 return NULL;
416 s = s->prev;
418 return NULL;
421 /* structure lookup */
422 ST_INLN Sym *struct_find(int v)
424 v -= TOK_IDENT;
425 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
426 return NULL;
427 return table_ident[v]->sym_struct;
430 /* find an identifier */
431 ST_INLN Sym *sym_find(int v)
433 v -= TOK_IDENT;
434 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
435 return NULL;
436 return table_ident[v]->sym_identifier;
439 /* push a given symbol on the symbol stack */
440 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
442 Sym *s, **ps;
443 TokenSym *ts;
445 if (local_stack)
446 ps = &local_stack;
447 else
448 ps = &global_stack;
449 s = sym_push2(ps, v, type->t, c);
450 s->type.ref = type->ref;
451 s->r = r;
452 /* don't record fields or anonymous symbols */
453 /* XXX: simplify */
454 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
455 /* record symbol in token array */
456 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
457 if (v & SYM_STRUCT)
458 ps = &ts->sym_struct;
459 else
460 ps = &ts->sym_identifier;
461 s->prev_tok = *ps;
462 *ps = s;
463 s->scope = local_scope;
464 if (s->prev_tok && s->prev_tok->scope == s->scope)
465 tcc_error("redeclaration of '%s'",
466 get_tok_str(v & ~SYM_STRUCT, NULL));
468 return s;
471 /* push a global identifier */
472 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
474 Sym *s, **ps;
475 s = sym_push2(&global_stack, v, t, c);
476 /* don't record anonymous symbol */
477 if (v < SYM_FIRST_ANOM) {
478 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
479 /* modify the top most local identifier, so that
480 sym_identifier will point to 's' when popped */
481 while (*ps != NULL)
482 ps = &(*ps)->prev_tok;
483 s->prev_tok = NULL;
484 *ps = s;
486 return s;
489 /* pop symbols until top reaches 'b' */
490 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
492 Sym *s, *ss, **ps;
493 TokenSym *ts;
494 int v;
496 s = *ptop;
497 while(s != b) {
498 ss = s->prev;
499 v = s->v;
500 /* remove symbol in token array */
501 /* XXX: simplify */
502 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
503 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
504 if (v & SYM_STRUCT)
505 ps = &ts->sym_struct;
506 else
507 ps = &ts->sym_identifier;
508 *ps = s->prev_tok;
510 sym_free(s);
511 s = ss;
513 *ptop = b;
516 static void weaken_symbol(Sym *sym)
518 sym->type.t |= VT_WEAK;
519 if (sym->c > 0) {
520 int esym_type;
521 ElfW(Sym) *esym;
523 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
524 esym_type = ELFW(ST_TYPE)(esym->st_info);
525 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
529 static void apply_visibility(Sym *sym, CType *type)
531 int vis = sym->type.t & VT_VIS_MASK;
532 int vis2 = type->t & VT_VIS_MASK;
533 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
534 vis = vis2;
535 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
537 else
538 vis = (vis < vis2) ? vis : vis2;
539 sym->type.t &= ~VT_VIS_MASK;
540 sym->type.t |= vis;
542 if (sym->c > 0) {
543 ElfW(Sym) *esym;
545 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
546 vis >>= VT_VIS_SHIFT;
547 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
551 /* ------------------------------------------------------------------------- */
553 ST_FUNC void swap(int *p, int *q)
555 int t;
556 t = *p;
557 *p = *q;
558 *q = t;
561 static void vsetc(CType *type, int r, CValue *vc)
563 int v;
565 if (vtop >= vstack + (VSTACK_SIZE - 1))
566 tcc_error("memory full (vstack)");
567 /* cannot let cpu flags if other instruction are generated. Also
568 avoid leaving VT_JMP anywhere except on the top of the stack
569 because it would complicate the code generator. */
570 if (vtop >= vstack) {
571 v = vtop->r & VT_VALMASK;
572 if (v == VT_CMP || (v & ~1) == VT_JMP)
573 gv(RC_INT);
575 vtop++;
576 vtop->type = *type;
577 vtop->r = r;
578 vtop->r2 = VT_CONST;
579 vtop->c = *vc;
582 /* push constant of type "type" with useless value */
583 ST_FUNC void vpush(CType *type)
585 CValue cval;
586 vsetc(type, VT_CONST, &cval);
589 /* push integer constant */
590 ST_FUNC void vpushi(int v)
592 CValue cval;
593 cval.i = v;
594 vsetc(&int_type, VT_CONST, &cval);
597 /* push a pointer sized constant */
598 static void vpushs(addr_t v)
600 CValue cval;
601 cval.i = v;
602 vsetc(&size_type, VT_CONST, &cval);
605 /* push arbitrary 64bit constant */
606 ST_FUNC void vpush64(int ty, unsigned long long v)
608 CValue cval;
609 CType ctype;
610 ctype.t = ty;
611 ctype.ref = NULL;
612 cval.i = v;
613 vsetc(&ctype, VT_CONST, &cval);
616 /* push long long constant */
617 static inline void vpushll(long long v)
619 vpush64(VT_LLONG, v);
622 /* push a symbol value of TYPE */
623 static inline void vpushsym(CType *type, Sym *sym)
625 CValue cval;
626 cval.i = 0;
627 vsetc(type, VT_CONST | VT_SYM, &cval);
628 vtop->sym = sym;
631 /* Return a static symbol pointing to a section */
632 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
634 int v;
635 Sym *sym;
637 v = anon_sym++;
638 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
639 sym->type.ref = type->ref;
640 sym->r = VT_CONST | VT_SYM;
641 put_extern_sym(sym, sec, offset, size);
642 return sym;
645 /* push a reference to a section offset by adding a dummy symbol */
646 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
648 vpushsym(type, get_sym_ref(type, sec, offset, size));
651 /* define a new external reference to a symbol 'v' of type 'u' */
652 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
654 Sym *s;
656 s = sym_find(v);
657 if (!s) {
658 /* push forward reference */
659 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
660 s->type.ref = type->ref;
661 s->r = r | VT_CONST | VT_SYM;
663 return s;
666 /* define a new external reference to a symbol 'v' */
667 static Sym *external_sym(int v, CType *type, int r)
669 Sym *s;
671 s = sym_find(v);
672 if (!s) {
673 /* push forward reference */
674 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
675 s->type.t |= VT_EXTERN;
676 } else if (s->type.ref == func_old_type.ref) {
677 s->type.ref = type->ref;
678 s->r = r | VT_CONST | VT_SYM;
679 s->type.t |= VT_EXTERN;
680 } else if (!is_compatible_types(&s->type, type)) {
681 tcc_error("incompatible types for redefinition of '%s'",
682 get_tok_str(v, NULL));
684 /* Merge some storage attributes. */
685 if (type->t & VT_WEAK)
686 weaken_symbol(s);
688 if (type->t & VT_VIS_MASK)
689 apply_visibility(s, type);
691 return s;
694 /* push a reference to global symbol v */
695 ST_FUNC void vpush_global_sym(CType *type, int v)
697 vpushsym(type, external_global_sym(v, type, 0));
700 ST_FUNC void vset(CType *type, int r, int v)
702 CValue cval;
704 cval.i = v;
705 vsetc(type, r, &cval);
708 static void vseti(int r, int v)
710 CType type;
711 type.t = VT_INT;
712 type.ref = 0;
713 vset(&type, r, v);
716 ST_FUNC void vswap(void)
718 SValue tmp;
719 /* cannot let cpu flags if other instruction are generated. Also
720 avoid leaving VT_JMP anywhere except on the top of the stack
721 because it would complicate the code generator. */
722 if (vtop >= vstack) {
723 int v = vtop->r & VT_VALMASK;
724 if (v == VT_CMP || (v & ~1) == VT_JMP)
725 gv(RC_INT);
727 tmp = vtop[0];
728 vtop[0] = vtop[-1];
729 vtop[-1] = tmp;
731 /* XXX: +2% overall speed possible with optimized memswap
733 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
737 ST_FUNC void vpushv(SValue *v)
739 if (vtop >= vstack + (VSTACK_SIZE - 1))
740 tcc_error("memory full (vstack)");
741 vtop++;
742 *vtop = *v;
745 static void vdup(void)
747 vpushv(vtop);
750 /* save registers up to (vtop - n) stack entry */
751 ST_FUNC void save_regs(int n)
753 SValue *p, *p1;
754 for(p = vstack, p1 = vtop - n; p <= p1; p++)
755 save_reg(p->r);
758 /* save r to the memory stack, and mark it as being free */
759 ST_FUNC void save_reg(int r)
761 save_reg_upstack(r, 0);
764 /* save r to the memory stack, and mark it as being free,
765 if seen up to (vtop - n) stack entry */
766 ST_FUNC void save_reg_upstack(int r, int n)
768 int l, saved, size, align;
769 SValue *p, *p1, sv;
770 CType *type;
772 if ((r &= VT_VALMASK) >= VT_CONST)
773 return;
775 /* modify all stack values */
776 saved = 0;
777 l = 0;
778 for(p = vstack, p1 = vtop - n; p <= p1; p++) {
779 if ((p->r & VT_VALMASK) == r ||
780 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
781 /* must save value on stack if not already done */
782 if (!saved) {
783 /* NOTE: must reload 'r' because r might be equal to r2 */
784 r = p->r & VT_VALMASK;
785 /* store register in the stack */
786 type = &p->type;
787 if ((p->r & VT_LVAL) ||
788 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
789 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
790 type = &char_pointer_type;
791 #else
792 type = &int_type;
793 #endif
794 size = type_size(type, &align);
795 loc = (loc - size) & -align;
796 sv.type.t = type->t;
797 sv.r = VT_LOCAL | VT_LVAL;
798 sv.c.i = loc;
799 store(r, &sv);
800 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
801 /* x86 specific: need to pop fp register ST0 if saved */
802 if (r == TREG_ST0) {
803 o(0xd8dd); /* fstp %st(0) */
805 #endif
806 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
807 /* special long long case */
808 if ((type->t & VT_BTYPE) == VT_LLONG) {
809 sv.c.i += 4;
810 store(p->r2, &sv);
812 #endif
813 l = loc;
814 saved = 1;
816 /* mark that stack entry as being saved on the stack */
817 if (p->r & VT_LVAL) {
818 /* also clear the bounded flag because the
819 relocation address of the function was stored in
820 p->c.i */
821 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
822 } else {
823 p->r = lvalue_type(p->type.t) | VT_LOCAL;
825 p->r2 = VT_CONST;
826 p->c.i = l;
831 #ifdef TCC_TARGET_ARM
832 /* find a register of class 'rc2' with at most one reference on stack.
833 * If none, call get_reg(rc) */
834 ST_FUNC int get_reg_ex(int rc, int rc2)
836 int r;
837 SValue *p;
839 for(r=0;r<NB_REGS;r++) {
840 if (reg_classes[r] & rc2) {
841 int n;
842 n=0;
843 for(p = vstack; p <= vtop; p++) {
844 if ((p->r & VT_VALMASK) == r ||
845 (p->r2 & VT_VALMASK) == r)
846 n++;
848 if (n <= 1)
849 return r;
852 return get_reg(rc);
854 #endif
856 /* find a free register of class 'rc'. If none, save one register */
857 ST_FUNC int get_reg(int rc)
859 int r;
860 SValue *p;
862 /* find a free register */
863 for(r=0;r<NB_REGS;r++) {
864 if (reg_classes[r] & rc) {
865 for(p=vstack;p<=vtop;p++) {
866 if ((p->r & VT_VALMASK) == r ||
867 (p->r2 & VT_VALMASK) == r)
868 goto notfound;
870 return r;
872 notfound: ;
875 /* no register left : free the first one on the stack (VERY
876 IMPORTANT to start from the bottom to ensure that we don't
877 spill registers used in gen_opi()) */
878 for(p=vstack;p<=vtop;p++) {
879 /* look at second register (if long long) */
880 r = p->r2 & VT_VALMASK;
881 if (r < VT_CONST && (reg_classes[r] & rc))
882 goto save_found;
883 r = p->r & VT_VALMASK;
884 if (r < VT_CONST && (reg_classes[r] & rc)) {
885 save_found:
886 save_reg(r);
887 return r;
890 /* Should never comes here */
891 return -1;
894 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
895 if needed */
896 static void move_reg(int r, int s, int t)
898 SValue sv;
900 if (r != s) {
901 save_reg(r);
902 sv.type.t = t;
903 sv.type.ref = NULL;
904 sv.r = s;
905 sv.c.i = 0;
906 load(r, &sv);
910 /* get address of vtop (vtop MUST BE an lvalue) */
911 ST_FUNC void gaddrof(void)
913 if (vtop->r & VT_REF && !nocode_wanted)
914 gv(RC_INT);
915 vtop->r &= ~VT_LVAL;
916 /* tricky: if saved lvalue, then we can go back to lvalue */
917 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
918 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
923 #ifdef CONFIG_TCC_BCHECK
924 /* generate lvalue bound code */
925 static void gbound(void)
927 int lval_type;
928 CType type1;
930 vtop->r &= ~VT_MUSTBOUND;
931 /* if lvalue, then use checking code before dereferencing */
932 if (vtop->r & VT_LVAL) {
933 /* if not VT_BOUNDED value, then make one */
934 if (!(vtop->r & VT_BOUNDED)) {
935 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
936 /* must save type because we must set it to int to get pointer */
937 type1 = vtop->type;
938 vtop->type.t = VT_PTR;
939 gaddrof();
940 vpushi(0);
941 gen_bounded_ptr_add();
942 vtop->r |= lval_type;
943 vtop->type = type1;
945 /* then check for dereferencing */
946 gen_bounded_ptr_deref();
949 #endif
951 /* store vtop a register belonging to class 'rc'. lvalues are
952 converted to values. Cannot be used if cannot be converted to
953 register value (such as structures). */
954 ST_FUNC int gv(int rc)
956 int r, bit_pos, bit_size, size, align, i;
957 int rc2;
959 /* NOTE: get_reg can modify vstack[] */
960 if (vtop->type.t & VT_BITFIELD) {
961 CType type;
962 int bits = 32;
963 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
964 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
965 /* remove bit field info to avoid loops */
966 vtop->type.t &= ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
967 /* cast to int to propagate signedness in following ops */
968 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
969 type.t = VT_LLONG;
970 bits = 64;
971 } else
972 type.t = VT_INT;
973 if((vtop->type.t & VT_UNSIGNED) ||
974 (vtop->type.t & VT_BTYPE) == VT_BOOL)
975 type.t |= VT_UNSIGNED;
976 gen_cast(&type);
977 /* generate shifts */
978 vpushi(bits - (bit_pos + bit_size));
979 gen_op(TOK_SHL);
980 vpushi(bits - bit_size);
981 /* NOTE: transformed to SHR if unsigned */
982 gen_op(TOK_SAR);
983 r = gv(rc);
984 } else {
985 if (is_float(vtop->type.t) &&
986 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
987 Sym *sym;
988 int *ptr;
989 unsigned long offset;
990 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
991 CValue check;
992 #endif
994 /* XXX: unify with initializers handling ? */
995 /* CPUs usually cannot use float constants, so we store them
996 generically in data segment */
997 size = type_size(&vtop->type, &align);
998 offset = (data_section->data_offset + align - 1) & -align;
999 data_section->data_offset = offset;
1000 /* XXX: not portable yet */
1001 #if defined(__i386__) || defined(__x86_64__)
1002 /* Zero pad x87 tenbyte long doubles */
1003 if (size == LDOUBLE_SIZE) {
1004 vtop->c.tab[2] &= 0xffff;
1005 #if LDOUBLE_SIZE == 16
1006 vtop->c.tab[3] = 0;
1007 #endif
1009 #endif
1010 ptr = section_ptr_add(data_section, size);
1011 size = size >> 2;
1012 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
1013 check.d = 1;
1014 if(check.tab[0])
1015 for(i=0;i<size;i++)
1016 ptr[i] = vtop->c.tab[size-1-i];
1017 else
1018 #endif
1019 for(i=0;i<size;i++)
1020 ptr[i] = vtop->c.tab[i];
1021 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
1022 vtop->r |= VT_LVAL | VT_SYM;
1023 vtop->sym = sym;
1024 vtop->c.i = 0;
1026 #ifdef CONFIG_TCC_BCHECK
1027 if (vtop->r & VT_MUSTBOUND)
1028 gbound();
1029 #endif
1031 r = vtop->r & VT_VALMASK;
1032 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
1033 #ifndef TCC_TARGET_ARM64
1034 if (rc == RC_IRET)
1035 rc2 = RC_LRET;
1036 #ifdef TCC_TARGET_X86_64
1037 else if (rc == RC_FRET)
1038 rc2 = RC_QRET;
1039 #endif
1040 #endif
1042 /* need to reload if:
1043 - constant
1044 - lvalue (need to dereference pointer)
1045 - already a register, but not in the right class */
1046 if (r >= VT_CONST
1047 || (vtop->r & VT_LVAL)
1048 || !(reg_classes[r] & rc)
1049 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1050 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
1051 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
1052 #else
1053 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
1054 #endif
1057 r = get_reg(rc);
1058 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1059 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
1060 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
1061 #else
1062 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
1063 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
1064 unsigned long long ll;
1065 #endif
1066 int r2, original_type;
1067 original_type = vtop->type.t;
1068 /* two register type load : expand to two words
1069 temporarily */
1070 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1071 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1072 /* load constant */
1073 ll = vtop->c.i;
1074 vtop->c.i = ll; /* first word */
1075 load(r, vtop);
1076 vtop->r = r; /* save register value */
1077 vpushi(ll >> 32); /* second word */
1078 } else
1079 #endif
1080 if (vtop->r & VT_LVAL) {
1081 /* We do not want to modifier the long long
1082 pointer here, so the safest (and less
1083 efficient) is to save all the other registers
1084 in the stack. XXX: totally inefficient. */
1085 #if 0
1086 save_regs(1);
1087 #else
1088 /* lvalue_save: save only if used further down the stack */
1089 save_reg_upstack(vtop->r, 1);
1090 #endif
1091 /* load from memory */
1092 vtop->type.t = load_type;
1093 load(r, vtop);
1094 vdup();
1095 vtop[-1].r = r; /* save register value */
1096 /* increment pointer to get second word */
1097 vtop->type.t = addr_type;
1098 gaddrof();
1099 vpushi(load_size);
1100 gen_op('+');
1101 vtop->r |= VT_LVAL;
1102 vtop->type.t = load_type;
1103 } else {
1104 /* move registers */
1105 load(r, vtop);
1106 vdup();
1107 vtop[-1].r = r; /* save register value */
1108 vtop->r = vtop[-1].r2;
1110 /* Allocate second register. Here we rely on the fact that
1111 get_reg() tries first to free r2 of an SValue. */
1112 r2 = get_reg(rc2);
1113 load(r2, vtop);
1114 vpop();
1115 /* write second register */
1116 vtop->r2 = r2;
1117 vtop->type.t = original_type;
1118 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
1119 int t1, t;
1120 /* lvalue of scalar type : need to use lvalue type
1121 because of possible cast */
1122 t = vtop->type.t;
1123 t1 = t;
1124 /* compute memory access type */
1125 if (vtop->r & VT_REF)
1126 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1127 t = VT_PTR;
1128 #else
1129 t = VT_INT;
1130 #endif
1131 else if (vtop->r & VT_LVAL_BYTE)
1132 t = VT_BYTE;
1133 else if (vtop->r & VT_LVAL_SHORT)
1134 t = VT_SHORT;
1135 if (vtop->r & VT_LVAL_UNSIGNED)
1136 t |= VT_UNSIGNED;
1137 vtop->type.t = t;
1138 load(r, vtop);
1139 /* restore wanted type */
1140 vtop->type.t = t1;
1141 } else {
1142 /* one register type load */
1143 load(r, vtop);
1146 vtop->r = r;
1147 #ifdef TCC_TARGET_C67
1148 /* uses register pairs for doubles */
1149 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
1150 vtop->r2 = r+1;
1151 #endif
1153 return r;
1156 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
1157 ST_FUNC void gv2(int rc1, int rc2)
1159 int v;
1161 /* generate more generic register first. But VT_JMP or VT_CMP
1162 values must be generated first in all cases to avoid possible
1163 reload errors */
1164 v = vtop[0].r & VT_VALMASK;
1165 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
1166 vswap();
1167 gv(rc1);
1168 vswap();
1169 gv(rc2);
1170 /* test if reload is needed for first register */
1171 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1172 vswap();
1173 gv(rc1);
1174 vswap();
1176 } else {
1177 gv(rc2);
1178 vswap();
1179 gv(rc1);
1180 vswap();
1181 /* test if reload is needed for first register */
1182 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
1183 gv(rc2);
1188 #ifndef TCC_TARGET_ARM64
1189 /* wrapper around RC_FRET to return a register by type */
1190 static int rc_fret(int t)
1192 #ifdef TCC_TARGET_X86_64
1193 if (t == VT_LDOUBLE) {
1194 return RC_ST0;
1196 #endif
1197 return RC_FRET;
1199 #endif
1201 /* wrapper around REG_FRET to return a register by type */
1202 static int reg_fret(int t)
1204 #ifdef TCC_TARGET_X86_64
1205 if (t == VT_LDOUBLE) {
1206 return TREG_ST0;
1208 #endif
1209 return REG_FRET;
1212 /* expand long long on stack in two int registers */
1213 static void lexpand(void)
1215 int u;
1217 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1218 gv(RC_INT);
1219 vdup();
1220 vtop[0].r = vtop[-1].r2;
1221 vtop[0].r2 = VT_CONST;
1222 vtop[-1].r2 = VT_CONST;
1223 vtop[0].type.t = VT_INT | u;
1224 vtop[-1].type.t = VT_INT | u;
1227 #ifdef TCC_TARGET_ARM
1228 /* expand long long on stack */
1229 ST_FUNC void lexpand_nr(void)
1231 int u,v;
1233 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1234 vdup();
1235 vtop->r2 = VT_CONST;
1236 vtop->type.t = VT_INT | u;
1237 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1238 if (v == VT_CONST) {
1239 vtop[-1].c.i = vtop->c.i;
1240 vtop->c.i = vtop->c.i >> 32;
1241 vtop->r = VT_CONST;
1242 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1243 vtop->c.i += 4;
1244 vtop->r = vtop[-1].r;
1245 } else if (v > VT_CONST) {
1246 vtop--;
1247 lexpand();
1248 } else
1249 vtop->r = vtop[-1].r2;
1250 vtop[-1].r2 = VT_CONST;
1251 vtop[-1].type.t = VT_INT | u;
1253 #endif
1255 /* build a long long from two ints */
1256 static void lbuild(int t)
1258 gv2(RC_INT, RC_INT);
1259 vtop[-1].r2 = vtop[0].r;
1260 vtop[-1].type.t = t;
1261 vpop();
1264 /* rotate n first stack elements to the bottom
1265 I1 ... In -> I2 ... In I1 [top is right]
1267 ST_FUNC void vrotb(int n)
1269 int i;
1270 SValue tmp;
1272 tmp = vtop[-n + 1];
1273 for(i=-n+1;i!=0;i++)
1274 vtop[i] = vtop[i+1];
1275 vtop[0] = tmp;
1278 /* rotate the n elements before entry e towards the top
1279 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1281 ST_FUNC void vrote(SValue *e, int n)
1283 int i;
1284 SValue tmp;
1286 tmp = *e;
1287 for(i = 0;i < n - 1; i++)
1288 e[-i] = e[-i - 1];
1289 e[-n + 1] = tmp;
1292 /* rotate n first stack elements to the top
1293 I1 ... In -> In I1 ... I(n-1) [top is right]
1295 ST_FUNC void vrott(int n)
1297 vrote(vtop, n);
1300 /* pop stack value */
1301 ST_FUNC void vpop(void)
1303 int v;
1304 v = vtop->r & VT_VALMASK;
1305 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1306 /* for x86, we need to pop the FP stack */
1307 if (v == TREG_ST0 && !nocode_wanted) {
1308 o(0xd8dd); /* fstp %st(0) */
1309 } else
1310 #endif
1311 if (v == VT_JMP || v == VT_JMPI) {
1312 /* need to put correct jump if && or || without test */
1313 gsym(vtop->c.i);
1315 vtop--;
1318 /* convert stack entry to register and duplicate its value in another
1319 register */
1320 static void gv_dup(void)
1322 int rc, t, r, r1;
1323 SValue sv;
1325 t = vtop->type.t;
1326 if ((t & VT_BTYPE) == VT_LLONG) {
1327 lexpand();
1328 gv_dup();
1329 vswap();
1330 vrotb(3);
1331 gv_dup();
1332 vrotb(4);
1333 /* stack: H L L1 H1 */
1334 lbuild(t);
1335 vrotb(3);
1336 vrotb(3);
1337 vswap();
1338 lbuild(t);
1339 vswap();
1340 } else {
1341 /* duplicate value */
1342 rc = RC_INT;
1343 sv.type.t = VT_INT;
1344 if (is_float(t)) {
1345 rc = RC_FLOAT;
1346 #ifdef TCC_TARGET_X86_64
1347 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1348 rc = RC_ST0;
1350 #endif
1351 sv.type.t = t;
1353 r = gv(rc);
1354 r1 = get_reg(rc);
1355 sv.r = r;
1356 sv.c.i = 0;
1357 load(r1, &sv); /* move r to r1 */
1358 vdup();
1359 /* duplicates value */
1360 if (r != r1)
1361 vtop->r = r1;
1365 /* Generate value test
1367 * Generate a test for any value (jump, comparison and integers) */
1368 ST_FUNC int gvtst(int inv, int t)
1370 int v = vtop->r & VT_VALMASK;
1371 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1372 vpushi(0);
1373 gen_op(TOK_NE);
1375 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1376 /* constant jmp optimization */
1377 if ((vtop->c.i != 0) != inv)
1378 t = gjmp(t);
1379 vtop--;
1380 return t;
1382 return gtst(inv, t);
1385 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1386 /* generate CPU independent (unsigned) long long operations */
1387 static void gen_opl(int op)
1389 int t, a, b, op1, c, i;
1390 int func;
1391 unsigned short reg_iret = REG_IRET;
1392 unsigned short reg_lret = REG_LRET;
1393 SValue tmp;
1395 switch(op) {
1396 case '/':
1397 case TOK_PDIV:
1398 func = TOK___divdi3;
1399 goto gen_func;
1400 case TOK_UDIV:
1401 func = TOK___udivdi3;
1402 goto gen_func;
1403 case '%':
1404 func = TOK___moddi3;
1405 goto gen_mod_func;
1406 case TOK_UMOD:
1407 func = TOK___umoddi3;
1408 gen_mod_func:
1409 #ifdef TCC_ARM_EABI
1410 reg_iret = TREG_R2;
1411 reg_lret = TREG_R3;
1412 #endif
1413 gen_func:
1414 /* call generic long long function */
1415 vpush_global_sym(&func_old_type, func);
1416 vrott(3);
1417 gfunc_call(2);
1418 vpushi(0);
1419 vtop->r = reg_iret;
1420 vtop->r2 = reg_lret;
1421 break;
1422 case '^':
1423 case '&':
1424 case '|':
1425 case '*':
1426 case '+':
1427 case '-':
1428 //pv("gen_opl A",0,2);
1429 t = vtop->type.t;
1430 vswap();
1431 lexpand();
1432 vrotb(3);
1433 lexpand();
1434 /* stack: L1 H1 L2 H2 */
1435 tmp = vtop[0];
1436 vtop[0] = vtop[-3];
1437 vtop[-3] = tmp;
1438 tmp = vtop[-2];
1439 vtop[-2] = vtop[-3];
1440 vtop[-3] = tmp;
1441 vswap();
1442 /* stack: H1 H2 L1 L2 */
1443 //pv("gen_opl B",0,4);
1444 if (op == '*') {
1445 vpushv(vtop - 1);
1446 vpushv(vtop - 1);
1447 gen_op(TOK_UMULL);
1448 lexpand();
1449 /* stack: H1 H2 L1 L2 ML MH */
1450 for(i=0;i<4;i++)
1451 vrotb(6);
1452 /* stack: ML MH H1 H2 L1 L2 */
1453 tmp = vtop[0];
1454 vtop[0] = vtop[-2];
1455 vtop[-2] = tmp;
1456 /* stack: ML MH H1 L2 H2 L1 */
1457 gen_op('*');
1458 vrotb(3);
1459 vrotb(3);
1460 gen_op('*');
1461 /* stack: ML MH M1 M2 */
1462 gen_op('+');
1463 gen_op('+');
1464 } else if (op == '+' || op == '-') {
1465 /* XXX: add non carry method too (for MIPS or alpha) */
1466 if (op == '+')
1467 op1 = TOK_ADDC1;
1468 else
1469 op1 = TOK_SUBC1;
1470 gen_op(op1);
1471 /* stack: H1 H2 (L1 op L2) */
1472 vrotb(3);
1473 vrotb(3);
1474 gen_op(op1 + 1); /* TOK_xxxC2 */
1475 } else {
1476 gen_op(op);
1477 /* stack: H1 H2 (L1 op L2) */
1478 vrotb(3);
1479 vrotb(3);
1480 /* stack: (L1 op L2) H1 H2 */
1481 gen_op(op);
1482 /* stack: (L1 op L2) (H1 op H2) */
1484 /* stack: L H */
1485 lbuild(t);
1486 break;
1487 case TOK_SAR:
1488 case TOK_SHR:
1489 case TOK_SHL:
1490 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1491 t = vtop[-1].type.t;
1492 vswap();
1493 lexpand();
1494 vrotb(3);
1495 /* stack: L H shift */
1496 c = (int)vtop->c.i;
1497 /* constant: simpler */
1498 /* NOTE: all comments are for SHL. the other cases are
1499 done by swaping words */
1500 vpop();
1501 if (op != TOK_SHL)
1502 vswap();
1503 if (c >= 32) {
1504 /* stack: L H */
1505 vpop();
1506 if (c > 32) {
1507 vpushi(c - 32);
1508 gen_op(op);
1510 if (op != TOK_SAR) {
1511 vpushi(0);
1512 } else {
1513 gv_dup();
1514 vpushi(31);
1515 gen_op(TOK_SAR);
1517 vswap();
1518 } else {
1519 vswap();
1520 gv_dup();
1521 /* stack: H L L */
1522 vpushi(c);
1523 gen_op(op);
1524 vswap();
1525 vpushi(32 - c);
1526 if (op == TOK_SHL)
1527 gen_op(TOK_SHR);
1528 else
1529 gen_op(TOK_SHL);
1530 vrotb(3);
1531 /* stack: L L H */
1532 vpushi(c);
1533 if (op == TOK_SHL)
1534 gen_op(TOK_SHL);
1535 else
1536 gen_op(TOK_SHR);
1537 gen_op('|');
1539 if (op != TOK_SHL)
1540 vswap();
1541 lbuild(t);
1542 } else {
1543 /* XXX: should provide a faster fallback on x86 ? */
1544 switch(op) {
1545 case TOK_SAR:
1546 func = TOK___ashrdi3;
1547 goto gen_func;
1548 case TOK_SHR:
1549 func = TOK___lshrdi3;
1550 goto gen_func;
1551 case TOK_SHL:
1552 func = TOK___ashldi3;
1553 goto gen_func;
1556 break;
1557 default:
1558 /* compare operations */
1559 t = vtop->type.t;
1560 vswap();
1561 lexpand();
1562 vrotb(3);
1563 lexpand();
1564 /* stack: L1 H1 L2 H2 */
1565 tmp = vtop[-1];
1566 vtop[-1] = vtop[-2];
1567 vtop[-2] = tmp;
1568 /* stack: L1 L2 H1 H2 */
1569 /* compare high */
1570 op1 = op;
1571 /* when values are equal, we need to compare low words. since
1572 the jump is inverted, we invert the test too. */
1573 if (op1 == TOK_LT)
1574 op1 = TOK_LE;
1575 else if (op1 == TOK_GT)
1576 op1 = TOK_GE;
1577 else if (op1 == TOK_ULT)
1578 op1 = TOK_ULE;
1579 else if (op1 == TOK_UGT)
1580 op1 = TOK_UGE;
1581 a = 0;
1582 b = 0;
1583 gen_op(op1);
1584 if (op1 != TOK_NE) {
1585 a = gvtst(1, 0);
1587 if (op != TOK_EQ) {
1588 /* generate non equal test */
1589 /* XXX: NOT PORTABLE yet */
1590 if (a == 0) {
1591 b = gvtst(0, 0);
1592 } else {
1593 #if defined(TCC_TARGET_I386)
1594 b = psym(0x850f, 0);
1595 #elif defined(TCC_TARGET_ARM)
1596 b = ind;
1597 o(0x1A000000 | encbranch(ind, 0, 1));
1598 #elif defined(TCC_TARGET_C67) || defined(TCC_TARGET_ARM64)
1599 tcc_error("not implemented");
1600 #else
1601 #error not supported
1602 #endif
1605 /* compare low. Always unsigned */
1606 op1 = op;
1607 if (op1 == TOK_LT)
1608 op1 = TOK_ULT;
1609 else if (op1 == TOK_LE)
1610 op1 = TOK_ULE;
1611 else if (op1 == TOK_GT)
1612 op1 = TOK_UGT;
1613 else if (op1 == TOK_GE)
1614 op1 = TOK_UGE;
1615 gen_op(op1);
1616 a = gvtst(1, a);
1617 gsym(b);
1618 vseti(VT_JMPI, a);
1619 break;
1622 #endif
1624 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
1626 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
1627 return (a ^ b) >> 63 ? -x : x;
1630 static int gen_opic_lt(uint64_t a, uint64_t b)
1632 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
1635 /* handle integer constant optimizations and various machine
1636 independent opt */
1637 static void gen_opic(int op)
1639 SValue *v1 = vtop - 1;
1640 SValue *v2 = vtop;
1641 int t1 = v1->type.t & VT_BTYPE;
1642 int t2 = v2->type.t & VT_BTYPE;
1643 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1644 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1645 uint64_t l1 = c1 ? v1->c.i : 0;
1646 uint64_t l2 = c2 ? v2->c.i : 0;
1647 int shm = (t1 == VT_LLONG) ? 63 : 31;
1649 if (t1 != VT_LLONG)
1650 l1 = ((uint32_t)l1 |
1651 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
1652 if (t2 != VT_LLONG)
1653 l2 = ((uint32_t)l2 |
1654 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
1656 if (c1 && c2) {
1657 switch(op) {
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;
1663 case '*': l1 *= l2; break;
1665 case TOK_PDIV:
1666 case '/':
1667 case '%':
1668 case TOK_UDIV:
1669 case TOK_UMOD:
1670 /* if division by zero, generate explicit division */
1671 if (l2 == 0) {
1672 if (const_wanted)
1673 tcc_error("division by zero in constant");
1674 goto general_case;
1676 switch(op) {
1677 default: l1 = gen_opic_sdiv(l1, l2); break;
1678 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
1679 case TOK_UDIV: l1 = l1 / l2; break;
1680 case TOK_UMOD: l1 = l1 % l2; break;
1682 break;
1683 case TOK_SHL: l1 <<= (l2 & shm); break;
1684 case TOK_SHR: l1 >>= (l2 & shm); break;
1685 case TOK_SAR:
1686 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
1687 break;
1688 /* tests */
1689 case TOK_ULT: l1 = l1 < l2; break;
1690 case TOK_UGE: l1 = l1 >= l2; break;
1691 case TOK_EQ: l1 = l1 == l2; break;
1692 case TOK_NE: l1 = l1 != l2; break;
1693 case TOK_ULE: l1 = l1 <= l2; break;
1694 case TOK_UGT: l1 = l1 > l2; break;
1695 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
1696 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
1697 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
1698 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
1699 /* logical */
1700 case TOK_LAND: l1 = l1 && l2; break;
1701 case TOK_LOR: l1 = l1 || l2; break;
1702 default:
1703 goto general_case;
1705 v1->c.i = l1;
1706 vtop--;
1707 } else {
1708 /* if commutative ops, put c2 as constant */
1709 if (c1 && (op == '+' || op == '&' || op == '^' ||
1710 op == '|' || op == '*')) {
1711 vswap();
1712 c2 = c1; //c = c1, c1 = c2, c2 = c;
1713 l2 = l1; //l = l1, l1 = l2, l2 = l;
1715 if (!const_wanted &&
1716 c1 && ((l1 == 0 &&
1717 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
1718 (l1 == -1 && op == TOK_SAR))) {
1719 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
1720 vtop--;
1721 } else if (!const_wanted &&
1722 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
1723 (l2 == -1 && op == '|') ||
1724 (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
1725 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
1726 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
1727 if (l2 == 1)
1728 vtop->c.i = 0;
1729 vswap();
1730 vtop--;
1731 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1732 op == TOK_PDIV) &&
1733 l2 == 1) ||
1734 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1735 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1736 l2 == 0) ||
1737 (op == '&' &&
1738 l2 == -1))) {
1739 /* filter out NOP operations like x*1, x-0, x&-1... */
1740 vtop--;
1741 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1742 /* try to use shifts instead of muls or divs */
1743 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1744 int n = -1;
1745 while (l2) {
1746 l2 >>= 1;
1747 n++;
1749 vtop->c.i = n;
1750 if (op == '*')
1751 op = TOK_SHL;
1752 else if (op == TOK_PDIV)
1753 op = TOK_SAR;
1754 else
1755 op = TOK_SHR;
1757 goto general_case;
1758 } else if (c2 && (op == '+' || op == '-') &&
1759 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1760 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1761 /* symbol + constant case */
1762 if (op == '-')
1763 l2 = -l2;
1764 vtop--;
1765 vtop->c.i += l2;
1766 } else {
1767 general_case:
1768 if (!nocode_wanted) {
1769 /* call low level op generator */
1770 if (t1 == VT_LLONG || t2 == VT_LLONG ||
1771 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
1772 gen_opl(op);
1773 else
1774 gen_opi(op);
1775 } else {
1776 vtop--;
1782 /* generate a floating point operation with constant propagation */
1783 static void gen_opif(int op)
1785 int c1, c2;
1786 SValue *v1, *v2;
1787 long double f1, f2;
1789 v1 = vtop - 1;
1790 v2 = vtop;
1791 /* currently, we cannot do computations with forward symbols */
1792 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1793 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1794 if (c1 && c2) {
1795 if (v1->type.t == VT_FLOAT) {
1796 f1 = v1->c.f;
1797 f2 = v2->c.f;
1798 } else if (v1->type.t == VT_DOUBLE) {
1799 f1 = v1->c.d;
1800 f2 = v2->c.d;
1801 } else {
1802 f1 = v1->c.ld;
1803 f2 = v2->c.ld;
1806 /* NOTE: we only do constant propagation if finite number (not
1807 NaN or infinity) (ANSI spec) */
1808 if (!ieee_finite(f1) || !ieee_finite(f2))
1809 goto general_case;
1811 switch(op) {
1812 case '+': f1 += f2; break;
1813 case '-': f1 -= f2; break;
1814 case '*': f1 *= f2; break;
1815 case '/':
1816 if (f2 == 0.0) {
1817 if (const_wanted)
1818 tcc_error("division by zero in constant");
1819 goto general_case;
1821 f1 /= f2;
1822 break;
1823 /* XXX: also handles tests ? */
1824 default:
1825 goto general_case;
1827 /* XXX: overflow test ? */
1828 if (v1->type.t == VT_FLOAT) {
1829 v1->c.f = f1;
1830 } else if (v1->type.t == VT_DOUBLE) {
1831 v1->c.d = f1;
1832 } else {
1833 v1->c.ld = f1;
1835 vtop--;
1836 } else {
1837 general_case:
1838 if (!nocode_wanted) {
1839 gen_opf(op);
1840 } else {
1841 vtop--;
1846 static int pointed_size(CType *type)
1848 int align;
1849 return type_size(pointed_type(type), &align);
1852 static void vla_runtime_pointed_size(CType *type)
1854 int align;
1855 vla_runtime_type_size(pointed_type(type), &align);
1858 static inline int is_null_pointer(SValue *p)
1860 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1861 return 0;
1862 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
1863 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
1864 ((p->type.t & VT_BTYPE) == VT_PTR &&
1865 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
1868 static inline int is_integer_btype(int bt)
1870 return (bt == VT_BYTE || bt == VT_SHORT ||
1871 bt == VT_INT || bt == VT_LLONG);
1874 /* check types for comparison or subtraction of pointers */
1875 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1877 CType *type1, *type2, tmp_type1, tmp_type2;
1878 int bt1, bt2;
1880 /* null pointers are accepted for all comparisons as gcc */
1881 if (is_null_pointer(p1) || is_null_pointer(p2))
1882 return;
1883 type1 = &p1->type;
1884 type2 = &p2->type;
1885 bt1 = type1->t & VT_BTYPE;
1886 bt2 = type2->t & VT_BTYPE;
1887 /* accept comparison between pointer and integer with a warning */
1888 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1889 if (op != TOK_LOR && op != TOK_LAND )
1890 tcc_warning("comparison between pointer and integer");
1891 return;
1894 /* both must be pointers or implicit function pointers */
1895 if (bt1 == VT_PTR) {
1896 type1 = pointed_type(type1);
1897 } else if (bt1 != VT_FUNC)
1898 goto invalid_operands;
1900 if (bt2 == VT_PTR) {
1901 type2 = pointed_type(type2);
1902 } else if (bt2 != VT_FUNC) {
1903 invalid_operands:
1904 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1906 if ((type1->t & VT_BTYPE) == VT_VOID ||
1907 (type2->t & VT_BTYPE) == VT_VOID)
1908 return;
1909 tmp_type1 = *type1;
1910 tmp_type2 = *type2;
1911 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1912 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1913 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1914 /* gcc-like error if '-' is used */
1915 if (op == '-')
1916 goto invalid_operands;
1917 else
1918 tcc_warning("comparison of distinct pointer types lacks a cast");
1922 /* generic gen_op: handles types problems */
1923 ST_FUNC void gen_op(int op)
1925 int u, t1, t2, bt1, bt2, t;
1926 CType type1;
1928 t1 = vtop[-1].type.t;
1929 t2 = vtop[0].type.t;
1930 bt1 = t1 & VT_BTYPE;
1931 bt2 = t2 & VT_BTYPE;
1933 if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1934 tcc_error("operation on a struct");
1935 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
1936 /* at least one operand is a pointer */
1937 /* relationnal op: must be both pointers */
1938 if (op >= TOK_ULT && op <= TOK_LOR) {
1939 check_comparison_pointer_types(vtop - 1, vtop, op);
1940 /* pointers are handled are unsigned */
1941 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1942 t = VT_LLONG | VT_UNSIGNED;
1943 #else
1944 t = VT_INT | VT_UNSIGNED;
1945 #endif
1946 goto std_op;
1948 /* if both pointers, then it must be the '-' op */
1949 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1950 if (op != '-')
1951 tcc_error("cannot use pointers here");
1952 check_comparison_pointer_types(vtop - 1, vtop, op);
1953 /* XXX: check that types are compatible */
1954 if (vtop[-1].type.t & VT_VLA) {
1955 vla_runtime_pointed_size(&vtop[-1].type);
1956 } else {
1957 vpushi(pointed_size(&vtop[-1].type));
1959 vrott(3);
1960 gen_opic(op);
1961 /* set to integer type */
1962 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1963 vtop->type.t = VT_LLONG;
1964 #else
1965 vtop->type.t = VT_INT;
1966 #endif
1967 vswap();
1968 gen_op(TOK_PDIV);
1969 } else {
1970 /* exactly one pointer : must be '+' or '-'. */
1971 if (op != '-' && op != '+')
1972 tcc_error("cannot use pointers here");
1973 /* Put pointer as first operand */
1974 if (bt2 == VT_PTR) {
1975 vswap();
1976 swap(&t1, &t2);
1978 #if PTR_SIZE == 4
1979 if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
1980 /* XXX: truncate here because gen_opl can't handle ptr + long long */
1981 gen_cast(&int_type);
1982 #endif
1983 type1 = vtop[-1].type;
1984 type1.t &= ~VT_ARRAY;
1985 if (vtop[-1].type.t & VT_VLA)
1986 vla_runtime_pointed_size(&vtop[-1].type);
1987 else {
1988 u = pointed_size(&vtop[-1].type);
1989 if (u < 0)
1990 tcc_error("unknown array element size");
1991 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1992 vpushll(u);
1993 #else
1994 /* XXX: cast to int ? (long long case) */
1995 vpushi(u);
1996 #endif
1998 gen_op('*');
1999 #if 0
2000 /* #ifdef CONFIG_TCC_BCHECK
2001 The main reason to removing this code:
2002 #include <stdio.h>
2003 int main ()
2005 int v[10];
2006 int i = 10;
2007 int j = 9;
2008 fprintf(stderr, "v+i-j = %p\n", v+i-j);
2009 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
2011 When this code is on. then the output looks like
2012 v+i-j = 0xfffffffe
2013 v+(i-j) = 0xbff84000
2015 /* if evaluating constant expression, no code should be
2016 generated, so no bound check */
2017 if (tcc_state->do_bounds_check && !const_wanted) {
2018 /* if bounded pointers, we generate a special code to
2019 test bounds */
2020 if (op == '-') {
2021 vpushi(0);
2022 vswap();
2023 gen_op('-');
2025 gen_bounded_ptr_add();
2026 } else
2027 #endif
2029 gen_opic(op);
2031 /* put again type if gen_opic() swaped operands */
2032 vtop->type = type1;
2034 } else if (is_float(bt1) || is_float(bt2)) {
2035 /* compute bigger type and do implicit casts */
2036 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
2037 t = VT_LDOUBLE;
2038 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
2039 t = VT_DOUBLE;
2040 } else {
2041 t = VT_FLOAT;
2043 /* floats can only be used for a few operations */
2044 if (op != '+' && op != '-' && op != '*' && op != '/' &&
2045 (op < TOK_ULT || op > TOK_GT))
2046 tcc_error("invalid operands for binary operation");
2047 goto std_op;
2048 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
2049 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
2050 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
2051 t |= VT_UNSIGNED;
2052 goto std_op;
2053 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
2054 /* cast to biggest op */
2055 t = VT_LLONG;
2056 /* convert to unsigned if it does not fit in a long long */
2057 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
2058 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
2059 t |= VT_UNSIGNED;
2060 goto std_op;
2061 } else {
2062 /* integer operations */
2063 t = VT_INT;
2064 /* convert to unsigned if it does not fit in an integer */
2065 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
2066 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
2067 t |= VT_UNSIGNED;
2068 std_op:
2069 /* XXX: currently, some unsigned operations are explicit, so
2070 we modify them here */
2071 if (t & VT_UNSIGNED) {
2072 if (op == TOK_SAR)
2073 op = TOK_SHR;
2074 else if (op == '/')
2075 op = TOK_UDIV;
2076 else if (op == '%')
2077 op = TOK_UMOD;
2078 else if (op == TOK_LT)
2079 op = TOK_ULT;
2080 else if (op == TOK_GT)
2081 op = TOK_UGT;
2082 else if (op == TOK_LE)
2083 op = TOK_ULE;
2084 else if (op == TOK_GE)
2085 op = TOK_UGE;
2087 vswap();
2088 type1.t = t;
2089 gen_cast(&type1);
2090 vswap();
2091 /* special case for shifts and long long: we keep the shift as
2092 an integer */
2093 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
2094 type1.t = VT_INT;
2095 gen_cast(&type1);
2096 if (is_float(t))
2097 gen_opif(op);
2098 else
2099 gen_opic(op);
2100 if (op >= TOK_ULT && op <= TOK_GT) {
2101 /* relationnal op: the result is an int */
2102 vtop->type.t = VT_INT;
2103 } else {
2104 vtop->type.t = t;
2107 // Make sure that we have converted to an rvalue:
2108 if (vtop->r & VT_LVAL && !nocode_wanted)
2109 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
2112 #ifndef TCC_TARGET_ARM
2113 /* generic itof for unsigned long long case */
2114 static void gen_cvt_itof1(int t)
2116 #ifdef TCC_TARGET_ARM64
2117 gen_cvt_itof(t);
2118 #else
2119 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
2120 (VT_LLONG | VT_UNSIGNED)) {
2122 if (t == VT_FLOAT)
2123 vpush_global_sym(&func_old_type, TOK___floatundisf);
2124 #if LDOUBLE_SIZE != 8
2125 else if (t == VT_LDOUBLE)
2126 vpush_global_sym(&func_old_type, TOK___floatundixf);
2127 #endif
2128 else
2129 vpush_global_sym(&func_old_type, TOK___floatundidf);
2130 vrott(2);
2131 gfunc_call(1);
2132 vpushi(0);
2133 vtop->r = reg_fret(t);
2134 } else {
2135 gen_cvt_itof(t);
2137 #endif
2139 #endif
2141 /* generic ftoi for unsigned long long case */
2142 static void gen_cvt_ftoi1(int t)
2144 #ifdef TCC_TARGET_ARM64
2145 gen_cvt_ftoi(t);
2146 #else
2147 int st;
2149 if (t == (VT_LLONG | VT_UNSIGNED)) {
2150 /* not handled natively */
2151 st = vtop->type.t & VT_BTYPE;
2152 if (st == VT_FLOAT)
2153 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
2154 #if LDOUBLE_SIZE != 8
2155 else if (st == VT_LDOUBLE)
2156 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
2157 #endif
2158 else
2159 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
2160 vrott(2);
2161 gfunc_call(1);
2162 vpushi(0);
2163 vtop->r = REG_IRET;
2164 vtop->r2 = REG_LRET;
2165 } else {
2166 gen_cvt_ftoi(t);
2168 #endif
2171 /* force char or short cast */
2172 static void force_charshort_cast(int t)
2174 int bits, dbt;
2175 dbt = t & VT_BTYPE;
2176 /* XXX: add optimization if lvalue : just change type and offset */
2177 if (dbt == VT_BYTE)
2178 bits = 8;
2179 else
2180 bits = 16;
2181 if (t & VT_UNSIGNED) {
2182 vpushi((1 << bits) - 1);
2183 gen_op('&');
2184 } else {
2185 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
2186 bits = 64 - bits;
2187 else
2188 bits = 32 - bits;
2189 vpushi(bits);
2190 gen_op(TOK_SHL);
2191 /* result must be signed or the SAR is converted to an SHL
2192 This was not the case when "t" was a signed short
2193 and the last value on the stack was an unsigned int */
2194 vtop->type.t &= ~VT_UNSIGNED;
2195 vpushi(bits);
2196 gen_op(TOK_SAR);
2200 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
2201 static void gen_cast(CType *type)
2203 int sbt, dbt, sf, df, c, p;
2205 /* special delayed cast for char/short */
2206 /* XXX: in some cases (multiple cascaded casts), it may still
2207 be incorrect */
2208 if (vtop->r & VT_MUSTCAST) {
2209 vtop->r &= ~VT_MUSTCAST;
2210 force_charshort_cast(vtop->type.t);
2213 /* bitfields first get cast to ints */
2214 if (vtop->type.t & VT_BITFIELD && !nocode_wanted) {
2215 gv(RC_INT);
2218 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
2219 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
2221 if (sbt != dbt) {
2222 sf = is_float(sbt);
2223 df = is_float(dbt);
2224 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2225 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
2226 if (c) {
2227 /* constant case: we can do it now */
2228 /* XXX: in ISOC, cannot do it if error in convert */
2229 if (sbt == VT_FLOAT)
2230 vtop->c.ld = vtop->c.f;
2231 else if (sbt == VT_DOUBLE)
2232 vtop->c.ld = vtop->c.d;
2234 if (df) {
2235 if ((sbt & VT_BTYPE) == VT_LLONG) {
2236 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
2237 vtop->c.ld = vtop->c.i;
2238 else
2239 vtop->c.ld = -(long double)-vtop->c.i;
2240 } else if(!sf) {
2241 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
2242 vtop->c.ld = (uint32_t)vtop->c.i;
2243 else
2244 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
2247 if (dbt == VT_FLOAT)
2248 vtop->c.f = (float)vtop->c.ld;
2249 else if (dbt == VT_DOUBLE)
2250 vtop->c.d = (double)vtop->c.ld;
2251 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
2252 vtop->c.i = vtop->c.ld;
2253 } else if (sf && dbt == VT_BOOL) {
2254 vtop->c.i = (vtop->c.ld != 0);
2255 } else {
2256 if(sf)
2257 vtop->c.i = vtop->c.ld;
2258 else if (sbt == (VT_LLONG|VT_UNSIGNED))
2260 else if (sbt & VT_UNSIGNED)
2261 vtop->c.i = (uint32_t)vtop->c.i;
2262 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2263 else if (sbt == VT_PTR)
2265 #endif
2266 else if (sbt != VT_LLONG)
2267 vtop->c.i = ((uint32_t)vtop->c.i |
2268 -(vtop->c.i & 0x80000000));
2270 if (dbt == (VT_LLONG|VT_UNSIGNED))
2272 else if (dbt == VT_BOOL)
2273 vtop->c.i = (vtop->c.i != 0);
2274 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2275 else if (dbt == VT_PTR)
2277 #endif
2278 else if (dbt != VT_LLONG) {
2279 uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
2280 (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
2281 0xffffffff);
2282 vtop->c.i &= m;
2283 if (!(dbt & VT_UNSIGNED))
2284 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
2287 } else if (p && dbt == VT_BOOL) {
2288 vtop->r = VT_CONST;
2289 vtop->c.i = 1;
2290 } else if (!nocode_wanted) {
2291 /* non constant case: generate code */
2292 if (sf && df) {
2293 /* convert from fp to fp */
2294 gen_cvt_ftof(dbt);
2295 } else if (df) {
2296 /* convert int to fp */
2297 gen_cvt_itof1(dbt);
2298 } else if (sf) {
2299 /* convert fp to int */
2300 if (dbt == VT_BOOL) {
2301 vpushi(0);
2302 gen_op(TOK_NE);
2303 } else {
2304 /* we handle char/short/etc... with generic code */
2305 if (dbt != (VT_INT | VT_UNSIGNED) &&
2306 dbt != (VT_LLONG | VT_UNSIGNED) &&
2307 dbt != VT_LLONG)
2308 dbt = VT_INT;
2309 gen_cvt_ftoi1(dbt);
2310 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2311 /* additional cast for char/short... */
2312 vtop->type.t = dbt;
2313 gen_cast(type);
2316 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
2317 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2318 if ((sbt & VT_BTYPE) != VT_LLONG) {
2319 /* scalar to long long */
2320 /* machine independent conversion */
2321 gv(RC_INT);
2322 /* generate high word */
2323 if (sbt == (VT_INT | VT_UNSIGNED)) {
2324 vpushi(0);
2325 gv(RC_INT);
2326 } else {
2327 if (sbt == VT_PTR) {
2328 /* cast from pointer to int before we apply
2329 shift operation, which pointers don't support*/
2330 gen_cast(&int_type);
2332 gv_dup();
2333 vpushi(31);
2334 gen_op(TOK_SAR);
2336 /* patch second register */
2337 vtop[-1].r2 = vtop->r;
2338 vpop();
2340 #else
2341 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2342 (dbt & VT_BTYPE) == VT_PTR ||
2343 (dbt & VT_BTYPE) == VT_FUNC) {
2344 if ((sbt & VT_BTYPE) != VT_LLONG &&
2345 (sbt & VT_BTYPE) != VT_PTR &&
2346 (sbt & VT_BTYPE) != VT_FUNC) {
2347 /* need to convert from 32bit to 64bit */
2348 gv(RC_INT);
2349 if (sbt != (VT_INT | VT_UNSIGNED)) {
2350 #if defined(TCC_TARGET_ARM64)
2351 gen_cvt_sxtw();
2352 #elif defined(TCC_TARGET_X86_64)
2353 int r = gv(RC_INT);
2354 /* x86_64 specific: movslq */
2355 o(0x6348);
2356 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2357 #else
2358 #error
2359 #endif
2362 #endif
2363 } else if (dbt == VT_BOOL) {
2364 /* scalar to bool */
2365 vpushi(0);
2366 gen_op(TOK_NE);
2367 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2368 (dbt & VT_BTYPE) == VT_SHORT) {
2369 if (sbt == VT_PTR) {
2370 vtop->type.t = VT_INT;
2371 tcc_warning("nonportable conversion from pointer to char/short");
2373 force_charshort_cast(dbt);
2374 } else if ((dbt & VT_BTYPE) == VT_INT) {
2375 /* scalar to int */
2376 if ((sbt & VT_BTYPE) == VT_LLONG) {
2377 /* from long long: just take low order word */
2378 lexpand();
2379 vpop();
2381 /* if lvalue and single word type, nothing to do because
2382 the lvalue already contains the real type size (see
2383 VT_LVAL_xxx constants) */
2386 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2387 /* if we are casting between pointer types,
2388 we must update the VT_LVAL_xxx size */
2389 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2390 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2392 vtop->type = *type;
2395 /* return type size as known at compile time. Put alignment at 'a' */
2396 ST_FUNC int type_size(CType *type, int *a)
2398 Sym *s;
2399 int bt;
2401 bt = type->t & VT_BTYPE;
2402 if (bt == VT_STRUCT) {
2403 /* struct/union */
2404 s = type->ref;
2405 *a = s->r;
2406 return s->c;
2407 } else if (bt == VT_PTR) {
2408 if (type->t & VT_ARRAY) {
2409 int ts;
2411 s = type->ref;
2412 ts = type_size(&s->type, a);
2414 if (ts < 0 && s->c < 0)
2415 ts = -ts;
2417 return ts * s->c;
2418 } else {
2419 *a = PTR_SIZE;
2420 return PTR_SIZE;
2422 } else if (bt == VT_LDOUBLE) {
2423 *a = LDOUBLE_ALIGN;
2424 return LDOUBLE_SIZE;
2425 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2426 #ifdef TCC_TARGET_I386
2427 #ifdef TCC_TARGET_PE
2428 *a = 8;
2429 #else
2430 *a = 4;
2431 #endif
2432 #elif defined(TCC_TARGET_ARM)
2433 #ifdef TCC_ARM_EABI
2434 *a = 8;
2435 #else
2436 *a = 4;
2437 #endif
2438 #else
2439 *a = 8;
2440 #endif
2441 return 8;
2442 } else if (bt == VT_INT || bt == VT_FLOAT) {
2443 *a = 4;
2444 return 4;
2445 } else if (bt == VT_SHORT) {
2446 *a = 2;
2447 return 2;
2448 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2449 *a = 8;
2450 return 16;
2451 } else if (bt == VT_ENUM) {
2452 *a = 4;
2453 /* Enums might be incomplete, so don't just return '4' here. */
2454 return type->ref->c;
2455 } else {
2456 /* char, void, function, _Bool */
2457 *a = 1;
2458 return 1;
2462 /* push type size as known at runtime time on top of value stack. Put
2463 alignment at 'a' */
2464 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2466 if (type->t & VT_VLA) {
2467 type_size(&type->ref->type, a);
2468 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2469 } else {
2470 vpushi(type_size(type, a));
2474 static void vla_sp_restore(void) {
2475 if (vlas_in_scope) {
2476 gen_vla_sp_restore(vla_sp_loc);
2480 static void vla_sp_restore_root(void) {
2481 if (vlas_in_scope) {
2482 gen_vla_sp_restore(vla_sp_root_loc);
2486 /* return the pointed type of t */
2487 static inline CType *pointed_type(CType *type)
2489 return &type->ref->type;
2492 /* modify type so that its it is a pointer to type. */
2493 ST_FUNC void mk_pointer(CType *type)
2495 Sym *s;
2496 s = sym_push(SYM_FIELD, type, 0, -1);
2497 type->t = VT_PTR | (type->t & ~VT_TYPE);
2498 type->ref = s;
2501 /* compare function types. OLD functions match any new functions */
2502 static int is_compatible_func(CType *type1, CType *type2)
2504 Sym *s1, *s2;
2506 s1 = type1->ref;
2507 s2 = type2->ref;
2508 if (!is_compatible_types(&s1->type, &s2->type))
2509 return 0;
2510 /* check func_call */
2511 if (s1->a.func_call != s2->a.func_call)
2512 return 0;
2513 /* XXX: not complete */
2514 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2515 return 1;
2516 if (s1->c != s2->c)
2517 return 0;
2518 while (s1 != NULL) {
2519 if (s2 == NULL)
2520 return 0;
2521 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2522 return 0;
2523 s1 = s1->next;
2524 s2 = s2->next;
2526 if (s2)
2527 return 0;
2528 return 1;
2531 /* return true if type1 and type2 are the same. If unqualified is
2532 true, qualifiers on the types are ignored.
2534 - enums are not checked as gcc __builtin_types_compatible_p ()
2536 static int compare_types(CType *type1, CType *type2, int unqualified)
2538 int bt1, t1, t2;
2540 t1 = type1->t & VT_TYPE;
2541 t2 = type2->t & VT_TYPE;
2542 if (unqualified) {
2543 /* strip qualifiers before comparing */
2544 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2545 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2547 /* Default Vs explicit signedness only matters for char */
2548 if ((t1 & VT_BTYPE) != VT_BYTE) {
2549 t1 &= ~VT_DEFSIGN;
2550 t2 &= ~VT_DEFSIGN;
2552 /* XXX: bitfields ? */
2553 if (t1 != t2)
2554 return 0;
2555 /* test more complicated cases */
2556 bt1 = t1 & VT_BTYPE;
2557 if (bt1 == VT_PTR) {
2558 type1 = pointed_type(type1);
2559 type2 = pointed_type(type2);
2560 return is_compatible_types(type1, type2);
2561 } else if (bt1 == VT_STRUCT) {
2562 return (type1->ref == type2->ref);
2563 } else if (bt1 == VT_FUNC) {
2564 return is_compatible_func(type1, type2);
2565 } else {
2566 return 1;
2570 /* return true if type1 and type2 are exactly the same (including
2571 qualifiers).
2573 static int is_compatible_types(CType *type1, CType *type2)
2575 return compare_types(type1,type2,0);
2578 /* return true if type1 and type2 are the same (ignoring qualifiers).
2580 static int is_compatible_parameter_types(CType *type1, CType *type2)
2582 return compare_types(type1,type2,1);
2585 /* print a type. If 'varstr' is not NULL, then the variable is also
2586 printed in the type */
2587 /* XXX: union */
2588 /* XXX: add array and function pointers */
2589 static void type_to_str(char *buf, int buf_size,
2590 CType *type, const char *varstr)
2592 int bt, v, t;
2593 Sym *s, *sa;
2594 char buf1[256];
2595 const char *tstr;
2597 t = type->t & VT_TYPE;
2598 bt = t & VT_BTYPE;
2599 buf[0] = '\0';
2600 if (t & VT_CONSTANT)
2601 pstrcat(buf, buf_size, "const ");
2602 if (t & VT_VOLATILE)
2603 pstrcat(buf, buf_size, "volatile ");
2604 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2605 pstrcat(buf, buf_size, "unsigned ");
2606 else if (t & VT_DEFSIGN)
2607 pstrcat(buf, buf_size, "signed ");
2608 switch(bt) {
2609 case VT_VOID:
2610 tstr = "void";
2611 goto add_tstr;
2612 case VT_BOOL:
2613 tstr = "_Bool";
2614 goto add_tstr;
2615 case VT_BYTE:
2616 tstr = "char";
2617 goto add_tstr;
2618 case VT_SHORT:
2619 tstr = "short";
2620 goto add_tstr;
2621 case VT_INT:
2622 tstr = "int";
2623 goto add_tstr;
2624 case VT_LONG:
2625 tstr = "long";
2626 goto add_tstr;
2627 case VT_LLONG:
2628 tstr = "long long";
2629 goto add_tstr;
2630 case VT_FLOAT:
2631 tstr = "float";
2632 goto add_tstr;
2633 case VT_DOUBLE:
2634 tstr = "double";
2635 goto add_tstr;
2636 case VT_LDOUBLE:
2637 tstr = "long double";
2638 add_tstr:
2639 pstrcat(buf, buf_size, tstr);
2640 break;
2641 case VT_ENUM:
2642 case VT_STRUCT:
2643 if (bt == VT_STRUCT)
2644 tstr = "struct ";
2645 else
2646 tstr = "enum ";
2647 pstrcat(buf, buf_size, tstr);
2648 v = type->ref->v & ~SYM_STRUCT;
2649 if (v >= SYM_FIRST_ANOM)
2650 pstrcat(buf, buf_size, "<anonymous>");
2651 else
2652 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2653 break;
2654 case VT_FUNC:
2655 s = type->ref;
2656 type_to_str(buf, buf_size, &s->type, varstr);
2657 pstrcat(buf, buf_size, "(");
2658 sa = s->next;
2659 while (sa != NULL) {
2660 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2661 pstrcat(buf, buf_size, buf1);
2662 sa = sa->next;
2663 if (sa)
2664 pstrcat(buf, buf_size, ", ");
2666 pstrcat(buf, buf_size, ")");
2667 goto no_var;
2668 case VT_PTR:
2669 s = type->ref;
2670 if (t & VT_ARRAY) {
2671 snprintf(buf1, sizeof(buf1), "%s[%ld]", varstr ? varstr : "", s->c);
2672 type_to_str(buf, buf_size, &s->type, buf1);
2673 goto no_var;
2675 pstrcpy(buf1, sizeof(buf1), "*");
2676 if (t & VT_CONSTANT)
2677 pstrcat(buf1, buf_size, "const ");
2678 if (t & VT_VOLATILE)
2679 pstrcat(buf1, buf_size, "volatile ");
2680 if (varstr)
2681 pstrcat(buf1, sizeof(buf1), varstr);
2682 type_to_str(buf, buf_size, &s->type, buf1);
2683 goto no_var;
2685 if (varstr) {
2686 pstrcat(buf, buf_size, " ");
2687 pstrcat(buf, buf_size, varstr);
2689 no_var: ;
2692 /* verify type compatibility to store vtop in 'dt' type, and generate
2693 casts if needed. */
2694 static void gen_assign_cast(CType *dt)
2696 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2697 char buf1[256], buf2[256];
2698 int dbt, sbt;
2700 st = &vtop->type; /* source type */
2701 dbt = dt->t & VT_BTYPE;
2702 sbt = st->t & VT_BTYPE;
2703 if (sbt == VT_VOID || dbt == VT_VOID) {
2704 if (sbt == VT_VOID && dbt == VT_VOID)
2705 ; /*
2706 It is Ok if both are void
2707 A test program:
2708 void func1() {}
2709 void func2() {
2710 return func1();
2712 gcc accepts this program
2714 else
2715 tcc_error("cannot cast from/to void");
2717 if (dt->t & VT_CONSTANT)
2718 tcc_warning("assignment of read-only location");
2719 switch(dbt) {
2720 case VT_PTR:
2721 /* special cases for pointers */
2722 /* '0' can also be a pointer */
2723 if (is_null_pointer(vtop))
2724 goto type_ok;
2725 /* accept implicit pointer to integer cast with warning */
2726 if (is_integer_btype(sbt)) {
2727 tcc_warning("assignment makes pointer from integer without a cast");
2728 goto type_ok;
2730 type1 = pointed_type(dt);
2731 /* a function is implicitely a function pointer */
2732 if (sbt == VT_FUNC) {
2733 if ((type1->t & VT_BTYPE) != VT_VOID &&
2734 !is_compatible_types(pointed_type(dt), st))
2735 tcc_warning("assignment from incompatible pointer type");
2736 goto type_ok;
2738 if (sbt != VT_PTR)
2739 goto error;
2740 type2 = pointed_type(st);
2741 if ((type1->t & VT_BTYPE) == VT_VOID ||
2742 (type2->t & VT_BTYPE) == VT_VOID) {
2743 /* void * can match anything */
2744 } else {
2745 /* exact type match, except for unsigned */
2746 tmp_type1 = *type1;
2747 tmp_type2 = *type2;
2748 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2749 VT_VOLATILE);
2750 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2751 VT_VOLATILE);
2752 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2753 tcc_warning("assignment from incompatible pointer type");
2755 /* check const and volatile */
2756 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2757 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2758 tcc_warning("assignment discards qualifiers from pointer target type");
2759 break;
2760 case VT_BYTE:
2761 case VT_SHORT:
2762 case VT_INT:
2763 case VT_LLONG:
2764 if (sbt == VT_PTR || sbt == VT_FUNC) {
2765 tcc_warning("assignment makes integer from pointer without a cast");
2766 } else if (sbt == VT_STRUCT) {
2767 goto case_VT_STRUCT;
2769 /* XXX: more tests */
2770 break;
2771 case VT_STRUCT:
2772 case_VT_STRUCT:
2773 tmp_type1 = *dt;
2774 tmp_type2 = *st;
2775 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2776 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2777 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2778 error:
2779 type_to_str(buf1, sizeof(buf1), st, NULL);
2780 type_to_str(buf2, sizeof(buf2), dt, NULL);
2781 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2783 break;
2785 type_ok:
2786 gen_cast(dt);
2789 /* store vtop in lvalue pushed on stack */
2790 ST_FUNC void vstore(void)
2792 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2794 ft = vtop[-1].type.t;
2795 sbt = vtop->type.t & VT_BTYPE;
2796 dbt = ft & VT_BTYPE;
2797 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2798 (sbt == VT_INT && dbt == VT_SHORT))
2799 && !(vtop->type.t & VT_BITFIELD)) {
2800 /* optimize char/short casts */
2801 delayed_cast = VT_MUSTCAST;
2802 vtop->type.t = (ft & VT_TYPE & ~VT_BITFIELD &
2803 ((1 << VT_STRUCT_SHIFT) - 1));
2804 /* XXX: factorize */
2805 if (ft & VT_CONSTANT)
2806 tcc_warning("assignment of read-only location");
2807 } else {
2808 delayed_cast = 0;
2809 if (!(ft & VT_BITFIELD))
2810 gen_assign_cast(&vtop[-1].type);
2813 if (sbt == VT_STRUCT) {
2814 /* if structure, only generate pointer */
2815 /* structure assignment : generate memcpy */
2816 /* XXX: optimize if small size */
2817 if (!nocode_wanted) {
2818 size = type_size(&vtop->type, &align);
2820 /* destination */
2821 vswap();
2822 vtop->type.t = VT_PTR;
2823 gaddrof();
2825 /* address of memcpy() */
2826 #ifdef TCC_ARM_EABI
2827 if(!(align & 7))
2828 vpush_global_sym(&func_old_type, TOK_memcpy8);
2829 else if(!(align & 3))
2830 vpush_global_sym(&func_old_type, TOK_memcpy4);
2831 else
2832 #endif
2833 /* Use memmove, rather than memcpy, as dest and src may be same: */
2834 vpush_global_sym(&func_old_type, TOK_memmove);
2836 vswap();
2837 /* source */
2838 vpushv(vtop - 2);
2839 vtop->type.t = VT_PTR;
2840 gaddrof();
2841 /* type size */
2842 vpushi(size);
2843 gfunc_call(3);
2844 } else {
2845 vswap();
2846 vpop();
2848 /* leave source on stack */
2849 } else if (ft & VT_BITFIELD) {
2850 /* bitfield store handling */
2852 /* save lvalue as expression result (example: s.b = s.a = n;) */
2853 vdup(), vtop[-1] = vtop[-2];
2855 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2856 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2857 /* remove bit field info to avoid loops */
2858 vtop[-1].type.t = ft & ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
2860 if((ft & VT_BTYPE) == VT_BOOL) {
2861 gen_cast(&vtop[-1].type);
2862 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2865 /* duplicate destination */
2866 vdup();
2867 vtop[-1] = vtop[-2];
2869 /* mask and shift source */
2870 if((ft & VT_BTYPE) != VT_BOOL) {
2871 if((ft & VT_BTYPE) == VT_LLONG) {
2872 vpushll((1ULL << bit_size) - 1ULL);
2873 } else {
2874 vpushi((1 << bit_size) - 1);
2876 gen_op('&');
2878 vpushi(bit_pos);
2879 gen_op(TOK_SHL);
2880 /* load destination, mask and or with source */
2881 vswap();
2882 if((ft & VT_BTYPE) == VT_LLONG) {
2883 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2884 } else {
2885 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2887 gen_op('&');
2888 gen_op('|');
2889 /* store result */
2890 vstore();
2891 /* ... and discard */
2892 vpop();
2894 } else {
2895 if (!nocode_wanted) {
2896 #ifdef CONFIG_TCC_BCHECK
2897 /* bound check case */
2898 if (vtop[-1].r & VT_MUSTBOUND) {
2899 vswap();
2900 gbound();
2901 vswap();
2903 #endif
2904 rc = RC_INT;
2905 if (is_float(ft)) {
2906 rc = RC_FLOAT;
2907 #ifdef TCC_TARGET_X86_64
2908 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2909 rc = RC_ST0;
2910 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2911 rc = RC_FRET;
2913 #endif
2915 r = gv(rc); /* generate value */
2916 /* if lvalue was saved on stack, must read it */
2917 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2918 SValue sv;
2919 t = get_reg(RC_INT);
2920 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2921 sv.type.t = VT_PTR;
2922 #else
2923 sv.type.t = VT_INT;
2924 #endif
2925 sv.r = VT_LOCAL | VT_LVAL;
2926 sv.c.i = vtop[-1].c.i;
2927 load(t, &sv);
2928 vtop[-1].r = t | VT_LVAL;
2930 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2931 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2932 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2933 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2934 #else
2935 if ((ft & VT_BTYPE) == VT_LLONG) {
2936 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2937 #endif
2938 vtop[-1].type.t = load_type;
2939 store(r, vtop - 1);
2940 vswap();
2941 /* convert to int to increment easily */
2942 vtop->type.t = addr_type;
2943 gaddrof();
2944 vpushi(load_size);
2945 gen_op('+');
2946 vtop->r |= VT_LVAL;
2947 vswap();
2948 vtop[-1].type.t = load_type;
2949 /* XXX: it works because r2 is spilled last ! */
2950 store(vtop->r2, vtop - 1);
2951 } else {
2952 store(r, vtop - 1);
2955 vswap();
2956 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2957 vtop->r |= delayed_cast;
2961 /* post defines POST/PRE add. c is the token ++ or -- */
2962 ST_FUNC void inc(int post, int c)
2964 test_lvalue();
2965 vdup(); /* save lvalue */
2966 if (post) {
2967 if (!nocode_wanted)
2968 gv_dup(); /* duplicate value */
2969 else
2970 vdup(); /* duplicate value */
2971 vrotb(3);
2972 vrotb(3);
2974 /* add constant */
2975 vpushi(c - TOK_MID);
2976 gen_op('+');
2977 vstore(); /* store value */
2978 if (post)
2979 vpop(); /* if post op, return saved value */
2982 /* Parse GNUC __attribute__ extension. Currently, the following
2983 extensions are recognized:
2984 - aligned(n) : set data/function alignment.
2985 - packed : force data alignment to 1
2986 - section(x) : generate data/code in this section.
2987 - unused : currently ignored, but may be used someday.
2988 - regparm(n) : pass function parameters in registers (i386 only)
2990 static void parse_attribute(AttributeDef *ad)
2992 int t, n;
2994 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2995 next();
2996 skip('(');
2997 skip('(');
2998 while (tok != ')') {
2999 if (tok < TOK_IDENT)
3000 expect("attribute name");
3001 t = tok;
3002 next();
3003 switch(t) {
3004 case TOK_SECTION1:
3005 case TOK_SECTION2:
3006 skip('(');
3007 if (tok != TOK_STR)
3008 expect("section name");
3009 ad->section = find_section(tcc_state, (char *)tokc.str.data);
3010 next();
3011 skip(')');
3012 break;
3013 case TOK_ALIAS1:
3014 case TOK_ALIAS2:
3015 skip('(');
3016 if (tok != TOK_STR)
3017 expect("alias(\"target\")");
3018 ad->alias_target = /* save string as token, for later */
3019 tok_alloc((char*)tokc.str.data, tokc.str.size-1)->tok;
3020 next();
3021 skip(')');
3022 break;
3023 case TOK_VISIBILITY1:
3024 case TOK_VISIBILITY2:
3025 skip('(');
3026 if (tok != TOK_STR)
3027 expect("visibility(\"default|hidden|internal|protected\")");
3028 if (!strcmp (tokc.str.data, "default"))
3029 ad->a.visibility = STV_DEFAULT;
3030 else if (!strcmp (tokc.str.data, "hidden"))
3031 ad->a.visibility = STV_HIDDEN;
3032 else if (!strcmp (tokc.str.data, "internal"))
3033 ad->a.visibility = STV_INTERNAL;
3034 else if (!strcmp (tokc.str.data, "protected"))
3035 ad->a.visibility = STV_PROTECTED;
3036 else
3037 expect("visibility(\"default|hidden|internal|protected\")");
3038 next();
3039 skip(')');
3040 break;
3041 case TOK_ALIGNED1:
3042 case TOK_ALIGNED2:
3043 if (tok == '(') {
3044 next();
3045 n = expr_const();
3046 if (n <= 0 || (n & (n - 1)) != 0)
3047 tcc_error("alignment must be a positive power of two");
3048 skip(')');
3049 } else {
3050 n = MAX_ALIGN;
3052 ad->a.aligned = n;
3053 break;
3054 case TOK_PACKED1:
3055 case TOK_PACKED2:
3056 ad->a.packed = 1;
3057 break;
3058 case TOK_WEAK1:
3059 case TOK_WEAK2:
3060 ad->a.weak = 1;
3061 break;
3062 case TOK_UNUSED1:
3063 case TOK_UNUSED2:
3064 /* currently, no need to handle it because tcc does not
3065 track unused objects */
3066 break;
3067 case TOK_NORETURN1:
3068 case TOK_NORETURN2:
3069 /* currently, no need to handle it because tcc does not
3070 track unused objects */
3071 break;
3072 case TOK_CDECL1:
3073 case TOK_CDECL2:
3074 case TOK_CDECL3:
3075 ad->a.func_call = FUNC_CDECL;
3076 break;
3077 case TOK_STDCALL1:
3078 case TOK_STDCALL2:
3079 case TOK_STDCALL3:
3080 ad->a.func_call = FUNC_STDCALL;
3081 break;
3082 #ifdef TCC_TARGET_I386
3083 case TOK_REGPARM1:
3084 case TOK_REGPARM2:
3085 skip('(');
3086 n = expr_const();
3087 if (n > 3)
3088 n = 3;
3089 else if (n < 0)
3090 n = 0;
3091 if (n > 0)
3092 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
3093 skip(')');
3094 break;
3095 case TOK_FASTCALL1:
3096 case TOK_FASTCALL2:
3097 case TOK_FASTCALL3:
3098 ad->a.func_call = FUNC_FASTCALLW;
3099 break;
3100 #endif
3101 case TOK_MODE:
3102 skip('(');
3103 switch(tok) {
3104 case TOK_MODE_DI:
3105 ad->a.mode = VT_LLONG + 1;
3106 break;
3107 case TOK_MODE_QI:
3108 ad->a.mode = VT_BYTE + 1;
3109 break;
3110 case TOK_MODE_HI:
3111 ad->a.mode = VT_SHORT + 1;
3112 break;
3113 case TOK_MODE_SI:
3114 case TOK_MODE_word:
3115 ad->a.mode = VT_INT + 1;
3116 break;
3117 default:
3118 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
3119 break;
3121 next();
3122 skip(')');
3123 break;
3124 case TOK_DLLEXPORT:
3125 ad->a.func_export = 1;
3126 break;
3127 case TOK_DLLIMPORT:
3128 ad->a.func_import = 1;
3129 break;
3130 default:
3131 if (tcc_state->warn_unsupported)
3132 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
3133 /* skip parameters */
3134 if (tok == '(') {
3135 int parenthesis = 0;
3136 do {
3137 if (tok == '(')
3138 parenthesis++;
3139 else if (tok == ')')
3140 parenthesis--;
3141 next();
3142 } while (parenthesis && tok != -1);
3144 break;
3146 if (tok != ',')
3147 break;
3148 next();
3150 skip(')');
3151 skip(')');
3155 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
3156 static void struct_decl(CType *type, AttributeDef *ad, int u)
3158 int a, v, size, align, maxalign, c, offset, flexible;
3159 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
3160 Sym *s, *ss, *ass, **ps;
3161 AttributeDef ad1;
3162 CType type1, btype;
3164 a = tok; /* save decl type */
3165 next();
3166 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
3167 parse_attribute(ad);
3168 next();
3170 if (tok != '{') {
3171 v = tok;
3172 next();
3173 /* struct already defined ? return it */
3174 if (v < TOK_IDENT)
3175 expect("struct/union/enum name");
3176 s = struct_find(v);
3177 if (s && (s->scope == local_scope || (tok != '{' && tok != ';'))) {
3178 if (s->type.t != a)
3179 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
3180 goto do_decl;
3182 } else {
3183 v = anon_sym++;
3185 type1.t = a;
3186 type1.ref = NULL;
3187 /* we put an undefined size for struct/union */
3188 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
3189 s->r = 0; /* default alignment is zero as gcc */
3190 /* put struct/union/enum name in type */
3191 do_decl:
3192 type->t = u;
3193 type->ref = s;
3195 if (tok == '{') {
3196 next();
3197 if (s->c != -1)
3198 tcc_error("struct/union/enum already defined");
3199 /* cannot be empty */
3200 c = 0;
3201 /* non empty enums are not allowed */
3202 if (a == TOK_ENUM) {
3203 for(;;) {
3204 v = tok;
3205 if (v < TOK_UIDENT)
3206 expect("identifier");
3207 ss = sym_find(v);
3208 if (ss && !local_stack)
3209 tcc_error("redefinition of enumerator '%s'",
3210 get_tok_str(v, NULL));
3211 next();
3212 if (tok == '=') {
3213 next();
3214 c = expr_const();
3216 /* enum symbols have static storage */
3217 ss = sym_push(v, &int_type, VT_CONST, c);
3218 ss->type.t |= VT_STATIC;
3219 if (tok != ',')
3220 break;
3221 next();
3222 c++;
3223 /* NOTE: we accept a trailing comma */
3224 if (tok == '}')
3225 break;
3227 s->c = type_size(&int_type, &align);
3228 skip('}');
3229 } else {
3230 maxalign = 1;
3231 ps = &s->next;
3232 prevbt = VT_INT;
3233 bit_pos = 0;
3234 offset = 0;
3235 flexible = 0;
3236 while (tok != '}') {
3237 parse_btype(&btype, &ad1);
3238 while (1) {
3239 if (flexible)
3240 tcc_error("flexible array member '%s' not at the end of struct",
3241 get_tok_str(v, NULL));
3242 bit_size = -1;
3243 v = 0;
3244 type1 = btype;
3245 if (tok != ':') {
3246 type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT);
3247 if (v == 0) {
3248 if ((type1.t & VT_BTYPE) != VT_STRUCT)
3249 expect("identifier");
3250 else {
3251 int v = btype.ref->v;
3252 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
3253 if (tcc_state->ms_extensions == 0)
3254 expect("identifier");
3258 if (type_size(&type1, &align) < 0) {
3259 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
3260 flexible = 1;
3261 else
3262 tcc_error("field '%s' has incomplete type",
3263 get_tok_str(v, NULL));
3265 if ((type1.t & VT_BTYPE) == VT_FUNC ||
3266 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
3267 tcc_error("invalid type for '%s'",
3268 get_tok_str(v, NULL));
3270 if (tok == ':') {
3271 next();
3272 bit_size = expr_const();
3273 /* XXX: handle v = 0 case for messages */
3274 if (bit_size < 0)
3275 tcc_error("negative width in bit-field '%s'",
3276 get_tok_str(v, NULL));
3277 if (v && bit_size == 0)
3278 tcc_error("zero width for bit-field '%s'",
3279 get_tok_str(v, NULL));
3281 size = type_size(&type1, &align);
3282 if (ad1.a.aligned) {
3283 if (align < ad1.a.aligned)
3284 align = ad1.a.aligned;
3285 } else if (ad1.a.packed) {
3286 align = 1;
3287 } else if (*tcc_state->pack_stack_ptr) {
3288 if (align > *tcc_state->pack_stack_ptr)
3289 align = *tcc_state->pack_stack_ptr;
3291 lbit_pos = 0;
3292 if (bit_size >= 0) {
3293 bt = type1.t & VT_BTYPE;
3294 if (bt != VT_INT &&
3295 bt != VT_BYTE &&
3296 bt != VT_SHORT &&
3297 bt != VT_BOOL &&
3298 bt != VT_ENUM &&
3299 bt != VT_LLONG)
3300 tcc_error("bitfields must have scalar type");
3301 bsize = size * 8;
3302 if (bit_size > bsize) {
3303 tcc_error("width of '%s' exceeds its type",
3304 get_tok_str(v, NULL));
3305 } else if (bit_size == bsize) {
3306 /* no need for bit fields */
3307 bit_pos = 0;
3308 } else if (bit_size == 0) {
3309 /* XXX: what to do if only padding in a
3310 structure ? */
3311 /* zero size: means to pad */
3312 bit_pos = 0;
3313 } else {
3314 /* we do not have enough room ?
3315 did the type change?
3316 is it a union? */
3317 if ((bit_pos + bit_size) > bsize ||
3318 bt != prevbt || a == TOK_UNION)
3319 bit_pos = 0;
3320 lbit_pos = bit_pos;
3321 /* XXX: handle LSB first */
3322 type1.t |= VT_BITFIELD |
3323 (bit_pos << VT_STRUCT_SHIFT) |
3324 (bit_size << (VT_STRUCT_SHIFT + 6));
3325 bit_pos += bit_size;
3327 prevbt = bt;
3328 } else {
3329 bit_pos = 0;
3331 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3332 /* add new memory data only if starting
3333 bit field */
3334 if (lbit_pos == 0) {
3335 if (a == TOK_STRUCT) {
3336 c = (c + align - 1) & -align;
3337 offset = c;
3338 if (size > 0)
3339 c += size;
3340 } else {
3341 offset = 0;
3342 if (size > c)
3343 c = size;
3345 if (align > maxalign)
3346 maxalign = align;
3348 #if 0
3349 printf("add field %s offset=%d",
3350 get_tok_str(v, NULL), offset);
3351 if (type1.t & VT_BITFIELD) {
3352 printf(" pos=%d size=%d",
3353 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3354 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3356 printf("\n");
3357 #endif
3359 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3360 ass = type1.ref;
3361 while ((ass = ass->next) != NULL) {
3362 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3363 *ps = ss;
3364 ps = &ss->next;
3366 } else if (v) {
3367 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3368 *ps = ss;
3369 ps = &ss->next;
3371 if (tok == ';' || tok == TOK_EOF)
3372 break;
3373 skip(',');
3375 skip(';');
3377 skip('}');
3378 /* store size and alignment */
3379 s->c = (c + maxalign - 1) & -maxalign;
3380 s->r = maxalign;
3385 /* return 1 if basic type is a type size (short, long, long long) */
3386 ST_FUNC int is_btype_size(int bt)
3388 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3391 /* Add type qualifiers to a type. If the type is an array then the qualifiers
3392 are added to the element type, copied because it could be a typedef. */
3393 static void parse_btype_qualify(CType *type, int qualifiers)
3395 while (type->t & VT_ARRAY) {
3396 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
3397 type = &type->ref->type;
3399 type->t |= qualifiers;
3402 /* return 0 if no type declaration. otherwise, return the basic type
3403 and skip it.
3405 static int parse_btype(CType *type, AttributeDef *ad)
3407 int t, u, bt_size, complete, type_found, typespec_found;
3408 Sym *s;
3409 CType type1;
3411 memset(ad, 0, sizeof(AttributeDef));
3412 complete = 0;
3413 type_found = 0;
3414 typespec_found = 0;
3415 t = 0;
3416 while(1) {
3417 switch(tok) {
3418 case TOK_EXTENSION:
3419 /* currently, we really ignore extension */
3420 next();
3421 continue;
3423 /* basic types */
3424 case TOK_CHAR:
3425 u = VT_BYTE;
3426 basic_type:
3427 next();
3428 basic_type1:
3429 if (complete)
3430 tcc_error("too many basic types");
3431 t |= u;
3432 bt_size = is_btype_size (u & VT_BTYPE);
3433 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3434 complete = 1;
3435 typespec_found = 1;
3436 break;
3437 case TOK_VOID:
3438 u = VT_VOID;
3439 goto basic_type;
3440 case TOK_SHORT:
3441 u = VT_SHORT;
3442 goto basic_type;
3443 case TOK_INT:
3444 u = VT_INT;
3445 goto basic_type;
3446 case TOK_LONG:
3447 next();
3448 if ((t & VT_BTYPE) == VT_DOUBLE) {
3449 #ifndef TCC_TARGET_PE
3450 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3451 #endif
3452 } else if ((t & VT_BTYPE) == VT_LONG) {
3453 t = (t & ~VT_BTYPE) | VT_LLONG;
3454 } else {
3455 u = VT_LONG;
3456 goto basic_type1;
3458 break;
3459 #ifdef TCC_TARGET_ARM64
3460 case TOK_UINT128:
3461 /* GCC's __uint128_t appears in some Linux header files. Make it a
3462 synonym for long double to get the size and alignment right. */
3463 u = VT_LDOUBLE;
3464 goto basic_type;
3465 #endif
3466 case TOK_BOOL:
3467 u = VT_BOOL;
3468 goto basic_type;
3469 case TOK_FLOAT:
3470 u = VT_FLOAT;
3471 goto basic_type;
3472 case TOK_DOUBLE:
3473 next();
3474 if ((t & VT_BTYPE) == VT_LONG) {
3475 #ifdef TCC_TARGET_PE
3476 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3477 #else
3478 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3479 #endif
3480 } else {
3481 u = VT_DOUBLE;
3482 goto basic_type1;
3484 break;
3485 case TOK_ENUM:
3486 struct_decl(&type1, ad, VT_ENUM);
3487 basic_type2:
3488 u = type1.t;
3489 type->ref = type1.ref;
3490 goto basic_type1;
3491 case TOK_STRUCT:
3492 case TOK_UNION:
3493 struct_decl(&type1, ad, VT_STRUCT);
3494 goto basic_type2;
3496 /* type modifiers */
3497 case TOK_CONST1:
3498 case TOK_CONST2:
3499 case TOK_CONST3:
3500 type->t = t;
3501 parse_btype_qualify(type, VT_CONSTANT);
3502 t = type->t;
3503 next();
3504 break;
3505 case TOK_VOLATILE1:
3506 case TOK_VOLATILE2:
3507 case TOK_VOLATILE3:
3508 type->t = t;
3509 parse_btype_qualify(type, VT_VOLATILE);
3510 t = type->t;
3511 next();
3512 break;
3513 case TOK_SIGNED1:
3514 case TOK_SIGNED2:
3515 case TOK_SIGNED3:
3516 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3517 tcc_error("signed and unsigned modifier");
3518 typespec_found = 1;
3519 t |= VT_DEFSIGN;
3520 next();
3521 break;
3522 case TOK_REGISTER:
3523 case TOK_AUTO:
3524 case TOK_RESTRICT1:
3525 case TOK_RESTRICT2:
3526 case TOK_RESTRICT3:
3527 next();
3528 break;
3529 case TOK_UNSIGNED:
3530 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3531 tcc_error("signed and unsigned modifier");
3532 t |= VT_DEFSIGN | VT_UNSIGNED;
3533 next();
3534 typespec_found = 1;
3535 break;
3537 /* storage */
3538 case TOK_EXTERN:
3539 t |= VT_EXTERN;
3540 next();
3541 break;
3542 case TOK_STATIC:
3543 t |= VT_STATIC;
3544 next();
3545 break;
3546 case TOK_TYPEDEF:
3547 t |= VT_TYPEDEF;
3548 next();
3549 break;
3550 case TOK_INLINE1:
3551 case TOK_INLINE2:
3552 case TOK_INLINE3:
3553 t |= VT_INLINE;
3554 next();
3555 break;
3557 /* GNUC attribute */
3558 case TOK_ATTRIBUTE1:
3559 case TOK_ATTRIBUTE2:
3560 parse_attribute(ad);
3561 if (ad->a.mode) {
3562 u = ad->a.mode -1;
3563 t = (t & ~VT_BTYPE) | u;
3565 break;
3566 /* GNUC typeof */
3567 case TOK_TYPEOF1:
3568 case TOK_TYPEOF2:
3569 case TOK_TYPEOF3:
3570 next();
3571 parse_expr_type(&type1);
3572 /* remove all storage modifiers except typedef */
3573 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3574 goto basic_type2;
3575 default:
3576 if (typespec_found)
3577 goto the_end;
3578 s = sym_find(tok);
3579 if (!s || !(s->type.t & VT_TYPEDEF))
3580 goto the_end;
3582 type->t = ((s->type.t & ~VT_TYPEDEF) |
3583 (t & ~(VT_CONSTANT | VT_VOLATILE)));
3584 type->ref = s->type.ref;
3585 if (t & (VT_CONSTANT | VT_VOLATILE))
3586 parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE));
3587 t = type->t;
3589 if (s->r) {
3590 /* get attributes from typedef */
3591 if (0 == ad->a.aligned)
3592 ad->a.aligned = s->a.aligned;
3593 if (0 == ad->a.func_call)
3594 ad->a.func_call = s->a.func_call;
3595 ad->a.packed |= s->a.packed;
3597 next();
3598 typespec_found = 1;
3599 break;
3601 type_found = 1;
3603 the_end:
3604 if (tcc_state->char_is_unsigned) {
3605 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3606 t |= VT_UNSIGNED;
3609 /* long is never used as type */
3610 if ((t & VT_BTYPE) == VT_LONG)
3611 #if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \
3612 defined TCC_TARGET_PE
3613 t = (t & ~VT_BTYPE) | VT_INT;
3614 #else
3615 t = (t & ~VT_BTYPE) | VT_LLONG;
3616 #endif
3617 type->t = t;
3618 return type_found;
3621 /* convert a function parameter type (array to pointer and function to
3622 function pointer) */
3623 static inline void convert_parameter_type(CType *pt)
3625 /* remove const and volatile qualifiers (XXX: const could be used
3626 to indicate a const function parameter */
3627 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3628 /* array must be transformed to pointer according to ANSI C */
3629 pt->t &= ~VT_ARRAY;
3630 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3631 mk_pointer(pt);
3635 ST_FUNC void parse_asm_str(CString *astr)
3637 skip('(');
3638 /* read the string */
3639 if (tok != TOK_STR)
3640 expect("string constant");
3641 cstr_new(astr);
3642 while (tok == TOK_STR) {
3643 /* XXX: add \0 handling too ? */
3644 cstr_cat(astr, tokc.str.data, -1);
3645 next();
3647 cstr_ccat(astr, '\0');
3650 /* Parse an asm label and return the token */
3651 static int asm_label_instr(void)
3653 int v;
3654 CString astr;
3656 next();
3657 parse_asm_str(&astr);
3658 skip(')');
3659 #ifdef ASM_DEBUG
3660 printf("asm_alias: \"%s\"\n", (char *)astr.data);
3661 #endif
3662 v = tok_alloc(astr.data, astr.size - 1)->tok;
3663 cstr_free(&astr);
3664 return v;
3667 static void post_type(CType *type, AttributeDef *ad)
3669 int n, l, t1, arg_size, align;
3670 Sym **plast, *s, *first;
3671 AttributeDef ad1;
3672 CType pt;
3674 if (tok == '(') {
3675 /* function declaration */
3676 next();
3677 l = 0;
3678 first = NULL;
3679 plast = &first;
3680 arg_size = 0;
3681 if (tok != ')') {
3682 for(;;) {
3683 /* read param name and compute offset */
3684 if (l != FUNC_OLD) {
3685 if (!parse_btype(&pt, &ad1)) {
3686 if (l) {
3687 tcc_error("invalid type");
3688 } else {
3689 l = FUNC_OLD;
3690 goto old_proto;
3693 l = FUNC_NEW;
3694 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3695 break;
3696 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3697 if ((pt.t & VT_BTYPE) == VT_VOID)
3698 tcc_error("parameter declared as void");
3699 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3700 } else {
3701 old_proto:
3702 n = tok;
3703 if (n < TOK_UIDENT)
3704 expect("identifier");
3705 pt.t = VT_INT;
3706 next();
3708 convert_parameter_type(&pt);
3709 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3710 *plast = s;
3711 plast = &s->next;
3712 if (tok == ')')
3713 break;
3714 skip(',');
3715 if (l == FUNC_NEW && tok == TOK_DOTS) {
3716 l = FUNC_ELLIPSIS;
3717 next();
3718 break;
3722 /* if no parameters, then old type prototype */
3723 if (l == 0)
3724 l = FUNC_OLD;
3725 skip(')');
3726 /* NOTE: const is ignored in returned type as it has a special
3727 meaning in gcc / C++ */
3728 type->t &= ~VT_CONSTANT;
3729 /* some ancient pre-K&R C allows a function to return an array
3730 and the array brackets to be put after the arguments, such
3731 that "int c()[]" means something like "int[] c()" */
3732 if (tok == '[') {
3733 next();
3734 skip(']'); /* only handle simple "[]" */
3735 type->t |= VT_PTR;
3737 /* we push a anonymous symbol which will contain the function prototype */
3738 ad->a.func_args = arg_size;
3739 s = sym_push(SYM_FIELD, type, 0, l);
3740 s->a = ad->a;
3741 s->next = first;
3742 type->t = VT_FUNC;
3743 type->ref = s;
3744 } else if (tok == '[') {
3745 /* array definition */
3746 next();
3747 if (tok == TOK_RESTRICT1)
3748 next();
3749 n = -1;
3750 t1 = 0;
3751 if (tok != ']') {
3752 if (!local_stack || nocode_wanted)
3753 vpushi(expr_const());
3754 else gexpr();
3755 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3756 n = vtop->c.i;
3757 if (n < 0)
3758 tcc_error("invalid array size");
3759 } else {
3760 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3761 tcc_error("size of variable length array should be an integer");
3762 t1 = VT_VLA;
3765 skip(']');
3766 /* parse next post type */
3767 post_type(type, ad);
3768 if (type->t == VT_FUNC)
3769 tcc_error("declaration of an array of functions");
3770 t1 |= type->t & VT_VLA;
3772 if (t1 & VT_VLA) {
3773 loc -= type_size(&int_type, &align);
3774 loc &= -align;
3775 n = loc;
3777 vla_runtime_type_size(type, &align);
3778 gen_op('*');
3779 vset(&int_type, VT_LOCAL|VT_LVAL, n);
3780 vswap();
3781 vstore();
3783 if (n != -1)
3784 vpop();
3786 /* we push an anonymous symbol which will contain the array
3787 element type */
3788 s = sym_push(SYM_FIELD, type, 0, n);
3789 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3790 type->ref = s;
3794 /* Parse a type declaration (except basic type), and return the type
3795 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3796 expected. 'type' should contain the basic type. 'ad' is the
3797 attribute definition of the basic type. It can be modified by
3798 type_decl().
3800 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3802 Sym *s;
3803 CType type1, *type2;
3804 int qualifiers, storage;
3806 while (tok == '*') {
3807 qualifiers = 0;
3808 redo:
3809 next();
3810 switch(tok) {
3811 case TOK_CONST1:
3812 case TOK_CONST2:
3813 case TOK_CONST3:
3814 qualifiers |= VT_CONSTANT;
3815 goto redo;
3816 case TOK_VOLATILE1:
3817 case TOK_VOLATILE2:
3818 case TOK_VOLATILE3:
3819 qualifiers |= VT_VOLATILE;
3820 goto redo;
3821 case TOK_RESTRICT1:
3822 case TOK_RESTRICT2:
3823 case TOK_RESTRICT3:
3824 goto redo;
3826 mk_pointer(type);
3827 type->t |= qualifiers;
3830 /* XXX: clarify attribute handling */
3831 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3832 parse_attribute(ad);
3834 /* recursive type */
3835 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3836 type1.t = 0; /* XXX: same as int */
3837 if (tok == '(') {
3838 next();
3839 /* XXX: this is not correct to modify 'ad' at this point, but
3840 the syntax is not clear */
3841 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3842 parse_attribute(ad);
3843 type_decl(&type1, ad, v, td);
3844 skip(')');
3845 } else {
3846 /* type identifier */
3847 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3848 *v = tok;
3849 next();
3850 } else {
3851 if (!(td & TYPE_ABSTRACT))
3852 expect("identifier");
3853 *v = 0;
3856 storage = type->t & VT_STORAGE;
3857 type->t &= ~VT_STORAGE;
3858 if (storage & VT_STATIC) {
3859 int saved_nocode_wanted = nocode_wanted;
3860 nocode_wanted = 1;
3861 post_type(type, ad);
3862 nocode_wanted = saved_nocode_wanted;
3863 } else
3864 post_type(type, ad);
3865 type->t |= storage;
3866 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3867 parse_attribute(ad);
3869 if (!type1.t)
3870 return;
3871 /* append type at the end of type1 */
3872 type2 = &type1;
3873 for(;;) {
3874 s = type2->ref;
3875 type2 = &s->type;
3876 if (!type2->t) {
3877 *type2 = *type;
3878 break;
3881 *type = type1;
3884 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3885 ST_FUNC int lvalue_type(int t)
3887 int bt, r;
3888 r = VT_LVAL;
3889 bt = t & VT_BTYPE;
3890 if (bt == VT_BYTE || bt == VT_BOOL)
3891 r |= VT_LVAL_BYTE;
3892 else if (bt == VT_SHORT)
3893 r |= VT_LVAL_SHORT;
3894 else
3895 return r;
3896 if (t & VT_UNSIGNED)
3897 r |= VT_LVAL_UNSIGNED;
3898 return r;
3901 /* indirection with full error checking and bound check */
3902 ST_FUNC void indir(void)
3904 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3905 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3906 return;
3907 expect("pointer");
3909 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3910 gv(RC_INT);
3911 vtop->type = *pointed_type(&vtop->type);
3912 /* Arrays and functions are never lvalues */
3913 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3914 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3915 vtop->r |= lvalue_type(vtop->type.t);
3916 /* if bound checking, the referenced pointer must be checked */
3917 #ifdef CONFIG_TCC_BCHECK
3918 if (tcc_state->do_bounds_check)
3919 vtop->r |= VT_MUSTBOUND;
3920 #endif
3924 /* pass a parameter to a function and do type checking and casting */
3925 static void gfunc_param_typed(Sym *func, Sym *arg)
3927 int func_type;
3928 CType type;
3930 func_type = func->c;
3931 if (func_type == FUNC_OLD ||
3932 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3933 /* default casting : only need to convert float to double */
3934 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3935 type.t = VT_DOUBLE;
3936 gen_cast(&type);
3937 } else if (vtop->type.t & VT_BITFIELD) {
3938 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3939 gen_cast(&type);
3941 } else if (arg == NULL) {
3942 tcc_error("too many arguments to function");
3943 } else {
3944 type = arg->type;
3945 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3946 gen_assign_cast(&type);
3950 /* parse an expression of the form '(type)' or '(expr)' and return its
3951 type */
3952 static void parse_expr_type(CType *type)
3954 int n;
3955 AttributeDef ad;
3957 skip('(');
3958 if (parse_btype(type, &ad)) {
3959 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3960 } else {
3961 expr_type(type);
3963 skip(')');
3966 static void parse_type(CType *type)
3968 AttributeDef ad;
3969 int n;
3971 if (!parse_btype(type, &ad)) {
3972 expect("type");
3974 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3977 static void vpush_tokc(int t)
3979 CType type;
3980 type.t = t;
3981 type.ref = 0;
3982 vsetc(&type, VT_CONST, &tokc);
3985 ST_FUNC void unary(void)
3987 int n, t, align, size, r, sizeof_caller;
3988 CType type;
3989 Sym *s;
3990 AttributeDef ad;
3992 sizeof_caller = in_sizeof;
3993 in_sizeof = 0;
3994 /* XXX: GCC 2.95.3 does not generate a table although it should be
3995 better here */
3996 tok_next:
3997 switch(tok) {
3998 case TOK_EXTENSION:
3999 next();
4000 goto tok_next;
4001 case TOK_CINT:
4002 case TOK_CCHAR:
4003 case TOK_LCHAR:
4004 vpushi(tokc.i);
4005 next();
4006 break;
4007 case TOK_CUINT:
4008 vpush_tokc(VT_INT | VT_UNSIGNED);
4009 next();
4010 break;
4011 case TOK_CLLONG:
4012 vpush_tokc(VT_LLONG);
4013 next();
4014 break;
4015 case TOK_CULLONG:
4016 vpush_tokc(VT_LLONG | VT_UNSIGNED);
4017 next();
4018 break;
4019 case TOK_CFLOAT:
4020 vpush_tokc(VT_FLOAT);
4021 next();
4022 break;
4023 case TOK_CDOUBLE:
4024 vpush_tokc(VT_DOUBLE);
4025 next();
4026 break;
4027 case TOK_CLDOUBLE:
4028 vpush_tokc(VT_LDOUBLE);
4029 next();
4030 break;
4031 case TOK___FUNCTION__:
4032 if (!gnu_ext)
4033 goto tok_identifier;
4034 /* fall thru */
4035 case TOK___FUNC__:
4037 void *ptr;
4038 int len;
4039 /* special function name identifier */
4040 len = strlen(funcname) + 1;
4041 /* generate char[len] type */
4042 type.t = VT_BYTE;
4043 mk_pointer(&type);
4044 type.t |= VT_ARRAY;
4045 type.ref->c = len;
4046 vpush_ref(&type, data_section, data_section->data_offset, len);
4047 ptr = section_ptr_add(data_section, len);
4048 memcpy(ptr, funcname, len);
4049 next();
4051 break;
4052 case TOK_LSTR:
4053 #ifdef TCC_TARGET_PE
4054 t = VT_SHORT | VT_UNSIGNED;
4055 #else
4056 t = VT_INT;
4057 #endif
4058 goto str_init;
4059 case TOK_STR:
4060 /* string parsing */
4061 t = VT_BYTE;
4062 str_init:
4063 if (tcc_state->warn_write_strings)
4064 t |= VT_CONSTANT;
4065 type.t = t;
4066 mk_pointer(&type);
4067 type.t |= VT_ARRAY;
4068 memset(&ad, 0, sizeof(AttributeDef));
4069 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
4070 break;
4071 case '(':
4072 next();
4073 /* cast ? */
4074 if (parse_btype(&type, &ad)) {
4075 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
4076 skip(')');
4077 /* check ISOC99 compound literal */
4078 if (tok == '{') {
4079 /* data is allocated locally by default */
4080 if (global_expr)
4081 r = VT_CONST;
4082 else
4083 r = VT_LOCAL;
4084 /* all except arrays are lvalues */
4085 if (!(type.t & VT_ARRAY))
4086 r |= lvalue_type(type.t);
4087 memset(&ad, 0, sizeof(AttributeDef));
4088 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
4089 } else {
4090 if (sizeof_caller) {
4091 vpush(&type);
4092 return;
4094 unary();
4095 gen_cast(&type);
4097 } else if (tok == '{') {
4098 if (const_wanted)
4099 tcc_error("expected constant");
4100 /* save all registers */
4101 if (!nocode_wanted)
4102 save_regs(0);
4103 /* statement expression : we do not accept break/continue
4104 inside as GCC does */
4105 block(NULL, NULL, 1);
4106 skip(')');
4107 } else {
4108 gexpr();
4109 skip(')');
4111 break;
4112 case '*':
4113 next();
4114 unary();
4115 indir();
4116 break;
4117 case '&':
4118 next();
4119 unary();
4120 /* functions names must be treated as function pointers,
4121 except for unary '&' and sizeof. Since we consider that
4122 functions are not lvalues, we only have to handle it
4123 there and in function calls. */
4124 /* arrays can also be used although they are not lvalues */
4125 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
4126 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
4127 test_lvalue();
4128 mk_pointer(&vtop->type);
4129 gaddrof();
4130 break;
4131 case '!':
4132 next();
4133 unary();
4134 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4135 CType boolean;
4136 boolean.t = VT_BOOL;
4137 gen_cast(&boolean);
4138 vtop->c.i = !vtop->c.i;
4139 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
4140 vtop->c.i ^= 1;
4141 else {
4142 save_regs(1);
4143 vseti(VT_JMP, gvtst(1, 0));
4145 break;
4146 case '~':
4147 next();
4148 unary();
4149 vpushi(-1);
4150 gen_op('^');
4151 break;
4152 case '+':
4153 next();
4154 unary();
4155 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
4156 tcc_error("pointer not accepted for unary plus");
4157 /* In order to force cast, we add zero, except for floating point
4158 where we really need an noop (otherwise -0.0 will be transformed
4159 into +0.0). */
4160 if (!is_float(vtop->type.t)) {
4161 vpushi(0);
4162 gen_op('+');
4164 break;
4165 case TOK_SIZEOF:
4166 case TOK_ALIGNOF1:
4167 case TOK_ALIGNOF2:
4168 t = tok;
4169 next();
4170 in_sizeof++;
4171 unary_type(&type); // Perform a in_sizeof = 0;
4172 size = type_size(&type, &align);
4173 if (t == TOK_SIZEOF) {
4174 if (!(type.t & VT_VLA)) {
4175 if (size < 0)
4176 tcc_error("sizeof applied to an incomplete type");
4177 vpushs(size);
4178 } else {
4179 vla_runtime_type_size(&type, &align);
4181 } else {
4182 vpushs(align);
4184 vtop->type.t |= VT_UNSIGNED;
4185 break;
4187 case TOK_builtin_expect:
4189 /* __builtin_expect is a no-op for now */
4190 int saved_nocode_wanted;
4191 next();
4192 skip('(');
4193 expr_eq();
4194 skip(',');
4195 saved_nocode_wanted = nocode_wanted;
4196 nocode_wanted = 1;
4197 expr_lor_const();
4198 vpop();
4199 nocode_wanted = saved_nocode_wanted;
4200 skip(')');
4202 break;
4203 case TOK_builtin_types_compatible_p:
4205 CType type1, type2;
4206 next();
4207 skip('(');
4208 parse_type(&type1);
4209 skip(',');
4210 parse_type(&type2);
4211 skip(')');
4212 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
4213 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
4214 vpushi(is_compatible_types(&type1, &type2));
4216 break;
4217 case TOK_builtin_constant_p:
4219 int saved_nocode_wanted, res;
4220 next();
4221 skip('(');
4222 saved_nocode_wanted = nocode_wanted;
4223 nocode_wanted = 1;
4224 gexpr();
4225 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4226 vpop();
4227 nocode_wanted = saved_nocode_wanted;
4228 skip(')');
4229 vpushi(res);
4231 break;
4232 case TOK_builtin_frame_address:
4233 case TOK_builtin_return_address:
4235 int tok1 = tok;
4236 int level;
4237 CType type;
4238 next();
4239 skip('(');
4240 if (tok != TOK_CINT) {
4241 tcc_error("%s only takes positive integers",
4242 tok1 == TOK_builtin_return_address ?
4243 "__builtin_return_address" :
4244 "__builtin_frame_address");
4246 level = (uint32_t)tokc.i;
4247 next();
4248 skip(')');
4249 type.t = VT_VOID;
4250 mk_pointer(&type);
4251 vset(&type, VT_LOCAL, 0); /* local frame */
4252 while (level--) {
4253 mk_pointer(&vtop->type);
4254 indir(); /* -> parent frame */
4256 if (tok1 == TOK_builtin_return_address) {
4257 // assume return address is just above frame pointer on stack
4258 vpushi(PTR_SIZE);
4259 gen_op('+');
4260 mk_pointer(&vtop->type);
4261 indir();
4264 break;
4265 #ifdef TCC_TARGET_X86_64
4266 #ifdef TCC_TARGET_PE
4267 case TOK_builtin_va_start:
4269 next();
4270 skip('(');
4271 expr_eq();
4272 skip(',');
4273 expr_eq();
4274 skip(')');
4275 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
4276 tcc_error("__builtin_va_start expects a local variable");
4277 vtop->r &= ~(VT_LVAL | VT_REF);
4278 vtop->type = char_pointer_type;
4279 vtop->c.i += 8;
4280 vstore();
4282 break;
4283 #else
4284 case TOK_builtin_va_arg_types:
4286 CType type;
4287 next();
4288 skip('(');
4289 parse_type(&type);
4290 skip(')');
4291 vpushi(classify_x86_64_va_arg(&type));
4293 break;
4294 #endif
4295 #endif
4297 #ifdef TCC_TARGET_ARM64
4298 case TOK___va_start: {
4299 if (nocode_wanted)
4300 tcc_error("statement in global scope");
4301 next();
4302 skip('(');
4303 expr_eq();
4304 skip(',');
4305 expr_eq();
4306 skip(')');
4307 //xx check types
4308 gen_va_start();
4309 vpushi(0);
4310 vtop->type.t = VT_VOID;
4311 break;
4313 case TOK___va_arg: {
4314 CType type;
4315 if (nocode_wanted)
4316 tcc_error("statement in global scope");
4317 next();
4318 skip('(');
4319 expr_eq();
4320 skip(',');
4321 parse_type(&type);
4322 skip(')');
4323 //xx check types
4324 gen_va_arg(&type);
4325 vtop->type = type;
4326 break;
4328 case TOK___arm64_clear_cache: {
4329 next();
4330 skip('(');
4331 expr_eq();
4332 skip(',');
4333 expr_eq();
4334 skip(')');
4335 gen_clear_cache();
4336 vpushi(0);
4337 vtop->type.t = VT_VOID;
4338 break;
4340 #endif
4341 /* pre operations */
4342 case TOK_INC:
4343 case TOK_DEC:
4344 t = tok;
4345 next();
4346 unary();
4347 inc(0, t);
4348 break;
4349 case '-':
4350 next();
4351 unary();
4352 t = vtop->type.t & VT_BTYPE;
4353 if (is_float(t)) {
4354 /* In IEEE negate(x) isn't subtract(0,x), but rather
4355 subtract(-0, x). */
4356 vpush(&vtop->type);
4357 if (t == VT_FLOAT)
4358 vtop->c.f = -0.0f;
4359 else if (t == VT_DOUBLE)
4360 vtop->c.d = -0.0;
4361 else
4362 vtop->c.ld = -0.0;
4363 } else
4364 vpushi(0);
4365 vswap();
4366 gen_op('-');
4367 break;
4368 case TOK_LAND:
4369 if (!gnu_ext)
4370 goto tok_identifier;
4371 next();
4372 /* allow to take the address of a label */
4373 if (tok < TOK_UIDENT)
4374 expect("label identifier");
4375 s = label_find(tok);
4376 if (!s) {
4377 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4378 } else {
4379 if (s->r == LABEL_DECLARED)
4380 s->r = LABEL_FORWARD;
4382 if (!s->type.t) {
4383 s->type.t = VT_VOID;
4384 mk_pointer(&s->type);
4385 s->type.t |= VT_STATIC;
4387 vpushsym(&s->type, s);
4388 next();
4389 break;
4391 // special qnan , snan and infinity values
4392 case TOK___NAN__:
4393 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
4394 next();
4395 break;
4396 case TOK___SNAN__:
4397 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
4398 next();
4399 break;
4400 case TOK___INF__:
4401 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
4402 next();
4403 break;
4405 default:
4406 tok_identifier:
4407 t = tok;
4408 next();
4409 if (t < TOK_UIDENT)
4410 expect("identifier");
4411 s = sym_find(t);
4412 if (!s) {
4413 const char *name = get_tok_str(t, NULL);
4414 if (tok != '(')
4415 tcc_error("'%s' undeclared", name);
4416 /* for simple function calls, we tolerate undeclared
4417 external reference to int() function */
4418 if (tcc_state->warn_implicit_function_declaration
4419 #ifdef TCC_TARGET_PE
4420 /* people must be warned about using undeclared WINAPI functions
4421 (which usually start with uppercase letter) */
4422 || (name[0] >= 'A' && name[0] <= 'Z')
4423 #endif
4425 tcc_warning("implicit declaration of function '%s'", name);
4426 s = external_global_sym(t, &func_old_type, 0);
4428 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
4429 (VT_STATIC | VT_INLINE | VT_FUNC)) {
4430 /* if referencing an inline function, then we generate a
4431 symbol to it if not already done. It will have the
4432 effect to generate code for it at the end of the
4433 compilation unit. Inline function as always
4434 generated in the text section. */
4435 if (!s->c)
4436 put_extern_sym(s, text_section, 0, 0);
4437 r = VT_SYM | VT_CONST;
4438 } else {
4439 r = s->r;
4441 vset(&s->type, r, s->c);
4442 /* if forward reference, we must point to s */
4443 if (vtop->r & VT_SYM) {
4444 vtop->sym = s;
4445 vtop->c.i = 0;
4447 break;
4450 /* post operations */
4451 while (1) {
4452 if (tok == TOK_INC || tok == TOK_DEC) {
4453 inc(1, tok);
4454 next();
4455 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
4456 int qualifiers;
4457 /* field */
4458 if (tok == TOK_ARROW)
4459 indir();
4460 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4461 test_lvalue();
4462 gaddrof();
4463 /* expect pointer on structure */
4464 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4465 expect("struct or union");
4466 if (tok == TOK_CDOUBLE)
4467 expect("field name");
4468 next();
4469 if (tok == TOK_CINT || tok == TOK_CUINT)
4470 expect("field name");
4471 s = vtop->type.ref;
4472 /* find field */
4473 tok |= SYM_FIELD;
4474 while ((s = s->next) != NULL) {
4475 if (s->v == tok)
4476 break;
4478 if (!s)
4479 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
4480 /* add field offset to pointer */
4481 vtop->type = char_pointer_type; /* change type to 'char *' */
4482 vpushi(s->c);
4483 gen_op('+');
4484 /* change type to field type, and set to lvalue */
4485 vtop->type = s->type;
4486 vtop->type.t |= qualifiers;
4487 /* an array is never an lvalue */
4488 if (!(vtop->type.t & VT_ARRAY)) {
4489 vtop->r |= lvalue_type(vtop->type.t);
4490 #ifdef CONFIG_TCC_BCHECK
4491 /* if bound checking, the referenced pointer must be checked */
4492 if (tcc_state->do_bounds_check)
4493 vtop->r |= VT_MUSTBOUND;
4494 #endif
4496 next();
4497 } else if (tok == '[') {
4498 next();
4499 gexpr();
4500 gen_op('+');
4501 indir();
4502 skip(']');
4503 } else if (tok == '(') {
4504 SValue ret;
4505 Sym *sa;
4506 int nb_args, ret_nregs, ret_align, regsize, variadic;
4508 /* function call */
4509 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4510 /* pointer test (no array accepted) */
4511 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4512 vtop->type = *pointed_type(&vtop->type);
4513 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4514 goto error_func;
4515 } else {
4516 error_func:
4517 expect("function pointer");
4519 } else {
4520 vtop->r &= ~VT_LVAL; /* no lvalue */
4522 /* get return type */
4523 s = vtop->type.ref;
4524 next();
4525 sa = s->next; /* first parameter */
4526 nb_args = 0;
4527 ret.r2 = VT_CONST;
4528 /* compute first implicit argument if a structure is returned */
4529 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4530 variadic = (s->c == FUNC_ELLIPSIS);
4531 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4532 &ret_align, &regsize);
4533 if (!ret_nregs) {
4534 /* get some space for the returned structure */
4535 size = type_size(&s->type, &align);
4536 #ifdef TCC_TARGET_ARM64
4537 /* On arm64, a small struct is return in registers.
4538 It is much easier to write it to memory if we know
4539 that we are allowed to write some extra bytes, so
4540 round the allocated space up to a power of 2: */
4541 if (size < 16)
4542 while (size & (size - 1))
4543 size = (size | (size - 1)) + 1;
4544 #endif
4545 loc = (loc - size) & -align;
4546 ret.type = s->type;
4547 ret.r = VT_LOCAL | VT_LVAL;
4548 /* pass it as 'int' to avoid structure arg passing
4549 problems */
4550 vseti(VT_LOCAL, loc);
4551 ret.c = vtop->c;
4552 nb_args++;
4554 } else {
4555 ret_nregs = 1;
4556 ret.type = s->type;
4559 if (ret_nregs) {
4560 /* return in register */
4561 if (is_float(ret.type.t)) {
4562 ret.r = reg_fret(ret.type.t);
4563 #ifdef TCC_TARGET_X86_64
4564 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4565 ret.r2 = REG_QRET;
4566 #endif
4567 } else {
4568 #ifndef TCC_TARGET_ARM64
4569 #ifdef TCC_TARGET_X86_64
4570 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4571 #else
4572 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4573 #endif
4574 ret.r2 = REG_LRET;
4575 #endif
4576 ret.r = REG_IRET;
4578 ret.c.i = 0;
4580 if (tok != ')') {
4581 for(;;) {
4582 expr_eq();
4583 gfunc_param_typed(s, sa);
4584 nb_args++;
4585 if (sa)
4586 sa = sa->next;
4587 if (tok == ')')
4588 break;
4589 skip(',');
4592 if (sa)
4593 tcc_error("too few arguments to function");
4594 skip(')');
4595 if (!nocode_wanted) {
4596 gfunc_call(nb_args);
4597 } else {
4598 vtop -= (nb_args + 1);
4601 /* return value */
4602 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4603 vsetc(&ret.type, r, &ret.c);
4604 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4607 /* handle packed struct return */
4608 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4609 int addr, offset;
4611 size = type_size(&s->type, &align);
4612 /* We're writing whole regs often, make sure there's enough
4613 space. Assume register size is power of 2. */
4614 if (regsize > align)
4615 align = regsize;
4616 loc = (loc - size) & -align;
4617 addr = loc;
4618 offset = 0;
4619 for (;;) {
4620 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4621 vswap();
4622 vstore();
4623 vtop--;
4624 if (--ret_nregs == 0)
4625 break;
4626 offset += regsize;
4628 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4630 } else {
4631 break;
4636 ST_FUNC void expr_prod(void)
4638 int t;
4640 unary();
4641 while (tok == '*' || tok == '/' || tok == '%') {
4642 t = tok;
4643 next();
4644 unary();
4645 gen_op(t);
4649 ST_FUNC void expr_sum(void)
4651 int t;
4653 expr_prod();
4654 while (tok == '+' || tok == '-') {
4655 t = tok;
4656 next();
4657 expr_prod();
4658 gen_op(t);
4662 static void expr_shift(void)
4664 int t;
4666 expr_sum();
4667 while (tok == TOK_SHL || tok == TOK_SAR) {
4668 t = tok;
4669 next();
4670 expr_sum();
4671 gen_op(t);
4675 static void expr_cmp(void)
4677 int t;
4679 expr_shift();
4680 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4681 tok == TOK_ULT || tok == TOK_UGE) {
4682 t = tok;
4683 next();
4684 expr_shift();
4685 gen_op(t);
4689 static void expr_cmpeq(void)
4691 int t;
4693 expr_cmp();
4694 while (tok == TOK_EQ || tok == TOK_NE) {
4695 t = tok;
4696 next();
4697 expr_cmp();
4698 gen_op(t);
4702 static void expr_and(void)
4704 expr_cmpeq();
4705 while (tok == '&') {
4706 next();
4707 expr_cmpeq();
4708 gen_op('&');
4712 static void expr_xor(void)
4714 expr_and();
4715 while (tok == '^') {
4716 next();
4717 expr_and();
4718 gen_op('^');
4722 static void expr_or(void)
4724 expr_xor();
4725 while (tok == '|') {
4726 next();
4727 expr_xor();
4728 gen_op('|');
4732 /* XXX: fix this mess */
4733 static void expr_land_const(void)
4735 expr_or();
4736 while (tok == TOK_LAND) {
4737 next();
4738 expr_or();
4739 gen_op(TOK_LAND);
4742 static void expr_lor_const(void)
4744 expr_land_const();
4745 while (tok == TOK_LOR) {
4746 next();
4747 expr_land_const();
4748 gen_op(TOK_LOR);
4752 static void expr_land(void)
4754 expr_or();
4755 if (tok == TOK_LAND) {
4756 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4757 CType ctb, cti;
4758 ctb.t = VT_BOOL;
4759 cti.t = VT_INT;
4760 next();
4761 gen_cast(&ctb);
4762 if (vtop->c.i) {
4763 vpop();
4764 expr_land();
4765 gen_cast(&ctb);
4766 } else {
4767 int saved_nocode_wanted = nocode_wanted;
4768 nocode_wanted = 1;
4769 expr_land();
4770 vpop();
4771 nocode_wanted = saved_nocode_wanted;
4773 gen_cast(&cti);
4774 } else {
4775 int t = 0;
4776 save_regs(1);
4777 for(;;) {
4778 t = gvtst(1, t);
4779 if (tok != TOK_LAND) {
4780 vseti(VT_JMPI, t);
4781 break;
4783 next();
4784 expr_or();
4790 static void expr_lor(void)
4792 expr_land();
4793 if (tok == TOK_LOR) {
4794 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4795 CType ctb, cti;
4796 ctb.t = VT_BOOL;
4797 cti.t = VT_INT;
4798 next();
4799 gen_cast(&ctb);
4800 if (vtop->c.i) {
4801 int saved_nocode_wanted = nocode_wanted;
4802 nocode_wanted = 1;
4803 expr_lor();
4804 vpop();
4805 nocode_wanted = saved_nocode_wanted;
4806 } else {
4807 vpop();
4808 expr_lor();
4809 gen_cast(&ctb);
4811 gen_cast(&cti);
4812 } else {
4813 int t = 0;
4814 save_regs(1);
4815 for(;;) {
4816 t = gvtst(0, t);
4817 if (tok != TOK_LOR) {
4818 vseti(VT_JMP, t);
4819 break;
4821 next();
4822 expr_land();
4828 static void expr_cond(void)
4830 int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv;
4831 SValue sv;
4832 CType type, type1, type2;
4834 expr_lor();
4835 if (tok == '?') {
4836 next();
4837 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4838 int saved_nocode_wanted = nocode_wanted;
4839 CType boolean;
4840 int c;
4841 boolean.t = VT_BOOL;
4842 vdup();
4843 gen_cast(&boolean);
4844 c = vtop->c.i;
4845 vpop();
4846 if (c) {
4847 if (tok != ':' || !gnu_ext) {
4848 vpop();
4849 gexpr();
4851 skip(':');
4852 nocode_wanted = 1;
4853 expr_cond();
4854 vpop();
4855 nocode_wanted = saved_nocode_wanted;
4856 } else {
4857 vpop();
4858 if (tok != ':' || !gnu_ext) {
4859 nocode_wanted = 1;
4860 gexpr();
4861 vpop();
4862 nocode_wanted = saved_nocode_wanted;
4864 skip(':');
4865 expr_cond();
4868 else {
4869 if (vtop != vstack) {
4870 /* needed to avoid having different registers saved in
4871 each branch */
4872 if (is_float(vtop->type.t)) {
4873 rc = RC_FLOAT;
4874 #ifdef TCC_TARGET_X86_64
4875 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4876 rc = RC_ST0;
4878 #endif
4880 else
4881 rc = RC_INT;
4882 gv(rc);
4883 save_regs(1);
4885 if (tok == ':' && gnu_ext) {
4886 gv_dup();
4887 tt = gvtst(1, 0);
4888 } else {
4889 tt = gvtst(1, 0);
4890 gexpr();
4892 type1 = vtop->type;
4893 sv = *vtop; /* save value to handle it later */
4894 vtop--; /* no vpop so that FP stack is not flushed */
4895 skip(':');
4896 u = gjmp(0);
4897 gsym(tt);
4898 expr_cond();
4899 type2 = vtop->type;
4901 t1 = type1.t;
4902 bt1 = t1 & VT_BTYPE;
4903 t2 = type2.t;
4904 bt2 = t2 & VT_BTYPE;
4905 /* cast operands to correct type according to ISOC rules */
4906 if (is_float(bt1) || is_float(bt2)) {
4907 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4908 type.t = VT_LDOUBLE;
4909 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4910 type.t = VT_DOUBLE;
4911 } else {
4912 type.t = VT_FLOAT;
4914 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4915 /* cast to biggest op */
4916 type.t = VT_LLONG;
4917 /* convert to unsigned if it does not fit in a long long */
4918 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4919 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4920 type.t |= VT_UNSIGNED;
4921 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4922 /* If one is a null ptr constant the result type
4923 is the other. */
4924 if (is_null_pointer (vtop))
4925 type = type1;
4926 else if (is_null_pointer (&sv))
4927 type = type2;
4928 /* XXX: test pointer compatibility, C99 has more elaborate
4929 rules here. */
4930 else
4931 type = type1;
4932 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4933 /* XXX: test function pointer compatibility */
4934 type = bt1 == VT_FUNC ? type1 : type2;
4935 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4936 /* XXX: test structure compatibility */
4937 type = bt1 == VT_STRUCT ? type1 : type2;
4938 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4939 /* NOTE: as an extension, we accept void on only one side */
4940 type.t = VT_VOID;
4941 } else {
4942 /* integer operations */
4943 type.t = VT_INT;
4944 /* convert to unsigned if it does not fit in an integer */
4945 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4946 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4947 type.t |= VT_UNSIGNED;
4949 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
4950 that `(expr ? a : b).mem` does not error with "lvalue expected" */
4951 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
4953 /* now we convert second operand */
4954 gen_cast(&type);
4955 if (islv) {
4956 mk_pointer(&vtop->type);
4957 gaddrof();
4959 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4960 gaddrof();
4961 rc = RC_INT;
4962 if (is_float(type.t)) {
4963 rc = RC_FLOAT;
4964 #ifdef TCC_TARGET_X86_64
4965 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4966 rc = RC_ST0;
4968 #endif
4969 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4970 /* for long longs, we use fixed registers to avoid having
4971 to handle a complicated move */
4972 rc = RC_IRET;
4975 r2 = gv(rc);
4976 /* this is horrible, but we must also convert first
4977 operand */
4978 tt = gjmp(0);
4979 gsym(u);
4980 /* put again first value and cast it */
4981 *vtop = sv;
4982 gen_cast(&type);
4983 if (islv) {
4984 mk_pointer(&vtop->type);
4985 gaddrof();
4987 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4988 gaddrof();
4989 r1 = gv(rc);
4990 move_reg(r2, r1, type.t);
4991 vtop->r = r2;
4992 gsym(tt);
4993 if (islv)
4994 indir();
4999 static void expr_eq(void)
5001 int t;
5003 expr_cond();
5004 if (tok == '=' ||
5005 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5006 tok == TOK_A_XOR || tok == TOK_A_OR ||
5007 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5008 test_lvalue();
5009 t = tok;
5010 next();
5011 if (t == '=') {
5012 expr_eq();
5013 } else {
5014 vdup();
5015 expr_eq();
5016 gen_op(t & 0x7f);
5018 vstore();
5022 ST_FUNC void gexpr(void)
5024 while (1) {
5025 expr_eq();
5026 if (tok != ',')
5027 break;
5028 vpop();
5029 next();
5033 /* parse an expression and return its type without any side effect. */
5034 static void expr_type(CType *type)
5036 int saved_nocode_wanted;
5038 saved_nocode_wanted = nocode_wanted;
5039 nocode_wanted = 1;
5040 gexpr();
5041 *type = vtop->type;
5042 vpop();
5043 nocode_wanted = saved_nocode_wanted;
5046 /* parse a unary expression and return its type without any side
5047 effect. */
5048 static void unary_type(CType *type)
5050 int a;
5052 a = nocode_wanted;
5053 nocode_wanted = 1;
5054 unary();
5055 *type = vtop->type;
5056 vpop();
5057 nocode_wanted = a;
5060 /* parse a constant expression and return value in vtop. */
5061 static void expr_const1(void)
5063 int a;
5064 a = const_wanted;
5065 const_wanted = 1;
5066 expr_cond();
5067 const_wanted = a;
5070 /* parse an integer constant and return its value. */
5071 ST_FUNC int expr_const(void)
5073 int c;
5074 expr_const1();
5075 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5076 expect("constant expression");
5077 c = vtop->c.i;
5078 vpop();
5079 return c;
5082 /* return the label token if current token is a label, otherwise
5083 return zero */
5084 static int is_label(void)
5086 int last_tok;
5088 /* fast test first */
5089 if (tok < TOK_UIDENT)
5090 return 0;
5091 /* no need to save tokc because tok is an identifier */
5092 last_tok = tok;
5093 next();
5094 if (tok == ':') {
5095 next();
5096 return last_tok;
5097 } else {
5098 unget_tok(last_tok);
5099 return 0;
5103 static void label_or_decl(int l)
5105 int last_tok;
5107 /* fast test first */
5108 if (tok >= TOK_UIDENT)
5110 /* no need to save tokc because tok is an identifier */
5111 last_tok = tok;
5112 next();
5113 if (tok == ':') {
5114 unget_tok(last_tok);
5115 return;
5117 unget_tok(last_tok);
5119 decl(l);
5122 static int case_cmp(const void *pa, const void *pb)
5124 int a = (*(struct case_t**) pa)->v1;
5125 int b = (*(struct case_t**) pb)->v1;
5126 return a < b ? -1 : a > b;
5129 static int gcase(struct case_t **base, int len, int case_reg, int *bsym)
5131 struct case_t *p;
5132 int e;
5133 while (len > 4) {
5134 /* binary search */
5135 p = base[len/2];
5136 vseti(case_reg, 0);
5137 vdup();
5138 vpushi(p->v2);
5139 gen_op(TOK_LE);
5140 e = gtst(1, 0);
5141 case_reg = gv(RC_INT);
5142 vpop();
5143 vseti(case_reg, 0);
5144 vdup();
5145 vpushi(p->v1);
5146 gen_op(TOK_GE);
5147 gtst_addr(0, p->sym); /* v1 <= x <= v2 */
5148 case_reg = gv(RC_INT);
5149 vpop();
5150 /* x < v1 */
5151 case_reg = gcase(base, len/2, case_reg, bsym);
5152 if (cur_switch->def_sym)
5153 gjmp_addr(cur_switch->def_sym);
5154 else
5155 *bsym = gjmp(*bsym);
5156 /* x > v2 */
5157 gsym(e);
5158 e = len/2 + 1;
5159 base += e; len -= e;
5161 /* linear scan */
5162 while (len--) {
5163 p = *base++;
5164 vseti(case_reg, 0);
5165 vdup();
5166 vpushi(p->v2);
5167 if (p->v1 == p->v2) {
5168 gen_op(TOK_EQ);
5169 gtst_addr(0, p->sym);
5170 } else {
5171 gen_op(TOK_LE);
5172 e = gtst(1, 0);
5173 case_reg = gv(RC_INT);
5174 vpop();
5175 vseti(case_reg, 0);
5176 vdup();
5177 vpushi(p->v1);
5178 gen_op(TOK_GE);
5179 gtst_addr(0, p->sym);
5180 gsym(e);
5182 case_reg = gv(RC_INT);
5183 vpop();
5185 return case_reg;
5188 static void block(int *bsym, int *csym, int is_expr)
5190 int a, b, c, d;
5191 Sym *s;
5193 /* generate line number info */
5194 if (tcc_state->do_debug &&
5195 (last_line_num != file->line_num || last_ind != ind)) {
5196 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5197 last_ind = ind;
5198 last_line_num = file->line_num;
5201 if (is_expr) {
5202 /* default return value is (void) */
5203 vpushi(0);
5204 vtop->type.t = VT_VOID;
5207 if (tok == TOK_IF) {
5208 /* if test */
5209 next();
5210 skip('(');
5211 gexpr();
5212 skip(')');
5213 a = gvtst(1, 0);
5214 block(bsym, csym, 0);
5215 c = tok;
5216 if (c == TOK_ELSE) {
5217 next();
5218 d = gjmp(0);
5219 gsym(a);
5220 block(bsym, csym, 0);
5221 gsym(d); /* patch else jmp */
5222 } else
5223 gsym(a);
5224 } else if (tok == TOK_WHILE) {
5225 next();
5226 d = ind;
5227 vla_sp_restore();
5228 skip('(');
5229 gexpr();
5230 skip(')');
5231 a = gvtst(1, 0);
5232 b = 0;
5233 ++local_scope;
5234 block(&a, &b, 0);
5235 --local_scope;
5236 if(!nocode_wanted)
5237 gjmp_addr(d);
5238 gsym(a);
5239 gsym_addr(b, d);
5240 } else if (tok == '{') {
5241 Sym *llabel;
5242 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
5244 next();
5245 /* record local declaration stack position */
5246 s = local_stack;
5247 llabel = local_label_stack;
5248 ++local_scope;
5250 /* handle local labels declarations */
5251 if (tok == TOK_LABEL) {
5252 next();
5253 for(;;) {
5254 if (tok < TOK_UIDENT)
5255 expect("label identifier");
5256 label_push(&local_label_stack, tok, LABEL_DECLARED);
5257 next();
5258 if (tok == ',') {
5259 next();
5260 } else {
5261 skip(';');
5262 break;
5266 while (tok != '}') {
5267 label_or_decl(VT_LOCAL);
5268 if (tok != '}') {
5269 if (is_expr)
5270 vpop();
5271 block(bsym, csym, is_expr);
5274 /* pop locally defined labels */
5275 label_pop(&local_label_stack, llabel);
5276 if(is_expr) {
5277 /* XXX: this solution makes only valgrind happy...
5278 triggered by gcc.c-torture/execute/20000917-1.c */
5279 Sym *p;
5280 switch(vtop->type.t & VT_BTYPE) {
5281 /* case VT_PTR: */
5282 /* this breaks a compilation of the linux kernel v2.4.26 */
5283 /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
5284 /* Look a commit a80acab: Display error on statement expressions with complex return type */
5285 /* A pointer is not a complex return type */
5286 case VT_STRUCT:
5287 case VT_ENUM:
5288 case VT_FUNC:
5289 for(p=vtop->type.ref;p;p=p->prev)
5290 if(p->prev==s)
5291 tcc_error("unsupported expression type");
5294 /* pop locally defined symbols */
5295 --local_scope;
5296 sym_pop(&local_stack, s);
5298 /* Pop VLA frames and restore stack pointer if required */
5299 if (vlas_in_scope > saved_vlas_in_scope) {
5300 vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
5301 vla_sp_restore();
5303 vlas_in_scope = saved_vlas_in_scope;
5305 next();
5306 } else if (tok == TOK_RETURN) {
5307 next();
5308 if (tok != ';') {
5309 gexpr();
5310 gen_assign_cast(&func_vt);
5311 #ifdef TCC_TARGET_ARM64
5312 // Perhaps it would be better to use this for all backends:
5313 greturn();
5314 #else
5315 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
5316 CType type, ret_type;
5317 int ret_align, ret_nregs, regsize;
5318 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
5319 &ret_align, &regsize);
5320 if (0 == ret_nregs) {
5321 /* if returning structure, must copy it to implicit
5322 first pointer arg location */
5323 type = func_vt;
5324 mk_pointer(&type);
5325 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
5326 indir();
5327 vswap();
5328 /* copy structure value to pointer */
5329 vstore();
5330 } else {
5331 /* returning structure packed into registers */
5332 int r, size, addr, align;
5333 size = type_size(&func_vt,&align);
5334 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
5335 (vtop->c.i & (ret_align-1)))
5336 && (align & (ret_align-1))) {
5337 loc = (loc - size) & -ret_align;
5338 addr = loc;
5339 type = func_vt;
5340 vset(&type, VT_LOCAL | VT_LVAL, addr);
5341 vswap();
5342 vstore();
5343 vpop();
5344 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
5346 vtop->type = ret_type;
5347 if (is_float(ret_type.t))
5348 r = rc_fret(ret_type.t);
5349 else
5350 r = RC_IRET;
5352 if (ret_nregs == 1)
5353 gv(r);
5354 else {
5355 for (;;) {
5356 vdup();
5357 gv(r);
5358 vpop();
5359 if (--ret_nregs == 0)
5360 break;
5361 /* We assume that when a structure is returned in multiple
5362 registers, their classes are consecutive values of the
5363 suite s(n) = 2^n */
5364 r <<= 1;
5365 vtop->c.i += regsize;
5369 } else if (is_float(func_vt.t)) {
5370 gv(rc_fret(func_vt.t));
5371 } else {
5372 gv(RC_IRET);
5374 #endif
5375 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5377 skip(';');
5378 /* jump unless last stmt in top-level block */
5379 if (tok != '}' || local_scope != 1)
5380 rsym = gjmp(rsym);
5381 } else if (tok == TOK_BREAK) {
5382 /* compute jump */
5383 if (!bsym)
5384 tcc_error("cannot break");
5385 *bsym = gjmp(*bsym);
5386 next();
5387 skip(';');
5388 } else if (tok == TOK_CONTINUE) {
5389 /* compute jump */
5390 if (!csym)
5391 tcc_error("cannot continue");
5392 vla_sp_restore_root();
5393 *csym = gjmp(*csym);
5394 next();
5395 skip(';');
5396 } else if (tok == TOK_FOR) {
5397 int e;
5398 next();
5399 skip('(');
5400 s = local_stack;
5401 ++local_scope;
5402 if (tok != ';') {
5403 /* c99 for-loop init decl? */
5404 if (!decl0(VT_LOCAL, 1)) {
5405 /* no, regular for-loop init expr */
5406 gexpr();
5407 vpop();
5410 skip(';');
5411 d = ind;
5412 c = ind;
5413 vla_sp_restore();
5414 a = 0;
5415 b = 0;
5416 if (tok != ';') {
5417 gexpr();
5418 a = gvtst(1, 0);
5420 skip(';');
5421 if (tok != ')') {
5422 e = gjmp(0);
5423 c = ind;
5424 vla_sp_restore();
5425 gexpr();
5426 vpop();
5427 gjmp_addr(d);
5428 gsym(e);
5430 skip(')');
5431 block(&a, &b, 0);
5432 if(!nocode_wanted)
5433 gjmp_addr(c);
5434 gsym(a);
5435 gsym_addr(b, c);
5436 --local_scope;
5437 sym_pop(&local_stack, s);
5439 } else
5440 if (tok == TOK_DO) {
5441 next();
5442 a = 0;
5443 b = 0;
5444 d = ind;
5445 vla_sp_restore();
5446 block(&a, &b, 0);
5447 skip(TOK_WHILE);
5448 skip('(');
5449 gsym(b);
5450 gexpr();
5451 c = gvtst(0, 0);
5452 gsym_addr(c, d);
5453 skip(')');
5454 gsym(a);
5455 skip(';');
5456 } else
5457 if (tok == TOK_SWITCH) {
5458 struct switch_t *saved, sw;
5459 next();
5460 skip('(');
5461 gexpr();
5462 /* XXX: other types than integer */
5463 c = gv(RC_INT);
5464 vpop();
5465 skip(')');
5466 a = 0;
5467 b = gjmp(0); /* jump to first case */
5468 sw.p = NULL; sw.n = 0; sw.def_sym = 0;
5469 saved = cur_switch;
5470 cur_switch = &sw;
5471 block(&a, csym, 0);
5472 a = gjmp(a); /* add implicit break */
5473 /* case lookup */
5474 gsym(b);
5475 qsort(sw.p, sw.n, sizeof(void*), case_cmp);
5476 for (b = 1; b < sw.n; b++)
5477 if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
5478 tcc_error("duplicate case value");
5479 gcase(sw.p, sw.n, c, &a);
5480 if (sw.def_sym)
5481 gjmp_addr(sw.def_sym);
5482 dynarray_reset(&sw.p, &sw.n);
5483 cur_switch = saved;
5484 /* break label */
5485 gsym(a);
5486 } else
5487 if (tok == TOK_CASE) {
5488 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
5489 if (!cur_switch)
5490 expect("switch");
5491 next();
5492 cr->v1 = cr->v2 = expr_const();
5493 if (gnu_ext && tok == TOK_DOTS) {
5494 next();
5495 cr->v2 = expr_const();
5496 if (cr->v2 < cr->v1)
5497 tcc_warning("empty case range");
5499 cr->sym = ind;
5500 dynarray_add((void***) &cur_switch->p, &cur_switch->n, cr);
5501 skip(':');
5502 is_expr = 0;
5503 goto block_after_label;
5504 } else
5505 if (tok == TOK_DEFAULT) {
5506 next();
5507 skip(':');
5508 if (!cur_switch)
5509 expect("switch");
5510 if (cur_switch->def_sym)
5511 tcc_error("too many 'default'");
5512 cur_switch->def_sym = ind;
5513 is_expr = 0;
5514 goto block_after_label;
5515 } else
5516 if (tok == TOK_GOTO) {
5517 next();
5518 if (tok == '*' && gnu_ext) {
5519 /* computed goto */
5520 next();
5521 gexpr();
5522 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5523 expect("pointer");
5524 ggoto();
5525 } else if (tok >= TOK_UIDENT) {
5526 s = label_find(tok);
5527 /* put forward definition if needed */
5528 if (!s) {
5529 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5530 } else {
5531 if (s->r == LABEL_DECLARED)
5532 s->r = LABEL_FORWARD;
5534 vla_sp_restore_root();
5535 if (s->r & LABEL_FORWARD)
5536 s->jnext = gjmp(s->jnext);
5537 else
5538 gjmp_addr(s->jnext);
5539 next();
5540 } else {
5541 expect("label identifier");
5543 skip(';');
5544 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
5545 asm_instr();
5546 } else {
5547 b = is_label();
5548 if (b) {
5549 /* label case */
5550 s = label_find(b);
5551 if (s) {
5552 if (s->r == LABEL_DEFINED)
5553 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
5554 gsym(s->jnext);
5555 s->r = LABEL_DEFINED;
5556 } else {
5557 s = label_push(&global_label_stack, b, LABEL_DEFINED);
5559 s->jnext = ind;
5560 vla_sp_restore();
5561 /* we accept this, but it is a mistake */
5562 block_after_label:
5563 if (tok == '}') {
5564 tcc_warning("deprecated use of label at end of compound statement");
5565 } else {
5566 if (is_expr)
5567 vpop();
5568 block(bsym, csym, is_expr);
5570 } else {
5571 /* expression case */
5572 if (tok != ';') {
5573 if (is_expr) {
5574 vpop();
5575 gexpr();
5576 } else {
5577 gexpr();
5578 vpop();
5581 skip(';');
5586 /* t is the array or struct type. c is the array or struct
5587 address. cur_index/cur_field is the pointer to the current
5588 value. 'size_only' is true if only size info is needed (only used
5589 in arrays) */
5590 static void decl_designator(CType *type, Section *sec, unsigned long c,
5591 int *cur_index, Sym **cur_field,
5592 int size_only)
5594 Sym *s, *f;
5595 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5596 CType type1;
5598 notfirst = 0;
5599 elem_size = 0;
5600 nb_elems = 1;
5601 if (gnu_ext && (l = is_label()) != 0)
5602 goto struct_field;
5603 while (tok == '[' || tok == '.') {
5604 if (tok == '[') {
5605 if (!(type->t & VT_ARRAY))
5606 expect("array type");
5607 s = type->ref;
5608 next();
5609 index = expr_const();
5610 if (index < 0 || (s->c >= 0 && index >= s->c))
5611 expect("invalid index");
5612 if (tok == TOK_DOTS && gnu_ext) {
5613 next();
5614 index_last = expr_const();
5615 if (index_last < 0 ||
5616 (s->c >= 0 && index_last >= s->c) ||
5617 index_last < index)
5618 expect("invalid index");
5619 } else {
5620 index_last = index;
5622 skip(']');
5623 if (!notfirst)
5624 *cur_index = index_last;
5625 type = pointed_type(type);
5626 elem_size = type_size(type, &align);
5627 c += index * elem_size;
5628 /* NOTE: we only support ranges for last designator */
5629 nb_elems = index_last - index + 1;
5630 if (nb_elems != 1) {
5631 notfirst = 1;
5632 break;
5634 } else {
5635 next();
5636 l = tok;
5637 next();
5638 struct_field:
5639 if ((type->t & VT_BTYPE) != VT_STRUCT)
5640 expect("struct/union type");
5641 s = type->ref;
5642 l |= SYM_FIELD;
5643 f = s->next;
5644 while (f) {
5645 if (f->v == l)
5646 break;
5647 f = f->next;
5649 if (!f)
5650 expect("field");
5651 if (!notfirst)
5652 *cur_field = f;
5653 /* XXX: fix this mess by using explicit storage field */
5654 type1 = f->type;
5655 type1.t |= (type->t & ~VT_TYPE);
5656 type = &type1;
5657 c += f->c;
5659 notfirst = 1;
5661 if (notfirst) {
5662 if (tok == '=') {
5663 next();
5664 } else {
5665 if (!gnu_ext)
5666 expect("=");
5668 } else {
5669 if (type->t & VT_ARRAY) {
5670 index = *cur_index;
5671 type = pointed_type(type);
5672 c += index * type_size(type, &align);
5673 } else {
5674 f = *cur_field;
5675 if (!f)
5676 tcc_error("too many field init");
5677 /* XXX: fix this mess by using explicit storage field */
5678 type1 = f->type;
5679 type1.t |= (type->t & ~VT_TYPE);
5680 type = &type1;
5681 c += f->c;
5684 decl_initializer(type, sec, c, 0, size_only);
5686 /* XXX: make it more general */
5687 if (!size_only && nb_elems > 1) {
5688 unsigned long c_end;
5689 uint8_t *src, *dst;
5690 int i;
5692 if (!sec)
5693 tcc_error("range init not supported yet for dynamic storage");
5694 c_end = c + nb_elems * elem_size;
5695 if (c_end > sec->data_allocated)
5696 section_realloc(sec, c_end);
5697 src = sec->data + c;
5698 dst = src;
5699 for(i = 1; i < nb_elems; i++) {
5700 dst += elem_size;
5701 memcpy(dst, src, elem_size);
5706 #define EXPR_VAL 0
5707 #define EXPR_CONST 1
5708 #define EXPR_ANY 2
5710 /* store a value or an expression directly in global data or in local array */
5711 static void init_putv(CType *type, Section *sec, unsigned long c,
5712 int v, int expr_type)
5714 int saved_global_expr, bt, bit_pos, bit_size;
5715 void *ptr;
5716 unsigned long long bit_mask;
5717 CType dtype;
5719 switch(expr_type) {
5720 case EXPR_VAL:
5721 vpushi(v);
5722 break;
5723 case EXPR_CONST:
5724 /* compound literals must be allocated globally in this case */
5725 saved_global_expr = global_expr;
5726 global_expr = 1;
5727 expr_const1();
5728 global_expr = saved_global_expr;
5729 /* NOTE: symbols are accepted */
5730 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5731 tcc_error("initializer element is not constant");
5732 break;
5733 case EXPR_ANY:
5734 expr_eq();
5735 break;
5738 dtype = *type;
5739 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5741 if (sec) {
5742 /* XXX: not portable */
5743 /* XXX: generate error if incorrect relocation */
5744 gen_assign_cast(&dtype);
5745 bt = type->t & VT_BTYPE;
5746 /* we'll write at most 16 bytes */
5747 if (c + 16 > sec->data_allocated) {
5748 section_realloc(sec, c + 16);
5750 ptr = sec->data + c;
5751 /* XXX: make code faster ? */
5752 if (!(type->t & VT_BITFIELD)) {
5753 bit_pos = 0;
5754 bit_size = 32;
5755 bit_mask = -1LL;
5756 } else {
5757 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5758 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5759 bit_mask = (1LL << bit_size) - 1;
5761 if ((vtop->r & VT_SYM) &&
5762 (bt == VT_BYTE ||
5763 bt == VT_SHORT ||
5764 bt == VT_DOUBLE ||
5765 bt == VT_LDOUBLE ||
5766 bt == VT_LLONG ||
5767 (bt == VT_INT && bit_size != 32)))
5768 tcc_error("initializer element is not computable at load time");
5769 switch(bt) {
5770 /* XXX: when cross-compiling we assume that each type has the
5771 same representation on host and target, which is likely to
5772 be wrong in the case of long double */
5773 case VT_BOOL:
5774 vtop->c.i = (vtop->c.i != 0);
5775 case VT_BYTE:
5776 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5777 break;
5778 case VT_SHORT:
5779 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5780 break;
5781 case VT_DOUBLE:
5782 *(double *)ptr = vtop->c.d;
5783 break;
5784 case VT_LDOUBLE:
5785 if (sizeof(long double) == LDOUBLE_SIZE)
5786 *(long double *)ptr = vtop->c.ld;
5787 else if (sizeof(double) == LDOUBLE_SIZE)
5788 *(double *)ptr = vtop->c.ld;
5789 else
5790 tcc_error("can't cross compile long double constants");
5791 break;
5792 case VT_LLONG:
5793 *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5794 break;
5795 case VT_PTR: {
5796 addr_t val = (vtop->c.i & bit_mask) << bit_pos;
5797 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5798 if (vtop->r & VT_SYM)
5799 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5800 else
5801 *(addr_t *)ptr |= val;
5802 #else
5803 if (vtop->r & VT_SYM)
5804 greloc(sec, vtop->sym, c, R_DATA_PTR);
5805 *(addr_t *)ptr |= val;
5806 #endif
5807 break;
5809 default: {
5810 int val = (vtop->c.i & bit_mask) << bit_pos;
5811 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5812 if (vtop->r & VT_SYM)
5813 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5814 else
5815 *(int *)ptr |= val;
5816 #else
5817 if (vtop->r & VT_SYM)
5818 greloc(sec, vtop->sym, c, R_DATA_PTR);
5819 *(int *)ptr |= val;
5820 #endif
5821 break;
5824 vtop--;
5825 } else {
5826 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5827 vswap();
5828 vstore();
5829 vpop();
5833 /* put zeros for variable based init */
5834 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5836 if (sec) {
5837 /* nothing to do because globals are already set to zero */
5838 } else {
5839 vpush_global_sym(&func_old_type, TOK_memset);
5840 vseti(VT_LOCAL, c);
5841 #ifdef TCC_TARGET_ARM
5842 vpushs(size);
5843 vpushi(0);
5844 #else
5845 vpushi(0);
5846 vpushs(size);
5847 #endif
5848 gfunc_call(3);
5852 /* 't' contains the type and storage info. 'c' is the offset of the
5853 object in section 'sec'. If 'sec' is NULL, it means stack based
5854 allocation. 'first' is true if array '{' must be read (multi
5855 dimension implicit array init handling). 'size_only' is true if
5856 size only evaluation is wanted (only for arrays). */
5857 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5858 int first, int size_only)
5860 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5861 int size1, align1, expr_type;
5862 Sym *s, *f;
5863 CType *t1;
5865 if (type->t & VT_VLA) {
5866 int a;
5868 /* save current stack pointer */
5869 if (vlas_in_scope == 0) {
5870 if (vla_sp_root_loc == -1)
5871 vla_sp_root_loc = (loc -= PTR_SIZE);
5872 gen_vla_sp_save(vla_sp_root_loc);
5875 vla_runtime_type_size(type, &a);
5876 gen_vla_alloc(type, a);
5877 gen_vla_sp_save(c);
5878 vla_sp_loc = c;
5879 vlas_in_scope++;
5880 } else if (type->t & VT_ARRAY) {
5881 s = type->ref;
5882 n = s->c;
5883 array_length = 0;
5884 t1 = pointed_type(type);
5885 size1 = type_size(t1, &align1);
5887 no_oblock = 1;
5888 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5889 tok == '{') {
5890 if (tok != '{')
5891 tcc_error("character array initializer must be a literal,"
5892 " optionally enclosed in braces");
5893 skip('{');
5894 no_oblock = 0;
5897 /* only parse strings here if correct type (otherwise: handle
5898 them as ((w)char *) expressions */
5899 if ((tok == TOK_LSTR &&
5900 #ifdef TCC_TARGET_PE
5901 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5902 #else
5903 (t1->t & VT_BTYPE) == VT_INT
5904 #endif
5905 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5906 while (tok == TOK_STR || tok == TOK_LSTR) {
5907 int cstr_len, ch;
5909 /* compute maximum number of chars wanted */
5910 if (tok == TOK_STR)
5911 cstr_len = tokc.str.size;
5912 else
5913 cstr_len = tokc.str.size / sizeof(nwchar_t);
5914 cstr_len--;
5915 nb = cstr_len;
5916 if (n >= 0 && nb > (n - array_length))
5917 nb = n - array_length;
5918 if (!size_only) {
5919 if (cstr_len > nb)
5920 tcc_warning("initializer-string for array is too long");
5921 /* in order to go faster for common case (char
5922 string in global variable, we handle it
5923 specifically */
5924 if (sec && tok == TOK_STR && size1 == 1) {
5925 memcpy(sec->data + c + array_length, tokc.str.data, nb);
5926 } else {
5927 for(i=0;i<nb;i++) {
5928 if (tok == TOK_STR)
5929 ch = ((unsigned char *)tokc.str.data)[i];
5930 else
5931 ch = ((nwchar_t *)tokc.str.data)[i];
5932 init_putv(t1, sec, c + (array_length + i) * size1,
5933 ch, EXPR_VAL);
5937 array_length += nb;
5938 next();
5940 /* only add trailing zero if enough storage (no
5941 warning in this case since it is standard) */
5942 if (n < 0 || array_length < n) {
5943 if (!size_only) {
5944 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5946 array_length++;
5948 } else {
5949 index = 0;
5950 while (tok != '}') {
5951 decl_designator(type, sec, c, &index, NULL, size_only);
5952 if (n >= 0 && index >= n)
5953 tcc_error("index too large");
5954 /* must put zero in holes (note that doing it that way
5955 ensures that it even works with designators) */
5956 if (!size_only && array_length < index) {
5957 init_putz(t1, sec, c + array_length * size1,
5958 (index - array_length) * size1);
5960 index++;
5961 if (index > array_length)
5962 array_length = index;
5963 /* special test for multi dimensional arrays (may not
5964 be strictly correct if designators are used at the
5965 same time) */
5966 if (index >= n && no_oblock)
5967 break;
5968 if (tok == '}')
5969 break;
5970 skip(',');
5973 if (!no_oblock)
5974 skip('}');
5975 /* put zeros at the end */
5976 if (!size_only && n >= 0 && array_length < n) {
5977 init_putz(t1, sec, c + array_length * size1,
5978 (n - array_length) * size1);
5980 /* patch type size if needed */
5981 if (n < 0)
5982 s->c = array_length;
5983 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5984 (sec || !first || tok == '{')) {
5986 /* NOTE: the previous test is a specific case for automatic
5987 struct/union init */
5988 /* XXX: union needs only one init */
5990 int par_count = 0;
5991 if (tok == '(') {
5992 AttributeDef ad1;
5993 CType type1;
5994 next();
5995 if (tcc_state->old_struct_init_code) {
5996 /* an old version of struct initialization.
5997 It have a problems. But with a new version
5998 linux 2.4.26 can't load ramdisk.
6000 while (tok == '(') {
6001 par_count++;
6002 next();
6004 if (!parse_btype(&type1, &ad1))
6005 expect("cast");
6006 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
6007 #if 0
6008 if (!is_assignable_types(type, &type1))
6009 tcc_error("invalid type for cast");
6010 #endif
6011 skip(')');
6013 else
6015 if (tok != '(') {
6016 if (!parse_btype(&type1, &ad1))
6017 expect("cast");
6018 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
6019 #if 0
6020 if (!is_assignable_types(type, &type1))
6021 tcc_error("invalid type for cast");
6022 #endif
6023 skip(')');
6024 } else
6025 unget_tok(tok);
6029 no_oblock = 1;
6030 if (first || tok == '{') {
6031 skip('{');
6032 no_oblock = 0;
6034 s = type->ref;
6035 f = s->next;
6036 array_length = 0;
6037 index = 0;
6038 n = s->c;
6039 while (tok != '}') {
6040 decl_designator(type, sec, c, NULL, &f, size_only);
6041 index = f->c;
6042 if (!size_only && array_length < index) {
6043 init_putz(type, sec, c + array_length,
6044 index - array_length);
6046 index = index + type_size(&f->type, &align1);
6047 if (index > array_length)
6048 array_length = index;
6050 /* gr: skip fields from same union - ugly. */
6051 while (f->next) {
6052 int align = 0;
6053 int f_size = type_size(&f->type, &align);
6054 int f_type = (f->type.t & VT_BTYPE);
6056 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
6057 /* test for same offset */
6058 if (f->next->c != f->c)
6059 break;
6060 if ((f_type == VT_STRUCT) && (f_size == 0)) {
6062 Lets assume a structure of size 0 can't be a member of the union.
6063 This allow to compile the following code from a linux kernel v2.4.26
6064 typedef struct { } rwlock_t;
6065 struct fs_struct {
6066 int count;
6067 rwlock_t lock;
6068 int umask;
6070 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
6071 tcc-0.9.23 can succesfully compile this version of the kernel.
6072 gcc don't have problems with this code too.
6074 break;
6076 /* if yes, test for bitfield shift */
6077 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
6078 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
6079 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
6080 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
6081 if (bit_pos_1 != bit_pos_2)
6082 break;
6084 f = f->next;
6087 f = f->next;
6088 if (no_oblock && f == NULL)
6089 break;
6090 if (tok == '}')
6091 break;
6092 skip(',');
6094 /* put zeros at the end */
6095 if (!size_only && array_length < n) {
6096 init_putz(type, sec, c + array_length,
6097 n - array_length);
6099 if (!no_oblock)
6100 skip('}');
6101 while (par_count) {
6102 skip(')');
6103 par_count--;
6105 } else if (tok == '{') {
6106 next();
6107 decl_initializer(type, sec, c, first, size_only);
6108 skip('}');
6109 } else if (size_only) {
6110 /* just skip expression */
6111 parlevel = parlevel1 = 0;
6112 while ((parlevel > 0 || parlevel1 > 0 ||
6113 (tok != '}' && tok != ',')) && tok != -1) {
6114 if (tok == '(')
6115 parlevel++;
6116 else if (tok == ')') {
6117 if (parlevel == 0 && parlevel1 == 0)
6118 break;
6119 parlevel--;
6121 else if (tok == '{')
6122 parlevel1++;
6123 else if (tok == '}') {
6124 if (parlevel == 0 && parlevel1 == 0)
6125 break;
6126 parlevel1--;
6128 next();
6130 } else {
6131 /* currently, we always use constant expression for globals
6132 (may change for scripting case) */
6133 expr_type = EXPR_CONST;
6134 if (!sec)
6135 expr_type = EXPR_ANY;
6136 init_putv(type, sec, c, 0, expr_type);
6140 /* parse an initializer for type 't' if 'has_init' is non zero, and
6141 allocate space in local or global data space ('r' is either
6142 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6143 variable 'v' of scope 'scope' is declared before initializers
6144 are parsed. If 'v' is zero, then a reference to the new object
6145 is put in the value stack. If 'has_init' is 2, a special parsing
6146 is done to handle string constants. */
6147 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
6148 int has_init, int v, int scope)
6150 int size, align, addr, data_offset;
6151 int level;
6152 ParseState saved_parse_state = {0};
6153 TokenString *init_str = NULL;
6154 Section *sec;
6155 Sym *flexible_array;
6157 flexible_array = NULL;
6158 if ((type->t & VT_BTYPE) == VT_STRUCT) {
6159 Sym *field = type->ref->next;
6160 if (field) {
6161 while (field->next)
6162 field = field->next;
6163 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
6164 flexible_array = field;
6168 size = type_size(type, &align);
6169 /* If unknown size, we must evaluate it before
6170 evaluating initializers because
6171 initializers can generate global data too
6172 (e.g. string pointers or ISOC99 compound
6173 literals). It also simplifies local
6174 initializers handling */
6175 if (size < 0 || (flexible_array && has_init)) {
6176 if (!has_init)
6177 tcc_error("unknown type size");
6178 /* get all init string */
6179 init_str = tok_str_alloc();
6180 if (has_init == 2) {
6181 /* only get strings */
6182 while (tok == TOK_STR || tok == TOK_LSTR) {
6183 tok_str_add_tok(init_str);
6184 next();
6186 } else {
6187 level = 0;
6188 while (level > 0 || (tok != ',' && tok != ';')) {
6189 if (tok < 0)
6190 tcc_error("unexpected end of file in initializer");
6191 tok_str_add_tok(init_str);
6192 if (tok == '{')
6193 level++;
6194 else if (tok == '}') {
6195 level--;
6196 if (level <= 0) {
6197 next();
6198 break;
6201 next();
6204 tok_str_add(init_str, -1);
6205 tok_str_add(init_str, 0);
6207 /* compute size */
6208 save_parse_state(&saved_parse_state);
6210 begin_macro(init_str, 1);
6211 next();
6212 decl_initializer(type, NULL, 0, 1, 1);
6213 /* prepare second initializer parsing */
6214 macro_ptr = init_str->str;
6215 next();
6217 /* if still unknown size, error */
6218 size = type_size(type, &align);
6219 if (size < 0)
6220 tcc_error("unknown type size");
6222 /* If there's a flex member and it was used in the initializer
6223 adjust size. */
6224 if (flexible_array &&
6225 flexible_array->type.ref->c > 0)
6226 size += flexible_array->type.ref->c
6227 * pointed_size(&flexible_array->type);
6228 /* take into account specified alignment if bigger */
6229 if (ad->a.aligned) {
6230 if (ad->a.aligned > align)
6231 align = ad->a.aligned;
6232 } else if (ad->a.packed) {
6233 align = 1;
6235 if ((r & VT_VALMASK) == VT_LOCAL) {
6236 sec = NULL;
6237 #ifdef CONFIG_TCC_BCHECK
6238 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
6239 loc--;
6241 #endif
6242 loc = (loc - size) & -align;
6243 addr = loc;
6244 #ifdef CONFIG_TCC_BCHECK
6245 /* handles bounds */
6246 /* XXX: currently, since we do only one pass, we cannot track
6247 '&' operators, so we add only arrays */
6248 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
6249 addr_t *bounds_ptr;
6250 /* add padding between regions */
6251 loc--;
6252 /* then add local bound info */
6253 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
6254 bounds_ptr[0] = addr;
6255 bounds_ptr[1] = size;
6257 #endif
6258 if (v) {
6259 /* local variable */
6260 sym_push(v, type, r, addr);
6261 } else {
6262 /* push local reference */
6263 vset(type, r, addr);
6265 } else {
6266 Sym *sym;
6268 sym = NULL;
6269 if (v && scope == VT_CONST) {
6270 /* see if the symbol was already defined */
6271 sym = sym_find(v);
6272 if (sym) {
6273 if (!is_compatible_types(&sym->type, type))
6274 tcc_error("incompatible types for redefinition of '%s'",
6275 get_tok_str(v, NULL));
6276 if (sym->type.t & VT_EXTERN) {
6277 /* if the variable is extern, it was not allocated */
6278 sym->type.t &= ~VT_EXTERN;
6279 /* set array size if it was omitted in extern
6280 declaration */
6281 if ((sym->type.t & VT_ARRAY) &&
6282 sym->type.ref->c < 0 &&
6283 type->ref->c >= 0)
6284 sym->type.ref->c = type->ref->c;
6285 } else {
6286 /* we accept several definitions of the same
6287 global variable. this is tricky, because we
6288 must play with the SHN_COMMON type of the symbol */
6289 /* XXX: should check if the variable was already
6290 initialized. It is incorrect to initialized it
6291 twice */
6292 /* no init data, we won't add more to the symbol */
6293 if (!has_init)
6294 goto no_alloc;
6299 /* allocate symbol in corresponding section */
6300 sec = ad->section;
6301 if (!sec) {
6302 if (has_init)
6303 sec = data_section;
6304 else if (tcc_state->nocommon)
6305 sec = bss_section;
6307 if (sec) {
6308 data_offset = sec->data_offset;
6309 data_offset = (data_offset + align - 1) & -align;
6310 addr = data_offset;
6311 /* very important to increment global pointer at this time
6312 because initializers themselves can create new initializers */
6313 data_offset += size;
6314 #ifdef CONFIG_TCC_BCHECK
6315 /* add padding if bound check */
6316 if (tcc_state->do_bounds_check)
6317 data_offset++;
6318 #endif
6319 sec->data_offset = data_offset;
6320 /* allocate section space to put the data */
6321 if (sec->sh_type != SHT_NOBITS &&
6322 data_offset > sec->data_allocated)
6323 section_realloc(sec, data_offset);
6324 /* align section if needed */
6325 if (align > sec->sh_addralign)
6326 sec->sh_addralign = align;
6327 } else {
6328 addr = 0; /* avoid warning */
6331 if (v) {
6332 if (scope != VT_CONST || !sym) {
6333 sym = sym_push(v, type, r | VT_SYM, 0);
6334 sym->asm_label = ad->asm_label;
6336 /* update symbol definition */
6337 if (sec) {
6338 put_extern_sym(sym, sec, addr, size);
6339 } else {
6340 ElfW(Sym) *esym;
6341 /* put a common area */
6342 put_extern_sym(sym, NULL, align, size);
6343 /* XXX: find a nicer way */
6344 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
6345 esym->st_shndx = SHN_COMMON;
6347 } else {
6348 /* push global reference */
6349 sym = get_sym_ref(type, sec, addr, size);
6350 vpushsym(type, sym);
6352 /* patch symbol weakness */
6353 if (type->t & VT_WEAK)
6354 weaken_symbol(sym);
6355 apply_visibility(sym, type);
6356 #ifdef CONFIG_TCC_BCHECK
6357 /* handles bounds now because the symbol must be defined
6358 before for the relocation */
6359 if (tcc_state->do_bounds_check) {
6360 addr_t *bounds_ptr;
6362 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
6363 /* then add global bound info */
6364 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
6365 bounds_ptr[0] = 0; /* relocated */
6366 bounds_ptr[1] = size;
6368 #endif
6370 if (has_init || (type->t & VT_VLA)) {
6371 decl_initializer(type, sec, addr, 1, 0);
6372 /* patch flexible array member size back to -1, */
6373 /* for possible subsequent similar declarations */
6374 if (flexible_array)
6375 flexible_array->type.ref->c = -1;
6377 no_alloc: ;
6378 /* restore parse state if needed */
6379 if (init_str) {
6380 end_macro();
6381 restore_parse_state(&saved_parse_state);
6385 static void put_func_debug(Sym *sym)
6387 char buf[512];
6389 /* stabs info */
6390 /* XXX: we put here a dummy type */
6391 snprintf(buf, sizeof(buf), "%s:%c1",
6392 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
6393 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6394 cur_text_section, sym->c);
6395 /* //gr gdb wants a line at the function */
6396 put_stabn(N_SLINE, 0, file->line_num, 0);
6397 last_ind = 0;
6398 last_line_num = 0;
6401 /* parse an old style function declaration list */
6402 /* XXX: check multiple parameter */
6403 static void func_decl_list(Sym *func_sym)
6405 AttributeDef ad;
6406 int v;
6407 Sym *s;
6408 CType btype, type;
6410 /* parse each declaration */
6411 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
6412 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
6413 if (!parse_btype(&btype, &ad))
6414 expect("declaration list");
6415 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6416 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6417 tok == ';') {
6418 /* we accept no variable after */
6419 } else {
6420 for(;;) {
6421 type = btype;
6422 type_decl(&type, &ad, &v, TYPE_DIRECT);
6423 /* find parameter in function parameter list */
6424 s = func_sym->next;
6425 while (s != NULL) {
6426 if ((s->v & ~SYM_FIELD) == v)
6427 goto found;
6428 s = s->next;
6430 tcc_error("declaration for parameter '%s' but no such parameter",
6431 get_tok_str(v, NULL));
6432 found:
6433 /* check that no storage specifier except 'register' was given */
6434 if (type.t & VT_STORAGE)
6435 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
6436 convert_parameter_type(&type);
6437 /* we can add the type (NOTE: it could be local to the function) */
6438 s->type = type;
6439 /* accept other parameters */
6440 if (tok == ',')
6441 next();
6442 else
6443 break;
6446 skip(';');
6450 /* parse a function defined by symbol 'sym' and generate its code in
6451 'cur_text_section' */
6452 static void gen_function(Sym *sym)
6454 int saved_nocode_wanted = nocode_wanted;
6456 nocode_wanted = 0;
6457 ind = cur_text_section->data_offset;
6458 /* NOTE: we patch the symbol size later */
6459 put_extern_sym(sym, cur_text_section, ind, 0);
6460 funcname = get_tok_str(sym->v, NULL);
6461 func_ind = ind;
6462 /* Initialize VLA state */
6463 vla_sp_loc = -1;
6464 vla_sp_root_loc = -1;
6465 /* put debug symbol */
6466 if (tcc_state->do_debug)
6467 put_func_debug(sym);
6469 /* push a dummy symbol to enable local sym storage */
6470 sym_push2(&local_stack, SYM_FIELD, 0, 0);
6471 local_scope = 1; /* for function parameters */
6472 gfunc_prolog(&sym->type);
6473 local_scope = 0;
6475 rsym = 0;
6476 block(NULL, NULL, 0);
6477 gsym(rsym);
6478 gfunc_epilog();
6479 cur_text_section->data_offset = ind;
6480 label_pop(&global_label_stack, NULL);
6481 /* reset local stack */
6482 local_scope = 0;
6483 sym_pop(&local_stack, NULL);
6484 /* end of function */
6485 /* patch symbol size */
6486 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
6487 ind - func_ind;
6488 /* patch symbol weakness (this definition overrules any prototype) */
6489 if (sym->type.t & VT_WEAK)
6490 weaken_symbol(sym);
6491 apply_visibility(sym, &sym->type);
6492 if (tcc_state->do_debug) {
6493 put_stabn(N_FUN, 0, 0, ind - func_ind);
6495 /* It's better to crash than to generate wrong code */
6496 cur_text_section = NULL;
6497 funcname = ""; /* for safety */
6498 func_vt.t = VT_VOID; /* for safety */
6499 func_var = 0; /* for safety */
6500 ind = 0; /* for safety */
6501 nocode_wanted = saved_nocode_wanted;
6502 check_vstack();
6505 ST_FUNC void gen_inline_functions(void)
6507 Sym *sym;
6508 int inline_generated, i, ln;
6509 struct InlineFunc *fn;
6511 ln = file->line_num;
6512 /* iterate while inline function are referenced */
6513 for(;;) {
6514 inline_generated = 0;
6515 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6516 fn = tcc_state->inline_fns[i];
6517 sym = fn->sym;
6518 if (sym && sym->c) {
6519 /* the function was used: generate its code and
6520 convert it to a normal function */
6521 fn->sym = NULL;
6522 if (file)
6523 pstrcpy(file->filename, sizeof file->filename, fn->filename);
6524 sym->r = VT_SYM | VT_CONST;
6525 sym->type.t &= ~VT_INLINE;
6527 begin_macro(&fn->func_str, 0);
6528 next();
6529 cur_text_section = text_section;
6530 gen_function(sym);
6531 end_macro();
6533 inline_generated = 1;
6536 if (!inline_generated)
6537 break;
6539 file->line_num = ln;
6540 /* free tokens of unused inline functions */
6541 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6542 fn = tcc_state->inline_fns[i];
6543 if (fn->sym)
6544 tok_str_free(fn->func_str.str);
6546 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
6549 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6550 static int decl0(int l, int is_for_loop_init)
6552 int v, has_init, r;
6553 CType type, btype;
6554 Sym *sym;
6555 AttributeDef ad;
6557 while (1) {
6558 if (!parse_btype(&btype, &ad)) {
6559 if (is_for_loop_init)
6560 return 0;
6561 /* skip redundant ';' */
6562 /* XXX: find more elegant solution */
6563 if (tok == ';') {
6564 next();
6565 continue;
6567 if (l == VT_CONST &&
6568 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6569 /* global asm block */
6570 asm_global_instr();
6571 continue;
6573 /* special test for old K&R protos without explicit int
6574 type. Only accepted when defining global data */
6575 if (l == VT_LOCAL || tok < TOK_UIDENT)
6576 break;
6577 btype.t = VT_INT;
6579 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6580 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6581 tok == ';') {
6582 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
6583 int v = btype.ref->v;
6584 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
6585 tcc_warning("unnamed struct/union that defines no instances");
6587 next();
6588 continue;
6590 while (1) { /* iterate thru each declaration */
6591 type = btype;
6592 type_decl(&type, &ad, &v, TYPE_DIRECT);
6593 #if 0
6595 char buf[500];
6596 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6597 printf("type = '%s'\n", buf);
6599 #endif
6600 if ((type.t & VT_BTYPE) == VT_FUNC) {
6601 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
6602 tcc_error("function without file scope cannot be static");
6604 /* if old style function prototype, we accept a
6605 declaration list */
6606 sym = type.ref;
6607 if (sym->c == FUNC_OLD)
6608 func_decl_list(sym);
6611 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6612 ad.asm_label = asm_label_instr();
6613 /* parse one last attribute list, after asm label */
6614 parse_attribute(&ad);
6615 if (tok == '{')
6616 expect(";");
6619 if (ad.a.weak)
6620 type.t |= VT_WEAK;
6621 #ifdef TCC_TARGET_PE
6622 if (ad.a.func_import)
6623 type.t |= VT_IMPORT;
6624 if (ad.a.func_export)
6625 type.t |= VT_EXPORT;
6626 #endif
6627 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6629 if (tok == '{') {
6630 if (l == VT_LOCAL)
6631 tcc_error("cannot use local functions");
6632 if ((type.t & VT_BTYPE) != VT_FUNC)
6633 expect("function definition");
6635 /* reject abstract declarators in function definition */
6636 sym = type.ref;
6637 while ((sym = sym->next) != NULL)
6638 if (!(sym->v & ~SYM_FIELD))
6639 expect("identifier");
6641 /* XXX: cannot do better now: convert extern line to static inline */
6642 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6643 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6645 sym = sym_find(v);
6646 if (sym) {
6647 Sym *ref;
6648 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6649 goto func_error1;
6651 ref = sym->type.ref;
6652 if (0 == ref->a.func_proto)
6653 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6655 /* use func_call from prototype if not defined */
6656 if (ref->a.func_call != FUNC_CDECL
6657 && type.ref->a.func_call == FUNC_CDECL)
6658 type.ref->a.func_call = ref->a.func_call;
6660 /* use export from prototype */
6661 if (ref->a.func_export)
6662 type.ref->a.func_export = 1;
6664 /* use static from prototype */
6665 if (sym->type.t & VT_STATIC)
6666 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6668 /* If the definition has no visibility use the
6669 one from prototype. */
6670 if (! (type.t & VT_VIS_MASK))
6671 type.t |= sym->type.t & VT_VIS_MASK;
6673 if (!is_compatible_types(&sym->type, &type)) {
6674 func_error1:
6675 tcc_error("incompatible types for redefinition of '%s'",
6676 get_tok_str(v, NULL));
6678 type.ref->a.func_proto = 0;
6679 /* if symbol is already defined, then put complete type */
6680 sym->type = type;
6681 } else {
6682 /* put function symbol */
6683 sym = global_identifier_push(v, type.t, 0);
6684 sym->type.ref = type.ref;
6687 /* static inline functions are just recorded as a kind
6688 of macro. Their code will be emitted at the end of
6689 the compilation unit only if they are used */
6690 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6691 (VT_INLINE | VT_STATIC)) {
6692 int block_level;
6693 struct InlineFunc *fn;
6694 const char *filename;
6696 filename = file ? file->filename : "";
6697 fn = tcc_malloc(sizeof *fn + strlen(filename));
6698 strcpy(fn->filename, filename);
6699 fn->sym = sym;
6700 tok_str_new(&fn->func_str);
6702 block_level = 0;
6703 for(;;) {
6704 int t;
6705 if (tok == TOK_EOF)
6706 tcc_error("unexpected end of file");
6707 tok_str_add_tok(&fn->func_str);
6708 t = tok;
6709 next();
6710 if (t == '{') {
6711 block_level++;
6712 } else if (t == '}') {
6713 block_level--;
6714 if (block_level == 0)
6715 break;
6718 tok_str_add(&fn->func_str, -1);
6719 tok_str_add(&fn->func_str, 0);
6720 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6722 } else {
6723 /* compute text section */
6724 cur_text_section = ad.section;
6725 if (!cur_text_section)
6726 cur_text_section = text_section;
6727 sym->r = VT_SYM | VT_CONST;
6728 gen_function(sym);
6730 break;
6731 } else {
6732 if (btype.t & VT_TYPEDEF) {
6733 /* save typedefed type */
6734 /* XXX: test storage specifiers ? */
6735 sym = sym_find(v);
6736 if (sym && sym->scope == local_scope) {
6737 if (!is_compatible_types(&sym->type, &type)
6738 || !(sym->type.t & VT_TYPEDEF))
6739 tcc_error("incompatible redefinition of '%s'",
6740 get_tok_str(v, NULL));
6741 sym->type = type;
6742 } else {
6743 sym = sym_push(v, &type, 0, 0);
6745 sym->a = ad.a;
6746 sym->type.t |= VT_TYPEDEF;
6747 } else {
6748 r = 0;
6749 if ((type.t & VT_BTYPE) == VT_FUNC) {
6750 /* external function definition */
6751 /* specific case for func_call attribute */
6752 ad.a.func_proto = 1;
6753 type.ref->a = ad.a;
6754 } else if (!(type.t & VT_ARRAY)) {
6755 /* not lvalue if array */
6756 r |= lvalue_type(type.t);
6758 has_init = (tok == '=');
6759 if (has_init && (type.t & VT_VLA))
6760 tcc_error("Variable length array cannot be initialized");
6761 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6762 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6763 !has_init && l == VT_CONST && type.ref->c < 0)) {
6764 /* external variable or function */
6765 /* NOTE: as GCC, uninitialized global static
6766 arrays of null size are considered as
6767 extern */
6768 sym = external_sym(v, &type, r);
6769 sym->asm_label = ad.asm_label;
6771 if (ad.alias_target) {
6772 Section tsec;
6773 Elf32_Sym *esym;
6774 Sym *alias_target;
6776 alias_target = sym_find(ad.alias_target);
6777 if (!alias_target || !alias_target->c)
6778 tcc_error("unsupported forward __alias__ attribute");
6779 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6780 tsec.sh_num = esym->st_shndx;
6781 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6783 } else {
6784 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6785 if (type.t & VT_STATIC)
6786 r |= VT_CONST;
6787 else
6788 r |= l;
6789 if (has_init)
6790 next();
6791 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
6794 if (tok != ',') {
6795 if (is_for_loop_init)
6796 return 1;
6797 skip(';');
6798 break;
6800 next();
6802 ad.a.aligned = 0;
6805 return 0;
6808 ST_FUNC void decl(int l)
6810 decl0(l, 0);
6813 /* ------------------------------------------------------------------------- */