aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1998-09-01 13:08:44 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-09-01 13:08:44 +0000
commit61289ca3b2138024652663c1e547e61f14ffa6f9 (patch)
tree31c7a2ef347a8bcf594e7e004563551c5beb6079 /gcc
parent2c2b32dc364221b254133fd364ca47ea15e07ba5 (diff)
downloadgcc-61289ca3b2138024652663c1e547e61f14ffa6f9.zip
gcc-61289ca3b2138024652663c1e547e61f14ffa6f9.tar.gz
gcc-61289ca3b2138024652663c1e547e61f14ffa6f9.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h10
-rw-r--r--gcc/cp/decl2.c6
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/friend33.C28
5 files changed, 49 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 665f35d..c19dcd7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 096617a..19d14fd 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 <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. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 7d54dec..1359475 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 aadd36d..f557d04 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 0000000..5feec1a
--- /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 <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);
+}
+