Currently, address space are identified by an number and displayed as '<asn:%d>'. It would be more useful to display a name like the one used in the code: '__user', '__iomem', .... Prepare this by using an identifier instead of the AS number. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- evaluate.c | 43 +++++++++++++++++++++++-------------------- parse.c | 10 +++++++++- show-parse.c | 27 ++++++++++++--------------- symbol.c | 4 ++-- symbol.h | 24 ++++++++++++++++++++++-- 5 files changed, 68 insertions(+), 40 deletions(-) diff --git a/evaluate.c b/evaluate.c index 05ea76401..02eeaefb3 100644 --- a/evaluate.c +++ b/evaluate.c @@ -45,6 +45,8 @@ struct symbol *current_fn; +struct ident bad_address_space = { .len = 6, .name = "bad AS", }; + static struct symbol *degenerate(struct expression *expr); static struct symbol *evaluate_symbol(struct symbol *sym); @@ -208,14 +210,14 @@ static int same_cast_type(struct symbol *orig, struct symbol *new) orig->bit_offset == new->bit_offset; } -static struct symbol *base_type(struct symbol *node, unsigned long *modp, unsigned long *asp) +static struct symbol *base_type(struct symbol *node, unsigned long *modp, struct ident **asp) { - unsigned long mod, as; + unsigned long mod = 0; + struct ident *as = NULL; - mod = 0; as = 0; while (node) { mod |= node->ctype.modifiers; - as |= node->ctype.as; + combine_address_space(&as, node->ctype.as); if (node->type == SYM_NODE) { node = node->ctype.base_type; continue; @@ -230,7 +232,8 @@ static struct symbol *base_type(struct symbol *node, unsigned long *modp, unsign static int is_same_type(struct expression *expr, struct symbol *new) { struct symbol *old = expr->ctype; - unsigned long oldmod, newmod, oldas, newas; + unsigned long oldmod, newmod; + struct ident *oldas, *newas; old = base_type(old, &oldmod, &oldas); new = base_type(new, &newmod, &newas); @@ -660,7 +663,7 @@ static void examine_fn_arguments(struct symbol *fn); const char *type_difference(struct ctype *c1, struct ctype *c2, unsigned long mod1, unsigned long mod2) { - unsigned long as1 = c1->as, as2 = c2->as; + struct ident *as1 = c1->as, *as2 = c2->as; struct symbol *t1 = c1->base_type; struct symbol *t2 = c2->base_type; int move1 = 1, move2 = 1; @@ -678,7 +681,7 @@ const char *type_difference(struct ctype *c1, struct ctype *c2, if (move1) { if (t1 && t1->type != SYM_PTR) { mod1 |= t1->ctype.modifiers; - as1 |= t1->ctype.as; + combine_address_space(&as1, t1->ctype.as); } move1 = 0; } @@ -686,7 +689,7 @@ const char *type_difference(struct ctype *c1, struct ctype *c2, if (move2) { if (t2 && t2->type != SYM_PTR) { mod2 |= t2->ctype.modifiers; - as2 |= t2->ctype.as; + combine_address_space(&as2, t2->ctype.as); } move2 = 0; } @@ -1609,7 +1612,7 @@ static void examine_fn_arguments(struct symbol *fn) ptr->ctype = arg->ctype; else ptr->ctype.base_type = arg; - ptr->ctype.as |= s->ctype.as; + combine_address_space(&ptr->ctype.as, s->ctype.as); ptr->ctype.modifiers |= s->ctype.modifiers & MOD_PTRINHERIT; s->ctype.base_type = ptr; @@ -1627,7 +1630,7 @@ static void examine_fn_arguments(struct symbol *fn) } END_FOR_EACH_PTR(s); } -static struct symbol *convert_to_as_mod(struct symbol *sym, int as, int mod) +static struct symbol *convert_to_as_mod(struct symbol *sym, struct ident *as, int mod) { /* Take the modifiers of the pointer, and apply them to the member */ mod |= sym->ctype.modifiers; @@ -1659,12 +1662,12 @@ static struct symbol *create_pointer(struct expression *expr, struct symbol *sym sym->ctype.modifiers &= ~MOD_REGISTER; } if (sym->type == SYM_NODE) { - ptr->ctype.as |= sym->ctype.as; + combine_address_space(&ptr->ctype.as, sym->ctype.as); ptr->ctype.modifiers |= sym->ctype.modifiers & MOD_PTRINHERIT; sym = sym->ctype.base_type; } if (degenerate && sym->type == SYM_ARRAY) { - ptr->ctype.as |= sym->ctype.as; + combine_address_space(&ptr->ctype.as, sym->ctype.as); ptr->ctype.modifiers |= sym->ctype.modifiers & MOD_PTRINHERIT; sym = sym->ctype.base_type; } @@ -2051,8 +2054,8 @@ static struct symbol *evaluate_member_dereference(struct expression *expr) struct symbol *ctype, *member; struct expression *deref = expr->deref, *add; struct ident *ident = expr->member; + struct ident *address_space; unsigned int mod; - int address_space; if (!evaluate_expression(deref)) return NULL; @@ -2067,7 +2070,7 @@ static struct symbol *evaluate_member_dereference(struct expression *expr) mod = ctype->ctype.modifiers; if (ctype->type == SYM_NODE) { ctype = ctype->ctype.base_type; - address_space |= ctype->ctype.as; + combine_address_space(&address_space, ctype->ctype.as); mod |= ctype->ctype.modifiers; } if (!ctype || (ctype->type != SYM_STRUCT && ctype->type != SYM_UNION)) { @@ -2913,7 +2916,7 @@ static struct symbol *evaluate_cast(struct expression *expr) struct symbol *ctype; struct symbol *ttype, *stype; int tclass, sclass; - int tas = 0, sas = 0; + struct ident *tas = NULL, *sas = NULL; if (!source) return NULL; @@ -3004,24 +3007,24 @@ static struct symbol *evaluate_cast(struct expression *expr) } if (ttype == &ulong_ctype && !Wcast_from_as) - tas = -1; + tas = &bad_address_space; else if (tclass == TYPE_PTR) { examine_pointer_target(ttype); tas = ttype->ctype.as; } if (stype == &ulong_ctype && !Wcast_from_as) - sas = -1; + sas = &bad_address_space; else if (sclass == TYPE_PTR) { examine_pointer_target(stype); sas = stype->ctype.as; } - if (!tas && sas > 0) + if (!tas && valid_as(sas)) warning(expr->pos, "cast removes address space '%s' of expression", show_as(sas)); - if (tas > 0 && sas > 0 && tas != sas) + if (valid_as(tas) && valid_as(sas) && tas != sas) warning(expr->pos, "cast between address spaces (%s -> %s)", show_as(sas), show_as(tas)); - if (tas > 0 && !sas && + if (valid_as(tas) && !sas && !is_null_pointer_constant(source) && Wcast_to_as) warning(expr->pos, "cast adds address space '%s' to expression", show_as(tas)); diff --git a/parse.c b/parse.c index da912acab..af60549f5 100644 --- a/parse.c +++ b/parse.c @@ -1094,6 +1094,14 @@ static struct token *attribute_bitwise(struct token *token, struct symbol *attr, return token; } +static struct ident *numerical_address_space(int asn) +{ + char buff[32]; + + sprintf(buff, "<asn:%d>", asn); + return built_in_ident(buff); +} + static struct token *attribute_address_space(struct token *token, struct symbol *attr, struct decl_state *ctx) { struct expression *expr = NULL; @@ -1103,7 +1111,7 @@ static struct token *attribute_address_space(struct token *token, struct symbol if (expr) { as = const_expression_value(expr); if (Waddress_space && as) - ctx->ctype.as = as; + ctx->ctype.as = numerical_address_space(as); } token = expect(token, ')', "after address_space attribute"); return token; diff --git a/show-parse.c b/show-parse.c index ae098c285..0a980a5a5 100644 --- a/show-parse.c +++ b/show-parse.c @@ -72,10 +72,11 @@ static void do_debug_symbol(struct symbol *sym, int indent) if (!sym) return; - fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %d) %p (%s:%d:%d) %s\n", + fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %s) %p (%s:%d:%d) %s\n", indent, indent_string, typestr[sym->type], sym->bit_size, sym->ctype.alignment, - modifier_string(sym->ctype.modifiers), show_ident(sym->ident), sym->ctype.as, + modifier_string(sym->ctype.modifiers), show_ident(sym->ident), + show_as(sym->ctype.as), sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos, builtin_typename(sym) ?: ""); i = 0; @@ -182,15 +183,11 @@ void show_symbol_list(struct symbol_list *list, const char *sep) } END_FOR_EACH_PTR(sym); } -const char *show_as(unsigned int as) +const char *show_as(struct ident *as) { - static char buffer[4][32]; - static int n; - char *buff; - - buff = buffer[3 & ++n]; - sprintf(buff, "<asn:%u>", as); - return buff; + if (!as) + return ""; + return show_ident(as); } struct type_name { @@ -287,7 +284,7 @@ static void do_show_type(struct symbol *sym, struct type_name *name) { const char *typename; unsigned long mod = 0; - int as = 0; + struct ident *as = NULL; int was_ptr = 0; int restr = 0; int fouled = 0; @@ -306,7 +303,7 @@ deeper: name->start -= len; memcpy(name->start, s, len); mod = 0; - as = 0; + as = NULL; } if (!sym) @@ -358,12 +355,12 @@ deeper: case SYM_NODE: append(name, "%s", show_ident(sym->ident)); mod |= sym->ctype.modifiers; - as |= sym->ctype.as; + combine_address_space(&as, sym->ctype.as); break; case SYM_BITFIELD: mod |= sym->ctype.modifiers; - as |= sym->ctype.as; + combine_address_space(&as, sym->ctype.as); append(name, ":%d", sym->bit_size); break; @@ -373,7 +370,7 @@ deeper: case SYM_ARRAY: mod |= sym->ctype.modifiers; - as |= sym->ctype.as; + combine_address_space(&as, sym->ctype.as); if (was_ptr) { prepend(name, "( "); append(name, " )"); diff --git a/symbol.c b/symbol.c index 2dcabe85b..a30212237 100644 --- a/symbol.c +++ b/symbol.c @@ -214,7 +214,7 @@ static struct symbol *examine_base_type(struct symbol *sym) base_type = examine_symbol_type(sym->ctype.base_type); if (!base_type || base_type->type == SYM_PTR) return base_type; - sym->ctype.as |= base_type->ctype.as; + combine_address_space(&sym->ctype.as, base_type->ctype.as); sym->ctype.modifiers |= base_type->ctype.modifiers & MOD_PTRINHERIT; concat_ptr_list((struct ptr_list *)base_type->ctype.contexts, (struct ptr_list **)&sym->ctype.contexts); @@ -278,7 +278,7 @@ static struct symbol *examine_bitfield_type(struct symbol *sym) */ void merge_type(struct symbol *sym, struct symbol *base_type) { - sym->ctype.as |= base_type->ctype.as; + combine_address_space(&sym->ctype.as, base_type->ctype.as); sym->ctype.modifiers |= (base_type->ctype.modifiers & ~MOD_STORAGE); concat_ptr_list((struct ptr_list *)base_type->ctype.contexts, (struct ptr_list **)&sym->ctype.contexts); diff --git a/symbol.h b/symbol.h index b8e0cac82..35e932d93 100644 --- a/symbol.h +++ b/symbol.h @@ -101,7 +101,7 @@ struct ctype { unsigned long modifiers; unsigned long alignment; struct context_list *contexts; - unsigned int as; + struct ident *as; struct symbol *base_type; }; @@ -315,7 +315,7 @@ extern void bind_symbol(struct symbol *, struct ident *, enum namespace); extern struct symbol *examine_symbol_type(struct symbol *); extern struct symbol *examine_pointer_target(struct symbol *); -extern const char *show_as(unsigned int as); +extern const char *show_as(struct ident *as); extern const char *show_typename(struct symbol *sym); extern const char *builtin_typename(struct symbol *sym); extern const char *builtin_ctypename(struct ctype *ctype); @@ -500,4 +500,24 @@ static inline struct symbol *lookup_keyword(struct ident *ident, enum namespace void create_fouled(struct symbol *type); struct symbol *befoul(struct symbol *type); + +extern struct ident bad_address_space; + +static inline bool valid_as(struct ident *as) +{ + return as && as != &bad_address_space; +} + +static inline void combine_address_space(struct ident **tas, struct ident *sas) +{ + struct ident *as; + if (!sas) + return; + as = *tas; + if (!as) + *tas = sas; + else if (as != sas) + *tas = &bad_address_space; +} + #endif /* SYMBOL_H */ -- 2.19.0