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
11enum class EnumType : unsigned {
12 A = 1,
13 B = 2
14};
15
16class 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
35class 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
58struct EmptyBase {};
59
60template<typename T>
61struct BaseClass {
62 constexpr BaseClass(int N)
63 : BaseMember(N) {}
64
65 int BaseMember;
66};
67
68struct DerivedClass : public BaseClass<int> {
69 constexpr DerivedClass(int Base, int Derived)
70 : BaseClass(Base), DerivedMember(Derived) {}
71
72 int DerivedMember;
73};
74
75struct EBO : public EmptyBase {
76 constexpr EBO(int N) : Member(N) {}
77 int Member;
78};
79
80struct 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
86struct 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
102char Statics::a = 'a';
103bool Statics::b = true;
104short Statics::c = 1234;
105unsigned short Statics::d = 2345;
106unsigned int Statics::e = 3456;
107int Statics::f = 4567;
108unsigned long Statics::g = 5678;
109long Statics::h = 6789;
110float Statics::i = 7890.1234;
111EnumType Statics::j = EnumType::A;
112double Statics::k = 8901.2345;
113unsigned long long Statics::l = 9012345;
114long long Statics::m = 1234567;
115
116
117struct 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
134struct 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
151constexpr 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
169constexpr 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
196constexpr 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
205constexpr 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
211constexpr 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
226constexpr 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
238constexpr 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: }
256constexpr 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
385int main(int argc, char **argv) {
386 return 0;
387}
388

source code of lldb/test/Shell/SymbolFile/NativePDB/global-classes.cpp