From 61289ca3b2138024652663c1e547e61f14ffa6f9 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 1 Sep 1998 13:08:44 +0000 Subject: [PATCH] cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): New macro. * cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): New macro. * decl2.c (import_export_decl): Likewise. * pt.c (instantiate_decl): Use it. From-SVN: r22160 --- gcc/cp/ChangeLog | 6 +++++ gcc/cp/cp-tree.h | 10 +++++++ gcc/cp/decl2.c | 6 +++-- gcc/cp/pt.c | 3 +-- gcc/testsuite/g++.old-deja/g++.pt/friend33.C | 28 ++++++++++++++++++++ 5 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/friend33.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 665f35d0155..c19dcd7e272 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +1998-09-01 Mark Mitchell + + * cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): New macro. + * decl2.c (import_export_decl): Likewise. + * pt.c (instantiate_decl): Use it. + 1998-09-01 Jason Merrill * decl.c (lookup_name_real): Also do implicit typename thing for diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 096617a5aa4..19d14fd754d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1724,6 +1724,16 @@ extern int flag_new_for_scope; #define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ (CLASSTYPE_USE_TEMPLATE(NODE) = 3) +/* Non-zero if DECL is a friend function which is an instantiation + from the point of view of the compiler, but not from the point of + view of the language. For example given: + template struct S { friend void f(T) {}; }; + the declaration of `void f(int)' generated when S is + instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be + a DECL_FRIEND_PSUEDO_TEMPLATE_INSTANTIATION. */ +#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \ + (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL)) + /* Non-zero iff we are currently processing a declaration for an entity with its own template parameter list, and which is not a full specialization. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 7d54deca6f6..1359475f486 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2837,10 +2837,12 @@ import_export_decl (decl) if (DECL_INTERFACE_KNOWN (decl)) return; - if (DECL_TEMPLATE_INSTANTIATION (decl)) + if (DECL_TEMPLATE_INSTANTIATION (decl) + || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) { DECL_NOT_REALLY_EXTERN (decl) = 1; - if (DECL_IMPLICIT_INSTANTIATION (decl) + if ((DECL_IMPLICIT_INSTANTIATION (decl) + || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) && (flag_implicit_templates || DECL_THIS_INLINE (decl))) { if (!TREE_PUBLIC (decl)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index aadd36d6c71..f557d04b56b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7939,8 +7939,7 @@ instantiate_decl (d) we don't need to look any further. That's what the check for DECL_INITIAL is for. */ || (TREE_CODE (d) == FUNCTION_DECL - && DECL_TEMPLATE_INFO (td) - && !DECL_TEMPLATE_SPECIALIZATION (td) + && DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (td) && !DECL_INITIAL (DECL_TEMPLATE_RESULT (td))); ) { diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend33.C b/gcc/testsuite/g++.old-deja/g++.pt/friend33.C new file mode 100644 index 00000000000..5feec1a06d7 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/friend33.C @@ -0,0 +1,28 @@ +// Build don't run: +// Special g++ Options: -g + +template +struct S1 +{ + struct SS1 + { + }; + friend void Foo (const SS1& ss1) + { + } +}; + +template +void Foo(const S1& s1) +{ + typedef typename S1::SS1 TYPE; + TYPE t; + Foo(t); +} + +int main () +{ + S1 obj; + Foo(obj); +} + -- 2.30.2