xref: /llvm-project/clang/test/AST/ast-dump-records.cpp (revision 8c2574832ed2064996389e4259eaf0bea0fa7951)
1 // Test without serialization:
2 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-dump %s \
3 // RUN: | FileCheck -strict-whitespace %s
4 //
5 // Test with serialization:
6 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -emit-pch -o %t %s
7 // RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -std=c++17 -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 struct A;
12 // CHECK: CXXRecordDecl 0x{{[^ ]*}} <{{.*}}:1, col:8> col:8 struct A
13 
14 struct B;
15 // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:8> col:8 referenced struct B
16 
17 struct A {
18   // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+32]]:1> line:[[@LINE-1]]:8 struct A definition
19   // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
20   // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
21   // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
22   // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
23   // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
24   // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
25   // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
26 
27   // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:8> col:8 implicit struct A
28   int a;
29   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 a 'int'
30   int b, c;
31   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 b 'int'
32   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:3, col:10> col:10 c 'int'
33   int d : 12;
34   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 d 'int'
35   // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int'
36   // CHECK-NEXT: value: Int 12
37   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 12
38   int : 0;
39   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:7 'int'
40   // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:9> 'int'
41   // CHECK-NEXT: value: Int 0
42   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 0
43   int e : 10;
44   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 e 'int'
45   // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int'
46   // CHECK-NEXT: value: Int 10
47   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 10
48   B *f;
49   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:6> col:6 f 'B *'
50 };
51 
52 struct C {
53   // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+66]]:1> line:[[@LINE-1]]:8 struct C definition
54   // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal has_variant_members
55   // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
56   // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
57   // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
58   // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
59   // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
60   // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
61 
62   // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:8> col:8 implicit struct C
63   struct {
64     // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+10]]:3> line:[[@LINE-1]]:3 struct definition
65     // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
66     // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
67     // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
68     // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
69     // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
70     // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
71     // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
72     int a;
73     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int'
74   } b;
75   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-12]]:3, line:[[@LINE-1]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-12]]:3)':'C::(unnamed struct at {{.*}}:[[@LINE-12]]:3)'
76 
77   union {
78     // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+12]]:3> line:[[@LINE-1]]:3 union definition
79     // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
80     // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
81     // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
82     // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
83     // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
84     // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
85     // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
86     int c;
87     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 c 'int'
88     float d;
89     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:11> col:11 d 'float'
90   };
91   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-14]]:3> col:3 implicit 'C::(anonymous union at {{.*}}:[[@LINE-14]]:3)'
92   // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-6]]:9> col:9 implicit c 'int'
93   // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'C::(anonymous union at {{.*}}:[[@LINE-16]]:3)'
94   // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int'
95   // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:11> col:11 implicit d 'float'
96   // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'C::(anonymous union at {{.*}}:[[@LINE-19]]:3)'
97   // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float'
98 
99   struct {
100     // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+11]]:3> line:[[@LINE-1]]:3 struct definition
101     // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
102     // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
103     // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
104     // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
105     // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
106     // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
107     // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
108     int e, f;
109     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 e 'int'
110     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:5, col:12> col:12 f 'int'
111   };
112   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-13]]:3> col:3 implicit 'C::(anonymous struct at {{.*}}:[[@LINE-13]]:3)'
113   // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:9> col:9 implicit e 'int'
114   // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'C::(anonymous struct at {{.*}}:[[@LINE-15]]:3)'
115   // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int'
116   // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <col:12> col:12 implicit f 'int'
117   // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'C::(anonymous struct at {{.*}}:[[@LINE-18]]:3)'
118   // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int'
119 };
120 
121 struct D {
122   // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+16]]:1> line:[[@LINE-1]]:8 struct D definition
123   // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
124   // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
125   // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
126   // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
127   // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
128   // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
129   // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
130 
131   // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:8> col:8 implicit struct D
132   int a;
133   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 a 'int'
134   int b[10];
135   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 b 'int[10]'
136   int c[];
137   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:7 c 'int[]'
138 };
139 
140 union E;
141 // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:7> col:7 union E
142 
143 union F;
144 // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:7> col:7 union F
145 
146 union E {
147   // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+32]]:1> line:[[@LINE-1]]:7 union E definition
148   // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
149   // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
150   // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
151   // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
152   // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
153   // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
154   // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
155 
156   // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:7> col:7 implicit union E
157   int a;
158   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 a 'int'
159   int b, c;
160   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 b 'int'
161   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:3, col:10> col:10 c 'int'
162   int d : 12;
163   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 d 'int'
164   // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int'
165   // CHECK-NEXT: value: Int 12
166   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 12
167   int : 0;
168   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:7 'int'
169   // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:9> 'int'
170   // CHECK-NEXT: value: Int 0
171   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 0
172   int e : 10;
173   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 e 'int'
174   // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int'
175   // CHECK-NEXT: value: Int 10
176   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 10
177   B *f;
178   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:6> col:6 f 'B *'
179 };
180 
181 union G {
182   // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+71]]:1> line:[[@LINE-1]]:7 union G definition
183   // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
184   // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
185   // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
186   // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
187   // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
188   // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
189   // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
190 
191   // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:7> col:7 implicit union G
192   struct {
193     // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+11]]:3> line:[[@LINE-1]]:3 struct definition
194     // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
195     // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
196     // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
197     // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
198     // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
199     // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
200     // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
201 
202     int a;
203     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int'
204   } b;
205   // FIXME: note that it talks about 'struct G' below; the same happens in
206   // other cases with union G as well.
207   // CHECK: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-15]]:3, line:[[@LINE-3]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-15]]:3)':'G::(unnamed struct at {{.*}}:[[@LINE-15]]:3)'
208 
209   union {
210     // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+13]]:3> line:[[@LINE-1]]:3 union definition
211     // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
212     // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
213     // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
214     // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
215     // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
216     // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
217     // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
218 
219     int c;
220     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 c 'int'
221     float d;
222     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:11> col:11 d 'float'
223   };
224   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-15]]:3> col:3 implicit 'G::(anonymous union at {{.*}}:[[@LINE-15]]:3)'
225   // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-6]]:9> col:9 implicit c 'int'
226   // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'G::(anonymous union at {{.*}}:[[@LINE-17]]:3)'
227   // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int'
228   // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:11> col:11 implicit d 'float'
229   // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'G::(anonymous union at {{.*}}:[[@LINE-20]]:3)'
230   // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float'
231 
232   struct {
233     // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+12]]:3> line:[[@LINE-1]]:3 struct definition
234     // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
235     // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
236     // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
237     // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit
238     // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
239     // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit
240     // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit
241 
242     int e, f;
243     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 e 'int'
244     // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:5, col:12> col:12 f 'int'
245   };
246   // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-14]]:3> col:3 implicit 'G::(anonymous struct at {{.*}}:[[@LINE-14]]:3)'
247   // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:9> col:9 implicit e 'int'
248   // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'G::(anonymous struct at {{.*}}:[[@LINE-16]]:3)'
249   // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int'
250   // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <col:12> col:12 implicit f 'int'
251   // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'G::(anonymous struct at {{.*}}:[[@LINE-19]]:3)'
252   // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int'
253 };
254 
255 struct Base1 {};
256 struct Base2 {};
257 struct Base3 {};
258 
259 struct Derived1 : Base1 {
260   // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived1 definition
261   // CHECK: public 'Base1'
262 };
263 
264 struct Derived2 : private Base1 {
265   // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived2 definition
266   // CHECK: private 'Base1'
267 };
268 
269 struct Derived3 : virtual Base1 {
270   // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived3 definition
271   // CHECK: virtual public 'Base1'
272 };
273 
274 struct Derived4 : Base1, virtual Base2, protected Base3 {
275   // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:1> line:[[@LINE-1]]:8 struct Derived4 definition
276   // CHECK: public 'Base1'
277   // CHECK-NEXT: virtual public 'Base2'
278   // CHECK-NEXT: protected 'Base3'
279 };
280 
281 struct Derived5 : protected virtual Base1 {
282   // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived5 definition
283   // CHECK: virtual protected 'Base1'
284 };
285 
286 template <typename... Bases>
287 struct Derived6 : virtual public Bases... {
288   // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived6 definition
289   // CHECK: virtual public 'Bases'...
290 };
291 
292 class NonTrivial {
293 // CHECK: |-CXXRecordDecl {{.*}} referenced class NonTrivial definition
294  public:
295   NonTrivial();
296 // CHECK: | |-CXXConstructorDecl {{.*}} referenced NonTrivial 'void ()'
297   ~NonTrivial();
298 // CHECK: | |-CXXDestructorDecl {{.*}} referenced ~NonTrivial 'void () noexcept'
299 };
300 
301 struct CheckFullExpression {
302 // CHECK: |-CXXRecordDecl {{.*}} struct CheckFullExpression definition
303   NonTrivial value = NonTrivial();
304 // CHECK: | |-FieldDecl {{.*}} value 'NonTrivial'
305 // CHECK-NEXT: | | `-ExprWithCleanups {{.*}} 'NonTrivial'
306 // CHECK-NEXT: | |   `-CXXBindTemporaryExpr {{.*}} 'NonTrivial' (CXXTemporary{{.*}})
307 // CHECK-NEXT: | |     `-CXXTemporaryObjectExpr {{.*}} 'NonTrivial' 'void ()'
308 };
309 
310 struct CheckNoCleanup {
311 // CHECK: `-CXXRecordDecl {{.*}} struct CheckNoCleanup definition
312   static constexpr char kConstant = '+';
313 // CHECK: `-VarDecl {{.*}} kConstant 'const char' static inline constexpr cinit
314 // CHECK-NEXT: |-value: Int 43
315 // CHECK-NEXT: `-CharacterLiteral {{.*}} 'char' 43
316 };
317