* removed asm_label stack * removed asm_free_labels() post-processing * using "impossible C type" for asm labels (VT_ASM) * tccgen.c:update_storage(): use it to refresh symbol attributes * tccelf.c:find_elf_sym(): ignore STB_LOCAL symbols * tccgen.c:unary(): asm symbols are supposed to be undeclared in C
Unified · Split
| @@ -440,8 +440,7 @@ struct SymAttr { · 439 unmodified lines | |||
| 440 | visibility : 2, | 440 | visibility : 2, |
| 441 | dllexport : 1, | 441 | dllexport : 1, |
| 442 | dllimport : 1, | 442 | dllimport : 1, |
| 443 | asmexport : 1, | 443 | unused : 5; |
| 444 | unused : 4; | ||
| 445 | }; | 444 | }; |
| 446 | 445 | ||
| 447 | /* function attributes or temporary attributes for parsing */ | 446 | /* function attributes or temporary attributes for parsing */ |
| @@ -796,8 +795,8 @@ struct TCCState { · 348 unmodified lines | |||
| 796 | /* extra attributes (eg. GOT/PLT value) for symtab symbols */ | 795 | /* extra attributes (eg. GOT/PLT value) for symtab symbols */ |
| 797 | struct sym_attr *sym_attrs; | 796 | struct sym_attr *sym_attrs; |
| 798 | int nb_sym_attrs; | 797 | int nb_sym_attrs; |
| 798 | |||
| 799 | /* tiny assembler state */ | 799 | /* tiny assembler state */ |
| 800 | Sym *asm_labels; | ||
| 801 | ElfSym esym_dot; | 800 | ElfSym esym_dot; |
| 802 | 801 | ||
| 803 | #ifdef TCC_TARGET_PE | 802 | #ifdef TCC_TARGET_PE |
| @@ -911,6 +910,11 @@ struct filespec { · 107 unmodified lines | |||
| 911 | #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE) | 910 | #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE) |
| 912 | #define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK)) | 911 | #define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK)) |
| 913 | 912 | ||
| 913 | /* symbol was created by tccasm.c first */ | ||
| 914 | #define VT_ASM (VT_VOID | VT_UNSIGNED) | ||
| 915 | #define VT_ASM_GLOBAL VT_DEFSIGN | ||
| 916 | #define IS_ASM_SYM(sym) (((sym)->type.t & (VT_BTYPE | VT_ASM)) == VT_ASM) | ||
| 917 | |||
| 914 | /* token values */ | 918 | /* token values */ |
| 915 | 919 | ||
| 916 | /* warning: the following compare tokens depend on i386 asm code */ | 920 | /* warning: the following compare tokens depend on i386 asm code */ |
| @@ -1147,7 +1151,7 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c); · 230 unmodified lines | |||
| 1147 | ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep); | 1151 | ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep); |
| 1148 | ST_INLN Sym *struct_find(int v); | 1152 | ST_INLN Sym *struct_find(int v); |
| 1149 | ST_INLN Sym *sym_find(int v); | 1153 | ST_INLN Sym *sym_find(int v); |
| 1150 | ST_FUNC Sym *global_identifier_push_1(Sym **, int v, int t, int c); | 1154 | ST_FUNC Sym *global_identifier_push(int v, int t, int c); |
| 1151 | 1155 | ||
| 1152 | ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen); | 1156 | ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen); |
| 1153 | ST_FUNC int tcc_open(TCCState *s1, const char *filename); | 1157 | ST_FUNC int tcc_open(TCCState *s1, const char *filename); |
| @@ -1317,6 +1321,7 @@ ST_FUNC int ieee_finite(double d); · 163 unmodified lines | |||
| 1317 | ST_FUNC void test_lvalue(void); | 1321 | ST_FUNC void test_lvalue(void); |
| 1318 | ST_FUNC void vpushi(int v); | 1322 | ST_FUNC void vpushi(int v); |
| 1319 | ST_FUNC ElfSym *elfsym(Sym *); | 1323 | ST_FUNC ElfSym *elfsym(Sym *); |
| 1324 | ST_FUNC void update_storage(Sym *sym); | ||
| 1320 | ST_FUNC Sym *external_global_sym(int v, CType *type, int r); | 1325 | ST_FUNC Sym *external_global_sym(int v, CType *type, int r); |
| 1321 | ST_FUNC void vset(CType *type, int r, int v); | 1326 | ST_FUNC void vset(CType *type, int r, int v); |
| 1322 | ST_FUNC void vswap(void); | 1327 | ST_FUNC void vswap(void); |
| @@ -1588,7 +1593,6 @@ ST_FUNC Sym* get_asm_sym(int name, Sym *csym); · 265 unmodified lines | |||
| 1588 | ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); | 1593 | ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); |
| 1589 | ST_FUNC int asm_int_expr(TCCState *s1); | 1594 | ST_FUNC int asm_int_expr(TCCState *s1); |
| 1590 | ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess); | 1595 | ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess); |
| 1591 | ST_FUNC void asm_free_labels(TCCState *st); | ||
| 1592 | /* ------------ i386-asm.c ------------ */ | 1596 | /* ------------ i386-asm.c ------------ */ |
| 1593 | ST_FUNC void gen_expr32(ExprValue *pe); | 1597 | ST_FUNC void gen_expr32(ExprValue *pe); |
| 1594 | #ifdef TCC_TARGET_X86_64 | 1598 | #ifdef TCC_TARGET_X86_64 |
| @@ -44,11 +44,11 @@ static Sym *asm_label_find(int v) · 43 unmodified lines | |||
| 44 | 44 | ||
| 45 | static Sym *asm_label_push(int v, int t) | 45 | static Sym *asm_label_push(int v, int t) |
| 46 | { | 46 | { |
| 47 | Sym *sym = global_identifier_push_1(&tcc_state->asm_labels, v, t, 0); | 47 | Sym *sym = global_identifier_push(v, t, 0); |
| 48 | /* We always add VT_EXTERN, for sym definition that's tentative | 48 | /* We always add VT_EXTERN, for sym definition that's tentative |
| 49 | (for .set, removed for real defs), for mere references it's correct | 49 | (for .set, removed for real defs), for mere references it's correct |
| 50 | as is. */ | 50 | as is. */ |
| 51 | sym->type.t |= VT_VOID | VT_EXTERN; | 51 | sym->type.t |= VT_ASM | VT_EXTERN; |
| 52 | sym->r = VT_CONST | VT_SYM; | 52 | sym->r = VT_CONST | VT_SYM; |
| 53 | return sym; | 53 | return sym; |
| 54 | } | 54 | } |
| @@ -149,7 +149,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) · 94 unmodified lines | |||
| 149 | pe->v = 0; | 149 | pe->v = 0; |
| 150 | pe->sym = &sym_dot; | 150 | pe->sym = &sym_dot; |
| 151 | pe->pcrel = 0; | 151 | pe->pcrel = 0; |
| 152 | sym_dot.type.t = VT_VOID | VT_STATIC; | 152 | sym_dot.type.t = VT_ASM | VT_STATIC; |
| 153 | sym_dot.c = -1; | 153 | sym_dot.c = -1; |
| 154 | tcc_state->esym_dot.st_shndx = cur_text_section->sh_num; | 154 | tcc_state->esym_dot.st_shndx = cur_text_section->sh_num; |
| 155 | tcc_state->esym_dot.st_value = ind; | 155 | tcc_state->esym_dot.st_value = ind; |
| @@ -371,7 +371,7 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, · 215 unmodified lines | |||
| 371 | definitions won't have VT_EXTERN set. */ | 371 | definitions won't have VT_EXTERN set. */ |
| 372 | if (esym && esym->st_shndx != SHN_UNDEF && !(sym->type.t & VT_EXTERN)) { | 372 | if (esym && esym->st_shndx != SHN_UNDEF && !(sym->type.t & VT_EXTERN)) { |
| 373 | /* the label is already defined */ | 373 | /* the label is already defined */ |
| 374 | if (!is_local) { | 374 | if (is_local != 1) { |
| 375 | tcc_error("assembler label '%s' already defined", | 375 | tcc_error("assembler label '%s' already defined", |
| 376 | get_tok_str(label, NULL)); | 376 | get_tok_str(label, NULL)); |
| 377 | } else { | 377 | } else { |
| @@ -381,13 +381,22 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, · 3 unmodified lines | |||
| 381 | } | 381 | } |
| 382 | } else { | 382 | } else { |
| 383 | new_label: | 383 | new_label: |
| 384 | sym = asm_label_push(label, is_local ? VT_STATIC : 0); | 384 | sym = asm_label_push(label, is_local == 1 ? VT_STATIC : 0); |
| 385 | } | 385 | } |
| 386 | if (!sym->c) | 386 | if (!sym->c) |
| 387 | put_extern_sym2(sym, NULL, 0, 0, 0); | 387 | put_extern_sym2(sym, NULL, 0, 0, 0); |
| 388 | esym = elfsym(sym); | 388 | esym = elfsym(sym); |
| 389 | esym->st_shndx = sh_num; | 389 | esym->st_shndx = sh_num; |
| 390 | esym->st_value = value; | 390 | esym->st_value = value; |
| 391 | |||
| 392 | if (is_local != 2) | ||
| 393 | sym->type.t &= ~VT_EXTERN; | ||
| 394 | |||
| 395 | if (IS_ASM_SYM(sym) && !(sym->type.t & VT_ASM_GLOBAL)) { | ||
| 396 | sym->type.t |= VT_STATIC; | ||
| 397 | update_storage(sym); | ||
| 398 | } | ||
| 399 | |||
| 391 | return sym; | 400 | return sym; |
| 392 | } | 401 | } |
| 393 | 402 | ||
| @@ -410,39 +419,11 @@ static Sym* set_symbol(TCCState *s1, int label) · 16 unmodified lines | |||
| 410 | esym = elfsym(e.sym); | 419 | esym = elfsym(e.sym); |
| 411 | if (esym) | 420 | if (esym) |
| 412 | n += esym->st_value; | 421 | n += esym->st_value; |
| 413 | sym = asm_new_label1(s1, label, 0, esym ? esym->st_shndx : SHN_ABS, n); | 422 | sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n); |
| 414 | elfsym(sym)->st_other |= ST_ASM_SET; | 423 | elfsym(sym)->st_other |= ST_ASM_SET; |
| 415 | return sym; | 424 | return sym; |
| 416 | } | 425 | } |
| 417 | 426 | ||
| 418 | ST_FUNC void asm_free_labels(TCCState *st) | ||
| 419 | { | ||
| 420 | Sym *s, *s1; | ||
| 421 | |||
| 422 | for(s = st->asm_labels; s != NULL; s = s1) { | ||
| 423 | ElfSym *esym = elfsym(s); | ||
| 424 | s1 = s->prev; | ||
| 425 | /* Possibly update binding and visibility from asm directives | ||
| 426 | if the symbol has no C decl (type is VT_VOID).*/ | ||
| 427 | s->type.t &= ~VT_EXTERN; | ||
| 428 | if (esym && s->type.t == VT_VOID) { | ||
| 429 | if (!s->a.asmexport && esym->st_shndx != SHN_UNDEF) | ||
| 430 | s->type.t |= VT_STATIC; | ||
| 431 | if (s->a.visibility) | ||
| 432 | esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | ||
| 433 | | s->a.visibility; | ||
| 434 | esym->st_info = ELFW(ST_INFO)(s->a.weak ? STB_WEAK | ||
| 435 | : (s->type.t & VT_STATIC) ? STB_LOCAL | ||
| 436 | : STB_GLOBAL, | ||
| 437 | ELFW(ST_TYPE)(esym->st_info)); | ||
| 438 | } | ||
| 439 | /* remove label */ | ||
| 440 | table_ident[s->v - TOK_IDENT]->sym_identifier = s->prev_tok; | ||
| 441 | sym_free(s); | ||
| 442 | } | ||
| 443 | st->asm_labels = NULL; | ||
| 444 | } | ||
| 445 | |||
| 446 | static void use_section1(TCCState *s1, Section *sec) | 427 | static void use_section1(TCCState *s1, Section *sec) |
| 447 | { | 428 | { |
| 448 | cur_text_section->data_offset = ind; | 429 | cur_text_section->data_offset = ind; |
| @@ -696,15 +677,18 @@ static void asm_parse_directive(TCCState *s1, int global) · 247 unmodified lines | |||
| 696 | tok1 = tok; | 677 | tok1 = tok; |
| 697 | do { | 678 | do { |
| 698 | Sym *sym; | 679 | Sym *sym; |
| 699 | |||
| 700 | next(); | 680 | next(); |
| 701 | sym = get_asm_sym(tok, NULL); | 681 | sym = get_asm_sym(tok, NULL); |
| 702 | if (tok1 != TOK_ASMDIR_hidden) | 682 | if (tok1 != TOK_ASMDIR_hidden) { |
| 703 | sym->type.t &= ~VT_STATIC, sym->a.asmexport = 1; | 683 | sym->type.t &= ~VT_STATIC; |
| 684 | if (IS_ASM_SYM(sym)) | ||
| 685 | sym->type.t |= VT_ASM_GLOBAL; | ||
| 686 | } | ||
| 704 | if (tok1 == TOK_ASMDIR_weak) | 687 | if (tok1 == TOK_ASMDIR_weak) |
| 705 | sym->a.weak = 1; | 688 | sym->a.weak = 1; |
| 706 | else if (tok1 == TOK_ASMDIR_hidden) | 689 | else if (tok1 == TOK_ASMDIR_hidden) |
| 707 | sym->a.visibility = STV_HIDDEN; | 690 | sym->a.visibility = STV_HIDDEN; |
| 691 | update_storage(sym); | ||
| 708 | next(); | 692 | next(); |
| 709 | } while (tok == ','); | 693 | } while (tok == ','); |
| 710 | break; | 694 | break; |
| @@ -947,7 +931,6 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) · 236 unmodified lines | |||
| 947 | } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) { | 931 | } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) { |
| 948 | asm_parse_directive(s1, global); | 932 | asm_parse_directive(s1, global); |
| 949 | } else if (tok == TOK_PPNUM) { | 933 | } else if (tok == TOK_PPNUM) { |
| 950 | Sym *sym; | ||
| 951 | const char *p; | 934 | const char *p; |
| 952 | int n; | 935 | int n; |
| 953 | p = tokc.str.data; | 936 | p = tokc.str.data; |
| @@ -955,9 +938,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) · 1 unmodified line | |||
| 955 | if (*p != '\0') | 938 | if (*p != '\0') |
| 956 | expect("':'"); | 939 | expect("':'"); |
| 957 | /* new local label */ | 940 | /* new local label */ |
| 958 | sym = asm_new_label(s1, asm_get_local_label_name(s1, n), 1); | 941 | asm_new_label(s1, asm_get_local_label_name(s1, n), 1); |
| 959 | /* Remove the marker for tentative definitions. */ | ||
| 960 | sym->type.t &= ~VT_EXTERN; | ||
| 961 | next(); | 942 | next(); |
| 962 | skip(':'); | 943 | skip(':'); |
| 963 | goto redo; | 944 | goto redo; |
| @@ -967,8 +948,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) · 3 unmodified lines | |||
| 967 | next(); | 948 | next(); |
| 968 | if (tok == ':') { | 949 | if (tok == ':') { |
| 969 | /* new label */ | 950 | /* new label */ |
| 970 | Sym *sym = asm_new_label(s1, opcode, 0); | 951 | asm_new_label(s1, opcode, 0); |
| 971 | sym->type.t &= ~VT_EXTERN; | ||
| 972 | next(); | 952 | next(); |
| 973 | goto redo; | 953 | goto redo; |
| 974 | } else if (tok == '=') { | 954 | } else if (tok == '=') { |
| @@ -998,7 +978,6 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) · 23 unmodified lines | |||
| 998 | ind = cur_text_section->data_offset; | 978 | ind = cur_text_section->data_offset; |
| 999 | nocode_wanted = 0; | 979 | nocode_wanted = 0; |
| 1000 | ret = tcc_assemble_internal(s1, do_preprocess, 1); | 980 | ret = tcc_assemble_internal(s1, do_preprocess, 1); |
| 1001 | asm_free_labels(s1); | ||
| 1002 | cur_text_section->data_offset = ind; | 981 | cur_text_section->data_offset = ind; |
| 1003 | tcc_debug_end(s1); | 982 | tcc_debug_end(s1); |
| 1004 | return ret; | 983 | return ret; |
| @@ -310,8 +310,7 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets) · 309 unmodified lines | |||
| 310 | 310 | ||
| 311 | sym = (ElfW(Sym) *)s->data + 1; | 311 | sym = (ElfW(Sym) *)s->data + 1; |
| 312 | for(sym_index = 1; sym_index < nb_syms; sym_index++) { | 312 | for(sym_index = 1; sym_index < nb_syms; sym_index++) { |
| 313 | if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL | 313 | if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { |
| 314 | || sym->st_shndx == SHN_UNDEF) { | ||
| 315 | h = elf_hash(strtab + sym->st_name) % nb_buckets; | 314 | h = elf_hash(strtab + sym->st_name) % nb_buckets; |
| 316 | *ptr = hash[h]; | 315 | *ptr = hash[h]; |
| 317 | hash[h] = sym_index; | 316 | hash[h] = sym_index; |
| @@ -350,9 +349,8 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, · 32 unmodified lines | |||
| 350 | int *ptr, *base; | 349 | int *ptr, *base; |
| 351 | ptr = section_ptr_add(hs, sizeof(int)); | 350 | ptr = section_ptr_add(hs, sizeof(int)); |
| 352 | base = (int *)hs->data; | 351 | base = (int *)hs->data; |
| 353 | /* only add global, weak or undef symbols. The latter might | 352 | /* only add global or weak symbols. */ |
| 354 | become global late (from asm references). */ | 353 | if (ELFW(ST_BIND)(info) != STB_LOCAL) { |
| 355 | if (ELFW(ST_BIND)(info) != STB_LOCAL || shndx == SHN_UNDEF) { | ||
| 356 | /* add another hashing entry */ | 354 | /* add another hashing entry */ |
| 357 | nbuckets = base[0]; | 355 | nbuckets = base[0]; |
| 358 | h = elf_hash((unsigned char *) name) % nbuckets; | 356 | h = elf_hash((unsigned char *) name) % nbuckets; |
| @@ -390,7 +388,7 @@ ST_FUNC int find_elf_sym(Section *s, const char *name) · 31 unmodified lines | |||
| 390 | while (sym_index != 0) { | 388 | while (sym_index != 0) { |
| 391 | sym = &((ElfW(Sym) *)s->data)[sym_index]; | 389 | sym = &((ElfW(Sym) *)s->data)[sym_index]; |
| 392 | name1 = (char *) s->link->data + sym->st_name; | 390 | name1 = (char *) s->link->data + sym->st_name; |
| 393 | if (!strcmp(name, name1)) | 391 | if (!strcmp(name, name1) && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) |
| 394 | return sym_index; | 392 | return sym_index; |
| 395 | sym_index = ((int *)hs->data)[2 + nbuckets + sym_index]; | 393 | sym_index = ((int *)hs->data)[2 + nbuckets + sym_index]; |
| 396 | } | 394 | } |
| @@ -275,11 +275,6 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 274 unmodified lines | |||
| 275 | decl(VT_CONST); | 275 | decl(VT_CONST); |
| 276 | gen_inline_functions(s1); | 276 | gen_inline_functions(s1); |
| 277 | check_vstack(); | 277 | check_vstack(); |
| 278 | |||
| 279 | #ifdef CONFIG_TCC_ASM | ||
| 280 | asm_free_labels(s1); | ||
| 281 | #endif | ||
| 282 | |||
| 283 | /* end of translation unit info */ | 278 | /* end of translation unit info */ |
| 284 | tcc_debug_end(s1); | 279 | tcc_debug_end(s1); |
| 285 | return 0; | 280 | return 0; |
| @@ -297,28 +292,42 @@ ST_FUNC ElfSym *elfsym(Sym *s) · 11 unmodified lines | |||
| 297 | } | 292 | } |
| 298 | 293 | ||
| 299 | /* apply storage attributes to Elf symbol */ | 294 | /* apply storage attributes to Elf symbol */ |
| 300 | 295 | ST_FUNC void update_storage(Sym *sym) | |
| 301 | static void update_storage(Sym *sym) | ||
| 302 | { | 296 | { |
| 303 | ElfSym *esym = elfsym(sym); | 297 | ElfSym *esym; |
| 298 | int sym_bind, old_sym_bind; | ||
| 299 | |||
| 300 | esym = elfsym(sym); | ||
| 304 | if (!esym) | 301 | if (!esym) |
| 305 | return; | 302 | return; |
| 303 | |||
| 306 | if (sym->a.visibility) | 304 | if (sym->a.visibility) |
| 307 | esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | 305 | esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) |
| 308 | | sym->a.visibility; | 306 | | sym->a.visibility; |
| 309 | if (sym->a.weak) | 307 | |
| 310 | esym->st_info = ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(esym->st_info)); | 308 | if (sym->type.t & VT_STATIC) |
| 309 | sym_bind = STB_LOCAL; | ||
| 310 | else if (sym->a.weak) | ||
| 311 | sym_bind = STB_WEAK; | ||
| 312 | else | ||
| 313 | sym_bind = STB_GLOBAL; | ||
| 314 | old_sym_bind = ELFW(ST_BIND)(esym->st_info); | ||
| 315 | if (sym_bind != old_sym_bind) { | ||
| 316 | esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info)); | ||
| 317 | } | ||
| 318 | |||
| 311 | #ifdef TCC_TARGET_PE | 319 | #ifdef TCC_TARGET_PE |
| 312 | if (sym->a.dllimport) | 320 | if (sym->a.dllimport) |
| 313 | esym->st_other |= ST_PE_IMPORT; | 321 | esym->st_other |= ST_PE_IMPORT; |
| 314 | if (sym->a.dllexport) | 322 | if (sym->a.dllexport) |
| 315 | esym->st_other |= ST_PE_EXPORT; | 323 | esym->st_other |= ST_PE_EXPORT; |
| 316 | #endif | 324 | #endif |
| 325 | |||
| 317 | #if 0 | 326 | #if 0 |
| 318 | printf("storage %s: vis=%d weak=%d exp=%d imp=%d\n", | 327 | printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n", |
| 319 | get_tok_str(sym->v, NULL), | 328 | get_tok_str(sym->v, NULL), |
| 329 | sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g', | ||
| 320 | sym->a.visibility, | 330 | sym->a.visibility, |
| 321 | sym->a.weak, | ||
| 322 | sym->a.dllexport, | 331 | sym->a.dllexport, |
| 323 | sym->a.dllimport | 332 | sym->a.dllimport |
| 324 | ); | 333 | ); |
| @@ -578,10 +587,10 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) · 253 unmodified lines | |||
| 578 | } | 587 | } |
| 579 | 588 | ||
| 580 | /* push a global identifier */ | 589 | /* push a global identifier */ |
| 581 | ST_FUNC Sym *global_identifier_push_1(Sym **ptop, int v, int t, int c) | 590 | ST_FUNC Sym *global_identifier_push(int v, int t, int c) |
| 582 | { | 591 | { |
| 583 | Sym *s, **ps; | 592 | Sym *s, **ps; |
| 584 | s = sym_push2(ptop, v, t, c); | 593 | s = sym_push2(&global_stack, v, t, c); |
| 585 | /* don't record anonymous symbol */ | 594 | /* don't record anonymous symbol */ |
| 586 | if (v < SYM_FIRST_ANOM) { | 595 | if (v < SYM_FIRST_ANOM) { |
| 587 | ps = &table_ident[v - TOK_IDENT]->sym_identifier; | 596 | ps = &table_ident[v - TOK_IDENT]->sym_identifier; |
| @@ -595,11 +604,6 @@ ST_FUNC Sym *global_identifier_push_1(Sym **ptop, int v, int t, int c) · 7 unmodified lines | |||
| 595 | return s; | 604 | return s; |
| 596 | } | 605 | } |
| 597 | 606 | ||
| 598 | static Sym *global_identifier_push(int v, int t, int c) | ||
| 599 | { | ||
| 600 | return global_identifier_push_1(&global_stack, v, t, c); | ||
| 601 | } | ||
| 602 | |||
| 603 | /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really | 607 | /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really |
| 604 | pop them yet from the list, but do remove them from the token array. */ | 608 | pop them yet from the list, but do remove them from the token array. */ |
| 605 | ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep) | 609 | ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep) |
| @@ -841,6 +845,9 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r) · 235 unmodified lines | |||
| 841 | s = global_identifier_push(v, type->t | VT_EXTERN, 0); | 845 | s = global_identifier_push(v, type->t | VT_EXTERN, 0); |
| 842 | s->type.ref = type->ref; | 846 | s->type.ref = type->ref; |
| 843 | s->r = r | VT_CONST | VT_SYM; | 847 | s->r = r | VT_CONST | VT_SYM; |
| 848 | } else if (IS_ASM_SYM(s)) { | ||
| 849 | s->type.t = type->t | (s->type.t & VT_EXTERN); | ||
| 850 | s->type.ref = type->ref; | ||
| 844 | } | 851 | } |
| 845 | return s; | 852 | return s; |
| 846 | } | 853 | } |
| @@ -849,7 +856,7 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r) · 2 unmodified lines | |||
| 849 | static void patch_storage(Sym *sym, AttributeDef *ad, CType *type) | 856 | static void patch_storage(Sym *sym, AttributeDef *ad, CType *type) |
| 850 | { | 857 | { |
| 851 | if (type) { | 858 | if (type) { |
| 852 | if ((sym->type.t & VT_BTYPE) == VT_VOID) /* from asm */ | 859 | if (IS_ASM_SYM(sym)) |
| 853 | sym->type = *type; | 860 | sym->type = *type; |
| 854 | else if (!is_compatible_types(&sym->type, type)) | 861 | else if (!is_compatible_types(&sym->type, type)) |
| 855 | tcc_error("incompatible types for redefinition of '%s'", | 862 | tcc_error("incompatible types for redefinition of '%s'", |
| @@ -5026,7 +5033,7 @@ ST_FUNC void unary(void) · 4170 unmodified lines | |||
| 5026 | if (t < TOK_UIDENT) | 5033 | if (t < TOK_UIDENT) |
| 5027 | expect("identifier"); | 5034 | expect("identifier"); |
| 5028 | s = sym_find(t); | 5035 | s = sym_find(t); |
| 5029 | if (!s) { | 5036 | if (!s || IS_ASM_SYM(s)) { |
| 5030 | const char *name = get_tok_str(t, NULL); | 5037 | const char *name = get_tok_str(t, NULL); |
| 5031 | if (tok != '(') | 5038 | if (tok != '(') |
| 5032 | tcc_error("'%s' undeclared", name); | 5039 | tcc_error("'%s' undeclared", name); |
| @@ -7223,12 +7230,8 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 2190 unmodified lines | |||
| 7223 | type.t = (type.t & ~VT_EXTERN) | VT_STATIC; | 7230 | type.t = (type.t & ~VT_EXTERN) | VT_STATIC; |
| 7224 | 7231 | ||
| 7225 | sym = sym_find(v); | 7232 | sym = sym_find(v); |
| 7226 | if (sym) { | 7233 | if (sym && !IS_ASM_SYM(sym)) { |
| 7227 | Sym *ref; | 7234 | Sym *ref; |
| 7228 | /* If type is VT_VOID the symbol was created by tccasm | ||
| 7229 | first, and we see the first reference from C now. */ | ||
| 7230 | if ((sym->type.t & VT_BTYPE) == VT_VOID) | ||
| 7231 | sym->type = type; | ||
| 7232 | 7235 | ||
| 7233 | if ((sym->type.t & VT_BTYPE) != VT_FUNC) | 7236 | if ((sym->type.t & VT_BTYPE) != VT_FUNC) |
| 7234 | goto func_error1; | 7237 | goto func_error1; |
| @@ -7261,15 +7264,14 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 26 unmodified lines | |||
| 7261 | tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); | 7264 | tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); |
| 7262 | /* if symbol is already defined, then put complete type */ | 7265 | /* if symbol is already defined, then put complete type */ |
| 7263 | sym->type = type; | 7266 | sym->type = type; |
| 7267 | sym->r = VT_SYM | VT_CONST; | ||
| 7264 | 7268 | ||
| 7265 | } else { | 7269 | } else { |
| 7266 | /* put function symbol */ | 7270 | /* put function symbol */ |
| 7267 | sym = global_identifier_push(v, type.t, 0); | 7271 | sym = external_global_sym(v, &type, 0); |
| 7268 | sym->type.ref = type.ref; | ||
| 7269 | } | 7272 | } |
| 7270 | 7273 | ||
| 7271 | sym->type.ref->f.func_body = 1; | 7274 | sym->type.ref->f.func_body = 1; |
| 7272 | sym->r = VT_SYM | VT_CONST; | ||
| 7273 | patch_storage(sym, &ad, NULL); | 7275 | patch_storage(sym, &ad, NULL); |
| 7274 | 7276 | ||
| 7275 | /* static inline functions are just recorded as a kind | 7277 | /* static inline functions are just recorded as a kind |