diff options
Diffstat (limited to 'test/CXX/temp')
-rw-r--r-- | test/CXX/temp/temp.decls/temp.class.spec/p6.cpp | 39 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.friend/p5.cpp | 2 | ||||
-rw-r--r-- | test/CXX/temp/temp.param/p14.cpp | 2 | ||||
-rw-r--r-- | test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp | 2 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp | 3 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p10.cpp | 33 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p12.cpp | 6 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p3.cpp | 14 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p5.cpp | 17 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p6.cpp | 14 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p7.cpp | 36 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p8.cpp | 27 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp | 66 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p9.cpp | 59 |
14 files changed, 306 insertions, 14 deletions
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp index afe6ab2b968e..79d6c54e29f0 100644 --- a/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp +++ b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp @@ -1,5 +1,6 @@ // RUN: clang-cc -fsyntax-only -verify %s +// Test class template partial specializations of member templates. template<typename T> struct X0 { template<typename U> struct Inner0 { @@ -16,5 +17,39 @@ struct X0<T>::Inner0<const U*> { static const unsigned value = 2; }; -// FIXME: Test instantiation of these partial specializations (once they are -// implemented). +int array0[X0<int>::Inner0<int>::value == 0? 1 : -1]; +int array1[X0<int>::Inner0<int*>::value == 1? 1 : -1]; +int array2[X0<int>::Inner0<const int*>::value == 2? 1 : -1]; + +// Make sure we can provide out-of-line class template partial specializations +// for member templates (and instantiate them). +template<class T> struct A { + struct C { + template<class T2> struct B; + }; +}; + +// partial specialization of A<T>::C::B<T2> +template<class T> template<class T2> struct A<T>::C::B<T2*> { }; + +A<short>::C::B<int*> absip; + +// Check for conflicts during template instantiation. +template<typename T, typename U> +struct Outer { + template<typename X, typename Y> struct Inner; + template<typename Y> struct Inner<T, Y> {}; // expected-note{{previous}} + template<typename Y> struct Inner<U, Y> {}; // expected-error{{cannot be redeclared}} +}; + +Outer<int, int> outer; // expected-note{{instantiation}} + +// Test specialization of class template partial specialization members. +template<> template<typename Z> +struct X0<float>::Inner0<Z*> { + static const unsigned value = 3; +}; + +int array3[X0<float>::Inner0<int>::value == 0? 1 : -1]; +int array4[X0<float>::Inner0<int*>::value == 3? 1 : -1]; +int array5[X0<float>::Inner0<const int*>::value == 2? 1 : -1]; diff --git a/test/CXX/temp/temp.decls/temp.friend/p5.cpp b/test/CXX/temp/temp.decls/temp.friend/p5.cpp index f1142a4129b2..74895c490623 100644 --- a/test/CXX/temp/temp.decls/temp.friend/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.friend/p5.cpp @@ -9,3 +9,5 @@ class B { template <class T> friend class A<T>::Member; }; +A<int> a; +B b; diff --git a/test/CXX/temp/temp.param/p14.cpp b/test/CXX/temp/temp.param/p14.cpp index 07e6bfe40983..150e0ad636be 100644 --- a/test/CXX/temp/temp.param/p14.cpp +++ b/test/CXX/temp/temp.param/p14.cpp @@ -1,5 +1,5 @@ // RUN: clang-cc -fsyntax-only -verify %s -// XFAIL +// XFAIL: * // A template-parameter shall not be used in its own default argument. template<typename T = typename T::type> struct X; // expected-error{{default}} diff --git a/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp b/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp index 650501069cc5..a41b46ff5c9b 100644 --- a/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp +++ b/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp @@ -1,5 +1,5 @@ // RUN: clang-cc -fsyntax-only -verify %s -// XFAIL +// XFAIL: * // Note: we fail this test because we perform template instantiation // at the end of the translation unit, so argument-dependent lookup diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp index 2bd1400faefb..33fb93bacfaf 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp @@ -4,8 +4,7 @@ namespace N { template<class T> class X; } -// FIXME: this diagnostic is terrible (PR3844). -template<> class X<int> { /* ... */ }; // expected-error {{unqualified-id}} +template<> class X<int> { /* ... */ }; // expected-error {{non-template class 'X'}} namespace N { diff --git a/test/CXX/temp/temp.spec/temp.explicit/p10.cpp b/test/CXX/temp/temp.spec/temp.explicit/p10.cpp new file mode 100644 index 000000000000..900b0b309277 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p10.cpp @@ -0,0 +1,33 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X0 { + void f(T&); + + struct Inner; + + static T static_var; +}; + +template<typename T> +void X0<T>::f(T& t) { + t = 1; // expected-error{{incompatible type}} +} + +template<typename T> +struct X0<T>::Inner { + T member; +}; + +template<typename T> +T X0<T>::static_var = 1; // expected-error{{incompatible type}} + +extern template struct X0<void*>; +template struct X0<void*>; // expected-note 2{{instantiation}} + +template struct X0<int>; // expected-note 4{{explicit instantiation definition is here}} + +extern template void X0<int>::f(int&); // expected-error{{follows explicit instantiation definition}} +extern template struct X0<int>::Inner; // expected-error{{follows explicit instantiation definition}} +extern template int X0<int>::static_var; // expected-error{{follows explicit instantiation definition}} +extern template struct X0<int>; // expected-error{{follows explicit instantiation definition}} diff --git a/test/CXX/temp/temp.spec/temp.explicit/p12.cpp b/test/CXX/temp/temp.spec/temp.explicit/p12.cpp new file mode 100644 index 000000000000..fdf4393d4385 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p12.cpp @@ -0,0 +1,6 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +char* p = 0; +template<class T> T g(T x = &p) { return x; } +template int g<int>(int); // OK even though &p isn’t an int. + diff --git a/test/CXX/temp/temp.spec/temp.explicit/p3.cpp b/test/CXX/temp/temp.spec/temp.explicit/p3.cpp index 2bd781bbed28..9057971a5bb4 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p3.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p3.cpp @@ -9,15 +9,13 @@ template void f0(int); // okay // template shall be in scope at the point of the explicit instantiation of // the member function template. struct X0; // expected-note 2{{forward declaration}} -template<typename> struct X1; // expected-note 2{{declared here}} \ - // expected-note 3{{forward declaration}} +template<typename> struct X1; // expected-note 5{{declared here}} // FIXME: Repeated diagnostics here! template void X0::f0<int>(int); // expected-error 2{{incomplete type}} \ - // expected-error{{invalid token after}} -template void X1<int>::f0<int>(int); // expected-error{{implicit instantiation of undefined template}} \ - // expected-error{{incomplete type}} \\ - // expected-error{{invalid token}} + // expected-error{{does not refer}} +template void X1<int>::f0<int>(int); // expected-error 2{{implicit instantiation of undefined template}} \ + // expected-error{{does not refer}} // A definition of a class template or class member template shall be in scope // at the point of the explicit instantiation of the class template or class @@ -37,10 +35,10 @@ template struct X2<int>::Inner<float>; // expected-error{{explicit instantiation // A definition of a class template shall be in scope at the point of an // explicit instantiation of a member function or a static data member of the // class template. -template void X1<int>::f1(int); // expected-error{{incomplete type}} \ +template void X1<int>::f1(int); // expected-error{{undefined template}} \ // expected-error{{does not refer}} -template int X1<int>::member; // expected-error{{incomplete type}} \ +template int X1<int>::member; // expected-error{{undefined template}} \ // expected-error{{does not refer}} // A definition of a member class of a class template shall be in scope at the diff --git a/test/CXX/temp/temp.spec/temp.explicit/p5.cpp b/test/CXX/temp/temp.spec/temp.explicit/p5.cpp new file mode 100644 index 000000000000..a992648d7c48 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p5.cpp @@ -0,0 +1,17 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace N { + template<class T> class Y { // expected-note{{explicit instantiation refers here}} + void mf() { } + }; +} + +template class Z<int>; // expected-error{{explicit instantiation of non-template class 'Z'}} + +// FIXME: This example from the standard is wrong; note posted to CWG reflector +// on 10/27/2009 +using N::Y; +template class Y<int>; // expected-error{{must occur in}} + +template class N::Y<char*>; +template void N::Y<double>::mf(); diff --git a/test/CXX/temp/temp.spec/temp.explicit/p6.cpp b/test/CXX/temp/temp.spec/temp.explicit/p6.cpp new file mode 100644 index 000000000000..763d679db7bb --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p6.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<class T> class Array { /* ... */ }; +template<class T> void sort(Array<T>& v) { } + +// instantiate sort(Array<int>&) - template-argument deduced +template void sort<>(Array<int>&); + +template void sort(Array<long>&); + +template<typename T, typename U> void f0(T, U*) { } + +template void f0<int>(int, float*); +template void f0<>(double, float*); diff --git a/test/CXX/temp/temp.spec/temp.explicit/p7.cpp b/test/CXX/temp/temp.spec/temp.explicit/p7.cpp new file mode 100644 index 000000000000..ffd653dbaa4f --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p7.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X0 { + struct MemberClass { + T member; // expected-error{{with function type}} + }; + + T* f0(T* ptr) { + return ptr + 1; // expected-error{{pointer to function}} + } + + static T* static_member; +}; + +template<typename T> +T* X0<T>::static_member = ((T*)0) + 1; // expected-error{{pointer to function}} + +template class X0<int>; // okay + +template class X0<int(int)>; // expected-note 3{{requested here}} + +// Specialize everything, so that the explicit instantiation does not trigger +// any diagnostics. +template<> +struct X0<int(long)>::MemberClass { }; + +typedef int int_long_func(long); +template<> +int_long_func *X0<int_long_func>::f0(int_long_func *) { return 0; } + +template<> +int_long_func *X0<int(long)>::static_member; + +template class X0<int(long)>; + diff --git a/test/CXX/temp/temp.spec/temp.explicit/p8.cpp b/test/CXX/temp/temp.spec/temp.explicit/p8.cpp new file mode 100644 index 000000000000..9a5bd3245c78 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p8.cpp @@ -0,0 +1,27 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X0 { + struct MemberClass; + + T* f0(T* ptr); + + static T* static_member; +}; + +template class X0<int>; // okay +template class X0<int(int)>; // okay; nothing gets instantiated. + +template<typename T> +struct X0<T>::MemberClass { + T member; +}; + +template<typename T> +T* X0<T>::f0(T* ptr) { + return ptr + 1; +} + +template<typename T> +T* X0<T>::static_member = 0; + diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp new file mode 100644 index 000000000000..59705d8a20e7 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp @@ -0,0 +1,66 @@ +// RUN: clang-cc -emit-llvm -std=c++0x -o - %s | FileCheck %s + +template<typename T> +struct X0 { + void f(T &t) { + t = 0; + } + + void g(T &t); + + void h(T &t); + + static T static_var; +}; + +template<typename T> +inline void X0<T>::g(T & t) { + t = 0; +} + +template<typename T> +void X0<T>::h(T & t) { + t = 0; +} + +template<typename T> +T X0<T>::static_var = 0; + +extern template struct X0<int*>; + +int *&test(X0<int*> xi, int *ip) { + // CHECK: define available_externally void @_ZN2X0IPiE1fERS0_ + xi.f(ip); + // CHECK: define available_externally void @_ZN2X0IPiE1gERS0_ + xi.g(ip); + // CHECK: declare void @_ZN2X0IPiE1hERS0_ + xi.h(ip); + return X0<int*>::static_var; +} + +template<typename T> +void f0(T& t) { + t = 0; +} + +template<typename T> +inline void f1(T& t) { + t = 0; +} + +extern template void f0<>(int *&); +extern template void f1<>(int *&); + +void test_f0(int *ip, float *fp) { + // CHECK: declare void @_Z2f0IPiEvRT_ + f0(ip); + // CHECK: define linkonce_odr void @_Z2f0IPfEvRT_ + f0(fp); +} + +void test_f1(int *ip, float *fp) { + // CHECK: define available_externally void @_Z2f1IPiEvRT_ + f1(ip); + // CHECK: define linkonce_odr void @_Z2f1IPfEvRT_ + f1(fp); +} diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9.cpp new file mode 100644 index 000000000000..a53113fb969e --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p9.cpp @@ -0,0 +1,59 @@ +// RUN: clang-cc -fsyntax-only -std=c++0x -verify %s + +template<typename T> +struct X0 { + void f(T &t) { + t = 1; // expected-error{{incompatible type}} + } + + void g(T &t); + + void h(T &t); + + static T static_var; +}; + +template<typename T> +inline void X0<T>::g(T & t) { + t = 1; // expected-error{{incompatible type}} +} + +template<typename T> +void X0<T>::h(T & t) { + t = 1; +} + +template<typename T> +T X0<T>::static_var = 1; + +extern template struct X0<int*>; + +int *&test(X0<int*> xi, int *ip) { + xi.f(ip); // expected-note{{instantiation}} + xi.g(ip); // expected-note{{instantiation}} + xi.h(ip); + return X0<int*>::static_var; +} + +template<typename T> +void f0(T& t) { + t = 1; // expected-error{{incompatible type}} +} + +template<typename T> +inline void f1(T& t) { + t = 1; // expected-error 2{{incompatible type}} +} + +extern template void f0<>(int *&); +extern template void f1<>(int *&); + +void test_f0(int *ip, float *fp) { + f0(ip); + f0(fp); // expected-note{{instantiation}} +} + +void test_f1(int *ip, float *fp) { + f1(ip); // expected-note{{instantiation}} + f1(fp); // expected-note{{instantiation}} +} |