aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2002-02-07 19:49:10 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2002-02-07 19:49:10 +0000
commitd5614afb57da11705ce88e6646bcd33ef67eb8ab (patch)
treeb7a3a796913e016fb175553b89fc5c74f709db2e /gcc
parent5d65aeb7e4432949ff6198d06b37c3ac1c58f1b7 (diff)
downloadgcc-d5614afb57da11705ce88e6646bcd33ef67eb8ab.zip
gcc-d5614afb57da11705ce88e6646bcd33ef67eb8ab.tar.gz
gcc-d5614afb57da11705ce88e6646bcd33ef67eb8ab.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/decl.c16
-rw-r--r--gcc/cp/decl2.c4
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/template/friend4.C46
6 files changed, 76 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5c463a7..f443253 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c1c254d..6fd9890 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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))
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 7a9a21ed..0cbb321 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5084f72..9e5b20c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 635223e..693b9a9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/template/friend4.C b/gcc/testsuite/g++.dg/template/friend4.C
new file mode 100644
index 0000000..9cd3810
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend4.C
@@ -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;
+}