Changeset 331 for EcnlProtoTool/trunk/tcc-0.9.27/tccgen.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/tcc-0.9.27
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/tcc-0.9.27/tccgen.c
r321 r331 31 31 ST_DATA int rsym, anon_sym, ind, loc; 32 32 33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */34 ST_DATA Section *cur_text_section; /* current section where function code is generated */35 #ifdef CONFIG_TCC_ASM36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */37 #endif38 #ifdef CONFIG_TCC_BCHECK39 /* bound check related sections */40 ST_DATA Section *bounds_section; /* contains global data bound description */41 ST_DATA Section *lbounds_section; /* contains local data bound description */42 #endif43 /* symbol sections */44 ST_DATA Section *symtab_section, *strtab_section;45 /* debug sections */46 ST_DATA Section *stab_section, *stabstr_section;47 33 ST_DATA Sym *sym_free_first; 48 34 ST_DATA void **sym_pools; … … 51 37 ST_DATA Sym *global_stack; 52 38 ST_DATA Sym *local_stack; 53 ST_DATA Sym *scope_stack_bottom;54 39 ST_DATA Sym *define_stack; 55 40 ST_DATA Sym *global_label_stack; 56 41 ST_DATA Sym *local_label_stack; 57 58 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop; 42 static int local_scope; 43 static int in_sizeof; 44 static int section_sym; 45 46 ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ 47 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */ 48 ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */ 49 50 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop; 59 51 60 52 ST_DATA int const_wanted; /* true if constant wanted */ 61 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ 53 ST_DATA int nocode_wanted; /* no code generation wanted */ 54 #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */ 55 #define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */ 62 56 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ 63 57 ST_DATA CType func_vt; /* current function return type (used by return instruction) */ 58 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */ 64 59 ST_DATA int func_vc; 65 60 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ 66 ST_DATA char *funcname; 67 68 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; 61 ST_DATA const char *funcname; 62 ST_DATA int g_debug; 63 64 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type; 65 66 ST_DATA struct switch_t { 67 struct case_t { 68 int64_t v1, v2; 69 int sym; 70 } **p; int n; /* list of case ranges */ 71 int def_sym; /* default symbol */ 72 } *cur_switch; /* current switch */ 69 73 70 74 /* ------------------------------------------------------------------------- */ 75 71 76 static void gen_cast(CType *type); 77 static void gen_cast_s(int t); 72 78 static inline CType *pointed_type(CType *type); 73 79 static int is_compatible_types(CType *type1, CType *type2); 74 80 static int parse_btype(CType *type, AttributeDef *ad); 75 static voidtype_decl(CType *type, AttributeDef *ad, int *v, int td);81 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td); 76 82 static void parse_expr_type(CType *type); 83 static void init_putv(CType *type, Section *sec, unsigned long c); 77 84 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); 78 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr); 79 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope); 80 static int decl0(int l, int is_for_loop_init); 85 static void block(int *bsym, int *csym, int is_expr); 86 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); 87 static void decl(int l); 88 static int decl0(int l, int is_for_loop_init, Sym *); 81 89 static void expr_eq(void); 82 static void unary_type(CType *type);83 90 static void vla_runtime_type_size(CType *type, int *a); 84 static int is_compatible_parameter_types(CType *type1, CType *type2); 85 static void expr_type(CType *type); 91 static void vla_sp_restore(void); 92 static void vla_sp_restore_root(void); 93 static int is_compatible_unqualified_types(CType *type1, CType *type2); 94 static inline int64_t expr_const64(void); 95 static void vpush64(int ty, unsigned long long v); 96 static void vpush(CType *type); 97 static int gvtst(int inv, int t); 98 static void gen_inline_functions(TCCState *s); 99 static void skip_or_save_block(TokenString **str); 100 static void gv_dup(void); 86 101 87 102 ST_INLN int is_float(int t) … … 89 104 int bt; 90 105 bt = t & VT_BTYPE; 91 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT ;106 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT; 92 107 } 93 108 … … 97 112 ST_FUNC int ieee_finite(double d) 98 113 { 99 int *p = (int *)&d; 114 int p[4]; 115 memcpy(p, &d, sizeof(double)); 100 116 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; 101 117 } 118 119 /* compiling intel long double natively */ 120 #if (defined __i386__ || defined __x86_64__) \ 121 && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) 122 # define TCC_IS_NATIVE_387 123 #endif 102 124 103 125 ST_FUNC void test_lvalue(void) … … 106 128 expect("lvalue"); 107 129 } 130 131 ST_FUNC void check_vstack(void) 132 { 133 if (pvtop != vtop) 134 tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop); 135 } 136 137 /* ------------------------------------------------------------------------- */ 138 /* vstack debugging aid */ 139 140 #if 0 141 void pv (const char *lbl, int a, int b) 142 { 143 int i; 144 for (i = a; i < a + b; ++i) { 145 SValue *p = &vtop[-i]; 146 printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n", 147 lbl, i, p->type.t, p->r, p->r2, (int)p->c.i); 148 } 149 } 150 #endif 151 152 /* ------------------------------------------------------------------------- */ 153 /* start of translation unit info */ 154 ST_FUNC void tcc_debug_start(TCCState *s1) 155 { 156 if (s1->do_debug) { 157 char buf[512]; 158 159 /* file info: full path + filename */ 160 section_sym = put_elf_sym(symtab_section, 0, 0, 161 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, 162 text_section->sh_num, NULL); 163 getcwd(buf, sizeof(buf)); 164 #ifdef _WIN32 165 normalize_slashes(buf); 166 #endif 167 pstrcat(buf, sizeof(buf), "/"); 168 put_stabs_r(buf, N_SO, 0, 0, 169 text_section->data_offset, text_section, section_sym); 170 put_stabs_r(file->filename, N_SO, 0, 0, 171 text_section->data_offset, text_section, section_sym); 172 last_ind = 0; 173 last_line_num = 0; 174 } 175 176 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL 177 symbols can be safely used */ 178 put_elf_sym(symtab_section, 0, 0, 179 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0, 180 SHN_ABS, file->filename); 181 } 182 183 /* put end of translation unit info */ 184 ST_FUNC void tcc_debug_end(TCCState *s1) 185 { 186 if (!s1->do_debug) 187 return; 188 put_stabs_r(NULL, N_SO, 0, 0, 189 text_section->data_offset, text_section, section_sym); 190 191 } 192 193 /* generate line number info */ 194 ST_FUNC void tcc_debug_line(TCCState *s1) 195 { 196 if (!s1->do_debug) 197 return; 198 if ((last_line_num != file->line_num || last_ind != ind)) { 199 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind); 200 last_ind = ind; 201 last_line_num = file->line_num; 202 } 203 } 204 205 /* put function symbol */ 206 ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym) 207 { 208 char buf[512]; 209 210 if (!s1->do_debug) 211 return; 212 213 /* stabs info */ 214 /* XXX: we put here a dummy type */ 215 snprintf(buf, sizeof(buf), "%s:%c1", 216 funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); 217 put_stabs_r(buf, N_FUN, 0, file->line_num, 0, 218 cur_text_section, sym->c); 219 /* //gr gdb wants a line at the function */ 220 put_stabn(N_SLINE, 0, file->line_num, 0); 221 222 last_ind = 0; 223 last_line_num = 0; 224 } 225 226 /* put function size */ 227 ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) 228 { 229 if (!s1->do_debug) 230 return; 231 put_stabn(N_FUN, 0, 0, size); 232 } 233 234 /* ------------------------------------------------------------------------- */ 235 ST_FUNC int tccgen_compile(TCCState *s1) 236 { 237 cur_text_section = NULL; 238 funcname = ""; 239 anon_sym = SYM_FIRST_ANOM; 240 section_sym = 0; 241 const_wanted = 0; 242 nocode_wanted = 0x80000000; 243 244 /* define some often used types */ 245 int_type.t = VT_INT; 246 char_pointer_type.t = VT_BYTE; 247 mk_pointer(&char_pointer_type); 248 #if PTR_SIZE == 4 249 size_type.t = VT_INT | VT_UNSIGNED; 250 ptrdiff_type.t = VT_INT; 251 #elif LONG_SIZE == 4 252 size_type.t = VT_LLONG | VT_UNSIGNED; 253 ptrdiff_type.t = VT_LLONG; 254 #else 255 size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED; 256 ptrdiff_type.t = VT_LONG | VT_LLONG; 257 #endif 258 func_old_type.t = VT_FUNC; 259 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0); 260 func_old_type.ref->f.func_call = FUNC_CDECL; 261 func_old_type.ref->f.func_type = FUNC_OLD; 262 263 tcc_debug_start(s1); 264 265 #ifdef TCC_TARGET_ARM 266 arm_init(s1); 267 #endif 268 269 #ifdef INC_DEBUG 270 printf("%s: **** new file\n", file->filename); 271 #endif 272 273 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; 274 next(); 275 decl(VT_CONST); 276 gen_inline_functions(s1); 277 check_vstack(); 278 /* end of translation unit info */ 279 tcc_debug_end(s1); 280 return 0; 281 } 282 283 /* ------------------------------------------------------------------------- */ 284 ST_FUNC ElfSym *elfsym(Sym *s) 285 { 286 if (!s || !s->c) 287 return NULL; 288 return &((ElfSym *)symtab_section->data)[s->c]; 289 } 290 291 /* apply storage attributes to Elf symbol */ 292 ST_FUNC void update_storage(Sym *sym) 293 { 294 ElfSym *esym; 295 int sym_bind, old_sym_bind; 296 297 esym = elfsym(sym); 298 if (!esym) 299 return; 300 301 if (sym->a.visibility) 302 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) 303 | sym->a.visibility; 304 305 if (sym->type.t & VT_STATIC) 306 sym_bind = STB_LOCAL; 307 else if (sym->a.weak) 308 sym_bind = STB_WEAK; 309 else 310 sym_bind = STB_GLOBAL; 311 old_sym_bind = ELFW(ST_BIND)(esym->st_info); 312 if (sym_bind != old_sym_bind) { 313 esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info)); 314 } 315 316 #ifdef TCC_TARGET_PE 317 if (sym->a.dllimport) 318 esym->st_other |= ST_PE_IMPORT; 319 if (sym->a.dllexport) 320 esym->st_other |= ST_PE_EXPORT; 321 #endif 322 323 #if 0 324 printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n", 325 get_tok_str(sym->v, NULL), 326 sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g', 327 sym->a.visibility, 328 sym->a.dllexport, 329 sym->a.dllimport 330 ); 331 #endif 332 } 333 334 /* ------------------------------------------------------------------------- */ 335 /* update sym->c so that it points to an external symbol in section 336 'section' with value 'value' */ 337 338 ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, 339 addr_t value, unsigned long size, 340 int can_add_underscore) 341 { 342 int sym_type, sym_bind, info, other, t; 343 ElfSym *esym; 344 const char *name; 345 char buf1[256]; 346 #ifdef CONFIG_TCC_BCHECK 347 char buf[32]; 348 #endif 349 350 if (!sym->c) { 351 name = get_tok_str(sym->v, NULL); 352 #ifdef CONFIG_TCC_BCHECK 353 if (tcc_state->do_bounds_check) { 354 /* XXX: avoid doing that for statics ? */ 355 /* if bound checking is activated, we change some function 356 names by adding the "__bound" prefix */ 357 switch(sym->v) { 358 #ifdef TCC_TARGET_PE 359 /* XXX: we rely only on malloc hooks */ 360 case TOK_malloc: 361 case TOK_free: 362 case TOK_realloc: 363 case TOK_memalign: 364 case TOK_calloc: 365 #endif 366 case TOK_memcpy: 367 case TOK_memmove: 368 case TOK_memset: 369 case TOK_strlen: 370 case TOK_strcpy: 371 case TOK_alloca: 372 strcpy(buf, "__bound_"); 373 strcat(buf, name); 374 name = buf; 375 break; 376 } 377 } 378 #endif 379 t = sym->type.t; 380 if ((t & VT_BTYPE) == VT_FUNC) { 381 sym_type = STT_FUNC; 382 } else if ((t & VT_BTYPE) == VT_VOID) { 383 sym_type = STT_NOTYPE; 384 } else { 385 sym_type = STT_OBJECT; 386 } 387 if (t & VT_STATIC) 388 sym_bind = STB_LOCAL; 389 else 390 sym_bind = STB_GLOBAL; 391 other = 0; 392 #ifdef TCC_TARGET_PE 393 if (sym_type == STT_FUNC && sym->type.ref) { 394 Sym *ref = sym->type.ref; 395 if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) { 396 sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE); 397 name = buf1; 398 other |= ST_PE_STDCALL; 399 can_add_underscore = 0; 400 } 401 } 402 #endif 403 if (tcc_state->leading_underscore && can_add_underscore) { 404 buf1[0] = '_'; 405 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); 406 name = buf1; 407 } 408 if (sym->asm_label) 409 name = get_tok_str(sym->asm_label, NULL); 410 info = ELFW(ST_INFO)(sym_bind, sym_type); 411 sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name); 412 } else { 413 esym = elfsym(sym); 414 esym->st_value = value; 415 esym->st_size = size; 416 esym->st_shndx = sh_num; 417 } 418 update_storage(sym); 419 } 420 421 ST_FUNC void put_extern_sym(Sym *sym, Section *section, 422 addr_t value, unsigned long size) 423 { 424 int sh_num = section ? section->sh_num : SHN_UNDEF; 425 put_extern_sym2(sym, sh_num, value, size, 1); 426 } 427 428 /* add a new relocation entry to symbol 'sym' in section 's' */ 429 ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, 430 addr_t addend) 431 { 432 int c = 0; 433 434 if (nocode_wanted && s == cur_text_section) 435 return; 436 437 if (sym) { 438 if (0 == sym->c) 439 put_extern_sym(sym, NULL, 0, 0); 440 c = sym->c; 441 } 442 443 /* now we can add ELF relocation info */ 444 put_elf_reloca(symtab_section, s, offset, type, c, addend); 445 } 446 447 #if PTR_SIZE == 4 448 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type) 449 { 450 greloca(s, sym, offset, type, 0); 451 } 452 #endif 108 453 109 454 /* ------------------------------------------------------------------------- */ … … 131 476 { 132 477 Sym *sym; 478 #ifndef SYM_DEBUG 133 479 sym = sym_free_first; 134 480 if (!sym) … … 136 482 sym_free_first = sym->next; 137 483 return sym; 484 #else 485 sym = tcc_malloc(sizeof(Sym)); 486 return sym; 487 #endif 138 488 } 139 489 140 490 ST_INLN void sym_free(Sym *sym) 141 491 { 492 #ifndef SYM_DEBUG 142 493 sym->next = sym_free_first; 143 tcc_free(sym->asm_label);144 494 sym_free_first = sym; 495 #else 496 tcc_free(sym); 497 #endif 145 498 } 146 499 147 500 /* push, without hashing */ 148 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, longc)501 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c) 149 502 { 150 503 Sym *s; 151 if (ps == &local_stack) { 152 for (s = *ps; s && s != scope_stack_bottom; s = s->prev) 153 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v) 154 tcc_error("incompatible types for redefinition of '%s'", 155 get_tok_str(v, NULL)); 156 } 157 s = *ps; 504 158 505 s = sym_malloc(); 159 s->asm_label = NULL;506 memset(s, 0, sizeof *s); 160 507 s->v = v; 161 508 s->type.t = t; 162 s->type.ref = NULL;163 #ifdef _WIN64164 s->d = NULL;165 #endif166 509 s->c = c; 167 s->next = NULL;168 510 /* add in stack */ 169 511 s->prev = *ps; … … 179 521 if (s->v == v) 180 522 return s; 523 else if (s->v == -1) 524 return NULL; 181 525 s = s->prev; 182 526 } … … 226 570 s->prev_tok = *ps; 227 571 *ps = s; 572 s->sym_scope = local_scope; 573 if (s->prev_tok && s->prev_tok->sym_scope == s->sym_scope) 574 tcc_error("redeclaration of '%s'", 575 get_tok_str(v & ~SYM_STRUCT, NULL)); 228 576 } 229 577 return s; … … 240 588 /* modify the top most local identifier, so that 241 589 sym_identifier will point to 's' when popped */ 242 while (*ps != NULL )590 while (*ps != NULL && (*ps)->sym_scope) 243 591 ps = &(*ps)->prev_tok; 244 s->prev_tok = NULL;592 s->prev_tok = *ps; 245 593 *ps = s; 246 594 } … … 248 596 } 249 597 250 /* pop symbols until top reaches 'b' */ 251 ST_FUNC void sym_pop(Sym **ptop, Sym *b) 598 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really 599 pop them yet from the list, but do remove them from the token array. */ 600 ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep) 252 601 { 253 602 Sym *s, *ss, **ps; … … 269 618 *ps = s->prev_tok; 270 619 } 271 sym_free(s); 620 if (!keep) 621 sym_free(s); 272 622 s = ss; 273 623 } 274 *ptop = b; 275 } 276 277 static void weaken_symbol(Sym *sym) 278 { 279 sym->type.t |= VT_WEAK; 280 if (sym->c > 0) { 281 int esym_type; 282 ElfW(Sym) *esym; 283 284 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; 285 esym_type = ELFW(ST_TYPE)(esym->st_info); 286 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type); 287 } 624 if (!keep) 625 *ptop = b; 288 626 } 289 627 290 628 /* ------------------------------------------------------------------------- */ 291 629 292 ST_FUNC void swap(int *p, int *q)293 {294 int t;295 t = *p;296 *p = *q;297 *q = t;298 }299 300 630 static void vsetc(CType *type, int r, CValue *vc) 301 631 { … … 303 633 304 634 if (vtop >= vstack + (VSTACK_SIZE - 1)) 305 tcc_error("memory full ");635 tcc_error("memory full (vstack)"); 306 636 /* cannot let cpu flags if other instruction are generated. Also 307 637 avoid leaving VT_JMP anywhere except on the top of the stack 308 because it would complicate the code generator. */ 309 if (vtop >= vstack) { 638 because it would complicate the code generator. 639 640 Don't do this when nocode_wanted. vtop might come from 641 !nocode_wanted regions (see 88_codeopt.c) and transforming 642 it to a register without actually generating code is wrong 643 as their value might still be used for real. All values 644 we push under nocode_wanted will eventually be popped 645 again, so that the VT_CMP/VT_JMP value will be in vtop 646 when code is unsuppressed again. 647 648 Same logic below in vswap(); */ 649 if (vtop >= vstack && !nocode_wanted) { 310 650 v = vtop->r & VT_VALMASK; 311 651 if (v == VT_CMP || (v & ~1) == VT_JMP) 312 652 gv(RC_INT); 313 653 } 654 314 655 vtop++; 315 656 vtop->type = *type; … … 317 658 vtop->r2 = VT_CONST; 318 659 vtop->c = *vc; 660 vtop->sym = NULL; 661 } 662 663 ST_FUNC void vswap(void) 664 { 665 SValue tmp; 666 /* cannot vswap cpu flags. See comment at vsetc() above */ 667 if (vtop >= vstack && !nocode_wanted) { 668 int v = vtop->r & VT_VALMASK; 669 if (v == VT_CMP || (v & ~1) == VT_JMP) 670 gv(RC_INT); 671 } 672 tmp = vtop[0]; 673 vtop[0] = vtop[-1]; 674 vtop[-1] = tmp; 675 } 676 677 /* pop stack value */ 678 ST_FUNC void vpop(void) 679 { 680 int v; 681 v = vtop->r & VT_VALMASK; 682 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) 683 /* for x86, we need to pop the FP stack */ 684 if (v == TREG_ST0) { 685 o(0xd8dd); /* fstp %st(0) */ 686 } else 687 #endif 688 if (v == VT_JMP || v == VT_JMPI) { 689 /* need to put correct jump if && or || without test */ 690 gsym(vtop->c.i); 691 } 692 vtop--; 319 693 } 320 694 321 695 /* push constant of type "type" with useless value */ 322 void vpush(CType *type) 323 { 324 CValue cval; 325 vsetc(type, VT_CONST, &cval); 696 ST_FUNC void vpush(CType *type) 697 { 698 vset(type, VT_CONST, 0); 326 699 } 327 700 … … 335 708 336 709 /* push a pointer sized constant */ 337 static void vpushs( long longv)710 static void vpushs(addr_t v) 338 711 { 339 712 CValue cval; 340 if (PTR_SIZE == 4) 341 cval.i = (int)v; 342 else 343 cval.ull = v; 713 cval.i = v; 344 714 vsetc(&size_type, VT_CONST, &cval); 345 715 } 346 716 347 717 /* push arbitrary 64bit constant */ 348 void vpush64(int ty, unsigned long long v)718 ST_FUNC void vpush64(int ty, unsigned long long v) 349 719 { 350 720 CValue cval; … … 352 722 ctype.t = ty; 353 723 ctype.ref = NULL; 354 cval. ull= v;724 cval.i = v; 355 725 vsetc(&ctype, VT_CONST, &cval); 356 726 } … … 360 730 { 361 731 vpush64(VT_LLONG, v); 732 } 733 734 ST_FUNC void vset(CType *type, int r, int v) 735 { 736 CValue cval; 737 738 cval.i = v; 739 vsetc(type, r, &cval); 740 } 741 742 static void vseti(int r, int v) 743 { 744 CType type; 745 type.t = VT_INT; 746 type.ref = NULL; 747 vset(&type, r, v); 748 } 749 750 ST_FUNC void vpushv(SValue *v) 751 { 752 if (vtop >= vstack + (VSTACK_SIZE - 1)) 753 tcc_error("memory full (vstack)"); 754 vtop++; 755 *vtop = *v; 756 } 757 758 static void vdup(void) 759 { 760 vpushv(vtop); 761 } 762 763 /* rotate n first stack elements to the bottom 764 I1 ... In -> I2 ... In I1 [top is right] 765 */ 766 ST_FUNC void vrotb(int n) 767 { 768 int i; 769 SValue tmp; 770 771 tmp = vtop[-n + 1]; 772 for(i=-n+1;i!=0;i++) 773 vtop[i] = vtop[i+1]; 774 vtop[0] = tmp; 775 } 776 777 /* rotate the n elements before entry e towards the top 778 I1 ... In ... -> In I1 ... I(n-1) ... [top is right] 779 */ 780 ST_FUNC void vrote(SValue *e, int n) 781 { 782 int i; 783 SValue tmp; 784 785 tmp = *e; 786 for(i = 0;i < n - 1; i++) 787 e[-i] = e[-i - 1]; 788 e[-n + 1] = tmp; 789 } 790 791 /* rotate n first stack elements to the top 792 I1 ... In -> In I1 ... I(n-1) [top is right] 793 */ 794 ST_FUNC void vrott(int n) 795 { 796 vrote(vtop, n); 797 } 798 799 /* push a symbol value of TYPE */ 800 static inline void vpushsym(CType *type, Sym *sym) 801 { 802 CValue cval; 803 cval.i = 0; 804 vsetc(type, VT_CONST | VT_SYM, &cval); 805 vtop->sym = sym; 362 806 } 363 807 … … 379 823 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size) 380 824 { 381 CValue cval; 382 383 cval.ul = 0; 384 vsetc(type, VT_CONST | VT_SYM, &cval); 385 vtop->sym = get_sym_ref(type, sec, offset, size); 825 vpushsym(type, get_sym_ref(type, sec, offset, size)); 386 826 } 387 827 … … 397 837 s->type.ref = type->ref; 398 838 s->r = r | VT_CONST | VT_SYM; 839 } else if (IS_ASM_SYM(s)) { 840 s->type.t = type->t | (s->type.t & VT_EXTERN); 841 s->type.ref = type->ref; 842 update_storage(s); 399 843 } 400 844 return s; 401 845 } 402 846 403 /* define a new external reference to a symbol 'v' with alternate asm 404 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there 405 is no alternate name (most cases) */ 406 static Sym *external_sym(int v, CType *type, int r, char *asm_label) 847 /* Merge some type attributes. */ 848 static void patch_type(Sym *sym, CType *type) 849 { 850 if (!(type->t & VT_EXTERN)) { 851 if (!(sym->type.t & VT_EXTERN)) 852 tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL)); 853 sym->type.t &= ~VT_EXTERN; 854 } 855 856 if (IS_ASM_SYM(sym)) { 857 /* stay static if both are static */ 858 sym->type.t = type->t & (sym->type.t | ~VT_STATIC); 859 sym->type.ref = type->ref; 860 } 861 862 if (!is_compatible_types(&sym->type, type)) { 863 tcc_error("incompatible types for redefinition of '%s'", 864 get_tok_str(sym->v, NULL)); 865 866 } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) { 867 int static_proto = sym->type.t & VT_STATIC; 868 /* warn if static follows non-static function declaration */ 869 if ((type->t & VT_STATIC) && !static_proto && !(type->t & VT_INLINE)) 870 tcc_warning("static storage ignored for redefinition of '%s'", 871 get_tok_str(sym->v, NULL)); 872 873 if (0 == (type->t & VT_EXTERN)) { 874 /* put complete type, use static from prototype */ 875 sym->type.t = (type->t & ~VT_STATIC) | static_proto; 876 if (type->t & VT_INLINE) 877 sym->type.t = type->t; 878 sym->type.ref = type->ref; 879 } 880 881 } else { 882 if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) { 883 /* set array size if it was omitted in extern declaration */ 884 if (sym->type.ref->c < 0) 885 sym->type.ref->c = type->ref->c; 886 else if (sym->type.ref->c != type->ref->c) 887 tcc_error("conflicting type for '%s'", get_tok_str(sym->v, NULL)); 888 } 889 if ((type->t ^ sym->type.t) & VT_STATIC) 890 tcc_warning("storage mismatch for redefinition of '%s'", 891 get_tok_str(sym->v, NULL)); 892 } 893 } 894 895 896 /* Merge some storage attributes. */ 897 static void patch_storage(Sym *sym, AttributeDef *ad, CType *type) 898 { 899 if (type) 900 patch_type(sym, type); 901 902 #ifdef TCC_TARGET_PE 903 if (sym->a.dllimport != ad->a.dllimport) 904 tcc_error("incompatible dll linkage for redefinition of '%s'", 905 get_tok_str(sym->v, NULL)); 906 sym->a.dllexport |= ad->a.dllexport; 907 #endif 908 sym->a.weak |= ad->a.weak; 909 if (ad->a.visibility) { 910 int vis = sym->a.visibility; 911 int vis2 = ad->a.visibility; 912 if (vis == STV_DEFAULT) 913 vis = vis2; 914 else if (vis2 != STV_DEFAULT) 915 vis = (vis < vis2) ? vis : vis2; 916 sym->a.visibility = vis; 917 } 918 if (ad->a.aligned) 919 sym->a.aligned = ad->a.aligned; 920 if (ad->asm_label) 921 sym->asm_label = ad->asm_label; 922 update_storage(sym); 923 } 924 925 /* define a new external reference to a symbol 'v' */ 926 static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad) 407 927 { 408 928 Sym *s; 409 410 929 s = sym_find(v); 411 930 if (!s) { 412 931 /* push forward reference */ 413 932 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); 414 s->asm_label = asm_label;415 933 s->type.t |= VT_EXTERN; 416 } else if (s->type.ref == func_old_type.ref) { 417 s->type.ref = type->ref; 418 s->r = r | VT_CONST | VT_SYM; 419 s->type.t |= VT_EXTERN; 420 } else if (!is_compatible_types(&s->type, type)) { 421 tcc_error("incompatible types for redefinition of '%s'", 422 get_tok_str(v, NULL)); 934 s->a = ad->a; 935 s->sym_scope = 0; 936 } else { 937 if (s->type.ref == func_old_type.ref) { 938 s->type.ref = type->ref; 939 s->r = r | VT_CONST | VT_SYM; 940 s->type.t |= VT_EXTERN; 941 } 942 patch_storage(s, ad, type); 423 943 } 424 944 return s; … … 428 948 ST_FUNC void vpush_global_sym(CType *type, int v) 429 949 { 430 Sym *sym; 431 CValue cval; 432 433 sym = external_global_sym(v, type, 0); 434 cval.ul = 0; 435 vsetc(type, VT_CONST | VT_SYM, &cval); 436 vtop->sym = sym; 437 } 438 439 ST_FUNC void vset(CType *type, int r, int v) 440 { 441 CValue cval; 442 443 cval.i = v; 444 vsetc(type, r, &cval); 445 } 446 447 static void vseti(int r, int v) 448 { 449 CType type; 450 type.t = VT_INT; 451 type.ref = 0; 452 vset(&type, r, v); 453 } 454 455 ST_FUNC void vswap(void) 456 { 457 SValue tmp; 458 /* cannot let cpu flags if other instruction are generated. Also 459 avoid leaving VT_JMP anywhere except on the top of the stack 460 because it would complicate the code generator. */ 461 if (vtop >= vstack) { 462 int v = vtop->r & VT_VALMASK; 463 if (v == VT_CMP || (v & ~1) == VT_JMP) 464 gv(RC_INT); 465 } 466 tmp = vtop[0]; 467 vtop[0] = vtop[-1]; 468 vtop[-1] = tmp; 469 470 /* XXX: +2% overall speed possible with optimized memswap 471 * 472 * memswap(&vtop[0], &vtop[1], sizeof *vtop); 473 */ 474 } 475 476 ST_FUNC void vpushv(SValue *v) 477 { 478 if (vtop >= vstack + (VSTACK_SIZE - 1)) 479 tcc_error("memory full"); 480 vtop++; 481 *vtop = *v; 482 } 483 484 static void vdup(void) 485 { 486 vpushv(vtop); 950 vpushsym(type, external_global_sym(v, type, 0)); 951 } 952 953 /* save registers up to (vtop - n) stack entry */ 954 ST_FUNC void save_regs(int n) 955 { 956 SValue *p, *p1; 957 for(p = vstack, p1 = vtop - n; p <= p1; p++) 958 save_reg(p->r); 487 959 } 488 960 … … 490 962 ST_FUNC void save_reg(int r) 491 963 { 964 save_reg_upstack(r, 0); 965 } 966 967 /* save r to the memory stack, and mark it as being free, 968 if seen up to (vtop - n) stack entry */ 969 ST_FUNC void save_reg_upstack(int r, int n) 970 { 492 971 int l, saved, size, align; 493 SValue *p, sv;972 SValue *p, *p1, sv; 494 973 CType *type; 974 975 if ((r &= VT_VALMASK) >= VT_CONST) 976 return; 977 if (nocode_wanted) 978 return; 495 979 496 980 /* modify all stack values */ 497 981 saved = 0; 498 982 l = 0; 499 for(p =vstack;p<=vtop;p++) {983 for(p = vstack, p1 = vtop - n; p <= p1; p++) { 500 984 if ((p->r & VT_VALMASK) == r || 501 985 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) { … … 508 992 if ((p->r & VT_LVAL) || 509 993 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG)) 510 #if def TCC_TARGET_X86_64994 #if PTR_SIZE == 8 511 995 type = &char_pointer_type; 512 996 #else … … 517 1001 sv.type.t = type->t; 518 1002 sv.r = VT_LOCAL | VT_LVAL; 519 sv.c. ul= loc;1003 sv.c.i = loc; 520 1004 store(r, &sv); 521 1005 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) … … 525 1009 } 526 1010 #endif 527 #if ndef TCC_TARGET_X86_641011 #if PTR_SIZE == 4 528 1012 /* special long long case */ 529 1013 if ((type->t & VT_BTYPE) == VT_LLONG) { 530 sv.c. ul+= 4;1014 sv.c.i += 4; 531 1015 store(p->r2, &sv); 532 1016 } … … 539 1023 /* also clear the bounded flag because the 540 1024 relocation address of the function was stored in 541 p->c. ul*/1025 p->c.i */ 542 1026 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL; 543 1027 } else { … … 545 1029 } 546 1030 p->r2 = VT_CONST; 547 p->c. ul= l;1031 p->c.i = l; 548 1032 } 549 1033 } … … 584 1068 for(r=0;r<NB_REGS;r++) { 585 1069 if (reg_classes[r] & rc) { 1070 if (nocode_wanted) 1071 return r; 586 1072 for(p=vstack;p<=vtop;p++) { 587 1073 if ((p->r & VT_VALMASK) == r || … … 613 1099 } 614 1100 615 /* save registers up to (vtop - n) stack entry */ 616 ST_FUNC void save_regs(int n) 617 { 618 int r; 619 SValue *p, *p1; 620 p1 = vtop - n; 621 for(p = vstack;p <= p1; p++) { 622 r = p->r & VT_VALMASK; 623 if (r < VT_CONST) { 624 save_reg(r); 625 } 626 } 627 } 628 629 /* move register 's' to 'r', and flush previous value of r to memory 1101 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory 630 1102 if needed */ 631 static void move_reg(int r, int s )1103 static void move_reg(int r, int s, int t) 632 1104 { 633 1105 SValue sv; … … 635 1107 if (r != s) { 636 1108 save_reg(r); 637 sv.type.t = VT_INT; 1109 sv.type.t = t; 1110 sv.type.ref = NULL; 638 1111 sv.r = s; 639 sv.c. ul= 0;1112 sv.c.i = 0; 640 1113 load(r, &sv); 641 1114 } … … 643 1116 644 1117 /* get address of vtop (vtop MUST BE an lvalue) */ 645 static void gaddrof(void) 646 { 647 if (vtop->r & VT_REF) 648 gv(RC_INT); 1118 ST_FUNC void gaddrof(void) 1119 { 649 1120 vtop->r &= ~VT_LVAL; 650 1121 /* tricky: if saved lvalue, then we can go back to lvalue */ … … 670 1141 /* must save type because we must set it to int to get pointer */ 671 1142 type1 = vtop->type; 672 vtop->type.t = VT_ INT;1143 vtop->type.t = VT_PTR; 673 1144 gaddrof(); 674 1145 vpushi(0); … … 683 1154 #endif 684 1155 1156 static void incr_bf_adr(int o) 1157 { 1158 vtop->type = char_pointer_type; 1159 gaddrof(); 1160 vpushi(o); 1161 gen_op('+'); 1162 vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN)) 1163 | (VT_BYTE|VT_UNSIGNED); 1164 vtop->r = (vtop->r & ~VT_LVAL_TYPE) 1165 | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL); 1166 } 1167 1168 /* single-byte load mode for packed or otherwise unaligned bitfields */ 1169 static void load_packed_bf(CType *type, int bit_pos, int bit_size) 1170 { 1171 int n, o, bits; 1172 save_reg_upstack(vtop->r, 1); 1173 vpush64(type->t & VT_BTYPE, 0); // B X 1174 bits = 0, o = bit_pos >> 3, bit_pos &= 7; 1175 do { 1176 vswap(); // X B 1177 incr_bf_adr(o); 1178 vdup(); // X B B 1179 n = 8 - bit_pos; 1180 if (n > bit_size) 1181 n = bit_size; 1182 if (bit_pos) 1183 vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y 1184 if (n < 8) 1185 vpushi((1 << n) - 1), gen_op('&'); 1186 gen_cast(type); 1187 if (bits) 1188 vpushi(bits), gen_op(TOK_SHL); 1189 vrotb(3); // B Y X 1190 gen_op('|'); // B X 1191 bits += n, bit_size -= n, o = 1; 1192 } while (bit_size); 1193 vswap(), vpop(); 1194 if (!(type->t & VT_UNSIGNED)) { 1195 n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits; 1196 vpushi(n), gen_op(TOK_SHL); 1197 vpushi(n), gen_op(TOK_SAR); 1198 } 1199 } 1200 1201 /* single-byte store mode for packed or otherwise unaligned bitfields */ 1202 static void store_packed_bf(int bit_pos, int bit_size) 1203 { 1204 int bits, n, o, m, c; 1205 1206 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 1207 vswap(); // X B 1208 save_reg_upstack(vtop->r, 1); 1209 bits = 0, o = bit_pos >> 3, bit_pos &= 7; 1210 do { 1211 incr_bf_adr(o); // X B 1212 vswap(); //B X 1213 c ? vdup() : gv_dup(); // B V X 1214 vrott(3); // X B V 1215 if (bits) 1216 vpushi(bits), gen_op(TOK_SHR); 1217 if (bit_pos) 1218 vpushi(bit_pos), gen_op(TOK_SHL); 1219 n = 8 - bit_pos; 1220 if (n > bit_size) 1221 n = bit_size; 1222 if (n < 8) { 1223 m = ((1 << n) - 1) << bit_pos; 1224 vpushi(m), gen_op('&'); // X B V1 1225 vpushv(vtop-1); // X B V1 B 1226 vpushi(m & 0x80 ? ~m & 0x7f : ~m); 1227 gen_op('&'); // X B V1 B1 1228 gen_op('|'); // X B V2 1229 } 1230 vdup(), vtop[-1] = vtop[-2]; // X B B V2 1231 vstore(), vpop(); // X B 1232 bits += n, bit_size -= n, bit_pos = 0, o = 1; 1233 } while (bit_size); 1234 vpop(), vpop(); 1235 } 1236 1237 static int adjust_bf(SValue *sv, int bit_pos, int bit_size) 1238 { 1239 int t; 1240 if (0 == sv->type.ref) 1241 return 0; 1242 t = sv->type.ref->auxtype; 1243 if (t != -1 && t != VT_STRUCT) { 1244 sv->type.t = (sv->type.t & ~VT_BTYPE) | t; 1245 sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t); 1246 } 1247 return t; 1248 } 1249 685 1250 /* store vtop a register belonging to class 'rc'. lvalues are 686 1251 converted to values. Cannot be used if cannot be converted to … … 688 1253 ST_FUNC int gv(int rc) 689 1254 { 690 int r, bit_pos, bit_size, size, align, i; 691 #ifndef TCC_TARGET_X86_64 692 int rc2; 693 #endif 1255 int r, bit_pos, bit_size, size, align, rc2; 694 1256 695 1257 /* NOTE: get_reg can modify vstack[] */ 696 1258 if (vtop->type.t & VT_BITFIELD) { 697 1259 CType type; 698 int bits = 32; 699 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;700 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;1260 1261 bit_pos = BIT_POS(vtop->type.t); 1262 bit_size = BIT_SIZE(vtop->type.t); 701 1263 /* remove bit field info to avoid loops */ 702 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); 703 /* cast to int to propagate signedness in following ops */ 704 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { 705 type.t = VT_LLONG; 706 bits = 64; 707 } else 708 type.t = VT_INT; 709 if((vtop->type.t & VT_UNSIGNED) || 710 (vtop->type.t & VT_BTYPE) == VT_BOOL) 1264 vtop->type.t &= ~VT_STRUCT_MASK; 1265 1266 type.ref = NULL; 1267 type.t = vtop->type.t & VT_UNSIGNED; 1268 if ((vtop->type.t & VT_BTYPE) == VT_BOOL) 711 1269 type.t |= VT_UNSIGNED; 712 gen_cast(&type); 713 /* generate shifts */ 714 vpushi(bits - (bit_pos + bit_size)); 715 gen_op(TOK_SHL); 716 vpushi(bits - bit_size); 717 /* NOTE: transformed to SHR if unsigned */ 718 gen_op(TOK_SAR); 1270 1271 r = adjust_bf(vtop, bit_pos, bit_size); 1272 1273 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) 1274 type.t |= VT_LLONG; 1275 else 1276 type.t |= VT_INT; 1277 1278 if (r == VT_STRUCT) { 1279 load_packed_bf(&type, bit_pos, bit_size); 1280 } else { 1281 int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32; 1282 /* cast to int to propagate signedness in following ops */ 1283 gen_cast(&type); 1284 /* generate shifts */ 1285 vpushi(bits - (bit_pos + bit_size)); 1286 gen_op(TOK_SHL); 1287 vpushi(bits - bit_size); 1288 /* NOTE: transformed to SHR if unsigned */ 1289 gen_op(TOK_SAR); 1290 } 719 1291 r = gv(rc); 720 1292 } else { 721 1293 if (is_float(vtop->type.t) && 722 1294 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { 723 Sym *sym;724 int *ptr;725 1295 unsigned long offset; 726 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)727 CValue check;728 #endif729 730 /* XXX: unify with initializers handling ? */731 1296 /* CPUs usually cannot use float constants, so we store them 732 1297 generically in data segment */ 733 1298 size = type_size(&vtop->type, &align); 734 offset = (data_section->data_offset + align - 1) & -align; 735 data_section->data_offset = offset; 736 /* XXX: not portable yet */ 737 #if defined(__i386__) || defined(__x86_64__) 738 /* Zero pad x87 tenbyte long doubles */ 739 if (size == LDOUBLE_SIZE) { 740 vtop->c.tab[2] &= 0xffff; 741 #if LDOUBLE_SIZE == 16 742 vtop->c.tab[3] = 0; 743 #endif 744 } 745 #endif 746 ptr = section_ptr_add(data_section, size); 747 size = size >> 2; 748 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) 749 check.d = 1; 750 if(check.tab[0]) 751 for(i=0;i<size;i++) 752 ptr[i] = vtop->c.tab[size-1-i]; 753 else 754 #endif 755 for(i=0;i<size;i++) 756 ptr[i] = vtop->c.tab[i]; 757 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2); 758 vtop->r |= VT_LVAL | VT_SYM; 759 vtop->sym = sym; 760 vtop->c.ul = 0; 1299 if (NODATA_WANTED) 1300 size = 0, align = 1; 1301 offset = section_add(data_section, size, align); 1302 vpush_ref(&vtop->type, data_section, offset, size); 1303 vswap(); 1304 init_putv(&vtop->type, data_section, offset); 1305 vtop->r |= VT_LVAL; 761 1306 } 762 1307 #ifdef CONFIG_TCC_BCHECK … … 766 1311 767 1312 r = vtop->r & VT_VALMASK; 768 #ifndef TCC_TARGET_X86_64 769 rc2 = RC_INT; 1313 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT; 1314 #ifndef TCC_TARGET_ARM64 770 1315 if (rc == RC_IRET) 771 1316 rc2 = RC_LRET; 1317 #ifdef TCC_TARGET_X86_64 1318 else if (rc == RC_FRET) 1319 rc2 = RC_QRET; 1320 #endif 772 1321 #endif 773 1322 /* need to reload if: … … 778 1327 || (vtop->r & VT_LVAL) 779 1328 || !(reg_classes[r] & rc) 780 #ifndef TCC_TARGET_X86_64 1329 #if PTR_SIZE == 8 1330 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2)) 1331 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2)) 1332 #else 781 1333 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2)) 782 1334 #endif … … 784 1336 { 785 1337 r = get_reg(rc); 786 #ifndef TCC_TARGET_X86_64 1338 #if PTR_SIZE == 8 1339 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) { 1340 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE; 1341 #else 787 1342 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { 788 int r2;1343 int addr_type = VT_INT, load_size = 4, load_type = VT_INT; 789 1344 unsigned long long ll; 1345 #endif 1346 int r2, original_type; 1347 original_type = vtop->type.t; 790 1348 /* two register type load : expand to two words 791 1349 temporarily */ 1350 #if PTR_SIZE == 4 792 1351 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { 793 1352 /* load constant */ 794 ll = vtop->c. ull;795 vtop->c. ui = ll; /* first word */1353 ll = vtop->c.i; 1354 vtop->c.i = ll; /* first word */ 796 1355 load(r, vtop); 797 1356 vtop->r = r; /* save register value */ 798 1357 vpushi(ll >> 32); /* second word */ 799 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ 800 (vtop->r & VT_LVAL)) { 1358 } else 1359 #endif 1360 if (vtop->r & VT_LVAL) { 801 1361 /* We do not want to modifier the long long 802 1362 pointer here, so the safest (and less 803 1363 efficient) is to save all the other registers 804 1364 in the stack. XXX: totally inefficient. */ 1365 #if 0 805 1366 save_regs(1); 1367 #else 1368 /* lvalue_save: save only if used further down the stack */ 1369 save_reg_upstack(vtop->r, 1); 1370 #endif 806 1371 /* load from memory */ 1372 vtop->type.t = load_type; 807 1373 load(r, vtop); 808 1374 vdup(); 809 1375 vtop[-1].r = r; /* save register value */ 810 1376 /* increment pointer to get second word */ 811 vtop->type.t = VT_INT;1377 vtop->type.t = addr_type; 812 1378 gaddrof(); 813 vpushi( 4);1379 vpushi(load_size); 814 1380 gen_op('+'); 815 1381 vtop->r |= VT_LVAL; 1382 vtop->type.t = load_type; 816 1383 } else { 817 1384 /* move registers */ … … 828 1395 /* write second register */ 829 1396 vtop->r2 = r2; 830 } else 831 #endif 832 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) { 1397 vtop->type.t = original_type; 1398 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) { 833 1399 int t1, t; 834 1400 /* lvalue of scalar type : need to use lvalue type … … 894 1460 } 895 1461 1462 #ifndef TCC_TARGET_ARM64 896 1463 /* wrapper around RC_FRET to return a register by type */ 897 1464 static int rc_fret(int t) … … 904 1471 return RC_FRET; 905 1472 } 1473 #endif 906 1474 907 1475 /* wrapper around REG_FRET to return a register by type */ … … 916 1484 } 917 1485 918 /* expand long long on stack in two int registers */ 1486 #if PTR_SIZE == 4 1487 /* expand 64bit on stack in two ints */ 919 1488 static void lexpand(void) 920 1489 { 921 int u; 922 923 u = vtop->type.t & VT_UNSIGNED; 924 gv(RC_INT); 925 vdup(); 926 vtop[0].r = vtop[-1].r2; 927 vtop[0].r2 = VT_CONST; 928 vtop[-1].r2 = VT_CONST; 929 vtop[0].type.t = VT_INT | u; 930 vtop[-1].type.t = VT_INT | u; 931 } 1490 int u, v; 1491 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); 1492 v = vtop->r & (VT_VALMASK | VT_LVAL); 1493 if (v == VT_CONST) { 1494 vdup(); 1495 vtop[0].c.i >>= 32; 1496 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) { 1497 vdup(); 1498 vtop[0].c.i += 4; 1499 } else { 1500 gv(RC_INT); 1501 vdup(); 1502 vtop[0].r = vtop[-1].r2; 1503 vtop[0].r2 = vtop[-1].r2 = VT_CONST; 1504 } 1505 vtop[0].type.t = vtop[-1].type.t = VT_INT | u; 1506 } 1507 #endif 932 1508 933 1509 #ifdef TCC_TARGET_ARM … … 937 1513 int u,v; 938 1514 939 u = vtop->type.t & VT_UNSIGNED;1515 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); 940 1516 vdup(); 941 1517 vtop->r2 = VT_CONST; … … 943 1519 v=vtop[-1].r & (VT_VALMASK | VT_LVAL); 944 1520 if (v == VT_CONST) { 945 vtop[-1].c. ui = vtop->c.ull;946 vtop->c. ui = vtop->c.ull>> 32;1521 vtop[-1].c.i = vtop->c.i; 1522 vtop->c.i = vtop->c.i >> 32; 947 1523 vtop->r = VT_CONST; 948 1524 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) { 949 vtop->c. ui += 4;1525 vtop->c.i += 4; 950 1526 vtop->r = vtop[-1].r; 951 1527 } else if (v > VT_CONST) { … … 959 1535 #endif 960 1536 1537 #if PTR_SIZE == 4 961 1538 /* build a long long from two ints */ 962 1539 static void lbuild(int t) … … 967 1544 vpop(); 968 1545 } 969 970 /* rotate n first stack elements to the bottom 971 I1 ... In -> I2 ... In I1 [top is right] 972 */ 973 ST_FUNC void vrotb(int n) 974 { 975 int i; 976 SValue tmp; 977 978 tmp = vtop[-n + 1]; 979 for(i=-n+1;i!=0;i++) 980 vtop[i] = vtop[i+1]; 981 vtop[0] = tmp; 982 } 983 984 /* rotate the n elements before entry e towards the top 985 I1 ... In ... -> In I1 ... I(n-1) ... [top is right] 986 */ 987 ST_FUNC void vrote(SValue *e, int n) 988 { 989 int i; 990 SValue tmp; 991 992 tmp = *e; 993 for(i = 0;i < n - 1; i++) 994 e[-i] = e[-i - 1]; 995 e[-n + 1] = tmp; 996 } 997 998 /* rotate n first stack elements to the top 999 I1 ... In -> In I1 ... I(n-1) [top is right] 1000 */ 1001 ST_FUNC void vrott(int n) 1002 { 1003 vrote(vtop, n); 1004 } 1005 1006 /* pop stack value */ 1007 ST_FUNC void vpop(void) 1008 { 1009 int v; 1010 v = vtop->r & VT_VALMASK; 1011 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) 1012 /* for x86, we need to pop the FP stack */ 1013 if (v == TREG_ST0 && !nocode_wanted) { 1014 o(0xd8dd); /* fstp %st(0) */ 1015 } else 1016 #endif 1017 if (v == VT_JMP || v == VT_JMPI) { 1018 /* need to put correct jump if && or || without test */ 1019 gsym(vtop->c.ul); 1020 } 1021 vtop--; 1022 } 1546 #endif 1023 1547 1024 1548 /* convert stack entry to register and duplicate its value in another … … 1030 1554 1031 1555 t = vtop->type.t; 1556 #if PTR_SIZE == 4 1032 1557 if ((t & VT_BTYPE) == VT_LLONG) { 1558 if (t & VT_BITFIELD) { 1559 gv(RC_INT); 1560 t = vtop->type.t; 1561 } 1033 1562 lexpand(); 1034 1563 gv_dup(); … … 1044 1573 lbuild(t); 1045 1574 vswap(); 1046 } else { 1575 } else 1576 #endif 1577 { 1047 1578 /* duplicate value */ 1048 1579 rc = RC_INT; … … 1060 1591 r1 = get_reg(rc); 1061 1592 sv.r = r; 1062 sv.c. ul= 0;1593 sv.c.i = 0; 1063 1594 load(r1, &sv); /* move r to r1 */ 1064 1595 vdup(); … … 1069 1600 } 1070 1601 1071 #ifndef TCC_TARGET_X86_64 1602 /* Generate value test 1603 * 1604 * Generate a test for any value (jump, comparison and integers) */ 1605 ST_FUNC int gvtst(int inv, int t) 1606 { 1607 int v = vtop->r & VT_VALMASK; 1608 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) { 1609 vpushi(0); 1610 gen_op(TOK_NE); 1611 } 1612 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { 1613 /* constant jmp optimization */ 1614 if ((vtop->c.i != 0) != inv) 1615 t = gjmp(t); 1616 vtop--; 1617 return t; 1618 } 1619 return gtst(inv, t); 1620 } 1621 1622 #if PTR_SIZE == 4 1072 1623 /* generate CPU independent (unsigned) long long operations */ 1073 1624 static void gen_opl(int op) … … 1112 1663 case '+': 1113 1664 case '-': 1665 //pv("gen_opl A",0,2); 1114 1666 t = vtop->type.t; 1115 1667 vswap(); … … 1126 1678 vswap(); 1127 1679 /* stack: H1 H2 L1 L2 */ 1680 //pv("gen_opl B",0,4); 1128 1681 if (op == '*') { 1129 1682 vpushv(vtop - 1); … … 1181 1734 /* constant: simpler */ 1182 1735 /* NOTE: all comments are for SHL. the other cases are 1183 done by swap ing words */1736 done by swapping words */ 1184 1737 vpop(); 1185 1738 if (op != TOK_SHL) … … 1266 1819 b = 0; 1267 1820 gen_op(op1); 1268 if (op1 != TOK_NE) { 1269 a = gtst(1, 0); 1270 } 1271 if (op != TOK_EQ) { 1272 /* generate non equal test */ 1273 /* XXX: NOT PORTABLE yet */ 1274 if (a == 0) { 1275 b = gtst(0, 0); 1276 } else { 1277 #if defined(TCC_TARGET_I386) 1278 b = psym(0x850f, 0); 1279 #elif defined(TCC_TARGET_ARM) 1280 b = ind; 1281 o(0x1A000000 | encbranch(ind, 0, 1)); 1282 #elif defined(TCC_TARGET_C67) 1283 tcc_error("not implemented"); 1284 #elif defined(TCC_TARGET_IL) 1285 tcc_error("not implemented"); 1286 #else 1287 #error not supported 1288 #endif 1821 if (op == TOK_NE) { 1822 b = gvtst(0, 0); 1823 } else { 1824 a = gvtst(1, 0); 1825 if (op != TOK_EQ) { 1826 /* generate non equal test */ 1827 vpushi(TOK_NE); 1828 vtop->r = VT_CMP; 1829 b = gvtst(0, 0); 1289 1830 } 1290 1831 } … … 1300 1841 op1 = TOK_UGE; 1301 1842 gen_op(op1); 1302 a = g tst(1, a);1843 a = gvtst(1, a); 1303 1844 gsym(b); 1304 1845 vseti(VT_JMPI, a); … … 1308 1849 #endif 1309 1850 1851 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b) 1852 { 1853 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b); 1854 return (a ^ b) >> 63 ? -x : x; 1855 } 1856 1857 static int gen_opic_lt(uint64_t a, uint64_t b) 1858 { 1859 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63); 1860 } 1861 1310 1862 /* handle integer constant optimizations and various machine 1311 1863 independent opt */ 1312 1864 static void gen_opic(int op) 1313 1865 { 1314 int c1, c2, t1, t2, n; 1315 SValue *v1, *v2; 1316 long long l1, l2; 1317 typedef unsigned long long U; 1318 1319 v1 = vtop - 1; 1320 v2 = vtop; 1321 t1 = v1->type.t & VT_BTYPE; 1322 t2 = v2->type.t & VT_BTYPE; 1323 1324 if (t1 == VT_LLONG) 1325 l1 = v1->c.ll; 1326 else if (v1->type.t & VT_UNSIGNED) 1327 l1 = v1->c.ui; 1328 else 1329 l1 = v1->c.i; 1330 1331 if (t2 == VT_LLONG) 1332 l2 = v2->c.ll; 1333 else if (v2->type.t & VT_UNSIGNED) 1334 l2 = v2->c.ui; 1335 else 1336 l2 = v2->c.i; 1337 1338 /* currently, we cannot do computations with forward symbols */ 1339 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 1340 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 1866 SValue *v1 = vtop - 1; 1867 SValue *v2 = vtop; 1868 int t1 = v1->type.t & VT_BTYPE; 1869 int t2 = v2->type.t & VT_BTYPE; 1870 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 1871 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 1872 uint64_t l1 = c1 ? v1->c.i : 0; 1873 uint64_t l2 = c2 ? v2->c.i : 0; 1874 int shm = (t1 == VT_LLONG) ? 63 : 31; 1875 1876 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR)) 1877 l1 = ((uint32_t)l1 | 1878 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000))); 1879 if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR)) 1880 l2 = ((uint32_t)l2 | 1881 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000))); 1882 1341 1883 if (c1 && c2) { 1342 1884 switch(op) { … … 1360 1902 } 1361 1903 switch(op) { 1362 default: l1 /= l2; break;1363 case '%': l1 %= l2; break;1364 case TOK_UDIV: l1 = (U)l1 / l2; break;1365 case TOK_UMOD: l1 = (U)l1 % l2; break;1904 default: l1 = gen_opic_sdiv(l1, l2); break; 1905 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break; 1906 case TOK_UDIV: l1 = l1 / l2; break; 1907 case TOK_UMOD: l1 = l1 % l2; break; 1366 1908 } 1367 1909 break; 1368 case TOK_SHL: l1 <<= l2; break; 1369 case TOK_SHR: l1 = (U)l1 >> l2; break; 1370 case TOK_SAR: l1 >>= l2; break; 1910 case TOK_SHL: l1 <<= (l2 & shm); break; 1911 case TOK_SHR: l1 >>= (l2 & shm); break; 1912 case TOK_SAR: 1913 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm); 1914 break; 1371 1915 /* tests */ 1372 case TOK_ULT: l1 = (U)l1 < (U)l2; break;1373 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;1916 case TOK_ULT: l1 = l1 < l2; break; 1917 case TOK_UGE: l1 = l1 >= l2; break; 1374 1918 case TOK_EQ: l1 = l1 == l2; break; 1375 1919 case TOK_NE: l1 = l1 != l2; break; 1376 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;1377 case TOK_UGT: l1 = (U)l1 > (U)l2; break;1378 case TOK_LT: l1 = l1 < l2; break;1379 case TOK_GE: l1 = l1 >= l2; break;1380 case TOK_LE: l1 = l1 <= l2; break;1381 case TOK_GT: l1 = l1 > l2; break;1920 case TOK_ULE: l1 = l1 <= l2; break; 1921 case TOK_UGT: l1 = l1 > l2; break; 1922 case TOK_LT: l1 = gen_opic_lt(l1, l2); break; 1923 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break; 1924 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break; 1925 case TOK_GT: l1 = gen_opic_lt(l2, l1); break; 1382 1926 /* logical */ 1383 1927 case TOK_LAND: l1 = l1 && l2; break; … … 1386 1930 goto general_case; 1387 1931 } 1388 v1->c.ll = l1; 1932 if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR)) 1933 l1 = ((uint32_t)l1 | 1934 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000))); 1935 v1->c.i = l1; 1389 1936 vtop--; 1390 1937 } else { … … 1396 1943 l2 = l1; //l = l1, l1 = l2, l2 = l; 1397 1944 } 1398 /* Filter out NOP operations like x*1, x-0, x&-1... */ 1399 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || 1400 op == TOK_PDIV) && 1401 l2 == 1) || 1402 ((op == '+' || op == '-' || op == '|' || op == '^' || 1403 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && 1404 l2 == 0) || 1405 (op == '&' && 1406 l2 == -1))) { 1407 /* nothing to do */ 1945 if (!const_wanted && 1946 c1 && ((l1 == 0 && 1947 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) || 1948 (l1 == -1 && op == TOK_SAR))) { 1949 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */ 1950 vtop--; 1951 } else if (!const_wanted && 1952 c2 && ((l2 == 0 && (op == '&' || op == '*')) || 1953 (op == '|' && 1954 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) || 1955 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) { 1956 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */ 1957 if (l2 == 1) 1958 vtop->c.i = 0; 1959 vswap(); 1960 vtop--; 1961 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || 1962 op == TOK_PDIV) && 1963 l2 == 1) || 1964 ((op == '+' || op == '-' || op == '|' || op == '^' || 1965 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && 1966 l2 == 0) || 1967 (op == '&' && 1968 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) { 1969 /* filter out NOP operations like x*1, x-0, x&-1... */ 1408 1970 vtop--; 1409 1971 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { 1410 1972 /* try to use shifts instead of muls or divs */ 1411 1973 if (l2 > 0 && (l2 & (l2 - 1)) == 0) { 1412 n = -1;1974 int n = -1; 1413 1975 while (l2) { 1414 1976 l2 >>= 1; 1415 1977 n++; 1416 1978 } 1417 vtop->c. ll= n;1979 vtop->c.i = n; 1418 1980 if (op == '*') 1419 1981 op = TOK_SHL; … … 1430 1992 if (op == '-') 1431 1993 l2 = -l2; 1994 l2 += vtop[-1].c.i; 1995 /* The backends can't always deal with addends to symbols 1996 larger than +-1<<31. Don't construct such. */ 1997 if ((int)l2 != l2) 1998 goto general_case; 1432 1999 vtop--; 1433 vtop->c. ll += l2;2000 vtop->c.i = l2; 1434 2001 } else { 1435 2002 general_case: 1436 if (!nocode_wanted) {1437 2003 /* call low level op generator */ 1438 if (t1 == VT_LLONG || t2 == VT_LLONG) 2004 if (t1 == VT_LLONG || t2 == VT_LLONG || 2005 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR))) 1439 2006 gen_opl(op); 1440 2007 else 1441 2008 gen_opi(op); 1442 } else {1443 vtop--;1444 }1445 2009 } 1446 2010 } … … 1452 2016 int c1, c2; 1453 2017 SValue *v1, *v2; 2018 #if defined _MSC_VER && defined _AMD64_ 2019 /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */ 2020 volatile 2021 #endif 1454 2022 long double f1, f2; 1455 2023 … … 1503 2071 } else { 1504 2072 general_case: 1505 if (!nocode_wanted) { 1506 gen_opf(op); 1507 } else { 1508 vtop--; 1509 } 2073 gen_opf(op); 1510 2074 } 1511 2075 } … … 1527 2091 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) 1528 2092 return 0; 1529 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) || 1530 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) || 1531 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0); 2093 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) || 2094 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) || 2095 ((p->type.t & VT_BTYPE) == VT_PTR && 2096 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0)); 1532 2097 } 1533 2098 … … 1538 2103 } 1539 2104 1540 /* check types for comparison or sub straction of pointers */2105 /* check types for comparison or subtraction of pointers */ 1541 2106 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) 1542 2107 { … … 1575 2140 tmp_type1 = *type1; 1576 2141 tmp_type2 = *type2; 1577 tmp_type1.t &= ~(VT_ UNSIGNED | VT_CONSTANT | VT_VOLATILE);1578 tmp_type2.t &= ~(VT_ UNSIGNED | VT_CONSTANT | VT_VOLATILE);2142 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); 2143 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); 1579 2144 if (!is_compatible_types(&tmp_type1, &tmp_type2)) { 1580 2145 /* gcc-like error if '-' is used */ … … 1592 2157 CType type1; 1593 2158 2159 redo: 1594 2160 t1 = vtop[-1].type.t; 1595 2161 t2 = vtop[0].type.t; … … 1597 2163 bt2 = t2 & VT_BTYPE; 1598 2164 1599 if (bt1 == VT_PTR || bt2 == VT_PTR) { 2165 if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { 2166 tcc_error("operation on a struct"); 2167 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { 2168 if (bt2 == VT_FUNC) { 2169 mk_pointer(&vtop->type); 2170 gaddrof(); 2171 } 2172 if (bt1 == VT_FUNC) { 2173 vswap(); 2174 mk_pointer(&vtop->type); 2175 gaddrof(); 2176 vswap(); 2177 } 2178 goto redo; 2179 } else if (bt1 == VT_PTR || bt2 == VT_PTR) { 1600 2180 /* at least one operand is a pointer */ 1601 /* relation nal op: must be both pointers */2181 /* relational op: must be both pointers */ 1602 2182 if (op >= TOK_ULT && op <= TOK_LOR) { 1603 2183 check_comparison_pointer_types(vtop - 1, vtop, op); 1604 2184 /* pointers are handled are unsigned */ 1605 #if def TCC_TARGET_X86_642185 #if PTR_SIZE == 8 1606 2186 t = VT_LLONG | VT_UNSIGNED; 1607 2187 #else … … 1623 2203 vrott(3); 1624 2204 gen_opic(op); 1625 /* set to integer type */ 1626 #ifdef TCC_TARGET_X86_64 1627 vtop->type.t = VT_LLONG; 1628 #else 1629 vtop->type.t = VT_INT; 1630 #endif 2205 vtop->type.t = ptrdiff_type.t; 1631 2206 vswap(); 1632 2207 gen_op(TOK_PDIV); … … 1638 2213 if (bt2 == VT_PTR) { 1639 2214 vswap(); 1640 swap(&t1, &t2); 1641 } 2215 t = t1, t1 = t2, t2 = t; 2216 } 2217 #if PTR_SIZE == 4 2218 if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG) 2219 /* XXX: truncate here because gen_opl can't handle ptr + long long */ 2220 gen_cast_s(VT_INT); 2221 #endif 1642 2222 type1 = vtop[-1].type; 1643 2223 type1.t &= ~VT_ARRAY; … … 1648 2228 if (u < 0) 1649 2229 tcc_error("unknown array element size"); 1650 #if def TCC_TARGET_X86_642230 #if PTR_SIZE == 8 1651 2231 vpushll(u); 1652 2232 #else … … 1656 2236 } 1657 2237 gen_op('*'); 1658 #ifdef CONFIG_TCC_BCHECK 2238 #if 0 2239 /* #ifdef CONFIG_TCC_BCHECK 2240 The main reason to removing this code: 2241 #include <stdio.h> 2242 int main () 2243 { 2244 int v[10]; 2245 int i = 10; 2246 int j = 9; 2247 fprintf(stderr, "v+i-j = %p\n", v+i-j); 2248 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j)); 2249 } 2250 When this code is on. then the output looks like 2251 v+i-j = 0xfffffffe 2252 v+(i-j) = 0xbff84000 2253 */ 1659 2254 /* if evaluating constant expression, no code should be 1660 2255 generated, so no bound check */ … … 1692 2287 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) { 1693 2288 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT; 1694 if ((t1 & (VT_BTYPE | VT_UNSIGNED )) == (t | VT_UNSIGNED))2289 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED)) 1695 2290 t |= VT_UNSIGNED; 2291 t |= (VT_LONG & t1); 1696 2292 goto std_op; 1697 2293 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { 1698 2294 /* cast to biggest op */ 1699 t = VT_LLONG; 2295 t = VT_LLONG | VT_LONG; 2296 if (bt1 == VT_LLONG) 2297 t &= t1; 2298 if (bt2 == VT_LLONG) 2299 t &= t2; 1700 2300 /* convert to unsigned if it does not fit in a long long */ 1701 if ((t1 & (VT_BTYPE | VT_UNSIGNED )) == (VT_LLONG | VT_UNSIGNED) ||1702 (t2 & (VT_BTYPE | VT_UNSIGNED )) == (VT_LLONG | VT_UNSIGNED))2301 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) || 2302 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED)) 1703 2303 t |= VT_UNSIGNED; 1704 2304 goto std_op; 1705 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {1706 tcc_error("comparison of struct");1707 2305 } else { 1708 2306 /* integer operations */ 1709 t = VT_INT ;2307 t = VT_INT | (VT_LONG & (t1 | t2)); 1710 2308 /* convert to unsigned if it does not fit in an integer */ 1711 if ((t1 & (VT_BTYPE | VT_UNSIGNED )) == (VT_INT | VT_UNSIGNED) ||1712 (t2 & (VT_BTYPE | VT_UNSIGNED )) == (VT_INT | VT_UNSIGNED))2309 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) || 2310 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED)) 1713 2311 t |= VT_UNSIGNED; 1714 2312 std_op: … … 1733 2331 vswap(); 1734 2332 type1.t = t; 2333 type1.ref = NULL; 1735 2334 gen_cast(&type1); 1736 2335 vswap(); … … 1745 2344 gen_opic(op); 1746 2345 if (op >= TOK_ULT && op <= TOK_GT) { 1747 /* relation nal op: the result is an int */2346 /* relational op: the result is an int */ 1748 2347 vtop->type.t = VT_INT; 1749 2348 } else { … … 1751 2350 } 1752 2351 } 2352 // Make sure that we have converted to an rvalue: 2353 if (vtop->r & VT_LVAL) 2354 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT); 1753 2355 } 1754 2356 … … 1757 2359 static void gen_cvt_itof1(int t) 1758 2360 { 2361 #ifdef TCC_TARGET_ARM64 2362 gen_cvt_itof(t); 2363 #else 1759 2364 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 1760 2365 (VT_LLONG | VT_UNSIGNED)) { … … 1775 2380 gen_cvt_itof(t); 1776 2381 } 2382 #endif 1777 2383 } 1778 2384 #endif … … 1781 2387 static void gen_cvt_ftoi1(int t) 1782 2388 { 2389 #ifdef TCC_TARGET_ARM64 2390 gen_cvt_ftoi(t); 2391 #else 1783 2392 int st; 1784 2393 … … 1802 2411 gen_cvt_ftoi(t); 1803 2412 } 2413 #endif 1804 2414 } 1805 2415 … … 1808 2418 { 1809 2419 int bits, dbt; 2420 2421 /* cannot cast static initializers */ 2422 if (STATIC_DATA_WANTED) 2423 return; 2424 1810 2425 dbt = t & VT_BTYPE; 1811 2426 /* XXX: add optimization if lvalue : just change type and offset */ … … 1818 2433 gen_op('&'); 1819 2434 } else { 1820 bits = 32 - bits; 2435 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) 2436 bits = 64 - bits; 2437 else 2438 bits = 32 - bits; 1821 2439 vpushi(bits); 1822 2440 gen_op(TOK_SHL); … … 1831 2449 1832 2450 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */ 2451 static void gen_cast_s(int t) 2452 { 2453 CType type; 2454 type.t = t; 2455 type.ref = NULL; 2456 gen_cast(&type); 2457 } 2458 1833 2459 static void gen_cast(CType *type) 1834 2460 { … … 1856 2482 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 1857 2483 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM); 2484 #if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387 2485 c &= dbt != VT_LDOUBLE; 2486 #endif 1858 2487 if (c) { 1859 2488 /* constant case: we can do it now */ … … 1866 2495 if (df) { 1867 2496 if ((sbt & VT_BTYPE) == VT_LLONG) { 1868 if ( sbt & VT_UNSIGNED)1869 vtop->c.ld = vtop->c. ull;2497 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63)) 2498 vtop->c.ld = vtop->c.i; 1870 2499 else 1871 vtop->c.ld = vtop->c.ll;2500 vtop->c.ld = -(long double)-vtop->c.i; 1872 2501 } else if(!sf) { 1873 if ( sbt & VT_UNSIGNED)1874 vtop->c.ld = vtop->c.ui;2502 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31)) 2503 vtop->c.ld = (uint32_t)vtop->c.i; 1875 2504 else 1876 vtop->c.ld = vtop->c.i;2505 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i; 1877 2506 } 1878 2507 … … 1882 2511 vtop->c.d = (double)vtop->c.ld; 1883 2512 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) { 1884 vtop->c. ull = (unsigned long long)vtop->c.ld;2513 vtop->c.i = vtop->c.ld; 1885 2514 } else if (sf && dbt == VT_BOOL) { 1886 2515 vtop->c.i = (vtop->c.ld != 0); 1887 2516 } else { 1888 2517 if(sf) 1889 vtop->c. ll = (long long)vtop->c.ld;2518 vtop->c.i = vtop->c.ld; 1890 2519 else if (sbt == (VT_LLONG|VT_UNSIGNED)) 1891 vtop->c.ll = vtop->c.ull;2520 ; 1892 2521 else if (sbt & VT_UNSIGNED) 1893 vtop->c. ll = vtop->c.ui;1894 #if def TCC_TARGET_X86_642522 vtop->c.i = (uint32_t)vtop->c.i; 2523 #if PTR_SIZE == 8 1895 2524 else if (sbt == VT_PTR) 1896 2525 ; 1897 2526 #endif 1898 2527 else if (sbt != VT_LLONG) 1899 vtop->c.ll = vtop->c.i; 2528 vtop->c.i = ((uint32_t)vtop->c.i | 2529 -(vtop->c.i & 0x80000000)); 1900 2530 1901 2531 if (dbt == (VT_LLONG|VT_UNSIGNED)) 1902 vtop->c.ull = vtop->c.ll;2532 ; 1903 2533 else if (dbt == VT_BOOL) 1904 vtop->c.i = (vtop->c.ll != 0); 2534 vtop->c.i = (vtop->c.i != 0); 2535 #if PTR_SIZE == 8 2536 else if (dbt == VT_PTR) 2537 ; 2538 #endif 1905 2539 else if (dbt != VT_LLONG) { 1906 int s = 0; 1907 if ((dbt & VT_BTYPE) == VT_BYTE) 1908 s = 24; 1909 else if ((dbt & VT_BTYPE) == VT_SHORT) 1910 s = 16; 1911 1912 if(dbt & VT_UNSIGNED) 1913 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s; 1914 else 1915 vtop->c.i = ((int)vtop->c.ll << s) >> s; 2540 uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff : 2541 (dbt & VT_BTYPE) == VT_SHORT ? 0xffff : 2542 0xffffffff); 2543 vtop->c.i &= m; 2544 if (!(dbt & VT_UNSIGNED)) 2545 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1)); 1916 2546 } 1917 2547 } … … 1919 2549 vtop->r = VT_CONST; 1920 2550 vtop->c.i = 1; 1921 } else if (!nocode_wanted){2551 } else { 1922 2552 /* non constant case: generate code */ 1923 2553 if (sf && df) { … … 1945 2575 } 1946 2576 } 1947 #if ndef TCC_TARGET_X86_642577 #if PTR_SIZE == 4 1948 2578 } else if ((dbt & VT_BTYPE) == VT_LLONG) { 1949 2579 if ((sbt & VT_BTYPE) != VT_LLONG) { … … 1959 2589 /* cast from pointer to int before we apply 1960 2590 shift operation, which pointers don't support*/ 1961 gen_cast (&int_type);2591 gen_cast_s(VT_INT); 1962 2592 } 1963 2593 gv_dup(); … … 1977 2607 (sbt & VT_BTYPE) != VT_FUNC) { 1978 2608 /* need to convert from 32bit to 64bit */ 1979 int r =gv(RC_INT);2609 gv(RC_INT); 1980 2610 if (sbt != (VT_INT | VT_UNSIGNED)) { 2611 #if defined(TCC_TARGET_ARM64) 2612 gen_cvt_sxtw(); 2613 #elif defined(TCC_TARGET_X86_64) 2614 int r = gv(RC_INT); 1981 2615 /* x86_64 specific: movslq */ 1982 2616 o(0x6348); 1983 2617 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r)); 2618 #else 2619 #error 2620 #endif 1984 2621 } 1985 2622 } … … 1996 2633 } 1997 2634 force_charshort_cast(dbt); 2635 #if PTR_SIZE == 4 1998 2636 } else if ((dbt & VT_BTYPE) == VT_INT) { 1999 2637 /* scalar to int */ 2000 if ( sbt== VT_LLONG) {2638 if ((sbt & VT_BTYPE) == VT_LLONG) { 2001 2639 /* from long long: just take low order word */ 2002 2640 lexpand(); … … 2006 2644 the lvalue already contains the real type size (see 2007 2645 VT_LVAL_xxx constants) */ 2646 #endif 2008 2647 } 2009 2648 } … … 2044 2683 return PTR_SIZE; 2045 2684 } 2685 } else if (IS_ENUM(type->t) && type->ref->c == -1) { 2686 return -1; /* incomplete enum */ 2046 2687 } else if (bt == VT_LDOUBLE) { 2047 2688 *a = LDOUBLE_ALIGN; … … 2064 2705 #endif 2065 2706 return 8; 2066 } else if (bt == VT_INT || bt == VT_ ENUM || bt == VT_FLOAT) {2707 } else if (bt == VT_INT || bt == VT_FLOAT) { 2067 2708 *a = 4; 2068 2709 return 4; … … 2070 2711 *a = 2; 2071 2712 return 2; 2713 } else if (bt == VT_QLONG || bt == VT_QFLOAT) { 2714 *a = 8; 2715 return 16; 2072 2716 } else { 2073 2717 /* char, void, function, _Bool */ … … 2082 2726 { 2083 2727 if (type->t & VT_VLA) { 2728 type_size(&type->ref->type, a); 2084 2729 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c); 2085 2730 } else { … … 2088 2733 } 2089 2734 2735 static void vla_sp_restore(void) { 2736 if (vlas_in_scope) { 2737 gen_vla_sp_restore(vla_sp_loc); 2738 } 2739 } 2740 2741 static void vla_sp_restore_root(void) { 2742 if (vlas_in_scope) { 2743 gen_vla_sp_restore(vla_sp_root_loc); 2744 } 2745 } 2746 2090 2747 /* return the pointed type of t */ 2091 2748 static inline CType *pointed_type(CType *type) … … 2099 2756 Sym *s; 2100 2757 s = sym_push(SYM_FIELD, type, 0, -1); 2101 type->t = VT_PTR | (type->t & ~VT_TYPE);2758 type->t = VT_PTR | (type->t & VT_STORAGE); 2102 2759 type->ref = s; 2103 2760 } … … 2113 2770 return 0; 2114 2771 /* check func_call */ 2115 if ( FUNC_CALL(s1->r) != FUNC_CALL(s2->r))2772 if (s1->f.func_call != s2->f.func_call) 2116 2773 return 0; 2117 2774 /* XXX: not complete */ 2118 if (s1-> c == FUNC_OLD || s2->c== FUNC_OLD)2775 if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD) 2119 2776 return 1; 2120 if (s1-> c != s2->c)2777 if (s1->f.func_type != s2->f.func_type) 2121 2778 return 0; 2122 2779 while (s1 != NULL) { 2123 2780 if (s2 == NULL) 2124 2781 return 0; 2125 if (!is_compatible_ parameter_types(&s1->type, &s2->type))2782 if (!is_compatible_unqualified_types(&s1->type, &s2->type)) 2126 2783 return 0; 2127 2784 s1 = s1->next; … … 2148 2805 t1 &= ~(VT_CONSTANT | VT_VOLATILE); 2149 2806 t2 &= ~(VT_CONSTANT | VT_VOLATILE); 2807 } 2808 2809 /* Default Vs explicit signedness only matters for char */ 2810 if ((t1 & VT_BTYPE) != VT_BYTE) { 2811 t1 &= ~VT_DEFSIGN; 2812 t2 &= ~VT_DEFSIGN; 2150 2813 } 2151 2814 /* XXX: bitfields ? */ … … 2177 2840 /* return true if type1 and type2 are the same (ignoring qualifiers). 2178 2841 */ 2179 static int is_compatible_ parameter_types(CType *type1, CType *type2)2842 static int is_compatible_unqualified_types(CType *type1, CType *type2) 2180 2843 { 2181 2844 return compare_types(type1,type2,1); … … 2194 2857 const char *tstr; 2195 2858 2196 t = type->t & VT_TYPE;2859 t = type->t; 2197 2860 bt = t & VT_BTYPE; 2198 2861 buf[0] = '\0'; 2862 2863 if (t & VT_EXTERN) 2864 pstrcat(buf, buf_size, "extern "); 2865 if (t & VT_STATIC) 2866 pstrcat(buf, buf_size, "static "); 2867 if (t & VT_TYPEDEF) 2868 pstrcat(buf, buf_size, "typedef "); 2869 if (t & VT_INLINE) 2870 pstrcat(buf, buf_size, "inline "); 2871 if (t & VT_VOLATILE) 2872 pstrcat(buf, buf_size, "volatile "); 2199 2873 if (t & VT_CONSTANT) 2200 2874 pstrcat(buf, buf_size, "const "); 2201 if (t & VT_VOLATILE) 2202 pstrcat(buf, buf_size, "volatile "); 2203 if (t & VT_UNSIGNED) 2204 pstrcat(buf, buf_size, "unsigned "); 2875 2876 if (((t & VT_DEFSIGN) && bt == VT_BYTE) 2877 || ((t & VT_UNSIGNED) 2878 && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG) 2879 && !IS_ENUM(t) 2880 )) 2881 pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed "); 2882 2883 buf_size -= strlen(buf); 2884 buf += strlen(buf); 2885 2205 2886 switch(bt) { 2206 2887 case VT_VOID: … … 2218 2899 case VT_INT: 2219 2900 tstr = "int"; 2220 goto add_tstr; 2221 case VT_LONG: 2222 tstr = "long"; 2223 goto add_tstr; 2901 goto maybe_long; 2224 2902 case VT_LLONG: 2225 2903 tstr = "long long"; 2226 goto add_tstr; 2904 maybe_long: 2905 if (t & VT_LONG) 2906 tstr = "long"; 2907 if (!IS_ENUM(t)) 2908 goto add_tstr; 2909 tstr = "enum "; 2910 goto tstruct; 2227 2911 case VT_FLOAT: 2228 2912 tstr = "float"; … … 2236 2920 pstrcat(buf, buf_size, tstr); 2237 2921 break; 2238 case VT_ENUM:2239 2922 case VT_STRUCT: 2240 if (bt == VT_STRUCT)2241 tstr = "struct ";2242 else2243 tstr = "enum ";2923 tstr = "struct "; 2924 if (IS_UNION(t)) 2925 tstr = "union "; 2926 tstruct: 2244 2927 pstrcat(buf, buf_size, tstr); 2245 2928 v = type->ref->v & ~SYM_STRUCT; … … 2265 2948 case VT_PTR: 2266 2949 s = type->ref; 2950 if (t & VT_ARRAY) { 2951 snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c); 2952 type_to_str(buf, buf_size, &s->type, buf1); 2953 goto no_var; 2954 } 2267 2955 pstrcpy(buf1, sizeof(buf1), "*"); 2956 if (t & VT_CONSTANT) 2957 pstrcat(buf1, buf_size, "const "); 2958 if (t & VT_VOLATILE) 2959 pstrcat(buf1, buf_size, "volatile "); 2268 2960 if (varstr) 2269 2961 pstrcat(buf1, sizeof(buf1), varstr); … … 2282 2974 static void gen_assign_cast(CType *dt) 2283 2975 { 2284 CType *st, *type1, *type2 , tmp_type1, tmp_type2;2976 CType *st, *type1, *type2; 2285 2977 char buf1[256], buf2[256]; 2286 2978 int dbt, sbt; … … 2289 2981 dbt = dt->t & VT_BTYPE; 2290 2982 sbt = st->t & VT_BTYPE; 2291 if (sbt == VT_VOID) 2292 tcc_error("Cannot assign void value"); 2983 if (sbt == VT_VOID || dbt == VT_VOID) { 2984 if (sbt == VT_VOID && dbt == VT_VOID) 2985 ; /* 2986 It is Ok if both are void 2987 A test program: 2988 void func1() {} 2989 void func2() { 2990 return func1(); 2991 } 2992 gcc accepts this program 2993 */ 2994 else 2995 tcc_error("cannot cast from/to void"); 2996 } 2293 2997 if (dt->t & VT_CONSTANT) 2294 2998 tcc_warning("assignment of read-only location"); … … 2305 3009 } 2306 3010 type1 = pointed_type(dt); 2307 /* a function is implicit ely a function pointer */3011 /* a function is implicitly a function pointer */ 2308 3012 if (sbt == VT_FUNC) { 2309 3013 if ((type1->t & VT_BTYPE) != VT_VOID && … … 2319 3023 /* void * can match anything */ 2320 3024 } else { 2321 /* exact type match, except for unsigned */ 2322 tmp_type1 = *type1; 2323 tmp_type2 = *type2; 2324 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); 2325 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); 2326 if (!is_compatible_types(&tmp_type1, &tmp_type2)) 2327 tcc_warning("assignment from incompatible pointer type"); 3025 //printf("types %08x %08x\n", type1->t, type2->t); 3026 /* exact type match, except for qualifiers */ 3027 if (!is_compatible_unqualified_types(type1, type2)) { 3028 /* Like GCC don't warn by default for merely changes 3029 in pointer target signedness. Do warn for different 3030 base types, though, in particular for unsigned enums 3031 and signed int targets. */ 3032 if ((type1->t & (VT_BTYPE|VT_LONG)) != (type2->t & (VT_BTYPE|VT_LONG)) 3033 || IS_ENUM(type1->t) || IS_ENUM(type2->t) 3034 ) 3035 tcc_warning("assignment from incompatible pointer type"); 3036 } 2328 3037 } 2329 3038 /* check const and volatile */ … … 2338 3047 if (sbt == VT_PTR || sbt == VT_FUNC) { 2339 3048 tcc_warning("assignment makes integer from pointer without a cast"); 3049 } else if (sbt == VT_STRUCT) { 3050 goto case_VT_STRUCT; 2340 3051 } 2341 3052 /* XXX: more tests */ 2342 3053 break; 2343 3054 case VT_STRUCT: 2344 tmp_type1 = *dt; 2345 tmp_type2 = *st; 2346 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE); 2347 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE); 2348 if (!is_compatible_types(&tmp_type1, &tmp_type2)) { 3055 case_VT_STRUCT: 3056 if (!is_compatible_unqualified_types(dt, st)) { 2349 3057 error: 2350 3058 type_to_str(buf1, sizeof(buf1), st, NULL); … … 2371 3079 /* optimize char/short casts */ 2372 3080 delayed_cast = VT_MUSTCAST; 2373 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));3081 vtop->type.t = ft & VT_TYPE; 2374 3082 /* XXX: factorize */ 2375 3083 if (ft & VT_CONSTANT) … … 2385 3093 /* structure assignment : generate memcpy */ 2386 3094 /* XXX: optimize if small size */ 2387 if (!nocode_wanted) {2388 3095 size = type_size(&vtop->type, &align); 2389 3096 … … 2401 3108 else 2402 3109 #endif 2403 vpush_global_sym(&func_old_type, TOK_memcpy); 3110 /* Use memmove, rather than memcpy, as dest and src may be same: */ 3111 vpush_global_sym(&func_old_type, TOK_memmove); 2404 3112 2405 3113 vswap(); … … 2411 3119 vpushi(size); 2412 3120 gfunc_call(3); 2413 } else { 2414 vswap(); 2415 vpop(); 2416 } 3121 2417 3122 /* leave source on stack */ 2418 3123 } else if (ft & VT_BITFIELD) { 2419 3124 /* bitfield store handling */ 2420 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f; 2421 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f; 3125 3126 /* save lvalue as expression result (example: s.b = s.a = n;) */ 3127 vdup(), vtop[-1] = vtop[-2]; 3128 3129 bit_pos = BIT_POS(ft); 3130 bit_size = BIT_SIZE(ft); 2422 3131 /* remove bit field info to avoid loops */ 2423 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); 2424 2425 /* duplicate source into other register */ 2426 gv_dup(); 2427 vswap(); 2428 vrott(3); 2429 2430 if((ft & VT_BTYPE) == VT_BOOL) { 3132 vtop[-1].type.t = ft & ~VT_STRUCT_MASK; 3133 3134 if ((ft & VT_BTYPE) == VT_BOOL) { 2431 3135 gen_cast(&vtop[-1].type); 2432 3136 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED); 2433 3137 } 2434 3138 2435 /* duplicate destination */ 2436 vdup(); 2437 vtop[-1] = vtop[-2]; 2438 2439 /* mask and shift source */ 2440 if((ft & VT_BTYPE) != VT_BOOL) { 2441 if((ft & VT_BTYPE) == VT_LLONG) { 2442 vpushll((1ULL << bit_size) - 1ULL); 2443 } else { 2444 vpushi((1 << bit_size) - 1); 2445 } 3139 r = adjust_bf(vtop - 1, bit_pos, bit_size); 3140 if (r == VT_STRUCT) { 3141 gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT); 3142 store_packed_bf(bit_pos, bit_size); 3143 } else { 3144 unsigned long long mask = (1ULL << bit_size) - 1; 3145 if ((ft & VT_BTYPE) != VT_BOOL) { 3146 /* mask source */ 3147 if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG) 3148 vpushll(mask); 3149 else 3150 vpushi((unsigned)mask); 3151 gen_op('&'); 3152 } 3153 /* shift source */ 3154 vpushi(bit_pos); 3155 gen_op(TOK_SHL); 3156 vswap(); 3157 /* duplicate destination */ 3158 vdup(); 3159 vrott(3); 3160 /* load destination, mask and or with source */ 3161 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) 3162 vpushll(~(mask << bit_pos)); 3163 else 3164 vpushi(~((unsigned)mask << bit_pos)); 2446 3165 gen_op('&'); 2447 } 2448 vpushi(bit_pos); 2449 gen_op(TOK_SHL); 2450 /* load destination, mask and or with source */ 2451 vswap(); 2452 if((ft & VT_BTYPE) == VT_LLONG) { 2453 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos)); 2454 } else { 2455 vpushi(~(((1 << bit_size) - 1) << bit_pos)); 2456 } 2457 gen_op('&'); 2458 gen_op('|'); 2459 /* store result */ 2460 vstore(); 2461 2462 /* pop off shifted source from "duplicate source..." above */ 2463 vpop(); 2464 3166 gen_op('|'); 3167 /* store result */ 3168 vstore(); 3169 /* ... and discard */ 3170 vpop(); 3171 } 3172 } else if (dbt == VT_VOID) { 3173 --vtop; 2465 3174 } else { 2466 3175 #ifdef CONFIG_TCC_BCHECK 2467 /* bound check case */ 2468 if (vtop[-1].r & VT_MUSTBOUND) { 2469 vswap(); 2470 gbound(); 2471 vswap(); 2472 } 2473 #endif 2474 if (!nocode_wanted) { 3176 /* bound check case */ 3177 if (vtop[-1].r & VT_MUSTBOUND) { 3178 vswap(); 3179 gbound(); 3180 vswap(); 3181 } 3182 #endif 2475 3183 rc = RC_INT; 2476 3184 if (is_float(ft)) { … … 2479 3187 if ((ft & VT_BTYPE) == VT_LDOUBLE) { 2480 3188 rc = RC_ST0; 3189 } else if ((ft & VT_BTYPE) == VT_QFLOAT) { 3190 rc = RC_FRET; 2481 3191 } 2482 3192 #endif … … 2487 3197 SValue sv; 2488 3198 t = get_reg(RC_INT); 2489 #if def TCC_TARGET_X86_643199 #if PTR_SIZE == 8 2490 3200 sv.type.t = VT_PTR; 2491 3201 #else … … 2493 3203 #endif 2494 3204 sv.r = VT_LOCAL | VT_LVAL; 2495 sv.c. ul = vtop[-1].c.ul;3205 sv.c.i = vtop[-1].c.i; 2496 3206 load(t, &sv); 2497 3207 vtop[-1].r = t | VT_LVAL; 2498 3208 } 2499 store(r, vtop - 1); 2500 #ifndef TCC_TARGET_X86_64 2501 /* two word case handling : store second register at word + 4 */ 3209 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */ 3210 #if PTR_SIZE == 8 3211 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) { 3212 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE; 3213 #else 2502 3214 if ((ft & VT_BTYPE) == VT_LLONG) { 3215 int addr_type = VT_INT, load_size = 4, load_type = VT_INT; 3216 #endif 3217 vtop[-1].type.t = load_type; 3218 store(r, vtop - 1); 2503 3219 vswap(); 2504 3220 /* convert to int to increment easily */ 2505 vtop->type.t = VT_INT;3221 vtop->type.t = addr_type; 2506 3222 gaddrof(); 2507 vpushi( 4);3223 vpushi(load_size); 2508 3224 gen_op('+'); 2509 3225 vtop->r |= VT_LVAL; 2510 3226 vswap(); 3227 vtop[-1].type.t = load_type; 2511 3228 /* XXX: it works because r2 is spilled last ! */ 2512 3229 store(vtop->r2, vtop - 1); 2513 } 2514 #endif 2515 } 3230 } else { 3231 store(r, vtop - 1); 3232 } 3233 2516 3234 vswap(); 2517 3235 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ … … 2538 3256 } 2539 3257 2540 /* Parse GNUC __attribute__ extension. Currently, the following 2541 extensions are recognized: 2542 - aligned(n) : set data/function alignment. 2543 - packed : force data alignment to 1 2544 - section(x) : generate data/code in this section. 2545 - unused : currently ignored, but may be used someday. 2546 - regparm(n) : pass function parameters in registers (i386 only) 2547 */ 3258 ST_FUNC void parse_mult_str (CString *astr, const char *msg) 3259 { 3260 /* read the string */ 3261 if (tok != TOK_STR) 3262 expect(msg); 3263 cstr_new(astr); 3264 while (tok == TOK_STR) { 3265 /* XXX: add \0 handling too ? */ 3266 cstr_cat(astr, tokc.str.data, -1); 3267 next(); 3268 } 3269 cstr_ccat(astr, '\0'); 3270 } 3271 3272 /* If I is >= 1 and a power of two, returns log2(i)+1. 3273 If I is 0 returns 0. */ 3274 static int exact_log2p1(int i) 3275 { 3276 int ret; 3277 if (!i) 3278 return 0; 3279 for (ret = 1; i >= 1 << 8; ret += 8) 3280 i >>= 8; 3281 if (i >= 1 << 4) 3282 ret += 4, i >>= 4; 3283 if (i >= 1 << 2) 3284 ret += 2, i >>= 2; 3285 if (i >= 1 << 1) 3286 ret++; 3287 return ret; 3288 } 3289 3290 /* Parse __attribute__((...)) GNUC extension. */ 2548 3291 static void parse_attribute(AttributeDef *ad) 2549 3292 { 2550 3293 int t, n; 3294 CString astr; 2551 3295 2552 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { 3296 redo: 3297 if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2) 3298 return; 2553 3299 next(); 2554 3300 skip('('); … … 2563 3309 case TOK_SECTION2: 2564 3310 skip('('); 2565 if (tok != TOK_STR) 2566 expect("section name"); 2567 ad->section = find_section(tcc_state, (char *)tokc.cstr->data); 2568 next(); 3311 parse_mult_str(&astr, "section name"); 3312 ad->section = find_section(tcc_state, (char *)astr.data); 2569 3313 skip(')'); 3314 cstr_free(&astr); 2570 3315 break; 2571 3316 case TOK_ALIAS1: 2572 3317 case TOK_ALIAS2: 2573 3318 skip('('); 2574 if (tok != TOK_STR) 2575 expect("alias(\"target\")"); 3319 parse_mult_str(&astr, "alias(\"target\")"); 2576 3320 ad->alias_target = /* save string as token, for later */ 2577 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok; 2578 next(); 3321 tok_alloc((char*)astr.data, astr.size-1)->tok; 2579 3322 skip(')'); 3323 cstr_free(&astr); 3324 break; 3325 case TOK_VISIBILITY1: 3326 case TOK_VISIBILITY2: 3327 skip('('); 3328 parse_mult_str(&astr, 3329 "visibility(\"default|hidden|internal|protected\")"); 3330 if (!strcmp (astr.data, "default")) 3331 ad->a.visibility = STV_DEFAULT; 3332 else if (!strcmp (astr.data, "hidden")) 3333 ad->a.visibility = STV_HIDDEN; 3334 else if (!strcmp (astr.data, "internal")) 3335 ad->a.visibility = STV_INTERNAL; 3336 else if (!strcmp (astr.data, "protected")) 3337 ad->a.visibility = STV_PROTECTED; 3338 else 3339 expect("visibility(\"default|hidden|internal|protected\")"); 3340 skip(')'); 3341 cstr_free(&astr); 2580 3342 break; 2581 3343 case TOK_ALIGNED1: … … 2590 3352 n = MAX_ALIGN; 2591 3353 } 2592 ad->aligned = n; 3354 ad->a.aligned = exact_log2p1(n); 3355 if (n != 1 << (ad->a.aligned - 1)) 3356 tcc_error("alignment of %d is larger than implemented", n); 2593 3357 break; 2594 3358 case TOK_PACKED1: 2595 3359 case TOK_PACKED2: 2596 ad-> packed = 1;3360 ad->a.packed = 1; 2597 3361 break; 2598 3362 case TOK_WEAK1: 2599 3363 case TOK_WEAK2: 2600 ad-> weak = 1;3364 ad->a.weak = 1; 2601 3365 break; 2602 3366 case TOK_UNUSED1: … … 2613 3377 case TOK_CDECL2: 2614 3378 case TOK_CDECL3: 2615 ad->f unc_call = FUNC_CDECL;3379 ad->f.func_call = FUNC_CDECL; 2616 3380 break; 2617 3381 case TOK_STDCALL1: 2618 3382 case TOK_STDCALL2: 2619 3383 case TOK_STDCALL3: 2620 ad->f unc_call = FUNC_STDCALL;3384 ad->f.func_call = FUNC_STDCALL; 2621 3385 break; 2622 3386 #ifdef TCC_TARGET_I386 … … 2630 3394 n = 0; 2631 3395 if (n > 0) 2632 ad->f unc_call = FUNC_FASTCALL1 + n - 1;3396 ad->f.func_call = FUNC_FASTCALL1 + n - 1; 2633 3397 skip(')'); 2634 3398 break; … … 2636 3400 case TOK_FASTCALL2: 2637 3401 case TOK_FASTCALL3: 2638 ad->f unc_call = FUNC_FASTCALLW;3402 ad->f.func_call = FUNC_FASTCALLW; 2639 3403 break; 2640 3404 #endif … … 2643 3407 switch(tok) { 2644 3408 case TOK_MODE_DI: 2645 ad->mode = VT_LLONG + 1; 3409 ad->attr_mode = VT_LLONG + 1; 3410 break; 3411 case TOK_MODE_QI: 3412 ad->attr_mode = VT_BYTE + 1; 2646 3413 break; 2647 3414 case TOK_MODE_HI: 2648 ad-> mode = VT_SHORT + 1;3415 ad->attr_mode = VT_SHORT + 1; 2649 3416 break; 2650 3417 case TOK_MODE_SI: 2651 ad->mode = VT_INT + 1; 3418 case TOK_MODE_word: 3419 ad->attr_mode = VT_INT + 1; 2652 3420 break; 2653 3421 default: … … 2659 3427 break; 2660 3428 case TOK_DLLEXPORT: 2661 ad-> func_export = 1;3429 ad->a.dllexport = 1; 2662 3430 break; 2663 3431 case TOK_DLLIMPORT: 2664 ad-> func_import = 1;3432 ad->a.dllimport = 1; 2665 3433 break; 2666 3434 default: … … 2686 3454 skip(')'); 2687 3455 skip(')'); 2688 } 2689 } 2690 2691 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ 3456 goto redo; 3457 } 3458 3459 static Sym * find_field (CType *type, int v) 3460 { 3461 Sym *s = type->ref; 3462 v |= SYM_FIELD; 3463 while ((s = s->next) != NULL) { 3464 if ((s->v & SYM_FIELD) && 3465 (s->type.t & VT_BTYPE) == VT_STRUCT && 3466 (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) { 3467 Sym *ret = find_field (&s->type, v); 3468 if (ret) 3469 return ret; 3470 } 3471 if (s->v == v) 3472 break; 3473 } 3474 return s; 3475 } 3476 3477 static void struct_add_offset (Sym *s, int offset) 3478 { 3479 while ((s = s->next) != NULL) { 3480 if ((s->v & SYM_FIELD) && 3481 (s->type.t & VT_BTYPE) == VT_STRUCT && 3482 (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) { 3483 struct_add_offset(s->type.ref, offset); 3484 } else 3485 s->c += offset; 3486 } 3487 } 3488 3489 static void struct_layout(CType *type, AttributeDef *ad) 3490 { 3491 int size, align, maxalign, offset, c, bit_pos, bit_size; 3492 int packed, a, bt, prevbt, prev_bit_size; 3493 int pcc = !tcc_state->ms_bitfields; 3494 int pragma_pack = *tcc_state->pack_stack_ptr; 3495 Sym *f; 3496 3497 maxalign = 1; 3498 offset = 0; 3499 c = 0; 3500 bit_pos = 0; 3501 prevbt = VT_STRUCT; /* make it never match */ 3502 prev_bit_size = 0; 3503 3504 //#define BF_DEBUG 3505 3506 for (f = type->ref->next; f; f = f->next) { 3507 if (f->type.t & VT_BITFIELD) 3508 bit_size = BIT_SIZE(f->type.t); 3509 else 3510 bit_size = -1; 3511 size = type_size(&f->type, &align); 3512 a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0; 3513 packed = 0; 3514 3515 if (pcc && bit_size == 0) { 3516 /* in pcc mode, packing does not affect zero-width bitfields */ 3517 3518 } else { 3519 /* in pcc mode, attribute packed overrides if set. */ 3520 if (pcc && (f->a.packed || ad->a.packed)) 3521 align = packed = 1; 3522 3523 /* pragma pack overrides align if lesser and packs bitfields always */ 3524 if (pragma_pack) { 3525 packed = 1; 3526 if (pragma_pack < align) 3527 align = pragma_pack; 3528 /* in pcc mode pragma pack also overrides individual align */ 3529 if (pcc && pragma_pack < a) 3530 a = 0; 3531 } 3532 } 3533 /* some individual align was specified */ 3534 if (a) 3535 align = a; 3536 3537 if (type->ref->type.t == VT_UNION) { 3538 if (pcc && bit_size >= 0) 3539 size = (bit_size + 7) >> 3; 3540 offset = 0; 3541 if (size > c) 3542 c = size; 3543 3544 } else if (bit_size < 0) { 3545 if (pcc) 3546 c += (bit_pos + 7) >> 3; 3547 c = (c + align - 1) & -align; 3548 offset = c; 3549 if (size > 0) 3550 c += size; 3551 bit_pos = 0; 3552 prevbt = VT_STRUCT; 3553 prev_bit_size = 0; 3554 3555 } else { 3556 /* A bit-field. Layout is more complicated. There are two 3557 options: PCC (GCC) compatible and MS compatible */ 3558 if (pcc) { 3559 /* In PCC layout a bit-field is placed adjacent to the 3560 preceding bit-fields, except if: 3561 - it has zero-width 3562 - an individual alignment was given 3563 - it would overflow its base type container and 3564 there is no packing */ 3565 if (bit_size == 0) { 3566 new_field: 3567 c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align; 3568 bit_pos = 0; 3569 } else if (f->a.aligned) { 3570 goto new_field; 3571 } else if (!packed) { 3572 int a8 = align * 8; 3573 int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8; 3574 if (ofs > size / align) 3575 goto new_field; 3576 } 3577 3578 /* in pcc mode, long long bitfields have type int if they fit */ 3579 if (size == 8 && bit_size <= 32) 3580 f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4; 3581 3582 while (bit_pos >= align * 8) 3583 c += align, bit_pos -= align * 8; 3584 offset = c; 3585 3586 /* In PCC layout named bit-fields influence the alignment 3587 of the containing struct using the base types alignment, 3588 except for packed fields (which here have correct align). */ 3589 if (f->v & SYM_FIRST_ANOM 3590 // && bit_size // ??? gcc on ARM/rpi does that 3591 ) 3592 align = 1; 3593 3594 } else { 3595 bt = f->type.t & VT_BTYPE; 3596 if ((bit_pos + bit_size > size * 8) 3597 || (bit_size > 0) == (bt != prevbt) 3598 ) { 3599 c = (c + align - 1) & -align; 3600 offset = c; 3601 bit_pos = 0; 3602 /* In MS bitfield mode a bit-field run always uses 3603 at least as many bits as the underlying type. 3604 To start a new run it's also required that this 3605 or the last bit-field had non-zero width. */ 3606 if (bit_size || prev_bit_size) 3607 c += size; 3608 } 3609 /* In MS layout the records alignment is normally 3610 influenced by the field, except for a zero-width 3611 field at the start of a run (but by further zero-width 3612 fields it is again). */ 3613 if (bit_size == 0 && prevbt != bt) 3614 align = 1; 3615 prevbt = bt; 3616 prev_bit_size = bit_size; 3617 } 3618 3619 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT)) 3620 | (bit_pos << VT_STRUCT_SHIFT); 3621 bit_pos += bit_size; 3622 } 3623 if (align > maxalign) 3624 maxalign = align; 3625 3626 #ifdef BF_DEBUG 3627 printf("set field %s offset %-2d size %-2d align %-2d", 3628 get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align); 3629 if (f->type.t & VT_BITFIELD) { 3630 printf(" pos %-2d bits %-2d", 3631 BIT_POS(f->type.t), 3632 BIT_SIZE(f->type.t) 3633 ); 3634 } 3635 printf("\n"); 3636 #endif 3637 3638 if (f->v & SYM_FIRST_ANOM && (f->type.t & VT_BTYPE) == VT_STRUCT) { 3639 Sym *ass; 3640 /* An anonymous struct/union. Adjust member offsets 3641 to reflect the real offset of our containing struct. 3642 Also set the offset of this anon member inside 3643 the outer struct to be zero. Via this it 3644 works when accessing the field offset directly 3645 (from base object), as well as when recursing 3646 members in initializer handling. */ 3647 int v2 = f->type.ref->v; 3648 if (!(v2 & SYM_FIELD) && 3649 (v2 & ~SYM_STRUCT) < SYM_FIRST_ANOM) { 3650 Sym **pps; 3651 /* This happens only with MS extensions. The 3652 anon member has a named struct type, so it 3653 potentially is shared with other references. 3654 We need to unshare members so we can modify 3655 them. */ 3656 ass = f->type.ref; 3657 f->type.ref = sym_push(anon_sym++ | SYM_FIELD, 3658 &f->type.ref->type, 0, 3659 f->type.ref->c); 3660 pps = &f->type.ref->next; 3661 while ((ass = ass->next) != NULL) { 3662 *pps = sym_push(ass->v, &ass->type, 0, ass->c); 3663 pps = &((*pps)->next); 3664 } 3665 *pps = NULL; 3666 } 3667 struct_add_offset(f->type.ref, offset); 3668 f->c = 0; 3669 } else { 3670 f->c = offset; 3671 } 3672 3673 f->r = 0; 3674 } 3675 3676 if (pcc) 3677 c += (bit_pos + 7) >> 3; 3678 3679 /* store size and alignment */ 3680 a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1; 3681 if (a < maxalign) 3682 a = maxalign; 3683 type->ref->r = a; 3684 if (pragma_pack && pragma_pack < maxalign && 0 == pcc) { 3685 /* can happen if individual align for some member was given. In 3686 this case MSVC ignores maxalign when aligning the size */ 3687 a = pragma_pack; 3688 if (a < bt) 3689 a = bt; 3690 } 3691 c = (c + a - 1) & -a; 3692 type->ref->c = c; 3693 3694 #ifdef BF_DEBUG 3695 printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout); 3696 #endif 3697 3698 /* check whether we can access bitfields by their type */ 3699 for (f = type->ref->next; f; f = f->next) { 3700 int s, px, cx, c0; 3701 CType t; 3702 3703 if (0 == (f->type.t & VT_BITFIELD)) 3704 continue; 3705 f->type.ref = f; 3706 f->auxtype = -1; 3707 bit_size = BIT_SIZE(f->type.t); 3708 if (bit_size == 0) 3709 continue; 3710 bit_pos = BIT_POS(f->type.t); 3711 size = type_size(&f->type, &align); 3712 if (bit_pos + bit_size <= size * 8 && f->c + size <= c) 3713 continue; 3714 3715 /* try to access the field using a different type */ 3716 c0 = -1, s = align = 1; 3717 for (;;) { 3718 px = f->c * 8 + bit_pos; 3719 cx = (px >> 3) & -align; 3720 px = px - (cx << 3); 3721 if (c0 == cx) 3722 break; 3723 s = (px + bit_size + 7) >> 3; 3724 if (s > 4) { 3725 t.t = VT_LLONG; 3726 } else if (s > 2) { 3727 t.t = VT_INT; 3728 } else if (s > 1) { 3729 t.t = VT_SHORT; 3730 } else { 3731 t.t = VT_BYTE; 3732 } 3733 s = type_size(&t, &align); 3734 c0 = cx; 3735 } 3736 3737 if (px + bit_size <= s * 8 && cx + s <= c) { 3738 /* update offset and bit position */ 3739 f->c = cx; 3740 bit_pos = px; 3741 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT)) 3742 | (bit_pos << VT_STRUCT_SHIFT); 3743 if (s != size) 3744 f->auxtype = t.t; 3745 #ifdef BF_DEBUG 3746 printf("FIX field %s offset %-2d size %-2d align %-2d " 3747 "pos %-2d bits %-2d\n", 3748 get_tok_str(f->v & ~SYM_FIELD, NULL), 3749 cx, s, align, px, bit_size); 3750 #endif 3751 } else { 3752 /* fall back to load/store single-byte wise */ 3753 f->auxtype = VT_STRUCT; 3754 #ifdef BF_DEBUG 3755 printf("FIX field %s : load byte-wise\n", 3756 get_tok_str(f->v & ~SYM_FIELD, NULL)); 3757 #endif 3758 } 3759 } 3760 } 3761 3762 /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */ 2692 3763 static void struct_decl(CType *type, int u) 2693 3764 { 2694 int a, v, size, align, maxalign, c, offset;2695 int bit_size, b it_pos, bsize, bt, lbit_pos, prevbt;2696 Sym *s, *ss, * ass, **ps;2697 AttributeDef ad ;3765 int v, c, size, align, flexible; 3766 int bit_size, bsize, bt; 3767 Sym *s, *ss, **ps; 3768 AttributeDef ad, ad1; 2698 3769 CType type1, btype; 2699 3770 2700 a = tok; /* save decl type */3771 memset(&ad, 0, sizeof ad); 2701 3772 next(); 3773 parse_attribute(&ad); 2702 3774 if (tok != '{') { 2703 3775 v = tok; … … 2707 3779 expect("struct/union/enum name"); 2708 3780 s = struct_find(v); 2709 if (s) { 2710 if (s->type.t != a) 2711 tcc_error("invalid type"); 2712 goto do_decl; 3781 if (s && (s->sym_scope == local_scope || tok != '{')) { 3782 if (u == s->type.t) 3783 goto do_decl; 3784 if (u == VT_ENUM && IS_ENUM(s->type.t)) 3785 goto do_decl; 3786 tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); 2713 3787 } 2714 3788 } else { 2715 3789 v = anon_sym++; 2716 3790 } 2717 type1.t = a; 3791 /* Record the original enum/struct/union token. */ 3792 type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u; 3793 type1.ref = NULL; 2718 3794 /* we put an undefined size for struct/union */ 2719 3795 s = sym_push(v | SYM_STRUCT, &type1, 0, -1); 2720 3796 s->r = 0; /* default alignment is zero as gcc */ 2721 /* put struct/union/enum name in type */ 2722 do_decl: 2723 type->t = u; 3797 do_decl: 3798 type->t = s->type.t; 2724 3799 type->ref = s; 2725 3800 2726 3801 if (tok == '{') { 2727 3802 next(); … … 2729 3804 tcc_error("struct/union/enum already defined"); 2730 3805 /* cannot be empty */ 2731 c = 0;2732 3806 /* non empty enums are not allowed */ 2733 if (a == TOK_ENUM) { 3807 ps = &s->next; 3808 if (u == VT_ENUM) { 3809 long long ll = 0, pl = 0, nl = 0; 3810 CType t; 3811 t.ref = s; 3812 /* enum symbols have static storage */ 3813 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL; 2734 3814 for(;;) { 2735 3815 v = tok; 2736 3816 if (v < TOK_UIDENT) 2737 3817 expect("identifier"); 3818 ss = sym_find(v); 3819 if (ss && !local_stack) 3820 tcc_error("redefinition of enumerator '%s'", 3821 get_tok_str(v, NULL)); 2738 3822 next(); 2739 3823 if (tok == '=') { 2740 3824 next(); 2741 c = expr_const();3825 ll = expr_const64(); 2742 3826 } 2743 /* enum symbols have static storage */ 2744 ss = sym_push(v, &int_type, VT_CONST, c); 2745 ss->type.t |= VT_STATIC; 3827 ss = sym_push(v, &t, VT_CONST, 0); 3828 ss->enum_val = ll; 3829 *ps = ss, ps = &ss->next; 3830 if (ll < nl) 3831 nl = ll; 3832 if (ll > pl) 3833 pl = ll; 2746 3834 if (tok != ',') 2747 3835 break; 2748 3836 next(); 2749 c++;3837 ll++; 2750 3838 /* NOTE: we accept a trailing comma */ 2751 3839 if (tok == '}') … … 2753 3841 } 2754 3842 skip('}'); 3843 /* set integral type of the enum */ 3844 t.t = VT_INT; 3845 if (nl >= 0) { 3846 if (pl != (unsigned)pl) 3847 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG); 3848 t.t |= VT_UNSIGNED; 3849 } else if (pl != (int)pl || nl != (int)nl) 3850 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG); 3851 s->type.t = type->t = t.t | VT_ENUM; 3852 s->c = 0; 3853 /* set type for enum members */ 3854 for (ss = s->next; ss; ss = ss->next) { 3855 ll = ss->enum_val; 3856 if (ll == (int)ll) /* default is int if it fits */ 3857 continue; 3858 if (t.t & VT_UNSIGNED) { 3859 ss->type.t |= VT_UNSIGNED; 3860 if (ll == (unsigned)ll) 3861 continue; 3862 } 3863 ss->type.t = (ss->type.t & ~VT_BTYPE) 3864 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG); 3865 } 2755 3866 } else { 2756 maxalign = 1; 2757 ps = &s->next; 2758 prevbt = VT_INT; 2759 bit_pos = 0; 2760 offset = 0; 3867 c = 0; 3868 flexible = 0; 2761 3869 while (tok != '}') { 2762 parse_btype(&btype, &ad); 3870 if (!parse_btype(&btype, &ad1)) { 3871 skip(';'); 3872 continue; 3873 } 2763 3874 while (1) { 3875 if (flexible) 3876 tcc_error("flexible array member '%s' not at the end of struct", 3877 get_tok_str(v, NULL)); 2764 3878 bit_size = -1; 2765 3879 v = 0; 2766 3880 type1 = btype; 2767 3881 if (tok != ':') { 2768 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); 2769 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) 2770 expect("identifier"); 3882 if (tok != ';') 3883 type_decl(&type1, &ad1, &v, TYPE_DIRECT); 3884 if (v == 0) { 3885 if ((type1.t & VT_BTYPE) != VT_STRUCT) 3886 expect("identifier"); 3887 else { 3888 int v = btype.ref->v; 3889 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { 3890 if (tcc_state->ms_extensions == 0) 3891 expect("identifier"); 3892 } 3893 } 3894 } 3895 if (type_size(&type1, &align) < 0) { 3896 if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c) 3897 flexible = 1; 3898 else 3899 tcc_error("field '%s' has incomplete type", 3900 get_tok_str(v, NULL)); 3901 } 2771 3902 if ((type1.t & VT_BTYPE) == VT_FUNC || 2772 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))3903 (type1.t & VT_STORAGE)) 2773 3904 tcc_error("invalid type for '%s'", 2774 3905 get_tok_str(v, NULL)); … … 2784 3915 tcc_error("zero width for bit-field '%s'", 2785 3916 get_tok_str(v, NULL)); 3917 parse_attribute(&ad1); 2786 3918 } 2787 3919 size = type_size(&type1, &align); 2788 if (ad.aligned) {2789 if (align < ad.aligned)2790 align = ad.aligned;2791 } else if (ad.packed) {2792 align = 1;2793 } else if (*tcc_state->pack_stack_ptr) {2794 if (align > *tcc_state->pack_stack_ptr)2795 align = *tcc_state->pack_stack_ptr;2796 }2797 lbit_pos = 0;2798 3920 if (bit_size >= 0) { 2799 3921 bt = type1.t & VT_BTYPE; … … 2802 3924 bt != VT_SHORT && 2803 3925 bt != VT_BOOL && 2804 bt != VT_ENUM &&2805 3926 bt != VT_LLONG) 2806 3927 tcc_error("bitfields must have scalar type"); … … 2809 3930 tcc_error("width of '%s' exceeds its type", 2810 3931 get_tok_str(v, NULL)); 2811 } else if (bit_size == bsize) { 3932 } else if (bit_size == bsize 3933 && !ad.a.packed && !ad1.a.packed) { 2812 3934 /* no need for bit fields */ 2813 bit_pos = 0; 2814 } else if (bit_size == 0) { 2815 /* XXX: what to do if only padding in a 2816 structure ? */ 2817 /* zero size: means to pad */ 2818 bit_pos = 0; 3935 ; 3936 } else if (bit_size == 64) { 3937 tcc_error("field width 64 not implemented"); 2819 3938 } else { 2820 /* we do not have enough room ? 2821 did the type change? 2822 is it a union? */ 2823 if ((bit_pos + bit_size) > bsize || 2824 bt != prevbt || a == TOK_UNION) 2825 bit_pos = 0; 2826 lbit_pos = bit_pos; 2827 /* XXX: handle LSB first */ 2828 type1.t |= VT_BITFIELD | 2829 (bit_pos << VT_STRUCT_SHIFT) | 2830 (bit_size << (VT_STRUCT_SHIFT + 6)); 2831 bit_pos += bit_size; 3939 type1.t = (type1.t & ~VT_STRUCT_MASK) 3940 | VT_BITFIELD 3941 | (bit_size << (VT_STRUCT_SHIFT + 6)); 2832 3942 } 2833 prevbt = bt;2834 } else {2835 bit_pos = 0;2836 3943 } 2837 3944 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) { 2838 /* add new memory data only if starting 2839 bit field */ 2840 if (lbit_pos == 0) { 2841 if (a == TOK_STRUCT) { 2842 c = (c + align - 1) & -align; 2843 offset = c; 2844 if (size > 0) 2845 c += size; 2846 } else { 2847 offset = 0; 2848 if (size > c) 2849 c = size; 2850 } 2851 if (align > maxalign) 2852 maxalign = align; 2853 } 2854 #if 0 2855 printf("add field %s offset=%d", 2856 get_tok_str(v, NULL), offset); 2857 if (type1.t & VT_BITFIELD) { 2858 printf(" pos=%d size=%d", 2859 (type1.t >> VT_STRUCT_SHIFT) & 0x3f, 2860 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f); 2861 } 2862 printf("\n"); 2863 #endif 3945 /* Remember we've seen a real field to check 3946 for placement of flexible array member. */ 3947 c = 1; 2864 3948 } 2865 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) { 2866 ass = type1.ref; 2867 while ((ass = ass->next) != NULL) { 2868 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c); 2869 *ps = ss; 2870 ps = &ss->next; 2871 } 2872 } else if (v) { 2873 ss = sym_push(v | SYM_FIELD, &type1, 0, offset); 3949 /* If member is a struct or bit-field, enforce 3950 placing into the struct (as anonymous). */ 3951 if (v == 0 && 3952 ((type1.t & VT_BTYPE) == VT_STRUCT || 3953 bit_size >= 0)) { 3954 v = anon_sym++; 3955 } 3956 if (v) { 3957 ss = sym_push(v | SYM_FIELD, &type1, 0, 0); 3958 ss->a = ad1.a; 2874 3959 *ps = ss; 2875 3960 ps = &ss->next; … … 2882 3967 } 2883 3968 skip('}'); 2884 /* store size and alignment */ 2885 s->c = (c + maxalign - 1) & -maxalign; 2886 s->r = maxalign; 2887 } 2888 } 3969 parse_attribute(&ad); 3970 struct_layout(type, &ad); 3971 } 3972 } 3973 } 3974 3975 static void sym_to_attr(AttributeDef *ad, Sym *s) 3976 { 3977 if (s->a.aligned && 0 == ad->a.aligned) 3978 ad->a.aligned = s->a.aligned; 3979 if (s->f.func_call && 0 == ad->f.func_call) 3980 ad->f.func_call = s->f.func_call; 3981 if (s->f.func_type && 0 == ad->f.func_type) 3982 ad->f.func_type = s->f.func_type; 3983 if (s->a.packed) 3984 ad->a.packed = 1; 3985 } 3986 3987 /* Add type qualifiers to a type. If the type is an array then the qualifiers 3988 are added to the element type, copied because it could be a typedef. */ 3989 static void parse_btype_qualify(CType *type, int qualifiers) 3990 { 3991 while (type->t & VT_ARRAY) { 3992 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c); 3993 type = &type->ref->type; 3994 } 3995 type->t |= qualifiers; 2889 3996 } 2890 3997 … … 2894 4001 static int parse_btype(CType *type, AttributeDef *ad) 2895 4002 { 2896 int t, u, type_found, typespec_found, typedef_found;4003 int t, u, bt, st, type_found, typespec_found, g; 2897 4004 Sym *s; 2898 4005 CType type1; … … 2901 4008 type_found = 0; 2902 4009 typespec_found = 0; 2903 typedef_found = 0; 2904 t = 0; 4010 t = VT_INT; 4011 bt = st = -1; 4012 type->ref = NULL; 4013 2905 4014 while(1) { 2906 4015 switch(tok) { … … 2916 4025 next(); 2917 4026 basic_type1: 2918 if ((t & VT_BTYPE) != 0) 2919 tcc_error("too many basic types"); 2920 t |= u; 4027 if (u == VT_SHORT || u == VT_LONG) { 4028 if (st != -1 || (bt != -1 && bt != VT_INT)) 4029 tmbt: tcc_error("too many basic types"); 4030 st = u; 4031 } else { 4032 if (bt != -1 || (st != -1 && u != VT_INT)) 4033 goto tmbt; 4034 bt = u; 4035 } 4036 if (u != VT_INT) 4037 t = (t & ~(VT_BTYPE|VT_LONG)) | u; 2921 4038 typespec_found = 1; 2922 4039 break; … … 2928 4045 goto basic_type; 2929 4046 case TOK_INT: 2930 next(); 2931 typespec_found = 1; 2932 break; 4047 u = VT_INT; 4048 goto basic_type; 2933 4049 case TOK_LONG: 2934 next();2935 4050 if ((t & VT_BTYPE) == VT_DOUBLE) { 2936 #ifndef TCC_TARGET_PE 2937 t = (t & ~VT_BTYPE) | VT_LDOUBLE; 2938 #endif 2939 } else if ((t & VT_BTYPE) == VT_LONG) { 2940 t = (t & ~VT_BTYPE) | VT_LLONG; 4051 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE; 4052 } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) { 4053 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG; 2941 4054 } else { 2942 4055 u = VT_LONG; 2943 goto basic_type1; 2944 } 4056 goto basic_type; 4057 } 4058 next(); 2945 4059 break; 4060 #ifdef TCC_TARGET_ARM64 4061 case TOK_UINT128: 4062 /* GCC's __uint128_t appears in some Linux header files. Make it a 4063 synonym for long double to get the size and alignment right. */ 4064 u = VT_LDOUBLE; 4065 goto basic_type; 4066 #endif 2946 4067 case TOK_BOOL: 2947 4068 u = VT_BOOL; … … 2951 4072 goto basic_type; 2952 4073 case TOK_DOUBLE: 2953 next(); 2954 if ((t & VT_BTYPE) == VT_LONG) { 2955 #ifdef TCC_TARGET_PE 2956 t = (t & ~VT_BTYPE) | VT_DOUBLE; 2957 #else 2958 t = (t & ~VT_BTYPE) | VT_LDOUBLE; 2959 #endif 4074 if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) { 4075 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE; 2960 4076 } else { 2961 4077 u = VT_DOUBLE; 2962 goto basic_type1; 2963 } 4078 goto basic_type; 4079 } 4080 next(); 2964 4081 break; 2965 4082 case TOK_ENUM: … … 2970 4087 goto basic_type1; 2971 4088 case TOK_STRUCT: 4089 struct_decl(&type1, VT_STRUCT); 4090 goto basic_type2; 2972 4091 case TOK_UNION: 2973 struct_decl(&type1, VT_ STRUCT);4092 struct_decl(&type1, VT_UNION); 2974 4093 goto basic_type2; 2975 4094 … … 2978 4097 case TOK_CONST2: 2979 4098 case TOK_CONST3: 2980 t |= VT_CONSTANT; 4099 type->t = t; 4100 parse_btype_qualify(type, VT_CONSTANT); 4101 t = type->t; 2981 4102 next(); 2982 4103 break; … … 2984 4105 case TOK_VOLATILE2: 2985 4106 case TOK_VOLATILE3: 2986 t |= VT_VOLATILE; 4107 type->t = t; 4108 parse_btype_qualify(type, VT_VOLATILE); 4109 t = type->t; 2987 4110 next(); 2988 4111 break; … … 2990 4113 case TOK_SIGNED2: 2991 4114 case TOK_SIGNED3: 4115 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED)) 4116 tcc_error("signed and unsigned modifier"); 4117 t |= VT_DEFSIGN; 4118 next(); 2992 4119 typespec_found = 1; 2993 t |= VT_SIGNED;2994 next();2995 4120 break; 2996 4121 case TOK_REGISTER: … … 3002 4127 break; 3003 4128 case TOK_UNSIGNED: 3004 t |= VT_UNSIGNED; 4129 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN) 4130 tcc_error("signed and unsigned modifier"); 4131 t |= VT_DEFSIGN | VT_UNSIGNED; 3005 4132 next(); 3006 4133 typespec_found = 1; … … 3009 4136 /* storage */ 3010 4137 case TOK_EXTERN: 3011 t |= VT_EXTERN; 3012 next(); 3013 break; 4138 g = VT_EXTERN; 4139 goto storage; 3014 4140 case TOK_STATIC: 3015 t |= VT_STATIC; 3016 next(); 3017 break; 4141 g = VT_STATIC; 4142 goto storage; 3018 4143 case TOK_TYPEDEF: 3019 t |= VT_TYPEDEF; 4144 g = VT_TYPEDEF; 4145 goto storage; 4146 storage: 4147 if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g) 4148 tcc_error("multiple storage classes"); 4149 t |= g; 3020 4150 next(); 3021 4151 break; … … 3031 4161 case TOK_ATTRIBUTE2: 3032 4162 parse_attribute(ad); 3033 if (ad-> mode) {3034 u = ad-> mode -1;3035 t = (t & ~ VT_BTYPE) | u;4163 if (ad->attr_mode) { 4164 u = ad->attr_mode -1; 4165 t = (t & ~(VT_BTYPE|VT_LONG)) | u; 3036 4166 } 3037 4167 break; … … 3044 4174 /* remove all storage modifiers except typedef */ 3045 4175 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF); 4176 if (type1.ref) 4177 sym_to_attr(ad, type1.ref); 3046 4178 goto basic_type2; 3047 4179 default: 3048 if (typespec_found || typedef_found)4180 if (typespec_found) 3049 4181 goto the_end; 3050 4182 s = sym_find(tok); 3051 4183 if (!s || !(s->type.t & VT_TYPEDEF)) 3052 4184 goto the_end; 3053 typedef_found = 1; 3054 t |= (s->type.t & ~VT_TYPEDEF); 4185 t &= ~(VT_BTYPE|VT_LONG); 4186 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u; 4187 type->t = (s->type.t & ~VT_TYPEDEF) | u; 3055 4188 type->ref = s->type.ref; 3056 if (s->r) { 3057 /* get attributes from typedef */ 3058 if (0 == ad->aligned) 3059 ad->aligned = FUNC_ALIGN(s->r); 3060 if (0 == ad->func_call) 3061 ad->func_call = FUNC_CALL(s->r); 3062 ad->packed |= FUNC_PACKED(s->r); 3063 } 4189 if (t) 4190 parse_btype_qualify(type, t); 4191 t = type->t; 4192 /* get attributes from typedef */ 4193 sym_to_attr(ad, s); 3064 4194 next(); 3065 4195 typespec_found = 1; 4196 st = bt = -2; 3066 4197 break; 3067 4198 } … … 3069 4200 } 3070 4201 the_end: 3071 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))3072 tcc_error("signed and unsigned modifier");3073 4202 if (tcc_state->char_is_unsigned) { 3074 if ((t & (VT_ SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)4203 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE) 3075 4204 t |= VT_UNSIGNED; 3076 4205 } 3077 t &= ~VT_SIGNED; 3078 3079 /* long is never used as type */ 3080 if ((t & VT_BTYPE) == VT_LONG) 3081 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE 3082 t = (t & ~VT_BTYPE) | VT_INT; 3083 #else 3084 t = (t & ~VT_BTYPE) | VT_LLONG; 4206 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */ 4207 bt = t & (VT_BTYPE|VT_LONG); 4208 if (bt == VT_LONG) 4209 t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT; 4210 #ifdef TCC_TARGET_PE 4211 if (bt == VT_LDOUBLE) 4212 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE; 3085 4213 #endif 3086 4214 type->t = t; … … 3105 4233 { 3106 4234 skip('('); 3107 /* read the string */ 3108 if (tok != TOK_STR) 3109 expect("string constant"); 3110 cstr_new(astr); 3111 while (tok == TOK_STR) { 3112 /* XXX: add \0 handling too ? */ 3113 cstr_cat(astr, tokc.cstr->data); 3114 next(); 3115 } 3116 cstr_ccat(astr, '\0'); 3117 } 3118 3119 /* Parse an asm label and return the label 3120 * Don't forget to free the CString in the caller! */ 3121 static void asm_label_instr(CString *astr) 3122 { 4235 parse_mult_str(astr, "string constant"); 4236 } 4237 4238 /* Parse an asm label and return the token */ 4239 static int asm_label_instr(void) 4240 { 4241 int v; 4242 CString astr; 4243 3123 4244 next(); 3124 parse_asm_str( astr);4245 parse_asm_str(&astr); 3125 4246 skip(')'); 3126 4247 #ifdef ASM_DEBUG 3127 printf("asm_alias: \"%s\"\n", (char *)astr->data); 3128 #endif 3129 } 3130 3131 static void post_type(CType *type, AttributeDef *ad) 4248 printf("asm_alias: \"%s\"\n", (char *)astr.data); 4249 #endif 4250 v = tok_alloc(astr.data, astr.size - 1)->tok; 4251 cstr_free(&astr); 4252 return v; 4253 } 4254 4255 static int post_type(CType *type, AttributeDef *ad, int storage, int td) 3132 4256 { 3133 4257 int n, l, t1, arg_size, align; … … 3137 4261 3138 4262 if (tok == '(') { 3139 /* function declaration*/4263 /* function type, or recursive declarator (return if so) */ 3140 4264 next(); 3141 l = 0; 4265 if (td && !(td & TYPE_ABSTRACT)) 4266 return 0; 4267 if (tok == ')') 4268 l = 0; 4269 else if (parse_btype(&pt, &ad1)) 4270 l = FUNC_NEW; 4271 else if (td) 4272 return 0; 4273 else 4274 l = FUNC_OLD; 3142 4275 first = NULL; 3143 4276 plast = &first; 3144 4277 arg_size = 0; 3145 if ( tok != ')') {4278 if (l) { 3146 4279 for(;;) { 3147 4280 /* read param name and compute offset */ 3148 4281 if (l != FUNC_OLD) { 3149 if (!parse_btype(&pt, &ad1)) {3150 if (l) {3151 tcc_error("invalid type");3152 } else {3153 l = FUNC_OLD;3154 goto old_proto;3155 }3156 }3157 l = FUNC_NEW;3158 4282 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')') 3159 4283 break; … … 3163 4287 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE; 3164 4288 } else { 3165 old_proto:3166 4289 n = tok; 3167 4290 if (n < TOK_UIDENT) 3168 4291 expect("identifier"); 3169 pt.t = VT_ INT;4292 pt.t = VT_VOID; /* invalid type */ 3170 4293 next(); 3171 4294 } … … 3182 4305 break; 3183 4306 } 3184 } 3185 } 3186 /* if no parameters, then old type prototype */ 3187 if (l == 0) 4307 if (l == FUNC_NEW && !parse_btype(&pt, &ad1)) 4308 tcc_error("invalid type"); 4309 } 4310 } else 4311 /* if no parameters, then old type prototype */ 3188 4312 l = FUNC_OLD; 3189 4313 skip(')'); … … 3197 4321 next(); 3198 4322 skip(']'); /* only handle simple "[]" */ 3199 type->t |= VT_PTR;4323 mk_pointer(type); 3200 4324 } 3201 4325 /* we push a anonymous symbol which will contain the function prototype */ 3202 ad->func_args = arg_size; 3203 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); 4326 ad->f.func_args = arg_size; 4327 ad->f.func_type = l; 4328 s = sym_push(SYM_FIELD, type, 0, 0); 4329 s->a = ad->a; 4330 s->f = ad->f; 3204 4331 s->next = first; 3205 4332 type->t = VT_FUNC; 3206 4333 type->ref = s; 3207 4334 } else if (tok == '[') { 4335 int saved_nocode_wanted = nocode_wanted; 3208 4336 /* array definition */ 3209 4337 next(); … … 3213 4341 t1 = 0; 3214 4342 if (tok != ']') { 3215 if (!local_stack || nocode_wanted) 3216 vpushi(expr_const()); 3217 else gexpr(); 4343 if (!local_stack || (storage & VT_STATIC)) 4344 vpushi(expr_const()); 4345 else { 4346 /* VLAs (which can only happen with local_stack && !VT_STATIC) 4347 length must always be evaluated, even under nocode_wanted, 4348 so that its size slot is initialized (e.g. under sizeof 4349 or typeof). */ 4350 nocode_wanted = 0; 4351 gexpr(); 4352 } 3218 4353 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { 3219 4354 n = vtop->c.i; … … 3228 4363 skip(']'); 3229 4364 /* parse next post type */ 3230 post_type(type, ad); 4365 post_type(type, ad, storage, 0); 4366 if (type->t == VT_FUNC) 4367 tcc_error("declaration of an array of functions"); 3231 4368 t1 |= type->t & VT_VLA; 3232 4369 … … 3238 4375 vla_runtime_type_size(type, &align); 3239 4376 gen_op('*'); 3240 vset(&int_type, VT_LOCAL|VT_LVAL, loc);4377 vset(&int_type, VT_LOCAL|VT_LVAL, n); 3241 4378 vswap(); 3242 4379 vstore(); … … 3244 4381 if (n != -1) 3245 4382 vpop(); 4383 nocode_wanted = saved_nocode_wanted; 3246 4384 3247 4385 /* we push an anonymous symbol which will contain the array … … 3251 4389 type->ref = s; 3252 4390 } 3253 } 3254 3255 /* Parse a type declaration (except basic type), and return the type 4391 return 1; 4392 } 4393 4394 /* Parse a type declarator (except basic type), and return the type 3256 4395 in 'type'. 'td' is a bitmask indicating which kind of type decl is 3257 4396 expected. 'type' should contain the basic type. 'ad' is the 3258 4397 attribute definition of the basic type. It can be modified by 3259 type_decl(). 3260 */3261 static void type_decl(CType *type, AttributeDef *ad, int *v, int td) 3262 { 3263 Sym *s; 3264 CType type1, *type2;4398 type_decl(). If this (possibly abstract) declarator is a pointer chain 4399 it returns the innermost pointed to type (equals *type, but is a different 4400 pointer), otherwise returns type itself, that's used for recursive calls. */ 4401 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) 4402 { 4403 CType *post, *ret; 3265 4404 int qualifiers, storage; 4405 4406 /* recursive type, remove storage bits first, apply them later again */ 4407 storage = type->t & VT_STORAGE; 4408 type->t &= ~VT_STORAGE; 4409 post = ret = type; 3266 4410 3267 4411 while (tok == '*') { … … 3284 4428 case TOK_RESTRICT3: 3285 4429 goto redo; 4430 /* XXX: clarify attribute handling */ 4431 case TOK_ATTRIBUTE1: 4432 case TOK_ATTRIBUTE2: 4433 parse_attribute(ad); 4434 break; 3286 4435 } 3287 4436 mk_pointer(type); 3288 4437 type->t |= qualifiers; 3289 } 3290 3291 /* XXX: clarify attribute handling */ 3292 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) 3293 parse_attribute(ad); 3294 3295 /* recursive type */ 3296 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ 3297 type1.t = 0; /* XXX: same as int */ 4438 if (ret == type) 4439 /* innermost pointed to type is the one for the first derivation */ 4440 ret = pointed_type(type); 4441 } 4442 3298 4443 if (tok == '(') { 3299 next(); 3300 /* XXX: this is not correct to modify 'ad' at this point, but 3301 the syntax is not clear */ 3302 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) 3303 parse_attribute(ad); 3304 type_decl(&type1, ad, v, td); 3305 skip(')'); 4444 /* This is possibly a parameter type list for abstract declarators 4445 ('int ()'), use post_type for testing this. */ 4446 if (!post_type(type, ad, 0, td)) { 4447 /* It's not, so it's a nested declarator, and the post operations 4448 apply to the innermost pointed to type (if any). */ 4449 /* XXX: this is not correct to modify 'ad' at this point, but 4450 the syntax is not clear */ 4451 parse_attribute(ad); 4452 post = type_decl(type, ad, v, td); 4453 skip(')'); 4454 } 4455 } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { 4456 /* type identifier */ 4457 *v = tok; 4458 next(); 3306 4459 } else { 3307 /* type identifier */ 3308 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { 3309 *v = tok; 3310 next(); 3311 } else { 3312 if (!(td & TYPE_ABSTRACT)) 3313 expect("identifier"); 3314 *v = 0; 3315 } 3316 } 3317 storage = type->t & VT_STORAGE; 3318 type->t &= ~VT_STORAGE; 3319 if (storage & VT_STATIC) { 3320 int saved_nocode_wanted = nocode_wanted; 3321 nocode_wanted = 1; 3322 post_type(type, ad); 3323 nocode_wanted = saved_nocode_wanted; 3324 } else 3325 post_type(type, ad); 4460 if (!(td & TYPE_ABSTRACT)) 4461 expect("identifier"); 4462 *v = 0; 4463 } 4464 post_type(post, ad, storage, 0); 4465 parse_attribute(ad); 3326 4466 type->t |= storage; 3327 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) 3328 parse_attribute(ad); 3329 3330 if (!type1.t) 3331 return; 3332 /* append type at the end of type1 */ 3333 type2 = &type1; 3334 for(;;) { 3335 s = type2->ref; 3336 type2 = &s->type; 3337 if (!type2->t) { 3338 *type2 = *type; 3339 break; 3340 } 3341 } 3342 *type = type1; 4467 return ret; 3343 4468 } 3344 4469 … … 3368 4493 expect("pointer"); 3369 4494 } 3370 if ( (vtop->r & VT_LVAL) && !nocode_wanted)4495 if (vtop->r & VT_LVAL) 3371 4496 gv(RC_INT); 3372 4497 vtop->type = *pointed_type(&vtop->type); … … 3389 4514 CType type; 3390 4515 3391 func_type = func-> c;4516 func_type = func->f.func_type; 3392 4517 if (func_type == FUNC_OLD || 3393 4518 (func_type == FUNC_ELLIPSIS && arg == NULL)) { 3394 4519 /* default casting : only need to convert float to double */ 3395 4520 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) { 3396 type.t = VT_DOUBLE; 4521 gen_cast_s(VT_DOUBLE); 4522 } else if (vtop->type.t & VT_BITFIELD) { 4523 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED); 4524 type.ref = vtop->type.ref; 3397 4525 gen_cast(&type); 3398 4526 } … … 3406 4534 } 3407 4535 4536 /* parse an expression and return its type without any side effect. */ 4537 static void expr_type(CType *type, void (*expr_fn)(void)) 4538 { 4539 nocode_wanted++; 4540 expr_fn(); 4541 *type = vtop->type; 4542 vpop(); 4543 nocode_wanted--; 4544 } 4545 3408 4546 /* parse an expression of the form '(type)' or '(expr)' and return its 3409 4547 type */ … … 3417 4555 type_decl(type, &ad, &n, TYPE_ABSTRACT); 3418 4556 } else { 3419 expr_type(type );4557 expr_type(type, gexpr); 3420 4558 } 3421 4559 skip(')'); … … 3433 4571 } 3434 4572 3435 static void vpush_tokc(int t) 3436 { 3437 CType type; 3438 type.t = t; 3439 type.ref = 0; 3440 vsetc(&type, VT_CONST, &tokc); 4573 static void parse_builtin_params(int nc, const char *args) 4574 { 4575 char c, sep = '('; 4576 CType t; 4577 if (nc) 4578 nocode_wanted++; 4579 next(); 4580 while ((c = *args++)) { 4581 skip(sep); 4582 sep = ','; 4583 switch (c) { 4584 case 'e': expr_eq(); continue; 4585 case 't': parse_type(&t); vpush(&t); continue; 4586 default: tcc_error("internal error"); break; 4587 } 4588 } 4589 skip(')'); 4590 if (nc) 4591 nocode_wanted--; 3441 4592 } 3442 4593 … … 3447 4598 Sym *s; 3448 4599 AttributeDef ad; 3449 static int in_sizeof = 0;3450 4600 3451 4601 sizeof_caller = in_sizeof; 3452 4602 in_sizeof = 0; 4603 type.ref = NULL; 3453 4604 /* XXX: GCC 2.95.3 does not generate a table although it should be 3454 4605 better here */ … … 3458 4609 next(); 3459 4610 goto tok_next; 4611 case TOK_LCHAR: 4612 #ifdef TCC_TARGET_PE 4613 t = VT_SHORT|VT_UNSIGNED; 4614 goto push_tokc; 4615 #endif 3460 4616 case TOK_CINT: 3461 4617 case TOK_CCHAR: 3462 case TOK_LCHAR: 3463 vpushi(tokc.i); 4618 t = VT_INT; 4619 push_tokc: 4620 type.t = t; 4621 vsetc(&type, VT_CONST, &tokc); 3464 4622 next(); 3465 4623 break; 3466 4624 case TOK_CUINT: 3467 vpush_tokc(VT_INT | VT_UNSIGNED); 3468 next(); 3469 break; 4625 t = VT_INT | VT_UNSIGNED; 4626 goto push_tokc; 3470 4627 case TOK_CLLONG: 3471 vpush_tokc(VT_LLONG); 3472 next(); 3473 break; 4628 t = VT_LLONG; 4629 goto push_tokc; 3474 4630 case TOK_CULLONG: 3475 vpush_tokc(VT_LLONG | VT_UNSIGNED); 3476 next(); 3477 break; 4631 t = VT_LLONG | VT_UNSIGNED; 4632 goto push_tokc; 3478 4633 case TOK_CFLOAT: 3479 vpush_tokc(VT_FLOAT); 3480 next(); 3481 break; 4634 t = VT_FLOAT; 4635 goto push_tokc; 3482 4636 case TOK_CDOUBLE: 3483 vpush_tokc(VT_DOUBLE); 3484 next(); 3485 break; 4637 t = VT_DOUBLE; 4638 goto push_tokc; 3486 4639 case TOK_CLDOUBLE: 3487 vpush_tokc(VT_LDOUBLE); 3488 next(); 3489 break; 4640 t = VT_LDOUBLE; 4641 goto push_tokc; 4642 case TOK_CLONG: 4643 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG; 4644 goto push_tokc; 4645 case TOK_CULONG: 4646 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED; 4647 goto push_tokc; 3490 4648 case TOK___FUNCTION__: 3491 4649 if (!gnu_ext) … … 3504 4662 type.ref->c = len; 3505 4663 vpush_ref(&type, data_section, data_section->data_offset, len); 3506 ptr = section_ptr_add(data_section, len); 3507 memcpy(ptr, funcname, len); 4664 if (!NODATA_WANTED) { 4665 ptr = section_ptr_add(data_section, len); 4666 memcpy(ptr, funcname, len); 4667 } 3508 4668 next(); 3509 4669 } … … 3519 4679 /* string parsing */ 3520 4680 t = VT_BYTE; 4681 if (tcc_state->char_is_unsigned) 4682 t = VT_BYTE | VT_UNSIGNED; 3521 4683 str_init: 3522 4684 if (tcc_state->warn_write_strings) … … 3526 4688 type.t |= VT_ARRAY; 3527 4689 memset(&ad, 0, sizeof(AttributeDef)); 3528 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL,0);4690 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0); 3529 4691 break; 3530 4692 case '(': … … 3545 4707 r |= lvalue_type(type.t); 3546 4708 memset(&ad, 0, sizeof(AttributeDef)); 3547 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL,0);4709 decl_initializer_alloc(&type, &ad, r, 1, 0, 0); 3548 4710 } else { 3549 4711 if (sizeof_caller) { … … 3555 4717 } 3556 4718 } else if (tok == '{') { 4719 int saved_nocode_wanted = nocode_wanted; 4720 if (const_wanted) 4721 tcc_error("expected constant"); 3557 4722 /* save all registers */ 3558 save_regs(0); 4723 save_regs(0); 3559 4724 /* statement expression : we do not accept break/continue 3560 inside as GCC does */ 3561 block(NULL, NULL, NULL, NULL, 0, 1); 4725 inside as GCC does. We do retain the nocode_wanted state, 4726 as statement expressions can't ever be entered from the 4727 outside, so any reactivation of code emission (from labels 4728 or loop heads) can be disabled again after the end of it. */ 4729 block(NULL, NULL, 1); 4730 nocode_wanted = saved_nocode_wanted; 3562 4731 skip(')'); 3563 4732 } else { … … 3580 4749 /* arrays can also be used although they are not lvalues */ 3581 4750 if ((vtop->type.t & VT_BTYPE) != VT_FUNC && 3582 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))4751 !(vtop->type.t & VT_ARRAY)) 3583 4752 test_lvalue(); 3584 4753 mk_pointer(&vtop->type); … … 3589 4758 unary(); 3590 4759 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { 3591 CType boolean; 3592 boolean.t = VT_BOOL; 3593 gen_cast(&boolean); 4760 gen_cast_s(VT_BOOL); 3594 4761 vtop->c.i = !vtop->c.i; 3595 4762 } else if ((vtop->r & VT_VALMASK) == VT_CMP) 3596 vtop->c.i = vtop->c.i ^1;4763 vtop->c.i ^= 1; 3597 4764 else { 3598 4765 save_regs(1); 3599 vseti(VT_JMP, g tst(1, 0));4766 vseti(VT_JMP, gvtst(1, 0)); 3600 4767 } 3601 4768 break; … … 3608 4775 case '+': 3609 4776 next(); 3610 /* in order to force cast, we add zero */3611 4777 unary(); 3612 4778 if ((vtop->type.t & VT_BTYPE) == VT_PTR) 3613 4779 tcc_error("pointer not accepted for unary plus"); 3614 vpushi(0); 3615 gen_op('+'); 4780 /* In order to force cast, we add zero, except for floating point 4781 where we really need an noop (otherwise -0.0 will be transformed 4782 into +0.0). */ 4783 if (!is_float(vtop->type.t)) { 4784 vpushi(0); 4785 gen_op('+'); 4786 } 3616 4787 break; 3617 4788 case TOK_SIZEOF: … … 3621 4792 next(); 3622 4793 in_sizeof++; 3623 unary_type(&type); // Perform a in_sizeof = 0; 4794 expr_type(&type, unary); /* Perform a in_sizeof = 0; */ 4795 s = vtop[1].sym; /* hack: accessing previous vtop */ 3624 4796 size = type_size(&type, &align); 4797 if (s && s->a.aligned) 4798 align = 1 << (s->a.aligned - 1); 3625 4799 if (t == TOK_SIZEOF) { 3626 4800 if (!(type.t & VT_VLA)) { … … 3637 4811 break; 3638 4812 4813 case TOK_builtin_expect: 4814 /* __builtin_expect is a no-op for now */ 4815 parse_builtin_params(0, "ee"); 4816 vpop(); 4817 break; 3639 4818 case TOK_builtin_types_compatible_p: 4819 parse_builtin_params(0, "tt"); 4820 vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE); 4821 vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE); 4822 n = is_compatible_types(&vtop[-1].type, &vtop[0].type); 4823 vtop -= 2; 4824 vpushi(n); 4825 break; 4826 case TOK_builtin_choose_expr: 4827 { 4828 int64_t c; 4829 next(); 4830 skip('('); 4831 c = expr_const64(); 4832 skip(','); 4833 if (!c) { 4834 nocode_wanted++; 4835 } 4836 expr_eq(); 4837 if (!c) { 4838 vpop(); 4839 nocode_wanted--; 4840 } 4841 skip(','); 4842 if (c) { 4843 nocode_wanted++; 4844 } 4845 expr_eq(); 4846 if (c) { 4847 vpop(); 4848 nocode_wanted--; 4849 } 4850 skip(')'); 4851 } 4852 break; 4853 case TOK_builtin_constant_p: 4854 parse_builtin_params(1, "e"); 4855 n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 4856 vtop--; 4857 vpushi(n); 4858 break; 4859 case TOK_builtin_frame_address: 4860 case TOK_builtin_return_address: 3640 4861 { 3641 CType type1, type2; 4862 int tok1 = tok; 4863 int level; 3642 4864 next(); 3643 4865 skip('('); 3644 parse_type(&type1); 3645 skip(','); 3646 parse_type(&type2); 3647 skip(')'); 3648 type1.t &= ~(VT_CONSTANT | VT_VOLATILE); 3649 type2.t &= ~(VT_CONSTANT | VT_VOLATILE); 3650 vpushi(is_compatible_types(&type1, &type2)); 3651 } 3652 break; 3653 case TOK_builtin_constant_p: 3654 { 3655 int saved_nocode_wanted, res; 3656 next(); 3657 skip('('); 3658 saved_nocode_wanted = nocode_wanted; 3659 nocode_wanted = 1; 3660 gexpr(); 3661 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 3662 vpop(); 3663 nocode_wanted = saved_nocode_wanted; 3664 skip(')'); 3665 vpushi(res); 3666 } 3667 break; 3668 case TOK_builtin_frame_address: 3669 { 3670 int level; 3671 CType type; 3672 next(); 3673 skip('('); 3674 if (tok != TOK_CINT || tokc.i < 0) { 3675 tcc_error("__builtin_frame_address only takes positive integers"); 3676 } 3677 level = tokc.i; 4866 if (tok != TOK_CINT) { 4867 tcc_error("%s only takes positive integers", 4868 tok1 == TOK_builtin_return_address ? 4869 "__builtin_return_address" : 4870 "__builtin_frame_address"); 4871 } 4872 level = (uint32_t)tokc.i; 3678 4873 next(); 3679 4874 skip(')'); … … 3685 4880 indir(); /* -> parent frame */ 3686 4881 } 4882 if (tok1 == TOK_builtin_return_address) { 4883 // assume return address is just above frame pointer on stack 4884 vpushi(PTR_SIZE); 4885 gen_op('+'); 4886 mk_pointer(&vtop->type); 4887 indir(); 4888 } 3687 4889 } 3688 4890 break; 3689 4891 #ifdef TCC_TARGET_X86_64 4892 #ifdef TCC_TARGET_PE 4893 case TOK_builtin_va_start: 4894 parse_builtin_params(0, "ee"); 4895 r = vtop->r & VT_VALMASK; 4896 if (r == VT_LLOCAL) 4897 r = VT_LOCAL; 4898 if (r != VT_LOCAL) 4899 tcc_error("__builtin_va_start expects a local variable"); 4900 vtop->r = r; 4901 vtop->type = char_pointer_type; 4902 vtop->c.i += 8; 4903 vstore(); 4904 break; 4905 #else 3690 4906 case TOK_builtin_va_arg_types: 3691 { 3692 /* This definition must be synced with stdarg.h */ 3693 enum __va_arg_type { 3694 __va_gen_reg, __va_float_reg, __va_stack 3695 }; 3696 CType type; 3697 int bt; 3698 next(); 3699 skip('('); 3700 parse_type(&type); 3701 skip(')'); 3702 bt = type.t & VT_BTYPE; 3703 if (bt == VT_STRUCT || bt == VT_LDOUBLE) { 3704 vpushi(__va_stack); 3705 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) { 3706 vpushi(__va_float_reg); 3707 } else { 3708 vpushi(__va_gen_reg); 3709 } 3710 } 4907 parse_builtin_params(0, "t"); 4908 vpushi(classify_x86_64_va_arg(&vtop->type)); 4909 vswap(); 4910 vpop(); 3711 4911 break; 3712 4912 #endif 4913 #endif 4914 4915 #ifdef TCC_TARGET_ARM64 4916 case TOK___va_start: { 4917 parse_builtin_params(0, "ee"); 4918 //xx check types 4919 gen_va_start(); 4920 vpushi(0); 4921 vtop->type.t = VT_VOID; 4922 break; 4923 } 4924 case TOK___va_arg: { 4925 parse_builtin_params(0, "et"); 4926 type = vtop->type; 4927 vpop(); 4928 //xx check types 4929 gen_va_arg(&type); 4930 vtop->type = type; 4931 break; 4932 } 4933 case TOK___arm64_clear_cache: { 4934 parse_builtin_params(0, "ee"); 4935 gen_clear_cache(); 4936 vpushi(0); 4937 vtop->type.t = VT_VOID; 4938 break; 4939 } 4940 #endif 4941 /* pre operations */ 3713 4942 case TOK_INC: 3714 4943 case TOK_DEC: … … 3720 4949 case '-': 3721 4950 next(); 3722 vpushi(0);3723 4951 unary(); 3724 gen_op('-'); 4952 t = vtop->type.t & VT_BTYPE; 4953 if (is_float(t)) { 4954 /* In IEEE negate(x) isn't subtract(0,x), but rather 4955 subtract(-0, x). */ 4956 vpush(&vtop->type); 4957 if (t == VT_FLOAT) 4958 vtop->c.f = -1.0 * 0.0; 4959 else if (t == VT_DOUBLE) 4960 vtop->c.d = -1.0 * 0.0; 4961 else 4962 vtop->c.ld = -1.0 * 0.0; 4963 } else 4964 vpushi(0); 4965 vswap(); 4966 gen_op('-'); 3725 4967 break; 3726 4968 case TOK_LAND: … … 3743 4985 s->type.t |= VT_STATIC; 3744 4986 } 3745 vset(&s->type, VT_CONST | VT_SYM, 0); 3746 vtop->sym = s; 4987 vpushsym(&s->type, s); 3747 4988 next(); 3748 4989 break; 3749 4990 4991 case TOK_GENERIC: 4992 { 4993 CType controlling_type; 4994 int has_default = 0; 4995 int has_match = 0; 4996 int learn = 0; 4997 TokenString *str = NULL; 4998 4999 next(); 5000 skip('('); 5001 expr_type(&controlling_type, expr_eq); 5002 controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY); 5003 for (;;) { 5004 learn = 0; 5005 skip(','); 5006 if (tok == TOK_DEFAULT) { 5007 if (has_default) 5008 tcc_error("too many 'default'"); 5009 has_default = 1; 5010 if (!has_match) 5011 learn = 1; 5012 next(); 5013 } else { 5014 AttributeDef ad_tmp; 5015 int itmp; 5016 CType cur_type; 5017 parse_btype(&cur_type, &ad_tmp); 5018 type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); 5019 if (compare_types(&controlling_type, &cur_type, 0)) { 5020 if (has_match) { 5021 tcc_error("type match twice"); 5022 } 5023 has_match = 1; 5024 learn = 1; 5025 } 5026 } 5027 skip(':'); 5028 if (learn) { 5029 if (str) 5030 tok_str_free(str); 5031 skip_or_save_block(&str); 5032 } else { 5033 skip_or_save_block(NULL); 5034 } 5035 if (tok == ')') 5036 break; 5037 } 5038 if (!str) { 5039 char buf[60]; 5040 type_to_str(buf, sizeof buf, &controlling_type, NULL); 5041 tcc_error("type '%s' does not match any association", buf); 5042 } 5043 begin_macro(str, 1); 5044 next(); 5045 expr_eq(); 5046 if (tok != TOK_EOF) 5047 expect(","); 5048 end_macro(); 5049 next(); 5050 break; 5051 } 3750 5052 // special qnan , snan and infinity values 3751 5053 case TOK___NAN__: … … 3769 5071 expect("identifier"); 3770 5072 s = sym_find(t); 3771 if (!s) { 5073 if (!s || IS_ASM_SYM(s)) { 5074 const char *name = get_tok_str(t, NULL); 3772 5075 if (tok != '(') 3773 tcc_error("'%s' undeclared", get_tok_str(t, NULL));5076 tcc_error("'%s' undeclared", name); 3774 5077 /* for simple function calls, we tolerate undeclared 3775 5078 external reference to int() function */ 3776 if (tcc_state->warn_implicit_function_declaration) 3777 tcc_warning("implicit declaration of function '%s'", 3778 get_tok_str(t, NULL)); 5079 if (tcc_state->warn_implicit_function_declaration 5080 #ifdef TCC_TARGET_PE 5081 /* people must be warned about using undeclared WINAPI functions 5082 (which usually start with uppercase letter) */ 5083 || (name[0] >= 'A' && name[0] <= 'Z') 5084 #endif 5085 ) 5086 tcc_warning("implicit declaration of function '%s'", name); 3779 5087 s = external_global_sym(t, &func_old_type, 0); 3780 5088 } 3781 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) == 3782 (VT_STATIC | VT_INLINE | VT_FUNC)) { 3783 /* if referencing an inline function, then we generate a 3784 symbol to it if not already done. It will have the 3785 effect to generate code for it at the end of the 3786 compilation unit. Inline function as always 3787 generated in the text section. */ 3788 if (!s->c) 3789 put_extern_sym(s, text_section, 0, 0); 3790 r = VT_SYM | VT_CONST; 3791 } else { 3792 r = s->r; 3793 } 5089 5090 r = s->r; 5091 /* A symbol that has a register is a local register variable, 5092 which starts out as VT_LOCAL value. */ 5093 if ((r & VT_VALMASK) < VT_CONST) 5094 r = (r & ~VT_VALMASK) | VT_LOCAL; 5095 3794 5096 vset(&s->type, r, s->c); 3795 /* if forward reference, we must point to s */ 3796 if (vtop->r & VT_SYM) { 3797 vtop->sym = s; 3798 vtop->c.ul = 0; 5097 /* Point to s as backpointer (even without r&VT_SYM). 5098 Will be used by at least the x86 inline asm parser for 5099 regvars. */ 5100 vtop->sym = s; 5101 5102 if (r & VT_SYM) { 5103 vtop->c.i = 0; 5104 } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) { 5105 vtop->c.i = s->enum_val; 3799 5106 } 3800 5107 break; … … 3806 5113 inc(1, tok); 3807 5114 next(); 3808 } else if (tok == '.' || tok == TOK_ARROW ) {5115 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) { 3809 5116 int qualifiers; 3810 5117 /* field */ … … 3814 5121 test_lvalue(); 3815 5122 gaddrof(); 3816 next();3817 5123 /* expect pointer on structure */ 3818 5124 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) 3819 5125 expect("struct or union"); 3820 s = vtop->type.ref; 3821 /* find field */ 3822 tok |= SYM_FIELD; 3823 while ((s = s->next) != NULL) { 3824 if (s->v == tok) 3825 break; 3826 } 5126 if (tok == TOK_CDOUBLE) 5127 expect("field name"); 5128 next(); 5129 if (tok == TOK_CINT || tok == TOK_CUINT) 5130 expect("field name"); 5131 s = find_field(&vtop->type, tok); 3827 5132 if (!s) 3828 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));5133 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc)); 3829 5134 /* add field offset to pointer */ 3830 5135 vtop->type = char_pointer_type; /* change type to 'char *' */ … … 3839 5144 #ifdef CONFIG_TCC_BCHECK 3840 5145 /* if bound checking, the referenced pointer must be checked */ 3841 if (tcc_state->do_bounds_check )5146 if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL) 3842 5147 vtop->r |= VT_MUSTBOUND; 3843 5148 #endif … … 3853 5158 SValue ret; 3854 5159 Sym *sa; 3855 int nb_args ;5160 int nb_args, ret_nregs, ret_align, regsize, variadic; 3856 5161 3857 5162 /* function call */ … … 3873 5178 next(); 3874 5179 sa = s->next; /* first parameter */ 3875 nb_args = 0;5180 nb_args = regsize = 0; 3876 5181 ret.r2 = VT_CONST; 3877 5182 /* compute first implicit argument if a structure is returned */ 3878 5183 if ((s->type.t & VT_BTYPE) == VT_STRUCT) { 3879 /* get some space for the returned structure */ 3880 size = type_size(&s->type, &align); 3881 loc = (loc - size) & -align; 5184 variadic = (s->f.func_type == FUNC_ELLIPSIS); 5185 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type, 5186 &ret_align, ®size); 5187 if (!ret_nregs) { 5188 /* get some space for the returned structure */ 5189 size = type_size(&s->type, &align); 5190 #ifdef TCC_TARGET_ARM64 5191 /* On arm64, a small struct is return in registers. 5192 It is much easier to write it to memory if we know 5193 that we are allowed to write some extra bytes, so 5194 round the allocated space up to a power of 2: */ 5195 if (size < 16) 5196 while (size & (size - 1)) 5197 size = (size | (size - 1)) + 1; 5198 #endif 5199 loc = (loc - size) & -align; 5200 ret.type = s->type; 5201 ret.r = VT_LOCAL | VT_LVAL; 5202 /* pass it as 'int' to avoid structure arg passing 5203 problems */ 5204 vseti(VT_LOCAL, loc); 5205 ret.c = vtop->c; 5206 nb_args++; 5207 } 5208 } else { 5209 ret_nregs = 1; 3882 5210 ret.type = s->type; 3883 ret.r = VT_LOCAL | VT_LVAL; 3884 /* pass it as 'int' to avoid structure arg passing 3885 problems */ 3886 vseti(VT_LOCAL, loc); 3887 ret.c = vtop->c; 3888 nb_args++; 3889 } else { 3890 ret.type = s->type; 5211 } 5212 5213 if (ret_nregs) { 3891 5214 /* return in register */ 3892 5215 if (is_float(ret.type.t)) { 3893 5216 ret.r = reg_fret(ret.type.t); 5217 #ifdef TCC_TARGET_X86_64 5218 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT) 5219 ret.r2 = REG_QRET; 5220 #endif 3894 5221 } else { 5222 #ifndef TCC_TARGET_ARM64 5223 #ifdef TCC_TARGET_X86_64 5224 if ((ret.type.t & VT_BTYPE) == VT_QLONG) 5225 #else 3895 5226 if ((ret.type.t & VT_BTYPE) == VT_LLONG) 5227 #endif 3896 5228 ret.r2 = REG_LRET; 5229 #endif 3897 5230 ret.r = REG_IRET; 3898 5231 } … … 3914 5247 tcc_error("too few arguments to function"); 3915 5248 skip(')'); 3916 if (!nocode_wanted) { 3917 gfunc_call(nb_args); 3918 } else { 3919 vtop -= (nb_args + 1); 3920 } 5249 gfunc_call(nb_args); 5250 3921 5251 /* return value */ 3922 vsetc(&ret.type, ret.r, &ret.c); 3923 vtop->r2 = ret.r2; 5252 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) { 5253 vsetc(&ret.type, r, &ret.c); 5254 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */ 5255 } 5256 5257 /* handle packed struct return */ 5258 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) { 5259 int addr, offset; 5260 5261 size = type_size(&s->type, &align); 5262 /* We're writing whole regs often, make sure there's enough 5263 space. Assume register size is power of 2. */ 5264 if (regsize > align) 5265 align = regsize; 5266 loc = (loc - size) & -align; 5267 addr = loc; 5268 offset = 0; 5269 for (;;) { 5270 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset); 5271 vswap(); 5272 vstore(); 5273 vtop--; 5274 if (--ret_nregs == 0) 5275 break; 5276 offset += regsize; 5277 } 5278 vset(&s->type, VT_LOCAL | VT_LVAL, addr); 5279 } 3924 5280 } else { 3925 5281 break; … … 4024 5380 } 4025 5381 4026 /* XXX: fix this mess */4027 static void expr_land_const(void)4028 {4029 expr_or();4030 while (tok == TOK_LAND) {4031 next();4032 expr_or();4033 gen_op(TOK_LAND);4034 }4035 }4036 4037 /* XXX: fix this mess */4038 static void expr_lor_const(void)4039 {4040 expr_land_const();4041 while (tok == TOK_LOR) {4042 next();4043 expr_land_const();4044 gen_op(TOK_LOR);4045 }4046 }4047 4048 /* only used if non constant */4049 5382 static void expr_land(void) 4050 5383 { 4051 int t;4052 4053 5384 expr_or(); 4054 5385 if (tok == TOK_LAND) { 4055 t = 0; 4056 save_regs(1); 4057 for(;;) { 4058 t = gtst(1, t); 4059 if (tok != TOK_LAND) { 4060 vseti(VT_JMPI, t); 4061 break; 4062 } 4063 next(); 4064 expr_or(); 4065 } 5386 int t = 0; 5387 for(;;) { 5388 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { 5389 gen_cast_s(VT_BOOL); 5390 if (vtop->c.i) { 5391 vpop(); 5392 } else { 5393 nocode_wanted++; 5394 while (tok == TOK_LAND) { 5395 next(); 5396 expr_or(); 5397 vpop(); 5398 } 5399 nocode_wanted--; 5400 if (t) 5401 gsym(t); 5402 gen_cast_s(VT_INT); 5403 break; 5404 } 5405 } else { 5406 if (!t) 5407 save_regs(1); 5408 t = gvtst(1, t); 5409 } 5410 if (tok != TOK_LAND) { 5411 if (t) 5412 vseti(VT_JMPI, t); 5413 else 5414 vpushi(1); 5415 break; 5416 } 5417 next(); 5418 expr_or(); 5419 } 4066 5420 } 4067 5421 } … … 4069 5423 static void expr_lor(void) 4070 5424 { 4071 int t;4072 4073 5425 expr_land(); 4074 5426 if (tok == TOK_LOR) { 4075 t = 0; 4076 save_regs(1); 4077 for(;;) { 4078 t = gtst(0, t); 4079 if (tok != TOK_LOR) { 4080 vseti(VT_JMP, t); 4081 break; 4082 } 4083 next(); 4084 expr_land(); 4085 } 4086 } 4087 } 4088 4089 /* XXX: better constant handling */ 5427 int t = 0; 5428 for(;;) { 5429 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { 5430 gen_cast_s(VT_BOOL); 5431 if (!vtop->c.i) { 5432 vpop(); 5433 } else { 5434 nocode_wanted++; 5435 while (tok == TOK_LOR) { 5436 next(); 5437 expr_land(); 5438 vpop(); 5439 } 5440 nocode_wanted--; 5441 if (t) 5442 gsym(t); 5443 gen_cast_s(VT_INT); 5444 break; 5445 } 5446 } else { 5447 if (!t) 5448 save_regs(1); 5449 t = gvtst(0, t); 5450 } 5451 if (tok != TOK_LOR) { 5452 if (t) 5453 vseti(VT_JMP, t); 5454 else 5455 vpushi(0); 5456 break; 5457 } 5458 next(); 5459 expr_land(); 5460 } 5461 } 5462 } 5463 5464 /* Assuming vtop is a value used in a conditional context 5465 (i.e. compared with zero) return 0 if it's false, 1 if 5466 true and -1 if it can't be statically determined. */ 5467 static int condition_3way(void) 5468 { 5469 int c = -1; 5470 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && 5471 (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) { 5472 vdup(); 5473 gen_cast_s(VT_BOOL); 5474 c = vtop->c.i; 5475 vpop(); 5476 } 5477 return c; 5478 } 5479 4090 5480 static void expr_cond(void) 4091 5481 { 4092 int tt, u, r1, r2, rc, t1, t2, bt1, bt2 ;5482 int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g; 4093 5483 SValue sv; 4094 5484 CType type, type1, type2; 4095 5485 4096 if (const_wanted) { 4097 expr_lor_const(); 4098 if (tok == '?') { 4099 CType boolean; 4100 int c; 4101 boolean.t = VT_BOOL; 4102 vdup(); 4103 gen_cast(&boolean); 4104 c = vtop->c.i; 4105 vpop(); 4106 next(); 4107 if (tok != ':' || !gnu_ext) { 5486 expr_lor(); 5487 if (tok == '?') { 5488 next(); 5489 c = condition_3way(); 5490 g = (tok == ':' && gnu_ext); 5491 if (c < 0) { 5492 /* needed to avoid having different registers saved in 5493 each branch */ 5494 if (is_float(vtop->type.t)) { 5495 rc = RC_FLOAT; 5496 #ifdef TCC_TARGET_X86_64 5497 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { 5498 rc = RC_ST0; 5499 } 5500 #endif 5501 } else 5502 rc = RC_INT; 5503 gv(rc); 5504 save_regs(1); 5505 if (g) 5506 gv_dup(); 5507 tt = gvtst(1, 0); 5508 5509 } else { 5510 if (!g) 4108 5511 vpop(); 5512 tt = 0; 5513 } 5514 5515 if (1) { 5516 if (c == 0) 5517 nocode_wanted++; 5518 if (!g) 4109 5519 gexpr(); 4110 } 4111 if (!c) 4112 vpop(); 4113 skip(':'); 4114 expr_cond(); 4115 if (c) 4116 vpop(); 4117 } 4118 } else { 4119 expr_lor(); 4120 if (tok == '?') { 4121 next(); 4122 if (vtop != vstack) { 4123 /* needed to avoid having different registers saved in 4124 each branch */ 4125 if (is_float(vtop->type.t)) { 4126 rc = RC_FLOAT; 4127 #ifdef TCC_TARGET_X86_64 4128 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { 4129 rc = RC_ST0; 4130 } 4131 #endif 4132 } 4133 else 4134 rc = RC_INT; 4135 gv(rc); 4136 save_regs(1); 4137 } 4138 if (tok == ':' && gnu_ext) { 4139 gv_dup(); 4140 tt = gtst(1, 0); 4141 } else { 4142 tt = gtst(1, 0); 4143 gexpr(); 4144 } 5520 4145 5521 type1 = vtop->type; 4146 5522 sv = *vtop; /* save value to handle it later */ 4147 5523 vtop--; /* no vpop so that FP stack is not flushed */ 4148 5524 skip(':'); 4149 u = gjmp(0); 5525 5526 u = 0; 5527 if (c < 0) 5528 u = gjmp(0); 4150 5529 gsym(tt); 5530 5531 if (c == 0) 5532 nocode_wanted--; 5533 if (c == 1) 5534 nocode_wanted++; 4151 5535 expr_cond(); 5536 if (c == 1) 5537 nocode_wanted--; 5538 4152 5539 type2 = vtop->type; 4153 4154 5540 t1 = type1.t; 4155 5541 bt1 = t1 & VT_BTYPE; 4156 5542 t2 = type2.t; 4157 5543 bt2 = t2 & VT_BTYPE; 5544 type.ref = NULL; 5545 4158 5546 /* cast operands to correct type according to ISOC rules */ 4159 5547 if (is_float(bt1) || is_float(bt2)) { 4160 5548 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { 4161 5549 type.t = VT_LDOUBLE; 5550 4162 5551 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) { 4163 5552 type.t = VT_DOUBLE; … … 4167 5556 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { 4168 5557 /* cast to biggest op */ 4169 type.t = VT_LLONG; 5558 type.t = VT_LLONG | VT_LONG; 5559 if (bt1 == VT_LLONG) 5560 type.t &= t1; 5561 if (bt2 == VT_LLONG) 5562 type.t &= t2; 4170 5563 /* convert to unsigned if it does not fit in a long long */ 4171 if ((t1 & (VT_BTYPE | VT_UNSIGNED )) == (VT_LLONG | VT_UNSIGNED) ||4172 (t2 & (VT_BTYPE | VT_UNSIGNED )) == (VT_LLONG | VT_UNSIGNED))5564 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) || 5565 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED)) 4173 5566 type.t |= VT_UNSIGNED; 4174 5567 } else if (bt1 == VT_PTR || bt2 == VT_PTR) { … … 4194 5587 } else { 4195 5588 /* integer operations */ 4196 type.t = VT_INT ;5589 type.t = VT_INT | (VT_LONG & (t1 | t2)); 4197 5590 /* convert to unsigned if it does not fit in an integer */ 4198 if ((t1 & (VT_BTYPE | VT_UNSIGNED )) == (VT_INT | VT_UNSIGNED) ||4199 (t2 & (VT_BTYPE | VT_UNSIGNED )) == (VT_INT | VT_UNSIGNED))5591 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) || 5592 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED)) 4200 5593 type.t |= VT_UNSIGNED; 4201 5594 } 4202 5595 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so 5596 that `(expr ? a : b).mem` does not error with "lvalue expected" */ 5597 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE); 5598 islv &= c < 0; 5599 4203 5600 /* now we convert second operand */ 4204 gen_cast(&type); 4205 if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) 4206 gaddrof(); 5601 if (c != 1) { 5602 gen_cast(&type); 5603 if (islv) { 5604 mk_pointer(&vtop->type); 5605 gaddrof(); 5606 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) 5607 gaddrof(); 5608 } 5609 4207 5610 rc = RC_INT; 4208 5611 if (is_float(type.t)) { … … 4216 5619 /* for long longs, we use fixed registers to avoid having 4217 5620 to handle a complicated move */ 4218 rc = RC_IRET; 4219 } 4220 4221 r2 = gv(rc); 5621 rc = RC_IRET; 5622 } 5623 5624 tt = r2 = 0; 5625 if (c < 0) { 5626 r2 = gv(rc); 5627 tt = gjmp(0); 5628 } 5629 gsym(u); 5630 4222 5631 /* this is horrible, but we must also convert first 4223 5632 operand */ 4224 tt = gjmp(0); 4225 gsym(u); 4226 /* put again first value and cast it */ 4227 *vtop = sv; 4228 gen_cast(&type); 4229 if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) 4230 gaddrof(); 4231 r1 = gv(rc); 4232 move_reg(r2, r1); 4233 vtop->r = r2; 4234 gsym(tt); 5633 if (c != 0) { 5634 *vtop = sv; 5635 gen_cast(&type); 5636 if (islv) { 5637 mk_pointer(&vtop->type); 5638 gaddrof(); 5639 } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) 5640 gaddrof(); 5641 } 5642 5643 if (c < 0) { 5644 r1 = gv(rc); 5645 move_reg(r2, r1, type.t); 5646 vtop->r = r2; 5647 gsym(tt); 5648 if (islv) 5649 indir(); 5650 } 4235 5651 } 4236 5652 } … … 4271 5687 } 4272 5688 4273 /* parse an expression and return its type without any side effect. */4274 static void expr_type(CType *type)4275 {4276 int saved_nocode_wanted;4277 4278 saved_nocode_wanted = nocode_wanted;4279 nocode_wanted = 1;4280 gexpr();4281 *type = vtop->type;4282 vpop();4283 nocode_wanted = saved_nocode_wanted;4284 }4285 4286 /* parse a unary expression and return its type without any side4287 effect. */4288 static void unary_type(CType *type)4289 {4290 int a;4291 4292 a = nocode_wanted;4293 nocode_wanted = 1;4294 unary();4295 *type = vtop->type;4296 vpop();4297 nocode_wanted = a;4298 }4299 4300 5689 /* parse a constant expression and return value in vtop. */ 4301 5690 static void expr_const1(void) 4302 5691 { 4303 int a; 4304 a = const_wanted; 4305 const_wanted = 1; 5692 const_wanted++; 5693 nocode_wanted++; 4306 5694 expr_cond(); 4307 const_wanted = a; 5695 nocode_wanted--; 5696 const_wanted--; 4308 5697 } 4309 5698 4310 5699 /* parse an integer constant and return its value. */ 4311 ST_FUNC int expr_const(void)4312 { 4313 int c;5700 static inline int64_t expr_const64(void) 5701 { 5702 int64_t c; 4314 5703 expr_const1(); 4315 5704 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) … … 4317 5706 c = vtop->c.i; 4318 5707 vpop(); 5708 return c; 5709 } 5710 5711 /* parse an integer constant and return its value. 5712 Complain if it doesn't fit 32bit (signed or unsigned). */ 5713 ST_FUNC int expr_const(void) 5714 { 5715 int c; 5716 int64_t wc = expr_const64(); 5717 c = wc; 5718 if (c != wc && (unsigned)c != wc) 5719 tcc_error("constant exceeds 32 bit"); 4319 5720 return c; 4320 5721 } … … 4333 5734 next(); 4334 5735 if (tok == ':') { 4335 next();4336 5736 return last_tok; 4337 5737 } else { … … 4341 5741 } 4342 5742 4343 static void label_or_decl(int l) 4344 { 4345 int last_tok; 4346 4347 /* fast test first */ 4348 if (tok >= TOK_UIDENT) 4349 { 4350 /* no need to save tokc because tok is an identifier */ 4351 last_tok = tok; 4352 next(); 4353 if (tok == ':') { 4354 unget_tok(last_tok); 4355 return; 4356 } 4357 unget_tok(last_tok); 4358 } 4359 decl(l); 4360 } 4361 4362 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 4363 int case_reg, int is_expr) 4364 { 4365 int a, b, c, d; 4366 Sym *s, *frame_bottom; 5743 #ifndef TCC_TARGET_ARM64 5744 static void gfunc_return(CType *func_type) 5745 { 5746 if ((func_type->t & VT_BTYPE) == VT_STRUCT) { 5747 CType type, ret_type; 5748 int ret_align, ret_nregs, regsize; 5749 ret_nregs = gfunc_sret(func_type, func_var, &ret_type, 5750 &ret_align, ®size); 5751 if (0 == ret_nregs) { 5752 /* if returning structure, must copy it to implicit 5753 first pointer arg location */ 5754 type = *func_type; 5755 mk_pointer(&type); 5756 vset(&type, VT_LOCAL | VT_LVAL, func_vc); 5757 indir(); 5758 vswap(); 5759 /* copy structure value to pointer */ 5760 vstore(); 5761 } else { 5762 /* returning structure packed into registers */ 5763 int r, size, addr, align; 5764 size = type_size(func_type,&align); 5765 if ((vtop->r != (VT_LOCAL | VT_LVAL) || 5766 (vtop->c.i & (ret_align-1))) 5767 && (align & (ret_align-1))) { 5768 loc = (loc - size) & -ret_align; 5769 addr = loc; 5770 type = *func_type; 5771 vset(&type, VT_LOCAL | VT_LVAL, addr); 5772 vswap(); 5773 vstore(); 5774 vpop(); 5775 vset(&ret_type, VT_LOCAL | VT_LVAL, addr); 5776 } 5777 vtop->type = ret_type; 5778 if (is_float(ret_type.t)) 5779 r = rc_fret(ret_type.t); 5780 else 5781 r = RC_IRET; 5782 5783 if (ret_nregs == 1) 5784 gv(r); 5785 else { 5786 for (;;) { 5787 vdup(); 5788 gv(r); 5789 vpop(); 5790 if (--ret_nregs == 0) 5791 break; 5792 /* We assume that when a structure is returned in multiple 5793 registers, their classes are consecutive values of the 5794 suite s(n) = 2^n */ 5795 r <<= 1; 5796 vtop->c.i += regsize; 5797 } 5798 } 5799 } 5800 } else if (is_float(func_type->t)) { 5801 gv(rc_fret(func_type->t)); 5802 } else { 5803 gv(RC_IRET); 5804 } 5805 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ 5806 } 5807 #endif 5808 5809 static int case_cmp(const void *pa, const void *pb) 5810 { 5811 int64_t a = (*(struct case_t**) pa)->v1; 5812 int64_t b = (*(struct case_t**) pb)->v1; 5813 return a < b ? -1 : a > b; 5814 } 5815 5816 static void gcase(struct case_t **base, int len, int *bsym) 5817 { 5818 struct case_t *p; 5819 int e; 5820 int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG; 5821 gv(RC_INT); 5822 while (len > 4) { 5823 /* binary search */ 5824 p = base[len/2]; 5825 vdup(); 5826 if (ll) 5827 vpushll(p->v2); 5828 else 5829 vpushi(p->v2); 5830 gen_op(TOK_LE); 5831 e = gtst(1, 0); 5832 vdup(); 5833 if (ll) 5834 vpushll(p->v1); 5835 else 5836 vpushi(p->v1); 5837 gen_op(TOK_GE); 5838 gtst_addr(0, p->sym); /* v1 <= x <= v2 */ 5839 /* x < v1 */ 5840 gcase(base, len/2, bsym); 5841 if (cur_switch->def_sym) 5842 gjmp_addr(cur_switch->def_sym); 5843 else 5844 *bsym = gjmp(*bsym); 5845 /* x > v2 */ 5846 gsym(e); 5847 e = len/2 + 1; 5848 base += e; len -= e; 5849 } 5850 /* linear scan */ 5851 while (len--) { 5852 p = *base++; 5853 vdup(); 5854 if (ll) 5855 vpushll(p->v2); 5856 else 5857 vpushi(p->v2); 5858 if (p->v1 == p->v2) { 5859 gen_op(TOK_EQ); 5860 gtst_addr(0, p->sym); 5861 } else { 5862 gen_op(TOK_LE); 5863 e = gtst(1, 0); 5864 vdup(); 5865 if (ll) 5866 vpushll(p->v1); 5867 else 5868 vpushi(p->v1); 5869 gen_op(TOK_GE); 5870 gtst_addr(0, p->sym); 5871 gsym(e); 5872 } 5873 } 5874 } 5875 5876 static void block(int *bsym, int *csym, int is_expr) 5877 { 5878 int a, b, c, d, cond; 5879 Sym *s; 4367 5880 4368 5881 /* generate line number info */ 4369 if (tcc_state->do_debug && 4370 (last_line_num != file->line_num || last_ind != ind)) { 4371 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind); 4372 last_ind = ind; 4373 last_line_num = file->line_num; 4374 } 5882 if (tcc_state->do_debug) 5883 tcc_debug_line(tcc_state); 4375 5884 4376 5885 if (is_expr) { … … 4382 5891 if (tok == TOK_IF) { 4383 5892 /* if test */ 5893 int saved_nocode_wanted = nocode_wanted; 4384 5894 next(); 4385 5895 skip('('); 4386 5896 gexpr(); 4387 5897 skip(')'); 4388 a = gtst(1, 0); 4389 block(bsym, csym, case_sym, def_sym, case_reg, 0); 5898 cond = condition_3way(); 5899 if (cond == 1) 5900 a = 0, vpop(); 5901 else 5902 a = gvtst(1, 0); 5903 if (cond == 0) 5904 nocode_wanted |= 0x20000000; 5905 block(bsym, csym, 0); 5906 if (cond != 1) 5907 nocode_wanted = saved_nocode_wanted; 4390 5908 c = tok; 4391 5909 if (c == TOK_ELSE) { … … 4393 5911 d = gjmp(0); 4394 5912 gsym(a); 4395 block(bsym, csym, case_sym, def_sym, case_reg, 0); 5913 if (cond == 1) 5914 nocode_wanted |= 0x20000000; 5915 block(bsym, csym, 0); 4396 5916 gsym(d); /* patch else jmp */ 5917 if (cond != 0) 5918 nocode_wanted = saved_nocode_wanted; 4397 5919 } else 4398 5920 gsym(a); 4399 5921 } else if (tok == TOK_WHILE) { 5922 int saved_nocode_wanted; 5923 nocode_wanted &= ~0x20000000; 4400 5924 next(); 4401 5925 d = ind; 5926 vla_sp_restore(); 4402 5927 skip('('); 4403 5928 gexpr(); 4404 5929 skip(')'); 4405 a = g tst(1, 0);5930 a = gvtst(1, 0); 4406 5931 b = 0; 4407 block(&a, &b, case_sym, def_sym, case_reg, 0); 5932 ++local_scope; 5933 saved_nocode_wanted = nocode_wanted; 5934 block(&a, &b, 0); 5935 nocode_wanted = saved_nocode_wanted; 5936 --local_scope; 4408 5937 gjmp_addr(d); 4409 5938 gsym(a); … … 4411 5940 } else if (tok == '{') { 4412 5941 Sym *llabel; 4413 5942 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope; 5943 4414 5944 next(); 4415 5945 /* record local declaration stack position */ 4416 5946 s = local_stack; 4417 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);4418 frame_bottom->next = scope_stack_bottom;4419 scope_stack_bottom = frame_bottom;4420 5947 llabel = local_label_stack; 5948 ++local_scope; 5949 4421 5950 /* handle local labels declarations */ 4422 5951 if (tok == TOK_LABEL) { … … 4436 5965 } 4437 5966 while (tok != '}') { 4438 label_or_decl(VT_LOCAL); 5967 if ((a = is_label())) 5968 unget_tok(a); 5969 else 5970 decl(VT_LOCAL); 4439 5971 if (tok != '}') { 4440 5972 if (is_expr) 4441 5973 vpop(); 4442 block(bsym, csym, case_sym, def_sym, case_reg,is_expr);5974 block(bsym, csym, is_expr); 4443 5975 } 4444 5976 } 4445 5977 /* pop locally defined labels */ 4446 label_pop(&local_label_stack, llabel); 4447 if(is_expr) { 4448 /* XXX: this solution makes only valgrind happy... 4449 triggered by gcc.c-torture/execute/20000917-1.c */ 4450 Sym *p; 4451 switch(vtop->type.t & VT_BTYPE) { 4452 case VT_PTR: 4453 case VT_STRUCT: 4454 case VT_ENUM: 4455 case VT_FUNC: 4456 for(p=vtop->type.ref;p;p=p->prev) 4457 if(p->prev==s) 4458 tcc_error("unsupported expression type"); 4459 } 4460 } 5978 label_pop(&local_label_stack, llabel, is_expr); 4461 5979 /* pop locally defined symbols */ 4462 scope_stack_bottom = scope_stack_bottom->next; 4463 sym_pop(&local_stack, s); 5980 --local_scope; 5981 /* In the is_expr case (a statement expression is finished here), 5982 vtop might refer to symbols on the local_stack. Either via the 5983 type or via vtop->sym. We can't pop those nor any that in turn 5984 might be referred to. To make it easier we don't roll back 5985 any symbols in that case; some upper level call to block() will 5986 do that. We do have to remove such symbols from the lookup 5987 tables, though. sym_pop will do that. */ 5988 sym_pop(&local_stack, s, is_expr); 5989 5990 /* Pop VLA frames and restore stack pointer if required */ 5991 if (vlas_in_scope > saved_vlas_in_scope) { 5992 vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc; 5993 vla_sp_restore(); 5994 } 5995 vlas_in_scope = saved_vlas_in_scope; 5996 4464 5997 next(); 4465 5998 } else if (tok == TOK_RETURN) { … … 4468 6001 gexpr(); 4469 6002 gen_assign_cast(&func_vt); 4470 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { 4471 CType type; 4472 /* if returning structure, must copy it to implicit 4473 first pointer arg location */ 4474 #ifdef TCC_ARM_EABI 4475 int align, size; 4476 size = type_size(&func_vt,&align); 4477 if(size <= 4) 4478 { 4479 if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3)) 4480 && (align & 3)) 4481 { 4482 int addr; 4483 loc = (loc - size) & -4; 4484 addr = loc; 4485 type = func_vt; 4486 vset(&type, VT_LOCAL | VT_LVAL, addr); 4487 vswap(); 4488 vstore(); 4489 vset(&int_type, VT_LOCAL | VT_LVAL, addr); 4490 } 4491 vtop->type = int_type; 4492 gv(RC_IRET); 4493 } else { 4494 #endif 4495 type = func_vt; 4496 mk_pointer(&type); 4497 vset(&type, VT_LOCAL | VT_LVAL, func_vc); 4498 indir(); 4499 vswap(); 4500 /* copy structure value to pointer */ 4501 vstore(); 4502 #ifdef TCC_ARM_EABI 4503 } 4504 #endif 4505 } else if (is_float(func_vt.t)) { 4506 gv(rc_fret(func_vt.t)); 4507 } else { 4508 gv(RC_IRET); 4509 } 4510 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ 6003 if ((func_vt.t & VT_BTYPE) == VT_VOID) 6004 vtop--; 6005 else 6006 gfunc_return(&func_vt); 4511 6007 } 4512 6008 skip(';'); 4513 rsym = gjmp(rsym); /* jmp */ 6009 /* jump unless last stmt in top-level block */ 6010 if (tok != '}' || local_scope != 1) 6011 rsym = gjmp(rsym); 6012 nocode_wanted |= 0x20000000; 4514 6013 } else if (tok == TOK_BREAK) { 4515 6014 /* compute jump */ … … 4519 6018 next(); 4520 6019 skip(';'); 6020 nocode_wanted |= 0x20000000; 4521 6021 } else if (tok == TOK_CONTINUE) { 4522 6022 /* compute jump */ 4523 6023 if (!csym) 4524 6024 tcc_error("cannot continue"); 6025 vla_sp_restore_root(); 4525 6026 *csym = gjmp(*csym); 4526 6027 next(); … … 4528 6029 } else if (tok == TOK_FOR) { 4529 6030 int e; 6031 int saved_nocode_wanted; 6032 nocode_wanted &= ~0x20000000; 4530 6033 next(); 4531 6034 skip('('); 4532 6035 s = local_stack; 4533 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0); 4534 frame_bottom->next = scope_stack_bottom; 4535 scope_stack_bottom = frame_bottom; 6036 ++local_scope; 4536 6037 if (tok != ';') { 4537 6038 /* c99 for-loop init decl? */ 4538 if (!decl0(VT_LOCAL, 1 )) {6039 if (!decl0(VT_LOCAL, 1, NULL)) { 4539 6040 /* no, regular for-loop init expr */ 4540 6041 gexpr(); … … 4545 6046 d = ind; 4546 6047 c = ind; 6048 vla_sp_restore(); 4547 6049 a = 0; 4548 6050 b = 0; 4549 6051 if (tok != ';') { 4550 6052 gexpr(); 4551 a = g tst(1, 0);6053 a = gvtst(1, 0); 4552 6054 } 4553 6055 skip(';'); … … 4555 6057 e = gjmp(0); 4556 6058 c = ind; 6059 vla_sp_restore(); 4557 6060 gexpr(); 4558 6061 vpop(); … … 4561 6064 } 4562 6065 skip(')'); 4563 block(&a, &b, case_sym, def_sym, case_reg, 0); 6066 saved_nocode_wanted = nocode_wanted; 6067 block(&a, &b, 0); 6068 nocode_wanted = saved_nocode_wanted; 4564 6069 gjmp_addr(c); 4565 6070 gsym(a); 4566 6071 gsym_addr(b, c); 4567 scope_stack_bottom = scope_stack_bottom->next; 4568 sym_pop(&local_stack, s); 6072 --local_scope; 6073 sym_pop(&local_stack, s, 0); 6074 4569 6075 } else 4570 6076 if (tok == TOK_DO) { 6077 int saved_nocode_wanted; 6078 nocode_wanted &= ~0x20000000; 4571 6079 next(); 4572 6080 a = 0; 4573 6081 b = 0; 4574 6082 d = ind; 4575 block(&a, &b, case_sym, def_sym, case_reg, 0); 6083 vla_sp_restore(); 6084 saved_nocode_wanted = nocode_wanted; 6085 block(&a, &b, 0); 4576 6086 skip(TOK_WHILE); 4577 6087 skip('('); 4578 6088 gsym(b); 4579 gexpr(); 4580 c = gtst(0, 0); 4581 gsym_addr(c, d); 6089 gexpr(); 6090 c = gvtst(0, 0); 6091 gsym_addr(c, d); 6092 nocode_wanted = saved_nocode_wanted; 4582 6093 skip(')'); 4583 6094 gsym(a); … … 4585 6096 } else 4586 6097 if (tok == TOK_SWITCH) { 6098 struct switch_t *saved, sw; 6099 int saved_nocode_wanted = nocode_wanted; 6100 SValue switchval; 4587 6101 next(); 4588 6102 skip('('); 4589 6103 gexpr(); 4590 /* XXX: other types than integer */4591 case_reg = gv(RC_INT);4592 vpop();4593 6104 skip(')'); 6105 switchval = *vtop--; 4594 6106 a = 0; 4595 6107 b = gjmp(0); /* jump to first case */ 4596 c = 0; 4597 block(&a, csym, &b, &c, case_reg, 0); 4598 /* if no default, jmp after switch */ 4599 if (c == 0) 4600 c = ind; 4601 /* default label */ 4602 gsym_addr(b, c); 6108 sw.p = NULL; sw.n = 0; sw.def_sym = 0; 6109 saved = cur_switch; 6110 cur_switch = &sw; 6111 block(&a, csym, 0); 6112 nocode_wanted = saved_nocode_wanted; 6113 a = gjmp(a); /* add implicit break */ 6114 /* case lookup */ 6115 gsym(b); 6116 qsort(sw.p, sw.n, sizeof(void*), case_cmp); 6117 for (b = 1; b < sw.n; b++) 6118 if (sw.p[b - 1]->v2 >= sw.p[b]->v1) 6119 tcc_error("duplicate case value"); 6120 /* Our switch table sorting is signed, so the compared 6121 value needs to be as well when it's 64bit. */ 6122 if ((switchval.type.t & VT_BTYPE) == VT_LLONG) 6123 switchval.type.t &= ~VT_UNSIGNED; 6124 vpushv(&switchval); 6125 gcase(sw.p, sw.n, &a); 6126 vpop(); 6127 if (sw.def_sym) 6128 gjmp_addr(sw.def_sym); 6129 dynarray_reset(&sw.p, &sw.n); 6130 cur_switch = saved; 4603 6131 /* break label */ 4604 6132 gsym(a); 4605 6133 } else 4606 6134 if (tok == TOK_CASE) { 4607 int v1, v2;4608 if (!c ase_sym)6135 struct case_t *cr = tcc_malloc(sizeof(struct case_t)); 6136 if (!cur_switch) 4609 6137 expect("switch"); 6138 nocode_wanted &= ~0x20000000; 4610 6139 next(); 4611 v1 = expr_const(); 4612 v2 = v1; 6140 cr->v1 = cr->v2 = expr_const64(); 4613 6141 if (gnu_ext && tok == TOK_DOTS) { 4614 6142 next(); 4615 v2 = expr_const();4616 if ( v2 <v1)6143 cr->v2 = expr_const64(); 6144 if (cr->v2 < cr->v1) 4617 6145 tcc_warning("empty case range"); 4618 6146 } 4619 /* since a case is like a label, we must skip it with a jmp */ 4620 b = gjmp(0); 4621 gsym(*case_sym); 4622 vseti(case_reg, 0); 4623 vpushi(v1); 4624 if (v1 == v2) { 4625 gen_op(TOK_EQ); 4626 *case_sym = gtst(1, 0); 4627 } else { 4628 gen_op(TOK_GE); 4629 *case_sym = gtst(1, 0); 4630 vseti(case_reg, 0); 4631 vpushi(v2); 4632 gen_op(TOK_LE); 4633 *case_sym = gtst(1, *case_sym); 4634 } 4635 gsym(b); 6147 cr->sym = ind; 6148 dynarray_add(&cur_switch->p, &cur_switch->n, cr); 4636 6149 skip(':'); 4637 6150 is_expr = 0; … … 4641 6154 next(); 4642 6155 skip(':'); 4643 if (! def_sym)6156 if (!cur_switch) 4644 6157 expect("switch"); 4645 if ( *def_sym)6158 if (cur_switch->def_sym) 4646 6159 tcc_error("too many 'default'"); 4647 *def_sym = ind;6160 cur_switch->def_sym = ind; 4648 6161 is_expr = 0; 4649 6162 goto block_after_label; … … 4667 6180 s->r = LABEL_FORWARD; 4668 6181 } 4669 /* label already defined */4670 if (s->r & LABEL_FORWARD) 6182 vla_sp_restore_root(); 6183 if (s->r & LABEL_FORWARD) 4671 6184 s->jnext = gjmp(s->jnext); 4672 6185 else … … 4683 6196 if (b) { 4684 6197 /* label case */ 6198 next(); 4685 6199 s = label_find(b); 4686 6200 if (s) { … … 4693 6207 } 4694 6208 s->jnext = ind; 6209 vla_sp_restore(); 4695 6210 /* we accept this, but it is a mistake */ 4696 6211 block_after_label: 6212 nocode_wanted &= ~0x20000000; 4697 6213 if (tok == '}') { 4698 6214 tcc_warning("deprecated use of label at end of compound statement"); … … 4700 6216 if (is_expr) 4701 6217 vpop(); 4702 block(bsym, csym, case_sym, def_sym, case_reg,is_expr);6218 block(bsym, csym, is_expr); 4703 6219 } 4704 6220 } else { … … 4718 6234 } 4719 6235 4720 /* t is the array or struct type. c is the array or struct 4721 address. cur_index/cur_field is the pointer to the current 4722 value. 'size_only' is true if only size info is needed (only used 4723 in arrays) */ 4724 static void decl_designator(CType *type, Section *sec, unsigned long c, 4725 int *cur_index, Sym **cur_field, 4726 int size_only) 4727 { 4728 Sym *s, *f; 4729 int notfirst, index, index_last, align, l, nb_elems, elem_size; 4730 CType type1; 4731 4732 notfirst = 0; 4733 elem_size = 0; 4734 nb_elems = 1; 4735 if (gnu_ext && (l = is_label()) != 0) 4736 goto struct_field; 4737 while (tok == '[' || tok == '.') { 4738 if (tok == '[') { 4739 if (!(type->t & VT_ARRAY)) 4740 expect("array type"); 4741 s = type->ref; 4742 next(); 4743 index = expr_const(); 4744 if (index < 0 || (s->c >= 0 && index >= s->c)) 4745 expect("invalid index"); 4746 if (tok == TOK_DOTS && gnu_ext) { 4747 next(); 4748 index_last = expr_const(); 4749 if (index_last < 0 || 4750 (s->c >= 0 && index_last >= s->c) || 4751 index_last < index) 4752 expect("invalid index"); 4753 } else { 4754 index_last = index; 4755 } 4756 skip(']'); 4757 if (!notfirst) 4758 *cur_index = index_last; 4759 type = pointed_type(type); 4760 elem_size = type_size(type, &align); 4761 c += index * elem_size; 4762 /* NOTE: we only support ranges for last designator */ 4763 nb_elems = index_last - index + 1; 4764 if (nb_elems != 1) { 4765 notfirst = 1; 4766 break; 4767 } 4768 } else { 4769 next(); 4770 l = tok; 4771 next(); 4772 struct_field: 4773 if ((type->t & VT_BTYPE) != VT_STRUCT) 4774 expect("struct/union type"); 4775 s = type->ref; 4776 l |= SYM_FIELD; 4777 f = s->next; 4778 while (f) { 4779 if (f->v == l) 4780 break; 4781 f = f->next; 4782 } 4783 if (!f) 4784 expect("field"); 4785 if (!notfirst) 4786 *cur_field = f; 4787 /* XXX: fix this mess by using explicit storage field */ 4788 type1 = f->type; 4789 type1.t |= (type->t & ~VT_TYPE); 4790 type = &type1; 4791 c += f->c; 4792 } 4793 notfirst = 1; 4794 } 4795 if (notfirst) { 4796 if (tok == '=') { 4797 next(); 4798 } else { 4799 if (!gnu_ext) 4800 expect("="); 4801 } 4802 } else { 4803 if (type->t & VT_ARRAY) { 4804 index = *cur_index; 4805 type = pointed_type(type); 4806 c += index * type_size(type, &align); 4807 } else { 4808 f = *cur_field; 4809 if (!f) 4810 tcc_error("too many field init"); 4811 /* XXX: fix this mess by using explicit storage field */ 4812 type1 = f->type; 4813 type1.t |= (type->t & ~VT_TYPE); 4814 type = &type1; 4815 c += f->c; 4816 } 4817 } 4818 decl_initializer(type, sec, c, 0, size_only); 4819 4820 /* XXX: make it more general */ 4821 if (!size_only && nb_elems > 1) { 4822 unsigned long c_end; 4823 uint8_t *src, *dst; 4824 int i; 4825 4826 if (!sec) 4827 tcc_error("range init not supported yet for dynamic storage"); 4828 c_end = c + nb_elems * elem_size; 4829 if (c_end > sec->data_allocated) 4830 section_realloc(sec, c_end); 4831 src = sec->data + c; 4832 dst = src; 4833 for(i = 1; i < nb_elems; i++) { 4834 dst += elem_size; 4835 memcpy(dst, src, elem_size); 4836 } 4837 } 4838 } 4839 4840 #define EXPR_VAL 0 6236 /* This skips over a stream of tokens containing balanced {} and () 6237 pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started 6238 with a '{'). If STR then allocates and stores the skipped tokens 6239 in *STR. This doesn't check if () and {} are nested correctly, 6240 i.e. "({)}" is accepted. */ 6241 static void skip_or_save_block(TokenString **str) 6242 { 6243 int braces = tok == '{'; 6244 int level = 0; 6245 if (str) 6246 *str = tok_str_alloc(); 6247 6248 while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) { 6249 int t; 6250 if (tok == TOK_EOF) { 6251 if (str || level > 0) 6252 tcc_error("unexpected end of file"); 6253 else 6254 break; 6255 } 6256 if (str) 6257 tok_str_add_tok(*str); 6258 t = tok; 6259 next(); 6260 if (t == '{' || t == '(') { 6261 level++; 6262 } else if (t == '}' || t == ')') { 6263 level--; 6264 if (level == 0 && braces && t == '}') 6265 break; 6266 } 6267 } 6268 if (str) { 6269 tok_str_add(*str, -1); 6270 tok_str_add(*str, 0); 6271 } 6272 } 6273 4841 6274 #define EXPR_CONST 1 4842 6275 #define EXPR_ANY 2 4843 6276 4844 /* store a value or an expression directly in global data or in local array */ 4845 static void init_putv(CType *type, Section *sec, unsigned long c, 4846 int v, int expr_type) 4847 { 4848 int saved_global_expr, bt, bit_pos, bit_size; 4849 void *ptr; 4850 unsigned long long bit_mask; 4851 CType dtype; 4852 6277 static void parse_init_elem(int expr_type) 6278 { 6279 int saved_global_expr; 4853 6280 switch(expr_type) { 4854 case EXPR_VAL:4855 vpushi(v);4856 break;4857 6281 case EXPR_CONST: 4858 6282 /* compound literals must be allocated globally in this case */ … … 4861 6285 expr_const1(); 4862 6286 global_expr = saved_global_expr; 4863 /* NOTE: symbols are accepted */ 4864 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST) 6287 /* NOTE: symbols are accepted, as well as lvalue for anon symbols 6288 (compound literals). */ 6289 if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST 6290 && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL) 6291 || vtop->sym->v < SYM_FIRST_ANOM)) 6292 #ifdef TCC_TARGET_PE 6293 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport) 6294 #endif 6295 ) 4865 6296 tcc_error("initializer element is not constant"); 4866 6297 break; … … 4869 6300 break; 4870 6301 } 4871 6302 } 6303 6304 /* put zeros for variable based init */ 6305 static void init_putz(Section *sec, unsigned long c, int size) 6306 { 6307 if (sec) { 6308 /* nothing to do because globals are already set to zero */ 6309 } else { 6310 vpush_global_sym(&func_old_type, TOK_memset); 6311 vseti(VT_LOCAL, c); 6312 #ifdef TCC_TARGET_ARM 6313 vpushs(size); 6314 vpushi(0); 6315 #else 6316 vpushi(0); 6317 vpushs(size); 6318 #endif 6319 gfunc_call(3); 6320 } 6321 } 6322 6323 /* t is the array or struct type. c is the array or struct 6324 address. cur_field is the pointer to the current 6325 field, for arrays the 'c' member contains the current start 6326 index. 'size_only' is true if only size info is needed (only used 6327 in arrays). al contains the already initialized length of the 6328 current container (starting at c). This returns the new length of that. */ 6329 static int decl_designator(CType *type, Section *sec, unsigned long c, 6330 Sym **cur_field, int size_only, int al) 6331 { 6332 Sym *s, *f; 6333 int index, index_last, align, l, nb_elems, elem_size; 6334 unsigned long corig = c; 6335 6336 elem_size = 0; 6337 nb_elems = 1; 6338 if (gnu_ext && (l = is_label()) != 0) 6339 goto struct_field; 6340 /* NOTE: we only support ranges for last designator */ 6341 while (nb_elems == 1 && (tok == '[' || tok == '.')) { 6342 if (tok == '[') { 6343 if (!(type->t & VT_ARRAY)) 6344 expect("array type"); 6345 next(); 6346 index = index_last = expr_const(); 6347 if (tok == TOK_DOTS && gnu_ext) { 6348 next(); 6349 index_last = expr_const(); 6350 } 6351 skip(']'); 6352 s = type->ref; 6353 if (index < 0 || (s->c >= 0 && index_last >= s->c) || 6354 index_last < index) 6355 tcc_error("invalid index"); 6356 if (cur_field) 6357 (*cur_field)->c = index_last; 6358 type = pointed_type(type); 6359 elem_size = type_size(type, &align); 6360 c += index * elem_size; 6361 nb_elems = index_last - index + 1; 6362 } else { 6363 next(); 6364 l = tok; 6365 struct_field: 6366 next(); 6367 if ((type->t & VT_BTYPE) != VT_STRUCT) 6368 expect("struct/union type"); 6369 f = find_field(type, l); 6370 if (!f) 6371 expect("field"); 6372 if (cur_field) 6373 *cur_field = f; 6374 type = &f->type; 6375 c += f->c; 6376 } 6377 cur_field = NULL; 6378 } 6379 if (!cur_field) { 6380 if (tok == '=') { 6381 next(); 6382 } else if (!gnu_ext) { 6383 expect("="); 6384 } 6385 } else { 6386 if (type->t & VT_ARRAY) { 6387 index = (*cur_field)->c; 6388 if (type->ref->c >= 0 && index >= type->ref->c) 6389 tcc_error("index too large"); 6390 type = pointed_type(type); 6391 c += index * type_size(type, &align); 6392 } else { 6393 f = *cur_field; 6394 while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD)) 6395 *cur_field = f = f->next; 6396 if (!f) 6397 tcc_error("too many field init"); 6398 type = &f->type; 6399 c += f->c; 6400 } 6401 } 6402 /* must put zero in holes (note that doing it that way 6403 ensures that it even works with designators) */ 6404 if (!size_only && c - corig > al) 6405 init_putz(sec, corig + al, c - corig - al); 6406 decl_initializer(type, sec, c, 0, size_only); 6407 6408 /* XXX: make it more general */ 6409 if (!size_only && nb_elems > 1) { 6410 unsigned long c_end; 6411 uint8_t *src, *dst; 6412 int i; 6413 6414 if (!sec) { 6415 vset(type, VT_LOCAL|VT_LVAL, c); 6416 for (i = 1; i < nb_elems; i++) { 6417 vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i); 6418 vswap(); 6419 vstore(); 6420 } 6421 vpop(); 6422 } else if (!NODATA_WANTED) { 6423 c_end = c + nb_elems * elem_size; 6424 if (c_end > sec->data_allocated) 6425 section_realloc(sec, c_end); 6426 src = sec->data + c; 6427 dst = src; 6428 for(i = 1; i < nb_elems; i++) { 6429 dst += elem_size; 6430 memcpy(dst, src, elem_size); 6431 } 6432 } 6433 } 6434 c += nb_elems * type_size(type, &align); 6435 if (c - corig > al) 6436 al = c - corig; 6437 return al; 6438 } 6439 6440 /* store a value or an expression directly in global data or in local array */ 6441 static void init_putv(CType *type, Section *sec, unsigned long c) 6442 { 6443 int bt; 6444 void *ptr; 6445 CType dtype; 6446 4872 6447 dtype = *type; 4873 6448 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ 4874 6449 4875 6450 if (sec) { 6451 int size, align; 4876 6452 /* XXX: not portable */ 4877 6453 /* XXX: generate error if incorrect relocation */ 4878 6454 gen_assign_cast(&dtype); 4879 6455 bt = type->t & VT_BTYPE; 4880 /* we'll write at most 12 bytes */ 4881 if (c + 12 > sec->data_allocated) { 4882 section_realloc(sec, c + 12); 4883 } 6456 6457 if ((vtop->r & VT_SYM) 6458 && bt != VT_PTR 6459 && bt != VT_FUNC 6460 && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT) 6461 || (type->t & VT_BITFIELD)) 6462 && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM) 6463 ) 6464 tcc_error("initializer element is not computable at load time"); 6465 6466 if (NODATA_WANTED) { 6467 vtop--; 6468 return; 6469 } 6470 6471 size = type_size(type, &align); 6472 section_reserve(sec, c + size); 4884 6473 ptr = sec->data + c; 6474 4885 6475 /* XXX: make code faster ? */ 4886 if (!(type->t & VT_BITFIELD)) { 4887 bit_pos = 0; 4888 bit_size = 32; 4889 bit_mask = -1LL; 4890 } else { 4891 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; 4892 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; 4893 bit_mask = (1LL << bit_size) - 1; 4894 } 4895 if ((vtop->r & VT_SYM) && 4896 (bt == VT_BYTE || 4897 bt == VT_SHORT || 4898 bt == VT_DOUBLE || 4899 bt == VT_LDOUBLE || 4900 bt == VT_LLONG || 4901 (bt == VT_INT && bit_size != 32))) 4902 tcc_error("initializer element is not computable at load time"); 4903 switch(bt) { 4904 case VT_BOOL: 4905 vtop->c.i = (vtop->c.i != 0); 4906 case VT_BYTE: 4907 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; 4908 break; 4909 case VT_SHORT: 4910 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos; 4911 break; 4912 case VT_DOUBLE: 4913 *(double *)ptr = vtop->c.d; 4914 break; 4915 case VT_LDOUBLE: 4916 *(long double *)ptr = vtop->c.ld; 4917 break; 4918 case VT_LLONG: 4919 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos; 4920 break; 4921 default: 4922 if (vtop->r & VT_SYM) { 4923 greloc(sec, vtop->sym, c, R_DATA_PTR); 4924 } 4925 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos; 4926 break; 4927 } 6476 if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) && 6477 vtop->sym->v >= SYM_FIRST_ANOM && 6478 /* XXX This rejects compound literals like 6479 '(void *){ptr}'. The problem is that '&sym' is 6480 represented the same way, which would be ruled out 6481 by the SYM_FIRST_ANOM check above, but also '"string"' 6482 in 'char *p = "string"' is represented the same 6483 with the type being VT_PTR and the symbol being an 6484 anonymous one. That is, there's no difference in vtop 6485 between '(void *){x}' and '&(void *){x}'. Ignore 6486 pointer typed entities here. Hopefully no real code 6487 will every use compound literals with scalar type. */ 6488 (vtop->type.t & VT_BTYPE) != VT_PTR) { 6489 /* These come from compound literals, memcpy stuff over. */ 6490 Section *ssec; 6491 ElfSym *esym; 6492 ElfW_Rel *rel; 6493 esym = elfsym(vtop->sym); 6494 ssec = tcc_state->sections[esym->st_shndx]; 6495 memmove (ptr, ssec->data + esym->st_value, size); 6496 if (ssec->reloc) { 6497 /* We need to copy over all memory contents, and that 6498 includes relocations. Use the fact that relocs are 6499 created it order, so look from the end of relocs 6500 until we hit one before the copied region. */ 6501 int num_relocs = ssec->reloc->data_offset / sizeof(*rel); 6502 rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset); 6503 while (num_relocs--) { 6504 rel--; 6505 if (rel->r_offset >= esym->st_value + size) 6506 continue; 6507 if (rel->r_offset < esym->st_value) 6508 break; 6509 /* Note: if the same fields are initialized multiple 6510 times (possible with designators) then we possibly 6511 add multiple relocations for the same offset here. 6512 That would lead to wrong code, the last reloc needs 6513 to win. We clean this up later after the whole 6514 initializer is parsed. */ 6515 put_elf_reloca(symtab_section, sec, 6516 c + rel->r_offset - esym->st_value, 6517 ELFW(R_TYPE)(rel->r_info), 6518 ELFW(R_SYM)(rel->r_info), 6519 #if PTR_SIZE == 8 6520 rel->r_addend 6521 #else 6522 0 6523 #endif 6524 ); 6525 } 6526 } 6527 } else { 6528 if (type->t & VT_BITFIELD) { 6529 int bit_pos, bit_size, bits, n; 6530 unsigned char *p, v, m; 6531 bit_pos = BIT_POS(vtop->type.t); 6532 bit_size = BIT_SIZE(vtop->type.t); 6533 p = (unsigned char*)ptr + (bit_pos >> 3); 6534 bit_pos &= 7, bits = 0; 6535 while (bit_size) { 6536 n = 8 - bit_pos; 6537 if (n > bit_size) 6538 n = bit_size; 6539 v = vtop->c.i >> bits << bit_pos; 6540 m = ((1 << n) - 1) << bit_pos; 6541 *p = (*p & ~m) | (v & m); 6542 bits += n, bit_size -= n, bit_pos = 0, ++p; 6543 } 6544 } else 6545 switch(bt) { 6546 /* XXX: when cross-compiling we assume that each type has the 6547 same representation on host and target, which is likely to 6548 be wrong in the case of long double */ 6549 case VT_BOOL: 6550 vtop->c.i = vtop->c.i != 0; 6551 case VT_BYTE: 6552 *(char *)ptr |= vtop->c.i; 6553 break; 6554 case VT_SHORT: 6555 *(short *)ptr |= vtop->c.i; 6556 break; 6557 case VT_FLOAT: 6558 *(float*)ptr = vtop->c.f; 6559 break; 6560 case VT_DOUBLE: 6561 *(double *)ptr = vtop->c.d; 6562 break; 6563 case VT_LDOUBLE: 6564 #if defined TCC_IS_NATIVE_387 6565 if (sizeof (long double) >= 10) /* zero pad ten-byte LD */ 6566 memcpy(ptr, &vtop->c.ld, 10); 6567 #ifdef __TINYC__ 6568 else if (sizeof (long double) == sizeof (double)) 6569 __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld)); 6570 #endif 6571 else if (vtop->c.ld == 0.0) 6572 ; 6573 else 6574 #endif 6575 if (sizeof(long double) == LDOUBLE_SIZE) 6576 *(long double*)ptr = vtop->c.ld; 6577 else if (sizeof(double) == LDOUBLE_SIZE) 6578 *(double *)ptr = (double)vtop->c.ld; 6579 else 6580 tcc_error("can't cross compile long double constants"); 6581 break; 6582 #if PTR_SIZE != 8 6583 case VT_LLONG: 6584 *(long long *)ptr |= vtop->c.i; 6585 break; 6586 #else 6587 case VT_LLONG: 6588 #endif 6589 case VT_PTR: 6590 { 6591 addr_t val = vtop->c.i; 6592 #if PTR_SIZE == 8 6593 if (vtop->r & VT_SYM) 6594 greloca(sec, vtop->sym, c, R_DATA_PTR, val); 6595 else 6596 *(addr_t *)ptr |= val; 6597 #else 6598 if (vtop->r & VT_SYM) 6599 greloc(sec, vtop->sym, c, R_DATA_PTR); 6600 *(addr_t *)ptr |= val; 6601 #endif 6602 break; 6603 } 6604 default: 6605 { 6606 int val = vtop->c.i; 6607 #if PTR_SIZE == 8 6608 if (vtop->r & VT_SYM) 6609 greloca(sec, vtop->sym, c, R_DATA_PTR, val); 6610 else 6611 *(int *)ptr |= val; 6612 #else 6613 if (vtop->r & VT_SYM) 6614 greloc(sec, vtop->sym, c, R_DATA_PTR); 6615 *(int *)ptr |= val; 6616 #endif 6617 break; 6618 } 6619 } 6620 } 4928 6621 vtop--; 4929 6622 } else { … … 4932 6625 vstore(); 4933 6626 vpop(); 4934 }4935 }4936 4937 /* put zeros for variable based init */4938 static void init_putz(CType *t, Section *sec, unsigned long c, int size)4939 {4940 if (sec) {4941 /* nothing to do because globals are already set to zero */4942 } else {4943 vpush_global_sym(&func_old_type, TOK_memset);4944 vseti(VT_LOCAL, c);4945 vpushi(0);4946 vpushi(size);4947 gfunc_call(3);4948 6627 } 4949 6628 } … … 4957 6636 int first, int size_only) 4958 6637 { 4959 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i; 4960 int size1, align1, expr_type; 6638 int len, n, no_oblock, nb, i; 6639 int size1, align1; 6640 int have_elem; 4961 6641 Sym *s, *f; 6642 Sym indexsym; 4962 6643 CType *t1; 4963 6644 4964 if (type->t & VT_VLA) { 4965 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 4966 int a; 4967 CValue retcval; 4968 4969 vpush_global_sym(&func_old_type, TOK_alloca); 4970 vla_runtime_type_size(type, &a); 4971 gfunc_call(1); 4972 4973 /* return value */ 4974 retcval.i = 0; 4975 vsetc(type, REG_IRET, &retcval); 4976 vset(type, VT_LOCAL|VT_LVAL, c); 4977 vswap(); 4978 vstore(); 4979 vpop(); 4980 #else 4981 tcc_error("variable length arrays unsupported for this target"); 4982 #endif 6645 /* If we currently are at an '}' or ',' we have read an initializer 6646 element in one of our callers, and not yet consumed it. */ 6647 have_elem = tok == '}' || tok == ','; 6648 if (!have_elem && tok != '{' && 6649 /* In case of strings we have special handling for arrays, so 6650 don't consume them as initializer value (which would commit them 6651 to some anonymous symbol). */ 6652 tok != TOK_LSTR && tok != TOK_STR && 6653 !size_only) { 6654 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST); 6655 have_elem = 1; 6656 } 6657 6658 if (have_elem && 6659 !(type->t & VT_ARRAY) && 6660 /* Use i_c_parameter_t, to strip toplevel qualifiers. 6661 The source type might have VT_CONSTANT set, which is 6662 of course assignable to non-const elements. */ 6663 is_compatible_unqualified_types(type, &vtop->type)) { 6664 init_putv(type, sec, c); 4983 6665 } else if (type->t & VT_ARRAY) { 4984 6666 s = type->ref; 4985 6667 n = s->c; 4986 array_length = 0;4987 6668 t1 = pointed_type(type); 4988 6669 size1 = type_size(t1, &align1); … … 5007 6688 #endif 5008 6689 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) { 6690 len = 0; 5009 6691 while (tok == TOK_STR || tok == TOK_LSTR) { 5010 6692 int cstr_len, ch; 5011 CString *cstr; 5012 5013 cstr = tokc.cstr; 6693 5014 6694 /* compute maximum number of chars wanted */ 5015 6695 if (tok == TOK_STR) 5016 cstr_len = cstr->size;6696 cstr_len = tokc.str.size; 5017 6697 else 5018 cstr_len = cstr->size / sizeof(nwchar_t);6698 cstr_len = tokc.str.size / sizeof(nwchar_t); 5019 6699 cstr_len--; 5020 6700 nb = cstr_len; 5021 if (n >= 0 && nb > (n - array_length))5022 nb = n - array_length;6701 if (n >= 0 && nb > (n - len)) 6702 nb = n - len; 5023 6703 if (!size_only) { 5024 6704 if (cstr_len > nb) … … 5028 6708 specifically */ 5029 6709 if (sec && tok == TOK_STR && size1 == 1) { 5030 memcpy(sec->data + c + array_length, cstr->data, nb); 6710 if (!NODATA_WANTED) 6711 memcpy(sec->data + c + len, tokc.str.data, nb); 5031 6712 } else { 5032 6713 for(i=0;i<nb;i++) { 5033 6714 if (tok == TOK_STR) 5034 ch = ((unsigned char *) cstr->data)[i];6715 ch = ((unsigned char *)tokc.str.data)[i]; 5035 6716 else 5036 ch = ((nwchar_t *) cstr->data)[i];5037 init_putv(t1, sec, c + (array_length + i) * size1, 5038 ch, EXPR_VAL);6717 ch = ((nwchar_t *)tokc.str.data)[i]; 6718 vpushi(ch); 6719 init_putv(t1, sec, c + (len + i) * size1); 5039 6720 } 5040 6721 } 5041 6722 } 5042 array_length+= nb;6723 len += nb; 5043 6724 next(); 5044 6725 } 5045 6726 /* only add trailing zero if enough storage (no 5046 6727 warning in this case since it is standard) */ 5047 if (n < 0 || array_length< n) {6728 if (n < 0 || len < n) { 5048 6729 if (!size_only) { 5049 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL); 6730 vpushi(0); 6731 init_putv(t1, sec, c + (len * size1)); 5050 6732 } 5051 array_length++; 5052 } 6733 len++; 6734 } 6735 len *= size1; 5053 6736 } else { 5054 index = 0; 5055 while (tok != '}') { 5056 decl_designator(type, sec, c, &index, NULL, size_only); 5057 if (n >= 0 && index >= n) 5058 tcc_error("index too large"); 5059 /* must put zero in holes (note that doing it that way 5060 ensures that it even works with designators) */ 5061 if (!size_only && array_length < index) { 5062 init_putz(t1, sec, c + array_length * size1, 5063 (index - array_length) * size1); 5064 } 5065 index++; 5066 if (index > array_length) 5067 array_length = index; 5068 /* special test for multi dimensional arrays (may not 5069 be strictly correct if designators are used at the 5070 same time) */ 5071 if (index >= n && no_oblock) 5072 break; 5073 if (tok == '}') 5074 break; 5075 skip(','); 5076 } 5077 } 6737 indexsym.c = 0; 6738 f = &indexsym; 6739 6740 do_init_list: 6741 len = 0; 6742 while (tok != '}' || have_elem) { 6743 len = decl_designator(type, sec, c, &f, size_only, len); 6744 have_elem = 0; 6745 if (type->t & VT_ARRAY) { 6746 ++indexsym.c; 6747 /* special test for multi dimensional arrays (may not 6748 be strictly correct if designators are used at the 6749 same time) */ 6750 if (no_oblock && len >= n*size1) 6751 break; 6752 } else { 6753 if (s->type.t == VT_UNION) 6754 f = NULL; 6755 else 6756 f = f->next; 6757 if (no_oblock && f == NULL) 6758 break; 6759 } 6760 6761 if (tok == '}') 6762 break; 6763 skip(','); 6764 } 6765 } 6766 /* put zeros at the end */ 6767 if (!size_only && len < n*size1) 6768 init_putz(sec, c + len, n*size1 - len); 5078 6769 if (!no_oblock) 5079 6770 skip('}'); 5080 /* put zeros at the end */ 5081 if (!size_only && n >= 0 && array_length < n) { 5082 init_putz(t1, sec, c + array_length * size1, 5083 (n - array_length) * size1); 5084 } 5085 /* patch type size if needed */ 6771 /* patch type size if needed, which happens only for array types */ 5086 6772 if (n < 0) 5087 s->c = array_length; 5088 } else if ((type->t & VT_BTYPE) == VT_STRUCT && 5089 (sec || !first || tok == '{')) { 5090 int par_count; 5091 5092 /* NOTE: the previous test is a specific case for automatic 5093 struct/union init */ 5094 /* XXX: union needs only one init */ 5095 5096 /* XXX: this test is incorrect for local initializers 5097 beginning with ( without {. It would be much more difficult 5098 to do it correctly (ideally, the expression parser should 5099 be used in all cases) */ 5100 par_count = 0; 5101 if (tok == '(') { 5102 AttributeDef ad1; 5103 CType type1; 5104 next(); 5105 while (tok == '(') { 5106 par_count++; 5107 next(); 5108 } 5109 if (!parse_btype(&type1, &ad1)) 5110 expect("cast"); 5111 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); 5112 #if 0 5113 if (!is_assignable_types(type, &type1)) 5114 tcc_error("invalid type for cast"); 5115 #endif 5116 skip(')'); 5117 } 6773 s->c = size1 == 1 ? len : ((len + size1 - 1)/size1); 6774 } else if ((type->t & VT_BTYPE) == VT_STRUCT) { 6775 size1 = 1; 5118 6776 no_oblock = 1; 5119 6777 if (first || tok == '{') { … … 5123 6781 s = type->ref; 5124 6782 f = s->next; 5125 array_length = 0;5126 index = 0;5127 6783 n = s->c; 5128 while (tok != '}') { 5129 decl_designator(type, sec, c, NULL, &f, size_only); 5130 index = f->c; 5131 if (!size_only && array_length < index) { 5132 init_putz(type, sec, c + array_length, 5133 index - array_length); 5134 } 5135 index = index + type_size(&f->type, &align1); 5136 if (index > array_length) 5137 array_length = index; 5138 5139 /* gr: skip fields from same union - ugly. */ 5140 while (f->next) { 5141 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t); 5142 /* test for same offset */ 5143 if (f->next->c != f->c) 5144 break; 5145 /* if yes, test for bitfield shift */ 5146 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) { 5147 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f; 5148 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f; 5149 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2); 5150 if (bit_pos_1 != bit_pos_2) 5151 break; 5152 } 5153 f = f->next; 5154 } 5155 5156 f = f->next; 5157 if (no_oblock && f == NULL) 5158 break; 5159 if (tok == '}') 5160 break; 5161 skip(','); 5162 } 5163 /* put zeros at the end */ 5164 if (!size_only && array_length < n) { 5165 init_putz(type, sec, c + array_length, 5166 n - array_length); 5167 } 5168 if (!no_oblock) 5169 skip('}'); 5170 while (par_count) { 5171 skip(')'); 5172 par_count--; 5173 } 6784 goto do_init_list; 5174 6785 } else if (tok == '{') { 5175 6786 next(); … … 5177 6788 skip('}'); 5178 6789 } else if (size_only) { 6790 /* If we supported only ISO C we wouldn't have to accept calling 6791 this on anything than an array size_only==1 (and even then 6792 only on the outermost level, so no recursion would be needed), 6793 because initializing a flex array member isn't supported. 6794 But GNU C supports it, so we need to recurse even into 6795 subfields of structs and arrays when size_only is set. */ 5179 6796 /* just skip expression */ 5180 parlevel = parlevel1 = 0; 5181 while ((parlevel > 0 || parlevel1 > 0 || 5182 (tok != '}' && tok != ',')) && tok != -1) { 5183 if (tok == '(') 5184 parlevel++; 5185 else if (tok == ')') 5186 parlevel--; 5187 else if (tok == '{') 5188 parlevel1++; 5189 else if (tok == '}') 5190 parlevel1--; 5191 next(); 5192 } 6797 skip_or_save_block(NULL); 5193 6798 } else { 5194 /* currently, we always use constant expression for globals 5195 (may change for scripting case) */ 5196 expr_type = EXPR_CONST; 5197 if (!sec) 5198 expr_type = EXPR_ANY; 5199 init_putv(type, sec, c, 0, expr_type); 6799 if (!have_elem) { 6800 /* This should happen only when we haven't parsed 6801 the init element above for fear of committing a 6802 string constant to memory too early. */ 6803 if (tok != TOK_STR && tok != TOK_LSTR) 6804 expect("string constant"); 6805 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST); 6806 } 6807 init_putv(type, sec, c); 5200 6808 } 5201 6809 } … … 5204 6812 allocate space in local or global data space ('r' is either 5205 6813 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated 5206 variable 'v' with an associated name represented by 'asm_label' of 5207 scope 'scope' is declared before initializers are parsed. If 'v' is 5208 zero, then a reference to the new object is put in the value stack. 5209 If 'has_init' is 2, a special parsing is done to handle string 5210 constants. */ 6814 variable 'v' of scope 'scope' is declared before initializers 6815 are parsed. If 'v' is zero, then a reference to the new object 6816 is put in the value stack. If 'has_init' is 2, a special parsing 6817 is done to handle string constants. */ 5211 6818 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 5212 int has_init, int v, char *asm_label, 5213 int scope) 5214 { 5215 int size, align, addr, data_offset; 5216 int level; 5217 ParseState saved_parse_state = {0}; 5218 TokenString init_str; 6819 int has_init, int v, int scope) 6820 { 6821 int size, align, addr; 6822 TokenString *init_str = NULL; 6823 5219 6824 Section *sec; 5220 6825 Sym *flexible_array; 6826 Sym *sym = NULL; 6827 int saved_nocode_wanted = nocode_wanted; 6828 #ifdef CONFIG_TCC_BCHECK 6829 int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED; 6830 #endif 6831 6832 if (type->t & VT_STATIC) 6833 nocode_wanted |= NODATA_WANTED ? 0x40000000 : 0x80000000; 5221 6834 5222 6835 flexible_array = NULL; 5223 6836 if ((type->t & VT_BTYPE) == VT_STRUCT) { 5224 Sym *field; 5225 field = type->ref; 5226 while (field && field->next) 5227 field = field->next; 5228 if (field->type.t & VT_ARRAY && field->type.ref->c < 0) 5229 flexible_array = field; 6837 Sym *field = type->ref->next; 6838 if (field) { 6839 while (field->next) 6840 field = field->next; 6841 if (field->type.t & VT_ARRAY && field->type.ref->c < 0) 6842 flexible_array = field; 6843 } 5230 6844 } 5231 6845 … … 5237 6851 literals). It also simplifies local 5238 6852 initializers handling */ 5239 tok_str_new(&init_str);5240 6853 if (size < 0 || (flexible_array && has_init)) { 5241 6854 if (!has_init) … … 5243 6856 /* get all init string */ 5244 6857 if (has_init == 2) { 6858 init_str = tok_str_alloc(); 5245 6859 /* only get strings */ 5246 6860 while (tok == TOK_STR || tok == TOK_LSTR) { 5247 tok_str_add_tok( &init_str);6861 tok_str_add_tok(init_str); 5248 6862 next(); 5249 6863 } 6864 tok_str_add(init_str, -1); 6865 tok_str_add(init_str, 0); 5250 6866 } else { 5251 level = 0; 5252 while (level > 0 || (tok != ',' && tok != ';')) { 5253 if (tok < 0) 5254 tcc_error("unexpected end of file in initializer"); 5255 tok_str_add_tok(&init_str); 5256 if (tok == '{') 5257 level++; 5258 else if (tok == '}') { 5259 level--; 5260 if (level <= 0) { 5261 next(); 5262 break; 5263 } 5264 } 5265 next(); 5266 } 5267 } 5268 tok_str_add(&init_str, -1); 5269 tok_str_add(&init_str, 0); 5270 6867 skip_or_save_block(&init_str); 6868 } 6869 unget_tok(0); 6870 5271 6871 /* compute size */ 5272 save_parse_state(&saved_parse_state); 5273 5274 macro_ptr = init_str.str; 6872 begin_macro(init_str, 1); 5275 6873 next(); 5276 6874 decl_initializer(type, NULL, 0, 1, 1); 5277 6875 /* prepare second initializer parsing */ 5278 macro_ptr = init_str .str;6876 macro_ptr = init_str->str; 5279 6877 next(); 5280 6878 … … 5284 6882 tcc_error("unknown type size"); 5285 6883 } 5286 if (flexible_array) 5287 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type); 6884 /* If there's a flex member and it was used in the initializer 6885 adjust size. */ 6886 if (flexible_array && 6887 flexible_array->type.ref->c > 0) 6888 size += flexible_array->type.ref->c 6889 * pointed_size(&flexible_array->type); 5288 6890 /* take into account specified alignment if bigger */ 5289 if (ad->aligned) { 5290 if (ad->aligned > align) 5291 align = ad->aligned; 5292 } else if (ad->packed) { 6891 if (ad->a.aligned) { 6892 int speca = 1 << (ad->a.aligned - 1); 6893 if (speca > align) 6894 align = speca; 6895 } else if (ad->a.packed) { 5293 6896 align = 1; 5294 6897 } 6898 6899 if (NODATA_WANTED) 6900 size = 0, align = 1; 6901 5295 6902 if ((r & VT_VALMASK) == VT_LOCAL) { 5296 6903 sec = NULL; 5297 6904 #ifdef CONFIG_TCC_BCHECK 5298 if ( tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {6905 if (bcheck && (type->t & VT_ARRAY)) { 5299 6906 loc--; 5300 6907 } … … 5306 6913 /* XXX: currently, since we do only one pass, we cannot track 5307 6914 '&' operators, so we add only arrays */ 5308 if ( tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {5309 unsigned long*bounds_ptr;6915 if (bcheck && (type->t & VT_ARRAY)) { 6916 addr_t *bounds_ptr; 5310 6917 /* add padding between regions */ 5311 6918 loc--; 5312 6919 /* then add local bound info */ 5313 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof( unsigned long));6920 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t)); 5314 6921 bounds_ptr[0] = addr; 5315 6922 bounds_ptr[1] = size; … … 5318 6925 if (v) { 5319 6926 /* local variable */ 5320 sym_push(v, type, r, addr); 6927 #ifdef CONFIG_TCC_ASM 6928 if (ad->asm_label) { 6929 int reg = asm_parse_regvar(ad->asm_label); 6930 if (reg >= 0) 6931 r = (r & ~VT_VALMASK) | reg; 6932 } 6933 #endif 6934 sym = sym_push(v, type, r, addr); 6935 sym->a = ad->a; 5321 6936 } else { 5322 6937 /* push local reference */ … … 5324 6939 } 5325 6940 } else { 5326 Sym *sym;5327 5328 sym = NULL;5329 6941 if (v && scope == VT_CONST) { 5330 6942 /* see if the symbol was already defined */ 5331 6943 sym = sym_find(v); 5332 6944 if (sym) { 5333 if (!is_compatible_types(&sym->type, type)) 5334 tcc_error("incompatible types for redefinition of '%s'", 5335 get_tok_str(v, NULL)); 5336 if (sym->type.t & VT_EXTERN) { 5337 /* if the variable is extern, it was not allocated */ 5338 sym->type.t &= ~VT_EXTERN; 5339 /* set array size if it was ommited in extern 5340 declaration */ 5341 if ((sym->type.t & VT_ARRAY) && 5342 sym->type.ref->c < 0 && 5343 type->ref->c >= 0) 5344 sym->type.ref->c = type->ref->c; 5345 } else { 5346 /* we accept several definitions of the same 5347 global variable. this is tricky, because we 5348 must play with the SHN_COMMON type of the symbol */ 5349 /* XXX: should check if the variable was already 5350 initialized. It is incorrect to initialized it 5351 twice */ 5352 /* no init data, we won't add more to the symbol */ 5353 if (!has_init) 5354 goto no_alloc; 5355 } 6945 patch_storage(sym, ad, type); 6946 /* we accept several definitions of the same global variable. */ 6947 if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF) 6948 goto no_alloc; 5356 6949 } 5357 6950 } … … 5365 6958 sec = bss_section; 5366 6959 } 6960 5367 6961 if (sec) { 5368 data_offset = sec->data_offset; 5369 data_offset = (data_offset + align - 1) & -align; 5370 addr = data_offset; 5371 /* very important to increment global pointer at this time 5372 because initializers themselves can create new initializers */ 5373 data_offset += size; 6962 addr = section_add(sec, size, align); 5374 6963 #ifdef CONFIG_TCC_BCHECK 5375 6964 /* add padding if bound check */ 5376 if (tcc_state->do_bounds_check) 5377 data_offset++; 5378 #endif 5379 sec->data_offset = data_offset; 5380 /* allocate section space to put the data */ 5381 if (sec->sh_type != SHT_NOBITS && 5382 data_offset > sec->data_allocated) 5383 section_realloc(sec, data_offset); 5384 /* align section if needed */ 5385 if (align > sec->sh_addralign) 5386 sec->sh_addralign = align; 6965 if (bcheck) 6966 section_add(sec, 1, 1); 6967 #endif 5387 6968 } else { 5388 addr = 0; /* avoid warning */ 6969 addr = align; /* SHN_COMMON is special, symbol value is align */ 6970 sec = common_section; 5389 6971 } 5390 6972 5391 6973 if (v) { 5392 if ( scope != VT_CONST ||!sym) {6974 if (!sym) { 5393 6975 sym = sym_push(v, type, r | VT_SYM, 0); 5394 sym->asm_label = asm_label; 5395 } 6976 patch_storage(sym, ad, NULL); 6977 } 6978 /* Local statics have a scope until now (for 6979 warnings), remove it here. */ 6980 sym->sym_scope = 0; 5396 6981 /* update symbol definition */ 5397 if (sec) { 5398 put_extern_sym(sym, sec, addr, size); 5399 } else { 5400 ElfW(Sym) *esym; 5401 /* put a common area */ 5402 put_extern_sym(sym, NULL, align, size); 5403 /* XXX: find a nicer way */ 5404 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; 5405 esym->st_shndx = SHN_COMMON; 5406 } 6982 put_extern_sym(sym, sec, addr, size); 5407 6983 } else { 5408 CValue cval;5409 5410 6984 /* push global reference */ 5411 6985 sym = get_sym_ref(type, sec, addr, size); 5412 cval.ul = 0; 5413 vsetc(type, VT_CONST | VT_SYM, &cval); 5414 vtop->sym = sym; 5415 } 5416 /* patch symbol weakness */ 5417 if (type->t & VT_WEAK) 5418 weaken_symbol(sym); 6986 vpushsym(type, sym); 6987 vtop->r |= r; 6988 } 6989 5419 6990 #ifdef CONFIG_TCC_BCHECK 5420 6991 /* handles bounds now because the symbol must be defined 5421 6992 before for the relocation */ 5422 if ( tcc_state->do_bounds_check) {5423 unsigned long*bounds_ptr;5424 5425 greloc (bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);6993 if (bcheck) { 6994 addr_t *bounds_ptr; 6995 6996 greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0); 5426 6997 /* then add global bound info */ 5427 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof( long));6998 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t)); 5428 6999 bounds_ptr[0] = 0; /* relocated */ 5429 7000 bounds_ptr[1] = size; … … 5431 7002 #endif 5432 7003 } 5433 if (has_init || (type->t & VT_VLA)) { 7004 7005 if (type->t & VT_VLA) { 7006 int a; 7007 7008 if (NODATA_WANTED) 7009 goto no_alloc; 7010 7011 /* save current stack pointer */ 7012 if (vlas_in_scope == 0) { 7013 if (vla_sp_root_loc == -1) 7014 vla_sp_root_loc = (loc -= PTR_SIZE); 7015 gen_vla_sp_save(vla_sp_root_loc); 7016 } 7017 7018 vla_runtime_type_size(type, &a); 7019 gen_vla_alloc(type, a); 7020 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64 7021 /* on _WIN64, because of the function args scratch area, the 7022 result of alloca differs from RSP and is returned in RAX. */ 7023 gen_vla_result(addr), addr = (loc -= PTR_SIZE); 7024 #endif 7025 gen_vla_sp_save(addr); 7026 vla_sp_loc = addr; 7027 vlas_in_scope++; 7028 7029 } else if (has_init) { 7030 size_t oldreloc_offset = 0; 7031 if (sec && sec->reloc) 7032 oldreloc_offset = sec->reloc->data_offset; 5434 7033 decl_initializer(type, sec, addr, 1, 0); 5435 /* restore parse state if needed */ 5436 if (init_str.str) { 5437 tok_str_free(init_str.str); 5438 restore_parse_state(&saved_parse_state); 5439 } 7034 if (sec && sec->reloc) 7035 squeeze_multi_relocs(sec, oldreloc_offset); 5440 7036 /* patch flexible array member size back to -1, */ 5441 7037 /* for possible subsequent similar declarations */ … … 5443 7039 flexible_array->type.ref->c = -1; 5444 7040 } 5445 no_alloc: ; 5446 } 5447 5448 static void put_func_debug(Sym *sym) 5449 { 5450 char buf[512]; 5451 5452 /* stabs info */ 5453 /* XXX: we put here a dummy type */ 5454 snprintf(buf, sizeof(buf), "%s:%c1", 5455 funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); 5456 put_stabs_r(buf, N_FUN, 0, file->line_num, 0, 5457 cur_text_section, sym->c); 5458 /* //gr gdb wants a line at the function */ 5459 put_stabn(N_SLINE, 0, file->line_num, 0); 5460 last_ind = 0; 5461 last_line_num = 0; 5462 } 5463 5464 /* parse an old style function declaration list */ 5465 /* XXX: check multiple parameter */ 5466 static void func_decl_list(Sym *func_sym) 5467 { 5468 AttributeDef ad; 5469 int v; 5470 Sym *s; 5471 CType btype, type; 5472 5473 /* parse each declaration */ 5474 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF && 5475 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) { 5476 if (!parse_btype(&btype, &ad)) 5477 expect("declaration list"); 5478 if (((btype.t & VT_BTYPE) == VT_ENUM || 5479 (btype.t & VT_BTYPE) == VT_STRUCT) && 5480 tok == ';') { 5481 /* we accept no variable after */ 5482 } else { 5483 for(;;) { 5484 type = btype; 5485 type_decl(&type, &ad, &v, TYPE_DIRECT); 5486 /* find parameter in function parameter list */ 5487 s = func_sym->next; 5488 while (s != NULL) { 5489 if ((s->v & ~SYM_FIELD) == v) 5490 goto found; 5491 s = s->next; 5492 } 5493 tcc_error("declaration for parameter '%s' but no such parameter", 5494 get_tok_str(v, NULL)); 5495 found: 5496 /* check that no storage specifier except 'register' was given */ 5497 if (type.t & VT_STORAGE) 5498 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL)); 5499 convert_parameter_type(&type); 5500 /* we can add the type (NOTE: it could be local to the function) */ 5501 s->type = type; 5502 /* accept other parameters */ 5503 if (tok == ',') 5504 next(); 5505 else 5506 break; 5507 } 5508 } 5509 skip(';'); 5510 } 7041 7042 no_alloc: 7043 /* restore parse state if needed */ 7044 if (init_str) { 7045 end_macro(); 7046 next(); 7047 } 7048 7049 nocode_wanted = saved_nocode_wanted; 5511 7050 } 5512 7051 … … 5515 7054 static void gen_function(Sym *sym) 5516 7055 { 5517 int saved_nocode_wanted = nocode_wanted;5518 7056 nocode_wanted = 0; 5519 7057 ind = cur_text_section->data_offset; … … 5522 7060 funcname = get_tok_str(sym->v, NULL); 5523 7061 func_ind = ind; 7062 /* Initialize VLA state */ 7063 vla_sp_loc = -1; 7064 vla_sp_root_loc = -1; 5524 7065 /* put debug symbol */ 5525 if (tcc_state->do_debug) 5526 put_func_debug(sym); 7066 tcc_debug_funcstart(tcc_state, sym); 5527 7067 /* push a dummy symbol to enable local sym storage */ 5528 7068 sym_push2(&local_stack, SYM_FIELD, 0, 0); 7069 local_scope = 1; /* for function parameters */ 5529 7070 gfunc_prolog(&sym->type); 7071 local_scope = 0; 5530 7072 rsym = 0; 5531 block(NULL, NULL, NULL, NULL, 0, 0); 7073 block(NULL, NULL, 0); 7074 nocode_wanted = 0; 5532 7075 gsym(rsym); 5533 7076 gfunc_epilog(); 5534 7077 cur_text_section->data_offset = ind; 5535 label_pop(&global_label_stack, NULL );7078 label_pop(&global_label_stack, NULL, 0); 5536 7079 /* reset local stack */ 5537 scope_stack_bottom = NULL;5538 sym_pop(&local_stack, NULL );7080 local_scope = 0; 7081 sym_pop(&local_stack, NULL, 0); 5539 7082 /* end of function */ 5540 7083 /* patch symbol size */ 5541 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = 5542 ind - func_ind; 5543 /* patch symbol weakness (this definition overrules any prototype) */ 5544 if (sym->type.t & VT_WEAK) 5545 weaken_symbol(sym); 5546 if (tcc_state->do_debug) { 5547 put_stabn(N_FUN, 0, 0, ind - func_ind); 5548 } 7084 elfsym(sym)->st_size = ind - func_ind; 7085 tcc_debug_funcend(tcc_state, ind - func_ind); 5549 7086 /* It's better to crash than to generate wrong code */ 5550 7087 cur_text_section = NULL; 5551 7088 funcname = ""; /* for safety */ 5552 7089 func_vt.t = VT_VOID; /* for safety */ 7090 func_var = 0; /* for safety */ 5553 7091 ind = 0; /* for safety */ 5554 nocode_wanted = saved_nocode_wanted; 5555 } 5556 5557 ST_FUNC void gen_inline_functions(void) 7092 nocode_wanted = 0x80000000; 7093 check_vstack(); 7094 } 7095 7096 static void gen_inline_functions(TCCState *s) 5558 7097 { 5559 7098 Sym *sym; 5560 int *str, inline_generated, i;7099 int inline_generated, i, ln; 5561 7100 struct InlineFunc *fn; 5562 7101 7102 ln = file->line_num; 5563 7103 /* iterate while inline function are referenced */ 5564 for(;;){7104 do { 5565 7105 inline_generated = 0; 5566 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {5567 fn = tcc_state->inline_fns[i];7106 for (i = 0; i < s->nb_inline_fns; ++i) { 7107 fn = s->inline_fns[i]; 5568 7108 sym = fn->sym; 5569 7109 if (sym && sym->c) { 5570 7110 /* the function was used: generate its code and 5571 7111 convert it to a normal function */ 5572 str = fn->token_str;5573 7112 fn->sym = NULL; 5574 7113 if (file) 5575 7114 pstrcpy(file->filename, sizeof file->filename, fn->filename); 5576 sym->r = VT_SYM | VT_CONST;5577 7115 sym->type.t &= ~VT_INLINE; 5578 7116 5579 macro_ptr = str;7117 begin_macro(fn->func_str, 1); 5580 7118 next(); 5581 7119 cur_text_section = text_section; 5582 7120 gen_function(sym); 5583 macro_ptr = NULL; /* fail safe */7121 end_macro(); 5584 7122 5585 7123 inline_generated = 1; 5586 7124 } 5587 7125 } 5588 if (!inline_generated) 5589 break; 5590 } 5591 for (i = 0; i < tcc_state->nb_inline_fns; ++i) { 5592 fn = tcc_state->inline_fns[i]; 5593 str = fn->token_str; 5594 tok_str_free(str); 5595 } 5596 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns); 5597 } 5598 5599 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */ 5600 static int decl0(int l, int is_for_loop_init) 7126 } while (inline_generated); 7127 file->line_num = ln; 7128 } 7129 7130 ST_FUNC void free_inline_functions(TCCState *s) 7131 { 7132 int i; 7133 /* free tokens of unused inline functions */ 7134 for (i = 0; i < s->nb_inline_fns; ++i) { 7135 struct InlineFunc *fn = s->inline_fns[i]; 7136 if (fn->sym) 7137 tok_str_free(fn->func_str); 7138 } 7139 dynarray_reset(&s->inline_fns, &s->nb_inline_fns); 7140 } 7141 7142 /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP 7143 if parsing old style parameter decl list (and FUNC_SYM is set then) */ 7144 static int decl0(int l, int is_for_loop_init, Sym *func_sym) 5601 7145 { 5602 7146 int v, has_init, r; … … 5609 7153 if (is_for_loop_init) 5610 7154 return 0; 5611 /* skip redundant ';' */ 5612 /* XXX: find more elegant solution */ 5613 if (tok == ';') { 7155 /* skip redundant ';' if not in old parameter decl scope */ 7156 if (tok == ';' && l != VT_CMP) { 5614 7157 next(); 5615 7158 continue; 5616 7159 } 5617 if (l == VT_CONST && 5618 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { 7160 if (l != VT_CONST) 7161 break; 7162 if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { 5619 7163 /* global asm block */ 5620 7164 asm_global_instr(); 5621 7165 continue; 5622 7166 } 5623 /* special test for old K&R protos without explicit int 5624 type. Only accepted when defining global data */ 5625 if (l == VT_LOCAL || tok < TOK_DEFINE) 7167 if (tok >= TOK_UIDENT) { 7168 /* special test for old K&R protos without explicit int 7169 type. Only accepted when defining global data */ 7170 btype.t = VT_INT; 7171 } else { 7172 if (tok != TOK_EOF) 7173 expect("declaration"); 5626 7174 break; 5627 btype.t = VT_INT; 5628 } 5629 if (((btype.t & VT_BTYPE) == VT_ENUM || 5630 (btype.t & VT_BTYPE) == VT_STRUCT) && 5631 tok == ';') { 5632 /* we accept no variable after */ 5633 next(); 5634 continue; 7175 } 7176 } 7177 if (tok == ';') { 7178 if ((btype.t & VT_BTYPE) == VT_STRUCT) { 7179 int v = btype.ref->v; 7180 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM) 7181 tcc_warning("unnamed struct/union that defines no instances"); 7182 next(); 7183 continue; 7184 } 7185 if (IS_ENUM(btype.t)) { 7186 next(); 7187 continue; 7188 } 5635 7189 } 5636 7190 while (1) { /* iterate thru each declaration */ 5637 char *asm_label; // associated asm label5638 7191 type = btype; 7192 /* If the base type itself was an array type of unspecified 7193 size (like in 'typedef int arr[]; arr x = {1};') then 7194 we will overwrite the unknown size by the real one for 7195 this decl. We need to unshare the ref symbol holding 7196 that size. */ 7197 if ((type.t & VT_ARRAY) && type.ref->c < 0) { 7198 type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c); 7199 } 5639 7200 type_decl(&type, &ad, &v, TYPE_DIRECT); 5640 7201 #if 0 5641 7202 { 5642 7203 char buf[500]; 5643 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));7204 type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL)); 5644 7205 printf("type = '%s'\n", buf); 5645 7206 } … … 5652 7213 declaration list */ 5653 7214 sym = type.ref; 5654 if (sym->c == FUNC_OLD) 5655 func_decl_list(sym); 5656 } 5657 5658 asm_label = NULL; 7215 if (sym->f.func_type == FUNC_OLD && l == VT_CONST) 7216 decl0(VT_CMP, 0, sym); 7217 } 7218 5659 7219 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { 5660 CString astr; 5661 5662 asm_label_instr(&astr); 5663 asm_label = tcc_strdup(astr.data); 5664 cstr_free(&astr); 5665 7220 ad.asm_label = asm_label_instr(); 5666 7221 /* parse one last attribute list, after asm label */ 5667 7222 parse_attribute(&ad); 5668 }5669 5670 if (ad.weak)5671 type.t |= VT_WEAK; 7223 if (tok == '{') 7224 expect(";"); 7225 } 7226 5672 7227 #ifdef TCC_TARGET_PE 5673 if (ad.func_import) 5674 type.t |= VT_IMPORT; 5675 if (ad.func_export) 5676 type.t |= VT_EXPORT; 7228 if (ad.a.dllimport || ad.a.dllexport) { 7229 if (type.t & (VT_STATIC|VT_TYPEDEF)) 7230 tcc_error("cannot have dll linkage with static or typedef"); 7231 if (ad.a.dllimport) { 7232 if ((type.t & VT_BTYPE) == VT_FUNC) 7233 ad.a.dllimport = 0; 7234 else 7235 type.t |= VT_EXTERN; 7236 } 7237 } 5677 7238 #endif 5678 7239 if (tok == '{') { 5679 if (l == VT_LOCAL)7240 if (l != VT_CONST) 5680 7241 tcc_error("cannot use local functions"); 5681 7242 if ((type.t & VT_BTYPE) != VT_FUNC) 5682 7243 expect("function definition"); 5683 7244 5684 /* reject abstract declarators in function definition */ 7245 /* reject abstract declarators in function definition 7246 make old style params without decl have int type */ 5685 7247 sym = type.ref; 5686 while ((sym = sym->next) != NULL) 7248 while ((sym = sym->next) != NULL) { 5687 7249 if (!(sym->v & ~SYM_FIELD)) 5688 expect("identifier"); 7250 expect("identifier"); 7251 if (sym->type.t == VT_VOID) 7252 sym->type = int_type; 7253 } 5689 7254 5690 7255 /* XXX: cannot do better now: convert extern line to static inline */ 5691 7256 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE)) 5692 7257 type.t = (type.t & ~VT_EXTERN) | VT_STATIC; 5693 5694 sym = sym_find(v); 5695 if (sym) { 5696 if ((sym->type.t & VT_BTYPE) != VT_FUNC) 5697 goto func_error1; 5698 5699 r = sym->type.ref->r; 5700 /* use func_call from prototype if not defined */ 5701 if (FUNC_CALL(r) != FUNC_CDECL 5702 && FUNC_CALL(type.ref->r) == FUNC_CDECL) 5703 FUNC_CALL(type.ref->r) = FUNC_CALL(r); 5704 5705 /* use export from prototype */ 5706 if (FUNC_EXPORT(r)) 5707 FUNC_EXPORT(type.ref->r) = 1; 5708 5709 /* use static from prototype */ 5710 if (sym->type.t & VT_STATIC) 5711 type.t = (type.t & ~VT_EXTERN) | VT_STATIC; 5712 5713 if (!is_compatible_types(&sym->type, &type)) { 5714 func_error1: 5715 tcc_error("incompatible types for redefinition of '%s'", 5716 get_tok_str(v, NULL)); 5717 } 5718 /* if symbol is already defined, then put complete type */ 5719 sym->type = type; 5720 } else { 5721 /* put function symbol */ 5722 sym = global_identifier_push(v, type.t, 0); 5723 sym->type.ref = type.ref; 5724 } 7258 7259 /* put function symbol */ 7260 sym = external_global_sym(v, &type, 0); 7261 type.t &= ~VT_EXTERN; 7262 patch_storage(sym, &ad, &type); 5725 7263 5726 7264 /* static inline functions are just recorded as a kind … … 5729 7267 if ((type.t & (VT_INLINE | VT_STATIC)) == 5730 7268 (VT_INLINE | VT_STATIC)) { 5731 TokenString func_str;5732 int block_level;5733 7269 struct InlineFunc *fn; 5734 7270 const char *filename; 5735 7271 5736 tok_str_new(&func_str);5737 5738 block_level = 0;5739 for(;;) {5740 int t;5741 if (tok == TOK_EOF)5742 tcc_error("unexpected end of file");5743 tok_str_add_tok(&func_str);5744 t = tok;5745 next();5746 if (t == '{') {5747 block_level++;5748 } else if (t == '}') {5749 block_level--;5750 if (block_level == 0)5751 break;5752 }5753 }5754 tok_str_add(&func_str, -1);5755 tok_str_add(&func_str, 0);5756 7272 filename = file ? file->filename : ""; 5757 7273 fn = tcc_malloc(sizeof *fn + strlen(filename)); 5758 7274 strcpy(fn->filename, filename); 5759 7275 fn->sym = sym; 5760 fn->token_str = func_str.str;5761 dynarray_add( (void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);5762 7276 skip_or_save_block(&fn->func_str); 7277 dynarray_add(&tcc_state->inline_fns, 7278 &tcc_state->nb_inline_fns, fn); 5763 7279 } else { 5764 7280 /* compute text section */ … … 5766 7282 if (!cur_text_section) 5767 7283 cur_text_section = text_section; 5768 sym->r = VT_SYM | VT_CONST;5769 7284 gen_function(sym); 5770 7285 } 5771 7286 break; 5772 7287 } else { 5773 if (btype.t & VT_TYPEDEF) { 7288 if (l == VT_CMP) { 7289 /* find parameter in function parameter list */ 7290 for (sym = func_sym->next; sym; sym = sym->next) 7291 if ((sym->v & ~SYM_FIELD) == v) 7292 goto found; 7293 tcc_error("declaration for parameter '%s' but no such parameter", 7294 get_tok_str(v, NULL)); 7295 found: 7296 if (type.t & VT_STORAGE) /* 'register' is okay */ 7297 tcc_error("storage class specified for '%s'", 7298 get_tok_str(v, NULL)); 7299 if (sym->type.t != VT_VOID) 7300 tcc_error("redefinition of parameter '%s'", 7301 get_tok_str(v, NULL)); 7302 convert_parameter_type(&type); 7303 sym->type = type; 7304 } else if (type.t & VT_TYPEDEF) { 5774 7305 /* save typedefed type */ 5775 7306 /* XXX: test storage specifiers ? */ 5776 sym = sym_push(v, &type, INT_ATTR(&ad), 0); 5777 sym->type.t |= VT_TYPEDEF; 7307 sym = sym_find(v); 7308 if (sym && sym->sym_scope == local_scope) { 7309 if (!is_compatible_types(&sym->type, &type) 7310 || !(sym->type.t & VT_TYPEDEF)) 7311 tcc_error("incompatible redefinition of '%s'", 7312 get_tok_str(v, NULL)); 7313 sym->type = type; 7314 } else { 7315 sym = sym_push(v, &type, 0, 0); 7316 } 7317 sym->a = ad.a; 7318 sym->f = ad.f; 5778 7319 } else { 5779 7320 r = 0; … … 5781 7322 /* external function definition */ 5782 7323 /* specific case for func_call attribute */ 5783 type.ref-> r = INT_ATTR(&ad);7324 type.ref->f = ad.f; 5784 7325 } else if (!(type.t & VT_ARRAY)) { 5785 7326 /* not lvalue if array */ … … 5788 7329 has_init = (tok == '='); 5789 7330 if (has_init && (type.t & VT_VLA)) 5790 tcc_error("Variable length array cannot be initialized"); 5791 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) || 7331 tcc_error("variable length array cannot be initialized"); 7332 if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) || 7333 ((type.t & VT_BTYPE) == VT_FUNC) || 5792 7334 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && 5793 7335 !has_init && l == VT_CONST && type.ref->c < 0)) { … … 5796 7338 arrays of null size are considered as 5797 7339 extern */ 5798 sym = external_sym(v, &type, r, asm_label); 5799 5800 if (type.t & VT_WEAK) 5801 weaken_symbol(sym); 5802 7340 type.t |= VT_EXTERN; 7341 sym = external_sym(v, &type, r, &ad); 5803 7342 if (ad.alias_target) { 5804 Section tsec; 5805 Elf32_Sym *esym; 7343 ElfSym *esym; 5806 7344 Sym *alias_target; 5807 5808 7345 alias_target = sym_find(ad.alias_target); 5809 if (!alias_target || !alias_target->c) 7346 esym = elfsym(alias_target); 7347 if (!esym) 5810 7348 tcc_error("unsupported forward __alias__ attribute"); 5811 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c]; 5812 tsec.sh_num = esym->st_shndx; 5813 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0); 7349 /* Local statics have a scope until now (for 7350 warnings), remove it here. */ 7351 sym->sym_scope = 0; 7352 put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0); 5814 7353 } 5815 7354 } else { 5816 type.t |= (btype.t & VT_STATIC); /* Retain "static". */5817 7355 if (type.t & VT_STATIC) 5818 7356 r |= VT_CONST; … … 5821 7359 if (has_init) 5822 7360 next(); 5823 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l); 7361 else if (l == VT_CONST) 7362 /* uninitialized global variables may be overridden */ 7363 type.t |= VT_EXTERN; 7364 decl_initializer_alloc(&type, &ad, r, has_init, v, l); 5824 7365 } 5825 7366 } … … 5832 7373 next(); 5833 7374 } 5834 ad.a ligned = 0;7375 ad.a.aligned = 0; 5835 7376 } 5836 7377 } … … 5838 7379 } 5839 7380 5840 ST_FUNC void decl(int l) 5841 { 5842 decl0(l, 0); 5843 } 7381 static void decl(int l) 7382 { 7383 decl0(l, 0, NULL); 7384 } 7385 7386 /* ------------------------------------------------------------------------- */
Note:
See TracChangeset
for help on using the changeset viewer.