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
This commit is contained in:
parent
992cbda8d0
commit
54cf57ab1a
4 changed files with 42 additions and 42 deletions
2
libtcc.c
2
libtcc.c
|
@ -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
3
tcc.h
|
@ -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;
|
||||||
|
|
69
tccgen.c
69
tccgen.c
|
@ -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
10
tccpp.c
|
@ -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 */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue