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
This commit is contained in:
parent
a21309013c
commit
bd3d082ebe
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
11
gcc/cp/pt.c
11
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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
8
gcc/testsuite/g++.dg/lookup/hidden-class1.C
Normal file
8
gcc/testsuite/g++.dg/lookup/hidden-class1.C
Normal file
@ -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" }
|
||||
};
|
9
gcc/testsuite/g++.dg/lookup/hidden-class2.C
Normal file
9
gcc/testsuite/g++.dg/lookup/hidden-class2.C
Normal file
@ -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;
|
10
gcc/testsuite/g++.dg/lookup/hidden-class3.C
Normal file
10
gcc/testsuite/g++.dg/lookup/hidden-class3.C
Normal file
@ -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;
|
||||
};
|
10
gcc/testsuite/g++.dg/lookup/hidden-class4.C
Normal file
10
gcc/testsuite/g++.dg/lookup/hidden-class4.C
Normal file
@ -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;
|
9
gcc/testsuite/g++.dg/lookup/hidden-class5.C
Normal file
9
gcc/testsuite/g++.dg/lookup/hidden-class5.C
Normal file
@ -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" }
|
14
gcc/testsuite/g++.dg/lookup/hidden-class6.C
Normal file
14
gcc/testsuite/g++.dg/lookup/hidden-class6.C
Normal file
@ -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;
|
||||
};
|
||||
}
|
13
gcc/testsuite/g++.dg/lookup/hidden-class7.C
Normal file
13
gcc/testsuite/g++.dg/lookup/hidden-class7.C
Normal file
@ -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" }
|
12
gcc/testsuite/g++.dg/lookup/hidden-class8.C
Normal file
12
gcc/testsuite/g++.dg/lookup/hidden-class8.C
Normal file
@ -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" }
|
||||
};
|
11
gcc/testsuite/g++.dg/lookup/hidden-class9.C
Normal file
11
gcc/testsuite/g++.dg/lookup/hidden-class9.C
Normal file
@ -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" }
|
8
gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C
Normal file
8
gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C
Normal file
@ -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" }
|
||||
};
|
12
gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C
Normal file
12
gcc/testsuite/g++.dg/lookup/hidden-temp-class10.C
Normal file
@ -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" }
|
||||
};
|
11
gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C
Normal file
11
gcc/testsuite/g++.dg/lookup/hidden-temp-class11.C
Normal file
@ -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" }
|
9
gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C
Normal file
9
gcc/testsuite/g++.dg/lookup/hidden-temp-class2.C
Normal file
@ -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" }
|
9
gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C
Normal file
9
gcc/testsuite/g++.dg/lookup/hidden-temp-class3.C
Normal file
@ -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;
|
||||
};
|
9
gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C
Normal file
9
gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C
Normal file
@ -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" }
|
10
gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C
Normal file
10
gcc/testsuite/g++.dg/lookup/hidden-temp-class5.C
Normal file
@ -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;
|
11
gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C
Normal file
11
gcc/testsuite/g++.dg/lookup/hidden-temp-class6.C
Normal file
@ -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;
|
||||
};
|
||||
}
|
13
gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C
Normal file
13
gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C
Normal file
@ -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" }
|
11
gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C
Normal file
11
gcc/testsuite/g++.dg/lookup/hidden-temp-class8.C
Normal file
@ -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" }
|
||||
};
|
11
gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C
Normal file
11
gcc/testsuite/g++.dg/lookup/hidden-temp-class9.C
Normal file
@ -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" }
|
||||
};
|
Loading…
Reference in New Issue
Block a user