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