// 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); }