diff options
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc/tree.c b/gcc/tree.c index 60538bd197e..4533294af60 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -3114,6 +3114,44 @@ lookup_attribute (attr_name, list) return NULL_TREE; } + +/* Return an attribute list that is the union of a1 and a2. */ + +tree +merge_attributes (a1, a2) + register tree a1, a2; +{ + tree attributes; + + /* Either one unset? Take the set one. */ + + if (! (attributes = a1)) + attributes = a2; + + /* One that completely contains the other? Take it. */ + + else if (a2 && ! attribute_list_contained (a1, a2)) + if (attribute_list_contained (a2, a1)) + attributes = a2; + else + { + /* Pick the longest list, and hang on the other list. */ + /* ??? For the moment we punt on the issue of attrs with args. */ + + if (list_length (a1) < list_length (a2)) + attributes = a2, a2 = a1; + + for (; a2; a2 = TREE_CHAIN (a2)) + if (lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)), + attributes) == NULL_TREE) + { + a1 = copy_node (a2); + TREE_CHAIN (a1) = attributes; + attributes = a1; + } + } + return attributes; +} /* Return a type like TYPE except that its TYPE_READONLY is CONSTP and its TYPE_VOLATILE is VOLATILEP. |