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 \
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/nested-types.lldbinit 2>&1 | FileCheck %s
10
11 struct S {
12 struct NestedStruct {
13 int A = 0;
14 int B = 1;
15 };
16
17 enum class NestedEnum {
18 EnumValue1 = 0,
19 EnumValue2 = 1,
20 };
21 int C = 2;
22 int D = 3;
23 using VoidPtrT = void *;
24 VoidPtrT DD = nullptr;
25 };
26 struct T {
27 using NestedTypedef = int;
28 using NestedTypedef2 = S;
29
30 struct NestedStruct {
31 int E = 4;
32 int F = 5;
33 };
34
35 using NestedStructAlias = NestedStruct;
36 using NST = S::NestedStruct;
37
38 NestedTypedef NT = 4;
39
40 using U = struct {
41 int G = 6;
42 int H = 7;
43 };
44 };
45
46 template<typename Param>
47 class U {
48 public:
49 // See llvm.org/pr39607. clang-cl currently doesn't emit an important debug
50 // info record for nested template instantiations, so we can't reconstruct
51 // a proper DeclContext hierarchy for these. As such, U<X>::V<Y> will show up
52 // in the global namespace.
53 template<typename Param>
54 struct V {
55 Param I = 8;
56 Param J = 9;
57
58 using W = T::NestedTypedef;
59 using X = U<int>;
60 };
61
62 struct W {
63 Param M = 12;
64 Param N = 13;
65 };
66 Param K = 10;
67 Param L = 11;
68 using Y = V<int>;
69 using Z = V<T>;
70 };
71
72 constexpr S GlobalA;
73 constexpr S::NestedStruct GlobalB;
74 constexpr T GlobalC;
75 constexpr T::NestedStruct GlobalD;
76 constexpr T::U GlobalE;
77 constexpr U<int> GlobalF;
78 constexpr U<int>::V<int> GlobalG;
79 constexpr U<int>::W GlobalH;
80 constexpr S::NestedEnum GlobalEnum = S::NestedEnum::EnumValue1;
81
82
main(int argc,char ** argv)83 int main(int argc, char **argv) {
84 return 0;
85 }
86
87
88
89 // CHECK: (lldb) target variable -T GlobalA
90 // CHECK: (const S) GlobalA = {
91 // CHECK: (int) C = 2
92 // CHECK: (int) D = 3
93 // CHECK: (void *) DD = 0x00000000
94 // CHECK: }
95 // CHECK: (lldb) target variable -T GlobalB
96 // CHECK: (const S::NestedStruct) GlobalB = {
97 // CHECK: (int) A = 0
98 // CHECK: (int) B = 1
99 // CHECK: }
100 // CHECK: (lldb) target variable -T GlobalC
101 // CHECK: (const T) GlobalC = {
102 // CHECK: (int) NT = 4
103 // CHECK: }
104 // CHECK: (lldb) target variable -T GlobalD
105 // CHECK: (const T::NestedStruct) GlobalD = {
106 // CHECK: (int) E = 4
107 // CHECK: (int) F = 5
108 // CHECK: }
109 // CHECK: (lldb) target variable -T GlobalE
110 // CHECK: (const T::U) GlobalE = {
111 // CHECK: (int) G = 6
112 // CHECK: (int) H = 7
113 // CHECK: }
114 // CHECK: (lldb) target variable -T GlobalF
115 // CHECK: (const U<int>) GlobalF = {
116 // CHECK: (int) K = 10
117 // CHECK: (int) L = 11
118 // CHECK: }
119 // CHECK: (lldb) target variable -T GlobalG
120 // CHECK: (const U<int>::V<int>) GlobalG = {
121 // CHECK: (int) I = 8
122 // CHECK: (int) J = 9
123 // CHECK: }
124 // CHECK: (lldb) target variable -T GlobalEnum
125 // CHECK: (const S::NestedEnum) GlobalEnum = EnumValue1
126 // CHECK: (lldb) target modules dump ast
127 // CHECK: Dumping clang ast for 1 modules.
128 // CHECK: TranslationUnitDecl {{.*}}
129 // CHECK: |-CXXRecordDecl {{.*}} struct S definition
130 // CHECK: | |-FieldDecl {{.*}} C 'int'
131 // CHECK: | |-FieldDecl {{.*}} D 'int'
132 // CHECK: | |-FieldDecl {{.*}} DD 'void *'
133 // CHECK: | |-CXXRecordDecl {{.*}} struct NestedStruct definition
134 // CHECK: | | |-FieldDecl {{.*}} A 'int'
135 // CHECK: | | `-FieldDecl {{.*}} B 'int'
136 // CHECK: | `-EnumDecl {{.*}} NestedEnum
137 // CHECK: | |-EnumConstantDecl {{.*}} EnumValue1 'S::NestedEnum'
138 // CHECK: | `-EnumConstantDecl {{.*}} EnumValue2 'S::NestedEnum'
139 // CHECK: |-CXXRecordDecl {{.*}} struct T definition
140 // CHECK: | |-FieldDecl {{.*}} NT 'int'
141 // CHECK: | |-CXXRecordDecl {{.*}} struct NestedStruct definition
142 // CHECK: | | |-FieldDecl {{.*}} E 'int'
143 // CHECK: | | `-FieldDecl {{.*}} F 'int'
144 // CHECK: | `-CXXRecordDecl {{.*}} struct U definition
145 // CHECK: | |-FieldDecl {{.*}} G 'int'
146 // CHECK: | `-FieldDecl {{.*}} H 'int'
147 // CHECK: |-CXXRecordDecl {{.*}} class U<int> definition
148 // CHECK: | |-FieldDecl {{.*}} K 'int'
149 // CHECK: | |-FieldDecl {{.*}} L 'int'
150 // CHECK: | `-CXXRecordDecl {{.*}} struct W definition
151 // CHECK: | |-FieldDecl {{.*}} M 'int'
152 // CHECK: | `-FieldDecl {{.*}} N 'int'
153 // CHECK: |-CXXRecordDecl {{.*}} struct U<int>::V<int> definition
154 // CHECK: | |-FieldDecl {{.*}} I 'int'
155 // CHECK: | `-FieldDecl {{.*}} J 'int'
156