1// RUN: %clang_cc1 -fsyntax-only -ast-print %s | FileCheck %s
2namespace N {
3  template<typename T, typename U> void f(U);
4  template<int> void f();
5}
6
7void 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.
17namespace DRE {
18
19template <typename T>
20void foo();
21
22void 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.
37namespace ME {
38
39struct S {
40  template <typename T>
41  void mem();
42};
43
44void 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.
56namespace ULE {
57
58template <typename T>
59int foo();
60
61template <typename T>
62void 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.
73namespace UME {
74
75struct S {
76  template <typename T>
77  void mem();
78};
79
80template <typename U>
81void 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.
93namespace DSDRE {
94
95template <typename T>
96struct S;
97
98template <typename T>
99void 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.
114namespace DSME {
115
116template <typename T>
117struct S;
118
119template <typename T>
120void 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
134namespace DSDRE_withImplicitTemplateArgs {
135
136template <typename T> void foo() {
137  // CHECK: T::template bar();
138  T::template bar();
139}
140
141} // namespace DSDRE_withImplicitTemplateArgs
142