summaryrefslogtreecommitdiff
path: root/test/CXX/temp/temp.spec/temp.explicit
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2010-08-25 08:27:02 +0000
committerChandler Carruth <chandlerc@gmail.com>2010-08-25 08:27:02 +0000
commit58e390ef491c8fb11ae17445054ee09527b492d3 (patch)
tree4feae5dcb201c19aacc92fa153bed7092f981bc7 /test/CXX/temp/temp.spec/temp.explicit
parent384aff8b94bb0d1ad6c5667b90621e5699815bb2 (diff)
downloadclang-58e390ef491c8fb11ae17445054ee09527b492d3.tar.gz
Support explicit instantiation of function templates and members of class
templates when only the declaration is in scope. This requires deferring the instantiation to be lazy, and ensuring the definition is required for that translation unit. We re-use the existing pending instantiation queue, previously only used to track implicit instantiations which were required to be lazy. Fixes PR7979. A subsequent change will rename *PendingImplicitInstantiations to *PendingInstatiations for clarity given its broader role. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112037 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CXX/temp/temp.spec/temp.explicit')
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p3.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p3.cpp b/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
index e9758bcdec..48c42c399a 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
@@ -2,8 +2,9 @@
// A declaration of a function template shall be in scope at the point of the
// explicit instantiation of the function template.
-template<typename T> void f0(T) { }
+template<typename T> void f0(T);
template void f0(int); // okay
+template<typename T> void f0(T) { }
// A definition of the class or class template containing a member function
// template shall be in scope at the point of the explicit instantiation of
@@ -47,3 +48,27 @@ template X2<int>::X2(); // expected-error{{not an instantiation}}
template X2<int>::X2(const X2&); // expected-error{{not an instantiation}}
template X2<int>::~X2(); // expected-error{{not an instantiation}}
template X2<int> &X2<int>::operator=(const X2<int>&); // expected-error{{not an instantiation}}
+
+
+// A definition of a class template is sufficient to explicitly
+// instantiate a member of the class template which itself is not yet defined.
+namespace PR7979 {
+ template <typename T> struct S {
+ void f();
+ static void g();
+ static int i;
+ struct S2 {
+ void h();
+ };
+ };
+
+ template void S<int>::f();
+ template void S<int>::g();
+ template int S<int>::i;
+ template void S<int>::S2::h();
+
+ template <typename T> void S<T>::f() {}
+ template <typename T> void S<T>::g() {}
+ template <typename T> int S<T>::i;
+ template <typename T> void S<T>::S2::h() {}
+}