mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-18 11:40:54 +08:00
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
This commit is contained in:
parent
5d65aeb7e4
commit
d5614afb57
@ -1,3 +1,12 @@
|
||||
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)
|
||||
|
@ -1,3 +1,7 @@
|
||||
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
|
||||
|
46
gcc/testsuite/g++.dg/template/friend4.C
Normal file
46
gcc/testsuite/g++.dg/template/friend4.C
Normal file
@ -0,0 +1,46 @@
|
||||
// { 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user