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