Some types testcases
[tinycc.git] / tccgen.c
blob223a1a77de0f7f26b11c1064ae428da3c687f179
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"
22 /********************************************************/
23 /* global variables */
25 /* loc : local variable index
26 ind : output code index
27 rsym: return symbol
28 anon_sym: anonymous symbol index
30 ST_DATA int rsym, anon_sym, ind, loc;
32 ST_DATA Sym *sym_free_first;
33 ST_DATA void **sym_pools;
34 ST_DATA int nb_sym_pools;
36 ST_DATA Sym *global_stack;
37 ST_DATA Sym *local_stack;
38 ST_DATA Sym *define_stack;
39 ST_DATA Sym *global_label_stack;
40 ST_DATA Sym *local_label_stack;
42 static Sym *all_cleanups, *current_cleanups, *pending_gotos;
43 static int ncleanups;
45 static int local_scope;
46 static int in_sizeof;
47 static int section_sym;
49 ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
50 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
51 ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
53 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
55 ST_DATA int const_wanted; /* true if constant wanted */
56 ST_DATA int nocode_wanted; /* no code generation wanted */
57 #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
58 #define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
59 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
60 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
61 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
62 ST_DATA int func_vc;
63 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
64 ST_DATA const char *funcname;
65 ST_DATA int g_debug;
67 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type;
69 ST_DATA struct switch_t {
70 struct case_t {
71 int64_t v1, v2;
72 int sym;
73 } **p; int n; /* list of case ranges */
74 int def_sym; /* default symbol */
75 } *cur_switch; /* current switch */
77 #define MAX_TEMP_LOCAL_VARIABLE_NUMBER 0x4
78 /*list of temporary local variables on the stack in current function. */
79 ST_DATA struct temp_local_variable {
80 int location; //offset on stack. Svalue.c.i
81 short size;
82 short align;
83 } arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER];
84 short nb_temp_local_vars;
86 /* ------------------------------------------------------------------------- */
88 static void gen_cast(CType *type);
89 static void gen_cast_s(int t);
90 static inline CType *pointed_type(CType *type);
91 static int is_compatible_types(CType *type1, CType *type2);
92 static int parse_btype(CType *type, AttributeDef *ad);
93 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
94 static void parse_expr_type(CType *type);
95 static void init_putv(CType *type, Section *sec, unsigned long c);
96 static void decl_initializer(CType *type, Section *sec, unsigned long c, int flags);
97 static void block(int *bsym, int *csym, int is_expr);
98 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
99 static void decl(int l);
100 static int decl0(int l, int is_for_loop_init, Sym *);
101 static void expr_eq(void);
102 static void vla_runtime_type_size(CType *type, int *a);
103 static void vla_sp_restore(void);
104 static void vla_sp_restore_root(void);
105 static int is_compatible_unqualified_types(CType *type1, CType *type2);
106 static inline int64_t expr_const64(void);
107 static void vpush64(int ty, unsigned long long v);
108 static void vpush(CType *type);
109 static int gvtst(int inv, int t);
110 static void gen_inline_functions(TCCState *s);
111 static void skip_or_save_block(TokenString **str);
112 static void gv_dup(void);
113 static int get_temp_local_var(int size,int align);
114 static void clear_temp_local_var_list();
117 static void reset_local_scope(void)
119 if (current_cleanups)
120 tcc_error("ICE current_cleanups");
121 sym_pop(&all_cleanups, NULL, 0);
122 local_scope = 0;
125 ST_INLN int is_float(int t)
127 int bt;
128 bt = t & VT_BTYPE;
129 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
132 /* we use our own 'finite' function to avoid potential problems with
133 non standard math libs */
134 /* XXX: endianness dependent */
135 ST_FUNC int ieee_finite(double d)
137 int p[4];
138 memcpy(p, &d, sizeof(double));
139 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
142 /* compiling intel long double natively */
143 #if (defined __i386__ || defined __x86_64__) \
144 && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
145 # define TCC_IS_NATIVE_387
146 #endif
148 ST_FUNC void test_lvalue(void)
150 if (!(vtop->r & VT_LVAL))
151 expect("lvalue");
154 ST_FUNC void check_vstack(void)
156 if (pvtop != vtop)
157 tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
160 /* ------------------------------------------------------------------------- */
161 /* vstack debugging aid */
163 #if 0
164 void pv (const char *lbl, int a, int b)
166 int i;
167 for (i = a; i < a + b; ++i) {
168 SValue *p = &vtop[-i];
169 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
170 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
173 #endif
175 /* ------------------------------------------------------------------------- */
176 /* start of translation unit info */
177 ST_FUNC void tcc_debug_start(TCCState *s1)
179 if (s1->do_debug) {
180 char buf[512];
182 /* file info: full path + filename */
183 section_sym = put_elf_sym(symtab_section, 0, 0,
184 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
185 text_section->sh_num, NULL);
186 getcwd(buf, sizeof(buf));
187 #ifdef _WIN32
188 normalize_slashes(buf);
189 #endif
190 pstrcat(buf, sizeof(buf), "/");
191 put_stabs_r(buf, N_SO, 0, 0,
192 text_section->data_offset, text_section, section_sym);
193 put_stabs_r(file->filename, N_SO, 0, 0,
194 text_section->data_offset, text_section, section_sym);
195 last_ind = 0;
196 last_line_num = 0;
199 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
200 symbols can be safely used */
201 put_elf_sym(symtab_section, 0, 0,
202 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
203 SHN_ABS, file->filename);
206 /* put end of translation unit info */
207 ST_FUNC void tcc_debug_end(TCCState *s1)
209 if (!s1->do_debug)
210 return;
211 put_stabs_r(NULL, N_SO, 0, 0,
212 text_section->data_offset, text_section, section_sym);
216 /* generate line number info */
217 ST_FUNC void tcc_debug_line(TCCState *s1)
219 if (!s1->do_debug)
220 return;
221 if ((last_line_num != file->line_num || last_ind != ind)) {
222 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
223 last_ind = ind;
224 last_line_num = file->line_num;
228 /* put function symbol */
229 ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
231 char buf[512];
233 if (!s1->do_debug)
234 return;
236 /* stabs info */
237 /* XXX: we put here a dummy type */
238 snprintf(buf, sizeof(buf), "%s:%c1",
239 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
240 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
241 cur_text_section, sym->c);
242 /* //gr gdb wants a line at the function */
243 put_stabn(N_SLINE, 0, file->line_num, 0);
245 last_ind = 0;
246 last_line_num = 0;
249 /* put function size */
250 ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
252 if (!s1->do_debug)
253 return;
254 put_stabn(N_FUN, 0, 0, size);
257 /* ------------------------------------------------------------------------- */
258 ST_FUNC int tccgen_compile(TCCState *s1)
260 cur_text_section = NULL;
261 funcname = "";
262 anon_sym = SYM_FIRST_ANOM;
263 section_sym = 0;
264 const_wanted = 0;
265 nocode_wanted = 0x80000000;
267 /* define some often used types */
268 int_type.t = VT_INT;
269 char_pointer_type.t = VT_BYTE;
270 mk_pointer(&char_pointer_type);
271 #if PTR_SIZE == 4
272 size_type.t = VT_INT | VT_UNSIGNED;
273 ptrdiff_type.t = VT_INT;
274 #elif LONG_SIZE == 4
275 size_type.t = VT_LLONG | VT_UNSIGNED;
276 ptrdiff_type.t = VT_LLONG;
277 #else
278 size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED;
279 ptrdiff_type.t = VT_LONG | VT_LLONG;
280 #endif
281 func_old_type.t = VT_FUNC;
282 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
283 func_old_type.ref->f.func_call = FUNC_CDECL;
284 func_old_type.ref->f.func_type = FUNC_OLD;
286 tcc_debug_start(s1);
288 #ifdef TCC_TARGET_ARM
289 arm_init(s1);
290 #endif
292 #ifdef INC_DEBUG
293 printf("%s: **** new file\n", file->filename);
294 #endif
296 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
297 next();
298 decl(VT_CONST);
299 gen_inline_functions(s1);
300 check_vstack();
301 /* end of translation unit info */
302 tcc_debug_end(s1);
303 return 0;
306 /* ------------------------------------------------------------------------- */
307 ST_FUNC ElfSym *elfsym(Sym *s)
309 if (!s || !s->c)
310 return NULL;
311 return &((ElfSym *)symtab_section->data)[s->c];
314 /* apply storage attributes to Elf symbol */
315 ST_FUNC void update_storage(Sym *sym)
317 ElfSym *esym;
318 int sym_bind, old_sym_bind;
320 esym = elfsym(sym);
321 if (!esym)
322 return;
324 if (sym->a.visibility)
325 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
326 | sym->a.visibility;
328 if (sym->type.t & VT_STATIC)
329 sym_bind = STB_LOCAL;
330 else if (sym->a.weak)
331 sym_bind = STB_WEAK;
332 else
333 sym_bind = STB_GLOBAL;
334 old_sym_bind = ELFW(ST_BIND)(esym->st_info);
335 if (sym_bind != old_sym_bind) {
336 esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
339 #ifdef TCC_TARGET_PE
340 if (sym->a.dllimport)
341 esym->st_other |= ST_PE_IMPORT;
342 if (sym->a.dllexport)
343 esym->st_other |= ST_PE_EXPORT;
344 #endif
346 #if 0
347 printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
348 get_tok_str(sym->v, NULL),
349 sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
350 sym->a.visibility,
351 sym->a.dllexport,
352 sym->a.dllimport
354 #endif
357 /* ------------------------------------------------------------------------- */
358 /* update sym->c so that it points to an external symbol in section
359 'section' with value 'value' */
361 ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
362 addr_t value, unsigned long size,
363 int can_add_underscore)
365 int sym_type, sym_bind, info, other, t;
366 ElfSym *esym;
367 const char *name;
368 char buf1[256];
369 #ifdef CONFIG_TCC_BCHECK
370 char buf[32];
371 #endif
373 if (!sym->c) {
374 name = get_tok_str(sym->v, NULL);
375 #ifdef CONFIG_TCC_BCHECK
376 if (tcc_state->do_bounds_check) {
377 /* XXX: avoid doing that for statics ? */
378 /* if bound checking is activated, we change some function
379 names by adding the "__bound" prefix */
380 switch(sym->v) {
381 #ifdef TCC_TARGET_PE
382 /* XXX: we rely only on malloc hooks */
383 case TOK_malloc:
384 case TOK_free:
385 case TOK_realloc:
386 case TOK_memalign:
387 case TOK_calloc:
388 #endif
389 case TOK_memcpy:
390 case TOK_memmove:
391 case TOK_memset:
392 case TOK_strlen:
393 case TOK_strcpy:
394 case TOK_alloca:
395 strcpy(buf, "__bound_");
396 strcat(buf, name);
397 name = buf;
398 break;
401 #endif
402 t = sym->type.t;
403 if ((t & VT_BTYPE) == VT_FUNC) {
404 sym_type = STT_FUNC;
405 } else if ((t & VT_BTYPE) == VT_VOID) {
406 sym_type = STT_NOTYPE;
407 } else {
408 sym_type = STT_OBJECT;
410 if (t & VT_STATIC)
411 sym_bind = STB_LOCAL;
412 else
413 sym_bind = STB_GLOBAL;
414 other = 0;
415 #ifdef TCC_TARGET_PE
416 if (sym_type == STT_FUNC && sym->type.ref) {
417 Sym *ref = sym->type.ref;
418 if (ref->a.nodecorate) {
419 can_add_underscore = 0;
421 if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
422 sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
423 name = buf1;
424 other |= ST_PE_STDCALL;
425 can_add_underscore = 0;
428 #endif
429 if (tcc_state->leading_underscore && can_add_underscore) {
430 buf1[0] = '_';
431 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
432 name = buf1;
434 if (sym->asm_label)
435 name = get_tok_str(sym->asm_label, NULL);
436 info = ELFW(ST_INFO)(sym_bind, sym_type);
437 sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
438 } else {
439 esym = elfsym(sym);
440 esym->st_value = value;
441 esym->st_size = size;
442 esym->st_shndx = sh_num;
444 update_storage(sym);
447 ST_FUNC void put_extern_sym(Sym *sym, Section *section,
448 addr_t value, unsigned long size)
450 int sh_num = section ? section->sh_num : SHN_UNDEF;
451 put_extern_sym2(sym, sh_num, value, size, 1);
454 /* add a new relocation entry to symbol 'sym' in section 's' */
455 ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
456 addr_t addend)
458 int c = 0;
460 if (nocode_wanted && s == cur_text_section)
461 return;
463 if (sym) {
464 if (0 == sym->c)
465 put_extern_sym(sym, NULL, 0, 0);
466 c = sym->c;
469 /* now we can add ELF relocation info */
470 put_elf_reloca(symtab_section, s, offset, type, c, addend);
473 #if PTR_SIZE == 4
474 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
476 greloca(s, sym, offset, type, 0);
478 #endif
480 /* ------------------------------------------------------------------------- */
481 /* symbol allocator */
482 static Sym *__sym_malloc(void)
484 Sym *sym_pool, *sym, *last_sym;
485 int i;
487 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
488 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
490 last_sym = sym_free_first;
491 sym = sym_pool;
492 for(i = 0; i < SYM_POOL_NB; i++) {
493 sym->next = last_sym;
494 last_sym = sym;
495 sym++;
497 sym_free_first = last_sym;
498 return last_sym;
501 static inline Sym *sym_malloc(void)
503 Sym *sym;
504 #ifndef SYM_DEBUG
505 sym = sym_free_first;
506 if (!sym)
507 sym = __sym_malloc();
508 sym_free_first = sym->next;
509 return sym;
510 #else
511 sym = tcc_malloc(sizeof(Sym));
512 return sym;
513 #endif
516 ST_INLN void sym_free(Sym *sym)
518 #ifndef SYM_DEBUG
519 sym->next = sym_free_first;
520 sym_free_first = sym;
521 #else
522 tcc_free(sym);
523 #endif
526 /* push, without hashing */
527 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c)
529 Sym *s;
531 s = sym_malloc();
532 memset(s, 0, sizeof *s);
533 s->v = v;
534 s->type.t = t;
535 s->c = c;
536 /* add in stack */
537 s->prev = *ps;
538 *ps = s;
539 return s;
542 /* find a symbol and return its associated structure. 's' is the top
543 of the symbol stack */
544 ST_FUNC Sym *sym_find2(Sym *s, int v)
546 while (s) {
547 if (s->v == v)
548 return s;
549 else if (s->v == -1)
550 return NULL;
551 s = s->prev;
553 return NULL;
556 /* structure lookup */
557 ST_INLN Sym *struct_find(int v)
559 v -= TOK_IDENT;
560 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
561 return NULL;
562 return table_ident[v]->sym_struct;
565 /* find an identifier */
566 ST_INLN Sym *sym_find(int v)
568 v -= TOK_IDENT;
569 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
570 return NULL;
571 return table_ident[v]->sym_identifier;
574 static int sym_scope(Sym *s)
576 if (IS_ENUM_VAL (s->type.t))
577 return s->type.ref->sym_scope;
578 else
579 return s->sym_scope;
582 /* push a given symbol on the symbol stack */
583 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
585 Sym *s, **ps;
586 TokenSym *ts;
588 if (local_stack)
589 ps = &local_stack;
590 else
591 ps = &global_stack;
592 s = sym_push2(ps, v, type->t, c);
593 s->type.ref = type->ref;
594 s->r = r;
595 /* don't record fields or anonymous symbols */
596 /* XXX: simplify */
597 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
598 /* record symbol in token array */
599 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
600 if (v & SYM_STRUCT)
601 ps = &ts->sym_struct;
602 else
603 ps = &ts->sym_identifier;
604 s->prev_tok = *ps;
605 *ps = s;
606 s->sym_scope = local_scope;
607 if (s->prev_tok && sym_scope(s->prev_tok) == s->sym_scope)
608 tcc_error("redeclaration of '%s'",
609 get_tok_str(v & ~SYM_STRUCT, NULL));
611 return s;
614 /* push a global identifier */
615 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
617 Sym *s, **ps;
618 s = sym_push2(&global_stack, v, t, c);
619 /* don't record anonymous symbol */
620 if (v < SYM_FIRST_ANOM) {
621 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
622 /* modify the top most local identifier, so that
623 sym_identifier will point to 's' when popped */
624 while (*ps != NULL && (*ps)->sym_scope)
625 ps = &(*ps)->prev_tok;
626 s->prev_tok = *ps;
627 *ps = s;
629 return s;
632 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
633 pop them yet from the list, but do remove them from the token array. */
634 ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
636 Sym *s, *ss, **ps;
637 TokenSym *ts;
638 int v;
640 s = *ptop;
641 while(s != b) {
642 ss = s->prev;
643 v = s->v;
644 /* remove symbol in token array */
645 /* XXX: simplify */
646 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
647 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
648 if (v & SYM_STRUCT)
649 ps = &ts->sym_struct;
650 else
651 ps = &ts->sym_identifier;
652 *ps = s->prev_tok;
654 if (!keep)
655 sym_free(s);
656 s = ss;
658 if (!keep)
659 *ptop = b;
662 /* ------------------------------------------------------------------------- */
664 static void vsetc(CType *type, int r, CValue *vc)
666 int v;
668 if (vtop >= vstack + (VSTACK_SIZE - 1))
669 tcc_error("memory full (vstack)");
670 /* cannot let cpu flags if other instruction are generated. Also
671 avoid leaving VT_JMP anywhere except on the top of the stack
672 because it would complicate the code generator.
674 Don't do this when nocode_wanted. vtop might come from
675 !nocode_wanted regions (see 88_codeopt.c) and transforming
676 it to a register without actually generating code is wrong
677 as their value might still be used for real. All values
678 we push under nocode_wanted will eventually be popped
679 again, so that the VT_CMP/VT_JMP value will be in vtop
680 when code is unsuppressed again.
682 Same logic below in vswap(); */
683 if (vtop >= vstack && !nocode_wanted) {
684 v = vtop->r & VT_VALMASK;
685 if (v == VT_CMP || (v & ~1) == VT_JMP)
686 gv(RC_INT);
689 vtop++;
690 vtop->type = *type;
691 vtop->r = r;
692 vtop->r2 = VT_CONST;
693 vtop->c = *vc;
694 vtop->sym = NULL;
697 ST_FUNC void vswap(void)
699 SValue tmp;
700 /* cannot vswap cpu flags. See comment at vsetc() above */
701 if (vtop >= vstack && !nocode_wanted) {
702 int v = vtop->r & VT_VALMASK;
703 if (v == VT_CMP || (v & ~1) == VT_JMP)
704 gv(RC_INT);
706 tmp = vtop[0];
707 vtop[0] = vtop[-1];
708 vtop[-1] = tmp;
711 /* pop stack value */
712 ST_FUNC void vpop(void)
714 int v;
715 v = vtop->r & VT_VALMASK;
716 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
717 /* for x86, we need to pop the FP stack */
718 if (v == TREG_ST0) {
719 o(0xd8dd); /* fstp %st(0) */
720 } else
721 #endif
722 if (v == VT_JMP || v == VT_JMPI) {
723 /* need to put correct jump if && or || without test */
724 gsym(vtop->c.i);
726 vtop--;
729 /* push constant of type "type" with useless value */
730 ST_FUNC void vpush(CType *type)
732 vset(type, VT_CONST, 0);
735 /* push integer constant */
736 ST_FUNC void vpushi(int v)
738 CValue cval;
739 cval.i = v;
740 vsetc(&int_type, VT_CONST, &cval);
743 /* push a pointer sized constant */
744 static void vpushs(addr_t v)
746 CValue cval;
747 cval.i = v;
748 vsetc(&size_type, VT_CONST, &cval);
751 /* push arbitrary 64bit constant */
752 ST_FUNC void vpush64(int ty, unsigned long long v)
754 CValue cval;
755 CType ctype;
756 ctype.t = ty;
757 ctype.ref = NULL;
758 cval.i = v;
759 vsetc(&ctype, VT_CONST, &cval);
762 /* push long long constant */
763 static inline void vpushll(long long v)
765 vpush64(VT_LLONG, v);
768 ST_FUNC void vset(CType *type, int r, int v)
770 CValue cval;
772 cval.i = v;
773 vsetc(type, r, &cval);
776 static void vseti(int r, int v)
778 CType type;
779 type.t = VT_INT;
780 type.ref = NULL;
781 vset(&type, r, v);
784 ST_FUNC void vpushv(SValue *v)
786 if (vtop >= vstack + (VSTACK_SIZE - 1))
787 tcc_error("memory full (vstack)");
788 vtop++;
789 *vtop = *v;
792 static void vdup(void)
794 vpushv(vtop);
797 /* rotate n first stack elements to the bottom
798 I1 ... In -> I2 ... In I1 [top is right]
800 ST_FUNC void vrotb(int n)
802 int i;
803 SValue tmp;
805 tmp = vtop[-n + 1];
806 for(i=-n+1;i!=0;i++)
807 vtop[i] = vtop[i+1];
808 vtop[0] = tmp;
811 /* rotate the n elements before entry e towards the top
812 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
814 ST_FUNC void vrote(SValue *e, int n)
816 int i;
817 SValue tmp;
819 tmp = *e;
820 for(i = 0;i < n - 1; i++)
821 e[-i] = e[-i - 1];
822 e[-n + 1] = tmp;
825 /* rotate n first stack elements to the top
826 I1 ... In -> In I1 ... I(n-1) [top is right]
828 ST_FUNC void vrott(int n)
830 vrote(vtop, n);
833 /* push a symbol value of TYPE */
834 static inline void vpushsym(CType *type, Sym *sym)
836 CValue cval;
837 cval.i = 0;
838 vsetc(type, VT_CONST | VT_SYM, &cval);
839 vtop->sym = sym;
842 /* Return a static symbol pointing to a section */
843 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
845 int v;
846 Sym *sym;
848 v = anon_sym++;
849 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
850 sym->type.ref = type->ref;
851 sym->r = VT_CONST | VT_SYM;
852 put_extern_sym(sym, sec, offset, size);
853 return sym;
856 /* push a reference to a section offset by adding a dummy symbol */
857 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
859 vpushsym(type, get_sym_ref(type, sec, offset, size));
862 /* define a new external reference to a symbol 'v' of type 'u' */
863 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
865 Sym *s;
867 s = sym_find(v);
868 if (!s) {
869 /* push forward reference */
870 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
871 s->type.ref = type->ref;
872 s->r = r | VT_CONST | VT_SYM;
873 } else if (IS_ASM_SYM(s)) {
874 s->type.t = type->t | (s->type.t & VT_EXTERN);
875 s->type.ref = type->ref;
876 update_storage(s);
878 return s;
881 /* Merge symbol attributes. */
882 static void merge_symattr(struct SymAttr *sa, struct SymAttr *sa1)
884 if (sa1->aligned && !sa->aligned)
885 sa->aligned = sa1->aligned;
886 sa->packed |= sa1->packed;
887 sa->weak |= sa1->weak;
888 if (sa1->visibility != STV_DEFAULT) {
889 int vis = sa->visibility;
890 if (vis == STV_DEFAULT
891 || vis > sa1->visibility)
892 vis = sa1->visibility;
893 sa->visibility = vis;
895 sa->dllexport |= sa1->dllexport;
896 sa->nodecorate |= sa1->nodecorate;
897 sa->dllimport |= sa1->dllimport;
900 /* Merge function attributes. */
901 static void merge_funcattr(struct FuncAttr *fa, struct FuncAttr *fa1)
903 if (fa1->func_call && !fa->func_call)
904 fa->func_call = fa1->func_call;
905 if (fa1->func_type && !fa->func_type)
906 fa->func_type = fa1->func_type;
907 if (fa1->func_args && !fa->func_args)
908 fa->func_args = fa1->func_args;
911 /* Merge attributes. */
912 static void merge_attr(AttributeDef *ad, AttributeDef *ad1)
914 merge_symattr(&ad->a, &ad1->a);
915 merge_funcattr(&ad->f, &ad1->f);
917 if (ad1->section)
918 ad->section = ad1->section;
919 if (ad1->alias_target)
920 ad->alias_target = ad1->alias_target;
921 if (ad1->asm_label)
922 ad->asm_label = ad1->asm_label;
923 if (ad1->attr_mode)
924 ad->attr_mode = ad1->attr_mode;
927 /* Merge some type attributes. */
928 static void patch_type(Sym *sym, CType *type)
930 if (!(type->t & VT_EXTERN) || IS_ENUM_VAL(sym->type.t)) {
931 if (!(sym->type.t & VT_EXTERN))
932 tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
933 sym->type.t &= ~VT_EXTERN;
936 if (IS_ASM_SYM(sym)) {
937 /* stay static if both are static */
938 sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
939 sym->type.ref = type->ref;
942 if (!is_compatible_types(&sym->type, type)) {
943 tcc_error("incompatible types for redefinition of '%s'",
944 get_tok_str(sym->v, NULL));
946 } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
947 int static_proto = sym->type.t & VT_STATIC;
948 /* warn if static follows non-static function declaration */
949 if ((type->t & VT_STATIC) && !static_proto && !(type->t & VT_INLINE))
950 tcc_warning("static storage ignored for redefinition of '%s'",
951 get_tok_str(sym->v, NULL));
953 if (0 == (type->t & VT_EXTERN)) {
954 /* put complete type, use static from prototype */
955 sym->type.t = (type->t & ~VT_STATIC) | static_proto;
956 if (type->t & VT_INLINE)
957 sym->type.t = type->t;
958 sym->type.ref = type->ref;
961 } else {
962 if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
963 /* set array size if it was omitted in extern declaration */
964 if (sym->type.ref->c < 0)
965 sym->type.ref->c = type->ref->c;
966 else if (sym->type.ref->c != type->ref->c)
967 tcc_error("conflicting type for '%s'", get_tok_str(sym->v, NULL));
969 if ((type->t ^ sym->type.t) & VT_STATIC)
970 tcc_warning("storage mismatch for redefinition of '%s'",
971 get_tok_str(sym->v, NULL));
976 /* Merge some storage attributes. */
977 static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
979 if (type)
980 patch_type(sym, type);
982 #ifdef TCC_TARGET_PE
983 if (sym->a.dllimport != ad->a.dllimport)
984 tcc_error("incompatible dll linkage for redefinition of '%s'",
985 get_tok_str(sym->v, NULL));
986 #endif
987 merge_symattr(&sym->a, &ad->a);
988 if (ad->asm_label)
989 sym->asm_label = ad->asm_label;
990 update_storage(sym);
993 /* define a new external reference to a symbol 'v' */
994 static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
996 Sym *s;
997 s = sym_find(v);
998 if (!s || (!IS_ASM_SYM(s) && !(s->type.t & VT_EXTERN)
999 && (s->type.t & VT_BTYPE) != VT_FUNC)) {
1000 if (s && !is_compatible_types(&s->type, type))
1001 tcc_error("conflicting types for '%s'", get_tok_str(s->v, NULL));
1002 /* push forward reference */
1003 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
1004 s->type.t |= VT_EXTERN;
1005 s->a = ad->a;
1006 s->sym_scope = 0;
1007 } else {
1008 if (s->type.ref == func_old_type.ref) {
1009 s->type.ref = type->ref;
1010 s->r = r | VT_CONST | VT_SYM;
1011 s->type.t |= VT_EXTERN;
1013 patch_storage(s, ad, type);
1015 return s;
1018 /* push a reference to global symbol v */
1019 ST_FUNC void vpush_global_sym(CType *type, int v)
1021 vpushsym(type, external_global_sym(v, type, 0));
1024 /* save registers up to (vtop - n) stack entry */
1025 ST_FUNC void save_regs(int n)
1027 SValue *p, *p1;
1028 for(p = vstack, p1 = vtop - n; p <= p1; p++)
1029 save_reg(p->r);
1032 /* save r to the memory stack, and mark it as being free */
1033 ST_FUNC void save_reg(int r)
1035 save_reg_upstack(r, 0);
1038 /* save r to the memory stack, and mark it as being free,
1039 if seen up to (vtop - n) stack entry */
1040 ST_FUNC void save_reg_upstack(int r, int n)
1042 int l, saved, size, align;
1043 SValue *p, *p1, sv;
1044 CType *type;
1046 if ((r &= VT_VALMASK) >= VT_CONST)
1047 return;
1048 if (nocode_wanted)
1049 return;
1051 /* modify all stack values */
1052 saved = 0;
1053 l = 0;
1054 for(p = vstack, p1 = vtop - n; p <= p1; p++) {
1055 if ((p->r & VT_VALMASK) == r ||
1056 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
1057 /* must save value on stack if not already done */
1058 if (!saved) {
1059 /* NOTE: must reload 'r' because r might be equal to r2 */
1060 r = p->r & VT_VALMASK;
1061 /* store register in the stack */
1062 type = &p->type;
1063 if ((p->r & VT_LVAL) ||
1064 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
1065 #if PTR_SIZE == 8
1066 type = &char_pointer_type;
1067 #else
1068 type = &int_type;
1069 #endif
1070 size = type_size(type, &align);
1071 l=get_temp_local_var(size,align);
1072 sv.type.t = type->t;
1073 sv.r = VT_LOCAL | VT_LVAL;
1074 sv.c.i = l;
1075 store(r, &sv);
1076 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1077 /* x86 specific: need to pop fp register ST0 if saved */
1078 if (r == TREG_ST0) {
1079 o(0xd8dd); /* fstp %st(0) */
1081 #endif
1082 #if PTR_SIZE == 4
1083 /* special long long case */
1084 if ((type->t & VT_BTYPE) == VT_LLONG) {
1085 sv.c.i += 4;
1086 store(p->r2, &sv);
1088 #endif
1089 saved = 1;
1091 /* mark that stack entry as being saved on the stack */
1092 if (p->r & VT_LVAL) {
1093 /* also clear the bounded flag because the
1094 relocation address of the function was stored in
1095 p->c.i */
1096 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
1097 } else {
1098 p->r = lvalue_type(p->type.t) | VT_LOCAL;
1100 p->r2 = VT_CONST;
1101 p->c.i = l;
1106 #ifdef TCC_TARGET_ARM
1107 /* find a register of class 'rc2' with at most one reference on stack.
1108 * If none, call get_reg(rc) */
1109 ST_FUNC int get_reg_ex(int rc, int rc2)
1111 int r;
1112 SValue *p;
1114 for(r=0;r<NB_REGS;r++) {
1115 if (reg_classes[r] & rc2) {
1116 int n;
1117 n=0;
1118 for(p = vstack; p <= vtop; p++) {
1119 if ((p->r & VT_VALMASK) == r ||
1120 (p->r2 & VT_VALMASK) == r)
1121 n++;
1123 if (n <= 1)
1124 return r;
1127 return get_reg(rc);
1129 #endif
1131 /* find a free register of class 'rc'. If none, save one register */
1132 ST_FUNC int get_reg(int rc)
1134 int r;
1135 SValue *p;
1137 /* find a free register */
1138 for(r=0;r<NB_REGS;r++) {
1139 if (reg_classes[r] & rc) {
1140 if (nocode_wanted)
1141 return r;
1142 for(p=vstack;p<=vtop;p++) {
1143 if ((p->r & VT_VALMASK) == r ||
1144 (p->r2 & VT_VALMASK) == r)
1145 goto notfound;
1147 return r;
1149 notfound: ;
1152 /* no register left : free the first one on the stack (VERY
1153 IMPORTANT to start from the bottom to ensure that we don't
1154 spill registers used in gen_opi()) */
1155 for(p=vstack;p<=vtop;p++) {
1156 /* look at second register (if long long) */
1157 r = p->r2 & VT_VALMASK;
1158 if (r < VT_CONST && (reg_classes[r] & rc))
1159 goto save_found;
1160 r = p->r & VT_VALMASK;
1161 if (r < VT_CONST && (reg_classes[r] & rc)) {
1162 save_found:
1163 save_reg(r);
1164 return r;
1167 /* Should never comes here */
1168 return -1;
1171 /* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1172 static int get_temp_local_var(int size,int align){
1173 int i;
1174 struct temp_local_variable *temp_var;
1175 int found_var;
1176 SValue *p;
1177 int r;
1178 char free;
1179 char found;
1180 found=0;
1181 for(i=0;i<nb_temp_local_vars;i++){
1182 temp_var=&arr_temp_local_vars[i];
1183 if(temp_var->size<size||align!=temp_var->align){
1184 continue;
1186 /*check if temp_var is free*/
1187 free=1;
1188 for(p=vstack;p<=vtop;p++) {
1189 r=p->r&VT_VALMASK;
1190 if(r==VT_LOCAL||r==VT_LLOCAL){
1191 if(p->c.i==temp_var->location){
1192 free=0;
1193 break;
1197 if(free){
1198 found_var=temp_var->location;
1199 found=1;
1200 break;
1203 if(!found){
1204 loc = (loc - size) & -align;
1205 if(nb_temp_local_vars<MAX_TEMP_LOCAL_VARIABLE_NUMBER){
1206 temp_var=&arr_temp_local_vars[i];
1207 temp_var->location=loc;
1208 temp_var->size=size;
1209 temp_var->align=align;
1210 nb_temp_local_vars++;
1212 found_var=loc;
1214 return found_var;
1217 static void clear_temp_local_var_list(){
1218 nb_temp_local_vars=0;
1221 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
1222 if needed */
1223 static void move_reg(int r, int s, int t)
1225 SValue sv;
1227 if (r != s) {
1228 save_reg(r);
1229 sv.type.t = t;
1230 sv.type.ref = NULL;
1231 sv.r = s;
1232 sv.c.i = 0;
1233 load(r, &sv);
1237 /* get address of vtop (vtop MUST BE an lvalue) */
1238 ST_FUNC void gaddrof(void)
1240 vtop->r &= ~VT_LVAL;
1241 /* tricky: if saved lvalue, then we can go back to lvalue */
1242 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
1243 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
1248 #ifdef CONFIG_TCC_BCHECK
1249 /* generate lvalue bound code */
1250 static void gbound(void)
1252 int lval_type;
1253 CType type1;
1255 vtop->r &= ~VT_MUSTBOUND;
1256 /* if lvalue, then use checking code before dereferencing */
1257 if (vtop->r & VT_LVAL) {
1258 /* if not VT_BOUNDED value, then make one */
1259 if (!(vtop->r & VT_BOUNDED)) {
1260 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
1261 /* must save type because we must set it to int to get pointer */
1262 type1 = vtop->type;
1263 vtop->type.t = VT_PTR;
1264 gaddrof();
1265 vpushi(0);
1266 gen_bounded_ptr_add();
1267 vtop->r |= lval_type;
1268 vtop->type = type1;
1270 /* then check for dereferencing */
1271 gen_bounded_ptr_deref();
1274 #endif
1276 static void incr_bf_adr(int o)
1278 vtop->type = char_pointer_type;
1279 gaddrof();
1280 vpushi(o);
1281 gen_op('+');
1282 vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN))
1283 | (VT_BYTE|VT_UNSIGNED);
1284 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1285 | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL);
1288 /* single-byte load mode for packed or otherwise unaligned bitfields */
1289 static void load_packed_bf(CType *type, int bit_pos, int bit_size)
1291 int n, o, bits;
1292 save_reg_upstack(vtop->r, 1);
1293 vpush64(type->t & VT_BTYPE, 0); // B X
1294 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
1295 do {
1296 vswap(); // X B
1297 incr_bf_adr(o);
1298 vdup(); // X B B
1299 n = 8 - bit_pos;
1300 if (n > bit_size)
1301 n = bit_size;
1302 if (bit_pos)
1303 vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
1304 if (n < 8)
1305 vpushi((1 << n) - 1), gen_op('&');
1306 gen_cast(type);
1307 if (bits)
1308 vpushi(bits), gen_op(TOK_SHL);
1309 vrotb(3); // B Y X
1310 gen_op('|'); // B X
1311 bits += n, bit_size -= n, o = 1;
1312 } while (bit_size);
1313 vswap(), vpop();
1314 if (!(type->t & VT_UNSIGNED)) {
1315 n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
1316 vpushi(n), gen_op(TOK_SHL);
1317 vpushi(n), gen_op(TOK_SAR);
1321 /* single-byte store mode for packed or otherwise unaligned bitfields */
1322 static void store_packed_bf(int bit_pos, int bit_size)
1324 int bits, n, o, m, c;
1326 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1327 vswap(); // X B
1328 save_reg_upstack(vtop->r, 1);
1329 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
1330 do {
1331 incr_bf_adr(o); // X B
1332 vswap(); //B X
1333 c ? vdup() : gv_dup(); // B V X
1334 vrott(3); // X B V
1335 if (bits)
1336 vpushi(bits), gen_op(TOK_SHR);
1337 if (bit_pos)
1338 vpushi(bit_pos), gen_op(TOK_SHL);
1339 n = 8 - bit_pos;
1340 if (n > bit_size)
1341 n = bit_size;
1342 if (n < 8) {
1343 m = ((1 << n) - 1) << bit_pos;
1344 vpushi(m), gen_op('&'); // X B V1
1345 vpushv(vtop-1); // X B V1 B
1346 vpushi(m & 0x80 ? ~m & 0x7f : ~m);
1347 gen_op('&'); // X B V1 B1
1348 gen_op('|'); // X B V2
1350 vdup(), vtop[-1] = vtop[-2]; // X B B V2
1351 vstore(), vpop(); // X B
1352 bits += n, bit_size -= n, bit_pos = 0, o = 1;
1353 } while (bit_size);
1354 vpop(), vpop();
1357 static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
1359 int t;
1360 if (0 == sv->type.ref)
1361 return 0;
1362 t = sv->type.ref->auxtype;
1363 if (t != -1 && t != VT_STRUCT) {
1364 sv->type.t = (sv->type.t & ~VT_BTYPE) | t;
1365 sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t);
1367 return t;
1370 /* store vtop a register belonging to class 'rc'. lvalues are
1371 converted to values. Cannot be used if cannot be converted to
1372 register value (such as structures). */
1373 ST_FUNC int gv(int rc)
1375 int r, bit_pos, bit_size, size, align, rc2;
1377 /* NOTE: get_reg can modify vstack[] */
1378 if (vtop->type.t & VT_BITFIELD) {
1379 CType type;
1381 bit_pos = BIT_POS(vtop->type.t);
1382 bit_size = BIT_SIZE(vtop->type.t);
1383 /* remove bit field info to avoid loops */
1384 vtop->type.t &= ~VT_STRUCT_MASK;
1386 type.ref = NULL;
1387 type.t = vtop->type.t & VT_UNSIGNED;
1388 if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
1389 type.t |= VT_UNSIGNED;
1391 r = adjust_bf(vtop, bit_pos, bit_size);
1393 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
1394 type.t |= VT_LLONG;
1395 else
1396 type.t |= VT_INT;
1398 if (r == VT_STRUCT) {
1399 load_packed_bf(&type, bit_pos, bit_size);
1400 } else {
1401 int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
1402 /* cast to int to propagate signedness in following ops */
1403 gen_cast(&type);
1404 /* generate shifts */
1405 vpushi(bits - (bit_pos + bit_size));
1406 gen_op(TOK_SHL);
1407 vpushi(bits - bit_size);
1408 /* NOTE: transformed to SHR if unsigned */
1409 gen_op(TOK_SAR);
1411 r = gv(rc);
1412 } else {
1413 if (is_float(vtop->type.t) &&
1414 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1415 unsigned long offset;
1416 /* CPUs usually cannot use float constants, so we store them
1417 generically in data segment */
1418 size = type_size(&vtop->type, &align);
1419 if (NODATA_WANTED)
1420 size = 0, align = 1;
1421 offset = section_add(data_section, size, align);
1422 vpush_ref(&vtop->type, data_section, offset, size);
1423 vswap();
1424 init_putv(&vtop->type, data_section, offset);
1425 vtop->r |= VT_LVAL;
1427 #ifdef CONFIG_TCC_BCHECK
1428 if (vtop->r & VT_MUSTBOUND)
1429 gbound();
1430 #endif
1432 r = vtop->r & VT_VALMASK;
1433 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
1434 #ifndef TCC_TARGET_ARM64
1435 if (rc == RC_IRET)
1436 rc2 = RC_LRET;
1437 #ifdef TCC_TARGET_X86_64
1438 else if (rc == RC_FRET)
1439 rc2 = RC_QRET;
1440 #endif
1441 #endif
1442 /* need to reload if:
1443 - constant
1444 - lvalue (need to dereference pointer)
1445 - already a register, but not in the right class */
1446 if (r >= VT_CONST
1447 || (vtop->r & VT_LVAL)
1448 || !(reg_classes[r] & rc)
1449 #if PTR_SIZE == 8
1450 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
1451 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
1452 #else
1453 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
1454 #endif
1457 r = get_reg(rc);
1458 #if PTR_SIZE == 8
1459 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
1460 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
1461 #else
1462 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
1463 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
1464 unsigned long long ll;
1465 #endif
1466 int r2, original_type;
1467 original_type = vtop->type.t;
1468 /* two register type load : expand to two words
1469 temporarily */
1470 #if PTR_SIZE == 4
1471 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1472 /* load constant */
1473 ll = vtop->c.i;
1474 vtop->c.i = ll; /* first word */
1475 load(r, vtop);
1476 vtop->r = r; /* save register value */
1477 vpushi(ll >> 32); /* second word */
1478 } else
1479 #endif
1480 if (vtop->r & VT_LVAL) {
1481 /* We do not want to modifier the long long
1482 pointer here, so the safest (and less
1483 efficient) is to save all the other registers
1484 in the stack. XXX: totally inefficient. */
1485 #if 0
1486 save_regs(1);
1487 #else
1488 /* lvalue_save: save only if used further down the stack */
1489 save_reg_upstack(vtop->r, 1);
1490 #endif
1491 /* load from memory */
1492 vtop->type.t = load_type;
1493 load(r, vtop);
1494 vdup();
1495 vtop[-1].r = r; /* save register value */
1496 /* increment pointer to get second word */
1497 vtop->type.t = addr_type;
1498 gaddrof();
1499 vpushi(load_size);
1500 gen_op('+');
1501 vtop->r |= VT_LVAL;
1502 vtop->type.t = load_type;
1503 } else {
1504 /* move registers */
1505 load(r, vtop);
1506 vdup();
1507 vtop[-1].r = r; /* save register value */
1508 vtop->r = vtop[-1].r2;
1510 /* Allocate second register. Here we rely on the fact that
1511 get_reg() tries first to free r2 of an SValue. */
1512 r2 = get_reg(rc2);
1513 load(r2, vtop);
1514 vpop();
1515 /* write second register */
1516 vtop->r2 = r2;
1517 vtop->type.t = original_type;
1518 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
1519 int t1, t;
1520 /* lvalue of scalar type : need to use lvalue type
1521 because of possible cast */
1522 t = vtop->type.t;
1523 t1 = t;
1524 /* compute memory access type */
1525 if (vtop->r & VT_LVAL_BYTE)
1526 t = VT_BYTE;
1527 else if (vtop->r & VT_LVAL_SHORT)
1528 t = VT_SHORT;
1529 if (vtop->r & VT_LVAL_UNSIGNED)
1530 t |= VT_UNSIGNED;
1531 vtop->type.t = t;
1532 load(r, vtop);
1533 /* restore wanted type */
1534 vtop->type.t = t1;
1535 } else {
1536 /* one register type load */
1537 load(r, vtop);
1540 vtop->r = r;
1541 #ifdef TCC_TARGET_C67
1542 /* uses register pairs for doubles */
1543 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
1544 vtop->r2 = r+1;
1545 #endif
1547 return r;
1550 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
1551 ST_FUNC void gv2(int rc1, int rc2)
1553 int v;
1555 /* generate more generic register first. But VT_JMP or VT_CMP
1556 values must be generated first in all cases to avoid possible
1557 reload errors */
1558 v = vtop[0].r & VT_VALMASK;
1559 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
1560 vswap();
1561 gv(rc1);
1562 vswap();
1563 gv(rc2);
1564 /* test if reload is needed for first register */
1565 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1566 vswap();
1567 gv(rc1);
1568 vswap();
1570 } else {
1571 gv(rc2);
1572 vswap();
1573 gv(rc1);
1574 vswap();
1575 /* test if reload is needed for first register */
1576 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
1577 gv(rc2);
1582 #ifndef TCC_TARGET_ARM64
1583 /* wrapper around RC_FRET to return a register by type */
1584 static int rc_fret(int t)
1586 #ifdef TCC_TARGET_X86_64
1587 if (t == VT_LDOUBLE) {
1588 return RC_ST0;
1590 #endif
1591 return RC_FRET;
1593 #endif
1595 /* wrapper around REG_FRET to return a register by type */
1596 static int reg_fret(int t)
1598 #ifdef TCC_TARGET_X86_64
1599 if (t == VT_LDOUBLE) {
1600 return TREG_ST0;
1602 #endif
1603 return REG_FRET;
1606 #if PTR_SIZE == 4
1607 /* expand 64bit on stack in two ints */
1608 ST_FUNC void lexpand(void)
1610 int u, v;
1611 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1612 v = vtop->r & (VT_VALMASK | VT_LVAL);
1613 if (v == VT_CONST) {
1614 vdup();
1615 vtop[0].c.i >>= 32;
1616 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1617 vdup();
1618 vtop[0].c.i += 4;
1619 } else {
1620 gv(RC_INT);
1621 vdup();
1622 vtop[0].r = vtop[-1].r2;
1623 vtop[0].r2 = vtop[-1].r2 = VT_CONST;
1625 vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
1627 #endif
1629 #if PTR_SIZE == 4
1630 /* build a long long from two ints */
1631 static void lbuild(int t)
1633 gv2(RC_INT, RC_INT);
1634 vtop[-1].r2 = vtop[0].r;
1635 vtop[-1].type.t = t;
1636 vpop();
1638 #endif
1640 /* convert stack entry to register and duplicate its value in another
1641 register */
1642 static void gv_dup(void)
1644 int rc, t, r, r1;
1645 SValue sv;
1647 t = vtop->type.t;
1648 #if PTR_SIZE == 4
1649 if ((t & VT_BTYPE) == VT_LLONG) {
1650 if (t & VT_BITFIELD) {
1651 gv(RC_INT);
1652 t = vtop->type.t;
1654 lexpand();
1655 gv_dup();
1656 vswap();
1657 vrotb(3);
1658 gv_dup();
1659 vrotb(4);
1660 /* stack: H L L1 H1 */
1661 lbuild(t);
1662 vrotb(3);
1663 vrotb(3);
1664 vswap();
1665 lbuild(t);
1666 vswap();
1667 } else
1668 #endif
1670 /* duplicate value */
1671 rc = RC_INT;
1672 sv.type.t = VT_INT;
1673 if (is_float(t)) {
1674 rc = RC_FLOAT;
1675 #ifdef TCC_TARGET_X86_64
1676 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1677 rc = RC_ST0;
1679 #endif
1680 sv.type.t = t;
1682 r = gv(rc);
1683 r1 = get_reg(rc);
1684 sv.r = r;
1685 sv.c.i = 0;
1686 load(r1, &sv); /* move r to r1 */
1687 vdup();
1688 /* duplicates value */
1689 if (r != r1)
1690 vtop->r = r1;
1694 /* Generate value test
1696 * Generate a test for any value (jump, comparison and integers) */
1697 ST_FUNC int gvtst(int inv, int t)
1699 int v = vtop->r & VT_VALMASK;
1700 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1701 vpushi(0);
1702 gen_op(TOK_NE);
1704 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1705 /* constant jmp optimization */
1706 if ((vtop->c.i != 0) != inv)
1707 t = gjmp(t);
1708 vtop--;
1709 return t;
1711 return gtst(inv, t);
1714 #if PTR_SIZE == 4
1715 /* generate CPU independent (unsigned) long long operations */
1716 static void gen_opl(int op)
1718 int t, a, b, op1, c, i;
1719 int func;
1720 unsigned short reg_iret = REG_IRET;
1721 unsigned short reg_lret = REG_LRET;
1722 SValue tmp;
1724 switch(op) {
1725 case '/':
1726 case TOK_PDIV:
1727 func = TOK___divdi3;
1728 goto gen_func;
1729 case TOK_UDIV:
1730 func = TOK___udivdi3;
1731 goto gen_func;
1732 case '%':
1733 func = TOK___moddi3;
1734 goto gen_mod_func;
1735 case TOK_UMOD:
1736 func = TOK___umoddi3;
1737 gen_mod_func:
1738 #ifdef TCC_ARM_EABI
1739 reg_iret = TREG_R2;
1740 reg_lret = TREG_R3;
1741 #endif
1742 gen_func:
1743 /* call generic long long function */
1744 vpush_global_sym(&func_old_type, func);
1745 vrott(3);
1746 gfunc_call(2);
1747 vpushi(0);
1748 vtop->r = reg_iret;
1749 vtop->r2 = reg_lret;
1750 break;
1751 case '^':
1752 case '&':
1753 case '|':
1754 case '*':
1755 case '+':
1756 case '-':
1757 //pv("gen_opl A",0,2);
1758 t = vtop->type.t;
1759 vswap();
1760 lexpand();
1761 vrotb(3);
1762 lexpand();
1763 /* stack: L1 H1 L2 H2 */
1764 tmp = vtop[0];
1765 vtop[0] = vtop[-3];
1766 vtop[-3] = tmp;
1767 tmp = vtop[-2];
1768 vtop[-2] = vtop[-3];
1769 vtop[-3] = tmp;
1770 vswap();
1771 /* stack: H1 H2 L1 L2 */
1772 //pv("gen_opl B",0,4);
1773 if (op == '*') {
1774 vpushv(vtop - 1);
1775 vpushv(vtop - 1);
1776 gen_op(TOK_UMULL);
1777 lexpand();
1778 /* stack: H1 H2 L1 L2 ML MH */
1779 for(i=0;i<4;i++)
1780 vrotb(6);
1781 /* stack: ML MH H1 H2 L1 L2 */
1782 tmp = vtop[0];
1783 vtop[0] = vtop[-2];
1784 vtop[-2] = tmp;
1785 /* stack: ML MH H1 L2 H2 L1 */
1786 gen_op('*');
1787 vrotb(3);
1788 vrotb(3);
1789 gen_op('*');
1790 /* stack: ML MH M1 M2 */
1791 gen_op('+');
1792 gen_op('+');
1793 } else if (op == '+' || op == '-') {
1794 /* XXX: add non carry method too (for MIPS or alpha) */
1795 if (op == '+')
1796 op1 = TOK_ADDC1;
1797 else
1798 op1 = TOK_SUBC1;
1799 gen_op(op1);
1800 /* stack: H1 H2 (L1 op L2) */
1801 vrotb(3);
1802 vrotb(3);
1803 gen_op(op1 + 1); /* TOK_xxxC2 */
1804 } else {
1805 gen_op(op);
1806 /* stack: H1 H2 (L1 op L2) */
1807 vrotb(3);
1808 vrotb(3);
1809 /* stack: (L1 op L2) H1 H2 */
1810 gen_op(op);
1811 /* stack: (L1 op L2) (H1 op H2) */
1813 /* stack: L H */
1814 lbuild(t);
1815 break;
1816 case TOK_SAR:
1817 case TOK_SHR:
1818 case TOK_SHL:
1819 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1820 t = vtop[-1].type.t;
1821 vswap();
1822 lexpand();
1823 vrotb(3);
1824 /* stack: L H shift */
1825 c = (int)vtop->c.i;
1826 /* constant: simpler */
1827 /* NOTE: all comments are for SHL. the other cases are
1828 done by swapping words */
1829 vpop();
1830 if (op != TOK_SHL)
1831 vswap();
1832 if (c >= 32) {
1833 /* stack: L H */
1834 vpop();
1835 if (c > 32) {
1836 vpushi(c - 32);
1837 gen_op(op);
1839 if (op != TOK_SAR) {
1840 vpushi(0);
1841 } else {
1842 gv_dup();
1843 vpushi(31);
1844 gen_op(TOK_SAR);
1846 vswap();
1847 } else {
1848 vswap();
1849 gv_dup();
1850 /* stack: H L L */
1851 vpushi(c);
1852 gen_op(op);
1853 vswap();
1854 vpushi(32 - c);
1855 if (op == TOK_SHL)
1856 gen_op(TOK_SHR);
1857 else
1858 gen_op(TOK_SHL);
1859 vrotb(3);
1860 /* stack: L L H */
1861 vpushi(c);
1862 if (op == TOK_SHL)
1863 gen_op(TOK_SHL);
1864 else
1865 gen_op(TOK_SHR);
1866 gen_op('|');
1868 if (op != TOK_SHL)
1869 vswap();
1870 lbuild(t);
1871 } else {
1872 /* XXX: should provide a faster fallback on x86 ? */
1873 switch(op) {
1874 case TOK_SAR:
1875 func = TOK___ashrdi3;
1876 goto gen_func;
1877 case TOK_SHR:
1878 func = TOK___lshrdi3;
1879 goto gen_func;
1880 case TOK_SHL:
1881 func = TOK___ashldi3;
1882 goto gen_func;
1885 break;
1886 default:
1887 /* compare operations */
1888 t = vtop->type.t;
1889 vswap();
1890 lexpand();
1891 vrotb(3);
1892 lexpand();
1893 /* stack: L1 H1 L2 H2 */
1894 tmp = vtop[-1];
1895 vtop[-1] = vtop[-2];
1896 vtop[-2] = tmp;
1897 /* stack: L1 L2 H1 H2 */
1898 /* compare high */
1899 op1 = op;
1900 /* when values are equal, we need to compare low words. since
1901 the jump is inverted, we invert the test too. */
1902 if (op1 == TOK_LT)
1903 op1 = TOK_LE;
1904 else if (op1 == TOK_GT)
1905 op1 = TOK_GE;
1906 else if (op1 == TOK_ULT)
1907 op1 = TOK_ULE;
1908 else if (op1 == TOK_UGT)
1909 op1 = TOK_UGE;
1910 a = 0;
1911 b = 0;
1912 gen_op(op1);
1913 if (op == TOK_NE) {
1914 b = gvtst(0, 0);
1915 } else {
1916 a = gvtst(1, 0);
1917 if (op != TOK_EQ) {
1918 /* generate non equal test */
1919 vpushi(TOK_NE);
1920 vtop->r = VT_CMP;
1921 b = gvtst(0, 0);
1924 /* compare low. Always unsigned */
1925 op1 = op;
1926 if (op1 == TOK_LT)
1927 op1 = TOK_ULT;
1928 else if (op1 == TOK_LE)
1929 op1 = TOK_ULE;
1930 else if (op1 == TOK_GT)
1931 op1 = TOK_UGT;
1932 else if (op1 == TOK_GE)
1933 op1 = TOK_UGE;
1934 gen_op(op1);
1935 a = gvtst(1, a);
1936 gsym(b);
1937 vseti(VT_JMPI, a);
1938 break;
1941 #endif
1943 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
1945 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
1946 return (a ^ b) >> 63 ? -x : x;
1949 static int gen_opic_lt(uint64_t a, uint64_t b)
1951 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
1954 /* handle integer constant optimizations and various machine
1955 independent opt */
1956 static void gen_opic(int op)
1958 SValue *v1 = vtop - 1;
1959 SValue *v2 = vtop;
1960 int t1 = v1->type.t & VT_BTYPE;
1961 int t2 = v2->type.t & VT_BTYPE;
1962 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1963 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1964 uint64_t l1 = c1 ? v1->c.i : 0;
1965 uint64_t l2 = c2 ? v2->c.i : 0;
1966 int shm = (t1 == VT_LLONG) ? 63 : 31;
1968 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
1969 l1 = ((uint32_t)l1 |
1970 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
1971 if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
1972 l2 = ((uint32_t)l2 |
1973 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
1975 if (c1 && c2) {
1976 switch(op) {
1977 case '+': l1 += l2; break;
1978 case '-': l1 -= l2; break;
1979 case '&': l1 &= l2; break;
1980 case '^': l1 ^= l2; break;
1981 case '|': l1 |= l2; break;
1982 case '*': l1 *= l2; break;
1984 case TOK_PDIV:
1985 case '/':
1986 case '%':
1987 case TOK_UDIV:
1988 case TOK_UMOD:
1989 /* if division by zero, generate explicit division */
1990 if (l2 == 0) {
1991 if (const_wanted)
1992 tcc_error("division by zero in constant");
1993 goto general_case;
1995 switch(op) {
1996 default: l1 = gen_opic_sdiv(l1, l2); break;
1997 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
1998 case TOK_UDIV: l1 = l1 / l2; break;
1999 case TOK_UMOD: l1 = l1 % l2; break;
2001 break;
2002 case TOK_SHL: l1 <<= (l2 & shm); break;
2003 case TOK_SHR: l1 >>= (l2 & shm); break;
2004 case TOK_SAR:
2005 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
2006 break;
2007 /* tests */
2008 case TOK_ULT: l1 = l1 < l2; break;
2009 case TOK_UGE: l1 = l1 >= l2; break;
2010 case TOK_EQ: l1 = l1 == l2; break;
2011 case TOK_NE: l1 = l1 != l2; break;
2012 case TOK_ULE: l1 = l1 <= l2; break;
2013 case TOK_UGT: l1 = l1 > l2; break;
2014 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
2015 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
2016 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
2017 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
2018 /* logical */
2019 case TOK_LAND: l1 = l1 && l2; break;
2020 case TOK_LOR: l1 = l1 || l2; break;
2021 default:
2022 goto general_case;
2024 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
2025 l1 = ((uint32_t)l1 |
2026 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
2027 v1->c.i = l1;
2028 vtop--;
2029 } else {
2030 /* if commutative ops, put c2 as constant */
2031 if (c1 && (op == '+' || op == '&' || op == '^' ||
2032 op == '|' || op == '*')) {
2033 vswap();
2034 c2 = c1; //c = c1, c1 = c2, c2 = c;
2035 l2 = l1; //l = l1, l1 = l2, l2 = l;
2037 if (!const_wanted &&
2038 c1 && ((l1 == 0 &&
2039 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
2040 (l1 == -1 && op == TOK_SAR))) {
2041 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2042 vtop--;
2043 } else if (!const_wanted &&
2044 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
2045 (op == '|' &&
2046 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
2047 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
2048 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
2049 if (l2 == 1)
2050 vtop->c.i = 0;
2051 vswap();
2052 vtop--;
2053 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
2054 op == TOK_PDIV) &&
2055 l2 == 1) ||
2056 ((op == '+' || op == '-' || op == '|' || op == '^' ||
2057 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
2058 l2 == 0) ||
2059 (op == '&' &&
2060 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
2061 /* filter out NOP operations like x*1, x-0, x&-1... */
2062 vtop--;
2063 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
2064 /* try to use shifts instead of muls or divs */
2065 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
2066 int n = -1;
2067 while (l2) {
2068 l2 >>= 1;
2069 n++;
2071 vtop->c.i = n;
2072 if (op == '*')
2073 op = TOK_SHL;
2074 else if (op == TOK_PDIV)
2075 op = TOK_SAR;
2076 else
2077 op = TOK_SHR;
2079 goto general_case;
2080 } else if (c2 && (op == '+' || op == '-') &&
2081 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
2082 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
2083 /* symbol + constant case */
2084 if (op == '-')
2085 l2 = -l2;
2086 l2 += vtop[-1].c.i;
2087 /* The backends can't always deal with addends to symbols
2088 larger than +-1<<31. Don't construct such. */
2089 if ((int)l2 != l2)
2090 goto general_case;
2091 vtop--;
2092 vtop->c.i = l2;
2093 } else {
2094 general_case:
2095 /* call low level op generator */
2096 if (t1 == VT_LLONG || t2 == VT_LLONG ||
2097 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
2098 gen_opl(op);
2099 else
2100 gen_opi(op);
2105 /* generate a floating point operation with constant propagation */
2106 static void gen_opif(int op)
2108 int c1, c2;
2109 SValue *v1, *v2;
2110 #if defined _MSC_VER && defined _AMD64_
2111 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
2112 volatile
2113 #endif
2114 long double f1, f2;
2116 v1 = vtop - 1;
2117 v2 = vtop;
2118 /* currently, we cannot do computations with forward symbols */
2119 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2120 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2121 if (c1 && c2) {
2122 if (v1->type.t == VT_FLOAT) {
2123 f1 = v1->c.f;
2124 f2 = v2->c.f;
2125 } else if (v1->type.t == VT_DOUBLE) {
2126 f1 = v1->c.d;
2127 f2 = v2->c.d;
2128 } else {
2129 f1 = v1->c.ld;
2130 f2 = v2->c.ld;
2133 /* NOTE: we only do constant propagation if finite number (not
2134 NaN or infinity) (ANSI spec) */
2135 if (!ieee_finite(f1) || !ieee_finite(f2))
2136 goto general_case;
2138 switch(op) {
2139 case '+': f1 += f2; break;
2140 case '-': f1 -= f2; break;
2141 case '*': f1 *= f2; break;
2142 case '/':
2143 if (f2 == 0.0) {
2144 /* If not in initializer we need to potentially generate
2145 FP exceptions at runtime, otherwise we want to fold. */
2146 if (!const_wanted)
2147 goto general_case;
2149 f1 /= f2;
2150 break;
2151 /* XXX: also handles tests ? */
2152 default:
2153 goto general_case;
2155 /* XXX: overflow test ? */
2156 if (v1->type.t == VT_FLOAT) {
2157 v1->c.f = f1;
2158 } else if (v1->type.t == VT_DOUBLE) {
2159 v1->c.d = f1;
2160 } else {
2161 v1->c.ld = f1;
2163 vtop--;
2164 } else {
2165 general_case:
2166 gen_opf(op);
2170 static int pointed_size(CType *type)
2172 int align;
2173 return type_size(pointed_type(type), &align);
2176 static void vla_runtime_pointed_size(CType *type)
2178 int align;
2179 vla_runtime_type_size(pointed_type(type), &align);
2182 static inline int is_null_pointer(SValue *p)
2184 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
2185 return 0;
2186 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
2187 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
2188 ((p->type.t & VT_BTYPE) == VT_PTR &&
2189 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0) &&
2190 ((pointed_type(&p->type)->t & VT_BTYPE) == VT_VOID) &&
2191 0 == (pointed_type(&p->type)->t & (VT_CONSTANT | VT_VOLATILE))
2194 static inline int is_integer_btype(int bt)
2196 return (bt == VT_BYTE || bt == VT_SHORT ||
2197 bt == VT_INT || bt == VT_LLONG);
2200 /* check types for comparison or subtraction of pointers */
2201 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
2203 CType *type1, *type2, tmp_type1, tmp_type2;
2204 int bt1, bt2;
2206 /* null pointers are accepted for all comparisons as gcc */
2207 if (is_null_pointer(p1) || is_null_pointer(p2))
2208 return;
2209 type1 = &p1->type;
2210 type2 = &p2->type;
2211 bt1 = type1->t & VT_BTYPE;
2212 bt2 = type2->t & VT_BTYPE;
2213 /* accept comparison between pointer and integer with a warning */
2214 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
2215 if (op != TOK_LOR && op != TOK_LAND )
2216 tcc_warning("comparison between pointer and integer");
2217 return;
2220 /* both must be pointers or implicit function pointers */
2221 if (bt1 == VT_PTR) {
2222 type1 = pointed_type(type1);
2223 } else if (bt1 != VT_FUNC)
2224 goto invalid_operands;
2226 if (bt2 == VT_PTR) {
2227 type2 = pointed_type(type2);
2228 } else if (bt2 != VT_FUNC) {
2229 invalid_operands:
2230 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
2232 if ((type1->t & VT_BTYPE) == VT_VOID ||
2233 (type2->t & VT_BTYPE) == VT_VOID)
2234 return;
2235 tmp_type1 = *type1;
2236 tmp_type2 = *type2;
2237 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2238 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2239 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2240 /* gcc-like error if '-' is used */
2241 if (op == '-')
2242 goto invalid_operands;
2243 else
2244 tcc_warning("comparison of distinct pointer types lacks a cast");
2248 /* generic gen_op: handles types problems */
2249 ST_FUNC void gen_op(int op)
2251 int u, t1, t2, bt1, bt2, t;
2252 CType type1;
2254 redo:
2255 t1 = vtop[-1].type.t;
2256 t2 = vtop[0].type.t;
2257 bt1 = t1 & VT_BTYPE;
2258 bt2 = t2 & VT_BTYPE;
2260 if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
2261 tcc_error("operation on a struct");
2262 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
2263 if (bt2 == VT_FUNC) {
2264 mk_pointer(&vtop->type);
2265 gaddrof();
2267 if (bt1 == VT_FUNC) {
2268 vswap();
2269 mk_pointer(&vtop->type);
2270 gaddrof();
2271 vswap();
2273 goto redo;
2274 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
2275 /* at least one operand is a pointer */
2276 /* relational op: must be both pointers */
2277 if (op >= TOK_ULT && op <= TOK_LOR) {
2278 check_comparison_pointer_types(vtop - 1, vtop, op);
2279 /* pointers are handled are unsigned */
2280 #if PTR_SIZE == 8
2281 t = VT_LLONG | VT_UNSIGNED;
2282 #else
2283 t = VT_INT | VT_UNSIGNED;
2284 #endif
2285 goto std_op;
2287 /* if both pointers, then it must be the '-' op */
2288 if (bt1 == VT_PTR && bt2 == VT_PTR) {
2289 if (op != '-')
2290 tcc_error("cannot use pointers here");
2291 check_comparison_pointer_types(vtop - 1, vtop, op);
2292 /* XXX: check that types are compatible */
2293 if (vtop[-1].type.t & VT_VLA) {
2294 vla_runtime_pointed_size(&vtop[-1].type);
2295 } else {
2296 vpushi(pointed_size(&vtop[-1].type));
2298 vrott(3);
2299 gen_opic(op);
2300 vtop->type.t = ptrdiff_type.t;
2301 vswap();
2302 gen_op(TOK_PDIV);
2303 } else {
2304 /* exactly one pointer : must be '+' or '-'. */
2305 if (op != '-' && op != '+')
2306 tcc_error("cannot use pointers here");
2307 /* Put pointer as first operand */
2308 if (bt2 == VT_PTR) {
2309 vswap();
2310 t = t1, t1 = t2, t2 = t;
2312 #if PTR_SIZE == 4
2313 if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
2314 /* XXX: truncate here because gen_opl can't handle ptr + long long */
2315 gen_cast_s(VT_INT);
2316 #endif
2317 type1 = vtop[-1].type;
2318 type1.t &= ~VT_ARRAY;
2319 if (vtop[-1].type.t & VT_VLA)
2320 vla_runtime_pointed_size(&vtop[-1].type);
2321 else {
2322 u = pointed_size(&vtop[-1].type);
2323 if (u < 0)
2324 tcc_error("unknown array element size");
2325 #if PTR_SIZE == 8
2326 vpushll(u);
2327 #else
2328 /* XXX: cast to int ? (long long case) */
2329 vpushi(u);
2330 #endif
2332 gen_op('*');
2333 #if 0
2334 /* #ifdef CONFIG_TCC_BCHECK
2335 The main reason to removing this code:
2336 #include <stdio.h>
2337 int main ()
2339 int v[10];
2340 int i = 10;
2341 int j = 9;
2342 fprintf(stderr, "v+i-j = %p\n", v+i-j);
2343 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
2345 When this code is on. then the output looks like
2346 v+i-j = 0xfffffffe
2347 v+(i-j) = 0xbff84000
2349 /* if evaluating constant expression, no code should be
2350 generated, so no bound check */
2351 if (tcc_state->do_bounds_check && !const_wanted) {
2352 /* if bounded pointers, we generate a special code to
2353 test bounds */
2354 if (op == '-') {
2355 vpushi(0);
2356 vswap();
2357 gen_op('-');
2359 gen_bounded_ptr_add();
2360 } else
2361 #endif
2363 gen_opic(op);
2365 /* put again type if gen_opic() swaped operands */
2366 vtop->type = type1;
2368 } else if (is_float(bt1) || is_float(bt2)) {
2369 /* compute bigger type and do implicit casts */
2370 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
2371 t = VT_LDOUBLE;
2372 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
2373 t = VT_DOUBLE;
2374 } else {
2375 t = VT_FLOAT;
2377 /* floats can only be used for a few operations */
2378 if (op != '+' && op != '-' && op != '*' && op != '/' &&
2379 (op < TOK_ULT || op > TOK_GT))
2380 tcc_error("invalid operands for binary operation");
2381 goto std_op;
2382 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
2383 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
2384 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
2385 t |= VT_UNSIGNED;
2386 t |= (VT_LONG & t1);
2387 goto std_op;
2388 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
2389 /* cast to biggest op */
2390 t = VT_LLONG | VT_LONG;
2391 if (bt1 == VT_LLONG)
2392 t &= t1;
2393 if (bt2 == VT_LLONG)
2394 t &= t2;
2395 /* convert to unsigned if it does not fit in a long long */
2396 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
2397 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
2398 t |= VT_UNSIGNED;
2399 goto std_op;
2400 } else {
2401 /* integer operations */
2402 t = VT_INT | (VT_LONG & (t1 | t2));
2403 /* convert to unsigned if it does not fit in an integer */
2404 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
2405 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
2406 t |= VT_UNSIGNED;
2407 std_op:
2408 /* XXX: currently, some unsigned operations are explicit, so
2409 we modify them here */
2410 if (t & VT_UNSIGNED) {
2411 if (op == TOK_SAR)
2412 op = TOK_SHR;
2413 else if (op == '/')
2414 op = TOK_UDIV;
2415 else if (op == '%')
2416 op = TOK_UMOD;
2417 else if (op == TOK_LT)
2418 op = TOK_ULT;
2419 else if (op == TOK_GT)
2420 op = TOK_UGT;
2421 else if (op == TOK_LE)
2422 op = TOK_ULE;
2423 else if (op == TOK_GE)
2424 op = TOK_UGE;
2426 vswap();
2427 type1.t = t;
2428 type1.ref = NULL;
2429 gen_cast(&type1);
2430 vswap();
2431 /* special case for shifts and long long: we keep the shift as
2432 an integer */
2433 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
2434 type1.t = VT_INT;
2435 gen_cast(&type1);
2436 if (is_float(t))
2437 gen_opif(op);
2438 else
2439 gen_opic(op);
2440 if (op >= TOK_ULT && op <= TOK_GT) {
2441 /* relational op: the result is an int */
2442 vtop->type.t = VT_INT;
2443 } else {
2444 vtop->type.t = t;
2447 // Make sure that we have converted to an rvalue:
2448 if (vtop->r & VT_LVAL)
2449 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
2452 #ifndef TCC_TARGET_ARM
2453 /* generic itof for unsigned long long case */
2454 static void gen_cvt_itof1(int t)
2456 #ifdef TCC_TARGET_ARM64
2457 gen_cvt_itof(t);
2458 #else
2459 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
2460 (VT_LLONG | VT_UNSIGNED)) {
2462 if (t == VT_FLOAT)
2463 vpush_global_sym(&func_old_type, TOK___floatundisf);
2464 #if LDOUBLE_SIZE != 8
2465 else if (t == VT_LDOUBLE)
2466 vpush_global_sym(&func_old_type, TOK___floatundixf);
2467 #endif
2468 else
2469 vpush_global_sym(&func_old_type, TOK___floatundidf);
2470 vrott(2);
2471 gfunc_call(1);
2472 vpushi(0);
2473 vtop->r = reg_fret(t);
2474 } else {
2475 gen_cvt_itof(t);
2477 #endif
2479 #endif
2481 /* generic ftoi for unsigned long long case */
2482 static void gen_cvt_ftoi1(int t)
2484 #ifdef TCC_TARGET_ARM64
2485 gen_cvt_ftoi(t);
2486 #else
2487 int st;
2489 if (t == (VT_LLONG | VT_UNSIGNED)) {
2490 /* not handled natively */
2491 st = vtop->type.t & VT_BTYPE;
2492 if (st == VT_FLOAT)
2493 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
2494 #if LDOUBLE_SIZE != 8
2495 else if (st == VT_LDOUBLE)
2496 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
2497 #endif
2498 else
2499 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
2500 vrott(2);
2501 gfunc_call(1);
2502 vpushi(0);
2503 vtop->r = REG_IRET;
2504 vtop->r2 = REG_LRET;
2505 } else {
2506 gen_cvt_ftoi(t);
2508 #endif
2511 /* force char or short cast */
2512 static void force_charshort_cast(int t)
2514 int bits, dbt;
2516 /* cannot cast static initializers */
2517 if (STATIC_DATA_WANTED)
2518 return;
2520 dbt = t & VT_BTYPE;
2521 /* XXX: add optimization if lvalue : just change type and offset */
2522 if (dbt == VT_BYTE)
2523 bits = 8;
2524 else
2525 bits = 16;
2526 if (t & VT_UNSIGNED) {
2527 vpushi((1 << bits) - 1);
2528 gen_op('&');
2529 } else {
2530 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
2531 bits = 64 - bits;
2532 else
2533 bits = 32 - bits;
2534 vpushi(bits);
2535 gen_op(TOK_SHL);
2536 /* result must be signed or the SAR is converted to an SHL
2537 This was not the case when "t" was a signed short
2538 and the last value on the stack was an unsigned int */
2539 vtop->type.t &= ~VT_UNSIGNED;
2540 vpushi(bits);
2541 gen_op(TOK_SAR);
2545 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
2546 static void gen_cast_s(int t)
2548 CType type;
2549 type.t = t;
2550 type.ref = NULL;
2551 gen_cast(&type);
2554 static void gen_cast(CType *type)
2556 int sbt, dbt, sf, df, c, p;
2558 /* special delayed cast for char/short */
2559 /* XXX: in some cases (multiple cascaded casts), it may still
2560 be incorrect */
2561 if (vtop->r & VT_MUSTCAST) {
2562 vtop->r &= ~VT_MUSTCAST;
2563 force_charshort_cast(vtop->type.t);
2566 /* bitfields first get cast to ints */
2567 if (vtop->type.t & VT_BITFIELD) {
2568 gv(RC_INT);
2571 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
2572 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
2574 if (sbt != dbt) {
2575 sf = is_float(sbt);
2576 df = is_float(dbt);
2577 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2578 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
2579 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
2580 c &= dbt != VT_LDOUBLE;
2581 #endif
2582 if (c) {
2583 /* constant case: we can do it now */
2584 /* XXX: in ISOC, cannot do it if error in convert */
2585 if (sbt == VT_FLOAT)
2586 vtop->c.ld = vtop->c.f;
2587 else if (sbt == VT_DOUBLE)
2588 vtop->c.ld = vtop->c.d;
2590 if (df) {
2591 if ((sbt & VT_BTYPE) == VT_LLONG) {
2592 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
2593 vtop->c.ld = vtop->c.i;
2594 else
2595 vtop->c.ld = -(long double)-vtop->c.i;
2596 } else if(!sf) {
2597 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
2598 vtop->c.ld = (uint32_t)vtop->c.i;
2599 else
2600 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
2603 if (dbt == VT_FLOAT)
2604 vtop->c.f = (float)vtop->c.ld;
2605 else if (dbt == VT_DOUBLE)
2606 vtop->c.d = (double)vtop->c.ld;
2607 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
2608 vtop->c.i = vtop->c.ld;
2609 } else if (sf && dbt == VT_BOOL) {
2610 vtop->c.i = (vtop->c.ld != 0);
2611 } else {
2612 if(sf)
2613 vtop->c.i = vtop->c.ld;
2614 else if (sbt == (VT_LLONG|VT_UNSIGNED))
2616 else if (sbt & VT_UNSIGNED)
2617 vtop->c.i = (uint32_t)vtop->c.i;
2618 #if PTR_SIZE == 8
2619 else if (sbt == VT_PTR)
2621 #endif
2622 else if (sbt != VT_LLONG)
2623 vtop->c.i = ((uint32_t)vtop->c.i |
2624 -(vtop->c.i & 0x80000000));
2626 if (dbt == (VT_LLONG|VT_UNSIGNED))
2628 else if (dbt == VT_BOOL)
2629 vtop->c.i = (vtop->c.i != 0);
2630 #if PTR_SIZE == 8
2631 else if (dbt == VT_PTR)
2633 #endif
2634 else if (dbt != VT_LLONG) {
2635 uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
2636 (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
2637 0xffffffff);
2638 vtop->c.i &= m;
2639 if (!(dbt & VT_UNSIGNED))
2640 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
2643 } else if (p && dbt == VT_BOOL) {
2644 vtop->r = VT_CONST;
2645 vtop->c.i = 1;
2646 } else {
2647 /* non constant case: generate code */
2648 if (sf && df) {
2649 /* convert from fp to fp */
2650 gen_cvt_ftof(dbt);
2651 } else if (df) {
2652 /* convert int to fp */
2653 gen_cvt_itof1(dbt);
2654 } else if (sf) {
2655 /* convert fp to int */
2656 if (dbt == VT_BOOL) {
2657 vpushi(0);
2658 gen_op(TOK_NE);
2659 } else {
2660 /* we handle char/short/etc... with generic code */
2661 if (dbt != (VT_INT | VT_UNSIGNED) &&
2662 dbt != (VT_LLONG | VT_UNSIGNED) &&
2663 dbt != VT_LLONG)
2664 dbt = VT_INT;
2665 gen_cvt_ftoi1(dbt);
2666 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2667 /* additional cast for char/short... */
2668 vtop->type.t = dbt;
2669 gen_cast(type);
2672 #if PTR_SIZE == 4
2673 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2674 if ((sbt & VT_BTYPE) != VT_LLONG) {
2675 /* scalar to long long */
2676 /* machine independent conversion */
2677 gv(RC_INT);
2678 /* generate high word */
2679 if (sbt == (VT_INT | VT_UNSIGNED)) {
2680 vpushi(0);
2681 gv(RC_INT);
2682 } else {
2683 if (sbt == VT_PTR) {
2684 /* cast from pointer to int before we apply
2685 shift operation, which pointers don't support*/
2686 gen_cast_s(VT_INT);
2688 gv_dup();
2689 vpushi(31);
2690 gen_op(TOK_SAR);
2692 /* patch second register */
2693 vtop[-1].r2 = vtop->r;
2694 vpop();
2696 #else
2697 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2698 (dbt & VT_BTYPE) == VT_PTR ||
2699 (dbt & VT_BTYPE) == VT_FUNC) {
2700 if ((sbt & VT_BTYPE) != VT_LLONG &&
2701 (sbt & VT_BTYPE) != VT_PTR &&
2702 (sbt & VT_BTYPE) != VT_FUNC) {
2703 /* need to convert from 32bit to 64bit */
2704 gv(RC_INT);
2705 if (sbt != (VT_INT | VT_UNSIGNED)) {
2706 #if defined(TCC_TARGET_ARM64)
2707 gen_cvt_sxtw();
2708 #elif defined(TCC_TARGET_X86_64)
2709 int r = gv(RC_INT);
2710 /* x86_64 specific: movslq */
2711 o(0x6348);
2712 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2713 #else
2714 #error
2715 #endif
2718 #endif
2719 } else if (dbt == VT_BOOL) {
2720 /* scalar to bool */
2721 vpushi(0);
2722 gen_op(TOK_NE);
2723 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2724 (dbt & VT_BTYPE) == VT_SHORT) {
2725 if (sbt == VT_PTR) {
2726 vtop->type.t = VT_INT;
2727 tcc_warning("nonportable conversion from pointer to char/short");
2729 force_charshort_cast(dbt);
2730 } else if ((dbt & VT_BTYPE) == VT_INT) {
2731 /* scalar to int */
2732 if ((sbt & VT_BTYPE) == VT_LLONG) {
2733 #if PTR_SIZE == 4
2734 /* from long long: just take low order word */
2735 lexpand();
2736 vpop();
2737 #else
2738 vpushi(0xffffffff);
2739 vtop->type.t |= VT_UNSIGNED;
2740 gen_op('&');
2741 #endif
2743 /* if lvalue and single word type, nothing to do because
2744 the lvalue already contains the real type size (see
2745 VT_LVAL_xxx constants) */
2748 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2749 /* if we are casting between pointer types,
2750 we must update the VT_LVAL_xxx size */
2751 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2752 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2754 vtop->type = *type;
2755 vtop->type.t &= ~ ( VT_CONSTANT | VT_VOLATILE | VT_ARRAY );
2758 /* return type size as known at compile time. Put alignment at 'a' */
2759 ST_FUNC int type_size(CType *type, int *a)
2761 Sym *s;
2762 int bt;
2764 bt = type->t & VT_BTYPE;
2765 if (bt == VT_STRUCT) {
2766 /* struct/union */
2767 s = type->ref;
2768 *a = s->r;
2769 return s->c;
2770 } else if (bt == VT_PTR) {
2771 if (type->t & VT_ARRAY) {
2772 int ts;
2774 s = type->ref;
2775 ts = type_size(&s->type, a);
2777 if (ts < 0 && s->c < 0)
2778 ts = -ts;
2780 return ts * s->c;
2781 } else {
2782 *a = PTR_SIZE;
2783 return PTR_SIZE;
2785 } else if (IS_ENUM(type->t) && type->ref->c < 0) {
2786 return -1; /* incomplete enum */
2787 } else if (bt == VT_LDOUBLE) {
2788 *a = LDOUBLE_ALIGN;
2789 return LDOUBLE_SIZE;
2790 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2791 #ifdef TCC_TARGET_I386
2792 #ifdef TCC_TARGET_PE
2793 *a = 8;
2794 #else
2795 *a = 4;
2796 #endif
2797 #elif defined(TCC_TARGET_ARM)
2798 #ifdef TCC_ARM_EABI
2799 *a = 8;
2800 #else
2801 *a = 4;
2802 #endif
2803 #else
2804 *a = 8;
2805 #endif
2806 return 8;
2807 } else if (bt == VT_INT || bt == VT_FLOAT) {
2808 *a = 4;
2809 return 4;
2810 } else if (bt == VT_SHORT) {
2811 *a = 2;
2812 return 2;
2813 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2814 *a = 8;
2815 return 16;
2816 } else {
2817 /* char, void, function, _Bool */
2818 *a = 1;
2819 return 1;
2823 /* push type size as known at runtime time on top of value stack. Put
2824 alignment at 'a' */
2825 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2827 if (type->t & VT_VLA) {
2828 type_size(&type->ref->type, a);
2829 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2830 } else {
2831 vpushi(type_size(type, a));
2835 static void vla_sp_restore(void) {
2836 if (vlas_in_scope) {
2837 gen_vla_sp_restore(vla_sp_loc);
2841 static void vla_sp_restore_root(void) {
2842 if (vlas_in_scope) {
2843 gen_vla_sp_restore(vla_sp_root_loc);
2847 /* return the pointed type of t */
2848 static inline CType *pointed_type(CType *type)
2850 return &type->ref->type;
2853 /* modify type so that its it is a pointer to type. */
2854 ST_FUNC void mk_pointer(CType *type)
2856 Sym *s;
2857 s = sym_push(SYM_FIELD, type, 0, -1);
2858 type->t = VT_PTR | (type->t & VT_STORAGE);
2859 type->ref = s;
2862 /* compare function types. OLD functions match any new functions */
2863 static int is_compatible_func(CType *type1, CType *type2)
2865 Sym *s1, *s2;
2867 s1 = type1->ref;
2868 s2 = type2->ref;
2869 if (!is_compatible_types(&s1->type, &s2->type))
2870 return 0;
2871 /* check func_call */
2872 if (s1->f.func_call != s2->f.func_call)
2873 return 0;
2874 /* XXX: not complete */
2875 if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD)
2876 return 1;
2877 if (s1->f.func_type != s2->f.func_type)
2878 return 0;
2879 while (s1 != NULL) {
2880 if (s2 == NULL)
2881 return 0;
2882 if (!is_compatible_unqualified_types(&s1->type, &s2->type))
2883 return 0;
2884 s1 = s1->next;
2885 s2 = s2->next;
2887 if (s2)
2888 return 0;
2889 return 1;
2892 /* return true if type1 and type2 are the same. If unqualified is
2893 true, qualifiers on the types are ignored.
2895 static int compare_types(CType *type1, CType *type2, int unqualified)
2897 int bt1, t1, t2;
2899 t1 = type1->t & VT_TYPE;
2900 t2 = type2->t & VT_TYPE;
2901 if (unqualified) {
2902 /* strip qualifiers before comparing */
2903 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2904 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2907 /* Default Vs explicit signedness only matters for char */
2908 if ((t1 & VT_BTYPE) != VT_BYTE) {
2909 t1 &= ~VT_DEFSIGN;
2910 t2 &= ~VT_DEFSIGN;
2912 /* XXX: bitfields ? */
2913 if (t1 != t2)
2914 return 0;
2915 /* test more complicated cases */
2916 bt1 = t1 & (VT_BTYPE | VT_ARRAY);
2917 if (bt1 == VT_PTR) {
2918 type1 = pointed_type(type1);
2919 type2 = pointed_type(type2);
2920 return is_compatible_types(type1, type2);
2921 } else if (bt1 & VT_ARRAY) {
2922 return type1->ref->c < 0 || type2->ref->c < 0
2923 || type1->ref->c == type2->ref->c;
2924 } else if (bt1 == VT_STRUCT) {
2925 return (type1->ref == type2->ref);
2926 } else if (bt1 == VT_FUNC) {
2927 return is_compatible_func(type1, type2);
2928 } else if (IS_ENUM(type1->t) || IS_ENUM(type2->t)) {
2929 return type1->ref == type2->ref;
2930 } else {
2931 return 1;
2935 /* return true if type1 and type2 are exactly the same (including
2936 qualifiers).
2938 static int is_compatible_types(CType *type1, CType *type2)
2940 return compare_types(type1,type2,0);
2943 /* return true if type1 and type2 are the same (ignoring qualifiers).
2945 static int is_compatible_unqualified_types(CType *type1, CType *type2)
2947 return compare_types(type1,type2,1);
2950 /* print a type. If 'varstr' is not NULL, then the variable is also
2951 printed in the type */
2952 /* XXX: union */
2953 /* XXX: add array and function pointers */
2954 static void type_to_str(char *buf, int buf_size,
2955 CType *type, const char *varstr)
2957 int bt, v, t;
2958 Sym *s, *sa;
2959 char buf1[256];
2960 const char *tstr;
2962 t = type->t;
2963 bt = t & VT_BTYPE;
2964 buf[0] = '\0';
2966 if (t & VT_EXTERN)
2967 pstrcat(buf, buf_size, "extern ");
2968 if (t & VT_STATIC)
2969 pstrcat(buf, buf_size, "static ");
2970 if (t & VT_TYPEDEF)
2971 pstrcat(buf, buf_size, "typedef ");
2972 if (t & VT_INLINE)
2973 pstrcat(buf, buf_size, "inline ");
2974 if (t & VT_VOLATILE)
2975 pstrcat(buf, buf_size, "volatile ");
2976 if (t & VT_CONSTANT)
2977 pstrcat(buf, buf_size, "const ");
2979 if (((t & VT_DEFSIGN) && bt == VT_BYTE)
2980 || ((t & VT_UNSIGNED)
2981 && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
2982 && !IS_ENUM(t)
2984 pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
2986 buf_size -= strlen(buf);
2987 buf += strlen(buf);
2989 switch(bt) {
2990 case VT_VOID:
2991 tstr = "void";
2992 goto add_tstr;
2993 case VT_BOOL:
2994 tstr = "_Bool";
2995 goto add_tstr;
2996 case VT_BYTE:
2997 tstr = "char";
2998 goto add_tstr;
2999 case VT_SHORT:
3000 tstr = "short";
3001 goto add_tstr;
3002 case VT_INT:
3003 tstr = "int";
3004 goto maybe_long;
3005 case VT_LLONG:
3006 tstr = "long long";
3007 maybe_long:
3008 if (t & VT_LONG)
3009 tstr = "long";
3010 if (!IS_ENUM(t))
3011 goto add_tstr;
3012 tstr = "enum ";
3013 goto tstruct;
3014 case VT_FLOAT:
3015 tstr = "float";
3016 goto add_tstr;
3017 case VT_DOUBLE:
3018 tstr = "double";
3019 goto add_tstr;
3020 case VT_LDOUBLE:
3021 tstr = "long double";
3022 add_tstr:
3023 pstrcat(buf, buf_size, tstr);
3024 break;
3025 case VT_STRUCT:
3026 tstr = "struct ";
3027 if (IS_UNION(t))
3028 tstr = "union ";
3029 tstruct:
3030 pstrcat(buf, buf_size, tstr);
3031 v = type->ref->v & ~SYM_STRUCT;
3032 if (v >= SYM_FIRST_ANOM)
3033 pstrcat(buf, buf_size, "<anonymous>");
3034 else
3035 pstrcat(buf, buf_size, get_tok_str(v, NULL));
3036 break;
3037 case VT_FUNC:
3038 s = type->ref;
3039 buf1[0]=0;
3040 if (varstr && '*' == *varstr) {
3041 pstrcat(buf1, sizeof(buf1), "(");
3042 pstrcat(buf1, sizeof(buf1), varstr);
3043 pstrcat(buf1, sizeof(buf1), ")");
3045 pstrcat(buf1, buf_size, "(");
3046 sa = s->next;
3047 while (sa != NULL) {
3048 char buf2[256];
3049 type_to_str(buf2, sizeof(buf2), &sa->type, NULL);
3050 pstrcat(buf1, sizeof(buf1), buf2);
3051 sa = sa->next;
3052 if (sa)
3053 pstrcat(buf1, sizeof(buf1), ", ");
3055 if (s->f.func_type == FUNC_ELLIPSIS)
3056 pstrcat(buf1, sizeof(buf1), ", ...");
3057 pstrcat(buf1, sizeof(buf1), ")");
3058 type_to_str(buf, buf_size, &s->type, buf1);
3059 goto no_var;
3060 case VT_PTR:
3061 s = type->ref;
3062 if (t & VT_ARRAY) {
3063 if (varstr && '*' == *varstr)
3064 snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c);
3065 else
3066 snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
3067 type_to_str(buf, buf_size, &s->type, buf1);
3068 goto no_var;
3070 pstrcpy(buf1, sizeof(buf1), "*");
3071 if (t & VT_CONSTANT)
3072 pstrcat(buf1, buf_size, "const ");
3073 if (t & VT_VOLATILE)
3074 pstrcat(buf1, buf_size, "volatile ");
3075 if (varstr)
3076 pstrcat(buf1, sizeof(buf1), varstr);
3077 type_to_str(buf, buf_size, &s->type, buf1);
3078 goto no_var;
3080 if (varstr) {
3081 pstrcat(buf, buf_size, " ");
3082 pstrcat(buf, buf_size, varstr);
3084 no_var: ;
3087 /* verify type compatibility to store vtop in 'dt' type, and generate
3088 casts if needed. */
3089 static void gen_assign_cast(CType *dt)
3091 CType *st, *type1, *type2;
3092 char buf1[256], buf2[256];
3093 int dbt, sbt, qualwarn, lvl;
3095 st = &vtop->type; /* source type */
3096 dbt = dt->t & VT_BTYPE;
3097 sbt = st->t & VT_BTYPE;
3098 if (sbt == VT_VOID || dbt == VT_VOID) {
3099 if (sbt == VT_VOID && dbt == VT_VOID)
3100 ; /* It is Ok if both are void */
3101 else
3102 tcc_error("cannot cast from/to void");
3104 if (dt->t & VT_CONSTANT)
3105 tcc_warning("assignment of read-only location");
3106 switch(dbt) {
3107 case VT_PTR:
3108 /* special cases for pointers */
3109 /* '0' can also be a pointer */
3110 if (is_null_pointer(vtop))
3111 break;
3112 /* accept implicit pointer to integer cast with warning */
3113 if (is_integer_btype(sbt)) {
3114 tcc_warning("assignment makes pointer from integer without a cast");
3115 break;
3117 type1 = pointed_type(dt);
3118 if (sbt == VT_PTR)
3119 type2 = pointed_type(st);
3120 else if (sbt == VT_FUNC)
3121 type2 = st; /* a function is implicitly a function pointer */
3122 else
3123 goto error;
3124 if (is_compatible_types(type1, type2))
3125 break;
3126 for (qualwarn = lvl = 0;; ++lvl) {
3127 if (((type2->t & VT_CONSTANT) && !(type1->t & VT_CONSTANT)) ||
3128 ((type2->t & VT_VOLATILE) && !(type1->t & VT_VOLATILE)))
3129 qualwarn = 1;
3130 dbt = type1->t & (VT_BTYPE|VT_LONG);
3131 sbt = type2->t & (VT_BTYPE|VT_LONG);
3132 if (dbt != VT_PTR || sbt != VT_PTR)
3133 break;
3134 type1 = pointed_type(type1);
3135 type2 = pointed_type(type2);
3137 if (!is_compatible_unqualified_types(type1, type2)) {
3138 if ((dbt == VT_VOID || sbt == VT_VOID) && lvl == 0) {
3139 /* void * can match anything */
3140 } else if (dbt == sbt
3141 && is_integer_btype(sbt & VT_BTYPE)
3142 && IS_ENUM(type1->t) + IS_ENUM(type2->t)
3143 + !!((type1->t ^ type2->t) & VT_UNSIGNED) < 2) {
3144 /* Like GCC don't warn by default for merely changes
3145 in pointer target signedness. Do warn for different
3146 base types, though, in particular for unsigned enums
3147 and signed int targets. */
3148 } else {
3149 tcc_warning("assignment from incompatible pointer type");
3150 break;
3153 if (qualwarn)
3154 tcc_warning("assignment discards qualifiers from pointer target type");
3155 break;
3156 case VT_BYTE:
3157 case VT_SHORT:
3158 case VT_INT:
3159 case VT_LLONG:
3160 if (sbt == VT_PTR || sbt == VT_FUNC) {
3161 tcc_warning("assignment makes integer from pointer without a cast");
3162 } else if (sbt == VT_STRUCT) {
3163 goto case_VT_STRUCT;
3165 /* XXX: more tests */
3166 break;
3167 case VT_STRUCT:
3168 case_VT_STRUCT:
3169 if (!is_compatible_unqualified_types(dt, st)) {
3170 error:
3171 type_to_str(buf1, sizeof(buf1), st, NULL);
3172 type_to_str(buf2, sizeof(buf2), dt, NULL);
3173 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
3175 break;
3177 gen_cast(dt);
3180 /* store vtop in lvalue pushed on stack */
3181 ST_FUNC void vstore(void)
3183 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
3185 ft = vtop[-1].type.t;
3186 sbt = vtop->type.t & VT_BTYPE;
3187 dbt = ft & VT_BTYPE;
3188 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
3189 (sbt == VT_INT && dbt == VT_SHORT))
3190 && !(vtop->type.t & VT_BITFIELD)) {
3191 /* optimize char/short casts */
3192 delayed_cast = VT_MUSTCAST;
3193 vtop->type.t = ft & VT_TYPE;
3194 /* XXX: factorize */
3195 if (ft & VT_CONSTANT)
3196 tcc_warning("assignment of read-only location");
3197 } else {
3198 delayed_cast = 0;
3199 if (!(ft & VT_BITFIELD))
3200 gen_assign_cast(&vtop[-1].type);
3203 if (sbt == VT_STRUCT) {
3204 /* if structure, only generate pointer */
3205 /* structure assignment : generate memcpy */
3206 /* XXX: optimize if small size */
3207 size = type_size(&vtop->type, &align);
3209 /* destination */
3210 vswap();
3211 vtop->type.t = VT_PTR;
3212 gaddrof();
3214 /* address of memcpy() */
3215 #ifdef TCC_ARM_EABI
3216 if(!(align & 7))
3217 vpush_global_sym(&func_old_type, TOK_memcpy8);
3218 else if(!(align & 3))
3219 vpush_global_sym(&func_old_type, TOK_memcpy4);
3220 else
3221 #endif
3222 /* Use memmove, rather than memcpy, as dest and src may be same: */
3223 vpush_global_sym(&func_old_type, TOK_memmove);
3225 vswap();
3226 /* source */
3227 vpushv(vtop - 2);
3228 vtop->type.t = VT_PTR;
3229 gaddrof();
3230 /* type size */
3231 vpushi(size);
3232 gfunc_call(3);
3234 /* leave source on stack */
3235 } else if (ft & VT_BITFIELD) {
3236 /* bitfield store handling */
3238 /* save lvalue as expression result (example: s.b = s.a = n;) */
3239 vdup(), vtop[-1] = vtop[-2];
3241 bit_pos = BIT_POS(ft);
3242 bit_size = BIT_SIZE(ft);
3243 /* remove bit field info to avoid loops */
3244 vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
3246 if ((ft & VT_BTYPE) == VT_BOOL) {
3247 gen_cast(&vtop[-1].type);
3248 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
3251 r = adjust_bf(vtop - 1, bit_pos, bit_size);
3252 if (r == VT_STRUCT) {
3253 gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT);
3254 store_packed_bf(bit_pos, bit_size);
3255 } else {
3256 unsigned long long mask = (1ULL << bit_size) - 1;
3257 if ((ft & VT_BTYPE) != VT_BOOL) {
3258 /* mask source */
3259 if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG)
3260 vpushll(mask);
3261 else
3262 vpushi((unsigned)mask);
3263 gen_op('&');
3265 /* shift source */
3266 vpushi(bit_pos);
3267 gen_op(TOK_SHL);
3268 vswap();
3269 /* duplicate destination */
3270 vdup();
3271 vrott(3);
3272 /* load destination, mask and or with source */
3273 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
3274 vpushll(~(mask << bit_pos));
3275 else
3276 vpushi(~((unsigned)mask << bit_pos));
3277 gen_op('&');
3278 gen_op('|');
3279 /* store result */
3280 vstore();
3281 /* ... and discard */
3282 vpop();
3284 } else if (dbt == VT_VOID) {
3285 --vtop;
3286 } else {
3287 #ifdef CONFIG_TCC_BCHECK
3288 /* bound check case */
3289 if (vtop[-1].r & VT_MUSTBOUND) {
3290 vswap();
3291 gbound();
3292 vswap();
3294 #endif
3295 rc = RC_INT;
3296 if (is_float(ft)) {
3297 rc = RC_FLOAT;
3298 #ifdef TCC_TARGET_X86_64
3299 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
3300 rc = RC_ST0;
3301 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
3302 rc = RC_FRET;
3304 #endif
3306 r = gv(rc); /* generate value */
3307 /* if lvalue was saved on stack, must read it */
3308 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
3309 SValue sv;
3310 t = get_reg(RC_INT);
3311 #if PTR_SIZE == 8
3312 sv.type.t = VT_PTR;
3313 #else
3314 sv.type.t = VT_INT;
3315 #endif
3316 sv.r = VT_LOCAL | VT_LVAL;
3317 sv.c.i = vtop[-1].c.i;
3318 load(t, &sv);
3319 vtop[-1].r = t | VT_LVAL;
3321 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
3322 #if PTR_SIZE == 8
3323 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
3324 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
3325 #else
3326 if ((ft & VT_BTYPE) == VT_LLONG) {
3327 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
3328 #endif
3329 vtop[-1].type.t = load_type;
3330 store(r, vtop - 1);
3331 vswap();
3332 /* convert to int to increment easily */
3333 vtop->type.t = addr_type;
3334 gaddrof();
3335 vpushi(load_size);
3336 gen_op('+');
3337 vtop->r |= VT_LVAL;
3338 vswap();
3339 vtop[-1].type.t = load_type;
3340 /* XXX: it works because r2 is spilled last ! */
3341 store(vtop->r2, vtop - 1);
3342 } else {
3343 store(r, vtop - 1);
3346 vswap();
3347 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
3348 vtop->r |= delayed_cast;
3352 /* post defines POST/PRE add. c is the token ++ or -- */
3353 ST_FUNC void inc(int post, int c)
3355 test_lvalue();
3356 vdup(); /* save lvalue */
3357 if (post) {
3358 gv_dup(); /* duplicate value */
3359 vrotb(3);
3360 vrotb(3);
3362 /* add constant */
3363 vpushi(c - TOK_MID);
3364 gen_op('+');
3365 vstore(); /* store value */
3366 if (post)
3367 vpop(); /* if post op, return saved value */
3370 ST_FUNC void parse_mult_str (CString *astr, const char *msg)
3372 /* read the string */
3373 if (tok != TOK_STR)
3374 expect(msg);
3375 cstr_new(astr);
3376 while (tok == TOK_STR) {
3377 /* XXX: add \0 handling too ? */
3378 cstr_cat(astr, tokc.str.data, -1);
3379 next();
3381 cstr_ccat(astr, '\0');
3384 /* If I is >= 1 and a power of two, returns log2(i)+1.
3385 If I is 0 returns 0. */
3386 static int exact_log2p1(int i)
3388 int ret;
3389 if (!i)
3390 return 0;
3391 for (ret = 1; i >= 1 << 8; ret += 8)
3392 i >>= 8;
3393 if (i >= 1 << 4)
3394 ret += 4, i >>= 4;
3395 if (i >= 1 << 2)
3396 ret += 2, i >>= 2;
3397 if (i >= 1 << 1)
3398 ret++;
3399 return ret;
3402 /* Parse __attribute__((...)) GNUC extension. */
3403 static void parse_attribute(AttributeDef *ad)
3405 int t, n;
3406 CString astr;
3408 redo:
3409 if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
3410 return;
3411 next();
3412 skip('(');
3413 skip('(');
3414 while (tok != ')') {
3415 if (tok < TOK_IDENT)
3416 expect("attribute name");
3417 t = tok;
3418 next();
3419 switch(t) {
3420 case TOK_CLEANUP1:
3421 case TOK_CLEANUP2:
3423 Sym *s;
3425 skip('(');
3426 s = sym_find(tok);
3427 if (!s) {
3428 tcc_warning("implicit declaration of function '%s'",
3429 get_tok_str(tok, &tokc));
3430 s = external_global_sym(tok, &func_old_type, 0);
3432 ad->cleanup_func = s;
3433 next();
3434 skip(')');
3435 break;
3437 case TOK_SECTION1:
3438 case TOK_SECTION2:
3439 skip('(');
3440 parse_mult_str(&astr, "section name");
3441 ad->section = find_section(tcc_state, (char *)astr.data);
3442 skip(')');
3443 cstr_free(&astr);
3444 break;
3445 case TOK_ALIAS1:
3446 case TOK_ALIAS2:
3447 skip('(');
3448 parse_mult_str(&astr, "alias(\"target\")");
3449 ad->alias_target = /* save string as token, for later */
3450 tok_alloc((char*)astr.data, astr.size-1)->tok;
3451 skip(')');
3452 cstr_free(&astr);
3453 break;
3454 case TOK_VISIBILITY1:
3455 case TOK_VISIBILITY2:
3456 skip('(');
3457 parse_mult_str(&astr,
3458 "visibility(\"default|hidden|internal|protected\")");
3459 if (!strcmp (astr.data, "default"))
3460 ad->a.visibility = STV_DEFAULT;
3461 else if (!strcmp (astr.data, "hidden"))
3462 ad->a.visibility = STV_HIDDEN;
3463 else if (!strcmp (astr.data, "internal"))
3464 ad->a.visibility = STV_INTERNAL;
3465 else if (!strcmp (astr.data, "protected"))
3466 ad->a.visibility = STV_PROTECTED;
3467 else
3468 expect("visibility(\"default|hidden|internal|protected\")");
3469 skip(')');
3470 cstr_free(&astr);
3471 break;
3472 case TOK_ALIGNED1:
3473 case TOK_ALIGNED2:
3474 if (tok == '(') {
3475 next();
3476 n = expr_const();
3477 if (n <= 0 || (n & (n - 1)) != 0)
3478 tcc_error("alignment must be a positive power of two");
3479 skip(')');
3480 } else {
3481 n = MAX_ALIGN;
3483 ad->a.aligned = exact_log2p1(n);
3484 if (n != 1 << (ad->a.aligned - 1))
3485 tcc_error("alignment of %d is larger than implemented", n);
3486 break;
3487 case TOK_PACKED1:
3488 case TOK_PACKED2:
3489 ad->a.packed = 1;
3490 break;
3491 case TOK_WEAK1:
3492 case TOK_WEAK2:
3493 ad->a.weak = 1;
3494 break;
3495 case TOK_UNUSED1:
3496 case TOK_UNUSED2:
3497 /* currently, no need to handle it because tcc does not
3498 track unused objects */
3499 break;
3500 case TOK_NORETURN1:
3501 case TOK_NORETURN2:
3502 /* currently, no need to handle it because tcc does not
3503 track unused objects */
3504 break;
3505 case TOK_CDECL1:
3506 case TOK_CDECL2:
3507 case TOK_CDECL3:
3508 ad->f.func_call = FUNC_CDECL;
3509 break;
3510 case TOK_STDCALL1:
3511 case TOK_STDCALL2:
3512 case TOK_STDCALL3:
3513 ad->f.func_call = FUNC_STDCALL;
3514 break;
3515 #ifdef TCC_TARGET_I386
3516 case TOK_REGPARM1:
3517 case TOK_REGPARM2:
3518 skip('(');
3519 n = expr_const();
3520 if (n > 3)
3521 n = 3;
3522 else if (n < 0)
3523 n = 0;
3524 if (n > 0)
3525 ad->f.func_call = FUNC_FASTCALL1 + n - 1;
3526 skip(')');
3527 break;
3528 case TOK_FASTCALL1:
3529 case TOK_FASTCALL2:
3530 case TOK_FASTCALL3:
3531 ad->f.func_call = FUNC_FASTCALLW;
3532 break;
3533 #endif
3534 case TOK_MODE:
3535 skip('(');
3536 switch(tok) {
3537 case TOK_MODE_DI:
3538 ad->attr_mode = VT_LLONG + 1;
3539 break;
3540 case TOK_MODE_QI:
3541 ad->attr_mode = VT_BYTE + 1;
3542 break;
3543 case TOK_MODE_HI:
3544 ad->attr_mode = VT_SHORT + 1;
3545 break;
3546 case TOK_MODE_SI:
3547 case TOK_MODE_word:
3548 ad->attr_mode = VT_INT + 1;
3549 break;
3550 default:
3551 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
3552 break;
3554 next();
3555 skip(')');
3556 break;
3557 case TOK_DLLEXPORT:
3558 ad->a.dllexport = 1;
3559 break;
3560 case TOK_NODECORATE:
3561 ad->a.nodecorate = 1;
3562 break;
3563 case TOK_DLLIMPORT:
3564 ad->a.dllimport = 1;
3565 break;
3566 default:
3567 if (tcc_state->warn_unsupported)
3568 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
3569 /* skip parameters */
3570 if (tok == '(') {
3571 int parenthesis = 0;
3572 do {
3573 if (tok == '(')
3574 parenthesis++;
3575 else if (tok == ')')
3576 parenthesis--;
3577 next();
3578 } while (parenthesis && tok != -1);
3580 break;
3582 if (tok != ',')
3583 break;
3584 next();
3586 skip(')');
3587 skip(')');
3588 goto redo;
3591 static Sym * find_field (CType *type, int v)
3593 Sym *s = type->ref;
3594 v |= SYM_FIELD;
3595 while ((s = s->next) != NULL) {
3596 if ((s->v & SYM_FIELD) &&
3597 (s->type.t & VT_BTYPE) == VT_STRUCT &&
3598 (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
3599 Sym *ret = find_field (&s->type, v);
3600 if (ret)
3601 return ret;
3603 if (s->v == v)
3604 break;
3606 return s;
3609 static void struct_add_offset (Sym *s, int offset)
3611 while ((s = s->next) != NULL) {
3612 if ((s->v & SYM_FIELD) &&
3613 (s->type.t & VT_BTYPE) == VT_STRUCT &&
3614 (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
3615 struct_add_offset(s->type.ref, offset);
3616 } else
3617 s->c += offset;
3621 static void struct_layout(CType *type, AttributeDef *ad)
3623 int size, align, maxalign, offset, c, bit_pos, bit_size;
3624 int packed, a, bt, prevbt, prev_bit_size;
3625 int pcc = !tcc_state->ms_bitfields;
3626 int pragma_pack = *tcc_state->pack_stack_ptr;
3627 Sym *f;
3629 maxalign = 1;
3630 offset = 0;
3631 c = 0;
3632 bit_pos = 0;
3633 prevbt = VT_STRUCT; /* make it never match */
3634 prev_bit_size = 0;
3636 //#define BF_DEBUG
3638 for (f = type->ref->next; f; f = f->next) {
3639 if (f->type.t & VT_BITFIELD)
3640 bit_size = BIT_SIZE(f->type.t);
3641 else
3642 bit_size = -1;
3643 size = type_size(&f->type, &align);
3644 a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
3645 packed = 0;
3647 if (pcc && bit_size == 0) {
3648 /* in pcc mode, packing does not affect zero-width bitfields */
3650 } else {
3651 /* in pcc mode, attribute packed overrides if set. */
3652 if (pcc && (f->a.packed || ad->a.packed))
3653 align = packed = 1;
3655 /* pragma pack overrides align if lesser and packs bitfields always */
3656 if (pragma_pack) {
3657 packed = 1;
3658 if (pragma_pack < align)
3659 align = pragma_pack;
3660 /* in pcc mode pragma pack also overrides individual align */
3661 if (pcc && pragma_pack < a)
3662 a = 0;
3665 /* some individual align was specified */
3666 if (a)
3667 align = a;
3669 if (type->ref->type.t == VT_UNION) {
3670 if (pcc && bit_size >= 0)
3671 size = (bit_size + 7) >> 3;
3672 offset = 0;
3673 if (size > c)
3674 c = size;
3676 } else if (bit_size < 0) {
3677 if (pcc)
3678 c += (bit_pos + 7) >> 3;
3679 c = (c + align - 1) & -align;
3680 offset = c;
3681 if (size > 0)
3682 c += size;
3683 bit_pos = 0;
3684 prevbt = VT_STRUCT;
3685 prev_bit_size = 0;
3687 } else {
3688 /* A bit-field. Layout is more complicated. There are two
3689 options: PCC (GCC) compatible and MS compatible */
3690 if (pcc) {
3691 /* In PCC layout a bit-field is placed adjacent to the
3692 preceding bit-fields, except if:
3693 - it has zero-width
3694 - an individual alignment was given
3695 - it would overflow its base type container and
3696 there is no packing */
3697 if (bit_size == 0) {
3698 new_field:
3699 c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
3700 bit_pos = 0;
3701 } else if (f->a.aligned) {
3702 goto new_field;
3703 } else if (!packed) {
3704 int a8 = align * 8;
3705 int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
3706 if (ofs > size / align)
3707 goto new_field;
3710 /* in pcc mode, long long bitfields have type int if they fit */
3711 if (size == 8 && bit_size <= 32)
3712 f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
3714 while (bit_pos >= align * 8)
3715 c += align, bit_pos -= align * 8;
3716 offset = c;
3718 /* In PCC layout named bit-fields influence the alignment
3719 of the containing struct using the base types alignment,
3720 except for packed fields (which here have correct align). */
3721 if (f->v & SYM_FIRST_ANOM
3722 // && bit_size // ??? gcc on ARM/rpi does that
3724 align = 1;
3726 } else {
3727 bt = f->type.t & VT_BTYPE;
3728 if ((bit_pos + bit_size > size * 8)
3729 || (bit_size > 0) == (bt != prevbt)
3731 c = (c + align - 1) & -align;
3732 offset = c;
3733 bit_pos = 0;
3734 /* In MS bitfield mode a bit-field run always uses
3735 at least as many bits as the underlying type.
3736 To start a new run it's also required that this
3737 or the last bit-field had non-zero width. */
3738 if (bit_size || prev_bit_size)
3739 c += size;
3741 /* In MS layout the records alignment is normally
3742 influenced by the field, except for a zero-width
3743 field at the start of a run (but by further zero-width
3744 fields it is again). */
3745 if (bit_size == 0 && prevbt != bt)
3746 align = 1;
3747 prevbt = bt;
3748 prev_bit_size = bit_size;
3751 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
3752 | (bit_pos << VT_STRUCT_SHIFT);
3753 bit_pos += bit_size;
3755 if (align > maxalign)
3756 maxalign = align;
3758 #ifdef BF_DEBUG
3759 printf("set field %s offset %-2d size %-2d align %-2d",
3760 get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
3761 if (f->type.t & VT_BITFIELD) {
3762 printf(" pos %-2d bits %-2d",
3763 BIT_POS(f->type.t),
3764 BIT_SIZE(f->type.t)
3767 printf("\n");
3768 #endif
3770 if (f->v & SYM_FIRST_ANOM && (f->type.t & VT_BTYPE) == VT_STRUCT) {
3771 Sym *ass;
3772 /* An anonymous struct/union. Adjust member offsets
3773 to reflect the real offset of our containing struct.
3774 Also set the offset of this anon member inside
3775 the outer struct to be zero. Via this it
3776 works when accessing the field offset directly
3777 (from base object), as well as when recursing
3778 members in initializer handling. */
3779 int v2 = f->type.ref->v;
3780 if (!(v2 & SYM_FIELD) &&
3781 (v2 & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
3782 Sym **pps;
3783 /* This happens only with MS extensions. The
3784 anon member has a named struct type, so it
3785 potentially is shared with other references.
3786 We need to unshare members so we can modify
3787 them. */
3788 ass = f->type.ref;
3789 f->type.ref = sym_push(anon_sym++ | SYM_FIELD,
3790 &f->type.ref->type, 0,
3791 f->type.ref->c);
3792 pps = &f->type.ref->next;
3793 while ((ass = ass->next) != NULL) {
3794 *pps = sym_push(ass->v, &ass->type, 0, ass->c);
3795 pps = &((*pps)->next);
3797 *pps = NULL;
3799 struct_add_offset(f->type.ref, offset);
3800 f->c = 0;
3801 } else {
3802 f->c = offset;
3805 f->r = 0;
3808 if (pcc)
3809 c += (bit_pos + 7) >> 3;
3811 /* store size and alignment */
3812 a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
3813 if (a < maxalign)
3814 a = maxalign;
3815 type->ref->r = a;
3816 if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
3817 /* can happen if individual align for some member was given. In
3818 this case MSVC ignores maxalign when aligning the size */
3819 a = pragma_pack;
3820 if (a < bt)
3821 a = bt;
3823 c = (c + a - 1) & -a;
3824 type->ref->c = c;
3826 #ifdef BF_DEBUG
3827 printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
3828 #endif
3830 /* check whether we can access bitfields by their type */
3831 for (f = type->ref->next; f; f = f->next) {
3832 int s, px, cx, c0;
3833 CType t;
3835 if (0 == (f->type.t & VT_BITFIELD))
3836 continue;
3837 f->type.ref = f;
3838 f->auxtype = -1;
3839 bit_size = BIT_SIZE(f->type.t);
3840 if (bit_size == 0)
3841 continue;
3842 bit_pos = BIT_POS(f->type.t);
3843 size = type_size(&f->type, &align);
3844 if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
3845 continue;
3847 /* try to access the field using a different type */
3848 c0 = -1, s = align = 1;
3849 for (;;) {
3850 px = f->c * 8 + bit_pos;
3851 cx = (px >> 3) & -align;
3852 px = px - (cx << 3);
3853 if (c0 == cx)
3854 break;
3855 s = (px + bit_size + 7) >> 3;
3856 if (s > 4) {
3857 t.t = VT_LLONG;
3858 } else if (s > 2) {
3859 t.t = VT_INT;
3860 } else if (s > 1) {
3861 t.t = VT_SHORT;
3862 } else {
3863 t.t = VT_BYTE;
3865 s = type_size(&t, &align);
3866 c0 = cx;
3869 if (px + bit_size <= s * 8 && cx + s <= c) {
3870 /* update offset and bit position */
3871 f->c = cx;
3872 bit_pos = px;
3873 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
3874 | (bit_pos << VT_STRUCT_SHIFT);
3875 if (s != size)
3876 f->auxtype = t.t;
3877 #ifdef BF_DEBUG
3878 printf("FIX field %s offset %-2d size %-2d align %-2d "
3879 "pos %-2d bits %-2d\n",
3880 get_tok_str(f->v & ~SYM_FIELD, NULL),
3881 cx, s, align, px, bit_size);
3882 #endif
3883 } else {
3884 /* fall back to load/store single-byte wise */
3885 f->auxtype = VT_STRUCT;
3886 #ifdef BF_DEBUG
3887 printf("FIX field %s : load byte-wise\n",
3888 get_tok_str(f->v & ~SYM_FIELD, NULL));
3889 #endif
3894 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
3895 static void struct_decl(CType *type, int u)
3897 int v, c, size, align, flexible;
3898 int bit_size, bsize, bt;
3899 Sym *s, *ss, **ps;
3900 AttributeDef ad, ad1;
3901 CType type1, btype;
3903 memset(&ad, 0, sizeof ad);
3904 next();
3905 parse_attribute(&ad);
3906 if (tok != '{') {
3907 v = tok;
3908 next();
3909 /* struct already defined ? return it */
3910 if (v < TOK_IDENT)
3911 expect("struct/union/enum name");
3912 s = struct_find(v);
3913 if (s && (s->sym_scope == local_scope || tok != '{')) {
3914 if (u == s->type.t)
3915 goto do_decl;
3916 if (u == VT_ENUM && IS_ENUM(s->type.t))
3917 goto do_decl;
3918 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
3920 } else {
3921 v = anon_sym++;
3923 /* Record the original enum/struct/union token. */
3924 type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
3925 type1.ref = NULL;
3926 /* we put an undefined size for struct/union */
3927 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
3928 s->r = 0; /* default alignment is zero as gcc */
3929 do_decl:
3930 type->t = s->type.t;
3931 type->ref = s;
3933 if (tok == '{') {
3934 next();
3935 if (s->c != -1)
3936 tcc_error("struct/union/enum already defined");
3937 s->c = -2;
3938 /* cannot be empty */
3939 /* non empty enums are not allowed */
3940 ps = &s->next;
3941 if (u == VT_ENUM) {
3942 long long ll = 0, pl = 0, nl = 0;
3943 CType t;
3944 t.ref = s;
3945 /* enum symbols have static storage */
3946 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
3947 for(;;) {
3948 v = tok;
3949 if (v < TOK_UIDENT)
3950 expect("identifier");
3951 ss = sym_find(v);
3952 if (ss && !local_stack)
3953 tcc_error("redefinition of enumerator '%s'",
3954 get_tok_str(v, NULL));
3955 next();
3956 if (tok == '=') {
3957 next();
3958 ll = expr_const64();
3960 ss = sym_push(v, &t, VT_CONST, 0);
3961 ss->enum_val = ll;
3962 *ps = ss, ps = &ss->next;
3963 if (ll < nl)
3964 nl = ll;
3965 if (ll > pl)
3966 pl = ll;
3967 if (tok != ',')
3968 break;
3969 next();
3970 ll++;
3971 /* NOTE: we accept a trailing comma */
3972 if (tok == '}')
3973 break;
3975 skip('}');
3976 /* set integral type of the enum */
3977 t.t = VT_INT;
3978 if (nl >= 0) {
3979 if (pl != (unsigned)pl)
3980 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
3981 t.t |= VT_UNSIGNED;
3982 } else if (pl != (int)pl || nl != (int)nl)
3983 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
3984 s->type.t = type->t = t.t | VT_ENUM;
3985 s->c = 0;
3986 /* set type for enum members */
3987 for (ss = s->next; ss; ss = ss->next) {
3988 ll = ss->enum_val;
3989 if (ll == (int)ll) /* default is int if it fits */
3990 continue;
3991 if (t.t & VT_UNSIGNED) {
3992 ss->type.t |= VT_UNSIGNED;
3993 if (ll == (unsigned)ll)
3994 continue;
3996 ss->type.t = (ss->type.t & ~VT_BTYPE)
3997 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
3999 } else {
4000 c = 0;
4001 flexible = 0;
4002 while (tok != '}') {
4003 if (!parse_btype(&btype, &ad1)) {
4004 skip(';');
4005 continue;
4007 while (1) {
4008 if (flexible)
4009 tcc_error("flexible array member '%s' not at the end of struct",
4010 get_tok_str(v, NULL));
4011 bit_size = -1;
4012 v = 0;
4013 type1 = btype;
4014 if (tok != ':') {
4015 if (tok != ';')
4016 type_decl(&type1, &ad1, &v, TYPE_DIRECT);
4017 if (v == 0) {
4018 if ((type1.t & VT_BTYPE) != VT_STRUCT)
4019 expect("identifier");
4020 else {
4021 int v = btype.ref->v;
4022 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
4023 if (tcc_state->ms_extensions == 0)
4024 expect("identifier");
4028 if (type_size(&type1, &align) < 0) {
4029 if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
4030 flexible = 1;
4031 else
4032 tcc_error("field '%s' has incomplete type",
4033 get_tok_str(v, NULL));
4035 if ((type1.t & VT_BTYPE) == VT_FUNC ||
4036 (type1.t & VT_BTYPE) == VT_VOID ||
4037 (type1.t & VT_STORAGE))
4038 tcc_error("invalid type for '%s'",
4039 get_tok_str(v, NULL));
4041 if (tok == ':') {
4042 next();
4043 bit_size = expr_const();
4044 /* XXX: handle v = 0 case for messages */
4045 if (bit_size < 0)
4046 tcc_error("negative width in bit-field '%s'",
4047 get_tok_str(v, NULL));
4048 if (v && bit_size == 0)
4049 tcc_error("zero width for bit-field '%s'",
4050 get_tok_str(v, NULL));
4051 parse_attribute(&ad1);
4053 size = type_size(&type1, &align);
4054 if (bit_size >= 0) {
4055 bt = type1.t & VT_BTYPE;
4056 if (bt != VT_INT &&
4057 bt != VT_BYTE &&
4058 bt != VT_SHORT &&
4059 bt != VT_BOOL &&
4060 bt != VT_LLONG)
4061 tcc_error("bitfields must have scalar type");
4062 bsize = size * 8;
4063 if (bit_size > bsize) {
4064 tcc_error("width of '%s' exceeds its type",
4065 get_tok_str(v, NULL));
4066 } else if (bit_size == bsize
4067 && !ad.a.packed && !ad1.a.packed) {
4068 /* no need for bit fields */
4070 } else if (bit_size == 64) {
4071 tcc_error("field width 64 not implemented");
4072 } else {
4073 type1.t = (type1.t & ~VT_STRUCT_MASK)
4074 | VT_BITFIELD
4075 | (bit_size << (VT_STRUCT_SHIFT + 6));
4078 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
4079 /* Remember we've seen a real field to check
4080 for placement of flexible array member. */
4081 c = 1;
4083 /* If member is a struct or bit-field, enforce
4084 placing into the struct (as anonymous). */
4085 if (v == 0 &&
4086 ((type1.t & VT_BTYPE) == VT_STRUCT ||
4087 bit_size >= 0)) {
4088 v = anon_sym++;
4090 if (v) {
4091 ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
4092 ss->a = ad1.a;
4093 *ps = ss;
4094 ps = &ss->next;
4096 if (tok == ';' || tok == TOK_EOF)
4097 break;
4098 skip(',');
4100 skip(';');
4102 skip('}');
4103 parse_attribute(&ad);
4104 struct_layout(type, &ad);
4109 static void sym_to_attr(AttributeDef *ad, Sym *s)
4111 merge_symattr(&ad->a, &s->a);
4112 merge_funcattr(&ad->f, &s->f);
4115 /* Add type qualifiers to a type. If the type is an array then the qualifiers
4116 are added to the element type, copied because it could be a typedef. */
4117 static void parse_btype_qualify(CType *type, int qualifiers)
4119 while (type->t & VT_ARRAY) {
4120 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
4121 type = &type->ref->type;
4123 type->t |= qualifiers;
4126 /* return 0 if no type declaration. otherwise, return the basic type
4127 and skip it.
4129 static int parse_btype(CType *type, AttributeDef *ad)
4131 int t, u, bt, st, type_found, typespec_found, g;
4132 Sym *s;
4133 CType type1;
4135 memset(ad, 0, sizeof(AttributeDef));
4136 type_found = 0;
4137 typespec_found = 0;
4138 t = VT_INT;
4139 bt = st = -1;
4140 type->ref = NULL;
4142 while(1) {
4143 switch(tok) {
4144 case TOK_EXTENSION:
4145 /* currently, we really ignore extension */
4146 next();
4147 continue;
4149 /* basic types */
4150 case TOK_CHAR:
4151 u = VT_BYTE;
4152 basic_type:
4153 next();
4154 basic_type1:
4155 if (u == VT_SHORT || u == VT_LONG) {
4156 if (st != -1 || (bt != -1 && bt != VT_INT))
4157 tmbt: tcc_error("too many basic types");
4158 st = u;
4159 } else {
4160 if (bt != -1 || (st != -1 && u != VT_INT))
4161 goto tmbt;
4162 bt = u;
4164 if (u != VT_INT)
4165 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
4166 typespec_found = 1;
4167 break;
4168 case TOK_VOID:
4169 u = VT_VOID;
4170 goto basic_type;
4171 case TOK_SHORT:
4172 u = VT_SHORT;
4173 goto basic_type;
4174 case TOK_INT:
4175 u = VT_INT;
4176 goto basic_type;
4177 case TOK_ALIGNAS:
4178 { int n;
4179 AttributeDef ad1;
4180 next();
4181 skip('(');
4182 memset(&ad1, 0, sizeof(AttributeDef));
4183 if (parse_btype(&type1, &ad1)) {
4184 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4185 if (ad1.a.aligned)
4186 n = 1 << (ad1.a.aligned - 1);
4187 else
4188 type_size(&type1, &n);
4189 } else {
4190 n = expr_const();
4191 if (n <= 0 || (n & (n - 1)) != 0)
4192 tcc_error("alignment must be a positive power of two");
4194 skip(')');
4195 ad->a.aligned = exact_log2p1(n);
4197 continue;
4198 case TOK_LONG:
4199 if ((t & VT_BTYPE) == VT_DOUBLE) {
4200 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
4201 } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4202 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
4203 } else {
4204 u = VT_LONG;
4205 goto basic_type;
4207 next();
4208 break;
4209 #ifdef TCC_TARGET_ARM64
4210 case TOK_UINT128:
4211 /* GCC's __uint128_t appears in some Linux header files. Make it a
4212 synonym for long double to get the size and alignment right. */
4213 u = VT_LDOUBLE;
4214 goto basic_type;
4215 #endif
4216 case TOK_BOOL:
4217 u = VT_BOOL;
4218 goto basic_type;
4219 case TOK_FLOAT:
4220 u = VT_FLOAT;
4221 goto basic_type;
4222 case TOK_DOUBLE:
4223 if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4224 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
4225 } else {
4226 u = VT_DOUBLE;
4227 goto basic_type;
4229 next();
4230 break;
4231 case TOK_ENUM:
4232 struct_decl(&type1, VT_ENUM);
4233 basic_type2:
4234 u = type1.t;
4235 type->ref = type1.ref;
4236 goto basic_type1;
4237 case TOK_STRUCT:
4238 struct_decl(&type1, VT_STRUCT);
4239 goto basic_type2;
4240 case TOK_UNION:
4241 struct_decl(&type1, VT_UNION);
4242 goto basic_type2;
4244 /* type modifiers */
4245 case TOK_CONST1:
4246 case TOK_CONST2:
4247 case TOK_CONST3:
4248 type->t = t;
4249 parse_btype_qualify(type, VT_CONSTANT);
4250 t = type->t;
4251 next();
4252 break;
4253 case TOK_VOLATILE1:
4254 case TOK_VOLATILE2:
4255 case TOK_VOLATILE3:
4256 type->t = t;
4257 parse_btype_qualify(type, VT_VOLATILE);
4258 t = type->t;
4259 next();
4260 break;
4261 case TOK_SIGNED1:
4262 case TOK_SIGNED2:
4263 case TOK_SIGNED3:
4264 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
4265 tcc_error("signed and unsigned modifier");
4266 t |= VT_DEFSIGN;
4267 next();
4268 typespec_found = 1;
4269 break;
4270 case TOK_REGISTER:
4271 case TOK_AUTO:
4272 case TOK_RESTRICT1:
4273 case TOK_RESTRICT2:
4274 case TOK_RESTRICT3:
4275 next();
4276 break;
4277 case TOK_UNSIGNED:
4278 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
4279 tcc_error("signed and unsigned modifier");
4280 t |= VT_DEFSIGN | VT_UNSIGNED;
4281 next();
4282 typespec_found = 1;
4283 break;
4285 /* storage */
4286 case TOK_EXTERN:
4287 g = VT_EXTERN;
4288 goto storage;
4289 case TOK_STATIC:
4290 g = VT_STATIC;
4291 goto storage;
4292 case TOK_TYPEDEF:
4293 g = VT_TYPEDEF;
4294 goto storage;
4295 storage:
4296 if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
4297 tcc_error("multiple storage classes");
4298 t |= g;
4299 next();
4300 break;
4301 case TOK_INLINE1:
4302 case TOK_INLINE2:
4303 case TOK_INLINE3:
4304 t |= VT_INLINE;
4305 next();
4306 break;
4307 case TOK_NORETURN3:
4308 /* currently, no need to handle it because tcc does not
4309 track unused objects */
4310 next();
4311 break;
4312 /* GNUC attribute */
4313 case TOK_ATTRIBUTE1:
4314 case TOK_ATTRIBUTE2:
4315 parse_attribute(ad);
4316 if (ad->attr_mode) {
4317 u = ad->attr_mode -1;
4318 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
4320 continue;
4321 /* GNUC typeof */
4322 case TOK_TYPEOF1:
4323 case TOK_TYPEOF2:
4324 case TOK_TYPEOF3:
4325 next();
4326 parse_expr_type(&type1);
4327 /* remove all storage modifiers except typedef */
4328 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
4329 if (type1.ref)
4330 sym_to_attr(ad, type1.ref);
4331 goto basic_type2;
4332 default:
4333 if (typespec_found)
4334 goto the_end;
4335 s = sym_find(tok);
4336 if (!s || !(s->type.t & VT_TYPEDEF))
4337 goto the_end;
4338 t &= ~(VT_BTYPE|VT_LONG);
4339 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
4340 type->t = (s->type.t & ~VT_TYPEDEF) | u;
4341 type->ref = s->type.ref;
4342 if (t)
4343 parse_btype_qualify(type, t);
4344 t = type->t;
4345 /* get attributes from typedef */
4346 sym_to_attr(ad, s);
4347 next();
4348 typespec_found = 1;
4349 st = bt = -2;
4350 break;
4352 type_found = 1;
4354 the_end:
4355 if (tcc_state->char_is_unsigned) {
4356 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
4357 t |= VT_UNSIGNED;
4359 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
4360 bt = t & (VT_BTYPE|VT_LONG);
4361 if (bt == VT_LONG)
4362 t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
4363 #ifdef TCC_TARGET_PE
4364 if (bt == VT_LDOUBLE)
4365 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE;
4366 #endif
4367 type->t = t;
4368 return type_found;
4371 /* convert a function parameter type (array to pointer and function to
4372 function pointer) */
4373 static inline void convert_parameter_type(CType *pt)
4375 /* remove const and volatile qualifiers (XXX: const could be used
4376 to indicate a const function parameter */
4377 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
4378 /* array must be transformed to pointer according to ANSI C */
4379 pt->t &= ~VT_ARRAY;
4380 if ((pt->t & VT_BTYPE) == VT_FUNC) {
4381 mk_pointer(pt);
4385 ST_FUNC void parse_asm_str(CString *astr)
4387 skip('(');
4388 parse_mult_str(astr, "string constant");
4391 /* Parse an asm label and return the token */
4392 static int asm_label_instr(void)
4394 int v;
4395 CString astr;
4397 next();
4398 parse_asm_str(&astr);
4399 skip(')');
4400 #ifdef ASM_DEBUG
4401 printf("asm_alias: \"%s\"\n", (char *)astr.data);
4402 #endif
4403 v = tok_alloc(astr.data, astr.size - 1)->tok;
4404 cstr_free(&astr);
4405 return v;
4408 static int post_type(CType *type, AttributeDef *ad, int storage, int td)
4410 int n, l, t1, arg_size, align;
4411 Sym **plast, *s, *first;
4412 AttributeDef ad1;
4413 CType pt;
4415 if (tok == '(') {
4416 /* function type, or recursive declarator (return if so) */
4417 next();
4418 if (td && !(td & TYPE_ABSTRACT))
4419 return 0;
4420 if (tok == ')')
4421 l = 0;
4422 else if (parse_btype(&pt, &ad1))
4423 l = FUNC_NEW;
4424 else if (td) {
4425 merge_attr (ad, &ad1);
4426 return 0;
4427 } else
4428 l = FUNC_OLD;
4429 first = NULL;
4430 plast = &first;
4431 arg_size = 0;
4432 if (l) {
4433 for(;;) {
4434 /* read param name and compute offset */
4435 if (l != FUNC_OLD) {
4436 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
4437 break;
4438 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
4439 if ((pt.t & VT_BTYPE) == VT_VOID)
4440 tcc_error("parameter declared as void");
4441 } else {
4442 n = tok;
4443 if (n < TOK_UIDENT)
4444 expect("identifier");
4445 pt.t = VT_VOID; /* invalid type */
4446 next();
4448 convert_parameter_type(&pt);
4449 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
4450 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
4451 *plast = s;
4452 plast = &s->next;
4453 if (tok == ')')
4454 break;
4455 skip(',');
4456 if (l == FUNC_NEW && tok == TOK_DOTS) {
4457 l = FUNC_ELLIPSIS;
4458 next();
4459 break;
4461 if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
4462 tcc_error("invalid type");
4464 } else
4465 /* if no parameters, then old type prototype */
4466 l = FUNC_OLD;
4467 skip(')');
4468 /* NOTE: const is ignored in returned type as it has a special
4469 meaning in gcc / C++ */
4470 type->t &= ~VT_CONSTANT;
4471 /* some ancient pre-K&R C allows a function to return an array
4472 and the array brackets to be put after the arguments, such
4473 that "int c()[]" means something like "int[] c()" */
4474 if (tok == '[') {
4475 next();
4476 skip(']'); /* only handle simple "[]" */
4477 mk_pointer(type);
4479 /* we push a anonymous symbol which will contain the function prototype */
4480 ad->f.func_args = arg_size;
4481 ad->f.func_type = l;
4482 s = sym_push(SYM_FIELD, type, 0, 0);
4483 s->a = ad->a;
4484 s->f = ad->f;
4485 s->next = first;
4486 type->t = VT_FUNC;
4487 type->ref = s;
4488 } else if (tok == '[') {
4489 int saved_nocode_wanted = nocode_wanted;
4490 /* array definition */
4491 next();
4492 while (1) {
4493 /* XXX The optional type-quals and static should only be accepted
4494 in parameter decls. The '*' as well, and then even only
4495 in prototypes (not function defs). */
4496 switch (tok) {
4497 case TOK_RESTRICT1: case TOK_RESTRICT2: case TOK_RESTRICT3:
4498 case TOK_CONST1:
4499 case TOK_VOLATILE1:
4500 case TOK_STATIC:
4501 case '*':
4502 next();
4503 continue;
4504 default:
4505 break;
4507 break;
4509 n = -1;
4510 t1 = 0;
4511 if (tok != ']') {
4512 if (!local_stack || (storage & VT_STATIC))
4513 vpushi(expr_const());
4514 else {
4515 /* VLAs (which can only happen with local_stack && !VT_STATIC)
4516 length must always be evaluated, even under nocode_wanted,
4517 so that its size slot is initialized (e.g. under sizeof
4518 or typeof). */
4519 nocode_wanted = 0;
4520 gexpr();
4522 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4523 n = vtop->c.i;
4524 if (n < 0)
4525 tcc_error("invalid array size");
4526 } else {
4527 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
4528 tcc_error("size of variable length array should be an integer");
4529 n = 0;
4530 t1 = VT_VLA;
4533 skip(']');
4534 /* parse next post type */
4535 post_type(type, ad, storage, 0);
4536 if (type->t == VT_FUNC)
4537 tcc_error("declaration of an array of functions");
4538 t1 |= type->t & VT_VLA;
4540 if (t1 & VT_VLA) {
4541 if (n < 0)
4542 tcc_error("need explicit inner array size in VLAs");
4543 loc -= type_size(&int_type, &align);
4544 loc &= -align;
4545 n = loc;
4547 vla_runtime_type_size(type, &align);
4548 gen_op('*');
4549 vset(&int_type, VT_LOCAL|VT_LVAL, n);
4550 vswap();
4551 vstore();
4553 if (n != -1)
4554 vpop();
4555 nocode_wanted = saved_nocode_wanted;
4557 /* we push an anonymous symbol which will contain the array
4558 element type */
4559 s = sym_push(SYM_FIELD, type, 0, n);
4560 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
4561 type->ref = s;
4563 return 1;
4566 /* Parse a type declarator (except basic type), and return the type
4567 in 'type'. 'td' is a bitmask indicating which kind of type decl is
4568 expected. 'type' should contain the basic type. 'ad' is the
4569 attribute definition of the basic type. It can be modified by
4570 type_decl(). If this (possibly abstract) declarator is a pointer chain
4571 it returns the innermost pointed to type (equals *type, but is a different
4572 pointer), otherwise returns type itself, that's used for recursive calls. */
4573 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
4575 CType *post, *ret;
4576 int qualifiers, storage;
4578 /* recursive type, remove storage bits first, apply them later again */
4579 storage = type->t & VT_STORAGE;
4580 type->t &= ~VT_STORAGE;
4581 post = ret = type;
4583 while (tok == '*') {
4584 qualifiers = 0;
4585 redo:
4586 next();
4587 switch(tok) {
4588 case TOK_CONST1:
4589 case TOK_CONST2:
4590 case TOK_CONST3:
4591 qualifiers |= VT_CONSTANT;
4592 goto redo;
4593 case TOK_VOLATILE1:
4594 case TOK_VOLATILE2:
4595 case TOK_VOLATILE3:
4596 qualifiers |= VT_VOLATILE;
4597 goto redo;
4598 case TOK_RESTRICT1:
4599 case TOK_RESTRICT2:
4600 case TOK_RESTRICT3:
4601 goto redo;
4602 /* XXX: clarify attribute handling */
4603 case TOK_ATTRIBUTE1:
4604 case TOK_ATTRIBUTE2:
4605 parse_attribute(ad);
4606 break;
4608 mk_pointer(type);
4609 type->t |= qualifiers;
4610 if (ret == type)
4611 /* innermost pointed to type is the one for the first derivation */
4612 ret = pointed_type(type);
4615 if (tok == '(') {
4616 /* This is possibly a parameter type list for abstract declarators
4617 ('int ()'), use post_type for testing this. */
4618 if (!post_type(type, ad, 0, td)) {
4619 /* It's not, so it's a nested declarator, and the post operations
4620 apply to the innermost pointed to type (if any). */
4621 /* XXX: this is not correct to modify 'ad' at this point, but
4622 the syntax is not clear */
4623 parse_attribute(ad);
4624 post = type_decl(type, ad, v, td);
4625 skip(')');
4626 } else
4627 goto abstract;
4628 } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
4629 /* type identifier */
4630 *v = tok;
4631 next();
4632 } else {
4633 abstract:
4634 if (!(td & TYPE_ABSTRACT))
4635 expect("identifier");
4636 *v = 0;
4638 post_type(post, ad, storage, 0);
4639 parse_attribute(ad);
4640 type->t |= storage;
4641 return ret;
4644 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4645 ST_FUNC int lvalue_type(int t)
4647 int bt, r;
4648 r = VT_LVAL;
4649 bt = t & VT_BTYPE;
4650 if (bt == VT_BYTE || bt == VT_BOOL)
4651 r |= VT_LVAL_BYTE;
4652 else if (bt == VT_SHORT)
4653 r |= VT_LVAL_SHORT;
4654 else
4655 return r;
4656 if (t & VT_UNSIGNED)
4657 r |= VT_LVAL_UNSIGNED;
4658 return r;
4661 /* indirection with full error checking and bound check */
4662 ST_FUNC void indir(void)
4664 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
4665 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
4666 return;
4667 expect("pointer");
4669 if (vtop->r & VT_LVAL)
4670 gv(RC_INT);
4671 vtop->type = *pointed_type(&vtop->type);
4672 /* Arrays and functions are never lvalues */
4673 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
4674 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
4675 vtop->r |= lvalue_type(vtop->type.t);
4676 /* if bound checking, the referenced pointer must be checked */
4677 #ifdef CONFIG_TCC_BCHECK
4678 if (tcc_state->do_bounds_check)
4679 vtop->r |= VT_MUSTBOUND;
4680 #endif
4684 /* pass a parameter to a function and do type checking and casting */
4685 static void gfunc_param_typed(Sym *func, Sym *arg)
4687 int func_type;
4688 CType type;
4690 func_type = func->f.func_type;
4691 if (func_type == FUNC_OLD ||
4692 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
4693 /* default casting : only need to convert float to double */
4694 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
4695 gen_cast_s(VT_DOUBLE);
4696 } else if (vtop->type.t & VT_BITFIELD) {
4697 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
4698 type.ref = vtop->type.ref;
4699 gen_cast(&type);
4701 } else if (arg == NULL) {
4702 tcc_error("too many arguments to function");
4703 } else {
4704 type = arg->type;
4705 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4706 gen_assign_cast(&type);
4710 /* parse an expression and return its type without any side effect. */
4711 static void expr_type(CType *type, void (*expr_fn)(void))
4713 nocode_wanted++;
4714 expr_fn();
4715 *type = vtop->type;
4716 vpop();
4717 nocode_wanted--;
4720 /* parse an expression of the form '(type)' or '(expr)' and return its
4721 type */
4722 static void parse_expr_type(CType *type)
4724 int n;
4725 AttributeDef ad;
4727 skip('(');
4728 if (parse_btype(type, &ad)) {
4729 type_decl(type, &ad, &n, TYPE_ABSTRACT);
4730 } else {
4731 expr_type(type, gexpr);
4733 skip(')');
4736 static void parse_type(CType *type)
4738 AttributeDef ad;
4739 int n;
4741 if (!parse_btype(type, &ad)) {
4742 expect("type");
4744 type_decl(type, &ad, &n, TYPE_ABSTRACT);
4747 static void parse_builtin_params(int nc, const char *args)
4749 char c, sep = '(';
4750 CType t;
4751 if (nc)
4752 nocode_wanted++;
4753 next();
4754 while ((c = *args++)) {
4755 skip(sep);
4756 sep = ',';
4757 switch (c) {
4758 case 'e': expr_eq(); continue;
4759 case 't': parse_type(&t); vpush(&t); continue;
4760 default: tcc_error("internal error"); break;
4763 skip(')');
4764 if (nc)
4765 nocode_wanted--;
4768 static void try_call_scope_cleanup(Sym *stop)
4770 Sym *cls = current_cleanups;
4772 for (; cls != stop; cls = cls->ncl) {
4773 Sym *fs = cls->next;
4774 Sym *vs = cls->prev_tok;
4776 vpushsym(&fs->type, fs);
4777 vset(&vs->type, vs->r, vs->c);
4778 vtop->sym = vs;
4779 mk_pointer(&vtop->type);
4780 gaddrof();
4781 gfunc_call(1);
4785 static void try_call_cleanup_goto(Sym *cleanupstate)
4787 Sym *oc, *cc;
4788 int ocd, ccd;
4790 if (!current_cleanups)
4791 return;
4793 /* search NCA of both cleanup chains given parents and initial depth */
4794 ocd = cleanupstate ? cleanupstate->v & ~SYM_FIELD : 0;
4795 for (ccd = ncleanups, oc = cleanupstate; ocd > ccd; --ocd, oc = oc->ncl)
4797 for (cc = current_cleanups; ccd > ocd; --ccd, cc = cc->ncl)
4799 for (; cc != oc; cc = cc->ncl, oc = oc->ncl, --ccd)
4802 try_call_scope_cleanup(cc);
4805 ST_FUNC void unary(void)
4807 int n, t, align, size, r, sizeof_caller;
4808 CType type;
4809 Sym *s;
4810 AttributeDef ad;
4812 sizeof_caller = in_sizeof;
4813 in_sizeof = 0;
4814 type.ref = NULL;
4815 /* XXX: GCC 2.95.3 does not generate a table although it should be
4816 better here */
4817 tok_next:
4818 switch(tok) {
4819 case TOK_EXTENSION:
4820 next();
4821 goto tok_next;
4822 case TOK_LCHAR:
4823 #ifdef TCC_TARGET_PE
4824 t = VT_SHORT|VT_UNSIGNED;
4825 goto push_tokc;
4826 #endif
4827 case TOK_CINT:
4828 case TOK_CCHAR:
4829 t = VT_INT;
4830 push_tokc:
4831 type.t = t;
4832 vsetc(&type, VT_CONST, &tokc);
4833 next();
4834 break;
4835 case TOK_CUINT:
4836 t = VT_INT | VT_UNSIGNED;
4837 goto push_tokc;
4838 case TOK_CLLONG:
4839 t = VT_LLONG;
4840 goto push_tokc;
4841 case TOK_CULLONG:
4842 t = VT_LLONG | VT_UNSIGNED;
4843 goto push_tokc;
4844 case TOK_CFLOAT:
4845 t = VT_FLOAT;
4846 goto push_tokc;
4847 case TOK_CDOUBLE:
4848 t = VT_DOUBLE;
4849 goto push_tokc;
4850 case TOK_CLDOUBLE:
4851 t = VT_LDOUBLE;
4852 goto push_tokc;
4853 case TOK_CLONG:
4854 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
4855 goto push_tokc;
4856 case TOK_CULONG:
4857 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
4858 goto push_tokc;
4859 case TOK___FUNCTION__:
4860 if (!gnu_ext)
4861 goto tok_identifier;
4862 /* fall thru */
4863 case TOK___FUNC__:
4865 void *ptr;
4866 int len;
4867 /* special function name identifier */
4868 len = strlen(funcname) + 1;
4869 /* generate char[len] type */
4870 type.t = VT_BYTE;
4871 mk_pointer(&type);
4872 type.t |= VT_ARRAY;
4873 type.ref->c = len;
4874 vpush_ref(&type, data_section, data_section->data_offset, len);
4875 if (!NODATA_WANTED) {
4876 ptr = section_ptr_add(data_section, len);
4877 memcpy(ptr, funcname, len);
4879 next();
4881 break;
4882 case TOK_LSTR:
4883 #ifdef TCC_TARGET_PE
4884 t = VT_SHORT | VT_UNSIGNED;
4885 #else
4886 t = VT_INT;
4887 #endif
4888 goto str_init;
4889 case TOK_STR:
4890 /* string parsing */
4891 t = VT_BYTE;
4892 if (tcc_state->char_is_unsigned)
4893 t = VT_BYTE | VT_UNSIGNED;
4894 str_init:
4895 if (tcc_state->warn_write_strings)
4896 t |= VT_CONSTANT;
4897 type.t = t;
4898 mk_pointer(&type);
4899 type.t |= VT_ARRAY;
4900 memset(&ad, 0, sizeof(AttributeDef));
4901 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
4902 break;
4903 case '(':
4904 next();
4905 /* cast ? */
4906 if (parse_btype(&type, &ad)) {
4907 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
4908 skip(')');
4909 /* check ISOC99 compound literal */
4910 if (tok == '{') {
4911 /* data is allocated locally by default */
4912 if (global_expr)
4913 r = VT_CONST;
4914 else
4915 r = VT_LOCAL;
4916 /* all except arrays are lvalues */
4917 if (!(type.t & VT_ARRAY))
4918 r |= lvalue_type(type.t);
4919 memset(&ad, 0, sizeof(AttributeDef));
4920 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
4921 } else {
4922 if (sizeof_caller) {
4923 vpush(&type);
4924 return;
4926 unary();
4927 gen_cast(&type);
4929 } else if (tok == '{') {
4930 int saved_nocode_wanted = nocode_wanted;
4931 if (const_wanted)
4932 tcc_error("expected constant");
4933 /* save all registers */
4934 save_regs(0);
4935 /* statement expression : we do not accept break/continue
4936 inside as GCC does. We do retain the nocode_wanted state,
4937 as statement expressions can't ever be entered from the
4938 outside, so any reactivation of code emission (from labels
4939 or loop heads) can be disabled again after the end of it. */
4940 block(NULL, NULL, 1);
4941 nocode_wanted = saved_nocode_wanted;
4942 skip(')');
4943 } else {
4944 gexpr();
4945 skip(')');
4947 break;
4948 case '*':
4949 next();
4950 unary();
4951 indir();
4952 break;
4953 case '&':
4954 next();
4955 unary();
4956 /* functions names must be treated as function pointers,
4957 except for unary '&' and sizeof. Since we consider that
4958 functions are not lvalues, we only have to handle it
4959 there and in function calls. */
4960 /* arrays can also be used although they are not lvalues */
4961 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
4962 !(vtop->type.t & VT_ARRAY))
4963 test_lvalue();
4964 mk_pointer(&vtop->type);
4965 gaddrof();
4966 break;
4967 case '!':
4968 next();
4969 unary();
4970 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4971 gen_cast_s(VT_BOOL);
4972 vtop->c.i = !vtop->c.i;
4973 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
4974 vtop->c.i ^= 1;
4975 else {
4976 save_regs(1);
4977 vseti(VT_JMP, gvtst(1, 0));
4979 break;
4980 case '~':
4981 next();
4982 unary();
4983 vpushi(-1);
4984 gen_op('^');
4985 break;
4986 case '+':
4987 next();
4988 unary();
4989 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
4990 tcc_error("pointer not accepted for unary plus");
4991 /* In order to force cast, we add zero, except for floating point
4992 where we really need an noop (otherwise -0.0 will be transformed
4993 into +0.0). */
4994 if (!is_float(vtop->type.t)) {
4995 vpushi(0);
4996 gen_op('+');
4998 break;
4999 case TOK_SIZEOF:
5000 case TOK_ALIGNOF1:
5001 case TOK_ALIGNOF2:
5002 case TOK_ALIGNOF3:
5003 t = tok;
5004 next();
5005 in_sizeof++;
5006 expr_type(&type, unary); /* Perform a in_sizeof = 0; */
5007 s = vtop[1].sym; /* hack: accessing previous vtop */
5008 size = type_size(&type, &align);
5009 if (s && s->a.aligned)
5010 align = 1 << (s->a.aligned - 1);
5011 if (t == TOK_SIZEOF) {
5012 if (!(type.t & VT_VLA)) {
5013 if (size < 0)
5014 tcc_error("sizeof applied to an incomplete type");
5015 vpushs(size);
5016 } else {
5017 vla_runtime_type_size(&type, &align);
5019 } else {
5020 vpushs(align);
5022 vtop->type.t |= VT_UNSIGNED;
5023 break;
5025 case TOK_builtin_expect:
5026 /* __builtin_expect is a no-op for now */
5027 parse_builtin_params(0, "ee");
5028 vpop();
5029 break;
5030 case TOK_builtin_types_compatible_p:
5031 parse_builtin_params(0, "tt");
5032 vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
5033 vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
5034 n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
5035 vtop -= 2;
5036 vpushi(n);
5037 break;
5038 case TOK_builtin_choose_expr:
5040 int64_t c;
5041 next();
5042 skip('(');
5043 c = expr_const64();
5044 skip(',');
5045 if (!c) {
5046 nocode_wanted++;
5048 expr_eq();
5049 if (!c) {
5050 vpop();
5051 nocode_wanted--;
5053 skip(',');
5054 if (c) {
5055 nocode_wanted++;
5057 expr_eq();
5058 if (c) {
5059 vpop();
5060 nocode_wanted--;
5062 skip(')');
5064 break;
5065 case TOK_builtin_constant_p:
5066 parse_builtin_params(1, "e");
5067 n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5068 vtop--;
5069 vpushi(n);
5070 break;
5071 case TOK_builtin_frame_address:
5072 case TOK_builtin_return_address:
5074 int tok1 = tok;
5075 int level;
5076 next();
5077 skip('(');
5078 if (tok != TOK_CINT) {
5079 tcc_error("%s only takes positive integers",
5080 tok1 == TOK_builtin_return_address ?
5081 "__builtin_return_address" :
5082 "__builtin_frame_address");
5084 level = (uint32_t)tokc.i;
5085 next();
5086 skip(')');
5087 type.t = VT_VOID;
5088 mk_pointer(&type);
5089 vset(&type, VT_LOCAL, 0); /* local frame */
5090 while (level--) {
5091 mk_pointer(&vtop->type);
5092 indir(); /* -> parent frame */
5094 if (tok1 == TOK_builtin_return_address) {
5095 // assume return address is just above frame pointer on stack
5096 vpushi(PTR_SIZE);
5097 gen_op('+');
5098 mk_pointer(&vtop->type);
5099 indir();
5102 break;
5103 #ifdef TCC_TARGET_X86_64
5104 #ifdef TCC_TARGET_PE
5105 case TOK_builtin_va_start:
5106 parse_builtin_params(0, "ee");
5107 r = vtop->r & VT_VALMASK;
5108 if (r == VT_LLOCAL)
5109 r = VT_LOCAL;
5110 if (r != VT_LOCAL)
5111 tcc_error("__builtin_va_start expects a local variable");
5112 vtop->r = r;
5113 vtop->type = char_pointer_type;
5114 vtop->c.i += 8;
5115 vstore();
5116 break;
5117 #else
5118 case TOK_builtin_va_arg_types:
5119 parse_builtin_params(0, "t");
5120 vpushi(classify_x86_64_va_arg(&vtop->type));
5121 vswap();
5122 vpop();
5123 break;
5124 #endif
5125 #endif
5127 #ifdef TCC_TARGET_ARM64
5128 case TOK___va_start: {
5129 parse_builtin_params(0, "ee");
5130 //xx check types
5131 gen_va_start();
5132 vpushi(0);
5133 vtop->type.t = VT_VOID;
5134 break;
5136 case TOK___va_arg: {
5137 parse_builtin_params(0, "et");
5138 type = vtop->type;
5139 vpop();
5140 //xx check types
5141 gen_va_arg(&type);
5142 vtop->type = type;
5143 break;
5145 case TOK___arm64_clear_cache: {
5146 parse_builtin_params(0, "ee");
5147 gen_clear_cache();
5148 vpushi(0);
5149 vtop->type.t = VT_VOID;
5150 break;
5152 #endif
5153 /* pre operations */
5154 case TOK_INC:
5155 case TOK_DEC:
5156 t = tok;
5157 next();
5158 unary();
5159 inc(0, t);
5160 break;
5161 case '-':
5162 next();
5163 unary();
5164 t = vtop->type.t & VT_BTYPE;
5165 if (is_float(t)) {
5166 /* In IEEE negate(x) isn't subtract(0,x), but rather
5167 subtract(-0, x). */
5168 vpush(&vtop->type);
5169 if (t == VT_FLOAT)
5170 vtop->c.f = -1.0 * 0.0;
5171 else if (t == VT_DOUBLE)
5172 vtop->c.d = -1.0 * 0.0;
5173 else
5174 vtop->c.ld = -1.0 * 0.0;
5175 } else
5176 vpushi(0);
5177 vswap();
5178 gen_op('-');
5179 break;
5180 case TOK_LAND:
5181 if (!gnu_ext)
5182 goto tok_identifier;
5183 next();
5184 /* allow to take the address of a label */
5185 if (tok < TOK_UIDENT)
5186 expect("label identifier");
5187 s = label_find(tok);
5188 if (!s) {
5189 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5190 } else {
5191 if (s->r == LABEL_DECLARED)
5192 s->r = LABEL_FORWARD;
5194 if (!s->type.t) {
5195 s->type.t = VT_VOID;
5196 mk_pointer(&s->type);
5197 s->type.t |= VT_STATIC;
5199 vpushsym(&s->type, s);
5200 next();
5201 break;
5203 case TOK_GENERIC:
5205 CType controlling_type;
5206 int has_default = 0;
5207 int has_match = 0;
5208 int learn = 0;
5209 TokenString *str = NULL;
5210 int saved_const_wanted = const_wanted;
5212 next();
5213 skip('(');
5214 const_wanted = 0;
5215 expr_type(&controlling_type, expr_eq);
5216 controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
5217 if ((controlling_type.t & VT_BTYPE) == VT_FUNC)
5218 mk_pointer(&controlling_type);
5219 const_wanted = saved_const_wanted;
5220 for (;;) {
5221 learn = 0;
5222 skip(',');
5223 if (tok == TOK_DEFAULT) {
5224 if (has_default)
5225 tcc_error("too many 'default'");
5226 has_default = 1;
5227 if (!has_match)
5228 learn = 1;
5229 next();
5230 } else {
5231 AttributeDef ad_tmp;
5232 int itmp;
5233 CType cur_type;
5234 parse_btype(&cur_type, &ad_tmp);
5235 type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
5236 if (compare_types(&controlling_type, &cur_type, 0)) {
5237 if (has_match) {
5238 tcc_error("type match twice");
5240 has_match = 1;
5241 learn = 1;
5244 skip(':');
5245 if (learn) {
5246 if (str)
5247 tok_str_free(str);
5248 skip_or_save_block(&str);
5249 } else {
5250 skip_or_save_block(NULL);
5252 if (tok == ')')
5253 break;
5255 if (!str) {
5256 char buf[60];
5257 type_to_str(buf, sizeof buf, &controlling_type, NULL);
5258 tcc_error("type '%s' does not match any association", buf);
5260 begin_macro(str, 1);
5261 next();
5262 expr_eq();
5263 if (tok != TOK_EOF)
5264 expect(",");
5265 end_macro();
5266 next();
5267 break;
5269 // special qnan , snan and infinity values
5270 case TOK___NAN__:
5271 n = 0x7fc00000;
5272 special_math_val:
5273 vpushi(n);
5274 vtop->type.t = VT_FLOAT;
5275 next();
5276 break;
5277 case TOK___SNAN__:
5278 n = 0x7f800001;
5279 goto special_math_val;
5280 case TOK___INF__:
5281 n = 0x7f800000;
5282 goto special_math_val;
5284 default:
5285 tok_identifier:
5286 t = tok;
5287 next();
5288 if (t < TOK_UIDENT)
5289 expect("identifier");
5290 s = sym_find(t);
5291 if (!s || IS_ASM_SYM(s)) {
5292 const char *name = get_tok_str(t, NULL);
5293 if (tok != '(')
5294 tcc_error("'%s' undeclared", name);
5295 /* for simple function calls, we tolerate undeclared
5296 external reference to int() function */
5297 if (tcc_state->warn_implicit_function_declaration
5298 #ifdef TCC_TARGET_PE
5299 /* people must be warned about using undeclared WINAPI functions
5300 (which usually start with uppercase letter) */
5301 || (name[0] >= 'A' && name[0] <= 'Z')
5302 #endif
5304 tcc_warning("implicit declaration of function '%s'", name);
5305 s = external_global_sym(t, &func_old_type, 0);
5308 r = s->r;
5309 /* A symbol that has a register is a local register variable,
5310 which starts out as VT_LOCAL value. */
5311 if ((r & VT_VALMASK) < VT_CONST)
5312 r = (r & ~VT_VALMASK) | VT_LOCAL;
5314 vset(&s->type, r, s->c);
5315 /* Point to s as backpointer (even without r&VT_SYM).
5316 Will be used by at least the x86 inline asm parser for
5317 regvars. */
5318 vtop->sym = s;
5320 if (r & VT_SYM) {
5321 vtop->c.i = 0;
5322 } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
5323 vtop->c.i = s->enum_val;
5325 break;
5328 /* post operations */
5329 while (1) {
5330 if (tok == TOK_INC || tok == TOK_DEC) {
5331 inc(1, tok);
5332 next();
5333 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
5334 int qualifiers;
5335 /* field */
5336 if (tok == TOK_ARROW)
5337 indir();
5338 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
5339 test_lvalue();
5340 gaddrof();
5341 /* expect pointer on structure */
5342 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
5343 expect("struct or union");
5344 if (tok == TOK_CDOUBLE)
5345 expect("field name");
5346 next();
5347 if (tok == TOK_CINT || tok == TOK_CUINT)
5348 expect("field name");
5349 s = find_field(&vtop->type, tok);
5350 if (!s)
5351 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
5352 /* add field offset to pointer */
5353 vtop->type = char_pointer_type; /* change type to 'char *' */
5354 vpushi(s->c);
5355 gen_op('+');
5356 /* change type to field type, and set to lvalue */
5357 vtop->type = s->type;
5358 vtop->type.t |= qualifiers;
5359 /* an array is never an lvalue */
5360 if (!(vtop->type.t & VT_ARRAY)) {
5361 vtop->r |= lvalue_type(vtop->type.t);
5362 #ifdef CONFIG_TCC_BCHECK
5363 /* if bound checking, the referenced pointer must be checked */
5364 if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL)
5365 vtop->r |= VT_MUSTBOUND;
5366 #endif
5368 next();
5369 } else if (tok == '[') {
5370 next();
5371 gexpr();
5372 gen_op('+');
5373 indir();
5374 skip(']');
5375 } else if (tok == '(') {
5376 SValue ret;
5377 Sym *sa;
5378 int nb_args, ret_nregs, ret_align, regsize, variadic;
5380 /* function call */
5381 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
5382 /* pointer test (no array accepted) */
5383 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5384 vtop->type = *pointed_type(&vtop->type);
5385 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
5386 goto error_func;
5387 } else {
5388 error_func:
5389 expect("function pointer");
5391 } else {
5392 vtop->r &= ~VT_LVAL; /* no lvalue */
5394 /* get return type */
5395 s = vtop->type.ref;
5396 next();
5397 sa = s->next; /* first parameter */
5398 nb_args = regsize = 0;
5399 ret.r2 = VT_CONST;
5400 /* compute first implicit argument if a structure is returned */
5401 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
5402 variadic = (s->f.func_type == FUNC_ELLIPSIS);
5403 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
5404 &ret_align, &regsize);
5405 if (!ret_nregs) {
5406 /* get some space for the returned structure */
5407 size = type_size(&s->type, &align);
5408 #ifdef TCC_TARGET_ARM64
5409 /* On arm64, a small struct is return in registers.
5410 It is much easier to write it to memory if we know
5411 that we are allowed to write some extra bytes, so
5412 round the allocated space up to a power of 2: */
5413 if (size < 16)
5414 while (size & (size - 1))
5415 size = (size | (size - 1)) + 1;
5416 #endif
5417 loc = (loc - size) & -align;
5418 ret.type = s->type;
5419 ret.r = VT_LOCAL | VT_LVAL;
5420 /* pass it as 'int' to avoid structure arg passing
5421 problems */
5422 vseti(VT_LOCAL, loc);
5423 ret.c = vtop->c;
5424 nb_args++;
5426 } else {
5427 ret_nregs = 1;
5428 ret.type = s->type;
5431 if (ret_nregs) {
5432 /* return in register */
5433 if (is_float(ret.type.t)) {
5434 ret.r = reg_fret(ret.type.t);
5435 #ifdef TCC_TARGET_X86_64
5436 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
5437 ret.r2 = REG_QRET;
5438 #endif
5439 } else {
5440 #ifndef TCC_TARGET_ARM64
5441 #ifdef TCC_TARGET_X86_64
5442 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
5443 #else
5444 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
5445 #endif
5446 ret.r2 = REG_LRET;
5447 #endif
5448 ret.r = REG_IRET;
5450 ret.c.i = 0;
5452 if (tok != ')') {
5453 for(;;) {
5454 expr_eq();
5455 gfunc_param_typed(s, sa);
5456 nb_args++;
5457 if (sa)
5458 sa = sa->next;
5459 if (tok == ')')
5460 break;
5461 skip(',');
5464 if (sa)
5465 tcc_error("too few arguments to function");
5466 skip(')');
5467 gfunc_call(nb_args);
5469 /* return value */
5470 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
5471 vsetc(&ret.type, r, &ret.c);
5472 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
5475 /* handle packed struct return */
5476 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
5477 int addr, offset;
5479 size = type_size(&s->type, &align);
5480 /* We're writing whole regs often, make sure there's enough
5481 space. Assume register size is power of 2. */
5482 if (regsize > align)
5483 align = regsize;
5484 loc = (loc - size) & -align;
5485 addr = loc;
5486 offset = 0;
5487 for (;;) {
5488 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
5489 vswap();
5490 vstore();
5491 vtop--;
5492 if (--ret_nregs == 0)
5493 break;
5494 offset += regsize;
5496 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
5498 } else {
5499 break;
5504 ST_FUNC void expr_prod(void)
5506 int t;
5508 unary();
5509 while (tok == '*' || tok == '/' || tok == '%') {
5510 t = tok;
5511 next();
5512 unary();
5513 gen_op(t);
5517 ST_FUNC void expr_sum(void)
5519 int t;
5521 expr_prod();
5522 while (tok == '+' || tok == '-') {
5523 t = tok;
5524 next();
5525 expr_prod();
5526 gen_op(t);
5530 static void expr_shift(void)
5532 int t;
5534 expr_sum();
5535 while (tok == TOK_SHL || tok == TOK_SAR) {
5536 t = tok;
5537 next();
5538 expr_sum();
5539 gen_op(t);
5543 static void expr_cmp(void)
5545 int t;
5547 expr_shift();
5548 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
5549 tok == TOK_ULT || tok == TOK_UGE) {
5550 t = tok;
5551 next();
5552 expr_shift();
5553 gen_op(t);
5557 static void expr_cmpeq(void)
5559 int t;
5561 expr_cmp();
5562 while (tok == TOK_EQ || tok == TOK_NE) {
5563 t = tok;
5564 next();
5565 expr_cmp();
5566 gen_op(t);
5570 static void expr_and(void)
5572 expr_cmpeq();
5573 while (tok == '&') {
5574 next();
5575 expr_cmpeq();
5576 gen_op('&');
5580 static void expr_xor(void)
5582 expr_and();
5583 while (tok == '^') {
5584 next();
5585 expr_and();
5586 gen_op('^');
5590 static void expr_or(void)
5592 expr_xor();
5593 while (tok == '|') {
5594 next();
5595 expr_xor();
5596 gen_op('|');
5600 static void expr_land(void)
5602 expr_or();
5603 if (tok == TOK_LAND) {
5604 int t = 0;
5605 for(;;) {
5606 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
5607 gen_cast_s(VT_BOOL);
5608 if (vtop->c.i) {
5609 vpop();
5610 } else {
5611 nocode_wanted++;
5612 while (tok == TOK_LAND) {
5613 next();
5614 expr_or();
5615 vpop();
5617 nocode_wanted--;
5618 if (t)
5619 gsym(t);
5620 gen_cast_s(VT_INT);
5621 break;
5623 } else {
5624 if (!t)
5625 save_regs(1);
5626 t = gvtst(1, t);
5628 if (tok != TOK_LAND) {
5629 if (t)
5630 vseti(VT_JMPI, t);
5631 else
5632 vpushi(1);
5633 break;
5635 next();
5636 expr_or();
5641 static void expr_lor(void)
5643 expr_land();
5644 if (tok == TOK_LOR) {
5645 int t = 0;
5646 for(;;) {
5647 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
5648 gen_cast_s(VT_BOOL);
5649 if (!vtop->c.i) {
5650 vpop();
5651 } else {
5652 nocode_wanted++;
5653 while (tok == TOK_LOR) {
5654 next();
5655 expr_land();
5656 vpop();
5658 nocode_wanted--;
5659 if (t)
5660 gsym(t);
5661 gen_cast_s(VT_INT);
5662 break;
5664 } else {
5665 if (!t)
5666 save_regs(1);
5667 t = gvtst(0, t);
5669 if (tok != TOK_LOR) {
5670 if (t)
5671 vseti(VT_JMP, t);
5672 else
5673 vpushi(0);
5674 break;
5676 next();
5677 expr_land();
5682 /* Assuming vtop is a value used in a conditional context
5683 (i.e. compared with zero) return 0 if it's false, 1 if
5684 true and -1 if it can't be statically determined. */
5685 static int condition_3way(void)
5687 int c = -1;
5688 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
5689 (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
5690 vdup();
5691 gen_cast_s(VT_BOOL);
5692 c = vtop->c.i;
5693 vpop();
5695 return c;
5698 static void expr_cond(void)
5700 int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g;
5701 SValue sv;
5702 CType type, type1, type2;
5704 expr_lor();
5705 if (tok == '?') {
5706 next();
5707 c = condition_3way();
5708 g = (tok == ':' && gnu_ext);
5709 if (c < 0) {
5710 /* needed to avoid having different registers saved in
5711 each branch */
5712 if (is_float(vtop->type.t)) {
5713 rc = RC_FLOAT;
5714 #ifdef TCC_TARGET_X86_64
5715 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
5716 rc = RC_ST0;
5718 #endif
5719 } else
5720 rc = RC_INT;
5721 gv(rc);
5722 save_regs(1);
5723 if (g)
5724 gv_dup();
5725 tt = gvtst(1, 0);
5727 } else {
5728 if (!g)
5729 vpop();
5730 tt = 0;
5733 if (1) {
5734 if (c == 0)
5735 nocode_wanted++;
5736 if (!g)
5737 gexpr();
5739 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
5740 mk_pointer(&vtop->type);
5741 type1 = vtop->type;
5742 sv = *vtop; /* save value to handle it later */
5743 vtop--; /* no vpop so that FP stack is not flushed */
5744 skip(':');
5746 u = 0;
5747 if (c < 0)
5748 u = gjmp(0);
5749 gsym(tt);
5751 if (c == 0)
5752 nocode_wanted--;
5753 if (c == 1)
5754 nocode_wanted++;
5755 expr_cond();
5756 if (c == 1)
5757 nocode_wanted--;
5759 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
5760 mk_pointer(&vtop->type);
5761 type2=vtop->type;
5762 t1 = type1.t;
5763 bt1 = t1 & VT_BTYPE;
5764 t2 = type2.t;
5765 bt2 = t2 & VT_BTYPE;
5766 type.ref = NULL;
5769 /* cast operands to correct type according to ISOC rules */
5770 if (bt1 == VT_VOID || bt2 == VT_VOID) {
5771 type.t = VT_VOID; /* NOTE: as an extension, we accept void on only one side */
5772 } else if (is_float(bt1) || is_float(bt2)) {
5773 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5774 type.t = VT_LDOUBLE;
5776 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5777 type.t = VT_DOUBLE;
5778 } else {
5779 type.t = VT_FLOAT;
5781 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5782 /* cast to biggest op */
5783 type.t = VT_LLONG | VT_LONG;
5784 if (bt1 == VT_LLONG)
5785 type.t &= t1;
5786 if (bt2 == VT_LLONG)
5787 type.t &= t2;
5788 /* convert to unsigned if it does not fit in a long long */
5789 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
5790 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
5791 type.t |= VT_UNSIGNED;
5792 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
5793 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
5794 /* If one is a null ptr constant the result type
5795 is the other. */
5796 if (is_null_pointer (vtop)) type = type1;
5797 else if (is_null_pointer (&sv)) type = type2;
5798 else if (bt1 != bt2)
5799 tcc_error("incompatible types in conditional expressions");
5800 else {
5801 CType *pt1 = pointed_type(&type1);
5802 CType *pt2 = pointed_type(&type2);
5803 int pbt1 = pt1->t & VT_BTYPE;
5804 int pbt2 = pt2->t & VT_BTYPE;
5805 int newquals, copied = 0;
5806 /* pointers to void get preferred, otherwise the
5807 pointed to types minus qualifs should be compatible */
5808 type = (pbt1 == VT_VOID) ? type1 : type2;
5809 if (pbt1 != VT_VOID && pbt2 != VT_VOID) {
5810 if(!compare_types(pt1, pt2, 1/*unqualif*/))
5811 tcc_warning("pointer type mismatch in conditional expression\n");
5813 /* combine qualifs */
5814 newquals = ((pt1->t | pt2->t) & (VT_CONSTANT | VT_VOLATILE));
5815 if ((~pointed_type(&type)->t & (VT_CONSTANT | VT_VOLATILE))
5816 & newquals)
5818 /* copy the pointer target symbol */
5819 type.ref = sym_push(SYM_FIELD, &type.ref->type,
5820 0, type.ref->c);
5821 copied = 1;
5822 pointed_type(&type)->t |= newquals;
5824 /* pointers to incomplete arrays get converted to
5825 pointers to completed ones if possible */
5826 if (pt1->t & VT_ARRAY
5827 && pt2->t & VT_ARRAY
5828 && pointed_type(&type)->ref->c < 0
5829 && (pt1->ref->c > 0 || pt2->ref->c > 0))
5831 if (!copied)
5832 type.ref = sym_push(SYM_FIELD, &type.ref->type,
5833 0, type.ref->c);
5834 pointed_type(&type)->ref =
5835 sym_push(SYM_FIELD, &pointed_type(&type)->ref->type,
5836 0, pointed_type(&type)->ref->c);
5837 pointed_type(&type)->ref->c =
5838 0 < pt1->ref->c ? pt1->ref->c : pt2->ref->c;
5841 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5842 /* XXX: test structure compatibility */
5843 type = bt1 == VT_STRUCT ? type1 : type2;
5844 } else {
5845 /* integer operations */
5846 type.t = VT_INT | (VT_LONG & (t1 | t2));
5847 /* convert to unsigned if it does not fit in an integer */
5848 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
5849 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
5850 type.t |= VT_UNSIGNED;
5852 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
5853 that `(expr ? a : b).mem` does not error with "lvalue expected" */
5854 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
5856 /* now we convert second operand */
5857 if (c != 1) {
5858 gen_cast(&type);
5859 if (islv) {
5860 mk_pointer(&vtop->type);
5861 gaddrof();
5862 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
5863 gaddrof();
5866 rc = RC_INT;
5867 if (is_float(type.t)) {
5868 rc = RC_FLOAT;
5869 #ifdef TCC_TARGET_X86_64
5870 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
5871 rc = RC_ST0;
5873 #endif
5874 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
5875 /* for long longs, we use fixed registers to avoid having
5876 to handle a complicated move */
5877 rc = RC_IRET;
5880 tt = r2 = 0;
5881 if (c < 0) {
5882 r2 = gv(rc);
5883 tt = gjmp(0);
5885 gsym(u);
5887 /* this is horrible, but we must also convert first
5888 operand */
5889 if (c != 0) {
5890 *vtop = sv;
5891 gen_cast(&type);
5892 if (islv) {
5893 mk_pointer(&vtop->type);
5894 gaddrof();
5895 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
5896 gaddrof();
5899 if (c < 0 || islv) {
5900 r1 = gv(rc);
5901 move_reg(r2, r1, type.t);
5902 vtop->r = r2;
5903 gsym(tt);
5904 if (islv)
5905 indir();
5911 static void expr_eq(void)
5913 int t;
5915 expr_cond();
5916 if (tok == '=' ||
5917 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5918 tok == TOK_A_XOR || tok == TOK_A_OR ||
5919 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5920 test_lvalue();
5921 t = tok;
5922 next();
5923 if (t == '=') {
5924 expr_eq();
5925 } else {
5926 vdup();
5927 expr_eq();
5928 gen_op(t & 0x7f);
5930 vstore();
5934 ST_FUNC void gexpr(void)
5936 while (1) {
5937 expr_eq();
5938 if (tok != ',')
5939 break;
5940 vpop();
5941 next();
5945 /* parse a constant expression and return value in vtop. */
5946 static void expr_const1(void)
5948 const_wanted++;
5949 nocode_wanted++;
5950 expr_cond();
5951 nocode_wanted--;
5952 const_wanted--;
5955 /* parse an integer constant and return its value. */
5956 static inline int64_t expr_const64(void)
5958 int64_t c;
5959 expr_const1();
5960 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5961 expect("constant expression");
5962 c = vtop->c.i;
5963 vpop();
5964 return c;
5967 /* parse an integer constant and return its value.
5968 Complain if it doesn't fit 32bit (signed or unsigned). */
5969 ST_FUNC int expr_const(void)
5971 int c;
5972 int64_t wc = expr_const64();
5973 c = wc;
5974 if (c != wc && (unsigned)c != wc)
5975 tcc_error("constant exceeds 32 bit");
5976 return c;
5979 /* return the label token if current token is a label, otherwise
5980 return zero */
5981 static int is_label(void)
5983 int last_tok;
5985 /* fast test first */
5986 if (tok < TOK_UIDENT)
5987 return 0;
5988 /* no need to save tokc because tok is an identifier */
5989 last_tok = tok;
5990 next();
5991 if (tok == ':') {
5992 return last_tok;
5993 } else {
5994 unget_tok(last_tok);
5995 return 0;
5999 #ifndef TCC_TARGET_ARM64
6000 static void gfunc_return(CType *func_type)
6002 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
6003 CType type, ret_type;
6004 int ret_align, ret_nregs, regsize;
6005 ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
6006 &ret_align, &regsize);
6007 if (0 == ret_nregs) {
6008 /* if returning structure, must copy it to implicit
6009 first pointer arg location */
6010 type = *func_type;
6011 mk_pointer(&type);
6012 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
6013 indir();
6014 vswap();
6015 /* copy structure value to pointer */
6016 vstore();
6017 } else {
6018 /* returning structure packed into registers */
6019 int r, size, addr, align;
6020 size = type_size(func_type,&align);
6021 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
6022 (vtop->c.i & (ret_align-1)))
6023 && (align & (ret_align-1))) {
6024 loc = (loc - size) & -ret_align;
6025 addr = loc;
6026 type = *func_type;
6027 vset(&type, VT_LOCAL | VT_LVAL, addr);
6028 vswap();
6029 vstore();
6030 vpop();
6031 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
6033 vtop->type = ret_type;
6034 if (is_float(ret_type.t))
6035 r = rc_fret(ret_type.t);
6036 else
6037 r = RC_IRET;
6039 if (ret_nregs == 1)
6040 gv(r);
6041 else {
6042 for (;;) {
6043 vdup();
6044 gv(r);
6045 vpop();
6046 if (--ret_nregs == 0)
6047 break;
6048 /* We assume that when a structure is returned in multiple
6049 registers, their classes are consecutive values of the
6050 suite s(n) = 2^n */
6051 r <<= 1;
6052 vtop->c.i += regsize;
6056 } else if (is_float(func_type->t)) {
6057 gv(rc_fret(func_type->t));
6058 } else {
6059 gv(RC_IRET);
6061 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6063 #endif
6065 static int case_cmp(const void *pa, const void *pb)
6067 int64_t a = (*(struct case_t**) pa)->v1;
6068 int64_t b = (*(struct case_t**) pb)->v1;
6069 return a < b ? -1 : a > b;
6072 static void gcase(struct case_t **base, int len, int *bsym)
6074 struct case_t *p;
6075 int e;
6076 int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
6077 gv(RC_INT);
6078 while (len > 4) {
6079 /* binary search */
6080 p = base[len/2];
6081 vdup();
6082 if (ll)
6083 vpushll(p->v2);
6084 else
6085 vpushi(p->v2);
6086 gen_op(TOK_LE);
6087 e = gtst(1, 0);
6088 vdup();
6089 if (ll)
6090 vpushll(p->v1);
6091 else
6092 vpushi(p->v1);
6093 gen_op(TOK_GE);
6094 gtst_addr(0, p->sym); /* v1 <= x <= v2 */
6095 /* x < v1 */
6096 gcase(base, len/2, bsym);
6097 if (cur_switch->def_sym)
6098 gjmp_addr(cur_switch->def_sym);
6099 else
6100 *bsym = gjmp(*bsym);
6101 /* x > v2 */
6102 gsym(e);
6103 e = len/2 + 1;
6104 base += e; len -= e;
6106 /* linear scan */
6107 while (len--) {
6108 p = *base++;
6109 vdup();
6110 if (ll)
6111 vpushll(p->v2);
6112 else
6113 vpushi(p->v2);
6114 if (p->v1 == p->v2) {
6115 gen_op(TOK_EQ);
6116 gtst_addr(0, p->sym);
6117 } else {
6118 gen_op(TOK_LE);
6119 e = gtst(1, 0);
6120 vdup();
6121 if (ll)
6122 vpushll(p->v1);
6123 else
6124 vpushi(p->v1);
6125 gen_op(TOK_GE);
6126 gtst_addr(0, p->sym);
6127 gsym(e);
6132 static void block(int *bsym, int *csym, int is_expr)
6134 int a, b, c, d, cond;
6135 Sym *s;
6137 /* generate line number info */
6138 if (tcc_state->do_debug)
6139 tcc_debug_line(tcc_state);
6141 if (is_expr) {
6142 /* default return value is (void) */
6143 vpushi(0);
6144 vtop->type.t = VT_VOID;
6147 if (tok == TOK_IF) {
6148 /* if test */
6149 int saved_nocode_wanted = nocode_wanted;
6150 next();
6151 skip('(');
6152 gexpr();
6153 skip(')');
6154 cond = condition_3way();
6155 if (cond == 1)
6156 a = 0, vpop();
6157 else
6158 a = gvtst(1, 0);
6159 if (cond == 0)
6160 nocode_wanted |= 0x20000000;
6161 block(bsym, csym, 0);
6162 if (cond != 1)
6163 nocode_wanted = saved_nocode_wanted;
6164 if (tok == TOK_ELSE) {
6165 next();
6166 d = gjmp(0);
6167 gsym(a);
6168 if (cond == 1)
6169 nocode_wanted |= 0x20000000;
6170 block(bsym, csym, 0);
6171 gsym(d); /* patch else jmp */
6172 if (cond != 0)
6173 nocode_wanted = saved_nocode_wanted;
6174 } else
6175 gsym(a);
6176 } else if (tok == TOK_WHILE) {
6177 int saved_nocode_wanted;
6178 nocode_wanted &= ~0x20000000;
6179 next();
6180 d = ind;
6181 vla_sp_restore();
6182 skip('(');
6183 gexpr();
6184 skip(')');
6185 a = gvtst(1, 0);
6186 b = 0;
6187 ++local_scope;
6188 saved_nocode_wanted = nocode_wanted;
6189 block(&a, &b, 0);
6190 nocode_wanted = saved_nocode_wanted;
6191 --local_scope;
6192 gjmp_addr(d);
6193 gsym(a);
6194 gsym_addr(b, d);
6195 } else if (tok == '{') {
6196 Sym *llabel, *lcleanup;
6197 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
6198 int lncleanups = ncleanups;
6200 next();
6201 /* record local declaration stack position */
6202 s = local_stack;
6203 llabel = local_label_stack;
6204 lcleanup = current_cleanups;
6205 ++local_scope;
6207 /* handle local labels declarations */
6208 while (tok == TOK_LABEL) {
6209 next();
6210 for(;;) {
6211 if (tok < TOK_UIDENT)
6212 expect("label identifier");
6213 label_push(&local_label_stack, tok, LABEL_DECLARED);
6214 next();
6215 if (tok == ',') {
6216 next();
6217 } else {
6218 skip(';');
6219 break;
6223 while (tok != '}') {
6224 if ((a = is_label()))
6225 unget_tok(a);
6226 else
6227 decl(VT_LOCAL);
6228 if (tok != '}') {
6229 if (is_expr)
6230 vpop();
6231 block(bsym, csym, is_expr);
6235 if (current_cleanups != lcleanup) {
6236 int jmp = 0;
6237 Sym *g, **pg;
6239 for (pg = &pending_gotos; (g = *pg) && g->c > lncleanups;)
6240 if (g->prev_tok->r & LABEL_FORWARD) {
6241 Sym *pcl = g->next;
6242 if (!jmp)
6243 jmp = gjmp(0);
6244 gsym(pcl->jnext);
6245 try_call_scope_cleanup(lcleanup);
6246 pcl->jnext = gjmp(0);
6247 if (!lncleanups)
6248 goto remove_pending;
6249 g->c = lncleanups;
6250 pg = &g->prev;
6251 } else {
6252 remove_pending:
6253 *pg = g->prev;
6254 sym_free(g);
6256 gsym(jmp);
6257 if (!nocode_wanted) {
6258 try_call_scope_cleanup(lcleanup);
6262 current_cleanups = lcleanup;
6263 ncleanups = lncleanups;
6264 /* pop locally defined labels */
6265 label_pop(&local_label_stack, llabel, is_expr);
6266 /* pop locally defined symbols */
6267 --local_scope;
6268 /* In the is_expr case (a statement expression is finished here),
6269 vtop might refer to symbols on the local_stack. Either via the
6270 type or via vtop->sym. We can't pop those nor any that in turn
6271 might be referred to. To make it easier we don't roll back
6272 any symbols in that case; some upper level call to block() will
6273 do that. We do have to remove such symbols from the lookup
6274 tables, though. sym_pop will do that. */
6275 sym_pop(&local_stack, s, is_expr);
6277 /* Pop VLA frames and restore stack pointer if required */
6278 if (vlas_in_scope > saved_vlas_in_scope) {
6279 vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
6280 vla_sp_restore();
6282 vlas_in_scope = saved_vlas_in_scope;
6284 next();
6285 } else if (tok == TOK_RETURN) {
6286 next();
6287 if (tok != ';') {
6288 gexpr();
6289 gen_assign_cast(&func_vt);
6290 try_call_scope_cleanup(NULL);
6291 if ((func_vt.t & VT_BTYPE) == VT_VOID)
6292 vtop--;
6293 else
6294 gfunc_return(&func_vt);
6295 } else {
6296 try_call_scope_cleanup(NULL);
6298 skip(';');
6299 /* jump unless last stmt in top-level block */
6300 if (tok != '}' || local_scope != 1)
6301 rsym = gjmp(rsym);
6302 nocode_wanted |= 0x20000000;
6303 } else if (tok == TOK_BREAK) {
6304 /* compute jump */
6305 if (!bsym)
6306 tcc_error("cannot break");
6307 *bsym = gjmp(*bsym);
6308 next();
6309 skip(';');
6310 nocode_wanted |= 0x20000000;
6311 } else if (tok == TOK_CONTINUE) {
6312 /* compute jump */
6313 if (!csym)
6314 tcc_error("cannot continue");
6315 vla_sp_restore_root();
6316 *csym = gjmp(*csym);
6317 next();
6318 skip(';');
6319 nocode_wanted |= 0x20000000;
6320 } else if (tok == TOK_FOR) {
6321 int e;
6322 int saved_nocode_wanted;
6323 nocode_wanted &= ~0x20000000;
6324 next();
6325 skip('(');
6326 s = local_stack;
6327 ++local_scope;
6328 if (tok != ';') {
6329 /* c99 for-loop init decl? */
6330 if (!decl0(VT_LOCAL, 1, NULL)) {
6331 /* no, regular for-loop init expr */
6332 gexpr();
6333 vpop();
6336 skip(';');
6337 d = ind;
6338 c = ind;
6339 vla_sp_restore();
6340 a = 0;
6341 b = 0;
6342 if (tok != ';') {
6343 gexpr();
6344 a = gvtst(1, 0);
6346 skip(';');
6347 if (tok != ')') {
6348 e = gjmp(0);
6349 c = ind;
6350 vla_sp_restore();
6351 gexpr();
6352 vpop();
6353 gjmp_addr(d);
6354 gsym(e);
6356 skip(')');
6357 saved_nocode_wanted = nocode_wanted;
6358 block(&a, &b, 0);
6359 nocode_wanted = saved_nocode_wanted;
6360 gjmp_addr(c);
6361 gsym(a);
6362 gsym_addr(b, c);
6363 --local_scope;
6364 sym_pop(&local_stack, s, 0);
6366 } else
6367 if (tok == TOK_DO) {
6368 int saved_nocode_wanted;
6369 nocode_wanted &= ~0x20000000;
6370 next();
6371 a = 0;
6372 b = 0;
6373 d = ind;
6374 vla_sp_restore();
6375 saved_nocode_wanted = nocode_wanted;
6376 block(&a, &b, 0);
6377 skip(TOK_WHILE);
6378 skip('(');
6379 gsym(b);
6380 if (b)
6381 nocode_wanted = saved_nocode_wanted;
6382 gexpr();
6383 c = gvtst(0, 0);
6384 gsym_addr(c, d);
6385 nocode_wanted = saved_nocode_wanted;
6386 skip(')');
6387 gsym(a);
6388 skip(';');
6389 } else
6390 if (tok == TOK_SWITCH) {
6391 struct switch_t *saved, sw;
6392 int saved_nocode_wanted = nocode_wanted;
6393 SValue switchval;
6394 next();
6395 skip('(');
6396 gexpr();
6397 skip(')');
6398 switchval = *vtop--;
6399 a = 0;
6400 b = gjmp(0); /* jump to first case */
6401 sw.p = NULL; sw.n = 0; sw.def_sym = 0;
6402 saved = cur_switch;
6403 cur_switch = &sw;
6404 block(&a, csym, 0);
6405 nocode_wanted = saved_nocode_wanted;
6406 a = gjmp(a); /* add implicit break */
6407 /* case lookup */
6408 gsym(b);
6409 qsort(sw.p, sw.n, sizeof(void*), case_cmp);
6410 for (b = 1; b < sw.n; b++)
6411 if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
6412 tcc_error("duplicate case value");
6413 /* Our switch table sorting is signed, so the compared
6414 value needs to be as well when it's 64bit. */
6415 if ((switchval.type.t & VT_BTYPE) == VT_LLONG)
6416 switchval.type.t &= ~VT_UNSIGNED;
6417 vpushv(&switchval);
6418 gcase(sw.p, sw.n, &a);
6419 vpop();
6420 if (sw.def_sym)
6421 gjmp_addr(sw.def_sym);
6422 dynarray_reset(&sw.p, &sw.n);
6423 cur_switch = saved;
6424 /* break label */
6425 gsym(a);
6426 } else
6427 if (tok == TOK_CASE) {
6428 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
6429 if (!cur_switch)
6430 expect("switch");
6431 nocode_wanted &= ~0x20000000;
6432 next();
6433 cr->v1 = cr->v2 = expr_const64();
6434 if (gnu_ext && tok == TOK_DOTS) {
6435 next();
6436 cr->v2 = expr_const64();
6437 if (cr->v2 < cr->v1)
6438 tcc_warning("empty case range");
6440 cr->sym = ind;
6441 dynarray_add(&cur_switch->p, &cur_switch->n, cr);
6442 skip(':');
6443 is_expr = 0;
6444 goto block_after_label;
6445 } else
6446 if (tok == TOK_DEFAULT) {
6447 next();
6448 skip(':');
6449 if (!cur_switch)
6450 expect("switch");
6451 if (cur_switch->def_sym)
6452 tcc_error("too many 'default'");
6453 cur_switch->def_sym = ind;
6454 is_expr = 0;
6455 goto block_after_label;
6456 } else
6457 if (tok == TOK_GOTO) {
6458 next();
6459 if (tok == '*' && gnu_ext) {
6460 /* computed goto */
6461 next();
6462 gexpr();
6463 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6464 expect("pointer");
6465 ggoto();
6466 } else if (tok >= TOK_UIDENT) {
6467 s = label_find(tok);
6468 /* put forward definition if needed */
6469 if (!s)
6470 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
6471 else if (s->r == LABEL_DECLARED)
6472 s->r = LABEL_FORWARD;
6474 vla_sp_restore_root();
6475 if (s->r & LABEL_FORWARD) {
6476 /* start new goto chain for cleanups, linked via label->next */
6477 if (current_cleanups) {
6478 sym_push2(&pending_gotos, SYM_FIELD, 0, ncleanups);
6479 pending_gotos->prev_tok = s;
6480 s = sym_push2(&s->next, SYM_FIELD, 0, 0);
6481 pending_gotos->next = s;
6483 s->jnext = gjmp(s->jnext);
6484 } else {
6485 try_call_cleanup_goto(s->cleanupstate);
6486 gjmp_addr(s->jnext);
6488 next();
6489 } else {
6490 expect("label identifier");
6492 skip(';');
6493 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
6494 asm_instr();
6495 } else {
6496 b = is_label();
6497 if (b) {
6498 /* label case */
6499 next();
6500 s = label_find(b);
6501 if (s) {
6502 if (s->r == LABEL_DEFINED)
6503 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
6504 s->r = LABEL_DEFINED;
6505 if (s->next) {
6506 Sym *pcl; /* pending cleanup goto */
6507 for (pcl = s->next; pcl; pcl = pcl->prev)
6508 gsym(pcl->jnext);
6509 sym_pop(&s->next, NULL, 0);
6510 } else
6511 gsym(s->jnext);
6512 } else {
6513 s = label_push(&global_label_stack, b, LABEL_DEFINED);
6515 s->jnext = ind;
6516 s->cleanupstate = current_cleanups;
6517 vla_sp_restore();
6518 /* we accept this, but it is a mistake */
6519 block_after_label:
6520 nocode_wanted &= ~0x20000000;
6521 if (tok == '}') {
6522 tcc_warning("deprecated use of label at end of compound statement");
6523 } else {
6524 if (is_expr)
6525 vpop();
6526 block(bsym, csym, is_expr);
6528 } else {
6529 /* expression case */
6530 if (tok != ';') {
6531 if (is_expr) {
6532 vpop();
6533 gexpr();
6534 } else {
6535 gexpr();
6536 vpop();
6539 skip(';');
6544 /* This skips over a stream of tokens containing balanced {} and ()
6545 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
6546 with a '{'). If STR then allocates and stores the skipped tokens
6547 in *STR. This doesn't check if () and {} are nested correctly,
6548 i.e. "({)}" is accepted. */
6549 static void skip_or_save_block(TokenString **str)
6551 int braces = tok == '{';
6552 int level = 0;
6553 if (str)
6554 *str = tok_str_alloc();
6556 while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
6557 int t;
6558 if (tok == TOK_EOF) {
6559 if (str || level > 0)
6560 tcc_error("unexpected end of file");
6561 else
6562 break;
6564 if (str)
6565 tok_str_add_tok(*str);
6566 t = tok;
6567 next();
6568 if (t == '{' || t == '(') {
6569 level++;
6570 } else if (t == '}' || t == ')') {
6571 level--;
6572 if (level == 0 && braces && t == '}')
6573 break;
6576 if (str) {
6577 tok_str_add(*str, -1);
6578 tok_str_add(*str, 0);
6582 #define EXPR_CONST 1
6583 #define EXPR_ANY 2
6585 static void parse_init_elem(int expr_type)
6587 int saved_global_expr;
6588 switch(expr_type) {
6589 case EXPR_CONST:
6590 /* compound literals must be allocated globally in this case */
6591 saved_global_expr = global_expr;
6592 global_expr = 1;
6593 expr_const1();
6594 global_expr = saved_global_expr;
6595 /* NOTE: symbols are accepted, as well as lvalue for anon symbols
6596 (compound literals). */
6597 if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
6598 && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
6599 || vtop->sym->v < SYM_FIRST_ANOM))
6600 #ifdef TCC_TARGET_PE
6601 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
6602 #endif
6604 tcc_error("initializer element is not constant");
6605 break;
6606 case EXPR_ANY:
6607 expr_eq();
6608 break;
6612 /* put zeros for variable based init */
6613 static void init_putz(Section *sec, unsigned long c, int size)
6615 if (sec) {
6616 /* nothing to do because globals are already set to zero */
6617 } else {
6618 vpush_global_sym(&func_old_type, TOK_memset);
6619 vseti(VT_LOCAL, c);
6620 #ifdef TCC_TARGET_ARM
6621 vpushs(size);
6622 vpushi(0);
6623 #else
6624 vpushi(0);
6625 vpushs(size);
6626 #endif
6627 gfunc_call(3);
6631 #define DIF_FIRST 1
6632 #define DIF_SIZE_ONLY 2
6633 #define DIF_HAVE_ELEM 4
6635 /* t is the array or struct type. c is the array or struct
6636 address. cur_field is the pointer to the current
6637 field, for arrays the 'c' member contains the current start
6638 index. 'flags' is as in decl_initializer.
6639 'al' contains the already initialized length of the
6640 current container (starting at c). This returns the new length of that. */
6641 static int decl_designator(CType *type, Section *sec, unsigned long c,
6642 Sym **cur_field, int flags, int al)
6644 Sym *s, *f;
6645 int index, index_last, align, l, nb_elems, elem_size;
6646 unsigned long corig = c;
6648 elem_size = 0;
6649 nb_elems = 1;
6650 if (flags & DIF_HAVE_ELEM)
6651 goto no_designator;
6652 if (gnu_ext && (l = is_label()) != 0)
6653 goto struct_field;
6654 /* NOTE: we only support ranges for last designator */
6655 while (nb_elems == 1 && (tok == '[' || tok == '.')) {
6656 if (tok == '[') {
6657 if (!(type->t & VT_ARRAY))
6658 expect("array type");
6659 next();
6660 index = index_last = expr_const();
6661 if (tok == TOK_DOTS && gnu_ext) {
6662 next();
6663 index_last = expr_const();
6665 skip(']');
6666 s = type->ref;
6667 if (index < 0 || (s->c >= 0 && index_last >= s->c) ||
6668 index_last < index)
6669 tcc_error("invalid index");
6670 if (cur_field)
6671 (*cur_field)->c = index_last;
6672 type = pointed_type(type);
6673 elem_size = type_size(type, &align);
6674 c += index * elem_size;
6675 nb_elems = index_last - index + 1;
6676 } else {
6677 next();
6678 l = tok;
6679 struct_field:
6680 next();
6681 if ((type->t & VT_BTYPE) != VT_STRUCT)
6682 expect("struct/union type");
6683 f = find_field(type, l);
6684 if (!f)
6685 expect("field");
6686 if (cur_field)
6687 *cur_field = f;
6688 type = &f->type;
6689 c += f->c;
6691 cur_field = NULL;
6693 if (!cur_field) {
6694 if (tok == '=') {
6695 next();
6696 } else if (!gnu_ext) {
6697 expect("=");
6699 } else {
6700 no_designator:
6701 if (type->t & VT_ARRAY) {
6702 index = (*cur_field)->c;
6703 if (type->ref->c >= 0 && index >= type->ref->c)
6704 tcc_error("index too large");
6705 type = pointed_type(type);
6706 c += index * type_size(type, &align);
6707 } else {
6708 f = *cur_field;
6709 while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
6710 *cur_field = f = f->next;
6711 if (!f)
6712 tcc_error("too many field init");
6713 type = &f->type;
6714 c += f->c;
6717 /* must put zero in holes (note that doing it that way
6718 ensures that it even works with designators) */
6719 if (!(flags & DIF_SIZE_ONLY) && c - corig > al)
6720 init_putz(sec, corig + al, c - corig - al);
6721 decl_initializer(type, sec, c, flags & ~DIF_FIRST);
6723 /* XXX: make it more general */
6724 if (!(flags & DIF_SIZE_ONLY) && nb_elems > 1) {
6725 unsigned long c_end;
6726 uint8_t *src, *dst;
6727 int i;
6729 if (!sec) {
6730 vset(type, VT_LOCAL|VT_LVAL, c);
6731 for (i = 1; i < nb_elems; i++) {
6732 vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
6733 vswap();
6734 vstore();
6736 vpop();
6737 } else if (!NODATA_WANTED) {
6738 c_end = c + nb_elems * elem_size;
6739 if (c_end > sec->data_allocated)
6740 section_realloc(sec, c_end);
6741 src = sec->data + c;
6742 dst = src;
6743 for(i = 1; i < nb_elems; i++) {
6744 dst += elem_size;
6745 memcpy(dst, src, elem_size);
6749 c += nb_elems * type_size(type, &align);
6750 if (c - corig > al)
6751 al = c - corig;
6752 return al;
6755 /* store a value or an expression directly in global data or in local array */
6756 static void init_putv(CType *type, Section *sec, unsigned long c)
6758 int bt;
6759 void *ptr;
6760 CType dtype;
6762 dtype = *type;
6763 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
6765 if (sec) {
6766 int size, align;
6767 /* XXX: not portable */
6768 /* XXX: generate error if incorrect relocation */
6769 gen_assign_cast(&dtype);
6770 bt = type->t & VT_BTYPE;
6772 if ((vtop->r & VT_SYM)
6773 && bt != VT_PTR
6774 && bt != VT_FUNC
6775 && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
6776 || (type->t & VT_BITFIELD))
6777 && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
6779 tcc_error("initializer element is not computable at load time");
6781 if (NODATA_WANTED) {
6782 vtop--;
6783 return;
6786 size = type_size(type, &align);
6787 section_reserve(sec, c + size);
6788 ptr = sec->data + c;
6790 /* XXX: make code faster ? */
6791 if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
6792 vtop->sym->v >= SYM_FIRST_ANOM &&
6793 /* XXX This rejects compound literals like
6794 '(void *){ptr}'. The problem is that '&sym' is
6795 represented the same way, which would be ruled out
6796 by the SYM_FIRST_ANOM check above, but also '"string"'
6797 in 'char *p = "string"' is represented the same
6798 with the type being VT_PTR and the symbol being an
6799 anonymous one. That is, there's no difference in vtop
6800 between '(void *){x}' and '&(void *){x}'. Ignore
6801 pointer typed entities here. Hopefully no real code
6802 will every use compound literals with scalar type. */
6803 (vtop->type.t & VT_BTYPE) != VT_PTR) {
6804 /* These come from compound literals, memcpy stuff over. */
6805 Section *ssec;
6806 ElfSym *esym;
6807 ElfW_Rel *rel;
6808 esym = elfsym(vtop->sym);
6809 ssec = tcc_state->sections[esym->st_shndx];
6810 memmove (ptr, ssec->data + esym->st_value, size);
6811 if (ssec->reloc) {
6812 /* We need to copy over all memory contents, and that
6813 includes relocations. Use the fact that relocs are
6814 created it order, so look from the end of relocs
6815 until we hit one before the copied region. */
6816 int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
6817 rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
6818 while (num_relocs--) {
6819 rel--;
6820 if (rel->r_offset >= esym->st_value + size)
6821 continue;
6822 if (rel->r_offset < esym->st_value)
6823 break;
6824 /* Note: if the same fields are initialized multiple
6825 times (possible with designators) then we possibly
6826 add multiple relocations for the same offset here.
6827 That would lead to wrong code, the last reloc needs
6828 to win. We clean this up later after the whole
6829 initializer is parsed. */
6830 put_elf_reloca(symtab_section, sec,
6831 c + rel->r_offset - esym->st_value,
6832 ELFW(R_TYPE)(rel->r_info),
6833 ELFW(R_SYM)(rel->r_info),
6834 #if PTR_SIZE == 8
6835 rel->r_addend
6836 #else
6838 #endif
6842 } else {
6843 if (type->t & VT_BITFIELD) {
6844 int bit_pos, bit_size, bits, n;
6845 unsigned char *p, v, m;
6846 bit_pos = BIT_POS(vtop->type.t);
6847 bit_size = BIT_SIZE(vtop->type.t);
6848 p = (unsigned char*)ptr + (bit_pos >> 3);
6849 bit_pos &= 7, bits = 0;
6850 while (bit_size) {
6851 n = 8 - bit_pos;
6852 if (n > bit_size)
6853 n = bit_size;
6854 v = vtop->c.i >> bits << bit_pos;
6855 m = ((1 << n) - 1) << bit_pos;
6856 *p = (*p & ~m) | (v & m);
6857 bits += n, bit_size -= n, bit_pos = 0, ++p;
6859 } else
6860 switch(bt) {
6861 /* XXX: when cross-compiling we assume that each type has the
6862 same representation on host and target, which is likely to
6863 be wrong in the case of long double */
6864 case VT_BOOL:
6865 vtop->c.i = vtop->c.i != 0;
6866 case VT_BYTE:
6867 *(char *)ptr |= vtop->c.i;
6868 break;
6869 case VT_SHORT:
6870 *(short *)ptr |= vtop->c.i;
6871 break;
6872 case VT_FLOAT:
6873 *(float*)ptr = vtop->c.f;
6874 break;
6875 case VT_DOUBLE:
6876 *(double *)ptr = vtop->c.d;
6877 break;
6878 case VT_LDOUBLE:
6879 #if defined TCC_IS_NATIVE_387
6880 if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
6881 memcpy(ptr, &vtop->c.ld, 10);
6882 #ifdef __TINYC__
6883 else if (sizeof (long double) == sizeof (double))
6884 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
6885 #endif
6886 else if (vtop->c.ld == 0.0)
6888 else
6889 #endif
6890 if (sizeof(long double) == LDOUBLE_SIZE)
6891 *(long double*)ptr = vtop->c.ld;
6892 else if (sizeof(double) == LDOUBLE_SIZE)
6893 *(double *)ptr = (double)vtop->c.ld;
6894 else
6895 tcc_error("can't cross compile long double constants");
6896 break;
6897 #if PTR_SIZE != 8
6898 case VT_LLONG:
6899 *(long long *)ptr |= vtop->c.i;
6900 break;
6901 #else
6902 case VT_LLONG:
6903 #endif
6904 case VT_PTR:
6906 addr_t val = vtop->c.i;
6907 #if PTR_SIZE == 8
6908 if (vtop->r & VT_SYM)
6909 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
6910 else
6911 *(addr_t *)ptr |= val;
6912 #else
6913 if (vtop->r & VT_SYM)
6914 greloc(sec, vtop->sym, c, R_DATA_PTR);
6915 *(addr_t *)ptr |= val;
6916 #endif
6917 break;
6919 default:
6921 int val = vtop->c.i;
6922 #if PTR_SIZE == 8
6923 if (vtop->r & VT_SYM)
6924 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
6925 else
6926 *(int *)ptr |= val;
6927 #else
6928 if (vtop->r & VT_SYM)
6929 greloc(sec, vtop->sym, c, R_DATA_PTR);
6930 *(int *)ptr |= val;
6931 #endif
6932 break;
6936 vtop--;
6937 } else {
6938 vset(&dtype, VT_LOCAL|VT_LVAL, c);
6939 vswap();
6940 vstore();
6941 vpop();
6945 /* 't' contains the type and storage info. 'c' is the offset of the
6946 object in section 'sec'. If 'sec' is NULL, it means stack based
6947 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
6948 dimension implicit array init handling). 'flags & DIF_SIZE_ONLY' is true if
6949 size only evaluation is wanted (only for arrays). */
6950 static void decl_initializer(CType *type, Section *sec, unsigned long c,
6951 int flags)
6953 int len, n, no_oblock, nb, i;
6954 int size1, align1;
6955 Sym *s, *f;
6956 Sym indexsym;
6957 CType *t1;
6959 if (!(flags & DIF_HAVE_ELEM) && tok != '{' &&
6960 /* In case of strings we have special handling for arrays, so
6961 don't consume them as initializer value (which would commit them
6962 to some anonymous symbol). */
6963 tok != TOK_LSTR && tok != TOK_STR &&
6964 !(flags & DIF_SIZE_ONLY)) {
6965 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
6966 flags |= DIF_HAVE_ELEM;
6969 if ((flags & DIF_HAVE_ELEM) &&
6970 !(type->t & VT_ARRAY) &&
6971 /* Use i_c_parameter_t, to strip toplevel qualifiers.
6972 The source type might have VT_CONSTANT set, which is
6973 of course assignable to non-const elements. */
6974 is_compatible_unqualified_types(type, &vtop->type)) {
6975 init_putv(type, sec, c);
6976 } else if (type->t & VT_ARRAY) {
6977 s = type->ref;
6978 n = s->c;
6979 t1 = pointed_type(type);
6980 size1 = type_size(t1, &align1);
6982 no_oblock = 1;
6983 if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
6984 tok == '{') {
6985 if (tok != '{')
6986 tcc_error("character array initializer must be a literal,"
6987 " optionally enclosed in braces");
6988 skip('{');
6989 no_oblock = 0;
6992 /* only parse strings here if correct type (otherwise: handle
6993 them as ((w)char *) expressions */
6994 if ((tok == TOK_LSTR &&
6995 #ifdef TCC_TARGET_PE
6996 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
6997 #else
6998 (t1->t & VT_BTYPE) == VT_INT
6999 #endif
7000 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
7001 len = 0;
7002 while (tok == TOK_STR || tok == TOK_LSTR) {
7003 int cstr_len, ch;
7005 /* compute maximum number of chars wanted */
7006 if (tok == TOK_STR)
7007 cstr_len = tokc.str.size;
7008 else
7009 cstr_len = tokc.str.size / sizeof(nwchar_t);
7010 cstr_len--;
7011 nb = cstr_len;
7012 if (n >= 0 && nb > (n - len))
7013 nb = n - len;
7014 if (!(flags & DIF_SIZE_ONLY)) {
7015 if (cstr_len > nb)
7016 tcc_warning("initializer-string for array is too long");
7017 /* in order to go faster for common case (char
7018 string in global variable, we handle it
7019 specifically */
7020 if (sec && tok == TOK_STR && size1 == 1) {
7021 if (!NODATA_WANTED)
7022 memcpy(sec->data + c + len, tokc.str.data, nb);
7023 } else {
7024 for(i=0;i<nb;i++) {
7025 if (tok == TOK_STR)
7026 ch = ((unsigned char *)tokc.str.data)[i];
7027 else
7028 ch = ((nwchar_t *)tokc.str.data)[i];
7029 vpushi(ch);
7030 init_putv(t1, sec, c + (len + i) * size1);
7034 len += nb;
7035 next();
7037 /* only add trailing zero if enough storage (no
7038 warning in this case since it is standard) */
7039 if (n < 0 || len < n) {
7040 if (!(flags & DIF_SIZE_ONLY)) {
7041 vpushi(0);
7042 init_putv(t1, sec, c + (len * size1));
7044 len++;
7046 len *= size1;
7047 } else {
7048 indexsym.c = 0;
7049 f = &indexsym;
7051 do_init_list:
7052 len = 0;
7053 while (tok != '}' || (flags & DIF_HAVE_ELEM)) {
7054 len = decl_designator(type, sec, c, &f, flags, len);
7055 flags &= ~DIF_HAVE_ELEM;
7056 if (type->t & VT_ARRAY) {
7057 ++indexsym.c;
7058 /* special test for multi dimensional arrays (may not
7059 be strictly correct if designators are used at the
7060 same time) */
7061 if (no_oblock && len >= n*size1)
7062 break;
7063 } else {
7064 if (s->type.t == VT_UNION)
7065 f = NULL;
7066 else
7067 f = f->next;
7068 if (no_oblock && f == NULL)
7069 break;
7072 if (tok == '}')
7073 break;
7074 skip(',');
7077 /* put zeros at the end */
7078 if (!(flags & DIF_SIZE_ONLY) && len < n*size1)
7079 init_putz(sec, c + len, n*size1 - len);
7080 if (!no_oblock)
7081 skip('}');
7082 /* patch type size if needed, which happens only for array types */
7083 if (n < 0)
7084 s->c = size1 == 1 ? len : ((len + size1 - 1)/size1);
7085 } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
7086 size1 = 1;
7087 no_oblock = 1;
7088 if ((flags & DIF_FIRST) || tok == '{') {
7089 skip('{');
7090 no_oblock = 0;
7092 s = type->ref;
7093 f = s->next;
7094 n = s->c;
7095 goto do_init_list;
7096 } else if (tok == '{') {
7097 if (flags & DIF_HAVE_ELEM)
7098 skip(';');
7099 next();
7100 decl_initializer(type, sec, c, flags & ~DIF_HAVE_ELEM);
7101 skip('}');
7102 } else if ((flags & DIF_SIZE_ONLY)) {
7103 /* If we supported only ISO C we wouldn't have to accept calling
7104 this on anything than an array if DIF_SIZE_ONLY (and even then
7105 only on the outermost level, so no recursion would be needed),
7106 because initializing a flex array member isn't supported.
7107 But GNU C supports it, so we need to recurse even into
7108 subfields of structs and arrays when DIF_SIZE_ONLY is set. */
7109 /* just skip expression */
7110 skip_or_save_block(NULL);
7111 } else {
7112 if (!(flags & DIF_HAVE_ELEM)) {
7113 /* This should happen only when we haven't parsed
7114 the init element above for fear of committing a
7115 string constant to memory too early. */
7116 if (tok != TOK_STR && tok != TOK_LSTR)
7117 expect("string constant");
7118 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
7120 init_putv(type, sec, c);
7124 /* parse an initializer for type 't' if 'has_init' is non zero, and
7125 allocate space in local or global data space ('r' is either
7126 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7127 variable 'v' of scope 'scope' is declared before initializers
7128 are parsed. If 'v' is zero, then a reference to the new object
7129 is put in the value stack. If 'has_init' is 2, a special parsing
7130 is done to handle string constants. */
7131 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7132 int has_init, int v, int scope)
7134 int size, align, addr;
7135 TokenString *init_str = NULL;
7137 Section *sec;
7138 Sym *flexible_array;
7139 Sym *sym = NULL;
7140 int saved_nocode_wanted = nocode_wanted;
7141 #ifdef CONFIG_TCC_BCHECK
7142 int bcheck;
7143 #endif
7145 /* Always allocate static or global variables */
7146 if (v && (r & VT_VALMASK) == VT_CONST)
7147 nocode_wanted |= 0x80000000;
7149 #ifdef CONFIG_TCC_BCHECK
7150 bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
7151 #endif
7153 flexible_array = NULL;
7154 if ((type->t & VT_BTYPE) == VT_STRUCT) {
7155 Sym *field = type->ref->next;
7156 if (field) {
7157 while (field->next)
7158 field = field->next;
7159 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
7160 flexible_array = field;
7164 size = type_size(type, &align);
7165 /* If unknown size, we must evaluate it before
7166 evaluating initializers because
7167 initializers can generate global data too
7168 (e.g. string pointers or ISOC99 compound
7169 literals). It also simplifies local
7170 initializers handling */
7171 if (size < 0 || (flexible_array && has_init)) {
7172 if (!has_init)
7173 tcc_error("unknown type size");
7174 /* get all init string */
7175 if (has_init == 2) {
7176 init_str = tok_str_alloc();
7177 /* only get strings */
7178 while (tok == TOK_STR || tok == TOK_LSTR) {
7179 tok_str_add_tok(init_str);
7180 next();
7182 tok_str_add(init_str, -1);
7183 tok_str_add(init_str, 0);
7184 } else {
7185 skip_or_save_block(&init_str);
7187 unget_tok(0);
7189 /* compute size */
7190 begin_macro(init_str, 1);
7191 next();
7192 decl_initializer(type, NULL, 0, DIF_FIRST | DIF_SIZE_ONLY);
7193 /* prepare second initializer parsing */
7194 macro_ptr = init_str->str;
7195 next();
7197 /* if still unknown size, error */
7198 size = type_size(type, &align);
7199 if (size < 0)
7200 tcc_error("unknown type size");
7202 /* If there's a flex member and it was used in the initializer
7203 adjust size. */
7204 if (flexible_array &&
7205 flexible_array->type.ref->c > 0)
7206 size += flexible_array->type.ref->c
7207 * pointed_size(&flexible_array->type);
7208 /* take into account specified alignment if bigger */
7209 if (ad->a.aligned) {
7210 int speca = 1 << (ad->a.aligned - 1);
7211 if (speca > align)
7212 align = speca;
7213 } else if (ad->a.packed) {
7214 align = 1;
7217 if (!v && NODATA_WANTED)
7218 size = 0, align = 1;
7220 if ((r & VT_VALMASK) == VT_LOCAL) {
7221 sec = NULL;
7222 #ifdef CONFIG_TCC_BCHECK
7223 if (bcheck && (type->t & VT_ARRAY)) {
7224 loc--;
7226 #endif
7227 loc = (loc - size) & -align;
7228 addr = loc;
7229 #ifdef CONFIG_TCC_BCHECK
7230 /* handles bounds */
7231 /* XXX: currently, since we do only one pass, we cannot track
7232 '&' operators, so we add only arrays */
7233 if (bcheck && (type->t & VT_ARRAY)) {
7234 addr_t *bounds_ptr;
7235 /* add padding between regions */
7236 loc--;
7237 /* then add local bound info */
7238 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
7239 bounds_ptr[0] = addr;
7240 bounds_ptr[1] = size;
7242 #endif
7243 if (v) {
7244 /* local variable */
7245 #ifdef CONFIG_TCC_ASM
7246 if (ad->asm_label) {
7247 int reg = asm_parse_regvar(ad->asm_label);
7248 if (reg >= 0)
7249 r = (r & ~VT_VALMASK) | reg;
7251 #endif
7252 sym = sym_push(v, type, r, addr);
7253 if (ad->cleanup_func) {
7254 Sym *cls = sym_push2(&all_cleanups, SYM_FIELD | ++ncleanups, 0, 0);
7255 cls->prev_tok = sym;
7256 cls->next = ad->cleanup_func;
7257 cls->ncl = current_cleanups;
7258 current_cleanups = cls;
7261 sym->a = ad->a;
7262 } else {
7263 /* push local reference */
7264 vset(type, r, addr);
7266 } else {
7267 if (v && scope == VT_CONST) {
7268 /* see if the symbol was already defined */
7269 sym = sym_find(v);
7270 if (sym) {
7271 patch_storage(sym, ad, type);
7272 /* we accept several definitions of the same global variable. */
7273 if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
7274 goto no_alloc;
7278 /* allocate symbol in corresponding section */
7279 sec = ad->section;
7280 if (!sec) {
7281 if (has_init)
7282 sec = data_section;
7283 else if (tcc_state->nocommon)
7284 sec = bss_section;
7287 if (sec) {
7288 addr = section_add(sec, size, align);
7289 #ifdef CONFIG_TCC_BCHECK
7290 /* add padding if bound check */
7291 if (bcheck)
7292 section_add(sec, 1, 1);
7293 #endif
7294 } else {
7295 addr = align; /* SHN_COMMON is special, symbol value is align */
7296 sec = common_section;
7299 if (v) {
7300 if (!sym) {
7301 sym = sym_push(v, type, r | VT_SYM, 0);
7302 patch_storage(sym, ad, NULL);
7304 /* Local statics have a scope until now (for
7305 warnings), remove it here. */
7306 sym->sym_scope = 0;
7307 /* update symbol definition */
7308 put_extern_sym(sym, sec, addr, size);
7309 } else {
7310 /* push global reference */
7311 sym = get_sym_ref(type, sec, addr, size);
7312 vpushsym(type, sym);
7313 vtop->r |= r;
7316 #ifdef CONFIG_TCC_BCHECK
7317 /* handles bounds now because the symbol must be defined
7318 before for the relocation */
7319 if (bcheck) {
7320 addr_t *bounds_ptr;
7322 greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
7323 /* then add global bound info */
7324 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
7325 bounds_ptr[0] = 0; /* relocated */
7326 bounds_ptr[1] = size;
7328 #endif
7331 if (type->t & VT_VLA) {
7332 int a;
7334 if (NODATA_WANTED)
7335 goto no_alloc;
7337 /* save current stack pointer */
7338 if (vlas_in_scope == 0) {
7339 if (vla_sp_root_loc == -1)
7340 vla_sp_root_loc = (loc -= PTR_SIZE);
7341 gen_vla_sp_save(vla_sp_root_loc);
7344 vla_runtime_type_size(type, &a);
7345 gen_vla_alloc(type, a);
7346 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
7347 /* on _WIN64, because of the function args scratch area, the
7348 result of alloca differs from RSP and is returned in RAX. */
7349 gen_vla_result(addr), addr = (loc -= PTR_SIZE);
7350 #endif
7351 gen_vla_sp_save(addr);
7352 vla_sp_loc = addr;
7353 vlas_in_scope++;
7355 } else if (has_init) {
7356 size_t oldreloc_offset = 0;
7357 if (sec && sec->reloc)
7358 oldreloc_offset = sec->reloc->data_offset;
7359 decl_initializer(type, sec, addr, DIF_FIRST);
7360 if (sec && sec->reloc)
7361 squeeze_multi_relocs(sec, oldreloc_offset);
7362 /* patch flexible array member size back to -1, */
7363 /* for possible subsequent similar declarations */
7364 if (flexible_array)
7365 flexible_array->type.ref->c = -1;
7368 no_alloc:
7369 /* restore parse state if needed */
7370 if (init_str) {
7371 end_macro();
7372 next();
7375 nocode_wanted = saved_nocode_wanted;
7378 /* parse a function defined by symbol 'sym' and generate its code in
7379 'cur_text_section' */
7380 static void gen_function(Sym *sym)
7382 nocode_wanted = 0;
7383 ind = cur_text_section->data_offset;
7384 if (sym->a.aligned) {
7385 size_t newoff = section_add(cur_text_section, 0,
7386 1 << (sym->a.aligned - 1));
7387 gen_fill_nops(newoff - ind);
7389 /* NOTE: we patch the symbol size later */
7390 put_extern_sym(sym, cur_text_section, ind, 0);
7391 funcname = get_tok_str(sym->v, NULL);
7392 func_ind = ind;
7393 /* Initialize VLA state */
7394 vla_sp_loc = -1;
7395 vla_sp_root_loc = -1;
7396 /* put debug symbol */
7397 tcc_debug_funcstart(tcc_state, sym);
7398 /* push a dummy symbol to enable local sym storage */
7399 sym_push2(&local_stack, SYM_FIELD, 0, 0);
7400 local_scope = 1; /* for function parameters */
7401 gfunc_prolog(&sym->type);
7402 reset_local_scope();
7403 rsym = 0;
7404 clear_temp_local_var_list();
7405 block(NULL, NULL, 0);
7406 if (!(nocode_wanted & 0x20000000)
7407 && ((func_vt.t & VT_BTYPE) == VT_INT)
7408 && !strcmp (funcname, "main"))
7410 nocode_wanted = 0;
7411 vpushi(0);
7412 gen_assign_cast(&func_vt);
7413 gfunc_return(&func_vt);
7415 nocode_wanted = 0;
7416 gsym(rsym);
7417 gfunc_epilog();
7418 cur_text_section->data_offset = ind;
7419 label_pop(&global_label_stack, NULL, 0);
7420 /* reset local stack */
7421 reset_local_scope();
7422 sym_pop(&local_stack, NULL, 0);
7423 /* end of function */
7424 /* patch symbol size */
7425 elfsym(sym)->st_size = ind - func_ind;
7426 tcc_debug_funcend(tcc_state, ind - func_ind);
7427 /* It's better to crash than to generate wrong code */
7428 cur_text_section = NULL;
7429 funcname = ""; /* for safety */
7430 func_vt.t = VT_VOID; /* for safety */
7431 func_var = 0; /* for safety */
7432 ind = 0; /* for safety */
7433 nocode_wanted = 0x80000000;
7434 check_vstack();
7437 static void gen_inline_functions(TCCState *s)
7439 Sym *sym;
7440 int inline_generated, i, ln;
7441 struct InlineFunc *fn;
7443 ln = file->line_num;
7444 /* iterate while inline function are referenced */
7445 do {
7446 inline_generated = 0;
7447 for (i = 0; i < s->nb_inline_fns; ++i) {
7448 fn = s->inline_fns[i];
7449 sym = fn->sym;
7450 if (sym && sym->c) {
7451 /* the function was used: generate its code and
7452 convert it to a normal function */
7453 fn->sym = NULL;
7454 if (file)
7455 pstrcpy(file->filename, sizeof file->filename, fn->filename);
7456 sym->type.t &= ~VT_INLINE;
7458 begin_macro(fn->func_str, 1);
7459 next();
7460 cur_text_section = text_section;
7461 gen_function(sym);
7462 end_macro();
7464 inline_generated = 1;
7467 } while (inline_generated);
7468 file->line_num = ln;
7471 ST_FUNC void free_inline_functions(TCCState *s)
7473 int i;
7474 /* free tokens of unused inline functions */
7475 for (i = 0; i < s->nb_inline_fns; ++i) {
7476 struct InlineFunc *fn = s->inline_fns[i];
7477 if (fn->sym)
7478 tok_str_free(fn->func_str);
7480 dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
7483 /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
7484 if parsing old style parameter decl list (and FUNC_SYM is set then) */
7485 static int decl0(int l, int is_for_loop_init, Sym *func_sym)
7487 int v, has_init, r;
7488 CType type, btype;
7489 Sym *sym;
7490 AttributeDef ad, adbase;
7492 while (1) {
7493 if (!parse_btype(&btype, &adbase)) {
7494 if (is_for_loop_init)
7495 return 0;
7496 /* skip redundant ';' if not in old parameter decl scope */
7497 if (tok == ';' && l != VT_CMP) {
7498 next();
7499 continue;
7501 if (l != VT_CONST)
7502 break;
7503 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
7504 /* global asm block */
7505 asm_global_instr();
7506 continue;
7508 if (tok >= TOK_UIDENT) {
7509 /* special test for old K&R protos without explicit int
7510 type. Only accepted when defining global data */
7511 btype.t = VT_INT;
7512 } else {
7513 if (tok != TOK_EOF)
7514 expect("declaration");
7515 break;
7518 if (tok == ';') {
7519 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
7520 int v = btype.ref->v;
7521 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
7522 tcc_warning("unnamed struct/union that defines no instances");
7523 next();
7524 continue;
7526 if (IS_ENUM(btype.t)) {
7527 next();
7528 continue;
7531 while (1) { /* iterate thru each declaration */
7532 type = btype;
7533 /* If the base type itself was an array type of unspecified
7534 size (like in 'typedef int arr[]; arr x = {1};') then
7535 we will overwrite the unknown size by the real one for
7536 this decl. We need to unshare the ref symbol holding
7537 that size. */
7538 if ((type.t & VT_ARRAY) && type.ref->c < 0) {
7539 type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
7541 ad = adbase;
7542 type_decl(&type, &ad, &v, TYPE_DIRECT);
7543 #if 0
7545 char buf[500];
7546 type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
7547 printf("type = '%s'\n", buf);
7549 #endif
7550 if ((type.t & VT_BTYPE) == VT_FUNC) {
7551 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
7552 tcc_error("function without file scope cannot be static");
7554 /* if old style function prototype, we accept a
7555 declaration list */
7556 sym = type.ref;
7557 if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
7558 decl0(VT_CMP, 0, sym);
7561 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
7562 ad.asm_label = asm_label_instr();
7563 /* parse one last attribute list, after asm label */
7564 parse_attribute(&ad);
7565 if (tok == '{')
7566 expect(";");
7569 #ifdef TCC_TARGET_PE
7570 if (ad.a.dllimport || ad.a.dllexport) {
7571 if (type.t & (VT_STATIC|VT_TYPEDEF))
7572 tcc_error("cannot have dll linkage with static or typedef");
7573 if (ad.a.dllimport) {
7574 if ((type.t & VT_BTYPE) == VT_FUNC)
7575 ad.a.dllimport = 0;
7576 else
7577 type.t |= VT_EXTERN;
7580 #endif
7581 if (tok == '{') {
7582 if (l != VT_CONST)
7583 tcc_error("cannot use local functions");
7584 if ((type.t & VT_BTYPE) != VT_FUNC)
7585 expect("function definition");
7587 /* reject abstract declarators in function definition
7588 make old style params without decl have int type */
7589 sym = type.ref;
7590 while ((sym = sym->next) != NULL) {
7591 if (!(sym->v & ~SYM_FIELD))
7592 expect("identifier");
7593 if (sym->type.t == VT_VOID)
7594 sym->type = int_type;
7597 /* XXX: cannot do better now: convert extern line to static inline */
7598 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
7599 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
7601 /* put function symbol */
7602 sym = external_global_sym(v, &type, 0);
7603 type.t &= ~VT_EXTERN;
7604 patch_storage(sym, &ad, &type);
7606 /* static inline functions are just recorded as a kind
7607 of macro. Their code will be emitted at the end of
7608 the compilation unit only if they are used */
7609 if ((type.t & (VT_INLINE | VT_STATIC)) ==
7610 (VT_INLINE | VT_STATIC)) {
7611 struct InlineFunc *fn;
7612 const char *filename;
7614 filename = file ? file->filename : "";
7615 fn = tcc_malloc(sizeof *fn + strlen(filename));
7616 strcpy(fn->filename, filename);
7617 fn->sym = sym;
7618 skip_or_save_block(&fn->func_str);
7619 dynarray_add(&tcc_state->inline_fns,
7620 &tcc_state->nb_inline_fns, fn);
7621 } else {
7622 /* compute text section */
7623 cur_text_section = ad.section;
7624 if (!cur_text_section)
7625 cur_text_section = text_section;
7626 gen_function(sym);
7628 break;
7629 } else {
7630 if (l == VT_CMP) {
7631 /* find parameter in function parameter list */
7632 for (sym = func_sym->next; sym; sym = sym->next)
7633 if ((sym->v & ~SYM_FIELD) == v)
7634 goto found;
7635 tcc_error("declaration for parameter '%s' but no such parameter",
7636 get_tok_str(v, NULL));
7637 found:
7638 if (type.t & VT_STORAGE) /* 'register' is okay */
7639 tcc_error("storage class specified for '%s'",
7640 get_tok_str(v, NULL));
7641 if (sym->type.t != VT_VOID)
7642 tcc_error("redefinition of parameter '%s'",
7643 get_tok_str(v, NULL));
7644 convert_parameter_type(&type);
7645 sym->type = type;
7646 } else if (type.t & VT_TYPEDEF) {
7647 /* save typedefed type */
7648 /* XXX: test storage specifiers ? */
7649 sym = sym_find(v);
7650 if (sym && sym->sym_scope == local_scope) {
7651 if (!is_compatible_types(&sym->type, &type)
7652 || !(sym->type.t & VT_TYPEDEF))
7653 tcc_error("incompatible redefinition of '%s'",
7654 get_tok_str(v, NULL));
7655 sym->type = type;
7656 } else {
7657 sym = sym_push(v, &type, 0, 0);
7659 sym->a = ad.a;
7660 sym->f = ad.f;
7661 } else if ((type.t & VT_BTYPE) == VT_VOID
7662 && !(type.t & VT_EXTERN)) {
7663 tcc_error("declaration of void object");
7664 } else {
7665 r = 0;
7666 if ((type.t & VT_BTYPE) == VT_FUNC) {
7667 /* external function definition */
7668 /* specific case for func_call attribute */
7669 type.ref->f = ad.f;
7670 } else if (!(type.t & VT_ARRAY)) {
7671 /* not lvalue if array */
7672 r |= lvalue_type(type.t);
7674 has_init = (tok == '=');
7675 if (has_init && (type.t & VT_VLA))
7676 tcc_error("variable length array cannot be initialized");
7677 if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) ||
7678 ((type.t & VT_BTYPE) == VT_FUNC) ||
7679 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
7680 !has_init && l == VT_CONST && type.ref->c < 0)) {
7681 /* external variable or function */
7682 /* NOTE: as GCC, uninitialized global static
7683 arrays of null size are considered as
7684 extern */
7685 type.t |= VT_EXTERN;
7686 sym = external_sym(v, &type, r, &ad);
7687 if (ad.alias_target) {
7688 ElfSym *esym;
7689 Sym *alias_target;
7690 alias_target = sym_find(ad.alias_target);
7691 esym = elfsym(alias_target);
7692 if (!esym)
7693 tcc_error("unsupported forward __alias__ attribute");
7694 /* Local statics have a scope until now (for
7695 warnings), remove it here. */
7696 sym->sym_scope = 0;
7697 put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0);
7699 } else {
7700 if (type.t & VT_STATIC)
7701 r |= VT_CONST;
7702 else
7703 r |= l;
7704 if (has_init)
7705 next();
7706 else if (l == VT_CONST)
7707 /* uninitialized global variables may be overridden */
7708 type.t |= VT_EXTERN;
7709 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
7712 if (tok != ',') {
7713 if (is_for_loop_init)
7714 return 1;
7715 skip(';');
7716 break;
7718 next();
7722 return 0;
7725 static void decl(int l)
7727 decl0(l, 0, NULL);
7730 /* ------------------------------------------------------------------------- */