| @@ -128,6 +128,7 @@ static inline Sym *sym_malloc(void) · 127 unmodified lines |
| 128 | ST_INLN void sym_free(Sym *sym) | 128 | ST_INLN void sym_free(Sym *sym) |
| 129 | { | 129 | { |
| 130 | sym->next = sym_free_first; | 130 | sym->next = sym_free_first; |
| | 131 | tcc_free(sym->asm_label); |
| 131 | sym_free_first = sym; | 132 | sym_free_first = sym; |
| 132 | } | 133 | } |
| 133 | | 134 | |
| @@ -136,7 +137,7 @@ ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c) · 2 unmodified lines |
| 136 | { | 137 | { |
| 137 | Sym *s; | 138 | Sym *s; |
| 138 | s = sym_malloc(); | 139 | s = sym_malloc(); |
| 139 | s->a = 0; | 140 | s->asm_label = NULL; |
| 140 | s->v = v; | 141 | s->v = v; |
| 141 | s->type.t = t; | 142 | s->type.t = t; |
| 142 | s->type.ref = NULL; | 143 | s->type.ref = NULL; |
| @@ -360,8 +361,10 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r) · 217 unmodified lines |
| 360 | return s; | 361 | return s; |
| 361 | } | 362 | } |
| 362 | | 363 | |
| 363 | /* define a new external reference to a symbol 'v' of type 'u' */ | 364 | /* define a new external reference to a symbol 'v' with alternate asm |
| 364 | static Sym *external_sym(int v, CType *type, int r) | 365 | name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there |
| | 366 | is no alternate name (most cases) */ |
| | 367 | static Sym *external_sym(int v, CType *type, int r, char *asm_label) |
| 365 | { | 368 | { |
| 366 | Sym *s; | 369 | Sym *s; |
| 367 | | 370 | |
| @@ -369,8 +372,7 @@ static Sym *external_sym(int v, CType *type, int r) · 1 unmodified line |
| 369 | if (!s) { | 372 | if (!s) { |
| 370 | /* push forward reference */ | 373 | /* push forward reference */ |
| 371 | s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); | 374 | s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); |
| 372 | if (type && type->ref && type->ref->a) | 375 | s->asm_label = asm_label; |
| 373 | s->a = type->ref->a; | | |
| 374 | s->type.t |= VT_EXTERN; | 376 | s->type.t |= VT_EXTERN; |
| 375 | } else if (s->type.ref == func_old_type.ref) { | 377 | } else if (s->type.ref == func_old_type.ref) { |
| 376 | s->type.ref = type->ref; | 378 | s->type.ref = type->ref; |
| @@ -3029,8 +3031,6 @@ static void post_type(CType *type, AttributeDef *ad) · 2652 unmodified lines |
| 3029 | CType pt; | 3031 | CType pt; |
| 3030 | | 3032 | |
| 3031 | if (tok == '(') { | 3033 | if (tok == '(') { |
| 3032 | TokenSym *ts = NULL; | | |
| 3033 | | | |
| 3034 | /* function declaration */ | 3034 | /* function declaration */ |
| 3035 | next(); | 3035 | next(); |
| 3036 | l = 0; | 3036 | l = 0; |
| @@ -3086,19 +3086,10 @@ static void post_type(CType *type, AttributeDef *ad) · 49 unmodified lines |
| 3086 | /* NOTE: const is ignored in returned type as it has a special | 3086 | /* NOTE: const is ignored in returned type as it has a special |
| 3087 | meaning in gcc / C++ */ | 3087 | meaning in gcc / C++ */ |
| 3088 | type->t &= ~(VT_STORAGE | VT_CONSTANT); | 3088 | type->t &= ~(VT_STORAGE | VT_CONSTANT); |
| 3089 | if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { | | |
| 3090 | CString astr; | | |
| 3091 | | | |
| 3092 | asm_label_instr(&astr); | | |
| 3093 | ts = tok_alloc(astr.data, strlen(astr.data)); | | |
| 3094 | cstr_free(&astr); | | |
| 3095 | } | | |
| 3096 | post_type(type, ad); | 3089 | post_type(type, ad); |
| 3097 | /* we push a anonymous symbol which will contain the function prototype */ | 3090 | /* we push a anonymous symbol which will contain the function prototype */ |
| 3098 | ad->func_args = arg_size; | 3091 | ad->func_args = arg_size; |
| 3099 | s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); | 3092 | s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); |
| 3100 | if (ts != NULL) | | |
| 3101 | s->a = ts->tok; | | |
| 3102 | s->next = first; | 3093 | s->next = first; |
| 3103 | type->t = t1 | VT_FUNC; | 3094 | type->t = t1 | VT_FUNC; |
| 3104 | type->ref = s; | 3095 | type->ref = s; |
| @@ -5251,7 +5242,8 @@ static void func_decl_list(Sym *func_sym) · 2146 unmodified lines |
| 5251 | CType btype, type; | 5242 | CType btype, type; |
| 5252 | | 5243 | |
| 5253 | /* parse each declaration */ | 5244 | /* parse each declaration */ |
| 5254 | while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) { | 5245 | while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF && |
| | 5246 | tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) { |
| 5255 | if (!parse_btype(&btype, &ad)) | 5247 | if (!parse_btype(&btype, &ad)) |
| 5256 | expect("declaration list"); | 5248 | expect("declaration list"); |
| 5257 | if (((btype.t & VT_BTYPE) == VT_ENUM || | 5249 | if (((btype.t & VT_BTYPE) == VT_ENUM || |
| @@ -5298,10 +5290,7 @@ static void gen_function(Sym *sym) · 40 unmodified lines |
| 5298 | ind = cur_text_section->data_offset; | 5290 | ind = cur_text_section->data_offset; |
| 5299 | /* NOTE: we patch the symbol size later */ | 5291 | /* NOTE: we patch the symbol size later */ |
| 5300 | put_extern_sym(sym, cur_text_section, ind, 0); | 5292 | put_extern_sym(sym, cur_text_section, ind, 0); |
| 5301 | if (sym->a) | 5293 | funcname = get_tok_str(sym->v, NULL); |
| 5302 | funcname = get_tok_str(sym->a, NULL); | | |
| 5303 | else | | |
| 5304 | funcname = get_tok_str(sym->v, NULL); | | |
| 5305 | func_ind = ind; | 5294 | func_ind = ind; |
| 5306 | /* put debug symbol */ | 5295 | /* put debug symbol */ |
| 5307 | if (tcc_state->do_debug) | 5296 | if (tcc_state->do_debug) |
| @@ -5387,12 +5376,6 @@ ST_FUNC void decl(int l) · 79 unmodified lines |
| 5387 | Sym *sym; | 5376 | Sym *sym; |
| 5388 | AttributeDef ad; | 5377 | AttributeDef ad; |
| 5389 | | 5378 | |
| 5390 | /* | | |
| 5391 | * type.ref must be either a valid reference or NULL for external_sym to | | |
| 5392 | * work. As type = btype is executed before external_sym is call, setting | | |
| 5393 | * btype.ref to 0 is enough. | | |
| 5394 | */ | | |
| 5395 | btype.ref = 0; | | |
| 5396 | while (1) { | 5379 | while (1) { |
| 5397 | if (!parse_btype(&btype, &ad)) { | 5380 | if (!parse_btype(&btype, &ad)) { |
| 5398 | /* skip redundant ';' */ | 5381 | /* skip redundant ';' */ |
| @@ -5548,39 +5531,24 @@ ST_FUNC void decl(int l) · 149 unmodified lines |
| 5548 | sym = sym_push(v, &type, INT_ATTR(&ad), 0); | 5531 | sym = sym_push(v, &type, INT_ATTR(&ad), 0); |
| 5549 | sym->type.t |= VT_TYPEDEF; | 5532 | sym->type.t |= VT_TYPEDEF; |
| 5550 | } else if ((type.t & VT_BTYPE) == VT_FUNC) { | 5533 | } else if ((type.t & VT_BTYPE) == VT_FUNC) { |
| | 5534 | char *asm_label; // associated asm label |
| 5551 | Sym *fn; | 5535 | Sym *fn; |
| | 5536 | |
| | 5537 | asm_label = NULL; |
| 5552 | /* external function definition */ | 5538 | /* external function definition */ |
| 5553 | /* specific case for func_call attribute */ | 5539 | /* specific case for func_call attribute */ |
| 5554 | type.ref->r = INT_ATTR(&ad); | 5540 | type.ref->r = INT_ATTR(&ad); |
| 5555 | fn = external_sym(v, &type, 0); | | |
| 5556 | | 5541 | |
| 5557 | if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { | 5542 | if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { |
| 5558 | char target[256]; | 5543 | CString astr; |
| 5559 | | | |
| 5560 | *target = 0; | | |
| 5561 | next(); | | |
| 5562 | skip('('); | | |
| 5563 | /* Part 1: __USER_LABEL_PREFIX__ (user defined) */ | | |
| 5564 | if (tok == TOK_STR) | | |
| 5565 | pstrcat(target, sizeof(target), tokc.cstr->data); | | |
| 5566 | else | | |
| 5567 | pstrcat(target, sizeof(target), get_tok_str(tok, NULL)); | | |
| 5568 | | | |
| 5569 | next(); | | |
| 5570 | /* Part 2: api name */ | | |
| 5571 | if (tok == TOK_STR) | | |
| 5572 | pstrcat(target, sizeof(target), tokc.cstr->data); | | |
| 5573 | else | | |
| 5574 | pstrcat(target, sizeof(target), get_tok_str(tok, NULL)); | | |
| 5575 | | | |
| 5576 | next(); | | |
| 5577 | skip(')'); | | |
| 5578 | if (tcc_state->warn_unsupported) | | |
| 5579 | warning("ignoring redirection from %s to %s\n", get_tok_str(v, NULL), target); | | |
| 5580 | | 5544 | |
| 5581 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) | 5545 | asm_label_instr(&astr); |
| 5582 | parse_attribute((AttributeDef *) &fn->type.ref->r); | 5546 | asm_label = tcc_strdup(astr.data); |
| | 5547 | cstr_free(&astr); |
| 5583 | } | 5548 | } |
| | 5549 | fn = external_sym(v, &type, 0, asm_label); |
| | 5550 | if (gnu_ext && (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)) |
| | 5551 | parse_attribute((AttributeDef *) &fn->type.ref->r); |
| 5584 | } else { | 5552 | } else { |
| 5585 | /* not lvalue if array */ | 5553 | /* not lvalue if array */ |
| 5586 | r = 0; | 5554 | r = 0; |
| @@ -5594,7 +5562,7 @@ ST_FUNC void decl(int l) · 7 unmodified lines |
| 5594 | /* NOTE: as GCC, uninitialized global static | 5562 | /* NOTE: as GCC, uninitialized global static |
| 5595 | arrays of null size are considered as | 5563 | arrays of null size are considered as |
| 5596 | extern */ | 5564 | extern */ |
| 5597 | external_sym(v, &type, r); | 5565 | external_sym(v, &type, r, NULL); |
| 5598 | } else { | 5566 | } else { |
| 5599 | type.t |= (btype.t & VT_STATIC); /* Retain "static". */ | 5567 | type.t |= (btype.t & VT_STATIC); /* Retain "static". */ |
| 5600 | if (type.t & VT_STATIC) | 5568 | if (type.t & VT_STATIC) |