246 lines
4.1 KiB
C++
246 lines
4.1 KiB
C++
|
// RUN: %clang_cc1 -fsyntax-only %s
|
||
|
typedef char one_byte;
|
||
|
typedef char (&two_bytes)[2];
|
||
|
typedef char (&four_bytes)[4];
|
||
|
typedef char (&eight_bytes)[8];
|
||
|
|
||
|
template<int N> struct A { };
|
||
|
|
||
|
namespace N1 {
|
||
|
struct X { };
|
||
|
}
|
||
|
|
||
|
namespace N2 {
|
||
|
struct Y { };
|
||
|
|
||
|
two_bytes operator+(Y, Y);
|
||
|
}
|
||
|
|
||
|
namespace N3 {
|
||
|
struct Z { };
|
||
|
|
||
|
eight_bytes operator+(Z, Z);
|
||
|
}
|
||
|
|
||
|
namespace N4 {
|
||
|
one_byte operator+(N1::X, N2::Y);
|
||
|
|
||
|
template<typename T, typename U>
|
||
|
struct BinOpOverload {
|
||
|
typedef A<sizeof(T() + U())> type;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
namespace N1 {
|
||
|
four_bytes operator+(X, X);
|
||
|
}
|
||
|
|
||
|
namespace N3 {
|
||
|
eight_bytes operator+(Z, Z); // redeclaration
|
||
|
}
|
||
|
|
||
|
void test_bin_op_overload(A<1> *a1, A<2> *a2, A<4> *a4, A<8> *a8) {
|
||
|
typedef N4::BinOpOverload<N1::X, N2::Y>::type XY;
|
||
|
XY *xy = a1;
|
||
|
typedef N4::BinOpOverload<N1::X, N1::X>::type XX;
|
||
|
XX *xx = a4;
|
||
|
typedef N4::BinOpOverload<N2::Y, N2::Y>::type YY;
|
||
|
YY *yy = a2;
|
||
|
typedef N4::BinOpOverload<N3::Z, N3::Z>::type ZZ;
|
||
|
ZZ *zz = a8;
|
||
|
}
|
||
|
|
||
|
namespace N3 {
|
||
|
eight_bytes operator-(::N3::Z);
|
||
|
}
|
||
|
|
||
|
namespace N4 {
|
||
|
template<typename T>
|
||
|
struct UnaryOpOverload {
|
||
|
typedef A<sizeof(-T())> type;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
void test_unary_op_overload(A<8> *a8) {
|
||
|
typedef N4::UnaryOpOverload<N3::Z>::type UZ;
|
||
|
UZ *uz = a8;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
namespace N5 {
|
||
|
template<int I>
|
||
|
struct Lookup {
|
||
|
enum { val = I, more = val + 1 };
|
||
|
};
|
||
|
|
||
|
template<bool B>
|
||
|
struct Cond {
|
||
|
enum Junk { is = B ? Lookup<B>::more : Lookup<Lookup<B+1>::more>::val };
|
||
|
};
|
||
|
|
||
|
enum { resultT = Cond<true>::is,
|
||
|
resultF = Cond<false>::is };
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
namespace N6 {
|
||
|
// non-typedependent
|
||
|
template<int I>
|
||
|
struct Lookup {};
|
||
|
|
||
|
template<bool B, typename T, typename E>
|
||
|
struct Cond {
|
||
|
typedef Lookup<B ? sizeof(T) : sizeof(E)> True;
|
||
|
typedef Lookup<!B ? sizeof(T) : sizeof(E)> False;
|
||
|
};
|
||
|
|
||
|
typedef Cond<true, int, char>::True True;
|
||
|
typedef Cond<true, int, char>::False False;
|
||
|
|
||
|
// check that we have the right types
|
||
|
Lookup<1> const &L1(False());
|
||
|
Lookup<sizeof(int)> const &L2(True());
|
||
|
}
|
||
|
|
||
|
|
||
|
namespace N7 {
|
||
|
// type dependent
|
||
|
template<int I>
|
||
|
struct Lookup {};
|
||
|
|
||
|
template<bool B, typename T, typename E>
|
||
|
struct Cond {
|
||
|
T foo() { return B ? T() : E(); }
|
||
|
typedef Lookup<sizeof(B ? T() : E())> Type;
|
||
|
};
|
||
|
|
||
|
//Cond<true, int*, double> C; // Errors
|
||
|
//int V(C.foo()); // Errors
|
||
|
//typedef Cond<true, int*, double>::Type Type; // Errors
|
||
|
typedef Cond<true, int, double>::Type Type;
|
||
|
}
|
||
|
|
||
|
template<typename T, unsigned long N> struct IntegralConstant { };
|
||
|
|
||
|
template<typename T>
|
||
|
struct X0 {
|
||
|
void f(T x, IntegralConstant<T, sizeof(x)>);
|
||
|
};
|
||
|
|
||
|
void test_X0(X0<int> x, IntegralConstant<int, sizeof(int)> ic) {
|
||
|
x.f(5,ic);
|
||
|
}
|
||
|
|
||
|
namespace N8 {
|
||
|
struct X {
|
||
|
X operator+(const X&) const;
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
T test_plus(const T* xp, const T& x, const T& y) {
|
||
|
x.operator+(y);
|
||
|
return xp->operator+(y);
|
||
|
}
|
||
|
|
||
|
void test_test_plus(X x) {
|
||
|
test_plus(&x, x, x);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace N9 {
|
||
|
struct A {
|
||
|
bool operator==(int value);
|
||
|
};
|
||
|
|
||
|
template<typename T> struct B {
|
||
|
bool f(A a) {
|
||
|
return a == 1;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template struct B<int>;
|
||
|
}
|
||
|
|
||
|
namespace N10 {
|
||
|
template <typename T>
|
||
|
class A {
|
||
|
struct X { };
|
||
|
|
||
|
public:
|
||
|
~A() {
|
||
|
f(reinterpret_cast<X *>(0), reinterpret_cast<X *>(0));
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
void f(X *);
|
||
|
void f(X *, X *);
|
||
|
};
|
||
|
|
||
|
template class A<int>;
|
||
|
}
|
||
|
|
||
|
namespace N12 {
|
||
|
// PR5224
|
||
|
template<typename T>
|
||
|
struct A { typedef int t0; };
|
||
|
|
||
|
struct C {
|
||
|
C(int);
|
||
|
|
||
|
template<typename T>
|
||
|
static C *f0(T a0) {return new C((typename A<T>::t0) 1); }
|
||
|
};
|
||
|
|
||
|
void f0(int **a) { C::f0(a); }
|
||
|
}
|
||
|
|
||
|
namespace PR7202 {
|
||
|
template<typename U, typename T>
|
||
|
struct meta {
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
struct X {
|
||
|
struct dummy;
|
||
|
|
||
|
template<typename T>
|
||
|
X(T, typename meta<T, dummy*>::type = 0);
|
||
|
|
||
|
template<typename T, typename A>
|
||
|
X(T, A);
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
struct Z { };
|
||
|
|
||
|
template<typename T> Z<T> g(T);
|
||
|
|
||
|
struct Y {
|
||
|
template<typename T>
|
||
|
void f(T t) {
|
||
|
new X(g(*this));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template void Y::f(int);
|
||
|
}
|
||
|
|
||
|
namespace N13 {
|
||
|
class A{
|
||
|
A(const A&);
|
||
|
|
||
|
public:
|
||
|
~A();
|
||
|
A(int);
|
||
|
template<typename T> A &operator<<(const T&);
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
void f(T t) {
|
||
|
A(17) << t;
|
||
|
}
|
||
|
|
||
|
template void f(int);
|
||
|
|
||
|
}
|