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<int, DebugCXX::traits<int> >"
+// CHECK-SAME: templateParams:
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE")
+// This type is anchored by a function parameter.
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A<void>"
+// CHECK-SAME: templateParams:
// CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE")
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "Template<float, DebugCXX::traits<float> >"
+// CHECK-SAME: flags: DIFlagFwdDecl
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")
// 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<void *>",
+// CHECK-SAME: flags: DIFlagFwdDecl
+// CHECK-SAME: identifier: "_ZTS9Template1IPvE")
+
+// Explicit instatiation.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1<int>",
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTS9Template1IiE")
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdDeclTemplate<int>",
+// 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<int>;
extern template struct traits<float>;
- typedef class Template<float> FloatInstatiation;
+ typedef class Template<float> FloatInstantiation;
inline void fn() {
Template<long> invisible;
@@ -48,6 +49,7 @@
template <typename...> class A;
template <typename T> class A<T> {};
typedef A<void> B;
+ // Anchored by a function parameter.
void foo(B) {}
}
@@ -83,3 +85,13 @@
Derived *getParent() const override;
};
};
+
+template <class T>
+class Template1 {
+ T t;
+};
+typedef Template1<void *> TypedefTemplate;
+extern template class Template1<int>;
+
+template <class T> class FwdDeclTemplate;
+typedef FwdDeclTemplate<int> TypedefFwdDeclTemplate;
Index: test/Modules/ExtDebugInfo.cpp
===================================================================
--- test/Modules/ExtDebugInfo.cpp
+++ test/Modules/ExtDebugInfo.cpp
@@ -30,7 +30,9 @@
DebugCXX::Enum e;
DebugCXX::Template<long> implicitTemplate;
DebugCXX::Template<int> 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<int> explicitTemplate1;
+
+template <class T> class FwdDeclTemplate { T t; };
+TypedefFwdDeclTemplate tdfdt;
InAnonymousNamespace anon;
void foo() {
anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum;
}
-// CHECK: ![[NS:.*]] = !DINamespace(name: "DebugCXX", scope: ![[MOD:[0-9]+]],
+// This type is anchored in the module by an explicit template instantiation.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A<void>",
+// CHECK-SAME: scope: ![[NS:[0-9]+]],
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE")
+
+// CHECK: ![[NS]] = !DINamespace(name: "DebugCXX", scope: ![[MOD:[0-9]+]],
// CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugCXX
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Struct",
@@ -63,24 +76,43 @@
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
+// This type is anchored in the module by an explicit template instantiation.
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "Template<int, DebugCXX::traits<int> >",
// CHECK-SAME: scope: ![[NS]],
// CHECK-SAME: flags: DIFlagFwdDecl,
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE")
+// This one isn't.
// CHECK: !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "Template<float, DebugCXX::traits<float> >",
// CHECK-SAME: scope: ![[NS]],
-// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: templateParams:
// CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")
// CHECK: !DICompositeType(tag: DW_TAG_union_type,
-// CHECK-SAME: flags: DIFlagFwdDecl, identifier: "_ZTS12TypedefUnion")
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTS12TypedefUnion")
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
-// CHECK-SAME: flags: DIFlagFwdDecl, identifier: "_ZTS11TypedefEnum")
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTS11TypedefEnum")
// CHECK: !DICompositeType(tag: DW_TAG_structure_type,
-// CHECK-SAME: flags: DIFlagFwdDecl, identifier: "_ZTS13TypedefStruct")
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTS13TypedefStruct")
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1<void *>",
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTS9Template1IPvE")
+
+// This type is anchored in the module by an explicit template instantiation.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1<int>",
+// CHECK-SAME: flags: DIFlagFwdDecl,
+// CHECK-SAME: identifier: "_ZTS9Template1IiE")
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdDeclTemplate<int>",
+// CHECK-SAME: templateParams:
+// CHECK-SAME: identifier: "_ZTS15FwdDeclTemplateIiE")
+
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_member",
// CHECK-SAME: scope: !"_ZTSN8DebugCXX6StructE"
Index: lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -1519,12 +1519,28 @@
return false;
}
+/// Does a type definition exist in an imported clang module?
+static bool isDefinedInClangModule(const RecordDecl *RD) {
+ if (!RD->isFromASTFile())
+ return false;
+ if (!RD->getDefinition())
+ return false;
+ if (!RD->isExternallyVisible() && RD->getName().empty())
+ return false;
+ if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
+ if (!CTSD->isCompleteDefinition())
+ return false;
+ // Make sure the instantiation is actually in a module.
+ if (CTSD->field_begin() != CTSD->field_end())
+ return CTSD->field_begin()->isFromASTFile();
+ }
+ return true;
+}
+
static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
bool DebugTypeExtRefs, const RecordDecl *RD,
const LangOptions &LangOpts) {
- // Does the type exist in an imported clang module?
- if (DebugTypeExtRefs && RD->isFromASTFile() && RD->getDefinition() &&
- (RD->isExternallyVisible() || !RD->getName().empty()))
+ if (DebugTypeExtRefs && isDefinedInClangModule(RD))
return true;
if (DebugKind > codegenoptions::LimitedDebugInfo)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits