From: Adrian Prantl Date: Thu, 30 Aug 2018 21:21:16 +0000 (+0000) Subject: dsymutil: Avoid pruning non-type forward declarations inside DW_TAG_module X-Git-Tag: llvmorg-8.0.0-rc1~9738 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bdffea12d0be98efbf6d6ec4dcba3267b8aa7dec;p=platform%2Fupstream%2Fllvm.git dsymutil: Avoid pruning non-type forward declarations inside DW_TAG_module forward declarations. Especially with template instantiations, there are legitimate reasons why for declarations might be emitted into a DW_TAG_module skeleton / forward-declaration sub-tree, that are not forward declarations in the sense of that there is a more complete definition over in a .pcm file. The example in the testcase is a constant DW_TAG_member of a DW_TAG_class template instatiation. rdar://problem/43623196 llvm-svn: 341123 --- diff --git a/llvm/test/tools/dsymutil/Inputs/modules-pruning/1.o b/llvm/test/tools/dsymutil/Inputs/modules-pruning/1.o new file mode 100644 index 0000000..89cb1b4 Binary files /dev/null and b/llvm/test/tools/dsymutil/Inputs/modules-pruning/1.o differ diff --git a/llvm/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm b/llvm/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm new file mode 100644 index 0000000..657a024 Binary files /dev/null and b/llvm/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm differ diff --git a/llvm/test/tools/dsymutil/X86/modules-pruning.cpp b/llvm/test/tools/dsymutil/X86/modules-pruning.cpp new file mode 100644 index 0000000..7f331f1 --- /dev/null +++ b/llvm/test/tools/dsymutil/X86/modules-pruning.cpp @@ -0,0 +1,59 @@ +// RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/modules-pruning \ +// RUN: -y %p/dummy-debug-map.map -o - \ +// RUN: | llvm-dwarfdump --name isRef -p - | FileCheck %s + +/* Compile with: + cat >modules.modulemap < struct is_reference : false_type {}; +template struct is_reference : true_type {}; + +template +class Template { +public: + static const bool isRef = is_reference::value; + Template() {} +}; +} +#else + +#include "template.h" + +void foo() { + M::Template TB1; + TB1.isRef; +} + +#endif diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index dae15c2..7459874 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -155,6 +155,40 @@ static bool isODRAttribute(uint16_t Attr) { llvm_unreachable("Improper attribute."); } +static bool isTypeTag(uint16_t Tag) { + switch (Tag) { + case dwarf::DW_TAG_array_type: + case dwarf::DW_TAG_class_type: + case dwarf::DW_TAG_enumeration_type: + case dwarf::DW_TAG_pointer_type: + case dwarf::DW_TAG_reference_type: + case dwarf::DW_TAG_string_type: + case dwarf::DW_TAG_structure_type: + case dwarf::DW_TAG_subroutine_type: + case dwarf::DW_TAG_typedef: + case dwarf::DW_TAG_union_type: + case dwarf::DW_TAG_ptr_to_member_type: + case dwarf::DW_TAG_set_type: + case dwarf::DW_TAG_subrange_type: + case dwarf::DW_TAG_base_type: + case dwarf::DW_TAG_const_type: + case dwarf::DW_TAG_constant: + case dwarf::DW_TAG_file_type: + case dwarf::DW_TAG_namelist: + case dwarf::DW_TAG_packed_type: + case dwarf::DW_TAG_volatile_type: + case dwarf::DW_TAG_restrict_type: + case dwarf::DW_TAG_atomic_type: + case dwarf::DW_TAG_interface_type: + case dwarf::DW_TAG_unspecified_type: + case dwarf::DW_TAG_shared_type: + return true; + default: + break; + } + return false; +} + bool DwarfLinker::DIECloner::getDIENames(const DWARFDie &Die, AttributesInfo &Info, OffsetsStringPool &StringPool, @@ -269,7 +303,8 @@ static bool analyzeContextInfo(const DWARFDie &DIE, unsigned ParentIdx, // DW_TAG_module or a DW_TAG_module that contains nothing but // forward declarations. Info.Prune &= (DIE.getTag() == dwarf::DW_TAG_module) || - dwarf::toUnsigned(DIE.find(dwarf::DW_AT_declaration), 0); + (isTypeTag(DIE.getTag()) && + dwarf::toUnsigned(DIE.find(dwarf::DW_AT_declaration), 0)); // Don't prune it if there is no definition for the DIE. Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset(); @@ -1258,40 +1293,6 @@ bool DwarfLinker::RelocationManager::applyValidRelocs( return Applied; } -static bool isTypeTag(uint16_t Tag) { - switch (Tag) { - case dwarf::DW_TAG_array_type: - case dwarf::DW_TAG_class_type: - case dwarf::DW_TAG_enumeration_type: - case dwarf::DW_TAG_pointer_type: - case dwarf::DW_TAG_reference_type: - case dwarf::DW_TAG_string_type: - case dwarf::DW_TAG_structure_type: - case dwarf::DW_TAG_subroutine_type: - case dwarf::DW_TAG_typedef: - case dwarf::DW_TAG_union_type: - case dwarf::DW_TAG_ptr_to_member_type: - case dwarf::DW_TAG_set_type: - case dwarf::DW_TAG_subrange_type: - case dwarf::DW_TAG_base_type: - case dwarf::DW_TAG_const_type: - case dwarf::DW_TAG_constant: - case dwarf::DW_TAG_file_type: - case dwarf::DW_TAG_namelist: - case dwarf::DW_TAG_packed_type: - case dwarf::DW_TAG_volatile_type: - case dwarf::DW_TAG_restrict_type: - case dwarf::DW_TAG_atomic_type: - case dwarf::DW_TAG_interface_type: - case dwarf::DW_TAG_unspecified_type: - case dwarf::DW_TAG_shared_type: - return true; - default: - break; - } - return false; -} - static bool isObjCSelector(StringRef Name) { return Name.size() > 2 && (Name[0] == '-' || Name[0] == '+') && (Name[1] == '[');