aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>2005-03-14 14:33:54 +0000
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>2005-03-14 14:33:54 +0000
commitbd3d082ebe2c5d6ef38d0c3bb53ae0baefe1654d (patch)
tree3d599413959c98f204efab81966efde722599232
parenta21309013c3bf59f796c2d92a50a85bd0597243c (diff)
downloadgcc-bd3d082ebe2c5d6ef38d0c3bb53ae0baefe1654d.zip
gcc-bd3d082ebe2c5d6ef38d0c3bb53ae0baefe1654d.tar.gz
gcc-bd3d082ebe2c5d6ef38d0c3bb53ae0baefe1654d.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog31
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c34
-rw-r--r--gcc/cp/name-lookup.c91
-rw-r--r--gcc/cp/name-lookup.h1
-rw-r--r--gcc/cp/parser.c5
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/cp/rtti.c8
-rw-r--r--gcc/cp/semantics.c4
-rw-r--r--gcc/testsuite/ChangeLog25
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class1.C8
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class2.C9
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class3.C10
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class4.C10
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class5.C9
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class6.C14
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class7.C13
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class8.C12
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class9.C11
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C8
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C12
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C11
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C9
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C9
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C9
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C10
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C11
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C13
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C11
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C11
30 files changed, 371 insertions, 51 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fefffd8..e2a7de3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,34 @@
+2005-03-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ 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.
+
2005-03-13 Mark Mitchell <mark@codesourcery.com>
PR c++/20157
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index aef5637..640d4dd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3761,7 +3761,7 @@ extern void maybe_push_cleanup_level (tree);
extern void finish_scope (void);
extern void push_switch (tree);
extern void pop_switch (void);
-extern tree pushtag (tree, tree, int);
+extern tree pushtag (tree, tree, tag_scope);
extern tree make_anon_name (void);
extern int decls_match (tree, tree);
extern tree duplicate_decls (tree, tree);
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;
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e861a66..4a5429c 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3296,12 +3296,13 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
case TEMPLATE_DECL:
/* If we expect types or namespaces, and not templates,
or this is not a template class. */
- if (LOOKUP_QUALIFIERS_ONLY (flags)
- && !DECL_CLASS_TEMPLATE_P (val))
+ if ((LOOKUP_QUALIFIERS_ONLY (flags)
+ && !DECL_CLASS_TEMPLATE_P (val))
+ || hidden_name_p (val))
val = NULL_TREE;
break;
case TYPE_DECL:
- if (LOOKUP_NAMESPACES_ONLY (flags))
+ if (LOOKUP_NAMESPACES_ONLY (flags) || hidden_name_p (val))
val = NULL_TREE;
break;
case NAMESPACE_DECL:
@@ -3310,7 +3311,7 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
break;
case FUNCTION_DECL:
/* Ignore built-in functions that are still anticipated. */
- if (LOOKUP_QUALIFIERS_ONLY (flags) || DECL_ANTICIPATED (val))
+ if (LOOKUP_QUALIFIERS_ONLY (flags) || hidden_name_p (val))
val = NULL_TREE;
break;
default:
@@ -3382,21 +3383,35 @@ lookup_flags (int prefer_type, int namespaces_only)
}
/* Given a lookup that returned VAL, use FLAGS to decide if we want to
- ignore it or not. Subroutine of lookup_name_real. */
+ ignore it or not. Subroutine of lookup_name_real and
+ lookup_type_scope. */
-static tree
+static bool
qualify_lookup (tree val, int flags)
{
if (val == NULL_TREE)
- return val;
+ return false;
if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
- return val;
+ return true;
if ((flags & LOOKUP_PREFER_TYPES)
&& (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
- return val;
+ return true;
if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
- return NULL_TREE;
- return val;
+ return false;
+ return true;
+}
+
+/* Given a lookup that returned VAL, decide if we want to ignore it or
+ not based on DECL_ANTICIPATED_P. */
+
+bool
+hidden_name_p (tree val)
+{
+ if (DECL_P (val)
+ && DECL_LANG_SPECIFIC (val)
+ && DECL_ANTICIPATED (val))
+ return true;
+ return false;
}
/* Look up NAME in the NAMESPACE. */
@@ -3467,10 +3482,9 @@ lookup_namespace_name (tree namespace, tree name)
if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
val = OVL_FUNCTION (val);
- /* Ignore built-in functions that haven't been prototyped yet. */
- if (!val || !DECL_P(val)
- || !DECL_LANG_SPECIFIC(val)
- || !DECL_ANTICIPATED (val))
+ /* Ignore built-in functions and friends that haven't been declared
+ yet. */
+ if (!val || !hidden_name_p (val))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
}
@@ -3529,10 +3543,8 @@ unqualified_namespace_lookup (tree name, int flags)
if (b)
{
- if (b->value && DECL_P (b->value)
- && DECL_LANG_SPECIFIC (b->value)
- && DECL_ANTICIPATED (b->value))
- /* Ignore anticipated built-in functions. */
+ if (b->value && hidden_name_p (b->value))
+ /* Ignore anticipated built-in functions and friends. */
;
else
binding.value = b->value;
@@ -3773,6 +3785,8 @@ innermost_non_namespace_value (tree name)
node of some kind representing its definition if there is only one
such declaration, or return a TREE_LIST with all the overloaded
definitions if there are many, or return 0 if it is undefined.
+ Hidden name, either friend declaration or built-in function, are
+ not ignored.
If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
@@ -3837,10 +3851,12 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
continue;
/* If this is the kind of thing we're looking for, we're done. */
- if (qualify_lookup (iter->value, flags))
+ if (qualify_lookup (iter->value, flags)
+ && !hidden_name_p (iter->value))
binding = iter->value;
else if ((flags & LOOKUP_PREFER_TYPES)
- && qualify_lookup (iter->type, flags))
+ && qualify_lookup (iter->type, flags)
+ && !hidden_name_p (iter->type))
binding = iter->type;
else
binding = NULL_TREE;
@@ -3898,7 +3914,8 @@ lookup_name (tree name, int prefer_type)
Unlike lookup_name_real, we make sure that NAME is actually
declared in the desired scope, not from inheritance, nor using
directive. For using declaration, there is DR138 still waiting
- to be resolved.
+ to be resolved. Hidden name coming from earlier an friend
+ declaration is also returned.
A TYPE_DECL best matching the NAME is returned. Catching error
and issuing diagnostics are caller's responsibility. */
@@ -3948,9 +3965,7 @@ lookup_type_scope (tree name, tag_scope scope)
if (iter)
{
- /* If this is the kind of thing we're looking for, we're done.
- Ignore names found via using declaration. See DR138 for
- current status. */
+ /* If this is the kind of thing we're looking for, we're done. */
if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES))
val = iter->type;
else if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
@@ -4500,7 +4515,7 @@ push_using_directive (tree used)
processing. */
static tree
-maybe_process_template_type_declaration (tree type, int globalize,
+maybe_process_template_type_declaration (tree type, int is_friend,
cxx_scope *b)
{
tree decl = TYPE_NAME (type);
@@ -4523,7 +4538,7 @@ maybe_process_template_type_declaration (tree type, int globalize,
push_template_decl_real, but we want the original value. */
tree name = DECL_NAME (decl);
- decl = push_template_decl_real (decl, globalize);
+ decl = push_template_decl_real (decl, is_friend);
/* If the current binding level is the binding level for the
template parameters (see the comment in
begin_template_parm_list) and the enclosing level is a class
@@ -4532,7 +4547,7 @@ maybe_process_template_type_declaration (tree type, int globalize,
friend case, push_template_decl will already have put the
friend into global scope, if appropriate. */
if (TREE_CODE (type) != ENUMERAL_TYPE
- && !globalize && b->kind == sk_template_parms
+ && !is_friend && b->kind == sk_template_parms
&& b->level_chain->kind == sk_class)
{
finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
@@ -4563,7 +4578,7 @@ maybe_process_template_type_declaration (tree type, int globalize,
Returns TYPE upon success and ERROR_MARK_NODE otherwise. */
tree
-pushtag (tree name, tree type, int globalize)
+pushtag (tree name, tree type, tag_scope scope)
{
struct cp_binding_level *b;
@@ -4580,7 +4595,7 @@ pushtag (tree name, tree type, int globalize)
template is instantiated. */
|| (b->kind == sk_template_parms && b->explicit_spec_p)
|| (b->kind == sk_class
- && (globalize
+ && (scope != ts_current
/* We may be defining a new type in the initializer
of a static member variable. We allow this when
not pedantic, and it is particularly useful for
@@ -4601,7 +4616,7 @@ pushtag (tree name, tree type, int globalize)
{
tree cs = current_scope ();
- if (! globalize)
+ if (scope == ts_current)
context = cs;
else if (cs != NULL_TREE && TYPE_P (cs))
/* When declaring a friend class of a local class, we want
@@ -4622,11 +4637,21 @@ pushtag (tree name, tree type, int globalize)
d = create_implicit_typedef (name, type);
DECL_CONTEXT (d) = FROB_CONTEXT (context);
+ if (scope == ts_within_enclosing_non_class)
+ {
+ /* This is a friend. Make this TYPE_DECL node hidden from
+ ordinary name lookup. Its corresponding TEMPLATE_DECL
+ will be marked in push_template_decl_real. */
+ retrofit_lang_decl (d);
+ DECL_ANTICIPATED (d) = 1;
+ DECL_FRIEND_P (d) = 1;
+ }
+
if (! in_class)
set_identifier_type_value_with_scope (name, d, b);
- d = maybe_process_template_type_declaration (type,
- globalize, b);
+ d = maybe_process_template_type_declaration
+ (type, scope == ts_within_enclosing_non_class, b);
if (d == error_mark_node)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index e443319..451e6ec 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -315,6 +315,7 @@ extern tree lookup_name_real (tree, int, int, bool, int, int);
extern tree lookup_type_scope (tree, tag_scope);
extern tree namespace_binding (tree, tree);
extern void set_namespace_binding (tree, tree, tree);
+extern bool hidden_name_p (tree);
extern tree lookup_namespace_name (tree, tree);
extern tree lookup_qualified_name (tree, tree, bool, bool);
extern tree lookup_name_nonclass (tree);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 6fb9fca..2b6c03b 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -14382,10 +14382,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
}
/* If the lookup failed, let our caller know. */
- if (!decl
- || decl == error_mark_node
- || (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_ANTICIPATED (decl)))
+ if (!decl || decl == error_mark_node)
return error_mark_node;
/* If it's a TREE_LIST, the result of the lookup was ambiguous. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c9d2f96..1147f79 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3132,6 +3132,13 @@ push_template_decl_real (tree decl, int is_friend)
tmpl = pushdecl_namespace_level (tmpl);
if (tmpl == error_mark_node)
return error_mark_node;
+
+ /* Hide template friend classes that haven't been declared yet. */
+ if (is_friend && TREE_CODE (decl) == TYPE_DECL)
+ {
+ DECL_ANTICIPATED (tmpl) = 1;
+ DECL_FRIEND_P (tmpl) = 1;
+ }
}
if (primary)
@@ -4629,7 +4636,7 @@ lookup_template_class (tree d1,
/* A local class. Make sure the decl gets registered properly. */
if (context == current_function_decl)
- pushtag (DECL_NAME (template), t, 0);
+ pushtag (DECL_NAME (template), t, /*tag_scope=*/ts_current);
}
/* If we called start_enum or pushtag above, this information
@@ -5679,7 +5686,7 @@ instantiate_class_template (tree type)
tsubst_enum. */
if (name)
SET_IDENTIFIER_TYPE_VALUE (name, newtag);
- pushtag (name, newtag, /*globalize=*/0);
+ pushtag (name, newtag, /*tag_scope=*/ts_current);
}
}
else if (TREE_CODE (t) == FUNCTION_DECL
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index a08a3ee..45f0b08 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -113,7 +113,7 @@ init_rtti_processing (void)
push_namespace (std_identifier);
type_info_type = xref_tag (class_type, get_identifier ("type_info"),
- /*tag_scope=*/ts_global, false);
+ /*tag_scope=*/ts_current, false);
pop_namespace ();
const_type_info_type_node
= build_qualified_type (type_info_type, TYPE_QUAL_CONST);
@@ -624,7 +624,7 @@ build_dynamic_cast_1 (tree type, tree expr)
push_nested_namespace (ns);
tinfo_ptr = xref_tag (class_type,
get_identifier ("__class_type_info"),
- /*tag_scope=*/ts_global, false);
+ /*tag_scope=*/ts_current, false);
tinfo_ptr = build_pointer_type
(build_qualified_type
@@ -805,7 +805,7 @@ tinfo_base_init (tree desc, tree target)
push_nested_namespace (abi_node);
real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
- /*tag_scope=*/ts_global, false);
+ /*tag_scope=*/ts_current, false);
pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (real_type))
@@ -1337,7 +1337,7 @@ emit_support_tinfos (void)
push_nested_namespace (abi_node);
bltn_type = xref_tag (class_type,
get_identifier ("__fundamental_type_info"),
- /*tag_scope=*/ts_global, false);
+ /*tag_scope=*/ts_current, false);
pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (bltn_type))
return;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 2daff6f..15762cb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2122,7 +2122,7 @@ begin_class_definition (tree t)
if (t == error_mark_node || ! IS_AGGR_TYPE (t))
{
t = make_aggr_type (RECORD_TYPE);
- pushtag (make_anon_name (), t, 0);
+ pushtag (make_anon_name (), t, /*tag_scope=*/ts_current);
}
/* Update the location of the decl. */
@@ -2131,7 +2131,7 @@ begin_class_definition (tree t)
if (TYPE_BEING_DEFINED (t))
{
t = make_aggr_type (TREE_CODE (t));
- pushtag (TYPE_IDENTIFIER (t), t, 0);
+ pushtag (TYPE_IDENTIFIER (t), t, /*tag_scope=*/ts_current);
}
maybe_process_partial_specialization (t);
pushclass (t);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1b6603f..993b95b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,28 @@
+2005-03-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ Friend class name lookup 5/n
+ PR c++/1016
+ * 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.
+
2005-03-13 Mark Mitchell <mark@codesourcery.com>
PR c++/20157
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class1.C b/gcc/testsuite/g++.dg/lookup/hidden-class1.C
new file mode 100644
index 0000000..fc71e96
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class1.C
@@ -0,0 +1,8 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ friend class B;
+ B *b; // { dg-error "no type|expected" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class2.C b/gcc/testsuite/g++.dg/lookup/hidden-class2.C
new file mode 100644
index 0000000..19287a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class2.C
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ friend class B;
+};
+
+class B* b;
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class3.C b/gcc/testsuite/g++.dg/lookup/hidden-class3.C
new file mode 100644
index 0000000..50a7e33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class3.C
@@ -0,0 +1,10 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ friend class B;
+
+ class B;
+ B *b;
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class4.C b/gcc/testsuite/g++.dg/lookup/hidden-class4.C
new file mode 100644
index 0000000..c407692
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class4.C
@@ -0,0 +1,10 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ friend class B;
+};
+
+class B *b;
+B *c;
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class5.C b/gcc/testsuite/g++.dg/lookup/hidden-class5.C
new file mode 100644
index 0000000..1cf06bc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class5.C
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ friend class B;
+};
+
+B* b; // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class6.C b/gcc/testsuite/g++.dg/lookup/hidden-class6.C
new file mode 100644
index 0000000..9642535
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class6.C
@@ -0,0 +1,14 @@
+// { dg-do compile }
+
+// Origin: Jay Cox <jaycox@gimp.org>
+
+// PR c++/1016: Name lookup for injected friend class
+
+class B;
+
+namespace N {
+ class A {
+ friend class B;
+ B* b;
+ };
+}
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class7.C b/gcc/testsuite/g++.dg/lookup/hidden-class7.C
new file mode 100644
index 0000000..f681cd6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class7.C
@@ -0,0 +1,13 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ friend class B;
+};
+
+class C {
+ friend class B;
+};
+
+B *b; // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class8.C b/gcc/testsuite/g++.dg/lookup/hidden-class8.C
new file mode 100644
index 0000000..ea4e2f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class8.C
@@ -0,0 +1,12 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+namespace N {
+ class A {
+ friend class B;
+ };
+}
+
+class N::B { // { dg-error "not name a class" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class9.C b/gcc/testsuite/g++.dg/lookup/hidden-class9.C
new file mode 100644
index 0000000..de86b12
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class9.C
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+namespace N {
+ class A {
+ friend class B;
+ };
+}
+
+using N::B; // { dg-error "declared" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C
new file mode 100644
index 0000000..c92b7f6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C
@@ -0,0 +1,8 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ template <class T> friend class B;
+ B<int> *b; // { dg-error "no type|expected" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C
new file mode 100644
index 0000000..2134635
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C
@@ -0,0 +1,12 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+namespace N {
+ class A {
+ template <class T> friend class B;
+ };
+}
+
+template <class T> class N::B { // { dg-error "not name a class" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C
new file mode 100644
index 0000000..6e8cbdb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+namespace N {
+ class A {
+ template <class T> friend class B;
+ };
+}
+
+using N::B; // { dg-error "declared" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C
new file mode 100644
index 0000000..56ba76b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ template <class T> friend class B;
+};
+
+class B* b; // { dg-error "argument required|invalid" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C
new file mode 100644
index 0000000..3f96622
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ template <class T> friend class B;
+ template <class T> class B;
+ B<int> *b;
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C
new file mode 100644
index 0000000..02dc9c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C
@@ -0,0 +1,9 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ template <class T> friend class B;
+};
+
+B<int> *b; // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C
new file mode 100644
index 0000000..e6b30b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C
@@ -0,0 +1,10 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ template <class T> friend class B;
+};
+
+template <class T> class B;
+B<int>* b;
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C
new file mode 100644
index 0000000..2072695
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class B;
+namespace N {
+ class A {
+ template <class T> friend class B;
+ B* b;
+ };
+}
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C
new file mode 100644
index 0000000..22804d7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C
@@ -0,0 +1,13 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ template <class T> friend class B;
+};
+
+class C {
+ template <class T> friend class B;
+};
+
+B<int> *b; // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C
new file mode 100644
index 0000000..247c78c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ template <class T> friend class B;
+};
+
+class C {
+ friend class B; // { dg-error "argument required|friend" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C
new file mode 100644
index 0000000..783139b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation
+// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+// { dg-do compile }
+
+class A {
+ friend class B;
+};
+
+class C {
+ template <class T> friend class B; // { dg-error "not a template" }
+};