diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2002-02-07 19:49:10 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2002-02-07 19:49:10 +0000 |
commit | d5614afb57da11705ce88e6646bcd33ef67eb8ab (patch) | |
tree | b7a3a796913e016fb175553b89fc5c74f709db2e /gcc | |
parent | 5d65aeb7e4432949ff6198d06b37c3ac1c58f1b7 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/decl.c | 16 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/friend4.C | 46 |
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; +} |