Commit d5614afb by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/109 (g++ 2.95.2 can't handle dependent friend member functions)

cp:
	PR c++/109
	* decl.c (grokdeclarator): Allow friend declarations from
	dependant types.
	* decl2.c (handle_class_head): Don't push into template parm contexts.
	* pt.c (push_template_decl_real): Template parm contexts are never
	being defined.
testsuite:
	* g++.dg/template/friend4.C: New test.

From-SVN: r49589
parent 5d65aeb7
2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
PR c++/109
* decl.c (grokdeclarator): Allow friend declarations from
dependant types.
* decl2.c (handle_class_head): Don't push into template parm contexts.
* pt.c (push_template_decl_real): Template parm contexts are never
being defined.
2002-02-05 Alexandre Oliva <aoliva@redhat.com>
* class.c: Include target.h.
......
......@@ -9612,6 +9612,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
int explicit_char = 0;
int defaulted_int = 0;
int extern_langp = 0;
tree dependant_name = NULL_TREE;
tree typedef_decl = NULL_TREE;
const char *name;
......@@ -9853,11 +9854,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM
|| TREE_CODE (cname) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
error ("`%T::%D' is not a valid declarator", cname,
TREE_OPERAND (decl, 1));
error (" perhaps you want `typename %T::%D' to make it a type",
cname, TREE_OPERAND (decl, 1));
return void_type_node;
/* This might be declaring a member of a template
parm to be a friend. */
ctype = cname;
dependant_name = TREE_OPERAND (decl, 1);
}
else if (ctype == NULL_TREE)
ctype = cname;
......@@ -10349,6 +10349,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
friendp = RIDBIT_SETP (RID_FRIEND, specbits);
RIDBIT_RESET (RID_FRIEND, specbits);
if (dependant_name && !friendp)
{
error ("`%T::%D' is not a valid declarator", ctype, dependant_name);
return void_type_node;
}
/* Warn if two storage classes are given. Default to `auto'. */
if (RIDBIT_ANY_SET (specbits))
......
......@@ -5258,7 +5258,9 @@ handle_class_head (aggr, scope, id, defn_p, new_type_p)
is different to the current scope. */
tree context = CP_DECL_CONTEXT (decl);
*new_type_p = current != context;
*new_type_p = (current != context
&& TREE_CODE (context) != TEMPLATE_TYPE_PARM
&& TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM);
if (*new_type_p)
push_scope (context);
......
......@@ -2571,7 +2571,9 @@ push_template_decl_real (decl, is_friend)
if (!ctx
|| TREE_CODE (ctx) == FUNCTION_DECL
|| TYPE_BEING_DEFINED (ctx)
|| (TREE_CODE (ctx) != TEMPLATE_TYPE_PARM
&& TREE_CODE (ctx) != BOUND_TEMPLATE_TEMPLATE_PARM
&& TYPE_BEING_DEFINED (ctx))
|| (is_friend && !DECL_TEMPLATE_INFO (decl)))
{
if (DECL_LANG_SPECIFIC (decl)
......
2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/template/friend4.C: New test.
2002-02-07 David Billinghurst <David.Billinghurst@riotinto.com>
PR fortran/3743
......
// { dg-do compile }
// Copyright (C) 2002 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 18 Dec 2001 <nathan@codesourcery.com>
// PR 109, dependant member friends
struct B
{
static int foo ();
struct N
{
static int bar ();
};
};
template <class T>
class A
{
friend int T::foo ();
friend int T::N::bar ();
private:
static int m;
};
template <class T>
class C
{
friend struct T::N;
private:
static int m;
};
int B::foo ()
{
return A<B>::m;
}
int B::N::bar ()
{
return A<B>::m + C<B>::m;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment