1 | // RUN: rm -rf %t |
2 | // Test that only forward declarations are emitted for types defined in modules. |
3 | |
4 | // Modules: |
5 | // RUN: %clang_cc1 -x objective-c++ -std=c++11 -debug-info-kind=standalone \ |
6 | // RUN: -dwarf-ext-refs -fmodules \ |
7 | // RUN: -fmodule-format=obj -fimplicit-module-maps -DMODULES \ |
8 | // RUN: -triple %itanium_abi_triple \ |
9 | // RUN: -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t-mod.ll |
10 | // RUN: cat %t-mod.ll | FileCheck %s |
11 | |
12 | // PCH: |
13 | // RUN: %clang_cc1 -x c++ -std=c++11 -fmodule-format=obj -emit-pch -I%S/Inputs \ |
14 | // RUN: -triple %itanium_abi_triple \ |
15 | // RUN: -o %t.pch %S/Inputs/DebugCXX.h |
16 | // RUN: %clang_cc1 -std=c++11 -debug-info-kind=standalone \ |
17 | // RUN: -dwarf-ext-refs -fmodule-format=obj \ |
18 | // RUN: -triple %itanium_abi_triple \ |
19 | // RUN: -include-pch %t.pch %s -emit-llvm -o %t-pch.ll |
20 | // RUN: cat %t-pch.ll | FileCheck %s |
21 | // RUN: cat %t-pch.ll | FileCheck %s --check-prefix=CHECK-PCH |
22 | |
23 | #ifdef MODULES |
24 | @import DebugCXX; |
25 | #endif |
26 | |
27 | using DebugCXX::Struct; |
28 | |
29 | Struct s; |
30 | DebugCXX::Enum e; |
31 | |
32 | // Template instantiations. |
33 | DebugCXX::Template<long> implicitTemplate; |
34 | DebugCXX::Template<int> explicitTemplate; |
35 | DebugCXX::FloatInstantiation typedefTemplate; |
36 | DebugCXX::B anchoredTemplate; |
37 | |
38 | int Struct::static_member = -1; |
39 | enum { |
40 | e3 = -1 |
41 | } conflicting_uid = e3; |
42 | auto anon_enum = DebugCXX::e2; |
43 | char _anchor = anon_enum + conflicting_uid; |
44 | |
45 | TypedefUnion tdu; |
46 | TypedefEnum tde; |
47 | TypedefStruct tds; |
48 | TypedefTemplate tdt; |
49 | Template1<int> explicitTemplate1; |
50 | |
51 | template <class T> class FwdDeclTemplate { T t; }; |
52 | TypedefFwdDeclTemplate tdfdt; |
53 | |
54 | InAnonymousNamespace anon; |
55 | |
56 | // Types that are forward-declared in the module and defined here. |
57 | struct PureFwdDecl { int i; }; |
58 | PureFwdDecl definedLocally; |
59 | |
60 | struct Specialized<int>::Member { int i; }; |
61 | struct Specialized<int>::Member definedLocally2; |
62 | |
63 | template <class T> struct FwdDeclTemplateMember<T>::Member { T t; }; |
64 | TypedefFwdDeclTemplateMember tdfdtm; |
65 | |
66 | SpecializedBase definedLocally3; |
67 | extern template class WithSpecializedBase<int>; |
68 | WithSpecializedBase<int> definedLocally4; |
69 | |
70 | void foo() { |
71 | anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum; |
72 | A a; |
73 | Virtual virt; |
74 | } |
75 | |
76 | // CHECK: ![[CPP:.*]] = !DIFile(filename: {{.*}}ExtDebugInfo.cpp" |
77 | |
78 | // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum", |
79 | // CHECK-SAME: scope: ![[NS:[0-9]+]], |
80 | // CHECK-SAME: flags: DIFlagFwdDecl, |
81 | // CHECK-SAME: identifier: "_ZTSN8DebugCXX4EnumE") |
82 | |
83 | // CHECK: ![[NS]] = !DINamespace(name: "DebugCXX", scope: ![[MOD:[0-9]+]]) |
84 | // CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugCXX |
85 | |
86 | // This type is not anchored in the module by an explicit template instantiation. |
87 | // CHECK: !DICompositeType(tag: DW_TAG_class_type, |
88 | // CHECK-SAME: name: "Template<long, DebugCXX::traits<long> >", |
89 | // CHECK-SAME: scope: ![[NS]], |
90 | // CHECK-SAME: elements: |
91 | // CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIlNS_6traitsIlEEEE") |
92 | |
93 | // This type is anchored in the module by an explicit template instantiation. |
94 | // CHECK: !DICompositeType(tag: DW_TAG_class_type, |
95 | // CHECK-SAME: name: "Template<int, DebugCXX::traits<int> >", |
96 | // CHECK-SAME: scope: ![[NS]], |
97 | // CHECK-SAME: flags: DIFlagFwdDecl, |
98 | // CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE") |
99 | |
100 | // This type isn't, however, even with standalone non-module debug info this |
101 | // type is a forward declaration. |
102 | // CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "traits<int>", |
103 | |
104 | // This one isn't. |
105 | // CHECK: !DICompositeType(tag: DW_TAG_class_type, |
106 | // CHECK-SAME: name: "Template<float, DebugCXX::traits<float> >", |
107 | // CHECK-SAME: scope: ![[NS]], |
108 | // CHECK-SAME: elements: |
109 | // CHECK-SAME: templateParams: |
110 | // CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE") |
111 | |
112 | // This type is anchored in the module by an explicit template instantiation. |
113 | // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "traits<float>", |
114 | // CHECK-SAME: flags: DIFlagFwdDecl, |
115 | // CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIfEE") |
116 | |
117 | |
118 | // This type is anchored in the module via a function argument, |
119 | // but we don't know this (yet). |
120 | // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A<void>", |
121 | // CHECK-SAME: scope: ![[NS]], |
122 | // CHECK-SAME: elements: |
123 | // CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE") |
124 | |
125 | // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_member", |
126 | // CHECK-SAME: scope: ![[STRUCT:[0-9]*]] |
127 | |
128 | // CHECK: ![[STRUCT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Struct", |
129 | // CHECK-SAME: scope: ![[NS]], |
130 | // CHECK-SAME: flags: DIFlagFwdDecl, |
131 | // CHECK-SAME: identifier: "_ZTSN8DebugCXX6StructE") |
132 | |
133 | // CHECK: !DICompositeType(tag: DW_TAG_union_type, |
134 | // CHECK-SAME: flags: DIFlagFwdDecl, |
135 | // CHECK-SAME: identifier: "_ZTS12TypedefUnion") |
136 | // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, |
137 | // CHECK-SAME: flags: DIFlagFwdDecl, |
138 | // CHECK-SAME: identifier: "_ZTS11TypedefEnum") |
139 | // CHECK: !DICompositeType(tag: DW_TAG_structure_type, |
140 | // CHECK-SAME: flags: DIFlagFwdDecl, |
141 | // CHECK-SAME: identifier: "_ZTS13TypedefStruct") |
142 | |
143 | // This one isn't. |
144 | // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1<void *>", |
145 | // CHECK-SAME: elements: |
146 | // CHECK-SAME: templateParams: |
147 | // CHECK-SAME: identifier: "_ZTS9Template1IPvE") |
148 | |
149 | // This type is anchored in the module by an explicit template instantiation. |
150 | // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1<int>", |
151 | // CHECK-SAME: flags: DIFlagFwdDecl, |
152 | // CHECK-SAME: identifier: "_ZTS9Template1IiE") |
153 | |
154 | // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdDeclTemplate<int>", |
155 | // CHECK-SAME: elements: |
156 | // CHECK-SAME: templateParams: |
157 | // CHECK-SAME: identifier: "_ZTS15FwdDeclTemplateIiE") |
158 | |
159 | // This type is defined locally and forward-declared in the module. |
160 | // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "PureFwdDecl", |
161 | // CHECK-SAME: elements: |
162 | // CHECK-SAME: identifier: "_ZTS11PureFwdDecl") |
163 | |
164 | // This type is defined locally and forward-declared in the module. |
165 | // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Member", |
166 | // CHECK-SAME: elements: |
167 | // CHECK-SAME: identifier: "_ZTSN11SpecializedIiE6MemberE") |
168 | |
169 | // This type is defined locally and forward-declared in the module. |
170 | // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Member", |
171 | // CHECK-SAME: elements: |
172 | // CHECK-SAME: identifier: "_ZTSN21FwdDeclTemplateMemberIiE6MemberE") |
173 | |
174 | // This type is defined locally and forward-declared in the module. |
175 | // CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "SpecializedBase", |
176 | // CHECK-SAME: baseType: ![[SPECIALIZEDBASE:.*]]) |
177 | // CHECK: ![[SPECIALIZEDBASE]] = |
178 | // CHECK-SAME: !DICompositeType(tag: DW_TAG_class_type, |
179 | // CHECK-SAME: name: "WithSpecializedBase<float>", |
180 | // CHECK-SAME: elements: |
181 | // CHECK-SAME: identifier: "_ZTS19WithSpecializedBaseIfE") |
182 | |
183 | // This type is explicitly specialized locally. |
184 | // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "WithSpecializedBase<int>", |
185 | // CHECK-SAME: elements: |
186 | // CHECK-SAME: identifier: "_ZTS19WithSpecializedBaseIiE") |
187 | |
188 | // CHECK: !DIGlobalVariable(name: "anon_enum", {{.*}}, type: ![[ANON_ENUM:[0-9]+]] |
189 | // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, scope: ![[NS]], |
190 | // CHECK-SAME: line: 19 |
191 | |
192 | // CHECK: !DIGlobalVariable(name: "GlobalUnion", |
193 | // CHECK-SAME: type: ![[GLOBAL_UNION:[0-9]+]] |
194 | // CHECK: ![[GLOBAL_UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type, |
195 | // CHECK-SAME: elements: !{{[0-9]+}}) |
196 | // CHECK: !DIGlobalVariable(name: "GlobalStruct", |
197 | // CHECK-SAME: type: ![[GLOBAL_STRUCT:[0-9]+]] |
198 | // CHECK: ![[GLOBAL_STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type, |
199 | // CHECK-SAME: elements: !{{[0-9]+}}) |
200 | |
201 | |
202 | // CHECK: !DIGlobalVariable(name: "anon", |
203 | // CHECK-SAME: type: ![[GLOBAL_ANON:[0-9]+]] |
204 | // CHECK: ![[GLOBAL_ANON]] = !DICompositeType(tag: DW_TAG_structure_type, |
205 | // CHECK-SAME: name: "InAnonymousNamespace", {{.*}}DIFlagFwdDecl) |
206 | |
207 | |
208 | // CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !{{[0-9]+}}, entity: ![[STRUCT]], file: ![[CPP]], line: 27) |
209 | |
210 | // CHECK: !DICompileUnit( |
211 | // CHECK-SAME: splitDebugFilename: |
212 | // CHECK-SAME: dwoId: |
213 | // CHECK-PCH: !DICompileUnit({{.*}}splitDebugFilename: |
214 | // CHECK-PCH: dwoId: 18446744073709551614 |
215 | |
216 | // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A", |
217 | // CHECK-SAME: DIFlagFwdDecl, identifier: "_ZTS1A") |
218 | |
219 | // There is a full definition of the type available in the module. |
220 | // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual", |
221 | // CHECK-SAME: DIFlagFwdDecl, identifier: "_ZTS7Virtual") |
222 | |