475 lines
10 KiB
C
475 lines
10 KiB
C
|
// Header for PCH test cxx-templates.cpp
|
||
|
|
||
|
template <typename T1, typename T2>
|
||
|
struct S;
|
||
|
|
||
|
template <typename T1, typename T2>
|
||
|
struct S {
|
||
|
S() { }
|
||
|
static void templ();
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
struct S<int, T> {
|
||
|
static void partial();
|
||
|
};
|
||
|
|
||
|
template <>
|
||
|
struct S<int, float> {
|
||
|
static void explicit_special();
|
||
|
};
|
||
|
|
||
|
template <int x>
|
||
|
int tmpl_f2() { return x; }
|
||
|
|
||
|
template <typename T, int y>
|
||
|
T templ_f(T x) {
|
||
|
int z = templ_f<int, 5>(3);
|
||
|
z = tmpl_f2<y+2>();
|
||
|
T data[y];
|
||
|
return x+y;
|
||
|
}
|
||
|
|
||
|
void govl(int);
|
||
|
void govl(char);
|
||
|
|
||
|
template <typename T>
|
||
|
struct Unresolv {
|
||
|
void f() {
|
||
|
govl(T());
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
struct Dep {
|
||
|
typedef typename T::type Ty;
|
||
|
void f() {
|
||
|
Ty x = Ty();
|
||
|
T::my_f();
|
||
|
int y = T::template my_templf<int>(0);
|
||
|
ovl(y);
|
||
|
}
|
||
|
|
||
|
void ovl(int);
|
||
|
void ovl(float);
|
||
|
};
|
||
|
|
||
|
template<typename T, typename A1>
|
||
|
inline T make_a(const A1& a1) {
|
||
|
T::depend_declref();
|
||
|
return T(a1);
|
||
|
}
|
||
|
|
||
|
template <class T> class UseBase {
|
||
|
void foo();
|
||
|
typedef int bar;
|
||
|
};
|
||
|
|
||
|
template <class T> class UseA : public UseBase<T> {
|
||
|
using UseBase<T>::foo;
|
||
|
using typename UseBase<T>::bar;
|
||
|
};
|
||
|
|
||
|
template <class T> class Sub : public UseBase<int> { };
|
||
|
|
||
|
template <class _Ret, class _Tp>
|
||
|
class mem_fun_t
|
||
|
{
|
||
|
public:
|
||
|
explicit
|
||
|
mem_fun_t(_Ret (_Tp::*__pf)())
|
||
|
{}
|
||
|
|
||
|
private:
|
||
|
_Ret (_Tp::*_M_f)();
|
||
|
};
|
||
|
|
||
|
template<unsigned N>
|
||
|
bool isInt(int x);
|
||
|
|
||
|
template<> bool isInt<8>(int x) {
|
||
|
try { ++x; } catch(...) { --x; }
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
template<typename _CharT>
|
||
|
int __copy_streambufs_eof(_CharT);
|
||
|
|
||
|
class basic_streambuf
|
||
|
{
|
||
|
void m() { }
|
||
|
friend int __copy_streambufs_eof<>(int);
|
||
|
};
|
||
|
|
||
|
// PR 7660
|
||
|
template<typename T> struct S_PR7660 { void g(void (*)(T)); };
|
||
|
template<> void S_PR7660<int>::g(void(*)(int)) {}
|
||
|
|
||
|
// PR 7670
|
||
|
template<typename> class C_PR7670;
|
||
|
template<> class C_PR7670<int>;
|
||
|
template<> class C_PR7670<int>;
|
||
|
|
||
|
template <bool B>
|
||
|
struct S2 {
|
||
|
static bool V;
|
||
|
};
|
||
|
|
||
|
extern template class S2<true>;
|
||
|
|
||
|
template <typename T>
|
||
|
struct S3 {
|
||
|
void m();
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
inline void S3<T>::m() { }
|
||
|
|
||
|
template <typename T>
|
||
|
struct S4 {
|
||
|
void m() { }
|
||
|
};
|
||
|
extern template struct S4<int>;
|
||
|
|
||
|
void S4ImplicitInst() {
|
||
|
S4<int> s;
|
||
|
s.m();
|
||
|
}
|
||
|
|
||
|
struct S5 {
|
||
|
S5(int x);
|
||
|
};
|
||
|
|
||
|
struct TS5 {
|
||
|
S5 s;
|
||
|
template <typename T>
|
||
|
TS5(T y) : s(y) {}
|
||
|
};
|
||
|
|
||
|
// PR 8134
|
||
|
template<class T> void f_PR8134(T);
|
||
|
template<class T> void f_PR8134(T);
|
||
|
void g_PR8134() { f_PR8134(0); f_PR8134('x'); }
|
||
|
|
||
|
// rdar8580149
|
||
|
template <typename T>
|
||
|
struct S6;
|
||
|
|
||
|
template <typename T, unsigned N>
|
||
|
struct S6<const T [N]>
|
||
|
{
|
||
|
private:
|
||
|
typedef const T t1[N];
|
||
|
public:
|
||
|
typedef t1& t2;
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
struct S7;
|
||
|
|
||
|
template<unsigned N>
|
||
|
struct S7<int[N]> : S6<const int[N]> { };
|
||
|
|
||
|
// Zero-length template argument lists
|
||
|
namespace ZeroLengthExplicitTemplateArgs {
|
||
|
template<typename T> void h();
|
||
|
|
||
|
struct Y {
|
||
|
template<typename T> void f();
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
void f(T *ptr) {
|
||
|
T::template g<>(17);
|
||
|
ptr->template g2<>(17);
|
||
|
h<T>();
|
||
|
h<int>();
|
||
|
Y y;
|
||
|
y.f<int>();
|
||
|
}
|
||
|
|
||
|
struct X {
|
||
|
template<typename T> static void g(T);
|
||
|
template<typename T> void g2(T);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
namespace NonTypeTemplateParmContext {
|
||
|
template<typename T, int inlineCapacity = 0> class Vector { };
|
||
|
|
||
|
struct String {
|
||
|
template<int inlineCapacity>
|
||
|
static String adopt(Vector<char, inlineCapacity>&);
|
||
|
};
|
||
|
|
||
|
template<int inlineCapacity>
|
||
|
inline bool equalIgnoringNullity(const Vector<char, inlineCapacity>& a, const String& b) { return false; }
|
||
|
}
|
||
|
|
||
|
// <rdar://problem/11112464>
|
||
|
template< typename > class Foo;
|
||
|
|
||
|
template< typename T >
|
||
|
class Foo : protected T
|
||
|
{
|
||
|
public:
|
||
|
Foo& operator=( const Foo& other );
|
||
|
};
|
||
|
|
||
|
template<typename...A> struct NestedExpansion {
|
||
|
template<typename...B> auto f(A...a, B...b) -> decltype(g(a + b...));
|
||
|
};
|
||
|
template struct NestedExpansion<char, char, char>;
|
||
|
|
||
|
namespace rdar13135282 {
|
||
|
template < typename _Alloc >
|
||
|
void foo(_Alloc = _Alloc());
|
||
|
|
||
|
template < bool > class __pool;
|
||
|
|
||
|
template < template < bool > class _PoolTp >
|
||
|
struct __common_pool {
|
||
|
typedef _PoolTp < 0 > pool_type;
|
||
|
};
|
||
|
|
||
|
template < template < bool > class _PoolTp >
|
||
|
struct __common_pool_base : __common_pool < _PoolTp > {};
|
||
|
|
||
|
template < template < bool > class _PoolTp >
|
||
|
struct A : __common_pool_base < _PoolTp > {};
|
||
|
|
||
|
template < typename _Poolp = A < __pool > >
|
||
|
struct __mt_alloc {
|
||
|
typedef typename _Poolp::pool_type __pool_type;
|
||
|
__mt_alloc() {
|
||
|
foo<__mt_alloc<> >();
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
namespace PR13020 {
|
||
|
template<typename T>
|
||
|
void f() {
|
||
|
enum E {
|
||
|
enumerator
|
||
|
};
|
||
|
|
||
|
T t = enumerator;
|
||
|
}
|
||
|
|
||
|
template void f<int>();
|
||
|
}
|
||
|
|
||
|
template<typename T> void doNotDeserialize() {}
|
||
|
template<typename T> struct ContainsDoNotDeserialize {
|
||
|
static int doNotDeserialize;
|
||
|
};
|
||
|
template<typename T> struct ContainsDoNotDeserialize2 {
|
||
|
static void doNotDeserialize();
|
||
|
};
|
||
|
template<typename T> int ContainsDoNotDeserialize<T>::doNotDeserialize = 0;
|
||
|
template<typename T> void ContainsDoNotDeserialize2<T>::doNotDeserialize() {}
|
||
|
|
||
|
|
||
|
template<typename T> void DependentSpecializedFunc(T x) { x.foo(); }
|
||
|
template<typename T> class DependentSpecializedFuncClass {
|
||
|
void foo() {}
|
||
|
friend void DependentSpecializedFunc<>(DependentSpecializedFuncClass);
|
||
|
};
|
||
|
|
||
|
namespace cyclic_module_load {
|
||
|
// Reduced from a libc++ modules crasher.
|
||
|
namespace std {
|
||
|
template<class> class mask_array;
|
||
|
template<class> class valarray {
|
||
|
public:
|
||
|
valarray(const valarray &v);
|
||
|
};
|
||
|
|
||
|
class gslice {
|
||
|
valarray<int> x;
|
||
|
valarray<int> stride() const { return x; }
|
||
|
};
|
||
|
|
||
|
template<class> class mask_array {
|
||
|
template<class> friend class valarray;
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace local_extern {
|
||
|
template<typename T> int f() {
|
||
|
extern int arr[3];
|
||
|
{
|
||
|
extern T arr;
|
||
|
return sizeof(arr);
|
||
|
}
|
||
|
}
|
||
|
template<typename T> int g() {
|
||
|
extern int arr[3];
|
||
|
extern T arr;
|
||
|
return sizeof(arr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace rdar15468709a {
|
||
|
template<typename> struct decay {};
|
||
|
|
||
|
template<typename FooParamTy> auto foo(FooParamTy fooParam) -> decltype(fooParam);
|
||
|
template<typename BarParamTy> auto bar(BarParamTy barParam) -> decay<decltype(barParam)>;
|
||
|
|
||
|
struct B {};
|
||
|
|
||
|
void crash() {
|
||
|
B some;
|
||
|
bar(some);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace rdar15468709b {
|
||
|
template<typename> struct decay {};
|
||
|
|
||
|
template<typename... Foos> int returnsInt(Foos... foos);
|
||
|
|
||
|
template<typename... FooParamTy> auto foo(FooParamTy... fooParam) -> decltype(returnsInt(fooParam...));
|
||
|
template<typename... BarParamTy> auto bar(BarParamTy... barParam) -> decay<decltype(returnsInt(barParam...))>;
|
||
|
|
||
|
struct B {};
|
||
|
|
||
|
void crash() {
|
||
|
B some;
|
||
|
bar(some);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace rdar15468709c {
|
||
|
template<typename> struct decay {};
|
||
|
|
||
|
template<class... Foos> int returnsInt(Foos... foos);
|
||
|
|
||
|
template<typename FooParamTy> void foo(FooParamTy fooParam) { decltype(fooParam) a; }
|
||
|
template<typename BarParamTy> auto bar(BarParamTy barParam) -> decay<decltype(barParam)>;
|
||
|
|
||
|
struct B {};
|
||
|
|
||
|
void crash() {
|
||
|
B some;
|
||
|
bar(some);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace MemberSpecializationLocation {
|
||
|
template<typename T> struct A { static int n; };
|
||
|
}
|
||
|
|
||
|
// https://bugs.llvm.org/show_bug.cgi?id=34728
|
||
|
namespace PR34728 {
|
||
|
|
||
|
// case 1: defaulted `NonTypeTemplateParmDecl`, non-defaulted 2nd tpl param
|
||
|
template <int foo = 10, class T>
|
||
|
int func1(T const &);
|
||
|
|
||
|
template <int foo, class T>
|
||
|
int func1(T const &) {
|
||
|
return foo;
|
||
|
}
|
||
|
|
||
|
// case 2: defaulted `TemplateTypeParmDecl`, non-defaulted 2nd tpl param
|
||
|
template <class A = int, class B>
|
||
|
A func2(B const &);
|
||
|
|
||
|
template <class A, class B>
|
||
|
A func2(B const &) {
|
||
|
return A(20.0f);
|
||
|
}
|
||
|
|
||
|
// case 3: defaulted `TemplateTemplateParmDecl`, non-defaulted 2nd tpl param
|
||
|
template <class T>
|
||
|
struct Container { T const &item; };
|
||
|
|
||
|
template <template <class> class C = Container, class D>
|
||
|
C<D> func3(D const &);
|
||
|
|
||
|
template <template <class> class C, class D>
|
||
|
C<D> func3(D const &d) {
|
||
|
return Container<D>{d};
|
||
|
}
|
||
|
|
||
|
} // end namespace PR34728
|
||
|
|
||
|
namespace ClassScopeExplicitSpecializations {
|
||
|
template<int> struct A {
|
||
|
template<int> constexpr int f() const { return 1; }
|
||
|
template<> constexpr int f<0>() const { return 2; }
|
||
|
};
|
||
|
|
||
|
template<> template<int> constexpr int A<0>::f() const { return 3; }
|
||
|
template<> template<> constexpr int A<0>::f<0>() const { return 4; }
|
||
|
template<> template<> constexpr int A<0>::f<1>() const { return 5; }
|
||
|
|
||
|
#pragma clang diagnostic push
|
||
|
#pragma clang diagnostic ignored "-Winstantiation-after-specialization"
|
||
|
template int A<2>::f<0>() const;
|
||
|
#pragma clang diagnostic pop
|
||
|
template int A<2>::f<1>() const;
|
||
|
extern template int A<3>::f<0>() const;
|
||
|
extern template int A<3>::f<1>() const;
|
||
|
|
||
|
template<int> struct B {
|
||
|
template<typename> static const int v = 1;
|
||
|
template<typename T> static const int v<T*> = 2;
|
||
|
template<> static const int v<int> = 3;
|
||
|
|
||
|
template<typename> static constexpr int w = 1;
|
||
|
template<typename T> static constexpr int w<T*> = 2;
|
||
|
template<> static constexpr int w<int> = 3;
|
||
|
};
|
||
|
|
||
|
template<> template<typename> constexpr int B<0>::v = 4;
|
||
|
template<> template<typename T> constexpr int B<0>::v<T*> = 5;
|
||
|
template<> template<typename T> constexpr int B<0>::v<T&> = 6;
|
||
|
// This is ill-formed: the initializer of v<int> is instantiated with the
|
||
|
// class.
|
||
|
//template<> template<> constexpr int B<0>::v<int> = 7;
|
||
|
template<> template<> constexpr int B<0>::v<float> = 8;
|
||
|
|
||
|
template<> template<typename> constexpr int B<0>::w = 4;
|
||
|
template<> template<typename T> constexpr int B<0>::w<T*> = 5;
|
||
|
template<> template<typename T> constexpr int B<0>::w<T&> = 6;
|
||
|
template<> template<> constexpr int B<0>::w<int> = 7;
|
||
|
template<> template<> constexpr int B<0>::w<float> = 8;
|
||
|
}
|
||
|
|
||
|
namespace DependentMemberExpr {
|
||
|
struct Base {
|
||
|
constexpr int setstate() { return 0; }
|
||
|
};
|
||
|
template<typename T> struct A : Base {
|
||
|
constexpr int f() { return Base::setstate(); }
|
||
|
};
|
||
|
}
|
||
|
|
||
|
namespace DependentTemplateName {
|
||
|
template <template <class> class Template>
|
||
|
struct TakesClassTemplate {};
|
||
|
|
||
|
template <class T>
|
||
|
TakesClassTemplate<T::template Member> getWithIdentifier();
|
||
|
}
|
||
|
|
||
|
namespace ClassTemplateCycle {
|
||
|
// Create a cycle: the typedef T refers to A<0, 8>, whose template argument
|
||
|
// list refers back to T.
|
||
|
template<int, int> struct A;
|
||
|
using T = A<0, sizeof(void*)>;
|
||
|
template<int N> struct A<N, sizeof(T*)> {};
|
||
|
T t;
|
||
|
|
||
|
// Create a cycle: the variable M refers to A<1, 1>, whose template argument
|
||
|
// list list refers back to M.
|
||
|
template<int, int> struct A;
|
||
|
const decltype(sizeof(A<1, 1>*)) M = 1;
|
||
|
template<int N> struct A<N, M> {};
|
||
|
A<1, 1> u;
|
||
|
}
|