From: Adrian Prantl Date: Wed, 17 Aug 2016 18:27:24 +0000 (+0000) Subject: Module debug info: Fix a bug in handling record decls without fields. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=db4c239f5ed8cdf4a0b886c2b18ccb8621f85230;p=clang Module debug info: Fix a bug in handling record decls without fields. The previous condition would erroneously mark all CXXRecordDecls that didn't have any fields as being defined in a clang module. This patch fixes the condition to only apply to explicit template instantiations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@278952 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index f56cd0a6bb..fa5f53e459 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1656,12 +1656,15 @@ static bool isDefinedInClangModule(const RecordDecl *RD) { return false; if (auto *CXXDecl = dyn_cast(RD)) { assert(CXXDecl->isCompleteDefinition() && "incomplete record definition"); - if (CXXDecl->getTemplateSpecializationKind() != TSK_Undeclared) - // Make sure the instantiation is actually in a module. - if (CXXDecl->field_begin() != CXXDecl->field_end()) - return CXXDecl->field_begin()->isFromASTFile(); + auto TemplateKind = CXXDecl->getTemplateSpecializationKind(); + if (TemplateKind != TSK_Undeclared) { + // This is a template, check the origin of the first member. + if (CXXDecl->field_begin() == CXXDecl->field_end()) + return TemplateKind == TSK_ExplicitInstantiationDeclaration; + if (!CXXDecl->field_begin()->isFromASTFile()) + return false; + } } - return true; } diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp index dbf79f4ff1..89a3c3945a 100644 --- a/test/Modules/ExtDebugInfo.cpp +++ b/test/Modules/ExtDebugInfo.cpp @@ -63,6 +63,10 @@ struct Specialized::Member definedLocally2; template struct FwdDeclTemplateMember::Member { T t; }; TypedefFwdDeclTemplateMember tdfdtm; +SpecializedBase definedLocally3; +extern template class WithSpecializedBase; +WithSpecializedBase definedLocally4; + void foo() { anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum; } @@ -103,6 +107,7 @@ void foo() { // CHECK: !DICompositeType(tag: DW_TAG_class_type, // CHECK-SAME: name: "Template >", // CHECK-SAME: scope: ![[NS]], +// CHECK-SAME: elements: // CHECK-SAME: templateParams: // CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE") @@ -112,10 +117,11 @@ void foo() { // CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIfEE") -// This type is anchored in the module by an explicit template instantiation. +// This type is anchored in the module via a function argument, +// but we don't know this (yet). // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A", // CHECK-SAME: scope: ![[NS]], -// CHECK-SAME: flags: DIFlagFwdDecl, +// CHECK-SAME: elements: // CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE") // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_member", @@ -133,6 +139,7 @@ void foo() { // This one isn't. // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template1", +// CHECK-SAME: elements: // CHECK-SAME: templateParams: // CHECK-SAME: identifier: "_ZTS9Template1IPvE") @@ -142,6 +149,7 @@ void foo() { // CHECK-SAME: identifier: "_ZTS9Template1IiE") // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdDeclTemplate", +// CHECK-SAME: elements: // CHECK-SAME: templateParams: // CHECK-SAME: identifier: "_ZTS15FwdDeclTemplateIiE") @@ -160,6 +168,19 @@ void foo() { // CHECK-SAME: elements: // CHECK-SAME: identifier: "_ZTSN21FwdDeclTemplateMemberIiE6MemberE") +// This type is defined locally and forward-declared in the module. +// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "SpecializedBase", +// CHECK-SAME: baseType: ![[SPECIALIZEDBASE:.*]]) +// CHECK: ![[SPECIALIZEDBASE]] = +// CHECK-SAME: !DICompositeType(tag: DW_TAG_class_type, +// CHECK-SAME: name: "WithSpecializedBase", +// CHECK-SAME: elements: +// CHECK-SAME: identifier: "_ZTS19WithSpecializedBaseIfE") + +// This type is explicitly specialized locally. +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "WithSpecializedBase", +// CHECK-SAME: elements: +// CHECK-SAME: identifier: "_ZTS19WithSpecializedBaseIiE") // CHECK: !DIGlobalVariable(name: "anon_enum", {{.*}}, type: ![[ANON_ENUM:[0-9]+]] // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, scope: ![[NS]], diff --git a/test/Modules/Inputs/DebugCXX.h b/test/Modules/Inputs/DebugCXX.h index 793ad209f8..c9cd68f30c 100644 --- a/test/Modules/Inputs/DebugCXX.h +++ b/test/Modules/Inputs/DebugCXX.h @@ -105,3 +105,9 @@ template <> struct Specialized { template struct FwdDeclTemplateMember { struct Member; }; typedef FwdDeclTemplateMember::Member TypedefFwdDeclTemplateMember; + +// Base class specialized on the class itself. +template class BaseTemplate {}; +template +class WithSpecializedBase : public BaseTemplate> {}; +typedef WithSpecializedBase SpecializedBase; diff --git a/test/Modules/ModuleDebugInfo.cpp b/test/Modules/ModuleDebugInfo.cpp index 021283a83e..1bc0613f42 100644 --- a/test/Modules/ModuleDebugInfo.cpp +++ b/test/Modules/ModuleDebugInfo.cpp @@ -49,6 +49,7 @@ // This type is anchored by a function parameter. // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A" +// CHECK-SAME: elements: // CHECK-SAME: templateParams: // CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE") @@ -58,6 +59,7 @@ // This type is anchored by an explicit template instantiation. // CHECK: !DICompositeType(tag: DW_TAG_class_type, // CHECK-SAME: name: "Template >" +// CHECK-SAME: elements: // CHECK-SAME: templateParams: // CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE") @@ -66,11 +68,13 @@ // CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIiEE") // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "traits" +// CHECK-SAME: elements: // CHECK-SAME: templateParams: // CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIfEE") // CHECK: !DICompositeType(tag: DW_TAG_class_type, // CHECK-SAME: name: "Template >" +// CHECK-SAME: elements: // CHECK-SAME: templateParams: // CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIlNS_6traitsIlEEEE") @@ -135,4 +139,10 @@ // CHECK-SAME: flags: DIFlagFwdDecl // CHECK-SAME: identifier: "_ZTSN21FwdDeclTemplateMemberIiE6MemberE") +// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "SpecializedBase", +// CHECK-SAME: baseType: ![[SPECIALIZEDBASE:.*]]) +// CHECK: ![[SPECIALIZEDBASE]] = !DICompositeType(tag: DW_TAG_class_type, +// CHECK-SAME: name: "WithSpecializedBase", +// CHECK-SAME: flags: DIFlagFwdDecl, + // CHECK-NEG-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "PureForwardDecl"