1// clang-format off
2// REQUIRES: lld, x86
3
4// Test various interesting cases for AST reconstruction.
5// RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 -c /Fo%t.obj -- %s
6// RUN: lld-link -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb
7// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
8// RUN: %p/Inputs/ast-types.lldbinit 2>&1 | FileCheck %s
9
10// Test trivial versions of each tag type.
11class TrivialC {};
12struct TrivialS {};
13union TrivialU {};
14enum TrivialE {TE_A};
15
16// Test reconstruction of DeclContext hierarchies.
17namespace A {
18 namespace B {
19 template<typename T>
20 struct C {
21 T ABCMember;
22 };
23
24 // Let's try a template specialization with a different implementation
25 template<>
26 struct C<void> {
27 void *ABCSpecializationMember;
28 };
29 }
30
31 // Let's make sure we can distinguish classes and namespaces. Also let's try
32 // a non-type template parameter.
33 template<int N>
34 struct C {
35 class D {
36 int ACDMember = 0;
37 C<N - 1> *CPtr = nullptr;
38 };
39 };
40
41 struct D {
42 // Let's make a nested class with the same name as another nested class
43 // elsewhere, and confirm that they appear in the right DeclContexts in
44 // the AST.
45 struct E {
46 int ADDMember;
47 };
48 };
49}
50
51
52// Let's try an anonymous namespace.
53namespace {
54 template<typename T>
55 struct Anonymous {
56 int AnonymousMember;
57 // And a nested class within an anonymous namespace
58 struct D {
59 int AnonymousDMember;
60 };
61 };
62}
63
64TrivialC TC;
65TrivialS TS;
66TrivialU TU;
67TrivialE TE;
68
69A::B::C<int> ABCInt;
70A::B::C<float> ABCFloat;
71A::B::C<void> ABCVoid;
72
73A::C<0> AC0;
74A::C<-1> ACNeg1;
75
76// FIXME: The type `D` is located now at the level of the translation unit.
77// FIXME: Should be located in the namespace `A`, in the struct `C<1>`.
78A::C<1>::D AC1D;
79
80A::C<0>::D AC0D;
81A::C<-1>::D ACNeg1D;
82A::D ;
83A::D::E ADE;
84
85Anonymous<int> AnonInt;
86Anonymous<A::B::C<void>> AnonABCVoid;
87Anonymous<A::B::C<void>>::D AnonABCVoidD;
88
89// The following tests that MSInheritanceAttr are set for record decls.
90class SI { int si; };
91struct SI2 { int si2; };
92class MI : SI, SI2 { int mi; };
93class MI2 : MI { int mi2; };
94class VI : virtual MI { int vi; };
95class VI2 : virtual SI, virtual SI2 { int vi; };
96class/* __unspecified_inheritance*/ UI;
97
98typedef void (SI::*SITYPE)();
99typedef void (MI::*MITYPE)();
100typedef void (MI2::*MI2TYPE)();
101typedef void (VI::*VITYPE)();
102typedef void (VI2::*VI2TYPE)();
103typedef void (UI::*UITYPE)();
104SITYPE mp1 = nullptr;
105MITYPE mp2 = nullptr;
106MI2TYPE mp3 = nullptr;
107VITYPE mp4 = nullptr;
108VI2TYPE mp5 = nullptr;
109UITYPE mp6 = nullptr;
110MITYPE *mp7 = nullptr;
111VI2TYPE *mp8 = nullptr;
112int SI::*mp9 = nullptr;
113
114// FIXME: Enum size isn't being correctly determined.
115// FIXME: Can't read memory for variable values.
116
117// CHECK: (TrivialC) TC = {}
118// CHECK: (TrivialS) TS = {}
119// CHECK: (TrivialU) TU = {}
120// CHECK: (TrivialE) TE = TE_A
121// CHECK: (A::B::C<int>) ABCInt = (ABCMember = 0)
122// CHECK: (A::B::C<float>) ABCFloat = (ABCMember = 0)
123// CHECK: (A::B::C<void>) ABCVoid = (ABCSpecializationMember = 0x{{0+}})
124// CHECK: (A::C<0>) AC0 = {}
125// CHECK: (A::C<-1>) ACNeg1 = {}
126// CHECK: (A::C<1>::D) AC1D = (ACDMember = 0, CPtr = 0x{{0+}})
127// CHECK: (A::C<0>::D) AC0D = (ACDMember = 0, CPtr = 0x{{0+}})
128// CHECK: (A::C<-1>::D) ACNeg1D = (ACDMember = 0, CPtr = 0x{{0+}})
129// CHECK: (A::D) AD = {}
130// CHECK: (A::D::E) ADE = (ADDMember = 0)
131// CHECK: (Anonymous<int>) AnonInt = (AnonymousMember = 0)
132// CHECK: (Anonymous<A::B::C<void>>) AnonABCVoid = (AnonymousMember = 0)
133// CHECK: (Anonymous<A::B::C<void>>::D) AnonABCVoidD = (AnonymousDMember = 0)
134// CHECK: (void (SI::*)()) mp1 = 0x0000000000000000
135// CHECK: (void (MI::*)()) mp2 = 0x0000000000000000
136// CHECK: (void (MI2::*)()) mp3 = 0x0000000000000000
137// CHECK: (void (VI::*)()) mp4 = 0x0000000000000000
138// CHECK: (void (VI2::*)()) mp5 = 0x0000000000000000
139// CHECK: (void (UI::*)()) mp6 = 0x0000000000000000
140// CHECK: (void (MI::**)()) mp7 = 0x0000000000000000
141// CHECK: (void (VI2::**)()) mp8 = 0x0000000000000000
142// CHECK: (int SI::*) mp9 = 0xffffffff
143// CHECK: Dumping clang ast for 1 modules.
144// CHECK: TranslationUnitDecl {{.*}}
145// CHECK: |-CXXRecordDecl {{.*}} class TrivialC definition
146// CHECK: |-CXXRecordDecl {{.*}} struct TrivialS definition
147// CHECK: |-CXXRecordDecl {{.*}} union TrivialU definition
148// CHECK: |-EnumDecl {{.*}} TrivialE
149// CHECK: | `-EnumConstantDecl {{.*}} TE_A 'TrivialE'
150// CHECK: |-NamespaceDecl {{.*}} A
151// CHECK: | |-NamespaceDecl {{.*}} B
152// CHECK: | | |-CXXRecordDecl {{.*}} struct C<int> definition
153// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'int'
154// CHECK: | | |-CXXRecordDecl {{.*}} struct C<float> definition
155// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'float'
156// CHECK: | | `-CXXRecordDecl {{.*}} struct C<void> definition
157// CHECK: | | `-FieldDecl {{.*}} ABCSpecializationMember 'void *'
158// FIXME: | |-CXXRecordDecl {{.*}} struct C<1> definition
159// FIXME: | | `-CXXRecordDecl {{.*}} class D definition
160// FIXME: | | |-FieldDecl {{.*}} ACDMember 'int'
161// FIXME: | | `-FieldDecl {{.*}} CPtr 'A::C<1> *'
162// CHECK: | |-CXXRecordDecl {{.*}} struct C<0> definition
163// CHECK: | | `-CXXRecordDecl {{.*}} class D definition
164// CHECK: | | |-FieldDecl {{.*}} ACDMember 'int'
165// CHECK: | | `-FieldDecl {{.*}} CPtr 'A::C<-1> *'
166// CHECK: | |-CXXRecordDecl {{.*}} struct C<-1> definition
167// CHECK: | | `-CXXRecordDecl {{.*}} class D definition
168// CHECK: | | |-FieldDecl {{.*}} ACDMember 'int'
169// CHECK: | | `-FieldDecl {{.*}} CPtr 'A::C<-2> *'
170// CHECK: | |-CXXRecordDecl {{.*}} struct C<-2>
171// CHECK: | `-CXXRecordDecl {{.*}} struct D definition
172// CHECK: | `-CXXRecordDecl {{.*}} struct E definition
173// CHECK: | `-FieldDecl {{.*}} ADDMember 'int'
174// CHECK: |-NamespaceDecl
175// CHECK: | |-CXXRecordDecl {{.*}} struct Anonymous<int> definition
176// CHECK: | | `-FieldDecl {{.*}} AnonymousMember 'int'
177// CHECK: | `-CXXRecordDecl {{.*}} struct Anonymous<A::B::C<void>> definition
178// CHECK: | |-FieldDecl {{.*}} AnonymousMember 'int'
179// CHECK: | `-CXXRecordDecl {{.*}} struct D definition
180// CHECK: | `-FieldDecl {{.*}} AnonymousDMember 'int'
181
182int main(int argc, char **argv) {
183 AnonInt.AnonymousMember = 1;
184 AnonABCVoid.AnonymousMember = 2;
185 AnonABCVoidD.AnonymousDMember = 3;
186
187 return 0;
188}
189

source code of lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp