2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-04-10 10:30:53 +08:00

re PR c++/28025 (multiple template friend compile error)

PR c++/28025
	* cp-tree.h (LOOKUP_HIDDEN): New macro.  Reformat comments.
	* name-lookup.c (unqualified_namespace_lookup): There is no way to
	have a hidden name in non-namespace scopes.
	* pt.c (tsubst_friend_class): Look for hidden names.
	* decl.c (lookup_and_check_tag): Fix typo in comment.
	* semantics.c (finish_compound_literal): Fix typo in comment.
	PR c++/28025
	* g++.dg/template/friend45.C: New test.

From-SVN: r115687
This commit is contained in:
Mark Mitchell 2006-07-23 20:28:26 +00:00 committed by Mark Mitchell
parent 74e55d0f8f
commit 105d72c595
8 changed files with 88 additions and 39 deletions

@ -1,3 +1,14 @@
2006-07-23 Mark Mitchell <mark@codesourcery.com>
PR c++/28025
* cp-tree.h (LOOKUP_HIDDEN): New macro. Reformat comments.
* name-lookup.c (unqualified_namespace_lookup): There is no way to
have a hidden name in non-namespace scopes.
* pt.c (tsubst_friend_class): Look for hidden names.
* decl.c (lookup_and_check_tag): Fix typo in comment.
* semantics.c (finish_compound_literal): Fix typo in comment.
2006-07-21 Jason Merrill <jason@redhat.com>
* decl2.c (determine_visibility): Don't propagate visibility from

@ -3380,46 +3380,51 @@ extern GTY(()) tree static_dtors;
enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
/* These are uses as bits in flags passed to build_new_method_call
to control its error reporting behavior.
LOOKUP_PROTECT means flag access violations.
LOOKUP_COMPLAIN mean complain if no suitable member function
matching the arguments is found.
LOOKUP_NORMAL is just a combination of these two.
LOOKUP_NONVIRTUAL means make a direct call to the member function found
LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried.
DIRECT_BIND means that if a temporary is created, it should be created so
that it lives as long as the current variable bindings; otherwise it
only lives until the end of the complete-expression. It also forces
direct-initialization in cases where other parts of the compiler have
already generated a temporary, such as reference initialization and the
catch parameter.
LOOKUP_NO_CONVERSION means that user-defined conversions are not
permitted. Built-in conversions are permitted.
LOOKUP_DESTRUCTOR means explicit call to destructor.
LOOKUP_NO_TEMP_BIND means temporaries will not be bound to references.
These are used in global lookup to support elaborated types and
qualifiers.
LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces.
LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types.
LOOKUP_PREFER_BOTH means class-or-namespace-name. */
/* These are uses as bits in flags passed to various functions to
control their behavior. Despite the LOOKUP_ prefix, many of these
do not control name lookup. ??? Functions using these flags should
probably be modified to accept explicit boolean flags for the
behaviors relevant to them. */
/* Check for access violations. */
#define LOOKUP_PROTECT (1 << 0)
/* Complain if no suitable member function matching the arguments is
found. */
#define LOOKUP_COMPLAIN (1 << 1)
#define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN)
/* Even if the function found by lookup is a virtual function, it
should be called directly. */
#define LOOKUP_NONVIRTUAL (1 << 2)
/* Non-converting (i.e., "explicit") constructors are not tried. */
#define LOOKUP_ONLYCONVERTING (1 << 3)
/* If a temporary is created, it should be created so that it lives
as long as the current variable bindings; otherwise it only lives
until the end of the complete-expression. It also forces
direct-initialization in cases where other parts of the compiler
have already generated a temporary, such as reference
initialization and the catch parameter. */
#define DIRECT_BIND (1 << 4)
/* User-defined conversions are not permitted. (Built-in conversions
are permitted.) */
#define LOOKUP_NO_CONVERSION (1 << 5)
/* The user has explicitly called a destructor. (Therefore, we do
not need to check that the object is non-NULL before calling the
destructor.) */
#define LOOKUP_DESTRUCTOR (1 << 6)
/* Do not permit references to bind to temporaries. */
#define LOOKUP_NO_TEMP_BIND (1 << 7)
/* Do not accept objects, and possibly namespaces. */
#define LOOKUP_PREFER_TYPES (1 << 8)
/* Do not accept objects, and possibly types. */
#define LOOKUP_PREFER_NAMESPACES (1 << 9)
/* Accept types or namespaces. */
#define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
/* We are checking that a constructor can be called -- but we do not
actually plan to call it. */
#define LOOKUP_CONSTRUCTOR_CALLABLE (1 << 10)
/* Return friend decarations and un-declared builtin functions.
(Normally, these entities are registered in the symbol table, but
not found by lookup.) */
#define LOOKUP_HIDDEN (LOOKUP_CONSTRUCTOR_CALLABLE << 1)
#define LOOKUP_NAMESPACES_ONLY(F) \
(((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))

@ -9503,7 +9503,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
/* 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.
scope. So lookup again but not ignoring hidden names.
If we find one, that name will be made visible rather than
creating a new tag. */
if (!decl)

@ -3681,10 +3681,8 @@ unqualified_namespace_lookup (tree name, int flags)
if (b)
{
if (b->value && hidden_name_p (b->value))
/* Ignore anticipated built-in functions and friends. */
;
else
if (b->value
&& ((flags & LOOKUP_HIDDEN) || !hidden_name_p (b->value)))
binding.value = b->value;
binding.type = b->type;
}
@ -3987,18 +3985,18 @@ 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)
&& !hidden_name_p (iter->value))
if (qualify_lookup (iter->value, flags))
binding = iter->value;
else if ((flags & LOOKUP_PREFER_TYPES)
&& qualify_lookup (iter->type, flags)
&& !hidden_name_p (iter->type))
&& qualify_lookup (iter->type, flags))
binding = iter->type;
else
binding = NULL_TREE;
if (binding)
{
/* Only namespace-scope bindings can be hidden. */
gcc_assert (!hidden_name_p (binding));
val = binding;
break;
}

@ -5408,8 +5408,21 @@ tsubst_friend_class (tree friend_tmpl, tree args)
push_nested_class (tsubst (context, args, tf_none, NULL_TREE));
}
/* First, we look for a class template. */
tmpl = lookup_name (DECL_NAME (friend_tmpl));
/* Look for a class template declaration. We look for hidden names
because two friend declarations of the same template are the
same. For example, in:
struct A {
template <typename> friend class F;
};
template <typename> struct B {
template <typename> friend class F;
};
both F templates are the same. */
tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0,
/*block_p=*/true, 0,
LOOKUP_COMPLAIN | LOOKUP_HIDDEN);
/* But, if we don't find one, it might be because we're in a
situation like this:

@ -2058,7 +2058,7 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
DECL_NAME (var) = make_anon_name ();
}
/* We must call pushdecl, since the gimplifier complains if the
variable hase been declared via a BIND_EXPR. */
variable has not been declared via a BIND_EXPR. */
pushdecl (var);
/* Initialize the variable as we would any other variable with a
brace-enclosed initializer. */

@ -1,3 +1,8 @@
2006-07-23 Mark Mitchell <mark@codesourcery.com>
PR c++/28025
* g++.dg/template/friend45.C: New test.
2006-07-21 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/28339

@ -0,0 +1,17 @@
// PR c++/28025
class BaseSubmit
{
template<class T> friend class PeriodicSubmit;
};
template<class ID>
class ValuesSubmit
{
template<class T> friend class PeriodicSubmit;
};
class A;
class MultiSubmit : public ValuesSubmit<A>
{
};