Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 // PR5336
      3 template<typename FromCl>
      4 struct isa_impl_cl {
      5  template<class ToCl>
      6  static void isa(const FromCl &Val) { }
      7 };
      8 
      9 template<class X, class Y>
     10 void isa(const Y &Val) {   return isa_impl_cl<Y>::template isa<X>(Val); }
     11 
     12 class Value;
     13 void f0(const Value &Val) { isa<Value>(Val); }
     14 
     15 // Implicit template-ids.
     16 template<typename T>
     17 struct X0 {
     18   template<typename U>
     19   void f1();
     20 
     21   template<typename U>
     22   void f2(U) {
     23     f1<U>();
     24   }
     25 };
     26 
     27 void test_X0_int(X0<int> xi, float f) {
     28   xi.f2(f);
     29 }
     30 
     31 // Not template-id expressions, but they almost look like it.
     32 template<typename F>
     33 struct Y {
     34   Y(const F&);
     35 };
     36 
     37 template<int I>
     38 struct X {
     39   X(int, int);
     40   void f() {
     41     Y<X<I> >(X<I>(0, 0));
     42     Y<X<I> >(::X<I>(0, 0));
     43   }
     44 };
     45 
     46 template struct X<3>;
     47 
     48 // 'template' as a disambiguator.
     49 // PR7030
     50 struct Y0 {
     51   template<typename U>
     52   void f1(U);
     53 
     54   template<typename U>
     55   static void f2(U);
     56 
     57   void f3(int);
     58 
     59   static int f4(int);
     60   template<typename U>
     61   static void f4(U);
     62 
     63   template<typename U>
     64   void f() {
     65     Y0::template f1<U>(0);
     66     Y0::template f1(0);
     67     this->template f1(0);
     68 
     69     Y0::template f2<U>(0);
     70     Y0::template f2(0);
     71 
     72     Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
     73     Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
     74 
     75     int x;
     76     x = Y0::f4(0);
     77     x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
     78     x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
     79 
     80     x = this->f4(0);
     81     x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
     82     x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
     83   }
     84 };
     85 
     86 struct A {
     87   template<int I>
     88   struct B {
     89     static void b1();
     90   };
     91 };
     92 
     93 template<int I>
     94 void f5() {
     95   A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}}
     96 }
     97 
     98 template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}}
     99 
    100 class C {};
    101 template <template <typename> class D>  // expected-note{{previous use is here}}
    102 class E {
    103   template class D<C>;  // expected-error {{elaborated type refers to a template template argument}}
    104 };
    105