return list;
}
+/* Similarly but also match namespace on the removed attributes. */
+
+tree
+remove_attribute (const char *attr_ns, const char *attr_name, tree list)
+{
+ tree *p;
+ gcc_checking_assert (attr_name[0] != '_');
+ gcc_checking_assert (attr_ns == NULL || attr_ns[0] != '_');
+
+ for (p = &list; *p;)
+ {
+ tree l = *p;
+
+ tree attr = get_attribute_name (l);
+ if (is_attribute_p (attr_name, attr))
+ {
+ tree ns = get_attribute_namespace (l);
+ if ((ns == NULL_TREE && attr_ns == NULL)
+ || (ns && attr_ns && is_attribute_p (attr_ns, ns)))
+ {
+ *p = TREE_CHAIN (l);
+ continue;
+ }
+ }
+ p = &TREE_CHAIN (l);
+ }
+
+ return list;
+}
+
/* Return an attribute list that is the union of a1 and a2. */
tree
return list;
}
+/* Similarly but with also attribute namespace. */
+
+tree
+private_lookup_attribute (const char *attr_ns, const char *attr_name,
+ size_t attr_ns_len, size_t attr_len, tree list)
+{
+ while (list)
+ {
+ tree attr = get_attribute_name (list);
+ size_t ident_len = IDENTIFIER_LENGTH (attr);
+ if (cmp_attribs (attr_name, attr_len, IDENTIFIER_POINTER (attr),
+ ident_len))
+ {
+ tree ns = get_attribute_namespace (list);
+ if (ns == NULL_TREE)
+ {
+ if (attr_ns == NULL)
+ break;
+ }
+ else if (attr_ns)
+ {
+ ident_len = IDENTIFIER_LENGTH (ns);
+ if (cmp_attribs (attr_ns, attr_ns_len, IDENTIFIER_POINTER (ns),
+ ident_len))
+ break;
+ }
+ }
+ list = TREE_CHAIN (list);
+ }
+
+ return list;
+}
+
/* Return true if the function decl or type NODE has been declared
with attribute ANAME among attributes ATTRS. */
extern tree remove_attribute (const char *, tree);
+/* Similarly but also with specific attribute namespace. */
+
+extern tree remove_attribute (const char *, const char *, tree);
+
/* Given two attributes lists, return a list of their union. */
extern tree merge_attributes (tree, tree);
for size. */
extern tree private_lookup_attribute (const char *attr_name, size_t attr_len,
tree list);
+extern tree private_lookup_attribute (const char *attr_ns,
+ const char *attr_name,
+ size_t attr_ns_len, size_t attr_len,
+ tree list);
extern unsigned decls_mismatched_attributes (tree, tree, tree,
const char* const[],
}
}
+/* Similar to lookup_attribute, but also match the attribute namespace. */
+
+static inline tree
+lookup_attribute (const char *attr_ns, const char *attr_name, tree list)
+{
+ if (CHECKING_P && attr_name[0] != '_')
+ {
+ size_t attr_len = strlen (attr_name);
+ gcc_checking_assert (!canonicalize_attr_name (attr_name, attr_len));
+ }
+ if (CHECKING_P && attr_ns && attr_ns[0] != '_')
+ {
+ size_t attr_ns_len = strlen (attr_ns);
+ gcc_checking_assert (!canonicalize_attr_name (attr_ns, attr_ns_len));
+ }
+ /* In most cases, list is NULL_TREE. */
+ if (list == NULL_TREE)
+ return NULL_TREE;
+ else
+ {
+ size_t attr_ns_len = attr_ns ? strlen (attr_ns) : 0;
+ size_t attr_len = strlen (attr_name);
+ /* Do the strlen() before calling the out-of-line implementation.
+ In most cases attr_name is a string constant, and the compiler
+ will optimize the strlen() away. */
+ return private_lookup_attribute (attr_ns, attr_name,
+ attr_ns_len, attr_len, list);
+ }
+}
+
/* Given an attribute name ATTR_NAME and a list of attributes LIST,
return a pointer to the attribute's list first element if the attribute
starts with ATTR_NAME. ATTR_NAME must be in the form 'text' (not