On Mon, Apr 25, 2016 at 1:52 PM, Adrian Prantl via cfe-commits < cfe-commits@lists.llvm.org> wrote:
> Author: adrian > Date: Mon Apr 25 15:52:40 2016 > New Revision: 267464 > > URL: http://llvm.org/viewvc/llvm-project?rev=267464&view=rev > Log: > Module Debugging: Fix the condition for determining whether a template > instantiation is in a module. > > 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. > > http://reviews.llvm.org/D19443 > rdar://problem/25553724 > > 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=267464&r1=267463&r2=267464&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Apr 25 15:52:40 2016 > @@ -1514,12 +1514,28 @@ static bool hasExplicitMemberDefinition( > 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)) { > The same issue also affects member classes of class template specializations (you can detect them with RD->getInstantiatedFromMemberClass(), or detect all the relevant cases at once with RD->getTemplateSpecializationKind()). + if (!CTSD->isCompleteDefinition()) > + return false; > You already checked this a few lines above. Actually, the two checks do different things depending on whether RD or some other declaration is the definition; did you really mean to treat a (non-template) class that's defined locally but forward-declared within a module as being defined in that module? (It might make more sense to map to the definition upfront and do all your queries on that if that's what you intend to check.) > + // 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) > > Modified: cfe/trunk/test/Modules/ExtDebugInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.cpp?rev=267464&r1=267463&r2=267464&view=diff > > ============================================================================== > --- cfe/trunk/test/Modules/ExtDebugInfo.cpp (original) > +++ cfe/trunk/test/Modules/ExtDebugInfo.cpp Mon Apr 25 15:52:40 2016 > @@ -2,7 +2,7 @@ > // Test that only forward declarations are emitted for types dfined in > modules. > > // Modules: > -// RUN: %clang_cc1 -x objective-c++ -std=c++11 -debug-info-kind=limited \ > +// RUN: %clang_cc1 -x objective-c++ -std=c++11 > -debug-info-kind=standalone \ > // RUN: -dwarf-ext-refs -fmodules \ > // RUN: -fmodule-format=obj -fimplicit-module-maps -DMODULES \ > // RUN: -triple %itanium_abi_triple \ > @@ -13,7 +13,7 @@ > // RUN: %clang_cc1 -x c++ -std=c++11 -fmodule-format=obj -emit-pch > -I%S/Inputs \ > // RUN: -triple %itanium_abi_triple \ > // RUN: -o %t.pch %S/Inputs/DebugCXX.h > -// RUN: %clang_cc1 -std=c++11 -debug-info-kind=limited \ > +// RUN: %clang_cc1 -std=c++11 -debug-info-kind=standalone \ > // RUN: -dwarf-ext-refs -fmodule-format=obj \ > // RUN: -triple %itanium_abi_triple \ > // RUN: -include-pch %t.pch %s -emit-llvm -o %t-pch.ll %s > @@ -30,7 +30,9 @@ Struct s; > 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,6 +43,11 @@ char _anchor = anon_enum + conflicting_u > TypedefUnion tdu; > TypedefEnum tde; > TypedefStruct tds; > +TypedefTemplate tdt; > +Template1<int> explicitTemplate1; > + > +template <class T> class FwdDeclTemplate { T t; }; > +TypedefFwdDeclTemplate tdfdt; > > InAnonymousNamespace anon; > > @@ -48,7 +55,8 @@ void foo() { > anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum; > } > > -// CHECK: ![[STRUCT:[0-9]+]] = !DICompositeType(tag: > DW_TAG_structure_type, name: "Struct", > + > +// CHECK: ![[STRUCT:.*]] = !DICompositeType(tag: DW_TAG_structure_type, > name: "Struct", > // CHECK-SAME: scope: ![[NS:[0-9]+]], > // CHECK-SAME: flags: DIFlagFwdDecl, > // CHECK-SAME: identifier: "_ZTSN8DebugCXX6StructE") > @@ -61,25 +69,69 @@ void foo() { > // CHECK-SAME: flags: DIFlagFwdDecl, > // CHECK-SAME: identifier: "_ZTSN8DebugCXX4EnumE") > > -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template<int, > DebugCXX::traits<int> >", > +// This type is anchored in the module by an explicit template > instantiation. > +// CHECK: !DICompositeType(tag: DW_TAG_class_type, > +// CHECK-SAME: name: "Template<long, DebugCXX::traits<long> > >", > // CHECK-SAME: scope: ![[NS]], > // CHECK-SAME: flags: DIFlagFwdDecl, > -// CHECK-SAME: identifier: > "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE") > +// CHECK-SAME: identifier: > "_ZTSN8DebugCXX8TemplateIlNS_6traitsIlEEEE") > > -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template<float, > DebugCXX::traits<float> >", > +// 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 type isn't, however, even with standalone non-module debug info > this > +// type is a forward declaration. > +// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: > "traits<int>", > + > +// 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: templateParams: > // CHECK-SAME: identifier: > "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE") > > +// This type is anchored in the module by an explicit template > instantiation. > +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: > "traits<float>", > +// CHECK-SAME: flags: DIFlagFwdDecl, > +// CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIfEE") > + > + > +// 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]], > +// CHECK-SAME: flags: DIFlagFwdDecl, > +// CHECK-SAME: identifier: "_ZTSN8DebugCXX1AIJvEEE") > + > // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_member", > // CHECK-SAME: scope: ![[STRUCT]] > > // 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") > + > +// This one isn't. > +// 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: !DIGlobalVariable(name: "anon_enum", {{.*}}, type: > ![[ANON_ENUM:[0-9]+]] > // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, scope: ![[NS]], > @@ -94,6 +146,7 @@ void foo() { > // CHECK: ![[GLOBAL_STRUCT]] = distinct !DICompositeType(tag: > DW_TAG_structure_type, > // CHECK-SAME: elements: !{{[0-9]+}}) > > + > // CHECK: !DIGlobalVariable(name: "anon", > // CHECK-SAME: type: ![[GLOBAL_ANON:[0-9]+]] > // CHECK: ![[GLOBAL_ANON]] = !DICompositeType(tag: DW_TAG_structure_type, > > Modified: cfe/trunk/test/Modules/Inputs/DebugCXX.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/DebugCXX.h?rev=267464&r1=267463&r2=267464&view=diff > > ============================================================================== > --- cfe/trunk/test/Modules/Inputs/DebugCXX.h (original) > +++ cfe/trunk/test/Modules/Inputs/DebugCXX.h Mon Apr 25 15:52:40 2016 > @@ -24,10 +24,11 @@ namespace DebugCXX { > > 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 @@ namespace DebugCXX { > 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 @@ class Derived : Base { > 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; > > Modified: cfe/trunk/test/Modules/ModuleDebugInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ModuleDebugInfo.cpp?rev=267464&r1=267463&r2=267464&view=diff > > ============================================================================== > --- cfe/trunk/test/Modules/ModuleDebugInfo.cpp (original) > +++ cfe/trunk/test/Modules/ModuleDebugInfo.cpp Mon Apr 25 15:52:40 2016 > @@ -47,19 +47,39 @@ > // CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "B", > // no mangled name here yet. > > +// 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_structure_type, name: "Struct" > // CHECK-SAME: identifier: "_ZTSN8DebugCXX6StructE") > > -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template<int, > DebugCXX::traits<int> >" > +// 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") > > -// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "FloatInstatiation" > +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "traits<int>" > +// CHECK-SAME: flags: DIFlagFwdDecl > +// CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIiEE") > + > +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: > "traits<float>" > +// CHECK-SAME: templateParams: > +// CHECK-SAME: identifier: "_ZTSN8DebugCXX6traitsIfEE") > + > +// CHECK: !DICompositeType(tag: DW_TAG_class_type, > +// CHECK-SAME: name: "Template<long, DebugCXX::traits<long> >" > +// CHECK-SAME: templateParams: > +// CHECK-SAME: identifier: > "_ZTSN8DebugCXX8TemplateIlNS_6traitsIlEEEE") > + > +// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "FloatInstantiation" > // no mangled name here yet. > > -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Template<float, > DebugCXX::traits<float> >" > +// 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: !DICompositeType(tag: DW_TAG_class_type, name: "FwdVirtual" > @@ -87,12 +107,28 @@ > // CHECK-SAME: name: "InAnonymousNamespace", > // CHECK-SAME: elements: !{{[0-9]+}}) > > -// CHECK: ![[A:[0-9]+]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, > name: "A", > -// CHECK: ![[DERIVED:[0-9]+]] = {{.*}}!DICompositeType(tag: > DW_TAG_class_type, name: "Derived", > -// CHECK-SAME: identifier: > "_ZTS7Derived") > +// CHECK: ![[DERIVED:.*]] = {{.*}}!DICompositeType(tag: > DW_TAG_class_type, name: "Derived", > +// CHECK-SAME: identifier: > "_ZTS7Derived") > // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B", scope: > ![[DERIVED]], > -// CHECK-SAME: elements: ![[B_MBRS:.*]], vtableHolder: ![[A]] > +// CHECK-SAME: elements: ![[B_MBRS:.*]], vtableHolder: > // CHECK: ![[B_MBRS]] = !{{{.*}}, ![[GET_PARENT:.*]]} > // CHECK: ![[GET_PARENT]] = !DISubprogram(name: "getParent" > > +// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefTemplate", > +// CHECK-SAME: baseType: ![[BASE:.*]]) > +// CHECK: ![[BASE]] = !DICompositeType(tag: DW_TAG_class_type, > +// CHECK-SAME: 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-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 >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits