xref: /llvm-project/clang/test/AST/ast-dump-template-decls.cpp (revision 7f78f99fe5af82361d37adcbd2daa4d04afba13d)
1 // Test without serialization:
2 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -ast-dump %s \
3 // RUN: | FileCheck -strict-whitespace %s
4 //
5 // Test with serialization:
6 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -emit-pch -o %t %s
7 // RUN: %clang_cc1 -x c++ -std=c++17 -triple x86_64-unknown-unknown -include-pch %t -ast-dump-all /dev/null \
8 // RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
9 // RUN: | FileCheck --strict-whitespace %s
10 
11 template <typename Ty>
12 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <{{.*}}:1, line:[[@LINE+2]]:10> col:6 a
13 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty
14 void a(Ty);
15 
16 template <typename... Ty>
17 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:13> col:6 b
18 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:23> col:23 referenced typename depth 0 index 0 ... Ty
19 void b(Ty...);
20 
21 template <typename Ty, typename Uy>
22 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:14> col:6 c
23 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty
24 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:24, col:33> col:33 referenced typename depth 0 index 1 Uy
25 void c(Ty, Uy);
26 
27 template <>
28 void c<float, int>(float, int);
29 // CHECK: FunctionDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:30> col:6 c 'void (float, int)'
30 // CHECK: TemplateArgument type 'float'
31 // CHECK: TemplateArgument type 'int'
32 
33 template <typename Ty, template<typename> typename Uy>
34 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:18> col:6 d
35 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty
36 // CHECK-NEXT: TemplateTemplateParmDecl 0x{{[^ ]*}} <col:24, col:52> col:52 depth 0 index 1 Uy
37 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:33> col:41 typename depth 1 index 0
38 void d(Ty, Uy<Ty>);
39 
40 template <class Ty>
41 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:10> col:6 e
42 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:17> col:17 referenced class depth 0 index 0 Ty
43 void e(Ty);
44 
45 template <int N>
46 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:17> col:6 f
47 // CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:15> col:15 referenced 'int' depth 0 index 0 N
48 void f(int i = N);
49 
50 template <typename Ty = int>
51 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:10> col:6 g
52 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:25> col:20 referenced typename depth 0 index 0 Ty
53 // CHECK-NEXT: TemplateArgument type 'int'
54 void g(Ty);
55 
56 template <typename = void>
57 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:8> col:6 h
58 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:22> col:20 typename depth 0 index 0
59 // CHECK-NEXT: TemplateArgument type 'void'
60 void h();
61 
62 template <typename Ty>
63 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:11> col:8 R
64 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 0 index 0 Ty
65 // CHECK: ClassTemplateSpecialization 0x{{[^ ]*}} 'R'
66 struct R {};
67 
68 template <>
69 // CHECK: ClassTemplateSpecializationDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:16> col:8 struct R definition
70 // CHECK: TemplateArgument type 'int'
71 struct R<int> {};
72 
73 template <typename Ty, class Uy>
74 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:11> col:8 S
75 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 0 index 0 Ty
76 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:24, col:30> col:30 class depth 0 index 1 Uy
77 struct S {};
78 
79 template <typename Ty>
80 // CHECK: ClassTemplatePartialSpecializationDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:20> col:8 struct S definition
81 // CHECK: TemplateArgument type 'type-parameter-0-0'
82 // CHECK: TemplateArgument type 'int'
83 // CHECK: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-4]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty
84 struct S<Ty, int> {};
85 
86 template <auto>
87 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:11> col:8 T
88 // CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11> col:15 'auto' depth 0 index 0
89 struct T {};
90 
91 template <decltype(auto)>
92 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:11> col:8 U
93 // CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:24> col:25 'decltype(auto)' depth 0 index 0
94 struct U {};
95 
96 template <typename Ty>
97 // CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+7]]:1> line:[[@LINE+2]]:8 V
98 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 0 index 0 Ty
99 struct V {
100   template <typename Uy>
101   // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+2]]:10> col:8 f
102   // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:13, col:22> col:22 typename depth 1 index 0 Uy
103   void f();
104 };
105 
106 template <typename Ty>
107 template <typename Uy>
108 // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} parent 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:18> col:13 f
109 // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 1 index 0 Uy
110 void V<Ty>::f() {}
111 
112 namespace PR55886 {
113 template <class T> struct C {
114   template <class U> using type1 = U(T);
115 };
116 using type2 = typename C<int>::type1<void>;
117 // CHECK:      TypeAliasDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:42> col:7 type2 'typename C<int>::type1<void>':'void (int)'
118 // CHECK-NEXT: ElaboratedType 0x{{[^ ]*}} 'typename C<int>::type1<void>' sugar
119 // CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1<void>' sugar alias
120 // CHECK-NEXT: name: 'C<int>::type1':'PR55886::C<int>::type1' qualified
121 // CHECK-NEXT: NestedNameSpecifier TypeSpec 'C<int>':'PR55886::C<int>'
122 // CHECK-NEXT: TypeAliasTemplateDecl {{.+}} type1
123 // CHECK-NEXT: TemplateArgument type 'void'
124 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
125 // CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl
126 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
127 // CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 T
128 // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'C'
129 // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
130 } // namespace PR55886
131 
132 namespace PR56099 {
133 template <typename... T> struct D {
134   template <typename... U> struct bind {
135     using bound_type = int(int (*...p)(T, U));
136   };
137 };
138 template struct D<float, char>::bind<int, short>;
139 // CHECK:      TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:5, col:45> col:11 bound_type 'int (int (*)(float, int), int (*)(char, short))'
140 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl
141 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
142 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... T pack_index 1
143 // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D'
144 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar typename depth 0 index 0 ... U pack_index 1
145 // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'bind'
146 // CHECK:      FunctionProtoType 0x{{[^ ]*}} 'int (char, short)' cdecl
147 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... T pack_index 0
148 // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D'
149 // CHECK:      SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar typename depth 0 index 0 ... U pack_index 0
150 // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'bind'
151 } // namespace PR56099
152 
153 namespace subst_default_argument {
154 template<class A1> class A {};
155 template<template<class C1, class C2 = A<C1>> class D1, class D2> using D = D1<D2>;
156 
157 template<class E1, class E2> class E {};
158 using test1 = D<E, int>;
159 // CHECK:      TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:1, col:23> col:7 test1 'D<E, int>':'subst_default_argument::E<int, subst_default_argument::A<int>>'
160 // CHECK:      TemplateSpecializationType 0x{{[^ ]*}} 'A<int>' sugar
161 // CHECK-NEXT: |-name: 'A':'subst_default_argument::A' qualified
162 // CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A
163 // CHECK-NEXT: |-TemplateArgument type 'int'
164 // CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
165 // CHECK-NEXT: `-RecordType 0x{{[^ ]*}} 'subst_default_argument::A<int>'
166 // CHECK-NEXT:   `-ClassTemplateSpecialization 0x{{[^ ]*}} 'A'
167 } // namespace subst_default_argument
168 
169 namespace D146733 {
170 template<class T>
171 T unTempl = 1;
172 // CHECK:VarTemplateDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:13> col:3 unTempl
173 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:10, col:16> col:16 referenced class depth 0 index 0 T
174 // CHECK-NEXT: |-VarDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, col:13> col:3 unTempl 'T' cinit
175 // CHECK-NEXT: | `-IntegerLiteral 0x{{[^ ]*}} <col:13> 'int' 1
176 
177 template<>
178 int unTempl<int>;
179 // CHECK:      VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:16> col:5 unTempl 'int'
180 // CHECK-NEXT: `-TemplateArgument type 'int'
181 // CHECK-NEXT: `-BuiltinType 0x{{[^ ]*}} 'int'
182 
183 template<>
184 float unTempl<float> = 1;
185 // CHECK:      VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:24> col:7 unTempl 'float'
186 // CHECK-NEXT: |-TemplateArgument type 'float'
187 // CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'float'
188 // CHECK-NEXT: `-ImplicitCastExpr 0x{{[^ ]*}} <col:24> 'float' <IntegralToFloating>
189 // CHECK-NEXT: `-IntegerLiteral 0x{{[^ ]*}} <col:24> 'int' 1
190 
191 template<class T, class U>
192 T binTempl = 1;
193 // CHECK:      VarTemplateDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:14> col:3 binTempl
194 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:10, col:16> col:16 referenced class depth 0 index 0 T
195 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{[^ ]*}} <col:19, col:25> col:25 class depth 0 index 1 U
196 // CHECK-NEXT: |-VarDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, col:14> col:3 binTempl 'T' cinit
197 // CHECK-NEXT: | `-IntegerLiteral 0x{{[^ ]*}} <col:14> 'int' 1
198 
199 template<class U>
200 int binTempl<int, U>;
201 // CHECK:      VarTemplatePartialSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:20> col:5 binTempl 'int'
202 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:10, col:16> col:16 referenced class depth 0 index 0 U
203 // CHECK-NEXT: |-TemplateArgument type 'int'
204 // CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
205 // CHECK-NEXT: `-TemplateArgument type 'type-parameter-0-0'
206 // CHECK-NEXT: `-TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-0' dependent depth 0 index 0
207 
208 template<class U>
209 float binTempl<float, U> = 1;
210 // CHECK:      VarTemplatePartialSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:28> col:7 binTempl 'float'
211 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:10, col:16> col:16 referenced class depth 0 index 0 U
212 // CHECK-NEXT: |-TemplateArgument type 'float'
213 // CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'float'
214 // CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-0'
215 // CHECK-NEXT: | `-TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-0' dependent depth 0 index 0
216 // CHECK-NEXT: `-ImplicitCastExpr 0x{{[^ ]*}} <line:{{[0-9]+}}:28> 'float' <IntegralToFloating>
217 // CHECK-NEXT: `-IntegerLiteral 0x{{[^ ]*}} <col:28> 'int' 1
218 
219 template<>
220 int binTempl<int, int>;
221 // CHECK:      VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:22> col:5 binTempl 'int'
222 // CHECK-NEXT: |-TemplateArgument type 'int'
223 // CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
224 // CHECK-NEXT: `-TemplateArgument type 'int'
225 // CHECK-NEXT: `-BuiltinType 0x{{[^ ]*}} 'int'
226 
227 template<>
228 float binTempl<float, float> = 1;
229 // CHECK:      VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:32> col:7 binTempl 'float'
230 // CHECK-NEXT: |-TemplateArgument type 'float'
231 // CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'float'
232 // CHECK-NEXT: |-TemplateArgument type 'float'
233 // CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'float'
234 // CHECK-NEXT: `-ImplicitCastExpr 0x{{[^ ]*}} <col:32> 'float' <IntegralToFloating>
235 // CHECK-NEXT: `-IntegerLiteral 0x{{[^ ]*}} <col:32> 'int' 1
236 }
237