tccgen: asm_label cleanup

- avoid memory allocation by using its (int) token number
- avoid additional function parameter by using Attribute

Also: fix some strange looking error messages
master
grischka 2015-11-20 11:22:56 +01:00
parent 992cbda8d0
commit 54cf57ab1a
4 changed files with 42 additions and 42 deletions

View File

@ -680,7 +680,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
name = buf1; name = buf1;
} }
if (sym->asm_label) { if (sym->asm_label) {
name = sym->asm_label; name = get_tok_str(sym->asm_label, NULL);
} }
info = ELFW(ST_INFO)(sym_bind, sym_type); info = ELFW(ST_INFO)(sym_bind, sym_type);
sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name); sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);

3
tcc.h
View File

@ -434,12 +434,13 @@ typedef struct AttributeDef {
struct Attribute a; struct Attribute a;
struct Section *section; struct Section *section;
int alias_target; /* token */ int alias_target; /* token */
int asm_label; /* associated asm label */
} AttributeDef; } AttributeDef;
/* symbol management */ /* symbol management */
typedef struct Sym { typedef struct Sym {
int v; /* symbol token */ int v; /* symbol token */
char *asm_label; /* associated asm label */ int asm_label; /* associated asm label */
union { union {
long r; /* associated register */ long r; /* associated register */
struct Attribute a; struct Attribute a;

View File

@ -81,7 +81,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
static void parse_expr_type(CType *type); static void parse_expr_type(CType *type);
static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr); static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope); static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
static int decl0(int l, int is_for_loop_init); static int decl0(int l, int is_for_loop_init);
static void expr_eq(void); static void expr_eq(void);
static void unary_type(CType *type); static void unary_type(CType *type);
@ -158,7 +158,6 @@ static inline Sym *sym_malloc(void)
ST_INLN void sym_free(Sym *sym) ST_INLN void sym_free(Sym *sym)
{ {
sym->next = sym_free_first; sym->next = sym_free_first;
tcc_free(sym->asm_label);
sym_free_first = sym; sym_free_first = sym;
} }
@ -173,7 +172,7 @@ ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
get_tok_str(v, NULL)); get_tok_str(v, NULL));
} }
s = sym_malloc(); s = sym_malloc();
s->asm_label = NULL; s->asm_label = 0;
s->v = v; s->v = v;
s->type.t = t; s->type.t = t;
s->type.ref = NULL; s->type.ref = NULL;
@ -443,10 +442,8 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
return s; return s;
} }
/* define a new external reference to a symbol 'v' with alternate asm /* define a new external reference to a symbol 'v' */
name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there static Sym *external_sym(int v, CType *type, int r)
is no alternate name (most cases) */
static Sym *external_sym(int v, CType *type, int r, char *asm_label)
{ {
Sym *s; Sym *s;
@ -454,7 +451,6 @@ static Sym *external_sym(int v, CType *type, int r, char *asm_label)
if (!s) { if (!s) {
/* push forward reference */ /* push forward reference */
s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
s->asm_label = asm_label ? tcc_strdup(asm_label) : 0;
s->type.t |= VT_EXTERN; s->type.t |= VT_EXTERN;
} else if (s->type.ref == func_old_type.ref) { } else if (s->type.ref == func_old_type.ref) {
s->type.ref = type->ref; s->type.ref = type->ref;
@ -3386,16 +3382,21 @@ ST_FUNC void parse_asm_str(CString *astr)
cstr_ccat(astr, '\0'); cstr_ccat(astr, '\0');
} }
/* Parse an asm label and return the label /* Parse an asm label and return the token */
* Don't forget to free the CString in the caller! */ static int asm_label_instr(void)
static void asm_label_instr(CString *astr)
{ {
int v;
CString astr;
next(); next();
parse_asm_str(astr); parse_asm_str(&astr);
skip(')'); skip(')');
#ifdef ASM_DEBUG #ifdef ASM_DEBUG
printf("asm_alias: \"%s\"\n", (char *)astr->data); printf("asm_alias: \"%s\"\n", (char *)astr.data);
#endif #endif
v = tok_alloc(astr.data, astr.size - 1)->tok;
cstr_free(&astr);
return v;
} }
static void post_type(CType *type, AttributeDef *ad) static void post_type(CType *type, AttributeDef *ad)
@ -3801,7 +3802,7 @@ ST_FUNC void unary(void)
mk_pointer(&type); mk_pointer(&type);
type.t |= VT_ARRAY; type.t |= VT_ARRAY;
memset(&ad, 0, sizeof(AttributeDef)); memset(&ad, 0, sizeof(AttributeDef));
decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0); decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
break; break;
case '(': case '(':
next(); next();
@ -3820,7 +3821,7 @@ ST_FUNC void unary(void)
if (!(type.t & VT_ARRAY)) if (!(type.t & VT_ARRAY))
r |= lvalue_type(type.t); r |= lvalue_type(type.t);
memset(&ad, 0, sizeof(AttributeDef)); memset(&ad, 0, sizeof(AttributeDef));
decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0); decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
} else { } else {
if (sizeof_caller) { if (sizeof_caller) {
vpush(&type); vpush(&type);
@ -4199,7 +4200,7 @@ ST_FUNC void unary(void)
break; break;
} }
if (!s) if (!s)
tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL)); tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
/* add field offset to pointer */ /* add field offset to pointer */
vtop->type = char_pointer_type; /* change type to 'char *' */ vtop->type = char_pointer_type; /* change type to 'char *' */
vpushi(s->c); vpushi(s->c);
@ -5742,14 +5743,12 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
/* parse an initializer for type 't' if 'has_init' is non zero, and /* parse an initializer for type 't' if 'has_init' is non zero, and
allocate space in local or global data space ('r' is either allocate space in local or global data space ('r' is either
VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
variable 'v' with an associated name represented by 'asm_label' of variable 'v' of scope 'scope' is declared before initializers
scope 'scope' is declared before initializers are parsed. If 'v' is are parsed. If 'v' is zero, then a reference to the new object
zero, then a reference to the new object is put in the value stack. is put in the value stack. If 'has_init' is 2, a special parsing
If 'has_init' is 2, a special parsing is done to handle string is done to handle string constants. */
constants. */
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
int has_init, int v, char *asm_label, int has_init, int v, int scope)
int scope)
{ {
int size, align, addr, data_offset; int size, align, addr, data_offset;
int level; int level;
@ -5931,7 +5930,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
if (v) { if (v) {
if (scope != VT_CONST || !sym) { if (scope != VT_CONST || !sym) {
sym = sym_push(v, type, r | VT_SYM, 0); sym = sym_push(v, type, r | VT_SYM, 0);
sym->asm_label = asm_label ? tcc_strdup(asm_label) : 0; sym->asm_label = ad->asm_label;
} }
/* update symbol definition */ /* update symbol definition */
if (sec) { if (sec) {
@ -6162,7 +6161,6 @@ static int decl0(int l, int is_for_loop_init)
CType type, btype; CType type, btype;
Sym *sym; Sym *sym;
AttributeDef ad; AttributeDef ad;
char *asm_label = 0; // associated asm label
while (1) { while (1) {
if (!parse_btype(&btype, &ad)) { if (!parse_btype(&btype, &ad)) {
@ -6218,17 +6216,12 @@ static int decl0(int l, int is_for_loop_init)
func_decl_list(sym); func_decl_list(sym);
} }
tcc_free(asm_label);
asm_label = 0;
if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
CString astr; ad.asm_label = asm_label_instr();
asm_label_instr(&astr);
asm_label = tcc_strdup(astr.data);
cstr_free(&astr);
/* parse one last attribute list, after asm label */ /* parse one last attribute list, after asm label */
parse_attribute(&ad); parse_attribute(&ad);
if (tok == '{')
expect(";");
} }
if (ad.a.weak) if (ad.a.weak)
@ -6371,7 +6364,8 @@ static int decl0(int l, int is_for_loop_init)
/* NOTE: as GCC, uninitialized global static /* NOTE: as GCC, uninitialized global static
arrays of null size are considered as arrays of null size are considered as
extern */ extern */
sym = external_sym(v, &type, r, asm_label); sym = external_sym(v, &type, r);
sym->asm_label = ad.asm_label;
if (ad.alias_target) { if (ad.alias_target) {
Section tsec; Section tsec;
@ -6393,14 +6387,12 @@ static int decl0(int l, int is_for_loop_init)
r |= l; r |= l;
if (has_init) if (has_init)
next(); next();
decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l); decl_initializer_alloc(&type, &ad, r, has_init, v, l);
} }
} }
if (tok != ',') { if (tok != ',') {
if (is_for_loop_init) { if (is_for_loop_init)
tcc_free(asm_label);
return 1; return 1;
}
skip(';'); skip(';');
break; break;
} }
@ -6409,7 +6401,6 @@ static int decl0(int l, int is_for_loop_init)
ad.a.aligned = 0; ad.a.aligned = 0;
} }
} }
tcc_free(asm_label);
return 0; return 0;
} }

10
tccpp.c
View File

@ -334,10 +334,18 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
break; break;
case TOK_CFLOAT: case TOK_CFLOAT:
cstr_cat(&cstr_buf, "<float>");
break;
case TOK_CDOUBLE: case TOK_CDOUBLE:
cstr_cat(&cstr_buf, "<double>");
break;
case TOK_CLDOUBLE: case TOK_CLDOUBLE:
cstr_cat(&cstr_buf, "<long double>");
break;
case TOK_LINENUM: case TOK_LINENUM:
return NULL; /* should not happen */ cstr_cat(&cstr_buf, "<linenumber>");
break;
//return NULL; /* should not happen */
/* above tokens have value, the ones below don't */ /* above tokens have value, the ones below don't */