diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-10-14 09:59:45 -0700 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-10-14 10:04:18 -0700 |
commit | 068644a14976ce670c2b32c37e18f0aafeb05569 (patch) | |
tree | b349fda340e8e82bbbf0e80205086754dcf2e5bf /gcc/cp/decl.c | |
parent | 06bec55e80d98419121f3998d98d969990a75b0b (diff) | |
download | gcc-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.c | 99 |
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); |