aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c3
-rw-r--r--gcc/cp/decl2.c10
-rw-r--r--gcc/cp/friend.c9
-rw-r--r--gcc/cp/pt.c51
6 files changed, 34 insertions, 43 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d693b43..dad3849 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3314,7 +3314,7 @@ add_implicitly_declared_members (tree t, tree* access_decls,
bool is_friend = DECL_CONTEXT (space) != t;
if (is_friend)
do_friend (NULL_TREE, DECL_NAME (eq), eq,
- NULL_TREE, NO_SPECIAL, true);
+ NO_SPECIAL, true);
else
{
add_method (t, eq, false);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d3639e3..368d9f5 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6848,7 +6848,7 @@ extern void mark_exp_read (tree);
extern int is_friend (tree, tree);
extern void make_friend_class (tree, tree, bool);
extern void add_friend (tree, tree, bool);
-extern tree do_friend (tree, tree, tree, tree,
+extern tree do_friend (tree, tree, tree,
enum overload_flags, bool);
extern void set_global_friend (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e51c1b0..d1e7337 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -13758,8 +13758,7 @@ grokdeclarator (const cp_declarator *declarator,
}
decl = do_friend (ctype, unqualified_id, decl,
- *attrlist, flags,
- funcdef_flag);
+ flags, funcdef_flag);
return decl;
}
else
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a82960f..89f874a 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -974,7 +974,11 @@ grokfield (const cp_declarator *declarator,
if ((TREE_CODE (value) == FUNCTION_DECL
|| TREE_CODE (value) == TEMPLATE_DECL)
&& DECL_CONTEXT (value) != current_class_type)
- return value;
+ {
+ if (attrlist)
+ cplus_decl_attributes (&value, attrlist, 0);
+ return value;
+ }
/* Need to set this before push_template_decl. */
if (VAR_P (value))
@@ -1278,9 +1282,9 @@ save_template_attributes (tree *attr_p, tree *decl_p, int flags)
tree old_attrs = *q;
- /* Merge the late attributes at the beginning with the attribute
+ /* Place the late attributes at the beginning of the attribute
list. */
- late_attrs = merge_attributes (late_attrs, *q);
+ late_attrs = chainon (late_attrs, *q);
if (*q != late_attrs
&& !DECL_P (*decl_p)
&& !(flags & ATTR_FLAG_TYPE_IN_PLACE))
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index ee73adb..4f62884 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -475,7 +475,7 @@ make_friend_class (tree type, tree friend_type, bool complain)
tree
do_friend (tree ctype, tree declarator, tree decl,
- tree attrlist, enum overload_flags flags,
+ enum overload_flags flags,
bool funcdef_flag)
{
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
@@ -488,13 +488,6 @@ do_friend (tree ctype, tree declarator, tree decl,
error ("friend declaration %qD may not have virt-specifiers",
decl);
- /* Unfortunately, we have to handle attributes here. Normally we would
- handle them in start_decl_1, but since this is a friend decl start_decl_1
- never gets to see it. */
-
- /* Set attributes here so if duplicate decl, will have proper attributes. */
- cplus_decl_attributes (&decl, attrlist, 0);
-
if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
{
declarator = TREE_OPERAND (declarator, 0);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index fc5065b..116bdd2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11659,7 +11659,6 @@ static bool
apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
tree args, tsubst_flags_t complain, tree in_decl)
{
- tree last_dep = NULL_TREE;
tree t;
tree *p;
@@ -11685,39 +11684,35 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
p = &TREE_CHAIN (*p);
}
+ /* save_template_attributes puts the dependent attributes at the beginning of
+ the list; find the non-dependent ones. */
for (t = attributes; t; t = TREE_CHAIN (t))
- if (ATTR_IS_DEPENDENT (t))
- {
- last_dep = t;
- attributes = copy_list (attributes);
- break;
- }
+ if (!ATTR_IS_DEPENDENT (t))
+ break;
+ tree nondep = t;
- *p = attributes;
- if (last_dep)
- {
- tree late_attrs = NULL_TREE;
- tree *q = &late_attrs;
+ /* Apply any non-dependent attributes. */
+ *p = nondep;
- for (; *p; )
+ /* And then any dependent ones. */
+ tree late_attrs = NULL_TREE;
+ tree *q = &late_attrs;
+ for (t = attributes; t != nondep; t = TREE_CHAIN (t))
+ {
+ *q = tsubst_attribute (t, decl_p, args, complain, in_decl);
+ if (*q == error_mark_node)
+ return false;
+ if (*q == t)
{
- t = *p;
- if (ATTR_IS_DEPENDENT (t))
- {
- *q = tsubst_attribute (t, decl_p, args, complain, in_decl);
- if (*q == error_mark_node)
- return false;
- *p = TREE_CHAIN (t);
- TREE_CHAIN (t) = NULL_TREE;
- while (*q)
- q = &TREE_CHAIN (*q);
- }
- else
- p = &TREE_CHAIN (t);
+ *q = copy_node (t);
+ TREE_CHAIN (*q) = NULL_TREE;
}
-
- cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+ while (*q)
+ q = &TREE_CHAIN (*q);
}
+
+ cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+
return true;
}