make -h|-hh succeed if the output is successfully written
[tinycc.git] / tccgen.c
blob0445144b429dccde1df50d0de9676a1e636a8acd
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, Sym *bcl, int *csym, Sym *ccl, 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 s->r = VT_CONST | VT_SYM;
620 /* don't record anonymous symbol */
621 if (v < SYM_FIRST_ANOM) {
622 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
623 /* modify the top most local identifier, so that sym_identifier will
624 point to 's' when popped; happens when called from inline asm */
625 while (*ps != NULL && (*ps)->sym_scope)
626 ps = &(*ps)->prev_tok;
627 s->prev_tok = *ps;
628 *ps = s;
630 return s;
633 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
634 pop them yet from the list, but do remove them from the token array. */
635 ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
637 Sym *s, *ss, **ps;
638 TokenSym *ts;
639 int v;
641 s = *ptop;
642 while(s != b) {
643 ss = s->prev;
644 v = s->v;
645 /* remove symbol in token array */
646 /* XXX: simplify */
647 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
648 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
649 if (v & SYM_STRUCT)
650 ps = &ts->sym_struct;
651 else
652 ps = &ts->sym_identifier;
653 *ps = s->prev_tok;
655 if (!keep)
656 sym_free(s);
657 s = ss;
659 if (!keep)
660 *ptop = b;
663 /* ------------------------------------------------------------------------- */
665 static void vsetc(CType *type, int r, CValue *vc)
667 int v;
669 if (vtop >= vstack + (VSTACK_SIZE - 1))
670 tcc_error("memory full (vstack)");
671 /* cannot let cpu flags if other instruction are generated. Also
672 avoid leaving VT_JMP anywhere except on the top of the stack
673 because it would complicate the code generator.
675 Don't do this when nocode_wanted. vtop might come from
676 !nocode_wanted regions (see 88_codeopt.c) and transforming
677 it to a register without actually generating code is wrong
678 as their value might still be used for real. All values
679 we push under nocode_wanted will eventually be popped
680 again, so that the VT_CMP/VT_JMP value will be in vtop
681 when code is unsuppressed again.
683 Same logic below in vswap(); */
684 if (vtop >= vstack && !nocode_wanted) {
685 v = vtop->r & VT_VALMASK;
686 if (v == VT_CMP || (v & ~1) == VT_JMP)
687 gv(RC_INT);
690 vtop++;
691 vtop->type = *type;
692 vtop->r = r;
693 vtop->r2 = VT_CONST;
694 vtop->c = *vc;
695 vtop->sym = NULL;
698 ST_FUNC void vswap(void)
700 SValue tmp;
701 /* cannot vswap cpu flags. See comment at vsetc() above */
702 if (vtop >= vstack && !nocode_wanted) {
703 int v = vtop->r & VT_VALMASK;
704 if (v == VT_CMP || (v & ~1) == VT_JMP)
705 gv(RC_INT);
707 tmp = vtop[0];
708 vtop[0] = vtop[-1];
709 vtop[-1] = tmp;
712 /* pop stack value */
713 ST_FUNC void vpop(void)
715 int v;
716 v = vtop->r & VT_VALMASK;
717 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
718 /* for x86, we need to pop the FP stack */
719 if (v == TREG_ST0) {
720 o(0xd8dd); /* fstp %st(0) */
721 } else
722 #endif
723 if (v == VT_JMP || v == VT_JMPI) {
724 /* need to put correct jump if && or || without test */
725 gsym(vtop->c.i);
727 vtop--;
730 /* push constant of type "type" with useless value */
731 ST_FUNC void vpush(CType *type)
733 vset(type, VT_CONST, 0);
736 /* push integer constant */
737 ST_FUNC void vpushi(int v)
739 CValue cval;
740 cval.i = v;
741 vsetc(&int_type, VT_CONST, &cval);
744 /* push a pointer sized constant */
745 static void vpushs(addr_t v)
747 CValue cval;
748 cval.i = v;
749 vsetc(&size_type, VT_CONST, &cval);
752 /* push arbitrary 64bit constant */
753 ST_FUNC void vpush64(int ty, unsigned long long v)
755 CValue cval;
756 CType ctype;
757 ctype.t = ty;
758 ctype.ref = NULL;
759 cval.i = v;
760 vsetc(&ctype, VT_CONST, &cval);
763 /* push long long constant */
764 static inline void vpushll(long long v)
766 vpush64(VT_LLONG, v);
769 ST_FUNC void vset(CType *type, int r, int v)
771 CValue cval;
773 cval.i = v;
774 vsetc(type, r, &cval);
777 static void vseti(int r, int v)
779 CType type;
780 type.t = VT_INT;
781 type.ref = NULL;
782 vset(&type, r, v);
785 ST_FUNC void vpushv(SValue *v)
787 if (vtop >= vstack + (VSTACK_SIZE - 1))
788 tcc_error("memory full (vstack)");
789 vtop++;
790 *vtop = *v;
793 static void vdup(void)
795 vpushv(vtop);
798 /* rotate n first stack elements to the bottom
799 I1 ... In -> I2 ... In I1 [top is right]
801 ST_FUNC void vrotb(int n)
803 int i;
804 SValue tmp;
806 tmp = vtop[-n + 1];
807 for(i=-n+1;i!=0;i++)
808 vtop[i] = vtop[i+1];
809 vtop[0] = tmp;
812 /* rotate the n elements before entry e towards the top
813 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
815 ST_FUNC void vrote(SValue *e, int n)
817 int i;
818 SValue tmp;
820 tmp = *e;
821 for(i = 0;i < n - 1; i++)
822 e[-i] = e[-i - 1];
823 e[-n + 1] = tmp;
826 /* rotate n first stack elements to the top
827 I1 ... In -> In I1 ... I(n-1) [top is right]
829 ST_FUNC void vrott(int n)
831 vrote(vtop, n);
834 /* push a symbol value of TYPE */
835 static inline void vpushsym(CType *type, Sym *sym)
837 CValue cval;
838 cval.i = 0;
839 vsetc(type, VT_CONST | VT_SYM, &cval);
840 vtop->sym = sym;
843 /* Return a static symbol pointing to a section */
844 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
846 int v;
847 Sym *sym;
849 v = anon_sym++;
850 sym = sym_push(v, type, VT_CONST | VT_SYM, 0);
851 sym->type.t |= VT_STATIC;
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)
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 } else if (IS_ASM_SYM(s)) {
873 s->type.t = type->t | (s->type.t & VT_EXTERN);
874 s->type.ref = type->ref;
875 update_storage(s);
877 return s;
880 /* Merge symbol attributes. */
881 static void merge_symattr(struct SymAttr *sa, struct SymAttr *sa1)
883 if (sa1->aligned && !sa->aligned)
884 sa->aligned = sa1->aligned;
885 sa->packed |= sa1->packed;
886 sa->weak |= sa1->weak;
887 if (sa1->visibility != STV_DEFAULT) {
888 int vis = sa->visibility;
889 if (vis == STV_DEFAULT
890 || vis > sa1->visibility)
891 vis = sa1->visibility;
892 sa->visibility = vis;
894 sa->dllexport |= sa1->dllexport;
895 sa->nodecorate |= sa1->nodecorate;
896 sa->dllimport |= sa1->dllimport;
899 /* Merge function attributes. */
900 static void merge_funcattr(struct FuncAttr *fa, struct FuncAttr *fa1)
902 if (fa1->func_call && !fa->func_call)
903 fa->func_call = fa1->func_call;
904 if (fa1->func_type && !fa->func_type)
905 fa->func_type = fa1->func_type;
906 if (fa1->func_args && !fa->func_args)
907 fa->func_args = fa1->func_args;
910 /* Merge attributes. */
911 static void merge_attr(AttributeDef *ad, AttributeDef *ad1)
913 merge_symattr(&ad->a, &ad1->a);
914 merge_funcattr(&ad->f, &ad1->f);
916 if (ad1->section)
917 ad->section = ad1->section;
918 if (ad1->alias_target)
919 ad->alias_target = ad1->alias_target;
920 if (ad1->asm_label)
921 ad->asm_label = ad1->asm_label;
922 if (ad1->attr_mode)
923 ad->attr_mode = ad1->attr_mode;
926 /* Merge some type attributes. */
927 static void patch_type(Sym *sym, CType *type)
929 if (!(type->t & VT_EXTERN) || IS_ENUM_VAL(sym->type.t)) {
930 if (!(sym->type.t & VT_EXTERN))
931 tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
932 sym->type.t &= ~VT_EXTERN;
935 if (IS_ASM_SYM(sym)) {
936 /* stay static if both are static */
937 sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
938 sym->type.ref = type->ref;
941 if (!is_compatible_types(&sym->type, type)) {
942 tcc_error("incompatible types for redefinition of '%s'",
943 get_tok_str(sym->v, NULL));
945 } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
946 int static_proto = sym->type.t & VT_STATIC;
947 /* warn if static follows non-static function declaration */
948 if ((type->t & VT_STATIC) && !static_proto && !(type->t & VT_INLINE))
949 tcc_warning("static storage ignored for redefinition of '%s'",
950 get_tok_str(sym->v, NULL));
952 if (0 == (type->t & VT_EXTERN)) {
953 /* put complete type, use static from prototype */
954 sym->type.t = (type->t & ~VT_STATIC) | static_proto;
955 if (type->t & VT_INLINE)
956 sym->type.t = type->t;
957 sym->type.ref = type->ref;
960 } else {
961 if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
962 /* set array size if it was omitted in extern declaration */
963 if (sym->type.ref->c < 0)
964 sym->type.ref->c = type->ref->c;
965 else if (sym->type.ref->c != type->ref->c)
966 tcc_error("conflicting type for '%s'", get_tok_str(sym->v, NULL));
968 if ((type->t ^ sym->type.t) & VT_STATIC)
969 tcc_warning("storage mismatch for redefinition of '%s'",
970 get_tok_str(sym->v, NULL));
975 /* Merge some storage attributes. */
976 static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
978 if (type)
979 patch_type(sym, type);
981 #ifdef TCC_TARGET_PE
982 if (sym->a.dllimport != ad->a.dllimport)
983 tcc_error("incompatible dll linkage for redefinition of '%s'",
984 get_tok_str(sym->v, NULL));
985 #endif
986 merge_symattr(&sym->a, &ad->a);
987 if (ad->asm_label)
988 sym->asm_label = ad->asm_label;
989 update_storage(sym);
992 /* define a new external reference to a symbol 'v' */
993 static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
995 Sym *s;
996 s = sym_find(v);
997 if (!s || (!IS_ASM_SYM(s) && !(s->type.t & VT_EXTERN)
998 && (s->type.t & VT_BTYPE) != VT_FUNC)) {
999 if (s && !is_compatible_types(&s->type, type))
1000 tcc_error("conflicting types for '%s'", get_tok_str(s->v, NULL));
1001 /* push forward reference */
1002 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
1003 s->a = ad->a;
1004 s->asm_label = ad->asm_label;
1005 s->sym_scope = 0;
1006 } else {
1007 if (s->type.ref == func_old_type.ref) {
1008 s->type.ref = type->ref;
1009 s->r = r | VT_CONST | VT_SYM;
1010 s->type.t |= VT_EXTERN;
1012 patch_storage(s, ad, type);
1014 return s;
1017 /* push a reference to global symbol v */
1018 ST_FUNC void vpush_global_sym(CType *type, int v)
1020 vpushsym(type, external_global_sym(v, type));
1023 /* save registers up to (vtop - n) stack entry */
1024 ST_FUNC void save_regs(int n)
1026 SValue *p, *p1;
1027 for(p = vstack, p1 = vtop - n; p <= p1; p++)
1028 save_reg(p->r);
1031 /* save r to the memory stack, and mark it as being free */
1032 ST_FUNC void save_reg(int r)
1034 save_reg_upstack(r, 0);
1037 /* save r to the memory stack, and mark it as being free,
1038 if seen up to (vtop - n) stack entry */
1039 ST_FUNC void save_reg_upstack(int r, int n)
1041 int l, saved, size, align;
1042 SValue *p, *p1, sv;
1043 CType *type;
1045 if ((r &= VT_VALMASK) >= VT_CONST)
1046 return;
1047 if (nocode_wanted)
1048 return;
1050 /* modify all stack values */
1051 saved = 0;
1052 l = 0;
1053 for(p = vstack, p1 = vtop - n; p <= p1; p++) {
1054 if ((p->r & VT_VALMASK) == r ||
1055 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
1056 /* must save value on stack if not already done */
1057 if (!saved) {
1058 /* NOTE: must reload 'r' because r might be equal to r2 */
1059 r = p->r & VT_VALMASK;
1060 /* store register in the stack */
1061 type = &p->type;
1062 if ((p->r & VT_LVAL) ||
1063 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
1064 #if PTR_SIZE == 8
1065 type = &char_pointer_type;
1066 #else
1067 type = &int_type;
1068 #endif
1069 size = type_size(type, &align);
1070 l=get_temp_local_var(size,align);
1071 sv.type.t = type->t;
1072 sv.r = VT_LOCAL | VT_LVAL;
1073 sv.c.i = l;
1074 store(r, &sv);
1075 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1076 /* x86 specific: need to pop fp register ST0 if saved */
1077 if (r == TREG_ST0) {
1078 o(0xd8dd); /* fstp %st(0) */
1080 #endif
1081 #if PTR_SIZE == 4
1082 /* special long long case */
1083 if ((type->t & VT_BTYPE) == VT_LLONG) {
1084 sv.c.i += 4;
1085 store(p->r2, &sv);
1087 #endif
1088 saved = 1;
1090 /* mark that stack entry as being saved on the stack */
1091 if (p->r & VT_LVAL) {
1092 /* also clear the bounded flag because the
1093 relocation address of the function was stored in
1094 p->c.i */
1095 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
1096 } else {
1097 p->r = lvalue_type(p->type.t) | VT_LOCAL;
1099 p->r2 = VT_CONST;
1100 p->c.i = l;
1105 #ifdef TCC_TARGET_ARM
1106 /* find a register of class 'rc2' with at most one reference on stack.
1107 * If none, call get_reg(rc) */
1108 ST_FUNC int get_reg_ex(int rc, int rc2)
1110 int r;
1111 SValue *p;
1113 for(r=0;r<NB_REGS;r++) {
1114 if (reg_classes[r] & rc2) {
1115 int n;
1116 n=0;
1117 for(p = vstack; p <= vtop; p++) {
1118 if ((p->r & VT_VALMASK) == r ||
1119 (p->r2 & VT_VALMASK) == r)
1120 n++;
1122 if (n <= 1)
1123 return r;
1126 return get_reg(rc);
1128 #endif
1130 /* find a free register of class 'rc'. If none, save one register */
1131 ST_FUNC int get_reg(int rc)
1133 int r;
1134 SValue *p;
1136 /* find a free register */
1137 for(r=0;r<NB_REGS;r++) {
1138 if (reg_classes[r] & rc) {
1139 if (nocode_wanted)
1140 return r;
1141 for(p=vstack;p<=vtop;p++) {
1142 if ((p->r & VT_VALMASK) == r ||
1143 (p->r2 & VT_VALMASK) == r)
1144 goto notfound;
1146 return r;
1148 notfound: ;
1151 /* no register left : free the first one on the stack (VERY
1152 IMPORTANT to start from the bottom to ensure that we don't
1153 spill registers used in gen_opi()) */
1154 for(p=vstack;p<=vtop;p++) {
1155 /* look at second register (if long long) */
1156 r = p->r2 & VT_VALMASK;
1157 if (r < VT_CONST && (reg_classes[r] & rc))
1158 goto save_found;
1159 r = p->r & VT_VALMASK;
1160 if (r < VT_CONST && (reg_classes[r] & rc)) {
1161 save_found:
1162 save_reg(r);
1163 return r;
1166 /* Should never comes here */
1167 return -1;
1170 /* find a free temporary local variable (return the offset on stack) match the size and align. If none, add new temporary stack variable*/
1171 static int get_temp_local_var(int size,int align){
1172 int i;
1173 struct temp_local_variable *temp_var;
1174 int found_var;
1175 SValue *p;
1176 int r;
1177 char free;
1178 char found;
1179 found=0;
1180 for(i=0;i<nb_temp_local_vars;i++){
1181 temp_var=&arr_temp_local_vars[i];
1182 if(temp_var->size<size||align!=temp_var->align){
1183 continue;
1185 /*check if temp_var is free*/
1186 free=1;
1187 for(p=vstack;p<=vtop;p++) {
1188 r=p->r&VT_VALMASK;
1189 if(r==VT_LOCAL||r==VT_LLOCAL){
1190 if(p->c.i==temp_var->location){
1191 free=0;
1192 break;
1196 if(free){
1197 found_var=temp_var->location;
1198 found=1;
1199 break;
1202 if(!found){
1203 loc = (loc - size) & -align;
1204 if(nb_temp_local_vars<MAX_TEMP_LOCAL_VARIABLE_NUMBER){
1205 temp_var=&arr_temp_local_vars[i];
1206 temp_var->location=loc;
1207 temp_var->size=size;
1208 temp_var->align=align;
1209 nb_temp_local_vars++;
1211 found_var=loc;
1213 return found_var;
1216 static void clear_temp_local_var_list(){
1217 nb_temp_local_vars=0;
1220 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
1221 if needed */
1222 static void move_reg(int r, int s, int t)
1224 SValue sv;
1226 if (r != s) {
1227 save_reg(r);
1228 sv.type.t = t;
1229 sv.type.ref = NULL;
1230 sv.r = s;
1231 sv.c.i = 0;
1232 load(r, &sv);
1236 /* get address of vtop (vtop MUST BE an lvalue) */
1237 ST_FUNC void gaddrof(void)
1239 vtop->r &= ~VT_LVAL;
1240 /* tricky: if saved lvalue, then we can go back to lvalue */
1241 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
1242 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
1247 #ifdef CONFIG_TCC_BCHECK
1248 /* generate lvalue bound code */
1249 static void gbound(void)
1251 int lval_type;
1252 CType type1;
1254 vtop->r &= ~VT_MUSTBOUND;
1255 /* if lvalue, then use checking code before dereferencing */
1256 if (vtop->r & VT_LVAL) {
1257 /* if not VT_BOUNDED value, then make one */
1258 if (!(vtop->r & VT_BOUNDED)) {
1259 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
1260 /* must save type because we must set it to int to get pointer */
1261 type1 = vtop->type;
1262 vtop->type.t = VT_PTR;
1263 gaddrof();
1264 vpushi(0);
1265 gen_bounded_ptr_add();
1266 vtop->r |= lval_type;
1267 vtop->type = type1;
1269 /* then check for dereferencing */
1270 gen_bounded_ptr_deref();
1273 #endif
1275 static void incr_bf_adr(int o)
1277 vtop->type = char_pointer_type;
1278 gaddrof();
1279 vpushi(o);
1280 gen_op('+');
1281 vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN))
1282 | (VT_BYTE|VT_UNSIGNED);
1283 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
1284 | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL);
1287 /* single-byte load mode for packed or otherwise unaligned bitfields */
1288 static void load_packed_bf(CType *type, int bit_pos, int bit_size)
1290 int n, o, bits;
1291 save_reg_upstack(vtop->r, 1);
1292 vpush64(type->t & VT_BTYPE, 0); // B X
1293 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
1294 do {
1295 vswap(); // X B
1296 incr_bf_adr(o);
1297 vdup(); // X B B
1298 n = 8 - bit_pos;
1299 if (n > bit_size)
1300 n = bit_size;
1301 if (bit_pos)
1302 vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
1303 if (n < 8)
1304 vpushi((1 << n) - 1), gen_op('&');
1305 gen_cast(type);
1306 if (bits)
1307 vpushi(bits), gen_op(TOK_SHL);
1308 vrotb(3); // B Y X
1309 gen_op('|'); // B X
1310 bits += n, bit_size -= n, o = 1;
1311 } while (bit_size);
1312 vswap(), vpop();
1313 if (!(type->t & VT_UNSIGNED)) {
1314 n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
1315 vpushi(n), gen_op(TOK_SHL);
1316 vpushi(n), gen_op(TOK_SAR);
1320 /* single-byte store mode for packed or otherwise unaligned bitfields */
1321 static void store_packed_bf(int bit_pos, int bit_size)
1323 int bits, n, o, m, c;
1325 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1326 vswap(); // X B
1327 save_reg_upstack(vtop->r, 1);
1328 bits = 0, o = bit_pos >> 3, bit_pos &= 7;
1329 do {
1330 incr_bf_adr(o); // X B
1331 vswap(); //B X
1332 c ? vdup() : gv_dup(); // B V X
1333 vrott(3); // X B V
1334 if (bits)
1335 vpushi(bits), gen_op(TOK_SHR);
1336 if (bit_pos)
1337 vpushi(bit_pos), gen_op(TOK_SHL);
1338 n = 8 - bit_pos;
1339 if (n > bit_size)
1340 n = bit_size;
1341 if (n < 8) {
1342 m = ((1 << n) - 1) << bit_pos;
1343 vpushi(m), gen_op('&'); // X B V1
1344 vpushv(vtop-1); // X B V1 B
1345 vpushi(m & 0x80 ? ~m & 0x7f : ~m);
1346 gen_op('&'); // X B V1 B1
1347 gen_op('|'); // X B V2
1349 vdup(), vtop[-1] = vtop[-2]; // X B B V2
1350 vstore(), vpop(); // X B
1351 bits += n, bit_size -= n, bit_pos = 0, o = 1;
1352 } while (bit_size);
1353 vpop(), vpop();
1356 static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
1358 int t;
1359 if (0 == sv->type.ref)
1360 return 0;
1361 t = sv->type.ref->auxtype;
1362 if (t != -1 && t != VT_STRUCT) {
1363 sv->type.t = (sv->type.t & ~VT_BTYPE) | t;
1364 sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t);
1366 return t;
1369 /* store vtop a register belonging to class 'rc'. lvalues are
1370 converted to values. Cannot be used if cannot be converted to
1371 register value (such as structures). */
1372 ST_FUNC int gv(int rc)
1374 int r, bit_pos, bit_size, size, align, rc2;
1376 /* NOTE: get_reg can modify vstack[] */
1377 if (vtop->type.t & VT_BITFIELD) {
1378 CType type;
1380 bit_pos = BIT_POS(vtop->type.t);
1381 bit_size = BIT_SIZE(vtop->type.t);
1382 /* remove bit field info to avoid loops */
1383 vtop->type.t &= ~VT_STRUCT_MASK;
1385 type.ref = NULL;
1386 type.t = vtop->type.t & VT_UNSIGNED;
1387 if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
1388 type.t |= VT_UNSIGNED;
1390 r = adjust_bf(vtop, bit_pos, bit_size);
1392 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
1393 type.t |= VT_LLONG;
1394 else
1395 type.t |= VT_INT;
1397 if (r == VT_STRUCT) {
1398 load_packed_bf(&type, bit_pos, bit_size);
1399 } else {
1400 int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
1401 /* cast to int to propagate signedness in following ops */
1402 gen_cast(&type);
1403 /* generate shifts */
1404 vpushi(bits - (bit_pos + bit_size));
1405 gen_op(TOK_SHL);
1406 vpushi(bits - bit_size);
1407 /* NOTE: transformed to SHR if unsigned */
1408 gen_op(TOK_SAR);
1410 r = gv(rc);
1411 } else {
1412 if (is_float(vtop->type.t) &&
1413 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1414 unsigned long offset;
1415 /* CPUs usually cannot use float constants, so we store them
1416 generically in data segment */
1417 size = type_size(&vtop->type, &align);
1418 if (NODATA_WANTED)
1419 size = 0, align = 1;
1420 offset = section_add(data_section, size, align);
1421 vpush_ref(&vtop->type, data_section, offset, size);
1422 vswap();
1423 init_putv(&vtop->type, data_section, offset);
1424 vtop->r |= VT_LVAL;
1426 #ifdef CONFIG_TCC_BCHECK
1427 if (vtop->r & VT_MUSTBOUND)
1428 gbound();
1429 #endif
1431 r = vtop->r & VT_VALMASK;
1432 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
1433 #ifndef TCC_TARGET_ARM64
1434 if (rc == RC_IRET)
1435 rc2 = RC_LRET;
1436 #ifdef TCC_TARGET_X86_64
1437 else if (rc == RC_FRET)
1438 rc2 = RC_QRET;
1439 #endif
1440 #endif
1441 /* need to reload if:
1442 - constant
1443 - lvalue (need to dereference pointer)
1444 - already a register, but not in the right class */
1445 if (r >= VT_CONST
1446 || (vtop->r & VT_LVAL)
1447 || !(reg_classes[r] & rc)
1448 #if PTR_SIZE == 8
1449 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
1450 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
1451 #else
1452 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
1453 #endif
1456 r = get_reg(rc);
1457 #if PTR_SIZE == 8
1458 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
1459 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
1460 #else
1461 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
1462 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
1463 unsigned long long ll;
1464 #endif
1465 int r2, original_type;
1466 original_type = vtop->type.t;
1467 /* two register type load : expand to two words
1468 temporarily */
1469 #if PTR_SIZE == 4
1470 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1471 /* load constant */
1472 ll = vtop->c.i;
1473 vtop->c.i = ll; /* first word */
1474 load(r, vtop);
1475 vtop->r = r; /* save register value */
1476 vpushi(ll >> 32); /* second word */
1477 } else
1478 #endif
1479 if (vtop->r & VT_LVAL) {
1480 /* We do not want to modifier the long long
1481 pointer here, so the safest (and less
1482 efficient) is to save all the other registers
1483 in the stack. XXX: totally inefficient. */
1484 #if 0
1485 save_regs(1);
1486 #else
1487 /* lvalue_save: save only if used further down the stack */
1488 save_reg_upstack(vtop->r, 1);
1489 #endif
1490 /* load from memory */
1491 vtop->type.t = load_type;
1492 load(r, vtop);
1493 vdup();
1494 vtop[-1].r = r; /* save register value */
1495 /* increment pointer to get second word */
1496 vtop->type.t = addr_type;
1497 gaddrof();
1498 vpushi(load_size);
1499 gen_op('+');
1500 vtop->r |= VT_LVAL;
1501 vtop->type.t = load_type;
1502 } else {
1503 /* move registers */
1504 load(r, vtop);
1505 vdup();
1506 vtop[-1].r = r; /* save register value */
1507 vtop->r = vtop[-1].r2;
1509 /* Allocate second register. Here we rely on the fact that
1510 get_reg() tries first to free r2 of an SValue. */
1511 r2 = get_reg(rc2);
1512 load(r2, vtop);
1513 vpop();
1514 /* write second register */
1515 vtop->r2 = r2;
1516 vtop->type.t = original_type;
1517 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
1518 int t1, t;
1519 /* lvalue of scalar type : need to use lvalue type
1520 because of possible cast */
1521 t = vtop->type.t;
1522 t1 = t;
1523 /* compute memory access type */
1524 if (vtop->r & VT_LVAL_BYTE)
1525 t = VT_BYTE;
1526 else if (vtop->r & VT_LVAL_SHORT)
1527 t = VT_SHORT;
1528 if (vtop->r & VT_LVAL_UNSIGNED)
1529 t |= VT_UNSIGNED;
1530 vtop->type.t = t;
1531 load(r, vtop);
1532 /* restore wanted type */
1533 vtop->type.t = t1;
1534 } else {
1535 /* one register type load */
1536 load(r, vtop);
1539 vtop->r = r;
1540 #ifdef TCC_TARGET_C67
1541 /* uses register pairs for doubles */
1542 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
1543 vtop->r2 = r+1;
1544 #endif
1546 return r;
1549 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
1550 ST_FUNC void gv2(int rc1, int rc2)
1552 int v;
1554 /* generate more generic register first. But VT_JMP or VT_CMP
1555 values must be generated first in all cases to avoid possible
1556 reload errors */
1557 v = vtop[0].r & VT_VALMASK;
1558 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
1559 vswap();
1560 gv(rc1);
1561 vswap();
1562 gv(rc2);
1563 /* test if reload is needed for first register */
1564 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1565 vswap();
1566 gv(rc1);
1567 vswap();
1569 } else {
1570 gv(rc2);
1571 vswap();
1572 gv(rc1);
1573 vswap();
1574 /* test if reload is needed for first register */
1575 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
1576 gv(rc2);
1581 #ifndef TCC_TARGET_ARM64
1582 /* wrapper around RC_FRET to return a register by type */
1583 static int rc_fret(int t)
1585 #ifdef TCC_TARGET_X86_64
1586 if (t == VT_LDOUBLE) {
1587 return RC_ST0;
1589 #endif
1590 return RC_FRET;
1592 #endif
1594 /* wrapper around REG_FRET to return a register by type */
1595 static int reg_fret(int t)
1597 #ifdef TCC_TARGET_X86_64
1598 if (t == VT_LDOUBLE) {
1599 return TREG_ST0;
1601 #endif
1602 return REG_FRET;
1605 #if PTR_SIZE == 4
1606 /* expand 64bit on stack in two ints */
1607 ST_FUNC void lexpand(void)
1609 int u, v;
1610 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1611 v = vtop->r & (VT_VALMASK | VT_LVAL);
1612 if (v == VT_CONST) {
1613 vdup();
1614 vtop[0].c.i >>= 32;
1615 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1616 vdup();
1617 vtop[0].c.i += 4;
1618 } else {
1619 gv(RC_INT);
1620 vdup();
1621 vtop[0].r = vtop[-1].r2;
1622 vtop[0].r2 = vtop[-1].r2 = VT_CONST;
1624 vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
1626 #endif
1628 #if PTR_SIZE == 4
1629 /* build a long long from two ints */
1630 static void lbuild(int t)
1632 gv2(RC_INT, RC_INT);
1633 vtop[-1].r2 = vtop[0].r;
1634 vtop[-1].type.t = t;
1635 vpop();
1637 #endif
1639 /* convert stack entry to register and duplicate its value in another
1640 register */
1641 static void gv_dup(void)
1643 int rc, t, r, r1;
1644 SValue sv;
1646 t = vtop->type.t;
1647 #if PTR_SIZE == 4
1648 if ((t & VT_BTYPE) == VT_LLONG) {
1649 if (t & VT_BITFIELD) {
1650 gv(RC_INT);
1651 t = vtop->type.t;
1653 lexpand();
1654 gv_dup();
1655 vswap();
1656 vrotb(3);
1657 gv_dup();
1658 vrotb(4);
1659 /* stack: H L L1 H1 */
1660 lbuild(t);
1661 vrotb(3);
1662 vrotb(3);
1663 vswap();
1664 lbuild(t);
1665 vswap();
1666 } else
1667 #endif
1669 /* duplicate value */
1670 rc = RC_INT;
1671 sv.type.t = VT_INT;
1672 if (is_float(t)) {
1673 rc = RC_FLOAT;
1674 #ifdef TCC_TARGET_X86_64
1675 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1676 rc = RC_ST0;
1678 #endif
1679 sv.type.t = t;
1681 r = gv(rc);
1682 r1 = get_reg(rc);
1683 sv.r = r;
1684 sv.c.i = 0;
1685 load(r1, &sv); /* move r to r1 */
1686 vdup();
1687 /* duplicates value */
1688 if (r != r1)
1689 vtop->r = r1;
1693 /* Generate value test
1695 * Generate a test for any value (jump, comparison and integers) */
1696 ST_FUNC int gvtst(int inv, int t)
1698 int v = vtop->r & VT_VALMASK;
1699 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1700 vpushi(0);
1701 gen_op(TOK_NE);
1703 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1704 /* constant jmp optimization */
1705 if ((vtop->c.i != 0) != inv)
1706 t = gjmp(t);
1707 vtop--;
1708 return t;
1710 return gtst(inv, t);
1713 #if PTR_SIZE == 4
1714 /* generate CPU independent (unsigned) long long operations */
1715 static void gen_opl(int op)
1717 int t, a, b, op1, c, i;
1718 int func;
1719 unsigned short reg_iret = REG_IRET;
1720 unsigned short reg_lret = REG_LRET;
1721 SValue tmp;
1723 switch(op) {
1724 case '/':
1725 case TOK_PDIV:
1726 func = TOK___divdi3;
1727 goto gen_func;
1728 case TOK_UDIV:
1729 func = TOK___udivdi3;
1730 goto gen_func;
1731 case '%':
1732 func = TOK___moddi3;
1733 goto gen_mod_func;
1734 case TOK_UMOD:
1735 func = TOK___umoddi3;
1736 gen_mod_func:
1737 #ifdef TCC_ARM_EABI
1738 reg_iret = TREG_R2;
1739 reg_lret = TREG_R3;
1740 #endif
1741 gen_func:
1742 /* call generic long long function */
1743 vpush_global_sym(&func_old_type, func);
1744 vrott(3);
1745 gfunc_call(2);
1746 vpushi(0);
1747 vtop->r = reg_iret;
1748 vtop->r2 = reg_lret;
1749 break;
1750 case '^':
1751 case '&':
1752 case '|':
1753 case '*':
1754 case '+':
1755 case '-':
1756 //pv("gen_opl A",0,2);
1757 t = vtop->type.t;
1758 vswap();
1759 lexpand();
1760 vrotb(3);
1761 lexpand();
1762 /* stack: L1 H1 L2 H2 */
1763 tmp = vtop[0];
1764 vtop[0] = vtop[-3];
1765 vtop[-3] = tmp;
1766 tmp = vtop[-2];
1767 vtop[-2] = vtop[-3];
1768 vtop[-3] = tmp;
1769 vswap();
1770 /* stack: H1 H2 L1 L2 */
1771 //pv("gen_opl B",0,4);
1772 if (op == '*') {
1773 vpushv(vtop - 1);
1774 vpushv(vtop - 1);
1775 gen_op(TOK_UMULL);
1776 lexpand();
1777 /* stack: H1 H2 L1 L2 ML MH */
1778 for(i=0;i<4;i++)
1779 vrotb(6);
1780 /* stack: ML MH H1 H2 L1 L2 */
1781 tmp = vtop[0];
1782 vtop[0] = vtop[-2];
1783 vtop[-2] = tmp;
1784 /* stack: ML MH H1 L2 H2 L1 */
1785 gen_op('*');
1786 vrotb(3);
1787 vrotb(3);
1788 gen_op('*');
1789 /* stack: ML MH M1 M2 */
1790 gen_op('+');
1791 gen_op('+');
1792 } else if (op == '+' || op == '-') {
1793 /* XXX: add non carry method too (for MIPS or alpha) */
1794 if (op == '+')
1795 op1 = TOK_ADDC1;
1796 else
1797 op1 = TOK_SUBC1;
1798 gen_op(op1);
1799 /* stack: H1 H2 (L1 op L2) */
1800 vrotb(3);
1801 vrotb(3);
1802 gen_op(op1 + 1); /* TOK_xxxC2 */
1803 } else {
1804 gen_op(op);
1805 /* stack: H1 H2 (L1 op L2) */
1806 vrotb(3);
1807 vrotb(3);
1808 /* stack: (L1 op L2) H1 H2 */
1809 gen_op(op);
1810 /* stack: (L1 op L2) (H1 op H2) */
1812 /* stack: L H */
1813 lbuild(t);
1814 break;
1815 case TOK_SAR:
1816 case TOK_SHR:
1817 case TOK_SHL:
1818 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1819 t = vtop[-1].type.t;
1820 vswap();
1821 lexpand();
1822 vrotb(3);
1823 /* stack: L H shift */
1824 c = (int)vtop->c.i;
1825 /* constant: simpler */
1826 /* NOTE: all comments are for SHL. the other cases are
1827 done by swapping words */
1828 vpop();
1829 if (op != TOK_SHL)
1830 vswap();
1831 if (c >= 32) {
1832 /* stack: L H */
1833 vpop();
1834 if (c > 32) {
1835 vpushi(c - 32);
1836 gen_op(op);
1838 if (op != TOK_SAR) {
1839 vpushi(0);
1840 } else {
1841 gv_dup();
1842 vpushi(31);
1843 gen_op(TOK_SAR);
1845 vswap();
1846 } else {
1847 vswap();
1848 gv_dup();
1849 /* stack: H L L */
1850 vpushi(c);
1851 gen_op(op);
1852 vswap();
1853 vpushi(32 - c);
1854 if (op == TOK_SHL)
1855 gen_op(TOK_SHR);
1856 else
1857 gen_op(TOK_SHL);
1858 vrotb(3);
1859 /* stack: L L H */
1860 vpushi(c);
1861 if (op == TOK_SHL)
1862 gen_op(TOK_SHL);
1863 else
1864 gen_op(TOK_SHR);
1865 gen_op('|');
1867 if (op != TOK_SHL)
1868 vswap();
1869 lbuild(t);
1870 } else {
1871 /* XXX: should provide a faster fallback on x86 ? */
1872 switch(op) {
1873 case TOK_SAR:
1874 func = TOK___ashrdi3;
1875 goto gen_func;
1876 case TOK_SHR:
1877 func = TOK___lshrdi3;
1878 goto gen_func;
1879 case TOK_SHL:
1880 func = TOK___ashldi3;
1881 goto gen_func;
1884 break;
1885 default:
1886 /* compare operations */
1887 t = vtop->type.t;
1888 vswap();
1889 lexpand();
1890 vrotb(3);
1891 lexpand();
1892 /* stack: L1 H1 L2 H2 */
1893 tmp = vtop[-1];
1894 vtop[-1] = vtop[-2];
1895 vtop[-2] = tmp;
1896 /* stack: L1 L2 H1 H2 */
1897 /* compare high */
1898 op1 = op;
1899 /* when values are equal, we need to compare low words. since
1900 the jump is inverted, we invert the test too. */
1901 if (op1 == TOK_LT)
1902 op1 = TOK_LE;
1903 else if (op1 == TOK_GT)
1904 op1 = TOK_GE;
1905 else if (op1 == TOK_ULT)
1906 op1 = TOK_ULE;
1907 else if (op1 == TOK_UGT)
1908 op1 = TOK_UGE;
1909 a = 0;
1910 b = 0;
1911 gen_op(op1);
1912 if (op == TOK_NE) {
1913 b = gvtst(0, 0);
1914 } else {
1915 a = gvtst(1, 0);
1916 if (op != TOK_EQ) {
1917 /* generate non equal test */
1918 vpushi(TOK_NE);
1919 vtop->r = VT_CMP;
1920 b = gvtst(0, 0);
1923 /* compare low. Always unsigned */
1924 op1 = op;
1925 if (op1 == TOK_LT)
1926 op1 = TOK_ULT;
1927 else if (op1 == TOK_LE)
1928 op1 = TOK_ULE;
1929 else if (op1 == TOK_GT)
1930 op1 = TOK_UGT;
1931 else if (op1 == TOK_GE)
1932 op1 = TOK_UGE;
1933 gen_op(op1);
1934 a = gvtst(1, a);
1935 gsym(b);
1936 vseti(VT_JMPI, a);
1937 break;
1940 #endif
1942 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
1944 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
1945 return (a ^ b) >> 63 ? -x : x;
1948 static int gen_opic_lt(uint64_t a, uint64_t b)
1950 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
1953 /* handle integer constant optimizations and various machine
1954 independent opt */
1955 static void gen_opic(int op)
1957 SValue *v1 = vtop - 1;
1958 SValue *v2 = vtop;
1959 int t1 = v1->type.t & VT_BTYPE;
1960 int t2 = v2->type.t & VT_BTYPE;
1961 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1962 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1963 uint64_t l1 = c1 ? v1->c.i : 0;
1964 uint64_t l2 = c2 ? v2->c.i : 0;
1965 int shm = (t1 == VT_LLONG) ? 63 : 31;
1967 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
1968 l1 = ((uint32_t)l1 |
1969 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
1970 if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
1971 l2 = ((uint32_t)l2 |
1972 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
1974 if (c1 && c2) {
1975 switch(op) {
1976 case '+': l1 += l2; break;
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;
1983 case TOK_PDIV:
1984 case '/':
1985 case '%':
1986 case TOK_UDIV:
1987 case TOK_UMOD:
1988 /* if division by zero, generate explicit division */
1989 if (l2 == 0) {
1990 if (const_wanted)
1991 tcc_error("division by zero in constant");
1992 goto general_case;
1994 switch(op) {
1995 default: l1 = gen_opic_sdiv(l1, l2); break;
1996 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
1997 case TOK_UDIV: l1 = l1 / l2; break;
1998 case TOK_UMOD: l1 = l1 % l2; break;
2000 break;
2001 case TOK_SHL: l1 <<= (l2 & shm); break;
2002 case TOK_SHR: l1 >>= (l2 & shm); break;
2003 case TOK_SAR:
2004 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
2005 break;
2006 /* tests */
2007 case TOK_ULT: l1 = l1 < l2; break;
2008 case TOK_UGE: l1 = l1 >= l2; break;
2009 case TOK_EQ: l1 = l1 == l2; break;
2010 case TOK_NE: l1 = l1 != l2; break;
2011 case TOK_ULE: l1 = l1 <= l2; break;
2012 case TOK_UGT: l1 = l1 > l2; break;
2013 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
2014 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
2015 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
2016 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
2017 /* logical */
2018 case TOK_LAND: l1 = l1 && l2; break;
2019 case TOK_LOR: l1 = l1 || l2; break;
2020 default:
2021 goto general_case;
2023 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
2024 l1 = ((uint32_t)l1 |
2025 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
2026 v1->c.i = l1;
2027 vtop--;
2028 } else {
2029 /* if commutative ops, put c2 as constant */
2030 if (c1 && (op == '+' || op == '&' || op == '^' ||
2031 op == '|' || op == '*')) {
2032 vswap();
2033 c2 = c1; //c = c1, c1 = c2, c2 = c;
2034 l2 = l1; //l = l1, l1 = l2, l2 = l;
2036 if (!const_wanted &&
2037 c1 && ((l1 == 0 &&
2038 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
2039 (l1 == -1 && op == TOK_SAR))) {
2040 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
2041 vtop--;
2042 } else if (!const_wanted &&
2043 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
2044 (op == '|' &&
2045 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
2046 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
2047 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
2048 if (l2 == 1)
2049 vtop->c.i = 0;
2050 vswap();
2051 vtop--;
2052 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
2053 op == TOK_PDIV) &&
2054 l2 == 1) ||
2055 ((op == '+' || op == '-' || op == '|' || op == '^' ||
2056 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
2057 l2 == 0) ||
2058 (op == '&' &&
2059 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
2060 /* filter out NOP operations like x*1, x-0, x&-1... */
2061 vtop--;
2062 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
2063 /* try to use shifts instead of muls or divs */
2064 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
2065 int n = -1;
2066 while (l2) {
2067 l2 >>= 1;
2068 n++;
2070 vtop->c.i = n;
2071 if (op == '*')
2072 op = TOK_SHL;
2073 else if (op == TOK_PDIV)
2074 op = TOK_SAR;
2075 else
2076 op = TOK_SHR;
2078 goto general_case;
2079 } else if (c2 && (op == '+' || op == '-') &&
2080 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
2081 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
2082 /* symbol + constant case */
2083 if (op == '-')
2084 l2 = -l2;
2085 l2 += vtop[-1].c.i;
2086 /* The backends can't always deal with addends to symbols
2087 larger than +-1<<31. Don't construct such. */
2088 if ((int)l2 != l2)
2089 goto general_case;
2090 vtop--;
2091 vtop->c.i = l2;
2092 } else {
2093 general_case:
2094 /* call low level op generator */
2095 if (t1 == VT_LLONG || t2 == VT_LLONG ||
2096 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
2097 gen_opl(op);
2098 else
2099 gen_opi(op);
2104 /* generate a floating point operation with constant propagation */
2105 static void gen_opif(int op)
2107 int c1, c2;
2108 SValue *v1, *v2;
2109 #if defined _MSC_VER && defined _AMD64_
2110 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
2111 volatile
2112 #endif
2113 long double f1, f2;
2115 v1 = vtop - 1;
2116 v2 = vtop;
2117 /* currently, we cannot do computations with forward symbols */
2118 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2119 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2120 if (c1 && c2) {
2121 if (v1->type.t == VT_FLOAT) {
2122 f1 = v1->c.f;
2123 f2 = v2->c.f;
2124 } else if (v1->type.t == VT_DOUBLE) {
2125 f1 = v1->c.d;
2126 f2 = v2->c.d;
2127 } else {
2128 f1 = v1->c.ld;
2129 f2 = v2->c.ld;
2132 /* NOTE: we only do constant propagation if finite number (not
2133 NaN or infinity) (ANSI spec) */
2134 if (!ieee_finite(f1) || !ieee_finite(f2))
2135 goto general_case;
2137 switch(op) {
2138 case '+': f1 += f2; break;
2139 case '-': f1 -= f2; break;
2140 case '*': f1 *= f2; break;
2141 case '/':
2142 if (f2 == 0.0) {
2143 /* If not in initializer we need to potentially generate
2144 FP exceptions at runtime, otherwise we want to fold. */
2145 if (!const_wanted)
2146 goto general_case;
2148 f1 /= f2;
2149 break;
2150 /* XXX: also handles tests ? */
2151 default:
2152 goto general_case;
2154 /* XXX: overflow test ? */
2155 if (v1->type.t == VT_FLOAT) {
2156 v1->c.f = f1;
2157 } else if (v1->type.t == VT_DOUBLE) {
2158 v1->c.d = f1;
2159 } else {
2160 v1->c.ld = f1;
2162 vtop--;
2163 } else {
2164 general_case:
2165 gen_opf(op);
2169 static int pointed_size(CType *type)
2171 int align;
2172 return type_size(pointed_type(type), &align);
2175 static void vla_runtime_pointed_size(CType *type)
2177 int align;
2178 vla_runtime_type_size(pointed_type(type), &align);
2181 static inline int is_null_pointer(SValue *p)
2183 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
2184 return 0;
2185 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
2186 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
2187 ((p->type.t & VT_BTYPE) == VT_PTR &&
2188 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0) &&
2189 ((pointed_type(&p->type)->t & VT_BTYPE) == VT_VOID) &&
2190 0 == (pointed_type(&p->type)->t & (VT_CONSTANT | VT_VOLATILE))
2193 static inline int is_integer_btype(int bt)
2195 return (bt == VT_BYTE || bt == VT_SHORT ||
2196 bt == VT_INT || bt == VT_LLONG);
2199 /* check types for comparison or subtraction of pointers */
2200 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
2202 CType *type1, *type2, tmp_type1, tmp_type2;
2203 int bt1, bt2;
2205 /* null pointers are accepted for all comparisons as gcc */
2206 if (is_null_pointer(p1) || is_null_pointer(p2))
2207 return;
2208 type1 = &p1->type;
2209 type2 = &p2->type;
2210 bt1 = type1->t & VT_BTYPE;
2211 bt2 = type2->t & VT_BTYPE;
2212 /* accept comparison between pointer and integer with a warning */
2213 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
2214 if (op != TOK_LOR && op != TOK_LAND )
2215 tcc_warning("comparison between pointer and integer");
2216 return;
2219 /* both must be pointers or implicit function pointers */
2220 if (bt1 == VT_PTR) {
2221 type1 = pointed_type(type1);
2222 } else if (bt1 != VT_FUNC)
2223 goto invalid_operands;
2225 if (bt2 == VT_PTR) {
2226 type2 = pointed_type(type2);
2227 } else if (bt2 != VT_FUNC) {
2228 invalid_operands:
2229 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
2231 if ((type1->t & VT_BTYPE) == VT_VOID ||
2232 (type2->t & VT_BTYPE) == VT_VOID)
2233 return;
2234 tmp_type1 = *type1;
2235 tmp_type2 = *type2;
2236 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2237 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2238 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2239 /* gcc-like error if '-' is used */
2240 if (op == '-')
2241 goto invalid_operands;
2242 else
2243 tcc_warning("comparison of distinct pointer types lacks a cast");
2247 /* generic gen_op: handles types problems */
2248 ST_FUNC void gen_op(int op)
2250 int u, t1, t2, bt1, bt2, t;
2251 CType type1;
2253 redo:
2254 t1 = vtop[-1].type.t;
2255 t2 = vtop[0].type.t;
2256 bt1 = t1 & VT_BTYPE;
2257 bt2 = t2 & VT_BTYPE;
2259 if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
2260 tcc_error("operation on a struct");
2261 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
2262 if (bt2 == VT_FUNC) {
2263 mk_pointer(&vtop->type);
2264 gaddrof();
2266 if (bt1 == VT_FUNC) {
2267 vswap();
2268 mk_pointer(&vtop->type);
2269 gaddrof();
2270 vswap();
2272 goto redo;
2273 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
2274 /* at least one operand is a pointer */
2275 /* relational op: must be both pointers */
2276 if (op >= TOK_ULT && op <= TOK_LOR) {
2277 check_comparison_pointer_types(vtop - 1, vtop, op);
2278 /* pointers are handled are unsigned */
2279 #if PTR_SIZE == 8
2280 t = VT_LLONG | VT_UNSIGNED;
2281 #else
2282 t = VT_INT | VT_UNSIGNED;
2283 #endif
2284 goto std_op;
2286 /* if both pointers, then it must be the '-' op */
2287 if (bt1 == VT_PTR && bt2 == VT_PTR) {
2288 if (op != '-')
2289 tcc_error("cannot use pointers here");
2290 check_comparison_pointer_types(vtop - 1, vtop, op);
2291 /* XXX: check that types are compatible */
2292 if (vtop[-1].type.t & VT_VLA) {
2293 vla_runtime_pointed_size(&vtop[-1].type);
2294 } else {
2295 vpushi(pointed_size(&vtop[-1].type));
2297 vrott(3);
2298 gen_opic(op);
2299 vtop->type.t = ptrdiff_type.t;
2300 vswap();
2301 gen_op(TOK_PDIV);
2302 } else {
2303 /* exactly one pointer : must be '+' or '-'. */
2304 if (op != '-' && op != '+')
2305 tcc_error("cannot use pointers here");
2306 /* Put pointer as first operand */
2307 if (bt2 == VT_PTR) {
2308 vswap();
2309 t = t1, t1 = t2, t2 = t;
2311 #if PTR_SIZE == 4
2312 if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
2313 /* XXX: truncate here because gen_opl can't handle ptr + long long */
2314 gen_cast_s(VT_INT);
2315 #endif
2316 type1 = vtop[-1].type;
2317 type1.t &= ~VT_ARRAY;
2318 if (vtop[-1].type.t & VT_VLA)
2319 vla_runtime_pointed_size(&vtop[-1].type);
2320 else {
2321 u = pointed_size(&vtop[-1].type);
2322 if (u < 0)
2323 tcc_error("unknown array element size");
2324 #if PTR_SIZE == 8
2325 vpushll(u);
2326 #else
2327 /* XXX: cast to int ? (long long case) */
2328 vpushi(u);
2329 #endif
2331 gen_op('*');
2332 #if 0
2333 /* #ifdef CONFIG_TCC_BCHECK
2334 The main reason to removing this code:
2335 #include <stdio.h>
2336 int main ()
2338 int v[10];
2339 int i = 10;
2340 int j = 9;
2341 fprintf(stderr, "v+i-j = %p\n", v+i-j);
2342 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
2344 When this code is on. then the output looks like
2345 v+i-j = 0xfffffffe
2346 v+(i-j) = 0xbff84000
2348 /* if evaluating constant expression, no code should be
2349 generated, so no bound check */
2350 if (tcc_state->do_bounds_check && !const_wanted) {
2351 /* if bounded pointers, we generate a special code to
2352 test bounds */
2353 if (op == '-') {
2354 vpushi(0);
2355 vswap();
2356 gen_op('-');
2358 gen_bounded_ptr_add();
2359 } else
2360 #endif
2362 gen_opic(op);
2364 /* put again type if gen_opic() swaped operands */
2365 vtop->type = type1;
2367 } else if (is_float(bt1) || is_float(bt2)) {
2368 /* compute bigger type and do implicit casts */
2369 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
2370 t = VT_LDOUBLE;
2371 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
2372 t = VT_DOUBLE;
2373 } else {
2374 t = VT_FLOAT;
2376 /* floats can only be used for a few operations */
2377 if (op != '+' && op != '-' && op != '*' && op != '/' &&
2378 (op < TOK_ULT || op > TOK_GT))
2379 tcc_error("invalid operands for binary operation");
2380 goto std_op;
2381 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
2382 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
2383 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
2384 t |= VT_UNSIGNED;
2385 t |= (VT_LONG & t1);
2386 goto std_op;
2387 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
2388 /* cast to biggest op */
2389 t = VT_LLONG | VT_LONG;
2390 if (bt1 == VT_LLONG)
2391 t &= t1;
2392 if (bt2 == VT_LLONG)
2393 t &= t2;
2394 /* convert to unsigned if it does not fit in a long long */
2395 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
2396 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
2397 t |= VT_UNSIGNED;
2398 goto std_op;
2399 } else {
2400 /* integer operations */
2401 t = VT_INT | (VT_LONG & (t1 | t2));
2402 /* convert to unsigned if it does not fit in an integer */
2403 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
2404 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
2405 t |= VT_UNSIGNED;
2406 std_op:
2407 /* XXX: currently, some unsigned operations are explicit, so
2408 we modify them here */
2409 if (t & VT_UNSIGNED) {
2410 if (op == TOK_SAR)
2411 op = TOK_SHR;
2412 else if (op == '/')
2413 op = TOK_UDIV;
2414 else if (op == '%')
2415 op = TOK_UMOD;
2416 else if (op == TOK_LT)
2417 op = TOK_ULT;
2418 else if (op == TOK_GT)
2419 op = TOK_UGT;
2420 else if (op == TOK_LE)
2421 op = TOK_ULE;
2422 else if (op == TOK_GE)
2423 op = TOK_UGE;
2425 vswap();
2426 type1.t = t;
2427 type1.ref = NULL;
2428 gen_cast(&type1);
2429 vswap();
2430 /* special case for shifts and long long: we keep the shift as
2431 an integer */
2432 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
2433 type1.t = VT_INT;
2434 gen_cast(&type1);
2435 if (is_float(t))
2436 gen_opif(op);
2437 else
2438 gen_opic(op);
2439 if (op >= TOK_ULT && op <= TOK_GT) {
2440 /* relational op: the result is an int */
2441 vtop->type.t = VT_INT;
2442 } else {
2443 vtop->type.t = t;
2446 // Make sure that we have converted to an rvalue:
2447 if (vtop->r & VT_LVAL)
2448 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
2451 #ifndef TCC_TARGET_ARM
2452 /* generic itof for unsigned long long case */
2453 static void gen_cvt_itof1(int t)
2455 #ifdef TCC_TARGET_ARM64
2456 gen_cvt_itof(t);
2457 #else
2458 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
2459 (VT_LLONG | VT_UNSIGNED)) {
2461 if (t == VT_FLOAT)
2462 vpush_global_sym(&func_old_type, TOK___floatundisf);
2463 #if LDOUBLE_SIZE != 8
2464 else if (t == VT_LDOUBLE)
2465 vpush_global_sym(&func_old_type, TOK___floatundixf);
2466 #endif
2467 else
2468 vpush_global_sym(&func_old_type, TOK___floatundidf);
2469 vrott(2);
2470 gfunc_call(1);
2471 vpushi(0);
2472 vtop->r = reg_fret(t);
2473 } else {
2474 gen_cvt_itof(t);
2476 #endif
2478 #endif
2480 /* generic ftoi for unsigned long long case */
2481 static void gen_cvt_ftoi1(int t)
2483 #ifdef TCC_TARGET_ARM64
2484 gen_cvt_ftoi(t);
2485 #else
2486 int st;
2488 if (t == (VT_LLONG | VT_UNSIGNED)) {
2489 /* not handled natively */
2490 st = vtop->type.t & VT_BTYPE;
2491 if (st == VT_FLOAT)
2492 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
2493 #if LDOUBLE_SIZE != 8
2494 else if (st == VT_LDOUBLE)
2495 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
2496 #endif
2497 else
2498 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
2499 vrott(2);
2500 gfunc_call(1);
2501 vpushi(0);
2502 vtop->r = REG_IRET;
2503 vtop->r2 = REG_LRET;
2504 } else {
2505 gen_cvt_ftoi(t);
2507 #endif
2510 /* force char or short cast */
2511 static void force_charshort_cast(int t)
2513 int bits, dbt;
2515 /* cannot cast static initializers */
2516 if (STATIC_DATA_WANTED)
2517 return;
2519 dbt = t & VT_BTYPE;
2520 /* XXX: add optimization if lvalue : just change type and offset */
2521 if (dbt == VT_BYTE)
2522 bits = 8;
2523 else
2524 bits = 16;
2525 if (t & VT_UNSIGNED) {
2526 vpushi((1 << bits) - 1);
2527 gen_op('&');
2528 } else {
2529 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
2530 bits = 64 - bits;
2531 else
2532 bits = 32 - bits;
2533 vpushi(bits);
2534 gen_op(TOK_SHL);
2535 /* result must be signed or the SAR is converted to an SHL
2536 This was not the case when "t" was a signed short
2537 and the last value on the stack was an unsigned int */
2538 vtop->type.t &= ~VT_UNSIGNED;
2539 vpushi(bits);
2540 gen_op(TOK_SAR);
2544 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
2545 static void gen_cast_s(int t)
2547 CType type;
2548 type.t = t;
2549 type.ref = NULL;
2550 gen_cast(&type);
2553 static void gen_cast(CType *type)
2555 int sbt, dbt, sf, df, c, p;
2557 /* special delayed cast for char/short */
2558 /* XXX: in some cases (multiple cascaded casts), it may still
2559 be incorrect */
2560 if (vtop->r & VT_MUSTCAST) {
2561 vtop->r &= ~VT_MUSTCAST;
2562 force_charshort_cast(vtop->type.t);
2565 /* bitfields first get cast to ints */
2566 if (vtop->type.t & VT_BITFIELD) {
2567 gv(RC_INT);
2570 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
2571 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
2573 if (sbt != dbt) {
2574 sf = is_float(sbt);
2575 df = is_float(dbt);
2576 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2577 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
2578 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
2579 c &= dbt != VT_LDOUBLE;
2580 #endif
2581 if (c) {
2582 /* constant case: we can do it now */
2583 /* XXX: in ISOC, cannot do it if error in convert */
2584 if (sbt == VT_FLOAT)
2585 vtop->c.ld = vtop->c.f;
2586 else if (sbt == VT_DOUBLE)
2587 vtop->c.ld = vtop->c.d;
2589 if (df) {
2590 if ((sbt & VT_BTYPE) == VT_LLONG) {
2591 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
2592 vtop->c.ld = vtop->c.i;
2593 else
2594 vtop->c.ld = -(long double)-vtop->c.i;
2595 } else if(!sf) {
2596 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
2597 vtop->c.ld = (uint32_t)vtop->c.i;
2598 else
2599 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
2602 if (dbt == VT_FLOAT)
2603 vtop->c.f = (float)vtop->c.ld;
2604 else if (dbt == VT_DOUBLE)
2605 vtop->c.d = (double)vtop->c.ld;
2606 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
2607 vtop->c.i = vtop->c.ld;
2608 } else if (sf && dbt == VT_BOOL) {
2609 vtop->c.i = (vtop->c.ld != 0);
2610 } else {
2611 if(sf)
2612 vtop->c.i = vtop->c.ld;
2613 else if (sbt == (VT_LLONG|VT_UNSIGNED))
2615 else if (sbt & VT_UNSIGNED)
2616 vtop->c.i = (uint32_t)vtop->c.i;
2617 #if PTR_SIZE == 8
2618 else if (sbt == VT_PTR)
2620 #endif
2621 else if (sbt != VT_LLONG)
2622 vtop->c.i = ((uint32_t)vtop->c.i |
2623 -(vtop->c.i & 0x80000000));
2625 if (dbt == (VT_LLONG|VT_UNSIGNED))
2627 else if (dbt == VT_BOOL)
2628 vtop->c.i = (vtop->c.i != 0);
2629 #if PTR_SIZE == 8
2630 else if (dbt == VT_PTR)
2632 #endif
2633 else if (dbt != VT_LLONG) {
2634 uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
2635 (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
2636 0xffffffff);
2637 vtop->c.i &= m;
2638 if (!(dbt & VT_UNSIGNED))
2639 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
2642 } else if (p && dbt == VT_BOOL) {
2643 vtop->r = VT_CONST;
2644 vtop->c.i = 1;
2645 } else {
2646 /* non constant case: generate code */
2647 if (sf && df) {
2648 /* convert from fp to fp */
2649 gen_cvt_ftof(dbt);
2650 } else if (df) {
2651 /* convert int to fp */
2652 gen_cvt_itof1(dbt);
2653 } else if (sf) {
2654 /* convert fp to int */
2655 if (dbt == VT_BOOL) {
2656 vpushi(0);
2657 gen_op(TOK_NE);
2658 } else {
2659 /* we handle char/short/etc... with generic code */
2660 if (dbt != (VT_INT | VT_UNSIGNED) &&
2661 dbt != (VT_LLONG | VT_UNSIGNED) &&
2662 dbt != VT_LLONG)
2663 dbt = VT_INT;
2664 gen_cvt_ftoi1(dbt);
2665 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2666 /* additional cast for char/short... */
2667 vtop->type.t = dbt;
2668 gen_cast(type);
2671 #if PTR_SIZE == 4
2672 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2673 if ((sbt & VT_BTYPE) != VT_LLONG) {
2674 /* scalar to long long */
2675 /* machine independent conversion */
2676 gv(RC_INT);
2677 /* generate high word */
2678 if (sbt == (VT_INT | VT_UNSIGNED)) {
2679 vpushi(0);
2680 gv(RC_INT);
2681 } else {
2682 if (sbt == VT_PTR) {
2683 /* cast from pointer to int before we apply
2684 shift operation, which pointers don't support*/
2685 gen_cast_s(VT_INT);
2687 gv_dup();
2688 vpushi(31);
2689 gen_op(TOK_SAR);
2691 /* patch second register */
2692 vtop[-1].r2 = vtop->r;
2693 vpop();
2695 #else
2696 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2697 (dbt & VT_BTYPE) == VT_PTR ||
2698 (dbt & VT_BTYPE) == VT_FUNC) {
2699 if ((sbt & VT_BTYPE) != VT_LLONG &&
2700 (sbt & VT_BTYPE) != VT_PTR &&
2701 (sbt & VT_BTYPE) != VT_FUNC) {
2702 /* need to convert from 32bit to 64bit */
2703 gv(RC_INT);
2704 if (sbt != (VT_INT | VT_UNSIGNED)) {
2705 #if defined(TCC_TARGET_ARM64)
2706 gen_cvt_sxtw();
2707 #elif defined(TCC_TARGET_X86_64)
2708 int r = gv(RC_INT);
2709 /* x86_64 specific: movslq */
2710 o(0x6348);
2711 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2712 #else
2713 #error
2714 #endif
2717 #endif
2718 } else if (dbt == VT_BOOL) {
2719 /* scalar to bool */
2720 vpushi(0);
2721 gen_op(TOK_NE);
2722 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2723 (dbt & VT_BTYPE) == VT_SHORT) {
2724 if (sbt == VT_PTR) {
2725 vtop->type.t = VT_INT;
2726 tcc_warning("nonportable conversion from pointer to char/short");
2728 force_charshort_cast(dbt);
2729 } else if ((dbt & VT_BTYPE) == VT_INT) {
2730 /* scalar to int */
2731 if ((sbt & VT_BTYPE) == VT_LLONG) {
2732 #if PTR_SIZE == 4
2733 /* from long long: just take low order word */
2734 lexpand();
2735 vpop();
2736 #else
2737 vpushi(0xffffffff);
2738 vtop->type.t |= VT_UNSIGNED;
2739 gen_op('&');
2740 #endif
2742 /* if lvalue and single word type, nothing to do because
2743 the lvalue already contains the real type size (see
2744 VT_LVAL_xxx constants) */
2747 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2748 /* if we are casting between pointer types,
2749 we must update the VT_LVAL_xxx size */
2750 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2751 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2753 vtop->type = *type;
2754 vtop->type.t &= ~ ( VT_CONSTANT | VT_VOLATILE | VT_ARRAY );
2757 /* return type size as known at compile time. Put alignment at 'a' */
2758 ST_FUNC int type_size(CType *type, int *a)
2760 Sym *s;
2761 int bt;
2763 bt = type->t & VT_BTYPE;
2764 if (bt == VT_STRUCT) {
2765 /* struct/union */
2766 s = type->ref;
2767 *a = s->r;
2768 return s->c;
2769 } else if (bt == VT_PTR) {
2770 if (type->t & VT_ARRAY) {
2771 int ts;
2773 s = type->ref;
2774 ts = type_size(&s->type, a);
2776 if (ts < 0 && s->c < 0)
2777 ts = -ts;
2779 return ts * s->c;
2780 } else {
2781 *a = PTR_SIZE;
2782 return PTR_SIZE;
2784 } else if (IS_ENUM(type->t) && type->ref->c < 0) {
2785 return -1; /* incomplete enum */
2786 } else if (bt == VT_LDOUBLE) {
2787 *a = LDOUBLE_ALIGN;
2788 return LDOUBLE_SIZE;
2789 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2790 #ifdef TCC_TARGET_I386
2791 #ifdef TCC_TARGET_PE
2792 *a = 8;
2793 #else
2794 *a = 4;
2795 #endif
2796 #elif defined(TCC_TARGET_ARM)
2797 #ifdef TCC_ARM_EABI
2798 *a = 8;
2799 #else
2800 *a = 4;
2801 #endif
2802 #else
2803 *a = 8;
2804 #endif
2805 return 8;
2806 } else if (bt == VT_INT || bt == VT_FLOAT) {
2807 *a = 4;
2808 return 4;
2809 } else if (bt == VT_SHORT) {
2810 *a = 2;
2811 return 2;
2812 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2813 *a = 8;
2814 return 16;
2815 } else {
2816 /* char, void, function, _Bool */
2817 *a = 1;
2818 return 1;
2822 /* push type size as known at runtime time on top of value stack. Put
2823 alignment at 'a' */
2824 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2826 if (type->t & VT_VLA) {
2827 type_size(&type->ref->type, a);
2828 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2829 } else {
2830 vpushi(type_size(type, a));
2834 static void vla_sp_restore(void) {
2835 if (vlas_in_scope) {
2836 gen_vla_sp_restore(vla_sp_loc);
2840 static void vla_sp_restore_root(void) {
2841 if (vlas_in_scope) {
2842 gen_vla_sp_restore(vla_sp_root_loc);
2846 /* return the pointed type of t */
2847 static inline CType *pointed_type(CType *type)
2849 return &type->ref->type;
2852 /* modify type so that its it is a pointer to type. */
2853 ST_FUNC void mk_pointer(CType *type)
2855 Sym *s;
2856 s = sym_push(SYM_FIELD, type, 0, -1);
2857 type->t = VT_PTR | (type->t & VT_STORAGE);
2858 type->ref = s;
2861 /* compare function types. OLD functions match any new functions */
2862 static int is_compatible_func(CType *type1, CType *type2)
2864 Sym *s1, *s2;
2866 s1 = type1->ref;
2867 s2 = type2->ref;
2868 if (!is_compatible_types(&s1->type, &s2->type))
2869 return 0;
2870 /* check func_call */
2871 if (s1->f.func_call != s2->f.func_call)
2872 return 0;
2873 /* XXX: not complete */
2874 if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD)
2875 return 1;
2876 if (s1->f.func_type != s2->f.func_type)
2877 return 0;
2878 while (s1 != NULL) {
2879 if (s2 == NULL)
2880 return 0;
2881 if (!is_compatible_unqualified_types(&s1->type, &s2->type))
2882 return 0;
2883 s1 = s1->next;
2884 s2 = s2->next;
2886 if (s2)
2887 return 0;
2888 return 1;
2891 /* return true if type1 and type2 are the same. If unqualified is
2892 true, qualifiers on the types are ignored.
2894 static int compare_types(CType *type1, CType *type2, int unqualified)
2896 int bt1, t1, t2;
2898 t1 = type1->t & VT_TYPE;
2899 t2 = type2->t & VT_TYPE;
2900 if (unqualified) {
2901 /* strip qualifiers before comparing */
2902 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2903 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2906 /* Default Vs explicit signedness only matters for char */
2907 if ((t1 & VT_BTYPE) != VT_BYTE) {
2908 t1 &= ~VT_DEFSIGN;
2909 t2 &= ~VT_DEFSIGN;
2911 /* XXX: bitfields ? */
2912 if (t1 != t2)
2913 return 0;
2914 /* test more complicated cases */
2915 bt1 = t1 & (VT_BTYPE | VT_ARRAY);
2916 if (bt1 == VT_PTR) {
2917 type1 = pointed_type(type1);
2918 type2 = pointed_type(type2);
2919 return is_compatible_types(type1, type2);
2920 } else if (bt1 & VT_ARRAY) {
2921 return type1->ref->c < 0 || type2->ref->c < 0
2922 || type1->ref->c == type2->ref->c;
2923 } else if (bt1 == VT_STRUCT) {
2924 return (type1->ref == type2->ref);
2925 } else if (bt1 == VT_FUNC) {
2926 return is_compatible_func(type1, type2);
2927 } else if (IS_ENUM(type1->t) || IS_ENUM(type2->t)) {
2928 return type1->ref == type2->ref;
2929 } else {
2930 return 1;
2934 /* return true if type1 and type2 are exactly the same (including
2935 qualifiers).
2937 static int is_compatible_types(CType *type1, CType *type2)
2939 return compare_types(type1,type2,0);
2942 /* return true if type1 and type2 are the same (ignoring qualifiers).
2944 static int is_compatible_unqualified_types(CType *type1, CType *type2)
2946 return compare_types(type1,type2,1);
2949 /* print a type. If 'varstr' is not NULL, then the variable is also
2950 printed in the type */
2951 /* XXX: union */
2952 /* XXX: add array and function pointers */
2953 static void type_to_str(char *buf, int buf_size,
2954 CType *type, const char *varstr)
2956 int bt, v, t;
2957 Sym *s, *sa;
2958 char buf1[256];
2959 const char *tstr;
2961 t = type->t;
2962 bt = t & VT_BTYPE;
2963 buf[0] = '\0';
2965 if (t & VT_EXTERN)
2966 pstrcat(buf, buf_size, "extern ");
2967 if (t & VT_STATIC)
2968 pstrcat(buf, buf_size, "static ");
2969 if (t & VT_TYPEDEF)
2970 pstrcat(buf, buf_size, "typedef ");
2971 if (t & VT_INLINE)
2972 pstrcat(buf, buf_size, "inline ");
2973 if (t & VT_VOLATILE)
2974 pstrcat(buf, buf_size, "volatile ");
2975 if (t & VT_CONSTANT)
2976 pstrcat(buf, buf_size, "const ");
2978 if (((t & VT_DEFSIGN) && bt == VT_BYTE)
2979 || ((t & VT_UNSIGNED)
2980 && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
2981 && !IS_ENUM(t)
2983 pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
2985 buf_size -= strlen(buf);
2986 buf += strlen(buf);
2988 switch(bt) {
2989 case VT_VOID:
2990 tstr = "void";
2991 goto add_tstr;
2992 case VT_BOOL:
2993 tstr = "_Bool";
2994 goto add_tstr;
2995 case VT_BYTE:
2996 tstr = "char";
2997 goto add_tstr;
2998 case VT_SHORT:
2999 tstr = "short";
3000 goto add_tstr;
3001 case VT_INT:
3002 tstr = "int";
3003 goto maybe_long;
3004 case VT_LLONG:
3005 tstr = "long long";
3006 maybe_long:
3007 if (t & VT_LONG)
3008 tstr = "long";
3009 if (!IS_ENUM(t))
3010 goto add_tstr;
3011 tstr = "enum ";
3012 goto tstruct;
3013 case VT_FLOAT:
3014 tstr = "float";
3015 goto add_tstr;
3016 case VT_DOUBLE:
3017 tstr = "double";
3018 goto add_tstr;
3019 case VT_LDOUBLE:
3020 tstr = "long double";
3021 add_tstr:
3022 pstrcat(buf, buf_size, tstr);
3023 break;
3024 case VT_STRUCT:
3025 tstr = "struct ";
3026 if (IS_UNION(t))
3027 tstr = "union ";
3028 tstruct:
3029 pstrcat(buf, buf_size, tstr);
3030 v = type->ref->v & ~SYM_STRUCT;
3031 if (v >= SYM_FIRST_ANOM)
3032 pstrcat(buf, buf_size, "<anonymous>");
3033 else
3034 pstrcat(buf, buf_size, get_tok_str(v, NULL));
3035 break;
3036 case VT_FUNC:
3037 s = type->ref;
3038 buf1[0]=0;
3039 if (varstr && '*' == *varstr) {
3040 pstrcat(buf1, sizeof(buf1), "(");
3041 pstrcat(buf1, sizeof(buf1), varstr);
3042 pstrcat(buf1, sizeof(buf1), ")");
3044 pstrcat(buf1, buf_size, "(");
3045 sa = s->next;
3046 while (sa != NULL) {
3047 char buf2[256];
3048 type_to_str(buf2, sizeof(buf2), &sa->type, NULL);
3049 pstrcat(buf1, sizeof(buf1), buf2);
3050 sa = sa->next;
3051 if (sa)
3052 pstrcat(buf1, sizeof(buf1), ", ");
3054 if (s->f.func_type == FUNC_ELLIPSIS)
3055 pstrcat(buf1, sizeof(buf1), ", ...");
3056 pstrcat(buf1, sizeof(buf1), ")");
3057 type_to_str(buf, buf_size, &s->type, buf1);
3058 goto no_var;
3059 case VT_PTR:
3060 s = type->ref;
3061 if (t & VT_ARRAY) {
3062 if (varstr && '*' == *varstr)
3063 snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c);
3064 else
3065 snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
3066 type_to_str(buf, buf_size, &s->type, buf1);
3067 goto no_var;
3069 pstrcpy(buf1, sizeof(buf1), "*");
3070 if (t & VT_CONSTANT)
3071 pstrcat(buf1, buf_size, "const ");
3072 if (t & VT_VOLATILE)
3073 pstrcat(buf1, buf_size, "volatile ");
3074 if (varstr)
3075 pstrcat(buf1, sizeof(buf1), varstr);
3076 type_to_str(buf, buf_size, &s->type, buf1);
3077 goto no_var;
3079 if (varstr) {
3080 pstrcat(buf, buf_size, " ");
3081 pstrcat(buf, buf_size, varstr);
3083 no_var: ;
3086 /* verify type compatibility to store vtop in 'dt' type, and generate
3087 casts if needed. */
3088 static void gen_assign_cast(CType *dt)
3090 CType *st, *type1, *type2;
3091 char buf1[256], buf2[256];
3092 int dbt, sbt, qualwarn, lvl;
3094 st = &vtop->type; /* source type */
3095 dbt = dt->t & VT_BTYPE;
3096 sbt = st->t & VT_BTYPE;
3097 if (sbt == VT_VOID || dbt == VT_VOID) {
3098 if (sbt == VT_VOID && dbt == VT_VOID)
3099 ; /* It is Ok if both are void */
3100 else
3101 tcc_error("cannot cast from/to void");
3103 if (dt->t & VT_CONSTANT)
3104 tcc_warning("assignment of read-only location");
3105 switch(dbt) {
3106 case VT_PTR:
3107 /* special cases for pointers */
3108 /* '0' can also be a pointer */
3109 if (is_null_pointer(vtop))
3110 break;
3111 /* accept implicit pointer to integer cast with warning */
3112 if (is_integer_btype(sbt)) {
3113 tcc_warning("assignment makes pointer from integer without a cast");
3114 break;
3116 type1 = pointed_type(dt);
3117 if (sbt == VT_PTR)
3118 type2 = pointed_type(st);
3119 else if (sbt == VT_FUNC)
3120 type2 = st; /* a function is implicitly a function pointer */
3121 else
3122 goto error;
3123 if (is_compatible_types(type1, type2))
3124 break;
3125 for (qualwarn = lvl = 0;; ++lvl) {
3126 if (((type2->t & VT_CONSTANT) && !(type1->t & VT_CONSTANT)) ||
3127 ((type2->t & VT_VOLATILE) && !(type1->t & VT_VOLATILE)))
3128 qualwarn = 1;
3129 dbt = type1->t & (VT_BTYPE|VT_LONG);
3130 sbt = type2->t & (VT_BTYPE|VT_LONG);
3131 if (dbt != VT_PTR || sbt != VT_PTR)
3132 break;
3133 type1 = pointed_type(type1);
3134 type2 = pointed_type(type2);
3136 if (!is_compatible_unqualified_types(type1, type2)) {
3137 if ((dbt == VT_VOID || sbt == VT_VOID) && lvl == 0) {
3138 /* void * can match anything */
3139 } else if (dbt == sbt
3140 && is_integer_btype(sbt & VT_BTYPE)
3141 && IS_ENUM(type1->t) + IS_ENUM(type2->t)
3142 + !!((type1->t ^ type2->t) & VT_UNSIGNED) < 2) {
3143 /* Like GCC don't warn by default for merely changes
3144 in pointer target signedness. Do warn for different
3145 base types, though, in particular for unsigned enums
3146 and signed int targets. */
3147 } else {
3148 tcc_warning("assignment from incompatible pointer type");
3149 break;
3152 if (qualwarn)
3153 tcc_warning("assignment discards qualifiers from pointer target type");
3154 break;
3155 case VT_BYTE:
3156 case VT_SHORT:
3157 case VT_INT:
3158 case VT_LLONG:
3159 if (sbt == VT_PTR || sbt == VT_FUNC) {
3160 tcc_warning("assignment makes integer from pointer without a cast");
3161 } else if (sbt == VT_STRUCT) {
3162 goto case_VT_STRUCT;
3164 /* XXX: more tests */
3165 break;
3166 case VT_STRUCT:
3167 case_VT_STRUCT:
3168 if (!is_compatible_unqualified_types(dt, st)) {
3169 error:
3170 type_to_str(buf1, sizeof(buf1), st, NULL);
3171 type_to_str(buf2, sizeof(buf2), dt, NULL);
3172 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
3174 break;
3176 gen_cast(dt);
3179 /* store vtop in lvalue pushed on stack */
3180 ST_FUNC void vstore(void)
3182 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
3184 ft = vtop[-1].type.t;
3185 sbt = vtop->type.t & VT_BTYPE;
3186 dbt = ft & VT_BTYPE;
3187 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
3188 (sbt == VT_INT && dbt == VT_SHORT))
3189 && !(vtop->type.t & VT_BITFIELD)) {
3190 /* optimize char/short casts */
3191 delayed_cast = VT_MUSTCAST;
3192 vtop->type.t = ft & VT_TYPE;
3193 /* XXX: factorize */
3194 if (ft & VT_CONSTANT)
3195 tcc_warning("assignment of read-only location");
3196 } else {
3197 delayed_cast = 0;
3198 if (!(ft & VT_BITFIELD))
3199 gen_assign_cast(&vtop[-1].type);
3202 if (sbt == VT_STRUCT) {
3203 /* if structure, only generate pointer */
3204 /* structure assignment : generate memcpy */
3205 /* XXX: optimize if small size */
3206 size = type_size(&vtop->type, &align);
3208 /* destination */
3209 vswap();
3210 vtop->type.t = VT_PTR;
3211 gaddrof();
3213 /* address of memcpy() */
3214 #ifdef TCC_ARM_EABI
3215 if(!(align & 7))
3216 vpush_global_sym(&func_old_type, TOK_memcpy8);
3217 else if(!(align & 3))
3218 vpush_global_sym(&func_old_type, TOK_memcpy4);
3219 else
3220 #endif
3221 /* Use memmove, rather than memcpy, as dest and src may be same: */
3222 vpush_global_sym(&func_old_type, TOK_memmove);
3224 vswap();
3225 /* source */
3226 vpushv(vtop - 2);
3227 vtop->type.t = VT_PTR;
3228 gaddrof();
3229 /* type size */
3230 vpushi(size);
3231 gfunc_call(3);
3233 /* leave source on stack */
3234 } else if (ft & VT_BITFIELD) {
3235 /* bitfield store handling */
3237 /* save lvalue as expression result (example: s.b = s.a = n;) */
3238 vdup(), vtop[-1] = vtop[-2];
3240 bit_pos = BIT_POS(ft);
3241 bit_size = BIT_SIZE(ft);
3242 /* remove bit field info to avoid loops */
3243 vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
3245 if ((ft & VT_BTYPE) == VT_BOOL) {
3246 gen_cast(&vtop[-1].type);
3247 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
3250 r = adjust_bf(vtop - 1, bit_pos, bit_size);
3251 if (r == VT_STRUCT) {
3252 gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT);
3253 store_packed_bf(bit_pos, bit_size);
3254 } else {
3255 unsigned long long mask = (1ULL << bit_size) - 1;
3256 if ((ft & VT_BTYPE) != VT_BOOL) {
3257 /* mask source */
3258 if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG)
3259 vpushll(mask);
3260 else
3261 vpushi((unsigned)mask);
3262 gen_op('&');
3264 /* shift source */
3265 vpushi(bit_pos);
3266 gen_op(TOK_SHL);
3267 vswap();
3268 /* duplicate destination */
3269 vdup();
3270 vrott(3);
3271 /* load destination, mask and or with source */
3272 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
3273 vpushll(~(mask << bit_pos));
3274 else
3275 vpushi(~((unsigned)mask << bit_pos));
3276 gen_op('&');
3277 gen_op('|');
3278 /* store result */
3279 vstore();
3280 /* ... and discard */
3281 vpop();
3283 } else if (dbt == VT_VOID) {
3284 --vtop;
3285 } else {
3286 #ifdef CONFIG_TCC_BCHECK
3287 /* bound check case */
3288 if (vtop[-1].r & VT_MUSTBOUND) {
3289 vswap();
3290 gbound();
3291 vswap();
3293 #endif
3294 rc = RC_INT;
3295 if (is_float(ft)) {
3296 rc = RC_FLOAT;
3297 #ifdef TCC_TARGET_X86_64
3298 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
3299 rc = RC_ST0;
3300 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
3301 rc = RC_FRET;
3303 #endif
3305 r = gv(rc); /* generate value */
3306 /* if lvalue was saved on stack, must read it */
3307 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
3308 SValue sv;
3309 t = get_reg(RC_INT);
3310 #if PTR_SIZE == 8
3311 sv.type.t = VT_PTR;
3312 #else
3313 sv.type.t = VT_INT;
3314 #endif
3315 sv.r = VT_LOCAL | VT_LVAL;
3316 sv.c.i = vtop[-1].c.i;
3317 load(t, &sv);
3318 vtop[-1].r = t | VT_LVAL;
3320 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
3321 #if PTR_SIZE == 8
3322 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
3323 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
3324 #else
3325 if ((ft & VT_BTYPE) == VT_LLONG) {
3326 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
3327 #endif
3328 vtop[-1].type.t = load_type;
3329 store(r, vtop - 1);
3330 vswap();
3331 /* convert to int to increment easily */
3332 vtop->type.t = addr_type;
3333 gaddrof();
3334 vpushi(load_size);
3335 gen_op('+');
3336 vtop->r |= VT_LVAL;
3337 vswap();
3338 vtop[-1].type.t = load_type;
3339 /* XXX: it works because r2 is spilled last ! */
3340 store(vtop->r2, vtop - 1);
3341 } else {
3342 store(r, vtop - 1);
3345 vswap();
3346 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
3347 vtop->r |= delayed_cast;
3351 /* post defines POST/PRE add. c is the token ++ or -- */
3352 ST_FUNC void inc(int post, int c)
3354 test_lvalue();
3355 vdup(); /* save lvalue */
3356 if (post) {
3357 gv_dup(); /* duplicate value */
3358 vrotb(3);
3359 vrotb(3);
3361 /* add constant */
3362 vpushi(c - TOK_MID);
3363 gen_op('+');
3364 vstore(); /* store value */
3365 if (post)
3366 vpop(); /* if post op, return saved value */
3369 ST_FUNC void parse_mult_str (CString *astr, const char *msg)
3371 /* read the string */
3372 if (tok != TOK_STR)
3373 expect(msg);
3374 cstr_new(astr);
3375 while (tok == TOK_STR) {
3376 /* XXX: add \0 handling too ? */
3377 cstr_cat(astr, tokc.str.data, -1);
3378 next();
3380 cstr_ccat(astr, '\0');
3383 /* If I is >= 1 and a power of two, returns log2(i)+1.
3384 If I is 0 returns 0. */
3385 static int exact_log2p1(int i)
3387 int ret;
3388 if (!i)
3389 return 0;
3390 for (ret = 1; i >= 1 << 8; ret += 8)
3391 i >>= 8;
3392 if (i >= 1 << 4)
3393 ret += 4, i >>= 4;
3394 if (i >= 1 << 2)
3395 ret += 2, i >>= 2;
3396 if (i >= 1 << 1)
3397 ret++;
3398 return ret;
3401 /* Parse __attribute__((...)) GNUC extension. */
3402 static void parse_attribute(AttributeDef *ad)
3404 int t, n;
3405 CString astr;
3407 redo:
3408 if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
3409 return;
3410 next();
3411 skip('(');
3412 skip('(');
3413 while (tok != ')') {
3414 if (tok < TOK_IDENT)
3415 expect("attribute name");
3416 t = tok;
3417 next();
3418 switch(t) {
3419 case TOK_CLEANUP1:
3420 case TOK_CLEANUP2:
3422 Sym *s;
3424 skip('(');
3425 s = sym_find(tok);
3426 if (!s) {
3427 tcc_warning("implicit declaration of function '%s'",
3428 get_tok_str(tok, &tokc));
3429 s = external_global_sym(tok, &func_old_type);
3431 ad->cleanup_func = s;
3432 next();
3433 skip(')');
3434 break;
3436 case TOK_SECTION1:
3437 case TOK_SECTION2:
3438 skip('(');
3439 parse_mult_str(&astr, "section name");
3440 ad->section = find_section(tcc_state, (char *)astr.data);
3441 skip(')');
3442 cstr_free(&astr);
3443 break;
3444 case TOK_ALIAS1:
3445 case TOK_ALIAS2:
3446 skip('(');
3447 parse_mult_str(&astr, "alias(\"target\")");
3448 ad->alias_target = /* save string as token, for later */
3449 tok_alloc((char*)astr.data, astr.size-1)->tok;
3450 skip(')');
3451 cstr_free(&astr);
3452 break;
3453 case TOK_VISIBILITY1:
3454 case TOK_VISIBILITY2:
3455 skip('(');
3456 parse_mult_str(&astr,
3457 "visibility(\"default|hidden|internal|protected\")");
3458 if (!strcmp (astr.data, "default"))
3459 ad->a.visibility = STV_DEFAULT;
3460 else if (!strcmp (astr.data, "hidden"))
3461 ad->a.visibility = STV_HIDDEN;
3462 else if (!strcmp (astr.data, "internal"))
3463 ad->a.visibility = STV_INTERNAL;
3464 else if (!strcmp (astr.data, "protected"))
3465 ad->a.visibility = STV_PROTECTED;
3466 else
3467 expect("visibility(\"default|hidden|internal|protected\")");
3468 skip(')');
3469 cstr_free(&astr);
3470 break;
3471 case TOK_ALIGNED1:
3472 case TOK_ALIGNED2:
3473 if (tok == '(') {
3474 next();
3475 n = expr_const();
3476 if (n <= 0 || (n & (n - 1)) != 0)
3477 tcc_error("alignment must be a positive power of two");
3478 skip(')');
3479 } else {
3480 n = MAX_ALIGN;
3482 ad->a.aligned = exact_log2p1(n);
3483 if (n != 1 << (ad->a.aligned - 1))
3484 tcc_error("alignment of %d is larger than implemented", n);
3485 break;
3486 case TOK_PACKED1:
3487 case TOK_PACKED2:
3488 ad->a.packed = 1;
3489 break;
3490 case TOK_WEAK1:
3491 case TOK_WEAK2:
3492 ad->a.weak = 1;
3493 break;
3494 case TOK_UNUSED1:
3495 case TOK_UNUSED2:
3496 /* currently, no need to handle it because tcc does not
3497 track unused objects */
3498 break;
3499 case TOK_NORETURN1:
3500 case TOK_NORETURN2:
3501 /* currently, no need to handle it because tcc does not
3502 track unused objects */
3503 break;
3504 case TOK_CDECL1:
3505 case TOK_CDECL2:
3506 case TOK_CDECL3:
3507 ad->f.func_call = FUNC_CDECL;
3508 break;
3509 case TOK_STDCALL1:
3510 case TOK_STDCALL2:
3511 case TOK_STDCALL3:
3512 ad->f.func_call = FUNC_STDCALL;
3513 break;
3514 #ifdef TCC_TARGET_I386
3515 case TOK_REGPARM1:
3516 case TOK_REGPARM2:
3517 skip('(');
3518 n = expr_const();
3519 if (n > 3)
3520 n = 3;
3521 else if (n < 0)
3522 n = 0;
3523 if (n > 0)
3524 ad->f.func_call = FUNC_FASTCALL1 + n - 1;
3525 skip(')');
3526 break;
3527 case TOK_FASTCALL1:
3528 case TOK_FASTCALL2:
3529 case TOK_FASTCALL3:
3530 ad->f.func_call = FUNC_FASTCALLW;
3531 break;
3532 #endif
3533 case TOK_MODE:
3534 skip('(');
3535 switch(tok) {
3536 case TOK_MODE_DI:
3537 ad->attr_mode = VT_LLONG + 1;
3538 break;
3539 case TOK_MODE_QI:
3540 ad->attr_mode = VT_BYTE + 1;
3541 break;
3542 case TOK_MODE_HI:
3543 ad->attr_mode = VT_SHORT + 1;
3544 break;
3545 case TOK_MODE_SI:
3546 case TOK_MODE_word:
3547 ad->attr_mode = VT_INT + 1;
3548 break;
3549 default:
3550 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
3551 break;
3553 next();
3554 skip(')');
3555 break;
3556 case TOK_DLLEXPORT:
3557 ad->a.dllexport = 1;
3558 break;
3559 case TOK_NODECORATE:
3560 ad->a.nodecorate = 1;
3561 break;
3562 case TOK_DLLIMPORT:
3563 ad->a.dllimport = 1;
3564 break;
3565 default:
3566 if (tcc_state->warn_unsupported)
3567 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
3568 /* skip parameters */
3569 if (tok == '(') {
3570 int parenthesis = 0;
3571 do {
3572 if (tok == '(')
3573 parenthesis++;
3574 else if (tok == ')')
3575 parenthesis--;
3576 next();
3577 } while (parenthesis && tok != -1);
3579 break;
3581 if (tok != ',')
3582 break;
3583 next();
3585 skip(')');
3586 skip(')');
3587 goto redo;
3590 static Sym * find_field (CType *type, int v, int *cumofs)
3592 Sym *s = type->ref;
3593 v |= SYM_FIELD;
3594 while ((s = s->next) != NULL) {
3595 if ((s->v & SYM_FIELD) &&
3596 (s->type.t & VT_BTYPE) == VT_STRUCT &&
3597 (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
3598 Sym *ret = find_field (&s->type, v, cumofs);
3599 if (ret) {
3600 *cumofs += s->c;
3601 return ret;
3604 if (s->v == v)
3605 break;
3607 return s;
3610 static void struct_layout(CType *type, AttributeDef *ad)
3612 int size, align, maxalign, offset, c, bit_pos, bit_size;
3613 int packed, a, bt, prevbt, prev_bit_size;
3614 int pcc = !tcc_state->ms_bitfields;
3615 int pragma_pack = *tcc_state->pack_stack_ptr;
3616 Sym *f;
3618 maxalign = 1;
3619 offset = 0;
3620 c = 0;
3621 bit_pos = 0;
3622 prevbt = VT_STRUCT; /* make it never match */
3623 prev_bit_size = 0;
3625 //#define BF_DEBUG
3627 for (f = type->ref->next; f; f = f->next) {
3628 if (f->type.t & VT_BITFIELD)
3629 bit_size = BIT_SIZE(f->type.t);
3630 else
3631 bit_size = -1;
3632 size = type_size(&f->type, &align);
3633 a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
3634 packed = 0;
3636 if (pcc && bit_size == 0) {
3637 /* in pcc mode, packing does not affect zero-width bitfields */
3639 } else {
3640 /* in pcc mode, attribute packed overrides if set. */
3641 if (pcc && (f->a.packed || ad->a.packed))
3642 align = packed = 1;
3644 /* pragma pack overrides align if lesser and packs bitfields always */
3645 if (pragma_pack) {
3646 packed = 1;
3647 if (pragma_pack < align)
3648 align = pragma_pack;
3649 /* in pcc mode pragma pack also overrides individual align */
3650 if (pcc && pragma_pack < a)
3651 a = 0;
3654 /* some individual align was specified */
3655 if (a)
3656 align = a;
3658 if (type->ref->type.t == VT_UNION) {
3659 if (pcc && bit_size >= 0)
3660 size = (bit_size + 7) >> 3;
3661 offset = 0;
3662 if (size > c)
3663 c = size;
3665 } else if (bit_size < 0) {
3666 if (pcc)
3667 c += (bit_pos + 7) >> 3;
3668 c = (c + align - 1) & -align;
3669 offset = c;
3670 if (size > 0)
3671 c += size;
3672 bit_pos = 0;
3673 prevbt = VT_STRUCT;
3674 prev_bit_size = 0;
3676 } else {
3677 /* A bit-field. Layout is more complicated. There are two
3678 options: PCC (GCC) compatible and MS compatible */
3679 if (pcc) {
3680 /* In PCC layout a bit-field is placed adjacent to the
3681 preceding bit-fields, except if:
3682 - it has zero-width
3683 - an individual alignment was given
3684 - it would overflow its base type container and
3685 there is no packing */
3686 if (bit_size == 0) {
3687 new_field:
3688 c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
3689 bit_pos = 0;
3690 } else if (f->a.aligned) {
3691 goto new_field;
3692 } else if (!packed) {
3693 int a8 = align * 8;
3694 int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
3695 if (ofs > size / align)
3696 goto new_field;
3699 /* in pcc mode, long long bitfields have type int if they fit */
3700 if (size == 8 && bit_size <= 32)
3701 f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
3703 while (bit_pos >= align * 8)
3704 c += align, bit_pos -= align * 8;
3705 offset = c;
3707 /* In PCC layout named bit-fields influence the alignment
3708 of the containing struct using the base types alignment,
3709 except for packed fields (which here have correct align). */
3710 if (f->v & SYM_FIRST_ANOM
3711 // && bit_size // ??? gcc on ARM/rpi does that
3713 align = 1;
3715 } else {
3716 bt = f->type.t & VT_BTYPE;
3717 if ((bit_pos + bit_size > size * 8)
3718 || (bit_size > 0) == (bt != prevbt)
3720 c = (c + align - 1) & -align;
3721 offset = c;
3722 bit_pos = 0;
3723 /* In MS bitfield mode a bit-field run always uses
3724 at least as many bits as the underlying type.
3725 To start a new run it's also required that this
3726 or the last bit-field had non-zero width. */
3727 if (bit_size || prev_bit_size)
3728 c += size;
3730 /* In MS layout the records alignment is normally
3731 influenced by the field, except for a zero-width
3732 field at the start of a run (but by further zero-width
3733 fields it is again). */
3734 if (bit_size == 0 && prevbt != bt)
3735 align = 1;
3736 prevbt = bt;
3737 prev_bit_size = bit_size;
3740 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
3741 | (bit_pos << VT_STRUCT_SHIFT);
3742 bit_pos += bit_size;
3744 if (align > maxalign)
3745 maxalign = align;
3747 #ifdef BF_DEBUG
3748 printf("set field %s offset %-2d size %-2d align %-2d",
3749 get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
3750 if (f->type.t & VT_BITFIELD) {
3751 printf(" pos %-2d bits %-2d",
3752 BIT_POS(f->type.t),
3753 BIT_SIZE(f->type.t)
3756 printf("\n");
3757 #endif
3759 f->c = offset;
3760 f->r = 0;
3763 if (pcc)
3764 c += (bit_pos + 7) >> 3;
3766 /* store size and alignment */
3767 a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
3768 if (a < maxalign)
3769 a = maxalign;
3770 type->ref->r = a;
3771 if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
3772 /* can happen if individual align for some member was given. In
3773 this case MSVC ignores maxalign when aligning the size */
3774 a = pragma_pack;
3775 if (a < bt)
3776 a = bt;
3778 c = (c + a - 1) & -a;
3779 type->ref->c = c;
3781 #ifdef BF_DEBUG
3782 printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
3783 #endif
3785 /* check whether we can access bitfields by their type */
3786 for (f = type->ref->next; f; f = f->next) {
3787 int s, px, cx, c0;
3788 CType t;
3790 if (0 == (f->type.t & VT_BITFIELD))
3791 continue;
3792 f->type.ref = f;
3793 f->auxtype = -1;
3794 bit_size = BIT_SIZE(f->type.t);
3795 if (bit_size == 0)
3796 continue;
3797 bit_pos = BIT_POS(f->type.t);
3798 size = type_size(&f->type, &align);
3799 if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
3800 continue;
3802 /* try to access the field using a different type */
3803 c0 = -1, s = align = 1;
3804 for (;;) {
3805 px = f->c * 8 + bit_pos;
3806 cx = (px >> 3) & -align;
3807 px = px - (cx << 3);
3808 if (c0 == cx)
3809 break;
3810 s = (px + bit_size + 7) >> 3;
3811 if (s > 4) {
3812 t.t = VT_LLONG;
3813 } else if (s > 2) {
3814 t.t = VT_INT;
3815 } else if (s > 1) {
3816 t.t = VT_SHORT;
3817 } else {
3818 t.t = VT_BYTE;
3820 s = type_size(&t, &align);
3821 c0 = cx;
3824 if (px + bit_size <= s * 8 && cx + s <= c) {
3825 /* update offset and bit position */
3826 f->c = cx;
3827 bit_pos = px;
3828 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
3829 | (bit_pos << VT_STRUCT_SHIFT);
3830 if (s != size)
3831 f->auxtype = t.t;
3832 #ifdef BF_DEBUG
3833 printf("FIX field %s offset %-2d size %-2d align %-2d "
3834 "pos %-2d bits %-2d\n",
3835 get_tok_str(f->v & ~SYM_FIELD, NULL),
3836 cx, s, align, px, bit_size);
3837 #endif
3838 } else {
3839 /* fall back to load/store single-byte wise */
3840 f->auxtype = VT_STRUCT;
3841 #ifdef BF_DEBUG
3842 printf("FIX field %s : load byte-wise\n",
3843 get_tok_str(f->v & ~SYM_FIELD, NULL));
3844 #endif
3849 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
3850 static void struct_decl(CType *type, int u)
3852 int v, c, size, align, flexible;
3853 int bit_size, bsize, bt;
3854 Sym *s, *ss, **ps;
3855 AttributeDef ad, ad1;
3856 CType type1, btype;
3858 memset(&ad, 0, sizeof ad);
3859 next();
3860 parse_attribute(&ad);
3861 if (tok != '{') {
3862 v = tok;
3863 next();
3864 /* struct already defined ? return it */
3865 if (v < TOK_IDENT)
3866 expect("struct/union/enum name");
3867 s = struct_find(v);
3868 if (s && (s->sym_scope == local_scope || tok != '{')) {
3869 if (u == s->type.t)
3870 goto do_decl;
3871 if (u == VT_ENUM && IS_ENUM(s->type.t))
3872 goto do_decl;
3873 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
3875 } else {
3876 v = anon_sym++;
3878 /* Record the original enum/struct/union token. */
3879 type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
3880 type1.ref = NULL;
3881 /* we put an undefined size for struct/union */
3882 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
3883 s->r = 0; /* default alignment is zero as gcc */
3884 do_decl:
3885 type->t = s->type.t;
3886 type->ref = s;
3888 if (tok == '{') {
3889 next();
3890 if (s->c != -1)
3891 tcc_error("struct/union/enum already defined");
3892 s->c = -2;
3893 /* cannot be empty */
3894 /* non empty enums are not allowed */
3895 ps = &s->next;
3896 if (u == VT_ENUM) {
3897 long long ll = 0, pl = 0, nl = 0;
3898 CType t;
3899 t.ref = s;
3900 /* enum symbols have static storage */
3901 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
3902 for(;;) {
3903 v = tok;
3904 if (v < TOK_UIDENT)
3905 expect("identifier");
3906 ss = sym_find(v);
3907 if (ss && !local_stack)
3908 tcc_error("redefinition of enumerator '%s'",
3909 get_tok_str(v, NULL));
3910 next();
3911 if (tok == '=') {
3912 next();
3913 ll = expr_const64();
3915 ss = sym_push(v, &t, VT_CONST, 0);
3916 ss->enum_val = ll;
3917 *ps = ss, ps = &ss->next;
3918 if (ll < nl)
3919 nl = ll;
3920 if (ll > pl)
3921 pl = ll;
3922 if (tok != ',')
3923 break;
3924 next();
3925 ll++;
3926 /* NOTE: we accept a trailing comma */
3927 if (tok == '}')
3928 break;
3930 skip('}');
3931 /* set integral type of the enum */
3932 t.t = VT_INT;
3933 if (nl >= 0) {
3934 if (pl != (unsigned)pl)
3935 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
3936 t.t |= VT_UNSIGNED;
3937 } else if (pl != (int)pl || nl != (int)nl)
3938 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
3939 s->type.t = type->t = t.t | VT_ENUM;
3940 s->c = 0;
3941 /* set type for enum members */
3942 for (ss = s->next; ss; ss = ss->next) {
3943 ll = ss->enum_val;
3944 if (ll == (int)ll) /* default is int if it fits */
3945 continue;
3946 if (t.t & VT_UNSIGNED) {
3947 ss->type.t |= VT_UNSIGNED;
3948 if (ll == (unsigned)ll)
3949 continue;
3951 ss->type.t = (ss->type.t & ~VT_BTYPE)
3952 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
3954 } else {
3955 c = 0;
3956 flexible = 0;
3957 while (tok != '}') {
3958 if (!parse_btype(&btype, &ad1)) {
3959 skip(';');
3960 continue;
3962 while (1) {
3963 if (flexible)
3964 tcc_error("flexible array member '%s' not at the end of struct",
3965 get_tok_str(v, NULL));
3966 bit_size = -1;
3967 v = 0;
3968 type1 = btype;
3969 if (tok != ':') {
3970 if (tok != ';')
3971 type_decl(&type1, &ad1, &v, TYPE_DIRECT);
3972 if (v == 0) {
3973 if ((type1.t & VT_BTYPE) != VT_STRUCT)
3974 expect("identifier");
3975 else {
3976 int v = btype.ref->v;
3977 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
3978 if (tcc_state->ms_extensions == 0)
3979 expect("identifier");
3983 if (type_size(&type1, &align) < 0) {
3984 if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
3985 flexible = 1;
3986 else
3987 tcc_error("field '%s' has incomplete type",
3988 get_tok_str(v, NULL));
3990 if ((type1.t & VT_BTYPE) == VT_FUNC ||
3991 (type1.t & VT_BTYPE) == VT_VOID ||
3992 (type1.t & VT_STORAGE))
3993 tcc_error("invalid type for '%s'",
3994 get_tok_str(v, NULL));
3996 if (tok == ':') {
3997 next();
3998 bit_size = expr_const();
3999 /* XXX: handle v = 0 case for messages */
4000 if (bit_size < 0)
4001 tcc_error("negative width in bit-field '%s'",
4002 get_tok_str(v, NULL));
4003 if (v && bit_size == 0)
4004 tcc_error("zero width for bit-field '%s'",
4005 get_tok_str(v, NULL));
4006 parse_attribute(&ad1);
4008 size = type_size(&type1, &align);
4009 if (bit_size >= 0) {
4010 bt = type1.t & VT_BTYPE;
4011 if (bt != VT_INT &&
4012 bt != VT_BYTE &&
4013 bt != VT_SHORT &&
4014 bt != VT_BOOL &&
4015 bt != VT_LLONG)
4016 tcc_error("bitfields must have scalar type");
4017 bsize = size * 8;
4018 if (bit_size > bsize) {
4019 tcc_error("width of '%s' exceeds its type",
4020 get_tok_str(v, NULL));
4021 } else if (bit_size == bsize
4022 && !ad.a.packed && !ad1.a.packed) {
4023 /* no need for bit fields */
4025 } else if (bit_size == 64) {
4026 tcc_error("field width 64 not implemented");
4027 } else {
4028 type1.t = (type1.t & ~VT_STRUCT_MASK)
4029 | VT_BITFIELD
4030 | (bit_size << (VT_STRUCT_SHIFT + 6));
4033 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
4034 /* Remember we've seen a real field to check
4035 for placement of flexible array member. */
4036 c = 1;
4038 /* If member is a struct or bit-field, enforce
4039 placing into the struct (as anonymous). */
4040 if (v == 0 &&
4041 ((type1.t & VT_BTYPE) == VT_STRUCT ||
4042 bit_size >= 0)) {
4043 v = anon_sym++;
4045 if (v) {
4046 ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
4047 ss->a = ad1.a;
4048 *ps = ss;
4049 ps = &ss->next;
4051 if (tok == ';' || tok == TOK_EOF)
4052 break;
4053 skip(',');
4055 skip(';');
4057 skip('}');
4058 parse_attribute(&ad);
4059 struct_layout(type, &ad);
4064 static void sym_to_attr(AttributeDef *ad, Sym *s)
4066 merge_symattr(&ad->a, &s->a);
4067 merge_funcattr(&ad->f, &s->f);
4070 /* Add type qualifiers to a type. If the type is an array then the qualifiers
4071 are added to the element type, copied because it could be a typedef. */
4072 static void parse_btype_qualify(CType *type, int qualifiers)
4074 while (type->t & VT_ARRAY) {
4075 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
4076 type = &type->ref->type;
4078 type->t |= qualifiers;
4081 /* return 0 if no type declaration. otherwise, return the basic type
4082 and skip it.
4084 static int parse_btype(CType *type, AttributeDef *ad)
4086 int t, u, bt, st, type_found, typespec_found, g;
4087 Sym *s;
4088 CType type1;
4090 memset(ad, 0, sizeof(AttributeDef));
4091 type_found = 0;
4092 typespec_found = 0;
4093 t = VT_INT;
4094 bt = st = -1;
4095 type->ref = NULL;
4097 while(1) {
4098 switch(tok) {
4099 case TOK_EXTENSION:
4100 /* currently, we really ignore extension */
4101 next();
4102 continue;
4104 /* basic types */
4105 case TOK_CHAR:
4106 u = VT_BYTE;
4107 basic_type:
4108 next();
4109 basic_type1:
4110 if (u == VT_SHORT || u == VT_LONG) {
4111 if (st != -1 || (bt != -1 && bt != VT_INT))
4112 tmbt: tcc_error("too many basic types");
4113 st = u;
4114 } else {
4115 if (bt != -1 || (st != -1 && u != VT_INT))
4116 goto tmbt;
4117 bt = u;
4119 if (u != VT_INT)
4120 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
4121 typespec_found = 1;
4122 break;
4123 case TOK_VOID:
4124 u = VT_VOID;
4125 goto basic_type;
4126 case TOK_SHORT:
4127 u = VT_SHORT;
4128 goto basic_type;
4129 case TOK_INT:
4130 u = VT_INT;
4131 goto basic_type;
4132 case TOK_ALIGNAS:
4133 { int n;
4134 AttributeDef ad1;
4135 next();
4136 skip('(');
4137 memset(&ad1, 0, sizeof(AttributeDef));
4138 if (parse_btype(&type1, &ad1)) {
4139 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
4140 if (ad1.a.aligned)
4141 n = 1 << (ad1.a.aligned - 1);
4142 else
4143 type_size(&type1, &n);
4144 } else {
4145 n = expr_const();
4146 if (n <= 0 || (n & (n - 1)) != 0)
4147 tcc_error("alignment must be a positive power of two");
4149 skip(')');
4150 ad->a.aligned = exact_log2p1(n);
4152 continue;
4153 case TOK_LONG:
4154 if ((t & VT_BTYPE) == VT_DOUBLE) {
4155 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
4156 } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4157 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
4158 } else {
4159 u = VT_LONG;
4160 goto basic_type;
4162 next();
4163 break;
4164 #ifdef TCC_TARGET_ARM64
4165 case TOK_UINT128:
4166 /* GCC's __uint128_t appears in some Linux header files. Make it a
4167 synonym for long double to get the size and alignment right. */
4168 u = VT_LDOUBLE;
4169 goto basic_type;
4170 #endif
4171 case TOK_BOOL:
4172 u = VT_BOOL;
4173 goto basic_type;
4174 case TOK_FLOAT:
4175 u = VT_FLOAT;
4176 goto basic_type;
4177 case TOK_DOUBLE:
4178 if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4179 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
4180 } else {
4181 u = VT_DOUBLE;
4182 goto basic_type;
4184 next();
4185 break;
4186 case TOK_ENUM:
4187 struct_decl(&type1, VT_ENUM);
4188 basic_type2:
4189 u = type1.t;
4190 type->ref = type1.ref;
4191 goto basic_type1;
4192 case TOK_STRUCT:
4193 struct_decl(&type1, VT_STRUCT);
4194 goto basic_type2;
4195 case TOK_UNION:
4196 struct_decl(&type1, VT_UNION);
4197 goto basic_type2;
4199 /* type modifiers */
4200 case TOK_CONST1:
4201 case TOK_CONST2:
4202 case TOK_CONST3:
4203 type->t = t;
4204 parse_btype_qualify(type, VT_CONSTANT);
4205 t = type->t;
4206 next();
4207 break;
4208 case TOK_VOLATILE1:
4209 case TOK_VOLATILE2:
4210 case TOK_VOLATILE3:
4211 type->t = t;
4212 parse_btype_qualify(type, VT_VOLATILE);
4213 t = type->t;
4214 next();
4215 break;
4216 case TOK_SIGNED1:
4217 case TOK_SIGNED2:
4218 case TOK_SIGNED3:
4219 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
4220 tcc_error("signed and unsigned modifier");
4221 t |= VT_DEFSIGN;
4222 next();
4223 typespec_found = 1;
4224 break;
4225 case TOK_REGISTER:
4226 case TOK_AUTO:
4227 case TOK_RESTRICT1:
4228 case TOK_RESTRICT2:
4229 case TOK_RESTRICT3:
4230 next();
4231 break;
4232 case TOK_UNSIGNED:
4233 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
4234 tcc_error("signed and unsigned modifier");
4235 t |= VT_DEFSIGN | VT_UNSIGNED;
4236 next();
4237 typespec_found = 1;
4238 break;
4240 /* storage */
4241 case TOK_EXTERN:
4242 g = VT_EXTERN;
4243 goto storage;
4244 case TOK_STATIC:
4245 g = VT_STATIC;
4246 goto storage;
4247 case TOK_TYPEDEF:
4248 g = VT_TYPEDEF;
4249 goto storage;
4250 storage:
4251 if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
4252 tcc_error("multiple storage classes");
4253 t |= g;
4254 next();
4255 break;
4256 case TOK_INLINE1:
4257 case TOK_INLINE2:
4258 case TOK_INLINE3:
4259 t |= VT_INLINE;
4260 next();
4261 break;
4262 case TOK_NORETURN3:
4263 /* currently, no need to handle it because tcc does not
4264 track unused objects */
4265 next();
4266 break;
4267 /* GNUC attribute */
4268 case TOK_ATTRIBUTE1:
4269 case TOK_ATTRIBUTE2:
4270 parse_attribute(ad);
4271 if (ad->attr_mode) {
4272 u = ad->attr_mode -1;
4273 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
4275 continue;
4276 /* GNUC typeof */
4277 case TOK_TYPEOF1:
4278 case TOK_TYPEOF2:
4279 case TOK_TYPEOF3:
4280 next();
4281 parse_expr_type(&type1);
4282 /* remove all storage modifiers except typedef */
4283 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
4284 if (type1.ref)
4285 sym_to_attr(ad, type1.ref);
4286 goto basic_type2;
4287 default:
4288 if (typespec_found)
4289 goto the_end;
4290 s = sym_find(tok);
4291 if (!s || !(s->type.t & VT_TYPEDEF))
4292 goto the_end;
4293 t &= ~(VT_BTYPE|VT_LONG);
4294 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
4295 type->t = (s->type.t & ~VT_TYPEDEF) | u;
4296 type->ref = s->type.ref;
4297 if (t)
4298 parse_btype_qualify(type, t);
4299 t = type->t;
4300 /* get attributes from typedef */
4301 sym_to_attr(ad, s);
4302 next();
4303 typespec_found = 1;
4304 st = bt = -2;
4305 break;
4307 type_found = 1;
4309 the_end:
4310 if (tcc_state->char_is_unsigned) {
4311 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
4312 t |= VT_UNSIGNED;
4314 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
4315 bt = t & (VT_BTYPE|VT_LONG);
4316 if (bt == VT_LONG)
4317 t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
4318 #ifdef TCC_TARGET_PE
4319 if (bt == VT_LDOUBLE)
4320 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE;
4321 #endif
4322 type->t = t;
4323 return type_found;
4326 /* convert a function parameter type (array to pointer and function to
4327 function pointer) */
4328 static inline void convert_parameter_type(CType *pt)
4330 /* remove const and volatile qualifiers (XXX: const could be used
4331 to indicate a const function parameter */
4332 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
4333 /* array must be transformed to pointer according to ANSI C */
4334 pt->t &= ~VT_ARRAY;
4335 if ((pt->t & VT_BTYPE) == VT_FUNC) {
4336 mk_pointer(pt);
4340 ST_FUNC void parse_asm_str(CString *astr)
4342 skip('(');
4343 parse_mult_str(astr, "string constant");
4346 /* Parse an asm label and return the token */
4347 static int asm_label_instr(void)
4349 int v;
4350 CString astr;
4352 next();
4353 parse_asm_str(&astr);
4354 skip(')');
4355 #ifdef ASM_DEBUG
4356 printf("asm_alias: \"%s\"\n", (char *)astr.data);
4357 #endif
4358 v = tok_alloc(astr.data, astr.size - 1)->tok;
4359 cstr_free(&astr);
4360 return v;
4363 static int post_type(CType *type, AttributeDef *ad, int storage, int td)
4365 int n, l, t1, arg_size, align;
4366 Sym **plast, *s, *first;
4367 AttributeDef ad1;
4368 CType pt;
4370 if (tok == '(') {
4371 /* function type, or recursive declarator (return if so) */
4372 next();
4373 if (td && !(td & TYPE_ABSTRACT))
4374 return 0;
4375 if (tok == ')')
4376 l = 0;
4377 else if (parse_btype(&pt, &ad1))
4378 l = FUNC_NEW;
4379 else if (td) {
4380 merge_attr (ad, &ad1);
4381 return 0;
4382 } else
4383 l = FUNC_OLD;
4384 first = NULL;
4385 plast = &first;
4386 arg_size = 0;
4387 if (l) {
4388 for(;;) {
4389 /* read param name and compute offset */
4390 if (l != FUNC_OLD) {
4391 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
4392 break;
4393 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
4394 if ((pt.t & VT_BTYPE) == VT_VOID)
4395 tcc_error("parameter declared as void");
4396 } else {
4397 n = tok;
4398 if (n < TOK_UIDENT)
4399 expect("identifier");
4400 pt.t = VT_VOID; /* invalid type */
4401 next();
4403 convert_parameter_type(&pt);
4404 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
4405 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
4406 *plast = s;
4407 plast = &s->next;
4408 if (tok == ')')
4409 break;
4410 skip(',');
4411 if (l == FUNC_NEW && tok == TOK_DOTS) {
4412 l = FUNC_ELLIPSIS;
4413 next();
4414 break;
4416 if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
4417 tcc_error("invalid type");
4419 } else
4420 /* if no parameters, then old type prototype */
4421 l = FUNC_OLD;
4422 skip(')');
4423 /* NOTE: const is ignored in returned type as it has a special
4424 meaning in gcc / C++ */
4425 type->t &= ~VT_CONSTANT;
4426 /* some ancient pre-K&R C allows a function to return an array
4427 and the array brackets to be put after the arguments, such
4428 that "int c()[]" means something like "int[] c()" */
4429 if (tok == '[') {
4430 next();
4431 skip(']'); /* only handle simple "[]" */
4432 mk_pointer(type);
4434 /* we push a anonymous symbol which will contain the function prototype */
4435 ad->f.func_args = arg_size;
4436 ad->f.func_type = l;
4437 s = sym_push(SYM_FIELD, type, 0, 0);
4438 s->a = ad->a;
4439 s->f = ad->f;
4440 s->next = first;
4441 type->t = VT_FUNC;
4442 type->ref = s;
4443 } else if (tok == '[') {
4444 int saved_nocode_wanted = nocode_wanted;
4445 /* array definition */
4446 next();
4447 while (1) {
4448 /* XXX The optional type-quals and static should only be accepted
4449 in parameter decls. The '*' as well, and then even only
4450 in prototypes (not function defs). */
4451 switch (tok) {
4452 case TOK_RESTRICT1: case TOK_RESTRICT2: case TOK_RESTRICT3:
4453 case TOK_CONST1:
4454 case TOK_VOLATILE1:
4455 case TOK_STATIC:
4456 case '*':
4457 next();
4458 continue;
4459 default:
4460 break;
4462 break;
4464 n = -1;
4465 t1 = 0;
4466 if (tok != ']') {
4467 if (!local_stack || (storage & VT_STATIC))
4468 vpushi(expr_const());
4469 else {
4470 /* VLAs (which can only happen with local_stack && !VT_STATIC)
4471 length must always be evaluated, even under nocode_wanted,
4472 so that its size slot is initialized (e.g. under sizeof
4473 or typeof). */
4474 nocode_wanted = 0;
4475 gexpr();
4477 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4478 n = vtop->c.i;
4479 if (n < 0)
4480 tcc_error("invalid array size");
4481 } else {
4482 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
4483 tcc_error("size of variable length array should be an integer");
4484 n = 0;
4485 t1 = VT_VLA;
4488 skip(']');
4489 /* parse next post type */
4490 post_type(type, ad, storage, 0);
4491 if (type->t == VT_FUNC)
4492 tcc_error("declaration of an array of functions");
4493 t1 |= type->t & VT_VLA;
4495 if (t1 & VT_VLA) {
4496 if (n < 0)
4497 tcc_error("need explicit inner array size in VLAs");
4498 loc -= type_size(&int_type, &align);
4499 loc &= -align;
4500 n = loc;
4502 vla_runtime_type_size(type, &align);
4503 gen_op('*');
4504 vset(&int_type, VT_LOCAL|VT_LVAL, n);
4505 vswap();
4506 vstore();
4508 if (n != -1)
4509 vpop();
4510 nocode_wanted = saved_nocode_wanted;
4512 /* we push an anonymous symbol which will contain the array
4513 element type */
4514 s = sym_push(SYM_FIELD, type, 0, n);
4515 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
4516 type->ref = s;
4518 return 1;
4521 /* Parse a type declarator (except basic type), and return the type
4522 in 'type'. 'td' is a bitmask indicating which kind of type decl is
4523 expected. 'type' should contain the basic type. 'ad' is the
4524 attribute definition of the basic type. It can be modified by
4525 type_decl(). If this (possibly abstract) declarator is a pointer chain
4526 it returns the innermost pointed to type (equals *type, but is a different
4527 pointer), otherwise returns type itself, that's used for recursive calls. */
4528 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
4530 CType *post, *ret;
4531 int qualifiers, storage;
4533 /* recursive type, remove storage bits first, apply them later again */
4534 storage = type->t & VT_STORAGE;
4535 type->t &= ~VT_STORAGE;
4536 post = ret = type;
4538 while (tok == '*') {
4539 qualifiers = 0;
4540 redo:
4541 next();
4542 switch(tok) {
4543 case TOK_CONST1:
4544 case TOK_CONST2:
4545 case TOK_CONST3:
4546 qualifiers |= VT_CONSTANT;
4547 goto redo;
4548 case TOK_VOLATILE1:
4549 case TOK_VOLATILE2:
4550 case TOK_VOLATILE3:
4551 qualifiers |= VT_VOLATILE;
4552 goto redo;
4553 case TOK_RESTRICT1:
4554 case TOK_RESTRICT2:
4555 case TOK_RESTRICT3:
4556 goto redo;
4557 /* XXX: clarify attribute handling */
4558 case TOK_ATTRIBUTE1:
4559 case TOK_ATTRIBUTE2:
4560 parse_attribute(ad);
4561 break;
4563 mk_pointer(type);
4564 type->t |= qualifiers;
4565 if (ret == type)
4566 /* innermost pointed to type is the one for the first derivation */
4567 ret = pointed_type(type);
4570 if (tok == '(') {
4571 /* This is possibly a parameter type list for abstract declarators
4572 ('int ()'), use post_type for testing this. */
4573 if (!post_type(type, ad, 0, td)) {
4574 /* It's not, so it's a nested declarator, and the post operations
4575 apply to the innermost pointed to type (if any). */
4576 /* XXX: this is not correct to modify 'ad' at this point, but
4577 the syntax is not clear */
4578 parse_attribute(ad);
4579 post = type_decl(type, ad, v, td);
4580 skip(')');
4581 } else
4582 goto abstract;
4583 } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
4584 /* type identifier */
4585 *v = tok;
4586 next();
4587 } else {
4588 abstract:
4589 if (!(td & TYPE_ABSTRACT))
4590 expect("identifier");
4591 *v = 0;
4593 post_type(post, ad, storage, 0);
4594 parse_attribute(ad);
4595 type->t |= storage;
4596 return ret;
4599 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4600 ST_FUNC int lvalue_type(int t)
4602 int bt, r;
4603 r = VT_LVAL;
4604 bt = t & VT_BTYPE;
4605 if (bt == VT_BYTE || bt == VT_BOOL)
4606 r |= VT_LVAL_BYTE;
4607 else if (bt == VT_SHORT)
4608 r |= VT_LVAL_SHORT;
4609 else
4610 return r;
4611 if (t & VT_UNSIGNED)
4612 r |= VT_LVAL_UNSIGNED;
4613 return r;
4616 /* indirection with full error checking and bound check */
4617 ST_FUNC void indir(void)
4619 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
4620 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
4621 return;
4622 expect("pointer");
4624 if (vtop->r & VT_LVAL)
4625 gv(RC_INT);
4626 vtop->type = *pointed_type(&vtop->type);
4627 /* Arrays and functions are never lvalues */
4628 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
4629 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
4630 vtop->r |= lvalue_type(vtop->type.t);
4631 /* if bound checking, the referenced pointer must be checked */
4632 #ifdef CONFIG_TCC_BCHECK
4633 if (tcc_state->do_bounds_check)
4634 vtop->r |= VT_MUSTBOUND;
4635 #endif
4639 /* pass a parameter to a function and do type checking and casting */
4640 static void gfunc_param_typed(Sym *func, Sym *arg)
4642 int func_type;
4643 CType type;
4645 func_type = func->f.func_type;
4646 if (func_type == FUNC_OLD ||
4647 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
4648 /* default casting : only need to convert float to double */
4649 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
4650 gen_cast_s(VT_DOUBLE);
4651 } else if (vtop->type.t & VT_BITFIELD) {
4652 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
4653 type.ref = vtop->type.ref;
4654 gen_cast(&type);
4656 } else if (arg == NULL) {
4657 tcc_error("too many arguments to function");
4658 } else {
4659 type = arg->type;
4660 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4661 gen_assign_cast(&type);
4665 /* parse an expression and return its type without any side effect. */
4666 static void expr_type(CType *type, void (*expr_fn)(void))
4668 nocode_wanted++;
4669 expr_fn();
4670 *type = vtop->type;
4671 vpop();
4672 nocode_wanted--;
4675 /* parse an expression of the form '(type)' or '(expr)' and return its
4676 type */
4677 static void parse_expr_type(CType *type)
4679 int n;
4680 AttributeDef ad;
4682 skip('(');
4683 if (parse_btype(type, &ad)) {
4684 type_decl(type, &ad, &n, TYPE_ABSTRACT);
4685 } else {
4686 expr_type(type, gexpr);
4688 skip(')');
4691 static void parse_type(CType *type)
4693 AttributeDef ad;
4694 int n;
4696 if (!parse_btype(type, &ad)) {
4697 expect("type");
4699 type_decl(type, &ad, &n, TYPE_ABSTRACT);
4702 static void parse_builtin_params(int nc, const char *args)
4704 char c, sep = '(';
4705 CType t;
4706 if (nc)
4707 nocode_wanted++;
4708 next();
4709 while ((c = *args++)) {
4710 skip(sep);
4711 sep = ',';
4712 switch (c) {
4713 case 'e': expr_eq(); continue;
4714 case 't': parse_type(&t); vpush(&t); continue;
4715 default: tcc_error("internal error"); break;
4718 skip(')');
4719 if (nc)
4720 nocode_wanted--;
4723 static void try_call_scope_cleanup(Sym *stop)
4725 Sym *cls = current_cleanups;
4727 for (; cls != stop; cls = cls->ncl) {
4728 Sym *fs = cls->next;
4729 Sym *vs = cls->prev_tok;
4731 vpushsym(&fs->type, fs);
4732 vset(&vs->type, vs->r, vs->c);
4733 vtop->sym = vs;
4734 mk_pointer(&vtop->type);
4735 gaddrof();
4736 gfunc_call(1);
4740 static void try_call_cleanup_goto(Sym *cleanupstate)
4742 Sym *oc, *cc;
4743 int ocd, ccd;
4745 if (!current_cleanups)
4746 return;
4748 /* search NCA of both cleanup chains given parents and initial depth */
4749 ocd = cleanupstate ? cleanupstate->v & ~SYM_FIELD : 0;
4750 for (ccd = ncleanups, oc = cleanupstate; ocd > ccd; --ocd, oc = oc->ncl)
4752 for (cc = current_cleanups; ccd > ocd; --ccd, cc = cc->ncl)
4754 for (; cc != oc; cc = cc->ncl, oc = oc->ncl, --ccd)
4757 try_call_scope_cleanup(cc);
4760 ST_FUNC void unary(void)
4762 int n, t, align, size, r, sizeof_caller;
4763 CType type;
4764 Sym *s;
4765 AttributeDef ad;
4767 sizeof_caller = in_sizeof;
4768 in_sizeof = 0;
4769 type.ref = NULL;
4770 /* XXX: GCC 2.95.3 does not generate a table although it should be
4771 better here */
4772 tok_next:
4773 switch(tok) {
4774 case TOK_EXTENSION:
4775 next();
4776 goto tok_next;
4777 case TOK_LCHAR:
4778 #ifdef TCC_TARGET_PE
4779 t = VT_SHORT|VT_UNSIGNED;
4780 goto push_tokc;
4781 #endif
4782 case TOK_CINT:
4783 case TOK_CCHAR:
4784 t = VT_INT;
4785 push_tokc:
4786 type.t = t;
4787 vsetc(&type, VT_CONST, &tokc);
4788 next();
4789 break;
4790 case TOK_CUINT:
4791 t = VT_INT | VT_UNSIGNED;
4792 goto push_tokc;
4793 case TOK_CLLONG:
4794 t = VT_LLONG;
4795 goto push_tokc;
4796 case TOK_CULLONG:
4797 t = VT_LLONG | VT_UNSIGNED;
4798 goto push_tokc;
4799 case TOK_CFLOAT:
4800 t = VT_FLOAT;
4801 goto push_tokc;
4802 case TOK_CDOUBLE:
4803 t = VT_DOUBLE;
4804 goto push_tokc;
4805 case TOK_CLDOUBLE:
4806 t = VT_LDOUBLE;
4807 goto push_tokc;
4808 case TOK_CLONG:
4809 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
4810 goto push_tokc;
4811 case TOK_CULONG:
4812 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
4813 goto push_tokc;
4814 case TOK___FUNCTION__:
4815 if (!gnu_ext)
4816 goto tok_identifier;
4817 /* fall thru */
4818 case TOK___FUNC__:
4820 void *ptr;
4821 int len;
4822 /* special function name identifier */
4823 len = strlen(funcname) + 1;
4824 /* generate char[len] type */
4825 type.t = VT_BYTE;
4826 mk_pointer(&type);
4827 type.t |= VT_ARRAY;
4828 type.ref->c = len;
4829 vpush_ref(&type, data_section, data_section->data_offset, len);
4830 if (!NODATA_WANTED) {
4831 ptr = section_ptr_add(data_section, len);
4832 memcpy(ptr, funcname, len);
4834 next();
4836 break;
4837 case TOK_LSTR:
4838 #ifdef TCC_TARGET_PE
4839 t = VT_SHORT | VT_UNSIGNED;
4840 #else
4841 t = VT_INT;
4842 #endif
4843 goto str_init;
4844 case TOK_STR:
4845 /* string parsing */
4846 t = VT_BYTE;
4847 if (tcc_state->char_is_unsigned)
4848 t = VT_BYTE | VT_UNSIGNED;
4849 str_init:
4850 if (tcc_state->warn_write_strings)
4851 t |= VT_CONSTANT;
4852 type.t = t;
4853 mk_pointer(&type);
4854 type.t |= VT_ARRAY;
4855 memset(&ad, 0, sizeof(AttributeDef));
4856 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
4857 break;
4858 case '(':
4859 next();
4860 /* cast ? */
4861 if (parse_btype(&type, &ad)) {
4862 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
4863 skip(')');
4864 /* check ISOC99 compound literal */
4865 if (tok == '{') {
4866 /* data is allocated locally by default */
4867 if (global_expr)
4868 r = VT_CONST;
4869 else
4870 r = VT_LOCAL;
4871 /* all except arrays are lvalues */
4872 if (!(type.t & VT_ARRAY))
4873 r |= lvalue_type(type.t);
4874 memset(&ad, 0, sizeof(AttributeDef));
4875 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
4876 } else {
4877 if (sizeof_caller) {
4878 vpush(&type);
4879 return;
4881 unary();
4882 gen_cast(&type);
4884 } else if (tok == '{') {
4885 int saved_nocode_wanted = nocode_wanted;
4886 if (const_wanted)
4887 tcc_error("expected constant");
4888 /* save all registers */
4889 save_regs(0);
4890 /* statement expression : we do not accept break/continue
4891 inside as GCC does. We do retain the nocode_wanted state,
4892 as statement expressions can't ever be entered from the
4893 outside, so any reactivation of code emission (from labels
4894 or loop heads) can be disabled again after the end of it. */
4895 block(NULL, NULL, NULL, NULL, 1);
4896 nocode_wanted = saved_nocode_wanted;
4897 skip(')');
4898 } else {
4899 gexpr();
4900 skip(')');
4902 break;
4903 case '*':
4904 next();
4905 unary();
4906 indir();
4907 break;
4908 case '&':
4909 next();
4910 unary();
4911 /* functions names must be treated as function pointers,
4912 except for unary '&' and sizeof. Since we consider that
4913 functions are not lvalues, we only have to handle it
4914 there and in function calls. */
4915 /* arrays can also be used although they are not lvalues */
4916 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
4917 !(vtop->type.t & VT_ARRAY))
4918 test_lvalue();
4919 mk_pointer(&vtop->type);
4920 gaddrof();
4921 break;
4922 case '!':
4923 next();
4924 unary();
4925 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4926 gen_cast_s(VT_BOOL);
4927 vtop->c.i = !vtop->c.i;
4928 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
4929 vtop->c.i ^= 1;
4930 else {
4931 save_regs(1);
4932 vseti(VT_JMP, gvtst(1, 0));
4934 break;
4935 case '~':
4936 next();
4937 unary();
4938 vpushi(-1);
4939 gen_op('^');
4940 break;
4941 case '+':
4942 next();
4943 unary();
4944 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
4945 tcc_error("pointer not accepted for unary plus");
4946 /* In order to force cast, we add zero, except for floating point
4947 where we really need an noop (otherwise -0.0 will be transformed
4948 into +0.0). */
4949 if (!is_float(vtop->type.t)) {
4950 vpushi(0);
4951 gen_op('+');
4953 break;
4954 case TOK_SIZEOF:
4955 case TOK_ALIGNOF1:
4956 case TOK_ALIGNOF2:
4957 case TOK_ALIGNOF3:
4958 t = tok;
4959 next();
4960 in_sizeof++;
4961 expr_type(&type, unary); /* Perform a in_sizeof = 0; */
4962 s = vtop[1].sym; /* hack: accessing previous vtop */
4963 size = type_size(&type, &align);
4964 if (s && s->a.aligned)
4965 align = 1 << (s->a.aligned - 1);
4966 if (t == TOK_SIZEOF) {
4967 if (!(type.t & VT_VLA)) {
4968 if (size < 0)
4969 tcc_error("sizeof applied to an incomplete type");
4970 vpushs(size);
4971 } else {
4972 vla_runtime_type_size(&type, &align);
4974 } else {
4975 vpushs(align);
4977 vtop->type.t |= VT_UNSIGNED;
4978 break;
4980 case TOK_builtin_expect:
4981 /* __builtin_expect is a no-op for now */
4982 parse_builtin_params(0, "ee");
4983 vpop();
4984 break;
4985 case TOK_builtin_types_compatible_p:
4986 parse_builtin_params(0, "tt");
4987 vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
4988 vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
4989 n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
4990 vtop -= 2;
4991 vpushi(n);
4992 break;
4993 case TOK_builtin_choose_expr:
4995 int64_t c;
4996 next();
4997 skip('(');
4998 c = expr_const64();
4999 skip(',');
5000 if (!c) {
5001 nocode_wanted++;
5003 expr_eq();
5004 if (!c) {
5005 vpop();
5006 nocode_wanted--;
5008 skip(',');
5009 if (c) {
5010 nocode_wanted++;
5012 expr_eq();
5013 if (c) {
5014 vpop();
5015 nocode_wanted--;
5017 skip(')');
5019 break;
5020 case TOK_builtin_constant_p:
5021 parse_builtin_params(1, "e");
5022 n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5023 vtop--;
5024 vpushi(n);
5025 break;
5026 case TOK_builtin_frame_address:
5027 case TOK_builtin_return_address:
5029 int tok1 = tok;
5030 int level;
5031 next();
5032 skip('(');
5033 if (tok != TOK_CINT) {
5034 tcc_error("%s only takes positive integers",
5035 tok1 == TOK_builtin_return_address ?
5036 "__builtin_return_address" :
5037 "__builtin_frame_address");
5039 level = (uint32_t)tokc.i;
5040 next();
5041 skip(')');
5042 type.t = VT_VOID;
5043 mk_pointer(&type);
5044 vset(&type, VT_LOCAL, 0); /* local frame */
5045 while (level--) {
5046 mk_pointer(&vtop->type);
5047 indir(); /* -> parent frame */
5049 if (tok1 == TOK_builtin_return_address) {
5050 // assume return address is just above frame pointer on stack
5051 vpushi(PTR_SIZE);
5052 gen_op('+');
5053 mk_pointer(&vtop->type);
5054 indir();
5057 break;
5058 #ifdef TCC_TARGET_X86_64
5059 #ifdef TCC_TARGET_PE
5060 case TOK_builtin_va_start:
5061 parse_builtin_params(0, "ee");
5062 r = vtop->r & VT_VALMASK;
5063 if (r == VT_LLOCAL)
5064 r = VT_LOCAL;
5065 if (r != VT_LOCAL)
5066 tcc_error("__builtin_va_start expects a local variable");
5067 vtop->r = r;
5068 vtop->type = char_pointer_type;
5069 vtop->c.i += 8;
5070 vstore();
5071 break;
5072 #else
5073 case TOK_builtin_va_arg_types:
5074 parse_builtin_params(0, "t");
5075 vpushi(classify_x86_64_va_arg(&vtop->type));
5076 vswap();
5077 vpop();
5078 break;
5079 #endif
5080 #endif
5082 #ifdef TCC_TARGET_ARM64
5083 case TOK___va_start: {
5084 parse_builtin_params(0, "ee");
5085 //xx check types
5086 gen_va_start();
5087 vpushi(0);
5088 vtop->type.t = VT_VOID;
5089 break;
5091 case TOK___va_arg: {
5092 parse_builtin_params(0, "et");
5093 type = vtop->type;
5094 vpop();
5095 //xx check types
5096 gen_va_arg(&type);
5097 vtop->type = type;
5098 break;
5100 case TOK___arm64_clear_cache: {
5101 parse_builtin_params(0, "ee");
5102 gen_clear_cache();
5103 vpushi(0);
5104 vtop->type.t = VT_VOID;
5105 break;
5107 #endif
5108 /* pre operations */
5109 case TOK_INC:
5110 case TOK_DEC:
5111 t = tok;
5112 next();
5113 unary();
5114 inc(0, t);
5115 break;
5116 case '-':
5117 next();
5118 unary();
5119 t = vtop->type.t & VT_BTYPE;
5120 if (is_float(t)) {
5121 /* In IEEE negate(x) isn't subtract(0,x), but rather
5122 subtract(-0, x). */
5123 vpush(&vtop->type);
5124 if (t == VT_FLOAT)
5125 vtop->c.f = -1.0 * 0.0;
5126 else if (t == VT_DOUBLE)
5127 vtop->c.d = -1.0 * 0.0;
5128 else
5129 vtop->c.ld = -1.0 * 0.0;
5130 } else
5131 vpushi(0);
5132 vswap();
5133 gen_op('-');
5134 break;
5135 case TOK_LAND:
5136 if (!gnu_ext)
5137 goto tok_identifier;
5138 next();
5139 /* allow to take the address of a label */
5140 if (tok < TOK_UIDENT)
5141 expect("label identifier");
5142 s = label_find(tok);
5143 if (!s) {
5144 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5145 } else {
5146 if (s->r == LABEL_DECLARED)
5147 s->r = LABEL_FORWARD;
5149 if (!s->type.t) {
5150 s->type.t = VT_VOID;
5151 mk_pointer(&s->type);
5152 s->type.t |= VT_STATIC;
5154 vpushsym(&s->type, s);
5155 next();
5156 break;
5158 case TOK_GENERIC:
5160 CType controlling_type;
5161 int has_default = 0;
5162 int has_match = 0;
5163 int learn = 0;
5164 TokenString *str = NULL;
5165 int saved_const_wanted = const_wanted;
5167 next();
5168 skip('(');
5169 const_wanted = 0;
5170 expr_type(&controlling_type, expr_eq);
5171 controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
5172 if ((controlling_type.t & VT_BTYPE) == VT_FUNC)
5173 mk_pointer(&controlling_type);
5174 const_wanted = saved_const_wanted;
5175 for (;;) {
5176 learn = 0;
5177 skip(',');
5178 if (tok == TOK_DEFAULT) {
5179 if (has_default)
5180 tcc_error("too many 'default'");
5181 has_default = 1;
5182 if (!has_match)
5183 learn = 1;
5184 next();
5185 } else {
5186 AttributeDef ad_tmp;
5187 int itmp;
5188 CType cur_type;
5189 parse_btype(&cur_type, &ad_tmp);
5190 type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
5191 if (compare_types(&controlling_type, &cur_type, 0)) {
5192 if (has_match) {
5193 tcc_error("type match twice");
5195 has_match = 1;
5196 learn = 1;
5199 skip(':');
5200 if (learn) {
5201 if (str)
5202 tok_str_free(str);
5203 skip_or_save_block(&str);
5204 } else {
5205 skip_or_save_block(NULL);
5207 if (tok == ')')
5208 break;
5210 if (!str) {
5211 char buf[60];
5212 type_to_str(buf, sizeof buf, &controlling_type, NULL);
5213 tcc_error("type '%s' does not match any association", buf);
5215 begin_macro(str, 1);
5216 next();
5217 expr_eq();
5218 if (tok != TOK_EOF)
5219 expect(",");
5220 end_macro();
5221 next();
5222 break;
5224 // special qnan , snan and infinity values
5225 case TOK___NAN__:
5226 n = 0x7fc00000;
5227 special_math_val:
5228 vpushi(n);
5229 vtop->type.t = VT_FLOAT;
5230 next();
5231 break;
5232 case TOK___SNAN__:
5233 n = 0x7f800001;
5234 goto special_math_val;
5235 case TOK___INF__:
5236 n = 0x7f800000;
5237 goto special_math_val;
5239 default:
5240 tok_identifier:
5241 t = tok;
5242 next();
5243 if (t < TOK_UIDENT)
5244 expect("identifier");
5245 s = sym_find(t);
5246 if (!s || IS_ASM_SYM(s)) {
5247 const char *name = get_tok_str(t, NULL);
5248 if (tok != '(')
5249 tcc_error("'%s' undeclared", name);
5250 /* for simple function calls, we tolerate undeclared
5251 external reference to int() function */
5252 if (tcc_state->warn_implicit_function_declaration
5253 #ifdef TCC_TARGET_PE
5254 /* people must be warned about using undeclared WINAPI functions
5255 (which usually start with uppercase letter) */
5256 || (name[0] >= 'A' && name[0] <= 'Z')
5257 #endif
5259 tcc_warning("implicit declaration of function '%s'", name);
5260 s = external_global_sym(t, &func_old_type);
5263 r = s->r;
5264 /* A symbol that has a register is a local register variable,
5265 which starts out as VT_LOCAL value. */
5266 if ((r & VT_VALMASK) < VT_CONST)
5267 r = (r & ~VT_VALMASK) | VT_LOCAL;
5269 vset(&s->type, r, s->c);
5270 /* Point to s as backpointer (even without r&VT_SYM).
5271 Will be used by at least the x86 inline asm parser for
5272 regvars. */
5273 vtop->sym = s;
5275 if (r & VT_SYM) {
5276 vtop->c.i = 0;
5277 } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
5278 vtop->c.i = s->enum_val;
5280 break;
5283 /* post operations */
5284 while (1) {
5285 if (tok == TOK_INC || tok == TOK_DEC) {
5286 inc(1, tok);
5287 next();
5288 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
5289 int qualifiers, cumofs = 0;
5290 /* field */
5291 if (tok == TOK_ARROW)
5292 indir();
5293 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
5294 test_lvalue();
5295 gaddrof();
5296 /* expect pointer on structure */
5297 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
5298 expect("struct or union");
5299 if (tok == TOK_CDOUBLE)
5300 expect("field name");
5301 next();
5302 if (tok == TOK_CINT || tok == TOK_CUINT)
5303 expect("field name");
5304 s = find_field(&vtop->type, tok, &cumofs);
5305 if (!s)
5306 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
5307 /* add field offset to pointer */
5308 vtop->type = char_pointer_type; /* change type to 'char *' */
5309 vpushi(cumofs + s->c);
5310 gen_op('+');
5311 /* change type to field type, and set to lvalue */
5312 vtop->type = s->type;
5313 vtop->type.t |= qualifiers;
5314 /* an array is never an lvalue */
5315 if (!(vtop->type.t & VT_ARRAY)) {
5316 vtop->r |= lvalue_type(vtop->type.t);
5317 #ifdef CONFIG_TCC_BCHECK
5318 /* if bound checking, the referenced pointer must be checked */
5319 if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL)
5320 vtop->r |= VT_MUSTBOUND;
5321 #endif
5323 next();
5324 } else if (tok == '[') {
5325 next();
5326 gexpr();
5327 gen_op('+');
5328 indir();
5329 skip(']');
5330 } else if (tok == '(') {
5331 SValue ret;
5332 Sym *sa;
5333 int nb_args, ret_nregs, ret_align, regsize, variadic;
5335 /* function call */
5336 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
5337 /* pointer test (no array accepted) */
5338 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5339 vtop->type = *pointed_type(&vtop->type);
5340 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
5341 goto error_func;
5342 } else {
5343 error_func:
5344 expect("function pointer");
5346 } else {
5347 vtop->r &= ~VT_LVAL; /* no lvalue */
5349 /* get return type */
5350 s = vtop->type.ref;
5351 next();
5352 sa = s->next; /* first parameter */
5353 nb_args = regsize = 0;
5354 ret.r2 = VT_CONST;
5355 /* compute first implicit argument if a structure is returned */
5356 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
5357 variadic = (s->f.func_type == FUNC_ELLIPSIS);
5358 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
5359 &ret_align, &regsize);
5360 if (!ret_nregs) {
5361 /* get some space for the returned structure */
5362 size = type_size(&s->type, &align);
5363 #ifdef TCC_TARGET_ARM64
5364 /* On arm64, a small struct is return in registers.
5365 It is much easier to write it to memory if we know
5366 that we are allowed to write some extra bytes, so
5367 round the allocated space up to a power of 2: */
5368 if (size < 16)
5369 while (size & (size - 1))
5370 size = (size | (size - 1)) + 1;
5371 #endif
5372 loc = (loc - size) & -align;
5373 ret.type = s->type;
5374 ret.r = VT_LOCAL | VT_LVAL;
5375 /* pass it as 'int' to avoid structure arg passing
5376 problems */
5377 vseti(VT_LOCAL, loc);
5378 ret.c = vtop->c;
5379 nb_args++;
5381 } else {
5382 ret_nregs = 1;
5383 ret.type = s->type;
5386 if (ret_nregs) {
5387 /* return in register */
5388 if (is_float(ret.type.t)) {
5389 ret.r = reg_fret(ret.type.t);
5390 #ifdef TCC_TARGET_X86_64
5391 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
5392 ret.r2 = REG_QRET;
5393 #endif
5394 } else {
5395 #ifndef TCC_TARGET_ARM64
5396 #ifdef TCC_TARGET_X86_64
5397 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
5398 #else
5399 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
5400 #endif
5401 ret.r2 = REG_LRET;
5402 #endif
5403 ret.r = REG_IRET;
5405 ret.c.i = 0;
5407 if (tok != ')') {
5408 for(;;) {
5409 expr_eq();
5410 gfunc_param_typed(s, sa);
5411 nb_args++;
5412 if (sa)
5413 sa = sa->next;
5414 if (tok == ')')
5415 break;
5416 skip(',');
5419 if (sa)
5420 tcc_error("too few arguments to function");
5421 skip(')');
5422 gfunc_call(nb_args);
5424 /* return value */
5425 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
5426 vsetc(&ret.type, r, &ret.c);
5427 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
5430 /* handle packed struct return */
5431 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
5432 int addr, offset;
5434 size = type_size(&s->type, &align);
5435 /* We're writing whole regs often, make sure there's enough
5436 space. Assume register size is power of 2. */
5437 if (regsize > align)
5438 align = regsize;
5439 loc = (loc - size) & -align;
5440 addr = loc;
5441 offset = 0;
5442 for (;;) {
5443 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
5444 vswap();
5445 vstore();
5446 vtop--;
5447 if (--ret_nregs == 0)
5448 break;
5449 offset += regsize;
5451 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
5453 } else {
5454 break;
5459 ST_FUNC void expr_prod(void)
5461 int t;
5463 unary();
5464 while (tok == '*' || tok == '/' || tok == '%') {
5465 t = tok;
5466 next();
5467 unary();
5468 gen_op(t);
5472 ST_FUNC void expr_sum(void)
5474 int t;
5476 expr_prod();
5477 while (tok == '+' || tok == '-') {
5478 t = tok;
5479 next();
5480 expr_prod();
5481 gen_op(t);
5485 static void expr_shift(void)
5487 int t;
5489 expr_sum();
5490 while (tok == TOK_SHL || tok == TOK_SAR) {
5491 t = tok;
5492 next();
5493 expr_sum();
5494 gen_op(t);
5498 static void expr_cmp(void)
5500 int t;
5502 expr_shift();
5503 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
5504 tok == TOK_ULT || tok == TOK_UGE) {
5505 t = tok;
5506 next();
5507 expr_shift();
5508 gen_op(t);
5512 static void expr_cmpeq(void)
5514 int t;
5516 expr_cmp();
5517 while (tok == TOK_EQ || tok == TOK_NE) {
5518 t = tok;
5519 next();
5520 expr_cmp();
5521 gen_op(t);
5525 static void expr_and(void)
5527 expr_cmpeq();
5528 while (tok == '&') {
5529 next();
5530 expr_cmpeq();
5531 gen_op('&');
5535 static void expr_xor(void)
5537 expr_and();
5538 while (tok == '^') {
5539 next();
5540 expr_and();
5541 gen_op('^');
5545 static void expr_or(void)
5547 expr_xor();
5548 while (tok == '|') {
5549 next();
5550 expr_xor();
5551 gen_op('|');
5555 static void expr_land(void)
5557 expr_or();
5558 if (tok == TOK_LAND) {
5559 int t = 0;
5560 for(;;) {
5561 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
5562 gen_cast_s(VT_BOOL);
5563 if (vtop->c.i) {
5564 vpop();
5565 } else {
5566 nocode_wanted++;
5567 while (tok == TOK_LAND) {
5568 next();
5569 expr_or();
5570 vpop();
5572 nocode_wanted--;
5573 if (t)
5574 gsym(t);
5575 gen_cast_s(VT_INT);
5576 break;
5578 } else {
5579 if (!t)
5580 save_regs(1);
5581 t = gvtst(1, t);
5583 if (tok != TOK_LAND) {
5584 if (t)
5585 vseti(VT_JMPI, t);
5586 else
5587 vpushi(1);
5588 break;
5590 next();
5591 expr_or();
5596 static void expr_lor(void)
5598 expr_land();
5599 if (tok == TOK_LOR) {
5600 int t = 0;
5601 for(;;) {
5602 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
5603 gen_cast_s(VT_BOOL);
5604 if (!vtop->c.i) {
5605 vpop();
5606 } else {
5607 nocode_wanted++;
5608 while (tok == TOK_LOR) {
5609 next();
5610 expr_land();
5611 vpop();
5613 nocode_wanted--;
5614 if (t)
5615 gsym(t);
5616 gen_cast_s(VT_INT);
5617 break;
5619 } else {
5620 if (!t)
5621 save_regs(1);
5622 t = gvtst(0, t);
5624 if (tok != TOK_LOR) {
5625 if (t)
5626 vseti(VT_JMP, t);
5627 else
5628 vpushi(0);
5629 break;
5631 next();
5632 expr_land();
5637 /* Assuming vtop is a value used in a conditional context
5638 (i.e. compared with zero) return 0 if it's false, 1 if
5639 true and -1 if it can't be statically determined. */
5640 static int condition_3way(void)
5642 int c = -1;
5643 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
5644 (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
5645 vdup();
5646 gen_cast_s(VT_BOOL);
5647 c = vtop->c.i;
5648 vpop();
5650 return c;
5653 static void expr_cond(void)
5655 int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g;
5656 SValue sv;
5657 CType type, type1, type2;
5659 expr_lor();
5660 if (tok == '?') {
5661 next();
5662 c = condition_3way();
5663 g = (tok == ':' && gnu_ext);
5664 if (c < 0) {
5665 /* needed to avoid having different registers saved in
5666 each branch */
5667 if (is_float(vtop->type.t)) {
5668 rc = RC_FLOAT;
5669 #ifdef TCC_TARGET_X86_64
5670 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
5671 rc = RC_ST0;
5673 #endif
5674 } else
5675 rc = RC_INT;
5676 gv(rc);
5677 save_regs(1);
5678 if (g)
5679 gv_dup();
5680 tt = gvtst(1, 0);
5682 } else {
5683 if (!g)
5684 vpop();
5685 tt = 0;
5688 if (1) {
5689 if (c == 0)
5690 nocode_wanted++;
5691 if (!g)
5692 gexpr();
5694 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
5695 mk_pointer(&vtop->type);
5696 type1 = vtop->type;
5697 sv = *vtop; /* save value to handle it later */
5698 vtop--; /* no vpop so that FP stack is not flushed */
5699 skip(':');
5701 u = 0;
5702 if (c < 0)
5703 u = gjmp(0);
5704 gsym(tt);
5706 if (c == 0)
5707 nocode_wanted--;
5708 if (c == 1)
5709 nocode_wanted++;
5710 expr_cond();
5711 if (c == 1)
5712 nocode_wanted--;
5714 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
5715 mk_pointer(&vtop->type);
5716 type2=vtop->type;
5717 t1 = type1.t;
5718 bt1 = t1 & VT_BTYPE;
5719 t2 = type2.t;
5720 bt2 = t2 & VT_BTYPE;
5721 type.ref = NULL;
5724 /* cast operands to correct type according to ISOC rules */
5725 if (bt1 == VT_VOID || bt2 == VT_VOID) {
5726 type.t = VT_VOID; /* NOTE: as an extension, we accept void on only one side */
5727 } else if (is_float(bt1) || is_float(bt2)) {
5728 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5729 type.t = VT_LDOUBLE;
5731 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5732 type.t = VT_DOUBLE;
5733 } else {
5734 type.t = VT_FLOAT;
5736 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5737 /* cast to biggest op */
5738 type.t = VT_LLONG | VT_LONG;
5739 if (bt1 == VT_LLONG)
5740 type.t &= t1;
5741 if (bt2 == VT_LLONG)
5742 type.t &= t2;
5743 /* convert to unsigned if it does not fit in a long long */
5744 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
5745 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
5746 type.t |= VT_UNSIGNED;
5747 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
5748 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
5749 /* If one is a null ptr constant the result type
5750 is the other. */
5751 if (is_null_pointer (vtop)) type = type1;
5752 else if (is_null_pointer (&sv)) type = type2;
5753 else if (bt1 != bt2)
5754 tcc_error("incompatible types in conditional expressions");
5755 else {
5756 CType *pt1 = pointed_type(&type1);
5757 CType *pt2 = pointed_type(&type2);
5758 int pbt1 = pt1->t & VT_BTYPE;
5759 int pbt2 = pt2->t & VT_BTYPE;
5760 int newquals, copied = 0;
5761 /* pointers to void get preferred, otherwise the
5762 pointed to types minus qualifs should be compatible */
5763 type = (pbt1 == VT_VOID) ? type1 : type2;
5764 if (pbt1 != VT_VOID && pbt2 != VT_VOID) {
5765 if(!compare_types(pt1, pt2, 1/*unqualif*/))
5766 tcc_warning("pointer type mismatch in conditional expression\n");
5768 /* combine qualifs */
5769 newquals = ((pt1->t | pt2->t) & (VT_CONSTANT | VT_VOLATILE));
5770 if ((~pointed_type(&type)->t & (VT_CONSTANT | VT_VOLATILE))
5771 & newquals)
5773 /* copy the pointer target symbol */
5774 type.ref = sym_push(SYM_FIELD, &type.ref->type,
5775 0, type.ref->c);
5776 copied = 1;
5777 pointed_type(&type)->t |= newquals;
5779 /* pointers to incomplete arrays get converted to
5780 pointers to completed ones if possible */
5781 if (pt1->t & VT_ARRAY
5782 && pt2->t & VT_ARRAY
5783 && pointed_type(&type)->ref->c < 0
5784 && (pt1->ref->c > 0 || pt2->ref->c > 0))
5786 if (!copied)
5787 type.ref = sym_push(SYM_FIELD, &type.ref->type,
5788 0, type.ref->c);
5789 pointed_type(&type)->ref =
5790 sym_push(SYM_FIELD, &pointed_type(&type)->ref->type,
5791 0, pointed_type(&type)->ref->c);
5792 pointed_type(&type)->ref->c =
5793 0 < pt1->ref->c ? pt1->ref->c : pt2->ref->c;
5796 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5797 /* XXX: test structure compatibility */
5798 type = bt1 == VT_STRUCT ? type1 : type2;
5799 } else {
5800 /* integer operations */
5801 type.t = VT_INT | (VT_LONG & (t1 | t2));
5802 /* convert to unsigned if it does not fit in an integer */
5803 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
5804 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
5805 type.t |= VT_UNSIGNED;
5807 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
5808 that `(expr ? a : b).mem` does not error with "lvalue expected" */
5809 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
5811 /* now we convert second operand */
5812 if (c != 1) {
5813 gen_cast(&type);
5814 if (islv) {
5815 mk_pointer(&vtop->type);
5816 gaddrof();
5817 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
5818 gaddrof();
5821 rc = RC_INT;
5822 if (is_float(type.t)) {
5823 rc = RC_FLOAT;
5824 #ifdef TCC_TARGET_X86_64
5825 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
5826 rc = RC_ST0;
5828 #endif
5829 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
5830 /* for long longs, we use fixed registers to avoid having
5831 to handle a complicated move */
5832 rc = RC_IRET;
5835 tt = r2 = 0;
5836 if (c < 0) {
5837 r2 = gv(rc);
5838 tt = gjmp(0);
5840 gsym(u);
5842 /* this is horrible, but we must also convert first
5843 operand */
5844 if (c != 0) {
5845 *vtop = sv;
5846 gen_cast(&type);
5847 if (islv) {
5848 mk_pointer(&vtop->type);
5849 gaddrof();
5850 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
5851 gaddrof();
5854 if (c < 0 || islv) {
5855 r1 = gv(rc);
5856 move_reg(r2, r1, type.t);
5857 vtop->r = r2;
5858 gsym(tt);
5859 if (islv)
5860 indir();
5866 static void expr_eq(void)
5868 int t;
5870 expr_cond();
5871 if (tok == '=' ||
5872 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5873 tok == TOK_A_XOR || tok == TOK_A_OR ||
5874 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5875 test_lvalue();
5876 t = tok;
5877 next();
5878 if (t == '=') {
5879 expr_eq();
5880 } else {
5881 vdup();
5882 expr_eq();
5883 gen_op(t & 0x7f);
5885 vstore();
5889 ST_FUNC void gexpr(void)
5891 while (1) {
5892 expr_eq();
5893 if (tok != ',')
5894 break;
5895 vpop();
5896 next();
5900 /* parse a constant expression and return value in vtop. */
5901 static void expr_const1(void)
5903 const_wanted++;
5904 nocode_wanted++;
5905 expr_cond();
5906 nocode_wanted--;
5907 const_wanted--;
5910 /* parse an integer constant and return its value. */
5911 static inline int64_t expr_const64(void)
5913 int64_t c;
5914 expr_const1();
5915 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5916 expect("constant expression");
5917 c = vtop->c.i;
5918 vpop();
5919 return c;
5922 /* parse an integer constant and return its value.
5923 Complain if it doesn't fit 32bit (signed or unsigned). */
5924 ST_FUNC int expr_const(void)
5926 int c;
5927 int64_t wc = expr_const64();
5928 c = wc;
5929 if (c != wc && (unsigned)c != wc)
5930 tcc_error("constant exceeds 32 bit");
5931 return c;
5934 /* return the label token if current token is a label, otherwise
5935 return zero */
5936 static int is_label(void)
5938 int last_tok;
5940 /* fast test first */
5941 if (tok < TOK_UIDENT)
5942 return 0;
5943 /* no need to save tokc because tok is an identifier */
5944 last_tok = tok;
5945 next();
5946 if (tok == ':') {
5947 return last_tok;
5948 } else {
5949 unget_tok(last_tok);
5950 return 0;
5954 #ifndef TCC_TARGET_ARM64
5955 static void gfunc_return(CType *func_type)
5957 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
5958 CType type, ret_type;
5959 int ret_align, ret_nregs, regsize;
5960 ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
5961 &ret_align, &regsize);
5962 if (0 == ret_nregs) {
5963 /* if returning structure, must copy it to implicit
5964 first pointer arg location */
5965 type = *func_type;
5966 mk_pointer(&type);
5967 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
5968 indir();
5969 vswap();
5970 /* copy structure value to pointer */
5971 vstore();
5972 } else {
5973 /* returning structure packed into registers */
5974 int r, size, addr, align;
5975 size = type_size(func_type,&align);
5976 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
5977 (vtop->c.i & (ret_align-1)))
5978 && (align & (ret_align-1))) {
5979 loc = (loc - size) & -ret_align;
5980 addr = loc;
5981 type = *func_type;
5982 vset(&type, VT_LOCAL | VT_LVAL, addr);
5983 vswap();
5984 vstore();
5985 vpop();
5986 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
5988 vtop->type = ret_type;
5989 if (is_float(ret_type.t))
5990 r = rc_fret(ret_type.t);
5991 else
5992 r = RC_IRET;
5994 if (ret_nregs == 1)
5995 gv(r);
5996 else {
5997 for (;;) {
5998 vdup();
5999 gv(r);
6000 vpop();
6001 if (--ret_nregs == 0)
6002 break;
6003 /* We assume that when a structure is returned in multiple
6004 registers, their classes are consecutive values of the
6005 suite s(n) = 2^n */
6006 r <<= 1;
6007 vtop->c.i += regsize;
6011 } else if (is_float(func_type->t)) {
6012 gv(rc_fret(func_type->t));
6013 } else {
6014 gv(RC_IRET);
6016 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6018 #endif
6020 static int case_cmp(const void *pa, const void *pb)
6022 int64_t a = (*(struct case_t**) pa)->v1;
6023 int64_t b = (*(struct case_t**) pb)->v1;
6024 return a < b ? -1 : a > b;
6027 static void gcase(struct case_t **base, int len, int *bsym)
6029 struct case_t *p;
6030 int e;
6031 int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
6032 gv(RC_INT);
6033 while (len > 4) {
6034 /* binary search */
6035 p = base[len/2];
6036 vdup();
6037 if (ll)
6038 vpushll(p->v2);
6039 else
6040 vpushi(p->v2);
6041 gen_op(TOK_LE);
6042 e = gtst(1, 0);
6043 vdup();
6044 if (ll)
6045 vpushll(p->v1);
6046 else
6047 vpushi(p->v1);
6048 gen_op(TOK_GE);
6049 gtst_addr(0, p->sym); /* v1 <= x <= v2 */
6050 /* x < v1 */
6051 gcase(base, len/2, bsym);
6052 if (cur_switch->def_sym)
6053 gjmp_addr(cur_switch->def_sym);
6054 else
6055 *bsym = gjmp(*bsym);
6056 /* x > v2 */
6057 gsym(e);
6058 e = len/2 + 1;
6059 base += e; len -= e;
6061 /* linear scan */
6062 while (len--) {
6063 p = *base++;
6064 vdup();
6065 if (ll)
6066 vpushll(p->v2);
6067 else
6068 vpushi(p->v2);
6069 if (p->v1 == p->v2) {
6070 gen_op(TOK_EQ);
6071 gtst_addr(0, p->sym);
6072 } else {
6073 gen_op(TOK_LE);
6074 e = gtst(1, 0);
6075 vdup();
6076 if (ll)
6077 vpushll(p->v1);
6078 else
6079 vpushi(p->v1);
6080 gen_op(TOK_GE);
6081 gtst_addr(0, p->sym);
6082 gsym(e);
6087 static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr)
6089 int a, b, c, d, cond;
6090 Sym *s;
6092 /* generate line number info */
6093 if (tcc_state->do_debug)
6094 tcc_debug_line(tcc_state);
6096 if (is_expr) {
6097 /* default return value is (void) */
6098 vpushi(0);
6099 vtop->type.t = VT_VOID;
6102 if (tok == TOK_IF) {
6103 /* if test */
6104 int saved_nocode_wanted = nocode_wanted;
6105 next();
6106 skip('(');
6107 gexpr();
6108 skip(')');
6109 cond = condition_3way();
6110 if (cond == 1)
6111 a = 0, vpop();
6112 else
6113 a = gvtst(1, 0);
6114 if (cond == 0)
6115 nocode_wanted |= 0x20000000;
6116 block(bsym, bcl, csym, ccl, 0);
6117 if (cond != 1)
6118 nocode_wanted = saved_nocode_wanted;
6119 if (tok == TOK_ELSE) {
6120 next();
6121 d = gjmp(0);
6122 gsym(a);
6123 if (cond == 1)
6124 nocode_wanted |= 0x20000000;
6125 block(bsym, bcl, csym, ccl, 0);
6126 gsym(d); /* patch else jmp */
6127 if (cond != 0)
6128 nocode_wanted = saved_nocode_wanted;
6129 } else
6130 gsym(a);
6131 } else if (tok == TOK_WHILE) {
6132 int saved_nocode_wanted;
6133 nocode_wanted &= ~0x20000000;
6134 next();
6135 d = ind;
6136 vla_sp_restore();
6137 skip('(');
6138 gexpr();
6139 skip(')');
6140 a = gvtst(1, 0);
6141 b = 0;
6142 ++local_scope;
6143 saved_nocode_wanted = nocode_wanted;
6144 block(&a, current_cleanups, &b, current_cleanups, 0);
6145 nocode_wanted = saved_nocode_wanted;
6146 --local_scope;
6147 gjmp_addr(d);
6148 gsym(a);
6149 gsym_addr(b, d);
6150 } else if (tok == '{') {
6151 Sym *llabel, *lcleanup;
6152 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
6153 int lncleanups = ncleanups;
6155 next();
6156 /* record local declaration stack position */
6157 s = local_stack;
6158 llabel = local_label_stack;
6159 lcleanup = current_cleanups;
6160 ++local_scope;
6162 /* handle local labels declarations */
6163 while (tok == TOK_LABEL) {
6164 next();
6165 for(;;) {
6166 if (tok < TOK_UIDENT)
6167 expect("label identifier");
6168 label_push(&local_label_stack, tok, LABEL_DECLARED);
6169 next();
6170 if (tok == ',') {
6171 next();
6172 } else {
6173 skip(';');
6174 break;
6178 while (tok != '}') {
6179 if ((a = is_label()))
6180 unget_tok(a);
6181 else
6182 decl(VT_LOCAL);
6183 if (tok != '}') {
6184 if (is_expr)
6185 vpop();
6186 block(bsym, bcl, csym, ccl, is_expr);
6190 if (current_cleanups != lcleanup) {
6191 int jmp = 0;
6192 Sym *g, **pg;
6194 for (pg = &pending_gotos; (g = *pg) && g->c > lncleanups;)
6195 if (g->prev_tok->r & LABEL_FORWARD) {
6196 Sym *pcl = g->next;
6197 if (!jmp)
6198 jmp = gjmp(0);
6199 gsym(pcl->jnext);
6200 try_call_scope_cleanup(lcleanup);
6201 pcl->jnext = gjmp(0);
6202 if (!lncleanups)
6203 goto remove_pending;
6204 g->c = lncleanups;
6205 pg = &g->prev;
6206 } else {
6207 remove_pending:
6208 *pg = g->prev;
6209 sym_free(g);
6211 gsym(jmp);
6212 if (!nocode_wanted) {
6213 try_call_scope_cleanup(lcleanup);
6217 current_cleanups = lcleanup;
6218 ncleanups = lncleanups;
6219 /* pop locally defined labels */
6220 label_pop(&local_label_stack, llabel, is_expr);
6221 /* pop locally defined symbols */
6222 --local_scope;
6223 /* In the is_expr case (a statement expression is finished here),
6224 vtop might refer to symbols on the local_stack. Either via the
6225 type or via vtop->sym. We can't pop those nor any that in turn
6226 might be referred to. To make it easier we don't roll back
6227 any symbols in that case; some upper level call to block() will
6228 do that. We do have to remove such symbols from the lookup
6229 tables, though. sym_pop will do that. */
6230 sym_pop(&local_stack, s, is_expr);
6232 /* Pop VLA frames and restore stack pointer if required */
6233 if (vlas_in_scope > saved_vlas_in_scope) {
6234 vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
6235 vla_sp_restore();
6237 vlas_in_scope = saved_vlas_in_scope;
6239 next();
6240 } else if (tok == TOK_RETURN) {
6241 next();
6242 if (tok != ';') {
6243 gexpr();
6244 gen_assign_cast(&func_vt);
6245 try_call_scope_cleanup(NULL);
6246 if ((func_vt.t & VT_BTYPE) == VT_VOID)
6247 vtop--;
6248 else
6249 gfunc_return(&func_vt);
6250 } else {
6251 try_call_scope_cleanup(NULL);
6253 skip(';');
6254 /* jump unless last stmt in top-level block */
6255 if (tok != '}' || local_scope != 1)
6256 rsym = gjmp(rsym);
6257 nocode_wanted |= 0x20000000;
6258 } else if (tok == TOK_BREAK) {
6259 /* compute jump */
6260 if (!bsym)
6261 tcc_error("cannot break");
6262 try_call_scope_cleanup(bcl);
6263 *bsym = gjmp(*bsym);
6264 next();
6265 skip(';');
6266 nocode_wanted |= 0x20000000;
6267 } else if (tok == TOK_CONTINUE) {
6268 /* compute jump */
6269 if (!csym)
6270 tcc_error("cannot continue");
6271 try_call_scope_cleanup(ccl);
6272 vla_sp_restore_root();
6273 *csym = gjmp(*csym);
6274 next();
6275 skip(';');
6276 nocode_wanted |= 0x20000000;
6277 } else if (tok == TOK_FOR) {
6278 int e;
6279 int saved_nocode_wanted;
6280 Sym *lcleanup = current_cleanups;
6281 int lncleanups = ncleanups;
6283 nocode_wanted &= ~0x20000000;
6284 next();
6285 skip('(');
6286 s = local_stack;
6287 ++local_scope;
6288 if (tok != ';') {
6289 /* c99 for-loop init decl? */
6290 if (!decl0(VT_LOCAL, 1, NULL)) {
6291 /* no, regular for-loop init expr */
6292 gexpr();
6293 vpop();
6296 skip(';');
6297 d = ind;
6298 c = ind;
6299 vla_sp_restore();
6300 a = 0;
6301 b = 0;
6302 if (tok != ';') {
6303 gexpr();
6304 a = gvtst(1, 0);
6306 skip(';');
6307 if (tok != ')') {
6308 e = gjmp(0);
6309 c = ind;
6310 vla_sp_restore();
6311 gexpr();
6312 vpop();
6313 gjmp_addr(d);
6314 gsym(e);
6316 skip(')');
6317 saved_nocode_wanted = nocode_wanted;
6318 block(&a, current_cleanups, &b, current_cleanups, 0);
6319 nocode_wanted = saved_nocode_wanted;
6320 gjmp_addr(c);
6321 gsym(a);
6322 gsym_addr(b, c);
6323 --local_scope;
6324 try_call_scope_cleanup(lcleanup);
6325 ncleanups = lncleanups;
6326 current_cleanups = lcleanup;
6327 sym_pop(&local_stack, s, 0);
6329 } else
6330 if (tok == TOK_DO) {
6331 int saved_nocode_wanted;
6332 nocode_wanted &= ~0x20000000;
6333 next();
6334 a = 0;
6335 b = 0;
6336 d = ind;
6337 vla_sp_restore();
6338 saved_nocode_wanted = nocode_wanted;
6339 block(&a, current_cleanups, &b, current_cleanups, 0);
6340 skip(TOK_WHILE);
6341 skip('(');
6342 gsym(b);
6343 if (b)
6344 nocode_wanted = saved_nocode_wanted;
6345 gexpr();
6346 c = gvtst(0, 0);
6347 gsym_addr(c, d);
6348 nocode_wanted = saved_nocode_wanted;
6349 skip(')');
6350 gsym(a);
6351 skip(';');
6352 } else
6353 if (tok == TOK_SWITCH) {
6354 struct switch_t *saved, sw;
6355 int saved_nocode_wanted = nocode_wanted;
6356 SValue switchval;
6357 next();
6358 skip('(');
6359 gexpr();
6360 skip(')');
6361 switchval = *vtop--;
6362 a = 0;
6363 b = gjmp(0); /* jump to first case */
6364 sw.p = NULL; sw.n = 0; sw.def_sym = 0;
6365 saved = cur_switch;
6366 cur_switch = &sw;
6367 block(&a, current_cleanups, csym, ccl, 0);
6368 nocode_wanted = saved_nocode_wanted;
6369 a = gjmp(a); /* add implicit break */
6370 /* case lookup */
6371 gsym(b);
6372 qsort(sw.p, sw.n, sizeof(void*), case_cmp);
6373 for (b = 1; b < sw.n; b++)
6374 if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
6375 tcc_error("duplicate case value");
6376 /* Our switch table sorting is signed, so the compared
6377 value needs to be as well when it's 64bit. */
6378 if ((switchval.type.t & VT_BTYPE) == VT_LLONG)
6379 switchval.type.t &= ~VT_UNSIGNED;
6380 vpushv(&switchval);
6381 gcase(sw.p, sw.n, &a);
6382 vpop();
6383 if (sw.def_sym)
6384 gjmp_addr(sw.def_sym);
6385 dynarray_reset(&sw.p, &sw.n);
6386 cur_switch = saved;
6387 /* break label */
6388 gsym(a);
6389 } else
6390 if (tok == TOK_CASE) {
6391 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
6392 if (!cur_switch)
6393 expect("switch");
6394 nocode_wanted &= ~0x20000000;
6395 next();
6396 cr->v1 = cr->v2 = expr_const64();
6397 if (gnu_ext && tok == TOK_DOTS) {
6398 next();
6399 cr->v2 = expr_const64();
6400 if (cr->v2 < cr->v1)
6401 tcc_warning("empty case range");
6403 cr->sym = ind;
6404 dynarray_add(&cur_switch->p, &cur_switch->n, cr);
6405 skip(':');
6406 is_expr = 0;
6407 goto block_after_label;
6408 } else
6409 if (tok == TOK_DEFAULT) {
6410 next();
6411 skip(':');
6412 if (!cur_switch)
6413 expect("switch");
6414 if (cur_switch->def_sym)
6415 tcc_error("too many 'default'");
6416 cur_switch->def_sym = ind;
6417 is_expr = 0;
6418 goto block_after_label;
6419 } else
6420 if (tok == TOK_GOTO) {
6421 next();
6422 if (tok == '*' && gnu_ext) {
6423 /* computed goto */
6424 next();
6425 gexpr();
6426 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6427 expect("pointer");
6428 ggoto();
6429 } else if (tok >= TOK_UIDENT) {
6430 s = label_find(tok);
6431 /* put forward definition if needed */
6432 if (!s)
6433 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
6434 else if (s->r == LABEL_DECLARED)
6435 s->r = LABEL_FORWARD;
6437 vla_sp_restore_root();
6438 if (s->r & LABEL_FORWARD) {
6439 /* start new goto chain for cleanups, linked via label->next */
6440 if (current_cleanups) {
6441 sym_push2(&pending_gotos, SYM_FIELD, 0, ncleanups);
6442 pending_gotos->prev_tok = s;
6443 s = sym_push2(&s->next, SYM_FIELD, 0, 0);
6444 pending_gotos->next = s;
6446 s->jnext = gjmp(s->jnext);
6447 } else {
6448 try_call_cleanup_goto(s->cleanupstate);
6449 gjmp_addr(s->jnext);
6451 next();
6452 } else {
6453 expect("label identifier");
6455 skip(';');
6456 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
6457 asm_instr();
6458 } else {
6459 b = is_label();
6460 if (b) {
6461 /* label case */
6462 next();
6463 s = label_find(b);
6464 if (s) {
6465 if (s->r == LABEL_DEFINED)
6466 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
6467 s->r = LABEL_DEFINED;
6468 if (s->next) {
6469 Sym *pcl; /* pending cleanup goto */
6470 for (pcl = s->next; pcl; pcl = pcl->prev)
6471 gsym(pcl->jnext);
6472 sym_pop(&s->next, NULL, 0);
6473 } else
6474 gsym(s->jnext);
6475 } else {
6476 s = label_push(&global_label_stack, b, LABEL_DEFINED);
6478 s->jnext = ind;
6479 s->cleanupstate = current_cleanups;
6480 vla_sp_restore();
6481 /* we accept this, but it is a mistake */
6482 block_after_label:
6483 nocode_wanted &= ~0x20000000;
6484 if (tok == '}') {
6485 tcc_warning("deprecated use of label at end of compound statement");
6486 } else {
6487 if (is_expr)
6488 vpop();
6489 block(bsym, bcl, csym, ccl, is_expr);
6491 } else {
6492 /* expression case */
6493 if (tok != ';') {
6494 if (is_expr) {
6495 vpop();
6496 gexpr();
6497 } else {
6498 gexpr();
6499 vpop();
6502 skip(';');
6507 /* This skips over a stream of tokens containing balanced {} and ()
6508 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
6509 with a '{'). If STR then allocates and stores the skipped tokens
6510 in *STR. This doesn't check if () and {} are nested correctly,
6511 i.e. "({)}" is accepted. */
6512 static void skip_or_save_block(TokenString **str)
6514 int braces = tok == '{';
6515 int level = 0;
6516 if (str)
6517 *str = tok_str_alloc();
6519 while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
6520 int t;
6521 if (tok == TOK_EOF) {
6522 if (str || level > 0)
6523 tcc_error("unexpected end of file");
6524 else
6525 break;
6527 if (str)
6528 tok_str_add_tok(*str);
6529 t = tok;
6530 next();
6531 if (t == '{' || t == '(') {
6532 level++;
6533 } else if (t == '}' || t == ')') {
6534 level--;
6535 if (level == 0 && braces && t == '}')
6536 break;
6539 if (str) {
6540 tok_str_add(*str, -1);
6541 tok_str_add(*str, 0);
6545 #define EXPR_CONST 1
6546 #define EXPR_ANY 2
6548 static void parse_init_elem(int expr_type)
6550 int saved_global_expr;
6551 switch(expr_type) {
6552 case EXPR_CONST:
6553 /* compound literals must be allocated globally in this case */
6554 saved_global_expr = global_expr;
6555 global_expr = 1;
6556 expr_const1();
6557 global_expr = saved_global_expr;
6558 /* NOTE: symbols are accepted, as well as lvalue for anon symbols
6559 (compound literals). */
6560 if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
6561 && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
6562 || vtop->sym->v < SYM_FIRST_ANOM))
6563 #ifdef TCC_TARGET_PE
6564 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
6565 #endif
6567 tcc_error("initializer element is not constant");
6568 break;
6569 case EXPR_ANY:
6570 expr_eq();
6571 break;
6575 /* put zeros for variable based init */
6576 static void init_putz(Section *sec, unsigned long c, int size)
6578 if (sec) {
6579 /* nothing to do because globals are already set to zero */
6580 } else {
6581 vpush_global_sym(&func_old_type, TOK_memset);
6582 vseti(VT_LOCAL, c);
6583 #ifdef TCC_TARGET_ARM
6584 vpushs(size);
6585 vpushi(0);
6586 #else
6587 vpushi(0);
6588 vpushs(size);
6589 #endif
6590 gfunc_call(3);
6594 #define DIF_FIRST 1
6595 #define DIF_SIZE_ONLY 2
6596 #define DIF_HAVE_ELEM 4
6598 /* t is the array or struct type. c is the array or struct
6599 address. cur_field is the pointer to the current
6600 field, for arrays the 'c' member contains the current start
6601 index. 'flags' is as in decl_initializer.
6602 'al' contains the already initialized length of the
6603 current container (starting at c). This returns the new length of that. */
6604 static int decl_designator(CType *type, Section *sec, unsigned long c,
6605 Sym **cur_field, int flags, int al)
6607 Sym *s, *f;
6608 int index, index_last, align, l, nb_elems, elem_size;
6609 unsigned long corig = c;
6611 elem_size = 0;
6612 nb_elems = 1;
6613 if (flags & DIF_HAVE_ELEM)
6614 goto no_designator;
6615 if (gnu_ext && (l = is_label()) != 0)
6616 goto struct_field;
6617 /* NOTE: we only support ranges for last designator */
6618 while (nb_elems == 1 && (tok == '[' || tok == '.')) {
6619 if (tok == '[') {
6620 if (!(type->t & VT_ARRAY))
6621 expect("array type");
6622 next();
6623 index = index_last = expr_const();
6624 if (tok == TOK_DOTS && gnu_ext) {
6625 next();
6626 index_last = expr_const();
6628 skip(']');
6629 s = type->ref;
6630 if (index < 0 || (s->c >= 0 && index_last >= s->c) ||
6631 index_last < index)
6632 tcc_error("invalid index");
6633 if (cur_field)
6634 (*cur_field)->c = index_last;
6635 type = pointed_type(type);
6636 elem_size = type_size(type, &align);
6637 c += index * elem_size;
6638 nb_elems = index_last - index + 1;
6639 } else {
6640 int cumofs = 0;
6641 next();
6642 l = tok;
6643 struct_field:
6644 next();
6645 if ((type->t & VT_BTYPE) != VT_STRUCT)
6646 expect("struct/union type");
6647 f = find_field(type, l, &cumofs);
6648 if (!f)
6649 expect("field");
6650 if (cur_field)
6651 *cur_field = f;
6652 type = &f->type;
6653 c += cumofs + f->c;
6655 cur_field = NULL;
6657 if (!cur_field) {
6658 if (tok == '=') {
6659 next();
6660 } else if (!gnu_ext) {
6661 expect("=");
6663 } else {
6664 no_designator:
6665 if (type->t & VT_ARRAY) {
6666 index = (*cur_field)->c;
6667 if (type->ref->c >= 0 && index >= type->ref->c)
6668 tcc_error("index too large");
6669 type = pointed_type(type);
6670 c += index * type_size(type, &align);
6671 } else {
6672 f = *cur_field;
6673 while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
6674 *cur_field = f = f->next;
6675 if (!f)
6676 tcc_error("too many field init");
6677 type = &f->type;
6678 c += f->c;
6681 /* must put zero in holes (note that doing it that way
6682 ensures that it even works with designators) */
6683 if (!(flags & DIF_SIZE_ONLY) && c - corig > al)
6684 init_putz(sec, corig + al, c - corig - al);
6685 decl_initializer(type, sec, c, flags & ~DIF_FIRST);
6687 /* XXX: make it more general */
6688 if (!(flags & DIF_SIZE_ONLY) && nb_elems > 1) {
6689 unsigned long c_end;
6690 uint8_t *src, *dst;
6691 int i;
6693 if (!sec) {
6694 vset(type, VT_LOCAL|VT_LVAL, c);
6695 for (i = 1; i < nb_elems; i++) {
6696 vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
6697 vswap();
6698 vstore();
6700 vpop();
6701 } else if (!NODATA_WANTED) {
6702 c_end = c + nb_elems * elem_size;
6703 if (c_end > sec->data_allocated)
6704 section_realloc(sec, c_end);
6705 src = sec->data + c;
6706 dst = src;
6707 for(i = 1; i < nb_elems; i++) {
6708 dst += elem_size;
6709 memcpy(dst, src, elem_size);
6713 c += nb_elems * type_size(type, &align);
6714 if (c - corig > al)
6715 al = c - corig;
6716 return al;
6719 /* store a value or an expression directly in global data or in local array */
6720 static void init_putv(CType *type, Section *sec, unsigned long c)
6722 int bt;
6723 void *ptr;
6724 CType dtype;
6726 dtype = *type;
6727 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
6729 if (sec) {
6730 int size, align;
6731 /* XXX: not portable */
6732 /* XXX: generate error if incorrect relocation */
6733 gen_assign_cast(&dtype);
6734 bt = type->t & VT_BTYPE;
6736 if ((vtop->r & VT_SYM)
6737 && bt != VT_PTR
6738 && bt != VT_FUNC
6739 && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
6740 || (type->t & VT_BITFIELD))
6741 && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
6743 tcc_error("initializer element is not computable at load time");
6745 if (NODATA_WANTED) {
6746 vtop--;
6747 return;
6750 size = type_size(type, &align);
6751 section_reserve(sec, c + size);
6752 ptr = sec->data + c;
6754 /* XXX: make code faster ? */
6755 if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
6756 vtop->sym->v >= SYM_FIRST_ANOM &&
6757 /* XXX This rejects compound literals like
6758 '(void *){ptr}'. The problem is that '&sym' is
6759 represented the same way, which would be ruled out
6760 by the SYM_FIRST_ANOM check above, but also '"string"'
6761 in 'char *p = "string"' is represented the same
6762 with the type being VT_PTR and the symbol being an
6763 anonymous one. That is, there's no difference in vtop
6764 between '(void *){x}' and '&(void *){x}'. Ignore
6765 pointer typed entities here. Hopefully no real code
6766 will every use compound literals with scalar type. */
6767 (vtop->type.t & VT_BTYPE) != VT_PTR) {
6768 /* These come from compound literals, memcpy stuff over. */
6769 Section *ssec;
6770 ElfSym *esym;
6771 ElfW_Rel *rel;
6772 esym = elfsym(vtop->sym);
6773 ssec = tcc_state->sections[esym->st_shndx];
6774 memmove (ptr, ssec->data + esym->st_value, size);
6775 if (ssec->reloc) {
6776 /* We need to copy over all memory contents, and that
6777 includes relocations. Use the fact that relocs are
6778 created it order, so look from the end of relocs
6779 until we hit one before the copied region. */
6780 int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
6781 rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
6782 while (num_relocs--) {
6783 rel--;
6784 if (rel->r_offset >= esym->st_value + size)
6785 continue;
6786 if (rel->r_offset < esym->st_value)
6787 break;
6788 /* Note: if the same fields are initialized multiple
6789 times (possible with designators) then we possibly
6790 add multiple relocations for the same offset here.
6791 That would lead to wrong code, the last reloc needs
6792 to win. We clean this up later after the whole
6793 initializer is parsed. */
6794 put_elf_reloca(symtab_section, sec,
6795 c + rel->r_offset - esym->st_value,
6796 ELFW(R_TYPE)(rel->r_info),
6797 ELFW(R_SYM)(rel->r_info),
6798 #if PTR_SIZE == 8
6799 rel->r_addend
6800 #else
6802 #endif
6806 } else {
6807 if (type->t & VT_BITFIELD) {
6808 int bit_pos, bit_size, bits, n;
6809 unsigned char *p, v, m;
6810 bit_pos = BIT_POS(vtop->type.t);
6811 bit_size = BIT_SIZE(vtop->type.t);
6812 p = (unsigned char*)ptr + (bit_pos >> 3);
6813 bit_pos &= 7, bits = 0;
6814 while (bit_size) {
6815 n = 8 - bit_pos;
6816 if (n > bit_size)
6817 n = bit_size;
6818 v = vtop->c.i >> bits << bit_pos;
6819 m = ((1 << n) - 1) << bit_pos;
6820 *p = (*p & ~m) | (v & m);
6821 bits += n, bit_size -= n, bit_pos = 0, ++p;
6823 } else
6824 switch(bt) {
6825 /* XXX: when cross-compiling we assume that each type has the
6826 same representation on host and target, which is likely to
6827 be wrong in the case of long double */
6828 case VT_BOOL:
6829 vtop->c.i = vtop->c.i != 0;
6830 case VT_BYTE:
6831 *(char *)ptr |= vtop->c.i;
6832 break;
6833 case VT_SHORT:
6834 *(short *)ptr |= vtop->c.i;
6835 break;
6836 case VT_FLOAT:
6837 *(float*)ptr = vtop->c.f;
6838 break;
6839 case VT_DOUBLE:
6840 *(double *)ptr = vtop->c.d;
6841 break;
6842 case VT_LDOUBLE:
6843 #if defined TCC_IS_NATIVE_387
6844 if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
6845 memcpy(ptr, &vtop->c.ld, 10);
6846 #ifdef __TINYC__
6847 else if (sizeof (long double) == sizeof (double))
6848 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
6849 #endif
6850 else if (vtop->c.ld == 0.0)
6852 else
6853 #endif
6854 if (sizeof(long double) == LDOUBLE_SIZE)
6855 *(long double*)ptr = vtop->c.ld;
6856 else if (sizeof(double) == LDOUBLE_SIZE)
6857 *(double *)ptr = (double)vtop->c.ld;
6858 else
6859 tcc_error("can't cross compile long double constants");
6860 break;
6861 #if PTR_SIZE != 8
6862 case VT_LLONG:
6863 *(long long *)ptr |= vtop->c.i;
6864 break;
6865 #else
6866 case VT_LLONG:
6867 #endif
6868 case VT_PTR:
6870 addr_t val = vtop->c.i;
6871 #if PTR_SIZE == 8
6872 if (vtop->r & VT_SYM)
6873 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
6874 else
6875 *(addr_t *)ptr |= val;
6876 #else
6877 if (vtop->r & VT_SYM)
6878 greloc(sec, vtop->sym, c, R_DATA_PTR);
6879 *(addr_t *)ptr |= val;
6880 #endif
6881 break;
6883 default:
6885 int val = vtop->c.i;
6886 #if PTR_SIZE == 8
6887 if (vtop->r & VT_SYM)
6888 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
6889 else
6890 *(int *)ptr |= val;
6891 #else
6892 if (vtop->r & VT_SYM)
6893 greloc(sec, vtop->sym, c, R_DATA_PTR);
6894 *(int *)ptr |= val;
6895 #endif
6896 break;
6900 vtop--;
6901 } else {
6902 vset(&dtype, VT_LOCAL|VT_LVAL, c);
6903 vswap();
6904 vstore();
6905 vpop();
6909 /* 't' contains the type and storage info. 'c' is the offset of the
6910 object in section 'sec'. If 'sec' is NULL, it means stack based
6911 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
6912 dimension implicit array init handling). 'flags & DIF_SIZE_ONLY' is true if
6913 size only evaluation is wanted (only for arrays). */
6914 static void decl_initializer(CType *type, Section *sec, unsigned long c,
6915 int flags)
6917 int len, n, no_oblock, nb, i;
6918 int size1, align1;
6919 Sym *s, *f;
6920 Sym indexsym;
6921 CType *t1;
6923 if (!(flags & DIF_HAVE_ELEM) && tok != '{' &&
6924 /* In case of strings we have special handling for arrays, so
6925 don't consume them as initializer value (which would commit them
6926 to some anonymous symbol). */
6927 tok != TOK_LSTR && tok != TOK_STR &&
6928 !(flags & DIF_SIZE_ONLY)) {
6929 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
6930 flags |= DIF_HAVE_ELEM;
6933 if ((flags & DIF_HAVE_ELEM) &&
6934 !(type->t & VT_ARRAY) &&
6935 /* Use i_c_parameter_t, to strip toplevel qualifiers.
6936 The source type might have VT_CONSTANT set, which is
6937 of course assignable to non-const elements. */
6938 is_compatible_unqualified_types(type, &vtop->type)) {
6939 init_putv(type, sec, c);
6940 } else if (type->t & VT_ARRAY) {
6941 s = type->ref;
6942 n = s->c;
6943 t1 = pointed_type(type);
6944 size1 = type_size(t1, &align1);
6946 no_oblock = 1;
6947 if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
6948 tok == '{') {
6949 if (tok != '{')
6950 tcc_error("character array initializer must be a literal,"
6951 " optionally enclosed in braces");
6952 skip('{');
6953 no_oblock = 0;
6956 /* only parse strings here if correct type (otherwise: handle
6957 them as ((w)char *) expressions */
6958 if ((tok == TOK_LSTR &&
6959 #ifdef TCC_TARGET_PE
6960 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
6961 #else
6962 (t1->t & VT_BTYPE) == VT_INT
6963 #endif
6964 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
6965 len = 0;
6966 while (tok == TOK_STR || tok == TOK_LSTR) {
6967 int cstr_len, ch;
6969 /* compute maximum number of chars wanted */
6970 if (tok == TOK_STR)
6971 cstr_len = tokc.str.size;
6972 else
6973 cstr_len = tokc.str.size / sizeof(nwchar_t);
6974 cstr_len--;
6975 nb = cstr_len;
6976 if (n >= 0 && nb > (n - len))
6977 nb = n - len;
6978 if (!(flags & DIF_SIZE_ONLY)) {
6979 if (cstr_len > nb)
6980 tcc_warning("initializer-string for array is too long");
6981 /* in order to go faster for common case (char
6982 string in global variable, we handle it
6983 specifically */
6984 if (sec && tok == TOK_STR && size1 == 1) {
6985 if (!NODATA_WANTED)
6986 memcpy(sec->data + c + len, tokc.str.data, nb);
6987 } else {
6988 for(i=0;i<nb;i++) {
6989 if (tok == TOK_STR)
6990 ch = ((unsigned char *)tokc.str.data)[i];
6991 else
6992 ch = ((nwchar_t *)tokc.str.data)[i];
6993 vpushi(ch);
6994 init_putv(t1, sec, c + (len + i) * size1);
6998 len += nb;
6999 next();
7001 /* only add trailing zero if enough storage (no
7002 warning in this case since it is standard) */
7003 if (n < 0 || len < n) {
7004 if (!(flags & DIF_SIZE_ONLY)) {
7005 vpushi(0);
7006 init_putv(t1, sec, c + (len * size1));
7008 len++;
7010 len *= size1;
7011 } else {
7012 indexsym.c = 0;
7013 f = &indexsym;
7015 do_init_list:
7016 len = 0;
7017 while (tok != '}' || (flags & DIF_HAVE_ELEM)) {
7018 len = decl_designator(type, sec, c, &f, flags, len);
7019 flags &= ~DIF_HAVE_ELEM;
7020 if (type->t & VT_ARRAY) {
7021 ++indexsym.c;
7022 /* special test for multi dimensional arrays (may not
7023 be strictly correct if designators are used at the
7024 same time) */
7025 if (no_oblock && len >= n*size1)
7026 break;
7027 } else {
7028 if (s->type.t == VT_UNION)
7029 f = NULL;
7030 else
7031 f = f->next;
7032 if (no_oblock && f == NULL)
7033 break;
7036 if (tok == '}')
7037 break;
7038 skip(',');
7041 /* put zeros at the end */
7042 if (!(flags & DIF_SIZE_ONLY) && len < n*size1)
7043 init_putz(sec, c + len, n*size1 - len);
7044 if (!no_oblock)
7045 skip('}');
7046 /* patch type size if needed, which happens only for array types */
7047 if (n < 0)
7048 s->c = size1 == 1 ? len : ((len + size1 - 1)/size1);
7049 } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
7050 size1 = 1;
7051 no_oblock = 1;
7052 if ((flags & DIF_FIRST) || tok == '{') {
7053 skip('{');
7054 no_oblock = 0;
7056 s = type->ref;
7057 f = s->next;
7058 n = s->c;
7059 goto do_init_list;
7060 } else if (tok == '{') {
7061 if (flags & DIF_HAVE_ELEM)
7062 skip(';');
7063 next();
7064 decl_initializer(type, sec, c, flags & ~DIF_HAVE_ELEM);
7065 skip('}');
7066 } else if ((flags & DIF_SIZE_ONLY)) {
7067 /* If we supported only ISO C we wouldn't have to accept calling
7068 this on anything than an array if DIF_SIZE_ONLY (and even then
7069 only on the outermost level, so no recursion would be needed),
7070 because initializing a flex array member isn't supported.
7071 But GNU C supports it, so we need to recurse even into
7072 subfields of structs and arrays when DIF_SIZE_ONLY is set. */
7073 /* just skip expression */
7074 skip_or_save_block(NULL);
7075 } else {
7076 if (!(flags & DIF_HAVE_ELEM)) {
7077 /* This should happen only when we haven't parsed
7078 the init element above for fear of committing a
7079 string constant to memory too early. */
7080 if (tok != TOK_STR && tok != TOK_LSTR)
7081 expect("string constant");
7082 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
7084 init_putv(type, sec, c);
7088 /* parse an initializer for type 't' if 'has_init' is non zero, and
7089 allocate space in local or global data space ('r' is either
7090 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7091 variable 'v' of scope 'scope' is declared before initializers
7092 are parsed. If 'v' is zero, then a reference to the new object
7093 is put in the value stack. If 'has_init' is 2, a special parsing
7094 is done to handle string constants. */
7095 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7096 int has_init, int v, int scope)
7098 int size, align, addr;
7099 TokenString *init_str = NULL;
7101 Section *sec;
7102 Sym *flexible_array;
7103 Sym *sym = NULL;
7104 int saved_nocode_wanted = nocode_wanted;
7105 #ifdef CONFIG_TCC_BCHECK
7106 int bcheck;
7107 #endif
7109 /* Always allocate static or global variables */
7110 if (v && (r & VT_VALMASK) == VT_CONST)
7111 nocode_wanted |= 0x80000000;
7113 #ifdef CONFIG_TCC_BCHECK
7114 bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
7115 #endif
7117 flexible_array = NULL;
7118 if ((type->t & VT_BTYPE) == VT_STRUCT) {
7119 Sym *field = type->ref->next;
7120 if (field) {
7121 while (field->next)
7122 field = field->next;
7123 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
7124 flexible_array = field;
7128 size = type_size(type, &align);
7129 /* If unknown size, we must evaluate it before
7130 evaluating initializers because
7131 initializers can generate global data too
7132 (e.g. string pointers or ISOC99 compound
7133 literals). It also simplifies local
7134 initializers handling */
7135 if (size < 0 || (flexible_array && has_init)) {
7136 if (!has_init)
7137 tcc_error("unknown type size");
7138 /* get all init string */
7139 if (has_init == 2) {
7140 init_str = tok_str_alloc();
7141 /* only get strings */
7142 while (tok == TOK_STR || tok == TOK_LSTR) {
7143 tok_str_add_tok(init_str);
7144 next();
7146 tok_str_add(init_str, -1);
7147 tok_str_add(init_str, 0);
7148 } else {
7149 skip_or_save_block(&init_str);
7151 unget_tok(0);
7153 /* compute size */
7154 begin_macro(init_str, 1);
7155 next();
7156 decl_initializer(type, NULL, 0, DIF_FIRST | DIF_SIZE_ONLY);
7157 /* prepare second initializer parsing */
7158 macro_ptr = init_str->str;
7159 next();
7161 /* if still unknown size, error */
7162 size = type_size(type, &align);
7163 if (size < 0)
7164 tcc_error("unknown type size");
7166 /* If there's a flex member and it was used in the initializer
7167 adjust size. */
7168 if (flexible_array &&
7169 flexible_array->type.ref->c > 0)
7170 size += flexible_array->type.ref->c
7171 * pointed_size(&flexible_array->type);
7172 /* take into account specified alignment if bigger */
7173 if (ad->a.aligned) {
7174 int speca = 1 << (ad->a.aligned - 1);
7175 if (speca > align)
7176 align = speca;
7177 } else if (ad->a.packed) {
7178 align = 1;
7181 if (!v && NODATA_WANTED)
7182 size = 0, align = 1;
7184 if ((r & VT_VALMASK) == VT_LOCAL) {
7185 sec = NULL;
7186 #ifdef CONFIG_TCC_BCHECK
7187 if (bcheck && (type->t & VT_ARRAY)) {
7188 loc--;
7190 #endif
7191 loc = (loc - size) & -align;
7192 addr = loc;
7193 #ifdef CONFIG_TCC_BCHECK
7194 /* handles bounds */
7195 /* XXX: currently, since we do only one pass, we cannot track
7196 '&' operators, so we add only arrays */
7197 if (bcheck && (type->t & VT_ARRAY)) {
7198 addr_t *bounds_ptr;
7199 /* add padding between regions */
7200 loc--;
7201 /* then add local bound info */
7202 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
7203 bounds_ptr[0] = addr;
7204 bounds_ptr[1] = size;
7206 #endif
7207 if (v) {
7208 /* local variable */
7209 #ifdef CONFIG_TCC_ASM
7210 if (ad->asm_label) {
7211 int reg = asm_parse_regvar(ad->asm_label);
7212 if (reg >= 0)
7213 r = (r & ~VT_VALMASK) | reg;
7215 #endif
7216 sym = sym_push(v, type, r, addr);
7217 if (ad->cleanup_func) {
7218 Sym *cls = sym_push2(&all_cleanups, SYM_FIELD | ++ncleanups, 0, 0);
7219 cls->prev_tok = sym;
7220 cls->next = ad->cleanup_func;
7221 cls->ncl = current_cleanups;
7222 current_cleanups = cls;
7225 sym->a = ad->a;
7226 } else {
7227 /* push local reference */
7228 vset(type, r, addr);
7230 } else {
7231 if (v && scope == VT_CONST) {
7232 /* see if the symbol was already defined */
7233 sym = sym_find(v);
7234 if (sym) {
7235 patch_storage(sym, ad, type);
7236 /* we accept several definitions of the same global variable. */
7237 if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
7238 goto no_alloc;
7242 /* allocate symbol in corresponding section */
7243 sec = ad->section;
7244 if (!sec) {
7245 if (has_init)
7246 sec = data_section;
7247 else if (tcc_state->nocommon)
7248 sec = bss_section;
7251 if (sec) {
7252 addr = section_add(sec, size, align);
7253 #ifdef CONFIG_TCC_BCHECK
7254 /* add padding if bound check */
7255 if (bcheck)
7256 section_add(sec, 1, 1);
7257 #endif
7258 } else {
7259 addr = align; /* SHN_COMMON is special, symbol value is align */
7260 sec = common_section;
7263 if (v) {
7264 if (!sym) {
7265 sym = sym_push(v, type, r | VT_SYM, 0);
7266 patch_storage(sym, ad, NULL);
7268 /* Local statics have a scope until now (for
7269 warnings), remove it here. */
7270 sym->sym_scope = 0;
7271 /* update symbol definition */
7272 put_extern_sym(sym, sec, addr, size);
7273 } else {
7274 /* push global reference */
7275 vpush_ref(type, sec, addr, size);
7276 sym = vtop->sym;
7277 vtop->r |= r;
7280 #ifdef CONFIG_TCC_BCHECK
7281 /* handles bounds now because the symbol must be defined
7282 before for the relocation */
7283 if (bcheck) {
7284 addr_t *bounds_ptr;
7286 greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
7287 /* then add global bound info */
7288 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
7289 bounds_ptr[0] = 0; /* relocated */
7290 bounds_ptr[1] = size;
7292 #endif
7295 if (type->t & VT_VLA) {
7296 int a;
7298 if (NODATA_WANTED)
7299 goto no_alloc;
7301 /* save current stack pointer */
7302 if (vlas_in_scope == 0) {
7303 if (vla_sp_root_loc == -1)
7304 vla_sp_root_loc = (loc -= PTR_SIZE);
7305 gen_vla_sp_save(vla_sp_root_loc);
7308 vla_runtime_type_size(type, &a);
7309 gen_vla_alloc(type, a);
7310 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
7311 /* on _WIN64, because of the function args scratch area, the
7312 result of alloca differs from RSP and is returned in RAX. */
7313 gen_vla_result(addr), addr = (loc -= PTR_SIZE);
7314 #endif
7315 gen_vla_sp_save(addr);
7316 vla_sp_loc = addr;
7317 vlas_in_scope++;
7319 } else if (has_init) {
7320 size_t oldreloc_offset = 0;
7321 if (sec && sec->reloc)
7322 oldreloc_offset = sec->reloc->data_offset;
7323 decl_initializer(type, sec, addr, DIF_FIRST);
7324 if (sec && sec->reloc)
7325 squeeze_multi_relocs(sec, oldreloc_offset);
7326 /* patch flexible array member size back to -1, */
7327 /* for possible subsequent similar declarations */
7328 if (flexible_array)
7329 flexible_array->type.ref->c = -1;
7332 no_alloc:
7333 /* restore parse state if needed */
7334 if (init_str) {
7335 end_macro();
7336 next();
7339 nocode_wanted = saved_nocode_wanted;
7342 /* parse a function defined by symbol 'sym' and generate its code in
7343 'cur_text_section' */
7344 static void gen_function(Sym *sym)
7346 nocode_wanted = 0;
7347 ind = cur_text_section->data_offset;
7348 if (sym->a.aligned) {
7349 size_t newoff = section_add(cur_text_section, 0,
7350 1 << (sym->a.aligned - 1));
7351 gen_fill_nops(newoff - ind);
7353 /* NOTE: we patch the symbol size later */
7354 put_extern_sym(sym, cur_text_section, ind, 0);
7355 funcname = get_tok_str(sym->v, NULL);
7356 func_ind = ind;
7357 /* Initialize VLA state */
7358 vla_sp_loc = -1;
7359 vla_sp_root_loc = -1;
7360 /* put debug symbol */
7361 tcc_debug_funcstart(tcc_state, sym);
7362 /* push a dummy symbol to enable local sym storage */
7363 sym_push2(&local_stack, SYM_FIELD, 0, 0);
7364 local_scope = 1; /* for function parameters */
7365 gfunc_prolog(&sym->type);
7366 reset_local_scope();
7367 rsym = 0;
7368 clear_temp_local_var_list();
7369 block(NULL, NULL, NULL, NULL, 0);
7370 if (!(nocode_wanted & 0x20000000)
7371 && ((func_vt.t & VT_BTYPE) == VT_INT)
7372 && !strcmp (funcname, "main"))
7374 nocode_wanted = 0;
7375 vpushi(0);
7376 gen_assign_cast(&func_vt);
7377 gfunc_return(&func_vt);
7379 nocode_wanted = 0;
7380 gsym(rsym);
7381 gfunc_epilog();
7382 cur_text_section->data_offset = ind;
7383 label_pop(&global_label_stack, NULL, 0);
7384 /* reset local stack */
7385 reset_local_scope();
7386 sym_pop(&local_stack, NULL, 0);
7387 /* end of function */
7388 /* patch symbol size */
7389 elfsym(sym)->st_size = ind - func_ind;
7390 tcc_debug_funcend(tcc_state, ind - func_ind);
7391 /* It's better to crash than to generate wrong code */
7392 cur_text_section = NULL;
7393 funcname = ""; /* for safety */
7394 func_vt.t = VT_VOID; /* for safety */
7395 func_var = 0; /* for safety */
7396 ind = 0; /* for safety */
7397 nocode_wanted = 0x80000000;
7398 check_vstack();
7401 static void gen_inline_functions(TCCState *s)
7403 Sym *sym;
7404 int inline_generated, i, ln;
7405 struct InlineFunc *fn;
7407 ln = file->line_num;
7408 /* iterate while inline function are referenced */
7409 do {
7410 inline_generated = 0;
7411 for (i = 0; i < s->nb_inline_fns; ++i) {
7412 fn = s->inline_fns[i];
7413 sym = fn->sym;
7414 if (sym && sym->c) {
7415 /* the function was used: generate its code and
7416 convert it to a normal function */
7417 fn->sym = NULL;
7418 if (file)
7419 pstrcpy(file->filename, sizeof file->filename, fn->filename);
7420 sym->type.t &= ~VT_INLINE;
7422 begin_macro(fn->func_str, 1);
7423 next();
7424 cur_text_section = text_section;
7425 gen_function(sym);
7426 end_macro();
7428 inline_generated = 1;
7431 } while (inline_generated);
7432 file->line_num = ln;
7435 ST_FUNC void free_inline_functions(TCCState *s)
7437 int i;
7438 /* free tokens of unused inline functions */
7439 for (i = 0; i < s->nb_inline_fns; ++i) {
7440 struct InlineFunc *fn = s->inline_fns[i];
7441 if (fn->sym)
7442 tok_str_free(fn->func_str);
7444 dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
7447 /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
7448 if parsing old style parameter decl list (and FUNC_SYM is set then) */
7449 static int decl0(int l, int is_for_loop_init, Sym *func_sym)
7451 int v, has_init, r;
7452 CType type, btype;
7453 Sym *sym;
7454 AttributeDef ad, adbase;
7456 while (1) {
7457 if (tok == TOK_STATIC_ASSERT) {
7458 int c;
7460 next();
7461 skip('(');
7462 c = expr_const();
7463 skip(',');
7464 if (c == 0)
7465 tcc_error("%s", get_tok_str(tok, &tokc));
7466 next();
7467 skip(')');
7468 skip(';');
7469 continue;
7471 if (!parse_btype(&btype, &adbase)) {
7472 if (is_for_loop_init)
7473 return 0;
7474 /* skip redundant ';' if not in old parameter decl scope */
7475 if (tok == ';' && l != VT_CMP) {
7476 next();
7477 continue;
7479 if (l != VT_CONST)
7480 break;
7481 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
7482 /* global asm block */
7483 asm_global_instr();
7484 continue;
7486 if (tok >= TOK_UIDENT) {
7487 /* special test for old K&R protos without explicit int
7488 type. Only accepted when defining global data */
7489 btype.t = VT_INT;
7490 } else {
7491 if (tok != TOK_EOF)
7492 expect("declaration");
7493 break;
7496 if (tok == ';') {
7497 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
7498 int v = btype.ref->v;
7499 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
7500 tcc_warning("unnamed struct/union that defines no instances");
7501 next();
7502 continue;
7504 if (IS_ENUM(btype.t)) {
7505 next();
7506 continue;
7509 while (1) { /* iterate thru each declaration */
7510 type = btype;
7511 /* If the base type itself was an array type of unspecified
7512 size (like in 'typedef int arr[]; arr x = {1};') then
7513 we will overwrite the unknown size by the real one for
7514 this decl. We need to unshare the ref symbol holding
7515 that size. */
7516 if ((type.t & VT_ARRAY) && type.ref->c < 0) {
7517 type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
7519 ad = adbase;
7520 type_decl(&type, &ad, &v, TYPE_DIRECT);
7521 #if 0
7523 char buf[500];
7524 type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
7525 printf("type = '%s'\n", buf);
7527 #endif
7528 if ((type.t & VT_BTYPE) == VT_FUNC) {
7529 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
7530 tcc_error("function without file scope cannot be static");
7532 /* if old style function prototype, we accept a
7533 declaration list */
7534 sym = type.ref;
7535 if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
7536 decl0(VT_CMP, 0, sym);
7539 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
7540 ad.asm_label = asm_label_instr();
7541 /* parse one last attribute list, after asm label */
7542 parse_attribute(&ad);
7543 if (tok == '{')
7544 expect(";");
7547 #ifdef TCC_TARGET_PE
7548 if (ad.a.dllimport || ad.a.dllexport) {
7549 if (type.t & (VT_STATIC|VT_TYPEDEF))
7550 tcc_error("cannot have dll linkage with static or typedef");
7551 if (ad.a.dllimport) {
7552 if ((type.t & VT_BTYPE) == VT_FUNC)
7553 ad.a.dllimport = 0;
7554 else
7555 type.t |= VT_EXTERN;
7558 #endif
7559 if (tok == '{') {
7560 if (l != VT_CONST)
7561 tcc_error("cannot use local functions");
7562 if ((type.t & VT_BTYPE) != VT_FUNC)
7563 expect("function definition");
7565 /* reject abstract declarators in function definition
7566 make old style params without decl have int type */
7567 sym = type.ref;
7568 while ((sym = sym->next) != NULL) {
7569 if (!(sym->v & ~SYM_FIELD))
7570 expect("identifier");
7571 if (sym->type.t == VT_VOID)
7572 sym->type = int_type;
7575 /* XXX: cannot do better now: convert extern line to static inline */
7576 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
7577 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
7579 /* put function symbol */
7580 sym = external_sym(v, &type, 0, &ad);
7582 /* static inline functions are just recorded as a kind
7583 of macro. Their code will be emitted at the end of
7584 the compilation unit only if they are used */
7585 if ((type.t & (VT_INLINE | VT_STATIC)) ==
7586 (VT_INLINE | VT_STATIC)) {
7587 struct InlineFunc *fn;
7588 const char *filename;
7590 filename = file ? file->filename : "";
7591 fn = tcc_malloc(sizeof *fn + strlen(filename));
7592 strcpy(fn->filename, filename);
7593 fn->sym = sym;
7594 skip_or_save_block(&fn->func_str);
7595 dynarray_add(&tcc_state->inline_fns,
7596 &tcc_state->nb_inline_fns, fn);
7597 } else {
7598 /* compute text section */
7599 cur_text_section = ad.section;
7600 if (!cur_text_section)
7601 cur_text_section = text_section;
7602 gen_function(sym);
7604 break;
7605 } else {
7606 if (l == VT_CMP) {
7607 /* find parameter in function parameter list */
7608 for (sym = func_sym->next; sym; sym = sym->next)
7609 if ((sym->v & ~SYM_FIELD) == v)
7610 goto found;
7611 tcc_error("declaration for parameter '%s' but no such parameter",
7612 get_tok_str(v, NULL));
7613 found:
7614 if (type.t & VT_STORAGE) /* 'register' is okay */
7615 tcc_error("storage class specified for '%s'",
7616 get_tok_str(v, NULL));
7617 if (sym->type.t != VT_VOID)
7618 tcc_error("redefinition of parameter '%s'",
7619 get_tok_str(v, NULL));
7620 convert_parameter_type(&type);
7621 sym->type = type;
7622 } else if (type.t & VT_TYPEDEF) {
7623 /* save typedefed type */
7624 /* XXX: test storage specifiers ? */
7625 sym = sym_find(v);
7626 if (sym && sym->sym_scope == local_scope) {
7627 if (!is_compatible_types(&sym->type, &type)
7628 || !(sym->type.t & VT_TYPEDEF))
7629 tcc_error("incompatible redefinition of '%s'",
7630 get_tok_str(v, NULL));
7631 sym->type = type;
7632 } else {
7633 sym = sym_push(v, &type, 0, 0);
7635 sym->a = ad.a;
7636 sym->f = ad.f;
7637 } else if ((type.t & VT_BTYPE) == VT_VOID
7638 && !(type.t & VT_EXTERN)) {
7639 tcc_error("declaration of void object");
7640 } else {
7641 r = 0;
7642 if ((type.t & VT_BTYPE) == VT_FUNC) {
7643 /* external function definition */
7644 /* specific case for func_call attribute */
7645 type.ref->f = ad.f;
7646 } else if (!(type.t & VT_ARRAY)) {
7647 /* not lvalue if array */
7648 r |= lvalue_type(type.t);
7650 has_init = (tok == '=');
7651 if (has_init && (type.t & VT_VLA))
7652 tcc_error("variable length array cannot be initialized");
7653 if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) ||
7654 ((type.t & VT_BTYPE) == VT_FUNC) ||
7655 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
7656 !has_init && l == VT_CONST && type.ref->c < 0)) {
7657 /* external variable or function */
7658 /* NOTE: as GCC, uninitialized global static
7659 arrays of null size are considered as
7660 extern */
7661 type.t |= VT_EXTERN;
7662 sym = external_sym(v, &type, r, &ad);
7663 if (ad.alias_target) {
7664 ElfSym *esym;
7665 Sym *alias_target;
7666 alias_target = sym_find(ad.alias_target);
7667 esym = elfsym(alias_target);
7668 if (!esym)
7669 tcc_error("unsupported forward __alias__ attribute");
7670 /* Local statics have a scope until now (for
7671 warnings), remove it here. */
7672 sym->sym_scope = 0;
7673 put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0);
7675 } else {
7676 if (type.t & VT_STATIC)
7677 r |= VT_CONST;
7678 else
7679 r |= l;
7680 if (has_init)
7681 next();
7682 else if (l == VT_CONST)
7683 /* uninitialized global variables may be overridden */
7684 type.t |= VT_EXTERN;
7685 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
7688 if (tok != ',') {
7689 if (is_for_loop_init)
7690 return 1;
7691 skip(';');
7692 break;
7694 next();
7698 return 0;
7701 static void decl(int l)
7703 decl0(l, 0, NULL);
7706 /* ------------------------------------------------------------------------- */