aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2011-06-22 09:52:55 +0000
committerNicola Pero <nicola@gcc.gnu.org>2011-06-22 09:52:55 +0000
commit70e41a6a27a6aad0abbe5598497b4b17ef3feb48 (patch)
treeeb06d313c03be1290b9c63500235d5b1ba88492d /gcc/tree.c
parent637c11bd1659581b3bd137b8e479301cbd6ff2b3 (diff)
downloadgcc-70e41a6a27a6aad0abbe5598497b4b17ef3feb48.zip
gcc-70e41a6a27a6aad0abbe5598497b4b17ef3feb48.tar.gz
gcc-70e41a6a27a6aad0abbe5598497b4b17ef3feb48.tar.bz2
In gcc/: 2011-06-21 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/: 2011-06-21 Nicola Pero <nicola.pero@meta-innovation.com> * attribs.c (register_attribute): Added assert to check that all attribute specs are registered with a name that is not empty and does not start with '_'. (decl_attributes): Avoid the lookup of the "naked" attribute spec if the function has no attributes. * tree.c (is_attribute_with_length_p): Removed. (is_attribute_p): Removed. (private_is_attribute_p): New. (private_lookup_attribute): New. (lookup_attribute): Removed. (lookup_ident_attribute): New. (remove_attribute): Require the first argument to be in the form 'text', not '__text__'. Updated asserts. (merge_attributes): Use lookup_ident_attributes instead of lookup_attribute. (merge_dllimport_decl_attributes): Use remove_attribute. (attribute_list_contained): Likewise. (attribute_list_equal): Immediately return 1 if the arguments are identical pointers. * tree.h (is_attribute_p): Made inline. Return a 'bool', not an 'int'. Require the first argument to be in the form 'text', not '__text__'. Require the second argument to be an identifier. (lookup_attribute): Made inline. Require the first argument to be in the form 'text', not '__text__'. (private_is_attribute_p, private_lookup_attribute): New. Updated comments. From-SVN: r175286
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c192
1 files changed, 107 insertions, 85 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 73126cf..d984ece 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5218,82 +5218,119 @@ struct simple_ipa_opt_pass pass_ipa_free_lang_data =
}
};
-/* Return nonzero if IDENT is a valid name for attribute ATTR,
- or zero if not.
-
- We try both `text' and `__text__', ATTR may be either one. */
-/* ??? It might be a reasonable simplification to require ATTR to be only
- `text'. One might then also require attribute lists to be stored in
- their canonicalized form. */
-
-static int
-is_attribute_with_length_p (const char *attr, int attr_len, const_tree ident)
+/* The backbone of is_attribute_p(). ATTR_LEN is the string length of
+ ATTR_NAME. Also used internally by remove_attribute(). */
+bool
+private_is_attribute_p (const char *attr_name, size_t attr_len, const_tree ident)
{
- int ident_len;
- const char *p;
+ size_t ident_len = IDENTIFIER_LENGTH (ident);
- if (TREE_CODE (ident) != IDENTIFIER_NODE)
- return 0;
-
- p = IDENTIFIER_POINTER (ident);
- ident_len = IDENTIFIER_LENGTH (ident);
-
- if (ident_len == attr_len
- && strcmp (attr, p) == 0)
- return 1;
-
- /* If ATTR is `__text__', IDENT must be `text'; and vice versa. */
- if (attr[0] == '_')
+ if (ident_len == attr_len)
{
- gcc_assert (attr[1] == '_');
- gcc_assert (attr[attr_len - 2] == '_');
- gcc_assert (attr[attr_len - 1] == '_');
- if (ident_len == attr_len - 4
- && strncmp (attr + 2, p, attr_len - 4) == 0)
- return 1;
+ if (strcmp (attr_name, IDENTIFIER_POINTER (ident)) == 0)
+ return true;
}
- else
+ else if (ident_len == attr_len + 4)
{
- if (ident_len == attr_len + 4
- && p[0] == '_' && p[1] == '_'
+ /* There is the possibility that ATTR is 'text' and IDENT is
+ '__text__'. */
+ const char *p = IDENTIFIER_POINTER (ident);
+ if (p[0] == '_' && p[1] == '_'
&& p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
- && strncmp (attr, p + 2, attr_len) == 0)
- return 1;
+ && strncmp (attr_name, p + 2, attr_len) == 0)
+ return true;
}
- return 0;
+ return false;
}
-/* Return nonzero if IDENT is a valid name for attribute ATTR,
- or zero if not.
+/* The backbone of lookup_attribute(). ATTR_LEN is the string length
+ of ATTR_NAME, and LIST is not NULL_TREE. */
+tree
+private_lookup_attribute (const char *attr_name, size_t attr_len, tree list)
+{
+ while (list)
+ {
+ size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list));
- We try both `text' and `__text__', ATTR may be either one. */
+ if (ident_len == attr_len)
+ {
+ if (strcmp (attr_name, IDENTIFIER_POINTER (TREE_PURPOSE (list))) == 0)
+ break;
+ }
+ /* TODO: If we made sure that attributes were stored in the
+ canonical form without '__...__' (ie, as in 'text' as opposed
+ to '__text__') then we could avoid the following case. */
+ else if (ident_len == attr_len + 4)
+ {
+ const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
+ if (p[0] == '_' && p[1] == '_'
+ && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
+ && strncmp (attr_name, p + 2, attr_len) == 0)
+ break;
+ }
+ list = TREE_CHAIN (list);
+ }
-int
-is_attribute_p (const char *attr, const_tree ident)
-{
- return is_attribute_with_length_p (attr, strlen (attr), ident);
+ return list;
}
-/* Given an attribute name and a list of attributes, return a pointer to the
- attribute's list element if the attribute is part of the list, or NULL_TREE
- if not found. If the attribute appears more than once, this only
- returns the first occurrence; the TREE_CHAIN of the return value should
- be passed back in if further occurrences are wanted. */
+/* A variant of lookup_attribute() that can be used with an identifier
+ as the first argument, and where the identifier can be either
+ 'text' or '__text__'.
-tree
-lookup_attribute (const char *attr_name, tree list)
+ Given an attribute ATTR_IDENTIFIER, and a list of attributes LIST,
+ return a pointer to the attribute's list element if the attribute
+ is part of the list, or NULL_TREE if not found. If the attribute
+ appears more than once, this only returns the first occurrence; the
+ TREE_CHAIN of the return value should be passed back in if further
+ occurrences are wanted. ATTR_IDENTIFIER must be an identifier but
+ can be in the form 'text' or '__text__'. */
+static tree
+lookup_ident_attribute (tree attr_identifier, tree list)
{
- tree l;
- size_t attr_len = strlen (attr_name);
+ gcc_checking_assert (TREE_CODE (attr_identifier) == IDENTIFIER_NODE);
- for (l = list; l; l = TREE_CHAIN (l))
+ while (list)
{
- gcc_assert (TREE_CODE (TREE_PURPOSE (l)) == IDENTIFIER_NODE);
- if (is_attribute_with_length_p (attr_name, attr_len, TREE_PURPOSE (l)))
- return l;
+ gcc_checking_assert (TREE_CODE (TREE_PURPOSE (list)) == IDENTIFIER_NODE);
+
+ /* Identifiers can be compared directly for equality. */
+ if (attr_identifier == TREE_PURPOSE (list))
+ break;
+
+ /* If they are not equal, they may still be one in the form
+ 'text' while the other one is in the form '__text__'. TODO:
+ If we were storing attributes in normalized 'text' form, then
+ this could all go away and we could take full advantage of
+ the fact that we're comparing identifiers. :-) */
+ {
+ size_t attr_len = IDENTIFIER_LENGTH (attr_identifier);
+ size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list));
+
+ if (ident_len == attr_len + 4)
+ {
+ const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
+ const char *q = IDENTIFIER_POINTER (attr_identifier);
+ if (p[0] == '_' && p[1] == '_'
+ && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
+ && strncmp (q, p + 2, attr_len) == 0)
+ break;
+ }
+ else if (ident_len + 4 == attr_len)
+ {
+ const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
+ const char *q = IDENTIFIER_POINTER (attr_identifier);
+ if (q[0] == '_' && q[1] == '_'
+ && q[attr_len - 2] == '_' && q[attr_len - 1] == '_'
+ && strncmp (q + 2, p, ident_len) == 0)
+ break;
+ }
+ }
+ list = TREE_CHAIN (list);
}
- return NULL_TREE;
+
+ return list;
}
/* Remove any instances of attribute ATTR_NAME in LIST and return the
@@ -5305,11 +5342,14 @@ remove_attribute (const char *attr_name, tree list)
tree *p;
size_t attr_len = strlen (attr_name);
+ gcc_checking_assert (attr_name[0] != '_');
+
for (p = &list; *p; )
{
tree l = *p;
- gcc_assert (TREE_CODE (TREE_PURPOSE (l)) == IDENTIFIER_NODE);
- if (is_attribute_with_length_p (attr_name, attr_len, TREE_PURPOSE (l)))
+ /* TODO: If we were storing attributes in normalized form, here
+ we could use a simple strcmp(). */
+ if (private_is_attribute_p (attr_name, attr_len, TREE_PURPOSE (l)))
*p = TREE_CHAIN (l);
else
p = &TREE_CHAIN (l);
@@ -5346,11 +5386,9 @@ merge_attributes (tree a1, tree a2)
for (; a2 != 0; a2 = TREE_CHAIN (a2))
{
tree a;
- for (a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
- attributes);
+ for (a = lookup_ident_attribute (TREE_PURPOSE (a2), attributes);
a != NULL_TREE && !attribute_value_equal (a, a2);
- a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
- TREE_CHAIN (a)))
+ a = lookup_ident_attribute (TREE_PURPOSE (a2), TREE_CHAIN (a)))
;
if (a == NULL_TREE)
{
@@ -5449,24 +5487,7 @@ merge_dllimport_decl_attributes (tree old, tree new_tree)
a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree));
if (delete_dllimport_p)
- {
- tree prev, t;
- const size_t attr_len = strlen ("dllimport");
-
- /* Scan the list for dllimport and delete it. */
- for (prev = NULL_TREE, t = a; t; prev = t, t = TREE_CHAIN (t))
- {
- if (is_attribute_with_length_p ("dllimport", attr_len,
- TREE_PURPOSE (t)))
- {
- if (prev == NULL_TREE)
- a = TREE_CHAIN (a);
- else
- TREE_CHAIN (prev) = TREE_CHAIN (t);
- break;
- }
- }
- }
+ a = remove_attribute ("dllimport", a);
return a;
}
@@ -6254,6 +6275,9 @@ attribute_hash_list (const_tree list, hashval_t hashcode)
int
attribute_list_equal (const_tree l1, const_tree l2)
{
+ if (l1 == l2)
+ return 1;
+
return attribute_list_contained (l1, l2)
&& attribute_list_contained (l2, l1);
}
@@ -6292,11 +6316,9 @@ attribute_list_contained (const_tree l1, const_tree l2)
/* This CONST_CAST is okay because lookup_attribute does not
modify its argument and the return value is assigned to a
const_tree. */
- for (attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
- CONST_CAST_TREE(l1));
+ for (attr = lookup_ident_attribute (TREE_PURPOSE (t2), CONST_CAST_TREE(l1));
attr != NULL_TREE && !attribute_value_equal (t2, attr);
- attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
- TREE_CHAIN (attr)))
+ attr = lookup_ident_attribute (TREE_PURPOSE (t2), TREE_CHAIN (attr)))
;
if (attr == NULL_TREE)