diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-10-14 23:41:34 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-10-14 23:41:34 +0000 |
| commit | e47f5a76ccd74c13d5c319e12720275ef58a84fc (patch) | |
| tree | 604fe426fd2171a88f77f98b6758bfe5acc4a3c4 /clang/test | |
| parent | 2f61e0946a9e3fe24d102e13d02a07f44b2728ba (diff) | |
| download | bcm5719-llvm-e47f5a76ccd74c13d5c319e12720275ef58a84fc.tar.gz bcm5719-llvm-e47f5a76ccd74c13d5c319e12720275ef58a84fc.zip | |
Additional semantic checking for explicit template instantiations,
focusing on the scope- and qualifier-related semantic requirements in
C++ [temp.explicit]p2.
llvm-svn: 84154
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp | 43 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/explicit-instantiation.cpp | 21 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/temp_explicit.cpp | 1 |
3 files changed, 55 insertions, 10 deletions
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp new file mode 100644 index 00000000000..aee0e5d19d5 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp @@ -0,0 +1,43 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Example from the standard +template<class T> class Array { void mf() { } }; + +template class Array<char>; +template void Array<int>::mf(); +template<class T> void sort(Array<T>& v) { /* ... */ } +template void sort(Array<char>&); +namespace N { + template<class T> void f(T&) { } +} +template void N::f<int>(int&); + + +template<typename T> +struct X0 { + struct Inner {}; + void f() { } + static T value; +}; + +template<typename T> +T X0<T>::value = 17; + +typedef X0<int> XInt; + +template struct XInt::Inner; // expected-error{{template-id}} +template void XInt::f(); // expected-error{{template-id}} +template int XInt::value; // expected-error{{template-id}} + +namespace N { + template<typename T> + struct X1 { // expected-note{{explicit instantiation refers here}} + }; + + template<typename T> + void f1(T); // expected-note{{explicit instantiation refers here}} +} +using namespace N; + +template struct X1<int>; // expected-error{{must occur in}} +template void f1(int); // expected-error{{must occur in}} diff --git a/clang/test/SemaTemplate/explicit-instantiation.cpp b/clang/test/SemaTemplate/explicit-instantiation.cpp index b9a4ad282b9..b04639f6e78 100644 --- a/clang/test/SemaTemplate/explicit-instantiation.cpp +++ b/clang/test/SemaTemplate/explicit-instantiation.cpp @@ -14,19 +14,22 @@ struct X0 { T f0(T x) { return x + 1; // expected-error{{invalid operands}} } - T* f0(T*, T*); + T* f0(T*, T*) { return T(); } template<typename U> - T f0(T, U); + T f0(T, U) { return T(); } }; +template<typename T> +T X0<T>::value; // expected-error{{no matching constructor}} + template int X0<int>::value; struct NotDefaultConstructible { NotDefaultConstructible(int); }; -template NotDefaultConstructible X0<NotDefaultConstructible>::value; +template NotDefaultConstructible X0<NotDefaultConstructible>::value; // expected-note{{instantiation}} template int X0<int>::f0(int); template int* X0<int>::f0(int*, int*); @@ -43,11 +46,11 @@ template MemPtr X0<MemPtr>::f0(MemPtr); // expected-note{{requested here}} struct X2 { int f0(int); // expected-note{{refers here}} - template<typename T> T f1(T); - template<typename T> T* f1(T*); + template<typename T> T f1(T) { return T(); } + template<typename T> T* f1(T*) { return 0; } - template<typename T, typename U> void f2(T, U*); // expected-note{{candidate}} - template<typename T, typename U> void f2(T*, U); // expected-note{{candidate}} + template<typename T, typename U> void f2(T, U*) { } // expected-note{{candidate}} + template<typename T, typename U> void f2(T*, U) { } // expected-note{{candidate}} }; template int X2::f0(int); // expected-error{{not an instantiation}} @@ -57,12 +60,12 @@ template int *X2::f1(int *); // okay template void X2::f2(int *, int *); // expected-error{{ambiguous}} -template<typename T> void print_type(); +template<typename T> void print_type() { } template void print_type<int>(); template void print_type<float>(); -template<typename T> void print_type(T*); +template<typename T> void print_type(T*) { } template void print_type(int*); template void print_type<int>(float*); // expected-error{{does not refer}} diff --git a/clang/test/SemaTemplate/temp_explicit.cpp b/clang/test/SemaTemplate/temp_explicit.cpp index 0292964a1a7..9c824d6f414 100644 --- a/clang/test/SemaTemplate/temp_explicit.cpp +++ b/clang/test/SemaTemplate/temp_explicit.cpp @@ -15,7 +15,6 @@ template class N::X1<int>; template class ::N::X1<int, float>; using namespace N; -template class X1<float>; // Check for some bogus syntax that probably means that the user // wanted to write an explicit specialization, but forgot the '<>' |

