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>
|
2005-03-13 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
PR c++/20157
|
PR c++/20157
|
||||||
|
|
|
@ -3761,7 +3761,7 @@ extern void maybe_push_cleanup_level (tree);
|
||||||
extern void finish_scope (void);
|
extern void finish_scope (void);
|
||||||
extern void push_switch (tree);
|
extern void push_switch (tree);
|
||||||
extern void pop_switch (void);
|
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 tree make_anon_name (void);
|
||||||
extern int decls_match (tree, tree);
|
extern int decls_match (tree, tree);
|
||||||
extern tree duplicate_decls (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
|
void f(class C); // No template header here
|
||||||
|
|
||||||
then the required template argument is missing. */
|
then the required template argument is missing. */
|
||||||
|
|
||||||
error ("template argument required for %<%s %T%>",
|
error ("template argument required for %<%s %T%>",
|
||||||
tag_name (tag_code),
|
tag_name (tag_code),
|
||||||
DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
|
DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
|
||||||
|
@ -9104,7 +9103,19 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
|
||||||
tree t;
|
tree t;
|
||||||
tree decl;
|
tree decl;
|
||||||
if (scope == ts_global)
|
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
|
else
|
||||||
decl = lookup_type_scope (name, scope);
|
decl = lookup_type_scope (name, scope);
|
||||||
|
|
||||||
|
@ -9264,8 +9275,7 @@ xref_tag (enum tag_types tag_code, tree name,
|
||||||
{
|
{
|
||||||
t = make_aggr_type (code);
|
t = make_aggr_type (code);
|
||||||
TYPE_CONTEXT (t) = context;
|
TYPE_CONTEXT (t) = context;
|
||||||
/* pushtag only cares whether SCOPE is zero or not. */
|
t = pushtag (name, t, scope);
|
||||||
t = pushtag (name, t, scope != ts_current);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -9279,6 +9289,20 @@ xref_tag (enum tag_types tag_code, tree name,
|
||||||
error ("redeclaration of %qT as a non-template", t);
|
error ("redeclaration of %qT as a non-template", t);
|
||||||
t = error_mark_node;
|
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);
|
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
|
||||||
|
@ -9520,7 +9544,7 @@ start_enum (tree name)
|
||||||
name = make_anon_name ();
|
name = make_anon_name ();
|
||||||
|
|
||||||
enumtype = make_node (ENUMERAL_TYPE);
|
enumtype = make_node (ENUMERAL_TYPE);
|
||||||
enumtype = pushtag (name, enumtype, 0);
|
enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
return enumtype;
|
return enumtype;
|
||||||
|
|
|
@ -3296,12 +3296,13 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
|
||||||
case TEMPLATE_DECL:
|
case TEMPLATE_DECL:
|
||||||
/* If we expect types or namespaces, and not templates,
|
/* If we expect types or namespaces, and not templates,
|
||||||
or this is not a template class. */
|
or this is not a template class. */
|
||||||
if (LOOKUP_QUALIFIERS_ONLY (flags)
|
if ((LOOKUP_QUALIFIERS_ONLY (flags)
|
||||||
&& !DECL_CLASS_TEMPLATE_P (val))
|
&& !DECL_CLASS_TEMPLATE_P (val))
|
||||||
|
|| hidden_name_p (val))
|
||||||
val = NULL_TREE;
|
val = NULL_TREE;
|
||||||
break;
|
break;
|
||||||
case TYPE_DECL:
|
case TYPE_DECL:
|
||||||
if (LOOKUP_NAMESPACES_ONLY (flags))
|
if (LOOKUP_NAMESPACES_ONLY (flags) || hidden_name_p (val))
|
||||||
val = NULL_TREE;
|
val = NULL_TREE;
|
||||||
break;
|
break;
|
||||||
case NAMESPACE_DECL:
|
case NAMESPACE_DECL:
|
||||||
|
@ -3310,7 +3311,7 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
|
||||||
break;
|
break;
|
||||||
case FUNCTION_DECL:
|
case FUNCTION_DECL:
|
||||||
/* Ignore built-in functions that are still anticipated. */
|
/* 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;
|
val = NULL_TREE;
|
||||||
break;
|
break;
|
||||||
default:
|
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
|
/* 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)
|
qualify_lookup (tree val, int flags)
|
||||||
{
|
{
|
||||||
if (val == NULL_TREE)
|
if (val == NULL_TREE)
|
||||||
return val;
|
return false;
|
||||||
if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
|
if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
|
||||||
return val;
|
return true;
|
||||||
if ((flags & LOOKUP_PREFER_TYPES)
|
if ((flags & LOOKUP_PREFER_TYPES)
|
||||||
&& (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
|
&& (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
|
||||||
return val;
|
return true;
|
||||||
if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
|
if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
|
||||||
return NULL_TREE;
|
return false;
|
||||||
return val;
|
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. */
|
/* 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))
|
if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
|
||||||
val = OVL_FUNCTION (val);
|
val = OVL_FUNCTION (val);
|
||||||
|
|
||||||
/* Ignore built-in functions that haven't been prototyped yet. */
|
/* Ignore built-in functions and friends that haven't been declared
|
||||||
if (!val || !DECL_P(val)
|
yet. */
|
||||||
|| !DECL_LANG_SPECIFIC(val)
|
if (!val || !hidden_name_p (val))
|
||||||
|| !DECL_ANTICIPATED (val))
|
|
||||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
|
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3529,10 +3543,8 @@ unqualified_namespace_lookup (tree name, int flags)
|
||||||
|
|
||||||
if (b)
|
if (b)
|
||||||
{
|
{
|
||||||
if (b->value && DECL_P (b->value)
|
if (b->value && hidden_name_p (b->value))
|
||||||
&& DECL_LANG_SPECIFIC (b->value)
|
/* Ignore anticipated built-in functions and friends. */
|
||||||
&& DECL_ANTICIPATED (b->value))
|
|
||||||
/* Ignore anticipated built-in functions. */
|
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
binding.value = b->value;
|
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
|
node of some kind representing its definition if there is only one
|
||||||
such declaration, or return a TREE_LIST with all the overloaded
|
such declaration, or return a TREE_LIST with all the overloaded
|
||||||
definitions if there are many, or return 0 if it is undefined.
|
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 > 0, we prefer TYPE_DECLs or namespaces.
|
||||||
If PREFER_TYPE is > 1, we reject non-type decls (e.g. 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;
|
continue;
|
||||||
|
|
||||||
/* If this is the kind of thing we're looking for, we're done. */
|
/* 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;
|
binding = iter->value;
|
||||||
else if ((flags & LOOKUP_PREFER_TYPES)
|
else if ((flags & LOOKUP_PREFER_TYPES)
|
||||||
&& qualify_lookup (iter->type, flags))
|
&& qualify_lookup (iter->type, flags)
|
||||||
|
&& !hidden_name_p (iter->type))
|
||||||
binding = iter->type;
|
binding = iter->type;
|
||||||
else
|
else
|
||||||
binding = NULL_TREE;
|
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
|
Unlike lookup_name_real, we make sure that NAME is actually
|
||||||
declared in the desired scope, not from inheritance, nor using
|
declared in the desired scope, not from inheritance, nor using
|
||||||
directive. For using declaration, there is DR138 still waiting
|
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
|
A TYPE_DECL best matching the NAME is returned. Catching error
|
||||||
and issuing diagnostics are caller's responsibility. */
|
and issuing diagnostics are caller's responsibility. */
|
||||||
|
@ -3948,9 +3965,7 @@ lookup_type_scope (tree name, tag_scope scope)
|
||||||
|
|
||||||
if (iter)
|
if (iter)
|
||||||
{
|
{
|
||||||
/* If this is the kind of thing we're looking for, we're done.
|
/* 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 (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES))
|
if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES))
|
||||||
val = iter->type;
|
val = iter->type;
|
||||||
else if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
|
else if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
|
||||||
|
@ -4500,7 +4515,7 @@ push_using_directive (tree used)
|
||||||
processing. */
|
processing. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
maybe_process_template_type_declaration (tree type, int globalize,
|
maybe_process_template_type_declaration (tree type, int is_friend,
|
||||||
cxx_scope *b)
|
cxx_scope *b)
|
||||||
{
|
{
|
||||||
tree decl = TYPE_NAME (type);
|
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. */
|
push_template_decl_real, but we want the original value. */
|
||||||
tree name = DECL_NAME (decl);
|
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
|
/* If the current binding level is the binding level for the
|
||||||
template parameters (see the comment in
|
template parameters (see the comment in
|
||||||
begin_template_parm_list) and the enclosing level is a class
|
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 case, push_template_decl will already have put the
|
||||||
friend into global scope, if appropriate. */
|
friend into global scope, if appropriate. */
|
||||||
if (TREE_CODE (type) != ENUMERAL_TYPE
|
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)
|
&& b->level_chain->kind == sk_class)
|
||||||
{
|
{
|
||||||
finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
|
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. */
|
Returns TYPE upon success and ERROR_MARK_NODE otherwise. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
pushtag (tree name, tree type, int globalize)
|
pushtag (tree name, tree type, tag_scope scope)
|
||||||
{
|
{
|
||||||
struct cp_binding_level *b;
|
struct cp_binding_level *b;
|
||||||
|
|
||||||
|
@ -4580,7 +4595,7 @@ pushtag (tree name, tree type, int globalize)
|
||||||
template is instantiated. */
|
template is instantiated. */
|
||||||
|| (b->kind == sk_template_parms && b->explicit_spec_p)
|
|| (b->kind == sk_template_parms && b->explicit_spec_p)
|
||||||
|| (b->kind == sk_class
|
|| (b->kind == sk_class
|
||||||
&& (globalize
|
&& (scope != ts_current
|
||||||
/* We may be defining a new type in the initializer
|
/* We may be defining a new type in the initializer
|
||||||
of a static member variable. We allow this when
|
of a static member variable. We allow this when
|
||||||
not pedantic, and it is particularly useful for
|
not pedantic, and it is particularly useful for
|
||||||
|
@ -4601,7 +4616,7 @@ pushtag (tree name, tree type, int globalize)
|
||||||
{
|
{
|
||||||
tree cs = current_scope ();
|
tree cs = current_scope ();
|
||||||
|
|
||||||
if (! globalize)
|
if (scope == ts_current)
|
||||||
context = cs;
|
context = cs;
|
||||||
else if (cs != NULL_TREE && TYPE_P (cs))
|
else if (cs != NULL_TREE && TYPE_P (cs))
|
||||||
/* When declaring a friend class of a local class, we want
|
/* 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);
|
d = create_implicit_typedef (name, type);
|
||||||
DECL_CONTEXT (d) = FROB_CONTEXT (context);
|
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)
|
if (! in_class)
|
||||||
set_identifier_type_value_with_scope (name, d, b);
|
set_identifier_type_value_with_scope (name, d, b);
|
||||||
|
|
||||||
d = maybe_process_template_type_declaration (type,
|
d = maybe_process_template_type_declaration
|
||||||
globalize, b);
|
(type, scope == ts_within_enclosing_non_class, b);
|
||||||
if (d == error_mark_node)
|
if (d == error_mark_node)
|
||||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, 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 lookup_type_scope (tree, tag_scope);
|
||||||
extern tree namespace_binding (tree, tree);
|
extern tree namespace_binding (tree, tree);
|
||||||
extern void set_namespace_binding (tree, 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_namespace_name (tree, tree);
|
||||||
extern tree lookup_qualified_name (tree, tree, bool, bool);
|
extern tree lookup_qualified_name (tree, tree, bool, bool);
|
||||||
extern tree lookup_name_nonclass (tree);
|
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 the lookup failed, let our caller know. */
|
||||||
if (!decl
|
if (!decl || decl == error_mark_node)
|
||||||
|| decl == error_mark_node
|
|
||||||
|| (TREE_CODE (decl) == FUNCTION_DECL
|
|
||||||
&& DECL_ANTICIPATED (decl)))
|
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
|
|
||||||
/* If it's a TREE_LIST, the result of the lookup was ambiguous. */
|
/* 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);
|
tmpl = pushdecl_namespace_level (tmpl);
|
||||||
if (tmpl == error_mark_node)
|
if (tmpl == error_mark_node)
|
||||||
return 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)
|
if (primary)
|
||||||
|
@ -4629,7 +4636,7 @@ lookup_template_class (tree d1,
|
||||||
|
|
||||||
/* A local class. Make sure the decl gets registered properly. */
|
/* A local class. Make sure the decl gets registered properly. */
|
||||||
if (context == current_function_decl)
|
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
|
/* If we called start_enum or pushtag above, this information
|
||||||
|
@ -5679,7 +5686,7 @@ instantiate_class_template (tree type)
|
||||||
tsubst_enum. */
|
tsubst_enum. */
|
||||||
if (name)
|
if (name)
|
||||||
SET_IDENTIFIER_TYPE_VALUE (name, newtag);
|
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
|
else if (TREE_CODE (t) == FUNCTION_DECL
|
||||||
|
|
|
@ -113,7 +113,7 @@ init_rtti_processing (void)
|
||||||
|
|
||||||
push_namespace (std_identifier);
|
push_namespace (std_identifier);
|
||||||
type_info_type = xref_tag (class_type, get_identifier ("type_info"),
|
type_info_type = xref_tag (class_type, get_identifier ("type_info"),
|
||||||
/*tag_scope=*/ts_global, false);
|
/*tag_scope=*/ts_current, false);
|
||||||
pop_namespace ();
|
pop_namespace ();
|
||||||
const_type_info_type_node
|
const_type_info_type_node
|
||||||
= build_qualified_type (type_info_type, TYPE_QUAL_CONST);
|
= 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);
|
push_nested_namespace (ns);
|
||||||
tinfo_ptr = xref_tag (class_type,
|
tinfo_ptr = xref_tag (class_type,
|
||||||
get_identifier ("__class_type_info"),
|
get_identifier ("__class_type_info"),
|
||||||
/*tag_scope=*/ts_global, false);
|
/*tag_scope=*/ts_current, false);
|
||||||
|
|
||||||
tinfo_ptr = build_pointer_type
|
tinfo_ptr = build_pointer_type
|
||||||
(build_qualified_type
|
(build_qualified_type
|
||||||
|
@ -805,7 +805,7 @@ tinfo_base_init (tree desc, tree target)
|
||||||
|
|
||||||
push_nested_namespace (abi_node);
|
push_nested_namespace (abi_node);
|
||||||
real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
|
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);
|
pop_nested_namespace (abi_node);
|
||||||
|
|
||||||
if (!COMPLETE_TYPE_P (real_type))
|
if (!COMPLETE_TYPE_P (real_type))
|
||||||
|
@ -1337,7 +1337,7 @@ emit_support_tinfos (void)
|
||||||
push_nested_namespace (abi_node);
|
push_nested_namespace (abi_node);
|
||||||
bltn_type = xref_tag (class_type,
|
bltn_type = xref_tag (class_type,
|
||||||
get_identifier ("__fundamental_type_info"),
|
get_identifier ("__fundamental_type_info"),
|
||||||
/*tag_scope=*/ts_global, false);
|
/*tag_scope=*/ts_current, false);
|
||||||
pop_nested_namespace (abi_node);
|
pop_nested_namespace (abi_node);
|
||||||
if (!COMPLETE_TYPE_P (bltn_type))
|
if (!COMPLETE_TYPE_P (bltn_type))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -2122,7 +2122,7 @@ begin_class_definition (tree t)
|
||||||
if (t == error_mark_node || ! IS_AGGR_TYPE (t))
|
if (t == error_mark_node || ! IS_AGGR_TYPE (t))
|
||||||
{
|
{
|
||||||
t = make_aggr_type (RECORD_TYPE);
|
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. */
|
/* Update the location of the decl. */
|
||||||
|
@ -2131,7 +2131,7 @@ begin_class_definition (tree t)
|
||||||
if (TYPE_BEING_DEFINED (t))
|
if (TYPE_BEING_DEFINED (t))
|
||||||
{
|
{
|
||||||
t = make_aggr_type (TREE_CODE (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);
|
maybe_process_partial_specialization (t);
|
||||||
pushclass (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>
|
2005-03-13 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
PR c++/20157
|
PR c++/20157
|
||||||
|
|
|
@ -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" }
|
||||||
|
};
|
|
@ -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;
|
|
@ -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;
|
||||||
|
};
|
|
@ -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;
|
|
@ -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" }
|
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -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" }
|
|
@ -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" }
|
||||||
|
};
|
|
@ -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" }
|
|
@ -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" }
|
||||||
|
};
|
|
@ -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" }
|
||||||
|
};
|
|
@ -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" }
|
|
@ -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" }
|
|
@ -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;
|
||||||
|
};
|
|
@ -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" }
|
|
@ -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;
|
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -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" }
|
|
@ -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" }
|
||||||
|
};
|
|
@ -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