aprantl created this revision.
aprantl added a reviewer: doug.gregor.
aprantl added a subscriber: cfe-commits.
aprantl set the repository for this revision to rL LLVM.
This patch fixes the condition for determining whether the debug info for a
template instantiation will exist in an imported clang module by:
- checking whether the ClassTemplateSpecializationDecl is complete and
- checking that the instantiation was in a module by looking at the first field.
I also added a negative check to make sure that a typedef to a forward-declared
template (with the definition outside of the module) is handled correctly.
Repository:
rL LLVM
http://reviews.llvm.org/D19443
Files:
lib/CodeGen/CGDebugInfo.cpp
test/Modules/ExtDebugInfo.cpp
test/Modules/Inputs/DebugCXX.h
test/Modules/ModuleDebugInfo.cpp
Index: test/Modules/ModuleDebugInfo.cpp
===
--- test/Modules/ModuleDebugInfo.cpp
+++ test/Modules/ModuleDebugInfo.cpp
@@ -47,15 +47,20 @@
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Struct"
// CHECK-SAME: identifier: "_ZTSN8DebugCXX6StructE")
+// This type is anchored by an explicit template instantiation.
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "Template >"
+// CHECK-SAME: templateParams:
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIi")
+// This type is anchored by a function parameter.
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A"
+// CHECK-SAME: templateParams:
// CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE")
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "Template >"
+// CHECK-SAME: flags: DIFlagFwdDecl
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIf")
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "B",
@@ -81,7 +86,20 @@
// CHECK: ![[B_MBRS]] = !{{{.*}}, ![[GET_PARENT:.*]]}
// CHECK: ![[GET_PARENT]] = !DISubprogram(name: "getParent"
-// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "FloatInstatiation"
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1",
+// CHECK-SAME: flags: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTS9Template1IPvE")
+
+// Explicit instatiation.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1",
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTS9Template1IiE")
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdDeclTemplate",
+// CHECK-SAME: flags: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTS15FwdDeclTemplateIiE")
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "FloatInstantiation"
// no mangled name here yet.
// CHECK: !DICompositeType(tag: DW_TAG_union_type,
@@ -96,4 +114,8 @@
// CHECK-SAME: name: "InAnonymousNamespace",
// CHECK-SAME: elements: !{{[0-9]+}})
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefTemplate",
+// CHECK-SAME: baseType: !"_ZTS9Template1IPvE")
+
+
// CHECK-NEG-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "PureForwardDecl"
Index: test/Modules/Inputs/DebugCXX.h
===
--- test/Modules/Inputs/DebugCXX.h
+++ test/Modules/Inputs/DebugCXX.h
@@ -24,10 +24,11 @@
> class Template {
T member;
};
+ // Explicit template instantiation.
extern template class Template;
extern template struct traits;
- typedef class Template FloatInstatiation;
+ typedef class Template FloatInstantiation;
inline void fn() {
Template invisible;
@@ -48,6 +49,7 @@
template class A;
template class A {};
typedef A B;
+ // Anchored by a function parameter.
void foo(B) {}
}
@@ -83,3 +85,13 @@
Derived *getParent() const override;
};
};
+
+template
+class Template1 {
+ T t;
+};
+typedef Template1 TypedefTemplate;
+extern template class Template1;
+
+template class FwdDeclTemplate;
+typedef FwdDeclTemplate TypedefFwdDeclTemplate;
Index: test/Modules/ExtDebugInfo.cpp
===
--- test/Modules/ExtDebugInfo.cpp
+++ test/Modules/ExtDebugInfo.cpp
@@ -30,7 +30,9 @@
DebugCXX::Enum e;
DebugCXX::Template implicitTemplate;
DebugCXX::Template explicitTemplate;
-DebugCXX::FloatInstatiation typedefTemplate;
+DebugCXX::FloatInstantiation typedefTemplate;
+DebugCXX::B anchoredTemplate;
+
int Struct::static_member = -1;
enum {
e3 = -1
@@ -41,14 +43,25 @@
TypedefUnion tdu;
TypedefEnum tde;
TypedefStruct tds;
+TypedefTemplate tdt;
+Template1 explicitTemplate1;
+
+template class FwdDeclTemplate { T t; };
+TypedefFwdDeclTemplate tdfdt;
InAnonymousNamespace anon;
void foo() {
anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum;
}
-// CHECK: ![[NS:.*]] = !DINamespace