diff options
Diffstat (limited to 'test/CXX/temp')
18 files changed, 493 insertions, 13 deletions
diff --git a/test/CXX/temp/temp.decls/p3.cpp b/test/CXX/temp/temp.decls/p3.cpp new file mode 100644 index 0000000..54800e4 --- /dev/null +++ b/test/CXX/temp/temp.decls/p3.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template<typename T> using A = int; +template<typename T> using A<T*> = char; // expected-error {{partial specialization of alias templates is not permitted}} +template<> using A<char> = char; // expected-error {{explicit specialization of alias templates is not permitted}} +template using A<char> = char; // expected-error {{explicit instantiation of alias templates is not permitted}} +using A<char> = char; // expected-error {{name defined in alias declaration must be an identifier}} diff --git a/test/CXX/temp/temp.decls/temp.alias/p1.cpp b/test/CXX/temp/temp.decls/temp.alias/p1.cpp new file mode 100644 index 0000000..80079b3 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.alias/p1.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template<typename T> using U = T; + +// The name of the alias template is a template-name. +U<char> x; +void f(U<int>); +typedef U<U<U<U<int>>>> I; diff --git a/test/CXX/temp/temp.decls/temp.alias/p2.cpp b/test/CXX/temp/temp.decls/temp.alias/p2.cpp new file mode 100644 index 0000000..e145727 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.alias/p2.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template<typename T> using U = T; + +using I = U<U<U<U<int>>>>; +using I = int; + +template<typename A, typename B> using Fst = A; +template<typename A, typename B> using Snd = B; + +using I = Fst<Snd<char,int>,double>; + +namespace StdExample { + // Prerequisites for example. + template<class T, class A> struct vector { /* ... */ }; + + + template<class T> struct Alloc {}; + template<class T> using Vec = vector<T, Alloc<T>>; + Vec<int> v; + + template<class T> + void process(Vec<T>& v) // expected-note {{previous definition is here}} + { /* ... */ } + + template<class T> + void process(vector<T, Alloc<T>>& w) // expected-error {{redefinition of 'process'}} + { /* ... */ } + + template<template<class> class TT> + void f(TT<int>); // expected-note {{candidate template ignored}} + + template<template<class,class> class TT> + void g(TT<int, Alloc<int>>); + + int h() { + f(v); // expected-error {{no matching function for call to 'f'}} + g(v); // OK: TT = vector + } + + + // v's type is same as vector<int, Alloc<int>>. + using VTest = vector<int, Alloc<int>>; + using VTest = decltype(v); +} diff --git a/test/CXX/temp/temp.decls/temp.alias/p3.cpp b/test/CXX/temp/temp.decls/temp.alias/p3.cpp new file mode 100644 index 0000000..2e9e55c --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.alias/p3.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +// The example given in the standard (this is rejected for other reasons anyway). +template<class T> struct A; +template<class T> using B = typename A<T>::U; // expected-error {{no type named 'U' in 'A<T>'}} +template<class T> struct A { + typedef B<T> U; // expected-note {{in instantiation of template type alias 'B' requested here}} +}; +B<short> b; + +template<typename T> using U = int; +// FIXME: This is illegal, but probably only because CWG1044 missed this paragraph. +template<typename T> using U = U<T>; diff --git a/test/CXX/temp/temp.decls/temp.friend/p3.cpp b/test/CXX/temp/temp.decls/temp.friend/p3.cpp index d116e01..0b2a25e 100644 --- a/test/CXX/temp/temp.decls/temp.friend/p3.cpp +++ b/test/CXX/temp/temp.decls/temp.friend/p3.cpp @@ -8,5 +8,5 @@ class B { template <class T> friend class A; template <class T> friend class Undeclared; - template <class T> friend typename A<T>::Member; // expected-warning {{non-class type 'typename A<T>::Member' cannot be a friend}} + template <class T> friend typename A<T>::Member; // expected-error {{friend type templates must use an elaborated type}} }; diff --git a/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp b/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp index 62cf429..7375f98 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp @@ -37,3 +37,10 @@ int f3(Args ...args) { } template int f3(const char*, int, float, double); + +template<typename ...Args> +int PR9953(Args ...args) { + return ^(Args *...block_args) { + return f1(block_args); // expected-error{{expression contains unexpanded parameter pack 'block_args'}} + }(&args...); +} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp new file mode 100644 index 0000000..d3af0d4 --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +#if !__has_feature(cxx_access_control_sfinae) +# error No support for access control as part of SFINAE? +#endif + +typedef char yes_type; +typedef char (&no_type)[2]; + +template<unsigned N> struct unsigned_c { }; + +template<typename T> +class has_copy_constructor { + static T t; + + template<typename U> static yes_type check(unsigned_c<sizeof(U(t))> * = 0); + template<typename U> static no_type check(...); + +public: + static const bool value = (sizeof(check<T>(0)) == sizeof(yes_type)); +}; + +struct HasCopy { }; + +struct HasNonConstCopy { + HasNonConstCopy(HasNonConstCopy&); +}; + +struct HasDeletedCopy { + HasDeletedCopy(const HasDeletedCopy&) = delete; +}; + +struct HasPrivateCopy { +private: + HasPrivateCopy(const HasPrivateCopy&); +}; + +int check0[has_copy_constructor<HasCopy>::value? 1 : -1]; +int check1[has_copy_constructor<HasNonConstCopy>::value? 1 : -1]; +int check2[has_copy_constructor<HasDeletedCopy>::value? -1 : 1]; +int check3[has_copy_constructor<HasPrivateCopy>::value? -1 : 1]; diff --git a/test/CXX/temp/temp.param/p10-0x.cpp b/test/CXX/temp/temp.param/p10-0x.cpp new file mode 100644 index 0000000..bc7e616 --- /dev/null +++ b/test/CXX/temp/temp.param/p10-0x.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +template<typename> struct Y1; +template<typename, int> struct Y2; + +template<class T1, class T2 = int> using B2 = T1; +template<class T1 = int, class T2> using B2 = T1; + +template<template<class> class F, template<class> class G = Y1> using B2t = F<G<int>>; +template<template<class> class F = Y2, template<class> class G> using B2t = F<G<int>>; + +template<int N, int M = 5> using B2n = Y2<int, N + M>; +template<int N = 5, int M> using B2n = Y2<int, N + M>; diff --git a/test/CXX/temp/temp.param/p11-0x.cpp b/test/CXX/temp/temp.param/p11-0x.cpp index 0bf4341..10a4438 100644 --- a/test/CXX/temp/temp.param/p11-0x.cpp +++ b/test/CXX/temp/temp.param/p11-0x.cpp @@ -1,29 +1,48 @@ // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s -// If a template-parameter of a class template has a default -// template-argument, each subsequent template-parameter shall either -// have a default template-argument supplied or be a template -// parameter pack. +// If a template-parameter of a class template or alias template has a default +// template-argument, each subsequent template-parameter shall either have a +// default template-argument supplied or be a template parameter pack. template<typename> struct vector; +template<typename T = int, typename> struct X3t; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<typename T = int, typename> using A3t = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<int V = 0, int> struct X3nt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<int V = 0, int> using A3nt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<template<class> class M = vector, template<class> class> struct X3tt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<template<class> class M = vector, template<class> class> using A3tt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} + template<typename T = int, typename ...Types> struct X2t; +template<typename T = int, typename ...Types> using A2t = X2t<T, Types...>; template<int V = 0, int ...Values> struct X2nt; +template<int V = 0, int ...Values> using A2nt = X2nt<V, Values...>; template<template<class> class M = vector, template<class> class... Metas> struct X2tt; +template<template<class> class M = vector, template<class> class... Metas> + using A2tt = X2tt<M, Metas...>; -// If a template-parameter of a primary class template is a template -// parameter pack, it shall be the last template-parameter . +// If a template-parameter of a primary class template or alias template is a +// template parameter pack, it shall be the last template-parameter. template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}} int After> struct X0t; +template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}} + int After> +using A0t = int; template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}} int After> struct X0nt; +template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}} + int After> +using A0nt = int; template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}} int After> struct X0tt; +template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}} + int After> +using A0tt = int; // [ Note: These are not requirements for function templates or class // template partial specializations because template arguments can be diff --git a/test/CXX/temp/temp.param/p9-0x.cpp b/test/CXX/temp/temp.param/p9-0x.cpp index 17eca7f..1dc6640 100644 --- a/test/CXX/temp/temp.param/p9-0x.cpp +++ b/test/CXX/temp/temp.param/p9-0x.cpp @@ -50,3 +50,12 @@ namespace PR8748 { template<typename T = int> struct Inner::X3 { }; template<typename T = int> void Inner::f2() {} } + +namespace PR10069 { + template<typename T, T a, T b=0, T c=1> + T f(T x); + + void g() { + f<unsigned int, 0>(0); + } +} diff --git a/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp b/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp new file mode 100644 index 0000000..1d1d350 --- /dev/null +++ b/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +// Examples from CWG1056. +namespace Example1 { + template<class T> struct A; + template<class T> using B = A<T>; + + template<class T> struct A { + struct C {}; + B<T>::C bc; // ok, B<T> is the current instantiation. + }; + + template<class T> struct A<A<T>> { + struct C {}; + B<B<T>>::C bc; // ok, B<B<T>> is the current instantiation. + }; + + template<class T> struct A<A<A<T>>> { + struct C {}; + B<B<T>>::C bc; // expected-error {{missing 'typename'}} + }; +} + +namespace Example2 { + template<class T> struct A { + void g(); + }; + template<class T> using B = A<T>; + template<class T> void B<T>::g() {} // ok. +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp new file mode 100644 index 0000000..f04c544 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp @@ -0,0 +1,209 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR5907 { + template<typename T> struct identity { typedef T type; }; + struct A { A(); }; + identity<A>::type::A() { } + + struct B { void f(); }; + template<typename T> struct C { typedef B type; }; + + void C<int>::type::f() { } +} + +namespace PR9421 { + namespace N { template<typename T> struct S { void f(); }; } + typedef N::S<int> T; + namespace N { template<> void T::f() {} } +} + +namespace PR8277 { + template< typename S > + struct C + { + template< int > + void F( void ) + { + } + }; + + template< typename S > + struct D + { + typedef C< int > A; + }; + + typedef D< int >::A A; + + template<> + template<> + void A::F< 0 >( void ) + { + } +} + +namespace PR8277b { + template<typename S> struct C { + void f(); + }; + template<typename S> struct D { + typedef C<int> A; + }; + template<> void D<int>::A::f() { + } +} + +namespace PR8708 { + template<typename T> struct A { + template<typename U> struct B { + // #2 + void f(); + }; + }; + + // #A specialize the member template for + // implicit instantiation of A<int>, + // leaving the member template "unspecialized" + // (14.7.3/16). Specialization uses the syntax + // for explicit specialization (14.7.3/14) + template<> template<typename U> + struct A<int>::B { + // #1 + void g(); + }; + + // #1 define its function g. There is an enclosing + // class template, so we write template<> for each + // specialized template (14.7.3/15). + template<> template<typename U> + void A<int>::B<U>::g() { } + + // #2 define the unspecialized member template's + // f + template<typename T> template<typename U> + void A<T>::B<U>::f() { } + + + // specialize the member template again, now + // specializing the member too. This specializes + // #A + template<> template<> + struct A<int>::B<int> { + // #3 + void h(); + }; + + // defines #3. There is no enclosing class template, so + // we write no "template<>". + void A<int>::B<int>::h() { } + + void test() { + // calls #1 + A<int>::B<float> a; a.g(); + + // calls #2 + A<float>::B<int> b; b.f(); + + // calls #3 + A<int>::B<int> c; c.h(); + } +} + +namespace PR9482 { + namespace N1 { + template <typename T> struct S { + void foo() {} + }; + } + + namespace N2 { + typedef N1::S<int> X; + } + + namespace N1 { + template<> void N2::X::foo() {} + } +} + +namespace PR9668 { + namespace First + { + template<class T> + class Bar + { + protected: + + static const bool static_bool; + }; + } + + namespace Second + { + class Foo; + } + + typedef First::Bar<Second::Foo> Special; + + namespace + First + { + template<> + const bool Special::static_bool(false); + } +} + +namespace PR9877 { + template<int> + struct X + { + struct Y; + }; + + template<> struct X<0>::Y { static const int Z = 1; }; + template<> struct X<1>::Y { static const int Z = 1; }; + + const int X<0>::Y::Z; + template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}} +} + +namespace PR9913 { + template<class,class=int>struct S; + template<class X>struct S<X> { + template<class T> class F; + }; + + template<class A> + template<class B> + class S<A>::F{}; +} + +namespace template_class_spec_perClassDecl_nested +{ + template <typename T1> struct A { + template <typename T2> struct B { + template <typename T3> struct C { + static void foo(); + }; + }; + }; + + template <> struct A<int> { + template <typename T2> struct B { + template <typename T3> struct C { + static void foo(); + }; + }; + }; + + template <> template <typename T3> struct A<int>::B<int>::C { + static void foo(); + }; + + template <> template <> struct A<int>::B<int>::C<int> { + static void foo(); + }; + + template <> template<> template <typename T2> struct A<bool>::B<bool>::C { + static void foo(); + }; +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp index a5ecf5fc..72f33df 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp @@ -20,3 +20,14 @@ NonDefaultConstructible &test(bool b) { return b? X<NonDefaultConstructible, int>::member // expected-note{{instantiation}} : X<NonDefaultConstructible, long>::member; } + +namespace rdar9422013 { + template<int> + struct X { + struct Inner { + static unsigned array[17]; + }; + }; + + template<> unsigned X<1>::Inner::array[]; // okay +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp index 2f9a3cb..c7597e9 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only %s +// RUN: %clang_cc1 -fsyntax-only -verify %s template<class T> struct A { void f(T); template<class X1> void g1(T, X1); @@ -24,3 +24,15 @@ template<> template<> // member specialization even if defined in class definition template<> void A<int>::h(int) { } + +namespace PR10024 { + template <typename T> + struct Test{ + template <typename U> + void get(U i) {} + }; + + template <typename T> + template <> + void Test<T>::get<double>(double i) {} // expected-error{{cannot specialize (with 'template<>') a member of an unspecialized template}} +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp index 88cfc5d..56231e2 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp @@ -24,12 +24,11 @@ namespace test1 { template <> class A<double> { public: - static int foo; // expected-note{{attempt to specialize}} + static int foo; static int bar; }; typedef A<double> AB; - template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}} \ - // expected-error{{does not specialize}} + template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}} int AB::bar = 1; } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp new file mode 100644 index 0000000..f49190e --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template<class T> struct A { + struct B { }; + template<class U> struct C { }; +}; + template<> struct A<int> { + void f(int); +}; +void h() { + A<int> a; + a.f(16); +} +// A<int>::f must be defined somewhere +// template<> not used for a member of an // explicitly specialized class template +void A<int>::f(int) { /* ... */ } + template<> struct A<char>::B { + void f(); +}; +// template<> also not used when defining a member of // an explicitly specialized member class +void A<char>::B::f() { /* ... */ } + template<> template<class U> struct A<char>::C { + void f(); +}; + +template<> +template<class U> void A<char>::C<U>::f() { /* ... */ } + template<> struct A<short>::B { + void f(); +}; +template<> void A<short>::B::f() { /* ... */ } // expected-error{{no function template matches function template specialization 'f'}} + template<> template<class U> struct A<short>::C { + void f(); +}; +template<class U> void A<short>::C<U>::f() { /* ... */ } // expected-error{{template parameter list matching the non-templated nested type 'A<short>' should be empty ('template<>')}} diff --git a/test/CXX/temp/temp.spec/temp.explicit/p2.cpp b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp index 70d338b..822f881 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p2.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s // Example from the standard template<class T> class Array { void mf() { } }; @@ -35,7 +35,7 @@ namespace N { }; template<typename T> - void f1(T) {}; // expected-note{{explicit instantiation refers here}} + void f1(T) {} // expected-note{{explicit instantiation refers here}} } using namespace N; diff --git a/test/CXX/temp/temp.type/p1-0x.cpp b/test/CXX/temp/temp.type/p1-0x.cpp new file mode 100644 index 0000000..c22af22 --- /dev/null +++ b/test/CXX/temp/temp.type/p1-0x.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +namespace Old { + template<template<class> class TT> struct X { }; + template<class> struct Y { }; + template<class T> using Z = Y<T>; + X<Y> y; + X<Z> z; + + using SameType = decltype(y); // expected-note {{here}} + using SameType = decltype(z); // expected-error {{different types}} +} + +namespace New { + template<class T> struct X { }; + template<class> struct Y { }; + template<class T> using Z = Y<T>; + X<Y<int>> y; + X<Z<int>> z; + + using SameType = decltype(y); + using SameType = decltype(z); // ok +} |