cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): New macro.
authorMark Mitchell <mark@markmitchell.com>
Tue, 1 Sep 1998 13:08:44 +0000 (13:08 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 1 Sep 1998 13:08:44 +0000 (13:08 +0000)
* 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
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.pt/friend33.C [new file with mode: 0644]

index 665f35d01559b0ff9cf0c75409da1f730441a498..c19dcd7e272c9fb8916dc3d63cfeed520e0e47be 100644 (file)
@@ -1,3 +1,9 @@
+1998-09-01  Mark Mitchell  <mark@markmitchell.com>
+
+       * 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  <jason@yorick.cygnus.com>
 
        * decl.c (lookup_name_real): Also do implicit typename thing for
index 096617a5aa4c2b44b43054dac29acae9b478beaa..19d14fd754d8c6b928b61956e96f4dbffd5b1ace 100644 (file)
@@ -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 <class T> struct S { friend void f(T) {}; };
+   the declaration of `void f(int)' generated when S<int> 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.  */
index 7d54deca6f6534b49934fcb85bfe9c61344211a1..1359475f4860c4266a281b796fd12f9013a6bc17 100644 (file)
@@ -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))
index aadd36d6c715f960bd492d333343689b3c55d547..f557d04b56b35eab2a59a6e61ebf036876d13d2d 100644 (file)
@@ -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 (file)
index 0000000..5feec1a
--- /dev/null
@@ -0,0 +1,28 @@
+// Build don't run:
+// Special g++ Options: -g
+
+template <class P1>
+struct S1
+{
+  struct SS1
+  {
+  };
+  friend void Foo (const SS1& ss1)
+    {
+    }
+};
+
+template <class P1>
+void Foo(const S1<P1>& s1)
+{
+  typedef typename S1<P1>::SS1 TYPE;
+  TYPE t;
+  Foo(t);
+}
+
+int main ()
+{
+  S1<double> obj;
+  Foo(obj);
+}
+