1 | // clang-format off |
2 | // REQUIRES: lld, x86 |
3 | |
4 | // Test that we can display tag types. |
5 | // RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 \ |
6 | // RUN: -Xclang -fkeep-static-consts -c /Fo%t.obj -- %s |
7 | // RUN: lld-link -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb |
8 | // RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \ |
9 | // RUN: %p/Inputs/globals-classes.lldbinit | FileCheck %s |
10 | |
11 | enum class EnumType : unsigned { |
12 | A = 1, |
13 | B = 2 |
14 | }; |
15 | |
16 | class ClassNoPadding { |
17 | /* [ 0] */ unsigned char a = 86; |
18 | /* [ 1] */ char b = 'a'; |
19 | /* [ 2] */ bool c = false; |
20 | /* [ 3] */ bool d = true; |
21 | /* [ 4] */ short e = -1234; |
22 | /* [ 6] */ unsigned short f = 8123; |
23 | /* [ 8] */ unsigned int g = 123908; |
24 | /* [12] */ int h = -890234; |
25 | /* [16] */ unsigned long i = 2908234; |
26 | /* [20] */ long j = 7234890; |
27 | /* [24] */ float k = 908234.12392; |
28 | /* [28] */ EnumType l = EnumType::A; |
29 | /* [32] */ double m = 23890.897423; |
30 | /* [40] */ unsigned long long n = 23490782; |
31 | /* [48] */ long long o = -923409823; |
32 | /* [56] */ int p[5] = { 2, 3, 5, 8, 13 }; |
33 | }; |
34 | |
35 | class ClassWithPadding { |
36 | /* [ 0] */ char a = '0'; |
37 | // char padding[1]; |
38 | /* [ 2] */ short b = 50; |
39 | /* [ 4] */ char c[2] = { '0', '1' }; |
40 | // char padding[2]; |
41 | /* [ 8] */ int d = 100; |
42 | /* [12] */ char e = '0'; |
43 | // char padding[3]; |
44 | /* [16] */ int f = 200; |
45 | // char padding[4]; |
46 | /* [24] */ long long g = 300; |
47 | /* [32] */ char h[3] = { '0', '1', '2' }; |
48 | // char padding[5]; |
49 | /* [40] */ long long i = 400; |
50 | /* [48] */ char j[2] = { '0', '1' }; |
51 | // char padding[6]; |
52 | /* [56] */ long long k = 500; |
53 | /* [64] */ char l = '0'; |
54 | // char padding[7]; |
55 | /* [72] */ long long m = 600; |
56 | } ; |
57 | |
58 | struct EmptyBase {}; |
59 | |
60 | template<typename T> |
61 | struct BaseClass { |
62 | constexpr BaseClass(int N) |
63 | : BaseMember(N) {} |
64 | |
65 | int BaseMember; |
66 | }; |
67 | |
68 | struct DerivedClass : public BaseClass<int> { |
69 | constexpr DerivedClass(int Base, int Derived) |
70 | : BaseClass(Base), DerivedMember(Derived) {} |
71 | |
72 | int DerivedMember; |
73 | }; |
74 | |
75 | struct EBO : public EmptyBase { |
76 | constexpr EBO(int N) : Member(N) {} |
77 | int Member; |
78 | }; |
79 | |
80 | struct PaddedBases : public BaseClass<char>, public BaseClass<short>, BaseClass<int> { |
81 | constexpr PaddedBases(char CH, short S, int N, long long D) |
82 | : BaseClass<char>(CH), BaseClass<short>(S), BaseClass<int>(N), DerivedMember(D) {} |
83 | long long DerivedMember; |
84 | }; |
85 | |
86 | struct Statics { |
87 | static char a; |
88 | static bool b; |
89 | static short c; |
90 | static unsigned short d; |
91 | static unsigned int e; |
92 | static int f; |
93 | static unsigned long g; |
94 | static long h; |
95 | static float i; |
96 | static EnumType j; |
97 | static double k; |
98 | static unsigned long long l; |
99 | static long long m; |
100 | }; |
101 | |
102 | char Statics::a = 'a'; |
103 | bool Statics::b = true; |
104 | short Statics::c = 1234; |
105 | unsigned short Statics::d = 2345; |
106 | unsigned int Statics::e = 3456; |
107 | int Statics::f = 4567; |
108 | unsigned long Statics::g = 5678; |
109 | long Statics::h = 6789; |
110 | float Statics::i = 7890.1234; |
111 | EnumType Statics::j = EnumType::A; |
112 | double Statics::k = 8901.2345; |
113 | unsigned long long Statics::l = 9012345; |
114 | long long Statics::m = 1234567; |
115 | |
116 | |
117 | struct Pointers { |
118 | void *a = nullptr; |
119 | char *b = &Statics::a; |
120 | bool *c = &Statics::b; |
121 | short *e = &Statics::c; |
122 | unsigned short *f = &Statics::d; |
123 | unsigned int *g = &Statics::e; |
124 | int *h = &Statics::f; |
125 | unsigned long *i = &Statics::g; |
126 | long *j = &Statics::h; |
127 | float *k = &Statics::i; |
128 | EnumType *l = &Statics::j; |
129 | double *m = &Statics::k; |
130 | unsigned long long *n = &Statics::l; |
131 | long long *o = &Statics::m; |
132 | }; |
133 | |
134 | struct References { |
135 | char &a = Statics::a; |
136 | bool &b = Statics::b; |
137 | short &c = Statics::c; |
138 | unsigned short &d = Statics::d; |
139 | unsigned int &e = Statics::e; |
140 | int &f = Statics::f; |
141 | unsigned long &g = Statics::g; |
142 | long &h = Statics::h; |
143 | float &i = Statics::i; |
144 | EnumType &j = Statics::j; |
145 | double &k = Statics::k; |
146 | unsigned long long &l = Statics::l; |
147 | long long &m = Statics::m; |
148 | }; |
149 | |
150 | |
151 | constexpr ClassWithPadding ClassWithPaddingInstance; |
152 | // CHECK: (lldb) target variable -T ClassWithPaddingInstance |
153 | // CHECK-NEXT: (const ClassWithPadding) ClassWithPaddingInstance = { |
154 | // CHECK-NEXT: (char) a = '0' |
155 | // CHECK-NEXT: (short) b = 50 |
156 | // CHECK-NEXT: (char[2]) c = "01" |
157 | // CHECK-NEXT: (int) d = 100 |
158 | // CHECK-NEXT: (char) e = '0' |
159 | // CHECK-NEXT: (int) f = 200 |
160 | // CHECK-NEXT: (long long) g = 300 |
161 | // CHECK-NEXT: (char[3]) h = "012" |
162 | // CHECK-NEXT: (long long) i = 400 |
163 | // CHECK-NEXT: (char[2]) j = "01" |
164 | // CHECK-NEXT: (long long) k = 500 |
165 | // CHECK-NEXT: (char) l = '0' |
166 | // CHECK-NEXT: (long long) m = 600 |
167 | // CHECK-NEXT: } |
168 | |
169 | constexpr ClassNoPadding ClassNoPaddingInstance; |
170 | // CHECK: (lldb) target variable -T ClassNoPaddingInstance |
171 | // CHECK-NEXT: (const ClassNoPadding) ClassNoPaddingInstance = { |
172 | // CHECK-NEXT: (unsigned char) a = 'V' |
173 | // CHECK-NEXT: (char) b = 'a' |
174 | // CHECK-NEXT: (bool) c = false |
175 | // CHECK-NEXT: (bool) d = true |
176 | // CHECK-NEXT: (short) e = -1234 |
177 | // CHECK-NEXT: (unsigned short) f = 8123 |
178 | // CHECK-NEXT: (unsigned int) g = 123908 |
179 | // CHECK-NEXT: (int) h = -890234 |
180 | // CHECK-NEXT: (unsigned long) i = 2908234 |
181 | // CHECK-NEXT: (long) j = 7234890 |
182 | // CHECK-NEXT: (float) k = 908234.125 |
183 | // CHECK-NEXT: (EnumType) l = A |
184 | // CHECK-NEXT: (double) m = 23890.897422999999 |
185 | // CHECK-NEXT: (unsigned long long) n = 23490782 |
186 | // CHECK-NEXT: (long long) o = -923409823 |
187 | // CHECK-NEXT: (int[5]) p = { |
188 | // CHECK-NEXT: (int) [0] = 2 |
189 | // CHECK-NEXT: (int) [1] = 3 |
190 | // CHECK-NEXT: (int) [2] = 5 |
191 | // CHECK-NEXT: (int) [3] = 8 |
192 | // CHECK-NEXT: (int) [4] = 13 |
193 | // CHECK-NEXT: } |
194 | // CHECK-NEXT: } |
195 | |
196 | constexpr DerivedClass DC(10, 20); |
197 | // CHECK: (lldb) target variable -T DC |
198 | // CHECK-NEXT: (const DerivedClass) DC = { |
199 | // CHECK-NEXT: (BaseClass<int>) BaseClass<int> = { |
200 | // CHECK-NEXT: (int) BaseMember = 10 |
201 | // CHECK-NEXT: } |
202 | // CHECK-NEXT: (int) DerivedMember = 20 |
203 | // CHECK-NEXT: } |
204 | |
205 | constexpr EBO EBOC(20); |
206 | // CHECK: (lldb) target variable -T EBOC |
207 | // CHECK-NEXT: (const EBO) EBOC = { |
208 | // CHECK-NEXT: (int) Member = 20 |
209 | // CHECK-NEXT: } |
210 | |
211 | constexpr PaddedBases PBC('a', 12, 120, 1200); |
212 | // CHECK: (lldb) target variable -T PBC |
213 | // CHECK-NEXT: (const PaddedBases) PBC = { |
214 | // CHECK-NEXT: (BaseClass<char>) BaseClass<char> = { |
215 | // CHECK-NEXT: (int) BaseMember = 97 |
216 | // CHECK-NEXT: } |
217 | // CHECK-NEXT: (BaseClass<short>) BaseClass<short> = { |
218 | // CHECK-NEXT: (int) BaseMember = 12 |
219 | // CHECK-NEXT: } |
220 | // CHECK-NEXT: (BaseClass<int>) BaseClass<int> = { |
221 | // CHECK-NEXT: (int) BaseMember = 120 |
222 | // CHECK-NEXT: } |
223 | // CHECK-NEXT: (long long) DerivedMember = 1200 |
224 | // CHECK-NEXT: } |
225 | |
226 | constexpr struct { |
227 | int x = 12; |
228 | EBO EBOC{ 42 }; |
229 | } UnnamedClassInstance; |
230 | // CHECK: (lldb) target variable -T UnnamedClassInstance |
231 | // CHECK-NEXT: (const <unnamed-type-UnnamedClassInstance>) UnnamedClassInstance = { |
232 | // CHECK-NEXT: (int) x = 12 |
233 | // CHECK-NEXT: (EBO) EBOC = { |
234 | // CHECK-NEXT: (int) Member = 42 |
235 | // CHECK-NEXT: } |
236 | // CHECK-NEXT: } |
237 | |
238 | constexpr Pointers PointersInstance; |
239 | // CHECK: (lldb) target variable -T PointersInstance |
240 | // CHECK-NEXT: (const Pointers) PointersInstance = { |
241 | // CHECK-NEXT: (void *) a = {{.*}} |
242 | // CHECK-NEXT: (char *) b = {{.*}} |
243 | // CHECK-NEXT: (bool *) c = {{.*}} |
244 | // CHECK-NEXT: (short *) e = {{.*}} |
245 | // CHECK-NEXT: (unsigned short *) f = {{.*}} |
246 | // CHECK-NEXT: (unsigned int *) g = {{.*}} |
247 | // CHECK-NEXT: (int *) h = {{.*}} |
248 | // CHECK-NEXT: (unsigned long *) i = {{.*}} |
249 | // CHECK-NEXT: (long *) j = {{.*}} |
250 | // CHECK-NEXT: (float *) k = {{.*}} |
251 | // CHECK-NEXT: (EnumType *) l = {{.*}} |
252 | // CHECK-NEXT: (double *) m = {{.*}} |
253 | // CHECK-NEXT: (unsigned long long *) n = {{.*}} |
254 | // CHECK-NEXT: (long long *) o = {{.*}} |
255 | // CHECK-NEXT: } |
256 | constexpr References ReferencesInstance; |
257 | // CHECK: (lldb) target variable -T ReferencesInstance |
258 | // CHECK-NEXT: (const References) ReferencesInstance = { |
259 | // CHECK-NEXT: (char &) a = {{.*}} |
260 | // CHECK-NEXT: (bool &) b = {{.*}} |
261 | // CHECK-NEXT: (short &) c = {{.*}} |
262 | // CHECK-NEXT: (unsigned short &) d = {{.*}} |
263 | // CHECK-NEXT: (unsigned int &) e = {{.*}} |
264 | // CHECK-NEXT: (int &) f = {{.*}} |
265 | // CHECK-NEXT: (unsigned long &) g = {{.*}} |
266 | // CHECK-NEXT: (long &) h = {{.*}} |
267 | // CHECK-NEXT: (float &) i = {{.*}} |
268 | // CHECK-NEXT: (EnumType &) j = {{.*}} |
269 | // CHECK-NEXT: (double &) k = {{.*}} |
270 | // CHECK-NEXT: (unsigned long long &) l = {{.*}} |
271 | // CHECK-NEXT: (long long &) m = {{.*}} |
272 | // CHECK-NEXT: } |
273 | |
274 | // CHECK: Dumping clang ast for 1 modules. |
275 | // CHECK: TranslationUnitDecl {{.*}} |
276 | // CHECK: |-CXXRecordDecl {{.*}} class ClassWithPadding definition |
277 | // CHECK: | |-FieldDecl {{.*}} a 'char' |
278 | // CHECK: | |-FieldDecl {{.*}} b 'short' |
279 | // CHECK: | |-FieldDecl {{.*}} c 'char[2]' |
280 | // CHECK: | |-FieldDecl {{.*}} d 'int' |
281 | // CHECK: | |-FieldDecl {{.*}} e 'char' |
282 | // CHECK: | |-FieldDecl {{.*}} f 'int' |
283 | // CHECK: | |-FieldDecl {{.*}} g 'long long' |
284 | // CHECK: | |-FieldDecl {{.*}} h 'char[3]' |
285 | // CHECK: | |-FieldDecl {{.*}} i 'long long' |
286 | // CHECK: | |-FieldDecl {{.*}} j 'char[2]' |
287 | // CHECK: | |-FieldDecl {{.*}} k 'long long' |
288 | // CHECK: | |-FieldDecl {{.*}} l 'char' |
289 | // CHECK: | `-FieldDecl {{.*}} m 'long long' |
290 | // CHECK: |-VarDecl {{.*}} ClassWithPaddingInstance 'const ClassWithPadding' |
291 | // CHECK: |-CXXRecordDecl {{.*}} class ClassNoPadding definition |
292 | // CHECK: | |-FieldDecl {{.*}} a 'unsigned char' |
293 | // CHECK: | |-FieldDecl {{.*}} b 'char' |
294 | // CHECK: | |-FieldDecl {{.*}} c 'bool' |
295 | // CHECK: | |-FieldDecl {{.*}} d 'bool' |
296 | // CHECK: | |-FieldDecl {{.*}} e 'short' |
297 | // CHECK: | |-FieldDecl {{.*}} f 'unsigned short' |
298 | // CHECK: | |-FieldDecl {{.*}} g 'unsigned int' |
299 | // CHECK: | |-FieldDecl {{.*}} h 'int' |
300 | // CHECK: | |-FieldDecl {{.*}} i 'unsigned long' |
301 | // CHECK: | |-FieldDecl {{.*}} j 'long' |
302 | // CHECK: | |-FieldDecl {{.*}} k 'float' |
303 | // CHECK: | |-FieldDecl {{.*}} l 'EnumType' |
304 | // CHECK: | |-FieldDecl {{.*}} m 'double' |
305 | // CHECK: | |-FieldDecl {{.*}} n 'unsigned long long' |
306 | // CHECK: | |-FieldDecl {{.*}} o 'long long' |
307 | // CHECK: | `-FieldDecl {{.*}} p 'int[5]' |
308 | // CHECK: |-VarDecl {{.*}} ClassNoPaddingInstance 'const ClassNoPadding' |
309 | // CHECK: |-EnumDecl {{.*}} EnumType |
310 | // CHECK: | |-EnumConstantDecl {{.*}} A 'EnumType' |
311 | // CHECK: | `-EnumConstantDecl {{.*}} B 'EnumType' |
312 | // CHECK: |-CXXRecordDecl {{.*}} struct DerivedClass definition |
313 | // CHECK: | |-public 'BaseClass<int>' |
314 | // CHECK: | |-CXXConstructorDecl {{.*}} DerivedClass 'void (int, int)' |
315 | // CHECK: | | |-ParmVarDecl {{.*}} 'int' |
316 | // CHECK: | | `-ParmVarDecl {{.*}} 'int' |
317 | // CHECK: | `-FieldDecl {{.*}} DerivedMember 'int' |
318 | // CHECK: |-VarDecl {{.*}} DC 'const DerivedClass' |
319 | // CHECK: |-CXXRecordDecl {{.*}} struct BaseClass<int> definition |
320 | // CHECK: | |-CXXMethodDecl {{.*}} BaseClass 'void (int)' |
321 | // CHECK: | | `-ParmVarDecl {{.*}} 'int' |
322 | // CHECK: | `-FieldDecl {{.*}} BaseMember 'int' |
323 | // CHECK: |-CXXRecordDecl {{.*}} struct EBO definition |
324 | // CHECK: | |-public 'EmptyBase' |
325 | // CHECK: | |-CXXConstructorDecl {{.*}} EBO 'void (int)' |
326 | // CHECK: | | `-ParmVarDecl {{.*}} 'int' |
327 | // CHECK: | `-FieldDecl {{.*}} Member 'int' |
328 | // CHECK: |-VarDecl {{.*}} EBOC 'const EBO' |
329 | // CHECK: |-CXXRecordDecl {{.*}} struct EmptyBase definition |
330 | // CHECK: |-CXXRecordDecl {{.*}} struct PaddedBases definition |
331 | // CHECK: | |-public 'BaseClass<char>' |
332 | // CHECK: | |-public 'BaseClass<short>' |
333 | // CHECK: | |-public 'BaseClass<int>' |
334 | // CHECK: | |-CXXConstructorDecl {{.*}} PaddedBases 'void (char, short, int, long long)' |
335 | // CHECK: | | |-ParmVarDecl {{.*}} 'char' |
336 | // CHECK: | | |-ParmVarDecl {{.*}} 'short' |
337 | // CHECK: | | |-ParmVarDecl {{.*}} 'int' |
338 | // CHECK: | | `-ParmVarDecl {{.*}} 'long long' |
339 | // CHECK: | `-FieldDecl {{.*}} DerivedMember 'long long' |
340 | // CHECK: |-VarDecl {{.*}} PBC 'const PaddedBases' |
341 | // CHECK: |-CXXRecordDecl {{.*}} struct BaseClass<char> definition |
342 | // CHECK: | |-CXXMethodDecl {{.*}} BaseClass 'void (int)' |
343 | // CHECK: | | `-ParmVarDecl {{.*}} 'int' |
344 | // CHECK: | `-FieldDecl {{.*}} BaseMember 'int' |
345 | // CHECK: |-CXXRecordDecl {{.*}} struct BaseClass<short> definition |
346 | // CHECK: | |-CXXMethodDecl {{.*}} BaseClass 'void (int)' |
347 | // CHECK: | | `-ParmVarDecl {{.*}} 'int' |
348 | // CHECK: | `-FieldDecl {{.*}} BaseMember 'int' |
349 | // CHECK: |-CXXRecordDecl {{.*}} struct <unnamed-type-UnnamedClassInstance> definition |
350 | // CHECK: | |-FieldDecl {{.*}} x 'int' |
351 | // CHECK: | `-FieldDecl {{.*}} EBOC 'EBO' |
352 | // CHECK: |-VarDecl {{.*}} UnnamedClassInstance 'const <unnamed-type-UnnamedClassInstance>' |
353 | // CHECK: |-CXXRecordDecl {{.*}} struct Pointers definition |
354 | // CHECK: | |-FieldDecl {{.*}} a 'void *' |
355 | // CHECK: | |-FieldDecl {{.*}} b 'char *' |
356 | // CHECK: | |-FieldDecl {{.*}} c 'bool *' |
357 | // CHECK: | |-FieldDecl {{.*}} e 'short *' |
358 | // CHECK: | |-FieldDecl {{.*}} f 'unsigned short *' |
359 | // CHECK: | |-FieldDecl {{.*}} g 'unsigned int *' |
360 | // CHECK: | |-FieldDecl {{.*}} h 'int *' |
361 | // CHECK: | |-FieldDecl {{.*}} i 'unsigned long *' |
362 | // CHECK: | |-FieldDecl {{.*}} j 'long *' |
363 | // CHECK: | |-FieldDecl {{.*}} k 'float *' |
364 | // CHECK: | |-FieldDecl {{.*}} l 'EnumType *' |
365 | // CHECK: | |-FieldDecl {{.*}} m 'double *' |
366 | // CHECK: | |-FieldDecl {{.*}} n 'unsigned long long *' |
367 | // CHECK: | `-FieldDecl {{.*}} o 'long long *' |
368 | // CHECK: |-VarDecl {{.*}} PointersInstance 'const Pointers' |
369 | // CHECK: |-CXXRecordDecl {{.*}} struct References definition |
370 | // CHECK: | |-FieldDecl {{.*}} a 'char &' |
371 | // CHECK: | |-FieldDecl {{.*}} b 'bool &' |
372 | // CHECK: | |-FieldDecl {{.*}} c 'short &' |
373 | // CHECK: | |-FieldDecl {{.*}} d 'unsigned short &' |
374 | // CHECK: | |-FieldDecl {{.*}} e 'unsigned int &' |
375 | // CHECK: | |-FieldDecl {{.*}} f 'int &' |
376 | // CHECK: | |-FieldDecl {{.*}} g 'unsigned long &' |
377 | // CHECK: | |-FieldDecl {{.*}} h 'long &' |
378 | // CHECK: | |-FieldDecl {{.*}} i 'float &' |
379 | // CHECK: | |-FieldDecl {{.*}} j 'EnumType &' |
380 | // CHECK: | |-FieldDecl {{.*}} k 'double &' |
381 | // CHECK: | |-FieldDecl {{.*}} l 'unsigned long long &' |
382 | // CHECK: | `-FieldDecl {{.*}} m 'long long &' |
383 | // CHECK: `-VarDecl {{.*}} ReferencesInstance 'const References' |
384 | |
385 | int main(int argc, char **argv) { |
386 | return 0; |
387 | } |
388 | |