Author: adrian Date: Wed Aug 17 13:27:24 2016 New Revision: 278952 URL: http://llvm.org/viewvc/llvm-project?rev=278952&view=rev Log: 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. <rdar://problem/27771823> Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/test/Modules/ExtDebugInfo.cpp cfe/trunk/test/Modules/Inputs/DebugCXX.h cfe/trunk/test/Modules/ModuleDebugInfo.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=278952&r1=278951&r2=278952&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Aug 17 13:27:24 2016 @@ -1656,12 +1656,15 @@ static bool isDefinedInClangModule(const return false; if (auto *CXXDecl = dyn_cast<CXXRecordDecl>(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; } Modified: cfe/trunk/test/Modules/ExtDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.cpp?rev=278952&r1=278951&r2=278952&view=diff ============================================================================== --- cfe/trunk/test/Modules/ExtDebugInfo.cpp (original) +++ cfe/trunk/test/Modules/ExtDebugInfo.cpp Wed Aug 17 13:27:24 2016 @@ -63,6 +63,10 @@ struct Specialized<int>::Member definedL template <class T> struct FwdDeclTemplateMember<T>::Member { T t; }; TypedefFwdDeclTemplateMember tdfdtm; +SpecializedBase definedLocally3; +extern template class WithSpecializedBase<int>; +WithSpecializedBase<int> 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<float, DebugCXX::traits<float> >", // 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<void>", // 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<void *>", +// 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<int>", +// 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<float>", +// CHECK-SAME: elements: +// CHECK-SAME: identifier: "_ZTS19WithSpecializedBaseIfE") + +// This type is explicitly specialized locally. +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "WithSpecializedBase<int>", +// 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]], Modified: cfe/trunk/test/Modules/Inputs/DebugCXX.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/DebugCXX.h?rev=278952&r1=278951&r2=278952&view=diff ============================================================================== --- cfe/trunk/test/Modules/Inputs/DebugCXX.h (original) +++ cfe/trunk/test/Modules/Inputs/DebugCXX.h Wed Aug 17 13:27:24 2016 @@ -105,3 +105,9 @@ template <> struct Specialized<int> { template <class T> struct FwdDeclTemplateMember { struct Member; }; typedef FwdDeclTemplateMember<int>::Member TypedefFwdDeclTemplateMember; + +// Base class specialized on the class itself. +template <typename Derived> class BaseTemplate {}; +template <typename T> +class WithSpecializedBase : public BaseTemplate<WithSpecializedBase<T>> {}; +typedef WithSpecializedBase<float> SpecializedBase; Modified: cfe/trunk/test/Modules/ModuleDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ModuleDebugInfo.cpp?rev=278952&r1=278951&r2=278952&view=diff ============================================================================== --- cfe/trunk/test/Modules/ModuleDebugInfo.cpp (original) +++ cfe/trunk/test/Modules/ModuleDebugInfo.cpp Wed Aug 17 13:27:24 2016 @@ -49,6 +49,7 @@ // This type is anchored by a function parameter. // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A<void>" +// 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<int, DebugCXX::traits<int> >" +// 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<float>" +// CHECK-SAME: elements: // CHECK-SAME: templateParams: // CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIfEE") // CHECK: !DICompositeType(tag: DW_TAG_class_type, // CHECK-SAME: name: "Template<long, DebugCXX::traits<long> >" +// 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<float>", +// CHECK-SAME: flags: DIFlagFwdDecl, + // CHECK-NEG-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "PureForwardDecl" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits