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