[PATCH v3 3/5] as-name: use idents for address spaces

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux