Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 template<typename U, typename T>
      3 U f0(T t) {
      4   return t.template get<U>();
      5 }
      6 
      7 template<typename U, typename T>
      8 int &f1(T t) {
      9   // FIXME: When we pretty-print this, we lose the "template" keyword.
     10   return t.U::template get<int&>();
     11 }
     12 
     13 struct X {
     14   template<typename T> T get();
     15 };
     16 
     17 void test_f0(X x) {
     18   int i = f0<int>(x);
     19   int &ir = f0<int&>(x);
     20 }
     21 
     22 struct XDerived : public X {
     23 };
     24 
     25 void test_f1(XDerived xd) {
     26   int &ir = f1<X>(xd);
     27 }
     28 
     29 // PR5213
     30 template <class T>
     31 struct A {};
     32 
     33 template<class T>
     34 class B
     35 {
     36   A<T> a_;
     37 
     38 public:
     39   void destroy();
     40 };
     41 
     42 template<class T>
     43 void
     44 B<T>::destroy()
     45 {
     46   a_.~A<T>();
     47 }
     48 
     49 void do_destroy_B(B<int> b) {
     50   b.destroy();
     51 }
     52 
     53 struct X1 {
     54   int* f1(int);
     55   template<typename T> float* f1(T);
     56 
     57   static int* f2(int);
     58   template<typename T> static float* f2(T);
     59 };
     60 
     61 void test_X1(X1 x1) {
     62   float *fp1 = x1.f1<>(17);
     63   float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}}
     64   int *ip1 = x1.f1(17);
     65   float *ip2 = x1.f1(3.14);
     66 
     67   float* (X1::*mf1)(int) = &X1::f1;
     68   float* (X1::*mf2)(int) = &X1::f1<>;
     69   float* (X1::*mf3)(float) = &X1::f1<float>;
     70 
     71   float* (*fp3)(int) = &X1::f2;
     72   float* (*fp4)(int) = &X1::f2<>;
     73   float* (*fp5)(float) = &X1::f2<float>;
     74   float* (*fp6)(int) = X1::f2;
     75   float* (*fp7)(int) = X1::f2<>;
     76   float* (*fp8)(float) = X1::f2<float>;
     77 }
     78 
     79 template<int A> struct X2 {
     80   int m;
     81 };
     82 
     83 template<typename T>
     84 struct X3 : T { };
     85 
     86 template<typename T>
     87 struct X4 {
     88   template<typename U>
     89   void f(X2<sizeof(X3<U>().U::m)>);
     90 };
     91 
     92 void f(X4<X3<int> > x4i) {
     93   X2<sizeof(int)> x2;
     94   x4i.f<X2<sizeof(int)> >(x2);
     95 }
     96 
     97 template<typename T>
     98 struct X5 {
     99   template<typename U>
    100   void f();
    101 
    102   void g() {
    103     this->f<T*>();
    104   }
    105 };
    106 
    107 namespace PR6021 {
    108   template< class T1, class T2 >
    109   class Outer
    110   {
    111   public: // Range operations
    112     template< class X > X tmpl( const X* = 0 ) const;
    113 
    114     struct Inner
    115     {
    116       const Outer& o;
    117 
    118       template< class X >
    119       operator X() const
    120       {
    121         return o.tmpl<X>();
    122       }
    123     };
    124   };
    125 }
    126 
    127 namespace rdar8198511 {
    128   template<int, typename U>
    129   struct Base {
    130     void f();
    131   };
    132 
    133   template<typename T>
    134   struct X0 : Base<1, T> { };
    135 
    136   template<typename T>
    137   struct X1 {
    138     X0<int> x0;
    139 
    140     void f() {
    141       this->x0.Base<1, int>::f();
    142     }
    143   };
    144 }
    145