[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-sparse
Subject:    [PATCH 1/2] Introduce the attribute structure.
From:       Christopher Li <sparse () chrisli ! org>
Date:       2013-02-27 15:18:00
Message-ID: CANeU7Qkq7DHCw1cJKy5AyscceVpRH-hqukMPXzd9e0TRazb18A () mail ! gmail ! com
[Download RAW message or body]

This duplicate the ctype->as and ctype->contexts into a
separate attribute structure. It also active check ans verify
the duplicated attribute bits are consistent.

Chris

["0001-Introduce-struct-attribute-into-ctype.patch" (application/octet-stream)]

From 7d662486879f8c954be8a1c2b85f3284483d583e Mon Sep 17 00:00:00 2001
From: Christopher Li <sparse@chrisli.org>
Date: Fri, 22 Feb 2013 00:25:45 -0800
Subject: [PATCH 1/2] Introduce struct attribute into ctype

The idea is that attirbute related storage
will move to attribute structure. The first step
is duplicate ctype.as and ctype.contexts into
attribute structure. It checks the attribute structure
is consistent with the ctype member.

Signed-off-by: Christopher Li <sparse@chrisli.org>
---
 allocate.c   |  1 +
 allocate.h   |  1 +
 evaluate.c   | 64 ++++++++++++++++++++++++++++++++++++-----------------
 expand.c     |  4 ++--
 lib.h        |  6 +++++
 linearize.c  |  3 ++-
 parse.c      | 27 ++++++++++-------------
 show-parse.c | 15 ++++++++-----
 sparse.c     |  3 ++-
 symbol.c     | 18 ++++++++++-----
 symbol.h     | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 11 files changed, 162 insertions(+), 52 deletions(-)

diff --git a/allocate.c b/allocate.c
index 5cc52a9..dbd3adc 100644
--- a/allocate.c
+++ b/allocate.c
@@ -125,5 +125,6 @@ ALLOCATOR(entrypoint, "entrypoint");
 ALLOCATOR(instruction, "instruction");
 ALLOCATOR(multijmp, "multijmp");
 ALLOCATOR(pseudo, "pseudo");
+ALLOCATOR(attribute, "attribute");
 
 
diff --git a/allocate.h b/allocate.h
index 9f1dc8c..5af2bac 100644
--- a/allocate.h
+++ b/allocate.h
@@ -77,5 +77,6 @@ DECLARE_ALLOCATOR(instruction);
 DECLARE_ALLOCATOR(multijmp);
 DECLARE_ALLOCATOR(phi);
 DECLARE_ALLOCATOR(pseudo);
+DECLARE_ALLOCATOR(attribute);
 
 #endif
diff --git a/evaluate.c b/evaluate.c
index cd053f7..3e087e6 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -185,7 +185,8 @@ static struct symbol *base_type(struct symbol *node, unsigned long *modp, unsign
 	mod = 0; as = 0;
 	while (node) {
 		mod |= node->ctype.modifiers;
-		as |= node->ctype.as;
+		check_sym(node);
+		as |= node->ctype.attribute->as;
 		if (node->type == SYM_NODE) {
 			node = node->ctype.base_type;
 			continue;
@@ -611,17 +612,22 @@ 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;
+	unsigned long as1 = c1->attribute->as, as2 = c2->attribute->as;
 	struct symbol *t1 = c1->base_type;
 	struct symbol *t2 = c2->base_type;
 	int move1 = 1, move2 = 1;
 	mod1 |= c1->modifiers;
 	mod2 |= c2->modifiers;
+	check_attr(c1);
+	check_attr(c2);
+
 	for (;;) {
 		unsigned long diff;
 		int type;
 		struct symbol *base1 = t1->ctype.base_type;
 		struct symbol *base2 = t2->ctype.base_type;
+		check_sym(t1);
+		check_sym(t2);
 
 		/*
 		 * FIXME! Collect alignment and context too here!
@@ -629,7 +635,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;
+				as1 |= t1->ctype.attribute->as;
 			}
 			move1 = 0;
 		}
@@ -637,7 +643,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;
+				as2 |= t2->ctype.attribute->as;
 			}
 			move2 = 0;
 		}
@@ -695,9 +701,11 @@ const char *type_difference(struct ctype *c1, struct ctype *c2,
 			base1 = examine_pointer_target(t1);
 			base2 = examine_pointer_target(t2);
 			mod1 = t1->ctype.modifiers;
-			as1 = t1->ctype.as;
+			as1 = t1->ctype.attribute->as;
 			mod2 = t2->ctype.modifiers;
-			as2 = t2->ctype.as;
+			as2 = t2->ctype.attribute->as;
+			check_sym(t1);
+			check_sym(t2);
 			break;
 		case SYM_FN: {
 			struct symbol *arg1, *arg2;
@@ -708,9 +716,11 @@ const char *type_difference(struct ctype *c1, struct ctype *c2,
 			if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SIGNEDNESS)
 				return "different modifiers";
 			mod1 = t1->ctype.modifiers;
-			as1 = t1->ctype.as;
+			as1 = t1->ctype.attribute->as;
 			mod2 = t2->ctype.modifiers;
-			as2 = t2->ctype.as;
+			as2 = t2->ctype.attribute->as;
+			check_sym(t1);
+			check_sym(t2);
 
 			if (base1->variadic != base2->variadic)
 				return "incompatible variadic arguments";
@@ -1042,7 +1052,9 @@ static struct symbol *evaluate_compare(struct expression *expr)
 
 	/* they also have special treatment for pointers to void */
 	if (expr->op == SPECIAL_EQUAL || expr->op == SPECIAL_NOTEQUAL) {
-		if (ltype->ctype.as == rtype->ctype.as) {
+		check_sym(ltype);
+		check_sym(rtype);
+		if (ltype->ctype.attribute->as == rtype->ctype.attribute->as) {
 			if (lbase == &void_ctype) {
 				right = cast_to(right, ltype);
 				goto OK;
@@ -1146,7 +1158,9 @@ static struct symbol *evaluate_conditional_expression(struct expression *expr)
 			goto Err;
 		}
 		/* OK, it's pointer on pointer */
-		if (ltype->ctype.as != rtype->ctype.as) {
+		check_sym(ltype);
+		check_sym(rtype);
+		if (ltype->ctype.attribute->as != rtype->ctype.attribute->as) {
 			typediff = "different address spaces";
 			goto Err;
 		}
@@ -1336,7 +1350,9 @@ static int compatible_assignment_types(struct expression *expr, struct symbol *t
 			 * we do not remove qualifiers from pointed to [C]
 			 * or mix address spaces [sparse].
 			 */
-			if (t->ctype.as != s->ctype.as) {
+			check_sym(t);
+			check_sym(s);
+			if (t->ctype.attribute->as != s->ctype.attribute->as) {
 				typediff = "different address spaces";
 				goto Err;
 			}
@@ -1462,11 +1478,13 @@ static void examine_fn_arguments(struct symbol *fn)
 					ptr->ctype = arg->ctype;
 				else
 					ptr->ctype.base_type = arg;
-				ptr->ctype.as |= s->ctype.as;
+				check_sym(s);
+				merge_attr(&ptr->ctype, &s->ctype);
 				ptr->ctype.modifiers |= s->ctype.modifiers & MOD_PTRINHERIT;
 
 				s->ctype.base_type = ptr;
 				s->ctype.as = 0;
+				s->ctype.attribute = &null_attr;
 				s->ctype.modifiers &= ~MOD_PTRINHERIT;
 				s->bit_size = 0;
 				s->examined = 0;
@@ -1484,10 +1502,11 @@ static struct symbol *convert_to_as_mod(struct symbol *sym, int as, int mod)
 {
 	/* Take the modifiers of the pointer, and apply them to the member */
 	mod |= sym->ctype.modifiers;
-	if (sym->ctype.as != as || sym->ctype.modifiers != mod) {
+	check_sym(sym);
+	if (sym->ctype.attribute->as != as || sym->ctype.modifiers != mod) {
 		struct symbol *newsym = alloc_symbol(sym->pos, SYM_NODE);
 		*newsym = *sym;
-		newsym->ctype.as = as;
+		attr_set_as(&newsym->ctype, as);
 		newsym->ctype.modifiers = mod;
 		sym = newsym;
 	}
@@ -1507,17 +1526,18 @@ static struct symbol *create_pointer(struct expression *expr, struct symbol *sym
 	node->ctype.alignment = pointer_alignment;
 
 	access_symbol(sym);
+	check_sym(sym);
 	if (sym->ctype.modifiers & MOD_REGISTER) {
 		warning(expr->pos, "taking address of 'register' variable '%s'", show_ident(sym->ident));
 		sym->ctype.modifiers &= ~MOD_REGISTER;
 	}
 	if (sym->type == SYM_NODE) {
-		ptr->ctype.as |= sym->ctype.as;
+		merge_attr(&ptr->ctype, &sym->ctype);
 		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;
+		merge_attr(&ptr->ctype, &sym->ctype);
 		ptr->ctype.modifiers |= sym->ctype.modifiers & MOD_PTRINHERIT;
 		sym = sym->ctype.base_type;
 	}
@@ -1896,11 +1916,13 @@ static struct symbol *evaluate_member_dereference(struct expression *expr)
 
 	ctype = deref->ctype;
 	examine_symbol_type(ctype);
-	address_space = ctype->ctype.as;
+	check_sym(ctype);
+	address_space = ctype->ctype.attribute->as;
 	mod = ctype->ctype.modifiers;
 	if (ctype->type == SYM_NODE) {
 		ctype = ctype->ctype.base_type;
-		address_space |= ctype->ctype.as;
+		check_sym(ctype);
+		address_space |= ctype->ctype.attribute->as;
 		mod |= ctype->ctype.modifiers;
 	}
 	if (!ctype || (ctype->type != SYM_STRUCT && ctype->type != SYM_UNION)) {
@@ -2706,14 +2728,16 @@ static struct symbol *evaluate_cast(struct expression *expr)
 		as1 = -1;
 	else if (class1 == TYPE_PTR) {
 		examine_pointer_target(t1);
-		as1 = t1->ctype.as;
+		check_sym(t1);
+		as1 = t1->ctype.attribute->as;
 	}
 
 	if (t2 == &ulong_ctype)
 		as2 = -1;
 	else if (class2 == TYPE_PTR) {
 		examine_pointer_target(t2);
-		as2 = t2->ctype.as;
+		check_sym(t2);
+		as2 = t2->ctype.attribute->as;
 	}
 
 	if (!as1 && as2 > 0)
diff --git a/expand.c b/expand.c
index 63a9075..b6cf837 100644
--- a/expand.c
+++ b/expand.c
@@ -461,8 +461,8 @@ static int expand_comma(struct expression *expr)
 
 static int compare_types(int op, struct symbol *left, struct symbol *right)
 {
-	struct ctype c1 = {.base_type = left};
-	struct ctype c2 = {.base_type = right};
+	struct ctype c1 = {.base_type = left, .attribute = &null_attr};
+	struct ctype c2 = {.base_type = right, .attribute = &null_attr};
 	switch (op) {
 	case SPECIAL_EQUAL:
 		return !type_difference(&c1, &c2, MOD_IGN, MOD_IGN);
diff --git a/lib.h b/lib.h
index ee954fe..802719b 100644
--- a/lib.h
+++ b/lib.h
@@ -57,6 +57,7 @@ DECLARE_PTR_LIST(statement_list, struct statement);
 DECLARE_PTR_LIST(expression_list, struct expression);
 DECLARE_PTR_LIST(basic_block_list, struct basic_block);
 DECLARE_PTR_LIST(instruction_list, struct instruction);
+DECLARE_PTR_LIST(context_list, struct context);
 DECLARE_PTR_LIST(multijmp_list, struct multijmp);
 DECLARE_PTR_LIST(pseudo_list, struct pseudo);
 DECLARE_PTR_LIST(string_list, char);
@@ -128,6 +129,11 @@ static inline int statement_list_size(struct statement_list *list)
 	return ptr_list_size((struct ptr_list *)(list));
 }
 
+static inline int context_list_size(struct context_list *list)
+{
+	return ptr_list_size((struct ptr_list *)(list));
+}
+
 static inline int expression_list_size(struct expression_list *list)
 {
 	return ptr_list_size((struct ptr_list *)(list));
diff --git a/linearize.c b/linearize.c
index 1d15cfd..42df529 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1240,7 +1240,8 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
 	add_one_insn(ep, insn);
 
 	if (ctype) {
-		FOR_EACH_PTR(ctype->contexts, context) {
+		check_attr(ctype);
+		FOR_EACH_PTR(ctype->attribute->contexts, context) {
 			int in = context->in;
 			int out = context->out;
 			int check = 0;
diff --git a/parse.c b/parse.c
index 9ec51fb..ffd6ad8 100644
--- a/parse.c
+++ b/parse.c
@@ -1064,7 +1064,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;
+			attr_set_as(&ctx->ctype, as);
 	}
 	token = expect(token, ')', "after address_space attribute");
 	return token;
@@ -1174,7 +1174,7 @@ static struct token *attribute_context(struct token *token, struct symbol *attr,
 	}
 
 	if (argc)
-		add_ptr_list(&ctx->ctype.contexts, context);
+		attr_add_context(&ctx->ctype, context);
 
 	token = expect(token, ')', "after context attribute");
 	return token;
@@ -1356,17 +1356,13 @@ static void apply_ctype(struct position pos, struct ctype *thistype, struct ctyp
 	if (mod)
 		apply_qualifier(&pos, ctype, mod);
 
-	/* Context */
-	concat_ptr_list((struct ptr_list *)thistype->contexts,
-	                (struct ptr_list **)&ctype->contexts);
-
 	/* Alignment */
 	if (thistype->alignment > ctype->alignment)
 		ctype->alignment = thistype->alignment;
 
-	/* Address space */
-	if (thistype->as)
-		ctype->as = thistype->as;
+	/* Attribute */
+	check_attr(thistype);
+	merge_attr(ctype, thistype);
 }
 
 static void specifier_conflict(struct position pos, int what, struct ident *new)
@@ -1715,11 +1711,12 @@ static struct token *pointer(struct token *token, struct decl_state *ctx)
 		struct symbol *ptr = alloc_symbol(token->pos, SYM_PTR);
 		ptr->ctype.modifiers = ctx->ctype.modifiers;
 		ptr->ctype.base_type = ctx->ctype.base_type;
-		ptr->ctype.as = ctx->ctype.as;
-		ptr->ctype.contexts = ctx->ctype.contexts;
+		check_attr(&ctx->ctype);
+		merge_attr(&ptr->ctype, &ctx->ctype);
 		ctx->ctype.modifiers = 0;
 		ctx->ctype.base_type = ptr;
 		ctx->ctype.as = 0;
+		ctx->ctype.attribute = &null_attr;
 		ctx->ctype.contexts = NULL;
 		ctx->ctype.alignment = 0;
 
@@ -1785,7 +1782,7 @@ static struct token *handle_bitfield(struct token *token, struct decl_state *ctx
 
 static struct token *declaration_list(struct token *token, struct symbol_list **list)
 {
-	struct decl_state ctx = {.prefer_abstract = 0};
+	struct decl_state ctx = {.prefer_abstract = 0, .ctype.attribute = &null_attr};
 	struct ctype saved;
 	unsigned long mod;
 
@@ -1831,7 +1828,7 @@ static struct token *struct_declaration_list(struct token *token, struct symbol_
 
 static struct token *parameter_declaration(struct token *token, struct symbol *sym)
 {
-	struct decl_state ctx = {.prefer_abstract = 1};
+	struct decl_state ctx = {.prefer_abstract = 1, .ctype.attribute = &null_attr};
 
 	token = declaration_specifiers(token, &ctx);
 	ctx.ident = &sym->ident;
@@ -1846,7 +1843,7 @@ static struct token *parameter_declaration(struct token *token, struct symbol *s
 
 struct token *typename(struct token *token, struct symbol **p, int *forced)
 {
-	struct decl_state ctx = {.prefer_abstract = 1};
+	struct decl_state ctx = {.prefer_abstract = 1, .ctype.attribute = &null_attr};
 	int class;
 	struct symbol *sym = alloc_symbol(token->pos, SYM_NODE);
 	*p = sym;
@@ -2675,7 +2672,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 {
 	struct ident *ident = NULL;
 	struct symbol *decl;
-	struct decl_state ctx = { .ident = &ident };
+	struct decl_state ctx = { .ident = &ident, .ctype.attribute = &null_attr};
 	struct ctype saved;
 	struct symbol *base_type;
 	unsigned long mod;
diff --git a/show-parse.c b/show-parse.c
index 1333e30..ca6232d 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -56,14 +56,16 @@ static void do_debug_symbol(struct symbol *sym, int indent)
 
 	if (!sym)
 		return;
+	check_sym(sym);
 	fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %d) %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), sym->ctype.attribute->as,
 		sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos,
 		builtin_typename(sym) ?: "");
 	i = 0;
-	FOR_EACH_PTR(sym->ctype.contexts, context) {
+	check_sym(sym);
+	FOR_EACH_PTR(sym->ctype.attribute->contexts, context) {
 		/* FIXME: should print context expression */
 		fprintf(stderr, "< context%d: in=%d, out=%d\n",
 			i, context->in, context->out);
@@ -294,12 +296,13 @@ deeper:
 		goto out;
 	}
 
+	check_sym(sym);
 	/* Prepend */
 	switch (sym->type) {
 	case SYM_PTR:
 		prepend(name, "*");
 		mod = sym->ctype.modifiers;
-		as = sym->ctype.as;
+		as = sym->ctype.attribute->as;
 		was_ptr = 1;
 		break;
 
@@ -331,12 +334,12 @@ deeper:
 	case SYM_NODE:
 		append(name, "%s", show_ident(sym->ident));
 		mod |= sym->ctype.modifiers;
-		as |= sym->ctype.as;
+		as |= sym->ctype.attribute->as;
 		break;
 
 	case SYM_BITFIELD:
 		mod |= sym->ctype.modifiers;
-		as |= sym->ctype.as;
+		as |= sym->ctype.attribute->as;
 		append(name, ":%d", sym->bit_size);
 		break;
 
@@ -346,7 +349,7 @@ deeper:
 
 	case SYM_ARRAY:
 		mod |= sym->ctype.modifiers;
-		as |= sym->ctype.as;
+		as |= sym->ctype.attribute->as;
 		if (was_ptr) {
 			prepend(name, "( ");
 			append(name, " )");
diff --git a/sparse.c b/sparse.c
index 67b7d9e..fad16ad 100644
--- a/sparse.c
+++ b/sparse.c
@@ -248,7 +248,8 @@ static void check_context(struct entrypoint *ep)
 
 	check_instructions(ep);
 
-	FOR_EACH_PTR(sym->ctype.contexts, context) {
+	check_sym(sym);
+	FOR_EACH_PTR(sym->ctype.attribute->contexts, context) {
 		in_context += context->in;
 		out_context += context->out;
 	} END_FOR_EACH_PTR(context);
diff --git a/symbol.c b/symbol.c
index 86aef1c..67cdfab 100644
--- a/symbol.c
+++ b/symbol.c
@@ -63,6 +63,7 @@ struct symbol *alloc_symbol(struct position pos, int type)
 	sym->type = type;
 	sym->pos = pos;
 	sym->endpos.type = 0;
+	sym->ctype.attribute = &null_attr;
 	return sym;
 }
 
@@ -197,10 +198,10 @@ 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;
 	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);
+
+	merge_attr(&sym->ctype, &base_type->ctype);
+
 	if (base_type->type == SYM_NODE) {
 		base_type = base_type->ctype.base_type;
 		sym->ctype.base_type = base_type;
@@ -253,10 +254,8 @@ 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;
 	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);
+	merge_attr(&sym->ctype, &base_type->ctype);
 	sym->ctype.base_type = base_type->ctype.base_type;
 	if (sym->ctype.base_type->type == SYM_NODE)
 		merge_type(sym, sym->ctype.base_type);
@@ -732,6 +731,10 @@ static struct sym_init {
 	{ NULL,		NULL,		0 }
 };
 
+/*
+ * Default empty attribute
+ */
+struct attribute null_attr = {};
 
 /*
  * Abstract types
@@ -775,11 +778,13 @@ void init_symbols(void)
 	init_parser(stream);
 
 	builtin_fn_type.variadic = 1;
+	builtin_fn_type.ctype.attribute = &null_attr;
 	for (ptr = eval_init_table; ptr->name; ptr++) {
 		struct symbol *sym;
 		sym = create_symbol(stream, ptr->name, SYM_NODE, NS_SYMBOL);
 		sym->ctype.base_type = ptr->base_type;
 		sym->ctype.modifiers = ptr->modifiers;
+		sym->ctype.attribute = &null_attr;
 		sym->op = ptr->op;
 	}
 }
@@ -852,5 +857,6 @@ void init_ctype(void)
 		sym->ctype.alignment = alignment;
 		sym->ctype.base_type = ctype->base_type;
 		sym->ctype.modifiers = ctype->modifiers;
+		sym->ctype.attribute = &null_attr;
 	}
 }
diff --git a/symbol.h b/symbol.h
index 1e74579..192a957 100644
--- a/symbol.h
+++ b/symbol.h
@@ -11,6 +11,7 @@
 
 #include "token.h"
 #include "target.h"
+#include "allocate.h"
 
 /*
  * An identifier with semantic meaning is a "symbol".
@@ -79,11 +80,16 @@ struct context {
 
 extern struct context *alloc_context(void);
 
-DECLARE_PTR_LIST(context_list, struct context);
+struct attribute {
+	struct context_list *contexts;
+	unsigned int as;
+};
+
 
 struct ctype {
 	unsigned long modifiers;
 	unsigned long alignment;
+	struct attribute *attribute;
 	struct context_list *contexts;
 	unsigned int as;
 	struct symbol *base_type;
@@ -231,6 +237,8 @@ struct symbol {
 	MOD_ASSIGNED | MOD_USERTYPE | MOD_ACCESSED | MOD_EXPLICITLY_SIGNED)
 #define MOD_PTRINHERIT (MOD_VOLATILE | MOD_CONST | MOD_NODEREF | MOD_STORAGE | MOD_NORETURN)
 
+/* default empty attribute */
+extern struct attribute null_attr;
 
 /* Current parsing/evaluation function */
 extern struct symbol *current_fn;
@@ -382,6 +390,68 @@ static inline struct symbol *lookup_keyword(struct ident *ident, enum namespace
 	return lookup_symbol(ident, ns);
 }
 
+static inline struct attribute *duplicate_attribute(struct attribute *attr)
+{
+		struct attribute *newattr = __alloc_attribute(0);
+		*newattr = *attr;
+		return newattr;
+}
+
+static inline void attr_set_as(struct ctype *ctype, unsigned int as)
+{
+	ctype->as = as;
+	if (ctype->attribute->as != as) {
+		ctype->attribute = duplicate_attribute(ctype->attribute);
+		ctype->attribute->as = as;
+	}
+}
+
+static inline void attr_add_context(struct ctype *ctype, struct context *context)
+{
+	add_ptr_list(&ctype->contexts, context);
+	ctype->attribute = duplicate_attribute(ctype->attribute);
+	add_ptr_list(&ctype->attribute->contexts, context);
+}
+
+/*
+ * Check the ctype.as is consistent with the ctype.attribute.
+ * This function will get removed with ctype.as eventually.
+ */
+static inline void check_attr(struct ctype *ctype)
+{
+	if (!ctype->attribute)
+		die("Empty attribute of %p\n", ctype);
+	if (ctype->as != ctype->attribute->as)
+		die("Attribute as difference %d %d\n", ctype->as, ctype->attribute->as);
+	if (context_list_size(ctype->contexts) != context_list_size(ctype->attribute->contexts))
+		die("Attribute context has different size \n");
+}
+
+static inline void check_sym(struct symbol *sym)
+{
+	check_attr(&sym->ctype);
+}
+
+static inline void merge_attr(struct ctype *dst, struct ctype *src)
+{
+	struct attribute *attr;
+	dst->as |= src->as;
+	concat_ptr_list((struct ptr_list *)src->contexts,
+			(struct ptr_list **)&dst->contexts);
+
+	if (src->attribute == &null_attr)
+		return;
+	if (dst->attribute == &null_attr) {
+		dst->attribute  = src->attribute;
+		return;
+	}
+	
+	dst->attribute = attr = duplicate_attribute(dst->attribute);
+	attr->as |= src->attribute->as;
+	concat_ptr_list((struct ptr_list *)src->attribute->contexts,
+			(struct ptr_list **)&attr->contexts);
+}
+
 #define is_restricted_type(type) (get_sym_type(type) == SYM_RESTRICT)
 #define is_fouled_type(type) (get_sym_type(type) == SYM_FOULED)
 #define is_bitfield_type(type)   (get_sym_type(type) == SYM_BITFIELD)
-- 
1.8.1.2


--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic