| @@ -128,6 +128,7 @@ static inline Sym *sym_malloc(void) · 127 unmodified lines |
| 128 | 128 | ST_INLN void sym_free(Sym *sym) |
| 129 | 129 | { |
| 130 | 130 | sym->next = sym_free_first; |
| 131 | + tcc_free(sym->asm_label); |
| 131 | 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 | 138 | Sym *s; |
| 138 | 139 | s = sym_malloc(); |
| 139 | | − s->a = 0; |
| 140 | + s->asm_label = NULL; |
| 140 | 141 | s->v = v; |
| 141 | 142 | s->type.t = t; |
| 142 | 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 | 361 | return s; |
| 361 | 362 | } |
| 362 | 363 | |
| 363 | | −/* define a new external reference to a symbol 'v' of type 'u' */ |
| 364 | | −static Sym *external_sym(int v, CType *type, int r) |
| 364 | +/* define a new external reference to a symbol 'v' with alternate asm |
| 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 | 369 | Sym *s; |
| 367 | 370 | |
| @@ -369,8 +372,7 @@ static Sym *external_sym(int v, CType *type, int r) · 1 unmodified line |
| 369 | 372 | if (!s) { |
| 370 | 373 | /* push forward reference */ |
| 371 | 374 | s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); |
| 372 | | − if (type && type->ref && type->ref->a) |
| 373 | | − s->a = type->ref->a; |
| 375 | + s->asm_label = asm_label; |
| 374 | 376 | s->type.t |= VT_EXTERN; |
| 375 | 377 | } else if (s->type.ref == func_old_type.ref) { |
| 376 | 378 | s->type.ref = type->ref; |
| @@ -3029,8 +3031,6 @@ static void post_type(CType *type, AttributeDef *ad) · 2652 unmodified lines |
| 3029 | 3031 | CType pt; |
| 3030 | 3032 | |
| 3031 | 3033 | if (tok == '(') { |
| 3032 | | − TokenSym *ts = NULL; |
| 3033 | | − |
| 3034 | 3034 | /* function declaration */ |
| 3035 | 3035 | next(); |
| 3036 | 3036 | l = 0; |
| @@ -3086,19 +3086,10 @@ static void post_type(CType *type, AttributeDef *ad) · 49 unmodified lines |
| 3086 | 3086 | /* NOTE: const is ignored in returned type as it has a special |
| 3087 | 3087 | meaning in gcc / C++ */ |
| 3088 | 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 | 3089 | post_type(type, ad); |
| 3097 | 3090 | /* we push a anonymous symbol which will contain the function prototype */ |
| 3098 | 3091 | ad->func_args = arg_size; |
| 3099 | 3092 | s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); |
| 3100 | | − if (ts != NULL) |
| 3101 | | − s->a = ts->tok; |
| 3102 | 3093 | s->next = first; |
| 3103 | 3094 | type->t = t1 | VT_FUNC; |
| 3104 | 3095 | type->ref = s; |
| @@ -5251,7 +5242,8 @@ static void func_decl_list(Sym *func_sym) · 2146 unmodified lines |
| 5251 | 5242 | CType btype, type; |
| 5252 | 5243 | |
| 5253 | 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 | 5247 | if (!parse_btype(&btype, &ad)) |
| 5256 | 5248 | expect("declaration list"); |
| 5257 | 5249 | if (((btype.t & VT_BTYPE) == VT_ENUM || |
| @@ -5298,10 +5290,7 @@ static void gen_function(Sym *sym) · 40 unmodified lines |
| 5298 | 5290 | ind = cur_text_section->data_offset; |
| 5299 | 5291 | /* NOTE: we patch the symbol size later */ |
| 5300 | 5292 | put_extern_sym(sym, cur_text_section, ind, 0); |
| 5301 | | − if (sym->a) |
| 5302 | | − funcname = get_tok_str(sym->a, NULL); |
| 5303 | | − else |
| 5304 | | − funcname = get_tok_str(sym->v, NULL); |
| 5293 | + funcname = get_tok_str(sym->v, NULL); |
| 5305 | 5294 | func_ind = ind; |
| 5306 | 5295 | /* put debug symbol */ |
| 5307 | 5296 | if (tcc_state->do_debug) |
| @@ -5387,12 +5376,6 @@ ST_FUNC void decl(int l) · 79 unmodified lines |
| 5387 | 5376 | Sym *sym; |
| 5388 | 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 | 5379 | while (1) { |
| 5397 | 5380 | if (!parse_btype(&btype, &ad)) { |
| 5398 | 5381 | /* skip redundant ';' */ |
| @@ -5548,39 +5531,24 @@ ST_FUNC void decl(int l) · 149 unmodified lines |
| 5548 | 5531 | sym = sym_push(v, &type, INT_ATTR(&ad), 0); |
| 5549 | 5532 | sym->type.t |= VT_TYPEDEF; |
| 5550 | 5533 | } else if ((type.t & VT_BTYPE) == VT_FUNC) { |
| 5534 | + char *asm_label; // associated asm label |
| 5551 | 5535 | Sym *fn; |
| 5536 | + |
| 5537 | + asm_label = NULL; |
| 5552 | 5538 | /* external function definition */ |
| 5553 | 5539 | /* specific case for func_call attribute */ |
| 5554 | 5540 | type.ref->r = INT_ATTR(&ad); |
| 5555 | | − fn = external_sym(v, &type, 0); |
| 5556 | 5541 | |
| 5557 | 5542 | if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { |
| 5558 | | − char target[256]; |
| 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); |
| 5543 | + CString astr; |
| 5580 | 5544 | |
| 5581 | | − if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) |
| 5582 | | − parse_attribute((AttributeDef *) &fn->type.ref->r); |
| 5545 | + asm_label_instr(&astr); |
| 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 | 5552 | } else { |
| 5585 | 5553 | /* not lvalue if array */ |
| 5586 | 5554 | r = 0; |
| @@ -5594,7 +5562,7 @@ ST_FUNC void decl(int l) · 7 unmodified lines |
| 5594 | 5562 | /* NOTE: as GCC, uninitialized global static |
| 5595 | 5563 | arrays of null size are considered as |
| 5596 | 5564 | extern */ |
| 5597 | | − external_sym(v, &type, r); |
| 5565 | + external_sym(v, &type, r, NULL); |
| 5598 | 5566 | } else { |
| 5599 | 5567 | type.t |= (btype.t & VT_STATIC); /* Retain "static". */ |
| 5600 | 5568 | if (type.t & VT_STATIC) |