Add support for asm labels for variables, that is the ability to rename a variable at assembly level with __asm__ ("newname") appended in its declaration. See http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Asm-Labels.html for more details.
Unified · Split
| @@ -75,7 +75,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td); · 74 unmodified lines | ||
| 75 | 75 | static void parse_expr_type(CType *type); |
| 76 | 76 | static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); |
| 77 | 77 | static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr); |
| 78 | −static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); | |
| 78 | +static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope); | |
| 79 | 79 | static void expr_eq(void); |
| 80 | 80 | static void unary_type(CType *type); |
| 81 | 81 | static int is_compatible_parameter_types(CType *type1, CType *type2); |
| @@ -3385,7 +3385,7 @@ ST_FUNC void unary(void) · 3303 unmodified lines | ||
| 3385 | 3385 | mk_pointer(&type); |
| 3386 | 3386 | type.t |= VT_ARRAY; |
| 3387 | 3387 | memset(&ad, 0, sizeof(AttributeDef)); |
| 3388 | − decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0); | |
| 3388 | + decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0); | |
| 3389 | 3389 | break; |
| 3390 | 3390 | case '(': |
| 3391 | 3391 | next(); |
| @@ -3404,7 +3404,7 @@ ST_FUNC void unary(void) · 12 unmodified lines | ||
| 3404 | 3404 | if (!(type.t & VT_ARRAY)) |
| 3405 | 3405 | r |= lvalue_type(type.t); |
| 3406 | 3406 | memset(&ad, 0, sizeof(AttributeDef)); |
| 3407 | − decl_initializer_alloc(&type, &ad, r, 1, 0, 0); | |
| 3407 | + decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0); | |
| 3408 | 3408 | } else { |
| 3409 | 3409 | if (sizeof_caller) { |
| 3410 | 3410 | vpush(&type); |
| @@ -4992,12 +4992,14 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 1581 unmodified lines | ||
| 4992 | 4992 | /* parse an initializer for type 't' if 'has_init' is non zero, and |
| 4993 | 4993 | allocate space in local or global data space ('r' is either |
| 4994 | 4994 | VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated |
| 4995 | − variable 'v' of scope 'scope' is declared before initializers are | |
| 4996 | − parsed. If 'v' is zero, then a reference to the new object is put | |
| 4997 | − in the value stack. If 'has_init' is 2, a special parsing is done | |
| 4998 | − to handle string constants. */ | |
| 4995 | + variable 'v' with an associated name represented by 'asm_label' of | |
| 4996 | + scope 'scope' is declared before initializers are parsed. If 'v' is | |
| 4997 | + zero, then a reference to the new object is put in the value stack. | |
| 4998 | + If 'has_init' is 2, a special parsing is done to handle string | |
| 4999 | + constants. */ | |
| 4999 | 5000 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, |
| 5000 | − int has_init, int v, int scope) | |
| 5001 | + int has_init, int v, char *asm_label, | |
| 5002 | + int scope) | |
| 5001 | 5003 | { |
| 5002 | 5004 | int size, align, addr, data_offset; |
| 5003 | 5005 | int level; |
| @@ -5164,6 +5166,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 160 unmodified lines | ||
| 5164 | 5166 | if (v) { |
| 5165 | 5167 | if (scope != VT_CONST || !sym) { |
| 5166 | 5168 | sym = sym_push(v, type, r | VT_SYM, 0); |
| 5169 | + sym->asm_label = asm_label; | |
| 5167 | 5170 | } |
| 5168 | 5171 | /* update symbol definition */ |
| 5169 | 5172 | if (sec) { |
| @@ -5550,10 +5553,20 @@ ST_FUNC void decl(int l) · 380 unmodified lines | ||
| 5550 | 5553 | if (gnu_ext && (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)) |
| 5551 | 5554 | parse_attribute((AttributeDef *) &fn->type.ref->r); |
| 5552 | 5555 | } else { |
| 5556 | + char *asm_label; // associated asm label | |
| 5557 | + | |
| 5553 | 5558 | /* not lvalue if array */ |
| 5554 | 5559 | r = 0; |
| 5560 | + asm_label = NULL; | |
| 5555 | 5561 | if (!(type.t & VT_ARRAY)) |
| 5556 | 5562 | r |= lvalue_type(type.t); |
| 5563 | + if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { | |
| 5564 | + CString astr; | |
| 5565 | + | |
| 5566 | + asm_label_instr(&astr); | |
| 5567 | + asm_label = tcc_strdup(astr.data); | |
| 5568 | + cstr_free(&astr); | |
| 5569 | + } | |
| 5557 | 5570 | has_init = (tok == '='); |
| 5558 | 5571 | if ((btype.t & VT_EXTERN) || |
| 5559 | 5572 | ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && |
| @@ -5562,7 +5575,7 @@ ST_FUNC void decl(int l) · 2 unmodified lines | ||
| 5562 | 5575 | /* NOTE: as GCC, uninitialized global static |
| 5563 | 5576 | arrays of null size are considered as |
| 5564 | 5577 | extern */ |
| 5565 | − external_sym(v, &type, r, NULL); | |
| 5578 | + external_sym(v, &type, r, asm_label); | |
| 5566 | 5579 | } else { |
| 5567 | 5580 | type.t |= (btype.t & VT_STATIC); /* Retain "static". */ |
| 5568 | 5581 | if (type.t & VT_STATIC) |
| @@ -5571,7 +5584,7 @@ ST_FUNC void decl(int l) · 2 unmodified lines | ||
| 5571 | 5584 | r |= l; |
| 5572 | 5585 | if (has_init) |
| 5573 | 5586 | next(); |
| 5574 | − decl_initializer_alloc(&type, &ad, r, has_init, v, l); | |
| 5587 | + decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l); | |
| 5575 | 5588 | } |
| 5576 | 5589 | } |
| 5577 | 5590 | if (tok != ',') { |