From bd3d082ebe2c5d6ef38d0c3bb53ae0baefe1654d Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Mon, 14 Mar 2005 14:33:54 +0000 Subject: Friend class name lookup 5/n PR c++/1016 Friend class name lookup 5/n PR c++/1016 * cp-tree.h (pushtag): Adjust declaration. * decl.c (lookup_and_check_tag): Call lookup_type_scope if lookup_name fails. (xref_tag): Adjust call to pushtag. Make hidden class visible. (start_enum): Adjust call to pushtag. * name-lookup.c (ambiguous_decl): Ignore hidden names. (qualify_lookup): Change return type to bool. (hidden_name_p): New function. (lookup_namespace_name, unqualified_namespace_lookup, lookup_name_real): Use it. (lookup_type_scope): Update comments. (maybe_process_template_type_declaration): Change parameter name from globalize to is_friend. (pushtag): Change globalize parameter of type int to tag_scope. Hide name if introduced by friend declaration. * name-lookup.h (hidden_name_p): Add declaration. * parser.c (cp_parser_lookup_name): Don't deal with hidden name here. * pt.c (push_template_decl_real): Make hidden class template visible. (lookup_template_class, instantiate_class_template): Adjust call to pushtag. * semantics.c (begin_class_definition): Likewise. * rtti.c (init_rtti_processing, build_dynamic_cast_1, tinfo_base_init, emit_support_tinfos): Use ts_current instead of ts_global. * g++.dg/lookup/hidden-class1.C: New test. * g++.dg/lookup/hidden-class2.C: Likewise. * g++.dg/lookup/hidden-class3.C: Likewise. * g++.dg/lookup/hidden-class4.C: Likewise. * g++.dg/lookup/hidden-class5.C: Likewise. * g++.dg/lookup/hidden-class6.C: Likewise. * g++.dg/lookup/hidden-class7.C: Likewise. * g++.dg/lookup/hidden-class8.C: Likewise. * g++.dg/lookup/hidden-class9.C: Likewise. * g++.dg/lookup/hidden-temp-class1.C: Likewise. * g++.dg/lookup/hidden-temp-class2.C: Likewise. * g++.dg/lookup/hidden-temp-class3.C: Likewise. * g++.dg/lookup/hidden-temp-class4.C: Likewise. * g++.dg/lookup/hidden-temp-class5.C: Likewise. * g++.dg/lookup/hidden-temp-class6.C: Likewise. * g++.dg/lookup/hidden-temp-class7.C: Likewise. * g++.dg/lookup/hidden-temp-class8.C: Likewise. * g++.dg/lookup/hidden-temp-class9.C: Likewise. * g++.dg/lookup/hidden-temp-class10.C: Likewise. * g++.dg/lookup/hidden-temp-class11.C: Likewise. From-SVN: r96430 --- gcc/cp/decl.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'gcc/cp/decl.c') diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index dee5c46..4e350c3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9082,7 +9082,6 @@ check_elaborated_type_specifier (enum tag_types tag_code, void f(class C); // No template header here then the required template argument is missing. */ - error ("template argument required for %<%s %T%>", tag_name (tag_code), DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))); @@ -9104,7 +9103,19 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, tree t; tree decl; if (scope == ts_global) - decl = lookup_name (name, 2); + { + /* First try ordinary name lookup, ignoring hidden class name + injected via friend declaration. */ + decl = lookup_name (name, 2); + /* If that fails, the name will be placed in the smallest + non-class, non-function-prototype scope according to 3.3.1/5. + We may already have a hidden name declared as friend in this + scope. So lookup again but not ignoring hidden name. + If we find one, that name will be made visible rather than + creating a new tag. */ + if (!decl) + decl = lookup_type_scope (name, ts_within_enclosing_non_class); + } else decl = lookup_type_scope (name, scope); @@ -9264,8 +9275,7 @@ xref_tag (enum tag_types tag_code, tree name, { t = make_aggr_type (code); TYPE_CONTEXT (t) = context; - /* pushtag only cares whether SCOPE is zero or not. */ - t = pushtag (name, t, scope != ts_current); + t = pushtag (name, t, scope); } } else @@ -9279,6 +9289,20 @@ xref_tag (enum tag_types tag_code, tree name, error ("redeclaration of %qT as a non-template", t); t = error_mark_node; } + + /* Make injected friend class visible. */ + if (scope != ts_within_enclosing_non_class + && hidden_name_p (TYPE_NAME (t))) + { + DECL_ANTICIPATED (TYPE_NAME (t)) = 0; + DECL_FRIEND_P (TYPE_NAME (t)) = 0; + + if (TYPE_TEMPLATE_INFO (t)) + { + DECL_ANTICIPATED (TYPE_TI_TEMPLATE (t)) = 0; + DECL_FRIEND_P (TYPE_TI_TEMPLATE (t)) = 0; + } + } } POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); @@ -9520,7 +9544,7 @@ start_enum (tree name) name = make_anon_name (); enumtype = make_node (ENUMERAL_TYPE); - enumtype = pushtag (name, enumtype, 0); + enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current); } return enumtype; -- cgit v1.1