1 // RUN: %clang_cc1 -fsyntax-only -ast-print %s | FileCheck %s
2 namespace N {
3   template<typename T, typename U> void f(U);
4   template<int> void f();
5 }
6 
7 void g() {
8   // CHECK: N::f<int>(3.14
9   N::f<int>(3.14);
10 
11   // CHECK: N::f<double>
12   void (*fp)(int) = N::f<double>;
13 }
14 
15 
16 // (NNS qualified) DeclRefExpr.
17 namespace DRE {
18 
19 template <typename T>
20 void foo();
21 
22 void test() {
23   // CHECK: DRE::foo<int>;
24   DRE::foo<int>;
25   // CHECK: DRE::template foo<int>;
26   DRE::template foo<int>;
27   // CHECK: DRE::foo<int>();
28   DRE::foo<int>();
29   // CHECK: DRE::template foo<int>();
30   DRE::template foo<int>();
31 }
32 
33 } // namespace DRE
34 
35 
36 // MemberExpr.
37 namespace ME {
38 
39 struct S {
40   template <typename T>
41   void mem();
42 };
43 
44 void test() {
45   S s;
46   // CHECK: s.mem<int>();
47   s.mem<int>();
48   // CHECK: s.template mem<int>();
49   s.template mem<int>();
50 }
51 
52 } // namespace ME
53 
54 
55 // UnresolvedLookupExpr.
56 namespace ULE {
57 
58 template <typename T>
59 int foo();
60 
61 template <typename T>
62 void test() {
63   // CHECK: ULE::foo<T>;
64   ULE::foo<T>;
65   // CHECK: ULE::template foo<T>;
66   ULE::template foo<T>;
67 }
68 
69 } // namespace ULE
70 
71 
72 // UnresolvedMemberExpr.
73 namespace UME {
74 
75 struct S {
76   template <typename T>
77   void mem();
78 };
79 
80 template <typename U>
81 void test() {
82   S s;
83   // CHECK: s.mem<U>();
84   s.mem<U>();
85   // CHECK: s.template mem<U>();
86   s.template mem<U>();
87 }
88 
89 } // namespace UME
90 
91 
92 // DependentScopeDeclRefExpr.
93 namespace DSDRE {
94 
95 template <typename T>
96 struct S;
97 
98 template <typename T>
99 void test() {
100   // CHECK: S<T>::foo;
101   S<T>::foo;
102   // CHECK: S<T>::template foo;
103   S<T>::template foo;
104   // CHECK: S<T>::template foo<>;
105   S<T>::template foo<>;
106   // CHECK: S<T>::template foo<T>;
107   S<T>::template foo<T>;
108 }
109 
110 } // namespace DSDRE
111 
112 
113 // DependentScopeMemberExpr.
114 namespace DSME {
115 
116 template <typename T>
117 struct S;
118 
119 template <typename T>
120 void test() {
121   S<T> s;
122   // CHECK: s.foo;
123   s.foo;
124   // CHECK: s.template foo;
125   s.template foo;
126   // CHECK: s.template foo<>;
127   s.template foo<>;
128   // CHECK: s.template foo<T>;
129   s.template foo<T>;
130 }
131 
132 } // namespace DSME
133 
134 namespace DSDRE_withImplicitTemplateArgs {
135 
136 template <typename T> void foo() {
137   // CHECK: T::template bar();
138   T::template bar();
139 }
140 
141 } // namespace DSDRE_withImplicitTemplateArgs
142