aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-10-14 09:59:45 -0700
committerNathan Sidwell <nathan@acm.org>2020-10-14 10:04:18 -0700
commit068644a14976ce670c2b32c37e18f0aafeb05569 (patch)
treeb349fda340e8e82bbbf0e80205086754dcf2e5bf /gcc/cp/decl.c
parent06bec55e80d98419121f3998d98d969990a75b0b (diff)
downloadgcc-068644a14976ce670c2b32c37e18f0aafeb05569.zip
gcc-068644a14976ce670c2b32c37e18f0aafeb05569.tar.gz
gcc-068644a14976ce670c2b32c37e18f0aafeb05569.tar.bz2
c++: DECL_FRIEND_P cleanup
DECL_FRIEND_P's meaning has changed over time. It now (almost) means the the friend function decl has not been met via an explicit decl. This completes that transition, renaming it to DECL_UNIQUE_FRIEND_P, so one doesn't think it is the sole indicator of friendliness (plenty of friends do not have the flag set). This allows reduction in the complexity of managing the field -- all in duplicate_decls now. gcc/cp/ * cp-tree.h (struct lang_decl_fn): Adjust context comment. (DECL_FRIEND_P): Replace with ... (DECL_UNIQUE_FRIEND_P): ... this. Only for FUNCTION_DECLs. (DECL_FRIEND_CONTEXT): Adjust. * class.c (add_implicitly_declared_members): Detect friendly spaceship from context. * constraint.cc (remove_constraints): Use a checking assert. (maybe_substitute_reqs_for): Use DECL_UNIQUE_FRIEND_P. * decl.c (check_no_redeclaration_friend_default_args): DECL_UNIQUE_FRIEND_P is signficant, not hiddenness. (duplicate_decls): Adjust DECL_UNIQUE_FRIEND_P clearing. (redeclaration_error_message): Use DECL_UNIQUE_FRIEND_P. (start_preparsed_function): Correct in-class friend processing. Refactor some initializers. (grokmethod): Directly check friend decl-spec. * decl2.c (grokfield): Check DECL_UNIQUE_FRIEND_P. * friend.c (do_friend): Set DECL_UNIQUE_FRIEND_P first, remove extraneous conditions. Don't re set it afterwards. * name-lookup.c (lookup_elaborated_type_1): Simplify revealing code. (do_pushtag): Likewise. * pt.c (optimize_specialization_lookup_p): Check DECL_UNIQUE_FRIEND_P. (push_template_decl): Likewise. Drop unneeded friend setting. (type_dependent_expression_p): Check DECL_UNIQUE_FRIEND_P. libcc1/ * libcp1plugin.cc (plugin_add_friend): Set DECL_UNIQUE_FRIEND_P.
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c99
1 files changed, 40 insertions, 59 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0fe74b2..2f1a2f0 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1340,18 +1340,17 @@ check_redeclaration_no_default_args (tree decl)
the function or function template in the translation unit." */
static void
-check_no_redeclaration_friend_default_args (tree olddecl, tree newdecl,
- bool olddecl_hidden_p)
+check_no_redeclaration_friend_default_args (tree olddecl, tree newdecl)
{
- if (!olddecl_hidden_p && !DECL_FRIEND_P (newdecl))
+ if (!DECL_UNIQUE_FRIEND_P (olddecl) && !DECL_UNIQUE_FRIEND_P (newdecl))
return;
for (tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl),
t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);
t1 && t1 != void_list_node;
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
- if ((olddecl_hidden_p && TREE_PURPOSE (t1))
- || (DECL_FRIEND_P (newdecl) && TREE_PURPOSE (t2)))
+ if ((DECL_UNIQUE_FRIEND_P (olddecl) && TREE_PURPOSE (t1))
+ || (DECL_UNIQUE_FRIEND_P (newdecl) && TREE_PURPOSE (t2)))
{
auto_diagnostic_group d;
if (permerror (DECL_SOURCE_LOCATION (newdecl),
@@ -1444,8 +1443,7 @@ tree
duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
{
unsigned olddecl_uid = DECL_UID (olddecl);
- int olddecl_friend = 0, types_match = 0;
- int olddecl_hidden_friend = 0;
+ int types_match = 0;
int new_defines_function = 0;
tree new_template_info;
location_t olddecl_loc = DECL_SOURCE_LOCATION (olddecl);
@@ -1987,8 +1985,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
argument expression, that declaration... shall be the only
declaration of the function or function template in the
translation unit." */
- check_no_redeclaration_friend_default_args
- (olddecl, newdecl, was_hidden);
+ check_no_redeclaration_friend_default_args (olddecl, newdecl);
}
}
}
@@ -2135,12 +2132,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
else
DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
- if (DECL_DECLARES_FUNCTION_P (olddecl))
- {
- olddecl_friend = DECL_FRIEND_P (STRIP_TEMPLATE (olddecl));
- olddecl_hidden_friend = olddecl_friend && was_hidden;
- }
-
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
tree old_result = DECL_TEMPLATE_RESULT (olddecl);
@@ -2167,8 +2158,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
declaration of the function or function template in the
translation unit." */
check_no_redeclaration_friend_default_args
- (old_result, new_result, olddecl_hidden_friend);
+ (old_result, new_result);
}
+ if (!DECL_UNIQUE_FRIEND_P (old_result))
+ DECL_UNIQUE_FRIEND_P (new_result) = false;
check_default_args (newdecl);
@@ -2366,6 +2359,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
&& !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl))
DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl);
+
+ if (!DECL_UNIQUE_FRIEND_P (olddecl))
+ DECL_UNIQUE_FRIEND_P (newdecl) = false;
}
else
{
@@ -2885,8 +2881,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
}
DECL_UID (olddecl) = olddecl_uid;
- if (olddecl_friend)
- DECL_FRIEND_P (olddecl) = true;
/* NEWDECL contains the merged attribute lists.
Update OLDDECL to be the same. */
@@ -3062,7 +3056,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
definition and shall be the only declaration of the
function template in the translation unit. */
if ((cxx_dialect != cxx98)
- && TREE_CODE (ot) == FUNCTION_DECL && DECL_FRIEND_P (ot)
+ && TREE_CODE (ot) == FUNCTION_DECL && DECL_UNIQUE_FRIEND_P (ot)
&& !check_default_tmpl_args (nt, DECL_TEMPLATE_PARMS (newdecl),
/*is_primary=*/true,
/*is_partial=*/false,
@@ -3073,7 +3067,8 @@ redeclaration_error_message (tree newdecl, tree olddecl)
return NULL;
}
else if (VAR_P (newdecl)
- && CP_DECL_THREAD_LOCAL_P (newdecl) != CP_DECL_THREAD_LOCAL_P (olddecl)
+ && (CP_DECL_THREAD_LOCAL_P (newdecl)
+ != CP_DECL_THREAD_LOCAL_P (olddecl))
&& (! DECL_LANG_SPECIFIC (olddecl)
|| ! CP_DECL_THREADPRIVATE_P (olddecl)
|| CP_DECL_THREAD_LOCAL_P (newdecl)))
@@ -16110,36 +16105,21 @@ bool
start_preparsed_function (tree decl1, tree attrs, int flags)
{
tree ctype = NULL_TREE;
- tree fntype;
- tree restype;
- int doing_friend = 0;
- cp_binding_level *bl;
- tree current_function_parms;
- struct c_fileinfo *finfo
- = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
- bool honor_interface;
+ bool doing_friend = false;
/* Sanity check. */
gcc_assert (VOID_TYPE_P (TREE_VALUE (void_list_node)));
gcc_assert (TREE_CHAIN (void_list_node) == NULL_TREE);
- fntype = TREE_TYPE (decl1);
+ tree fntype = TREE_TYPE (decl1);
if (TREE_CODE (fntype) == METHOD_TYPE)
ctype = TYPE_METHOD_BASETYPE (fntype);
-
- /* ISO C++ 11.4/5. A friend function defined in a class is in
- the (lexical) scope of the class in which it is defined. */
- if (!ctype && DECL_FRIEND_P (decl1))
+ else
{
ctype = DECL_FRIEND_CONTEXT (decl1);
- /* CTYPE could be null here if we're dealing with a template;
- for example, `inline friend float foo()' inside a template
- will have no CTYPE set. */
- if (ctype && TREE_CODE (ctype) != RECORD_TYPE)
- ctype = NULL_TREE;
- else
- doing_friend = 1;
+ if (ctype)
+ doing_friend = true;
}
if (DECL_DECLARED_INLINE_P (decl1)
@@ -16206,7 +16186,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
by push_nested_class.) */
if (processing_template_decl)
{
- tree newdecl1 = push_template_decl (decl1, DECL_FRIEND_P (decl1));
+ tree newdecl1 = push_template_decl (decl1, doing_friend);
if (newdecl1 == error_mark_node)
{
if (ctype || DECL_STATIC_FUNCTION_P (decl1))
@@ -16222,7 +16202,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
check_function_type (decl1, DECL_ARGUMENTS (decl1));
/* Build the return declaration for the function. */
- restype = TREE_TYPE (fntype);
+ tree restype = TREE_TYPE (fntype);
if (DECL_RESULT (decl1) == NULL_TREE)
{
@@ -16312,7 +16292,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
/* Save the parm names or decls from this function's declarator
where store_parm_decls will find them. */
- current_function_parms = DECL_ARGUMENTS (decl1);
+ tree current_function_parms = DECL_ARGUMENTS (decl1);
/* Let the user know we're compiling this function. */
announce_function (decl1);
@@ -16329,7 +16309,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
even when processing a template; this is how we get
CFUN set up, and our per-function variables initialized.
FIXME factor out the non-RTL stuff. */
- bl = current_binding_level;
+ cp_binding_level *bl = current_binding_level;
allocate_struct_function (decl1, processing_template_decl);
/* Initialize the language data structures. Whenever we start
@@ -16384,14 +16364,16 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
}
}
- honor_interface = (!DECL_TEMPLATE_INSTANTIATION (decl1)
- /* Implicitly-defined methods (like the
- destructor for a class in which no destructor
- is explicitly declared) must not be defined
- until their definition is needed. So, we
- ignore interface specifications for
- compiler-generated functions. */
- && !DECL_ARTIFICIAL (decl1));
+ bool honor_interface = (!DECL_TEMPLATE_INSTANTIATION (decl1)
+ /* Implicitly-defined methods (like the
+ destructor for a class in which no destructor
+ is explicitly declared) must not be defined
+ until their definition is needed. So, we
+ ignore interface specifications for
+ compiler-generated functions. */
+ && !DECL_ARTIFICIAL (decl1));
+ struct c_fileinfo *finfo
+ = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
if (processing_template_decl)
/* Don't mess with interface flags. */;
@@ -17311,18 +17293,17 @@ grokmethod (cp_decl_specifier_seq *declspecs,
/* We process method specializations in finish_struct_1. */
if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl))
{
- fndecl = push_template_decl (fndecl, DECL_FRIEND_P (fndecl));
+ /* Avoid calling decl_spec_seq... until we have to. */
+ bool friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
+ fndecl = push_template_decl (fndecl, friendp);
if (fndecl == error_mark_node)
return fndecl;
}
- if (! DECL_FRIEND_P (fndecl))
+ if (DECL_CHAIN (fndecl) && !decl_spec_seq_has_spec_p (declspecs, ds_friend))
{
- if (DECL_CHAIN (fndecl))
- {
- fndecl = copy_node (fndecl);
- TREE_CHAIN (fndecl) = NULL_TREE;
- }
+ fndecl = copy_node (fndecl);
+ TREE_CHAIN (fndecl) = NULL_TREE;
}
cp_finish_decl (fndecl, NULL_TREE, false, NULL_TREE, 0);