xref: /llvm-project/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp (revision cf3464bbb796d492bcd4e764ada945304e0c874f)
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: %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.
11 class TrivialC {};
12 struct TrivialS {};
13 union TrivialU {};
14 enum TrivialE {TE_A};
15 
16 // Test reconstruction of DeclContext hierarchies.
17 namespace 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.
53 namespace {
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 
64 TrivialC TC;
65 TrivialS TS;
66 TrivialU TU;
67 TrivialE TE;
68 
69 A::B::C<int> ABCInt;
70 A::B::C<float> ABCFloat;
71 A::B::C<void> ABCVoid;
72 
73 A::C<0> AC0;
74 A::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>`.
78 A::C<1>::D AC1D;
79 
80 A::C<0>::D AC0D;
81 A::C<-1>::D ACNeg1D;
82 A::D AD;
83 A::D::E ADE;
84 
85 Anonymous<int> AnonInt;
86 Anonymous<A::B::C<void>> AnonABCVoid;
87 Anonymous<A::B::C<void>>::D AnonABCVoidD;
88 
89 // The following tests that MSInheritanceAttr are set for record decls.
90 class  SI { int si; };
91 struct SI2 { int si2; };
92 class  MI : SI, SI2 { int mi; };
93 class MI2 : MI { int mi2; };
94 class VI : virtual MI { int vi; };
95 class VI2 : virtual SI, virtual SI2 { int vi; };
96 class/* __unspecified_inheritance*/ UI;
97 
98 typedef void (SI::*SITYPE)();
99 typedef void (MI::*MITYPE)();
100 typedef void (MI2::*MI2TYPE)();
101 typedef void (VI::*VITYPE)();
102 typedef void (VI2::*VI2TYPE)();
103 typedef void (UI::*UITYPE)();
104 SITYPE mp1 = nullptr;
105 MITYPE mp2 = nullptr;
106 MI2TYPE mp3 = nullptr;
107 VITYPE mp4 = nullptr;
108 VI2TYPE mp5 = nullptr;
109 UITYPE mp6 = nullptr;
110 MITYPE *mp7 = nullptr;
111 VI2TYPE *mp8 = nullptr;
112 int 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 
182 int main(int argc, char **argv) {
183   AnonInt.AnonymousMember = 1;
184   AnonABCVoid.AnonymousMember = 2;
185   AnonABCVoidD.AnonymousDMember = 3;
186 
187   return 0;
188 }
189