]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/SemaTemplate/template-id-expr.cpp
Vendor import of clang trunk r290819:
[FreeBSD/FreeBSD.git] / test / SemaTemplate / template-id-expr.cpp
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 {{template template argument 'D' cannot be referenced with a class specifier}}
104 };