diff options
| author | Adrian Prantl <aprantl@apple.com> | 2018-08-30 21:21:16 +0000 |
|---|---|---|
| committer | Adrian Prantl <aprantl@apple.com> | 2018-08-30 21:21:16 +0000 |
| commit | bdffea12d0be98efbf6d6ec4dcba3267b8aa7dec (patch) | |
| tree | d1ac2486e33f385cc3a609444639aacc4c776ae7 | |
| parent | a1f57030c624f39d9e97008635e1d9efe67962bd (diff) | |
| download | bcm5719-llvm-bdffea12d0be98efbf6d6ec4dcba3267b8aa7dec.tar.gz bcm5719-llvm-bdffea12d0be98efbf6d6ec4dcba3267b8aa7dec.zip | |
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
| -rw-r--r-- | llvm/test/tools/dsymutil/Inputs/modules-pruning/1.o | bin | 0 -> 2984 bytes | |||
| -rw-r--r-- | llvm/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm | bin | 0 -> 20988 bytes | |||
| -rw-r--r-- | llvm/test/tools/dsymutil/X86/modules-pruning.cpp | 59 | ||||
| -rw-r--r-- | llvm/tools/dsymutil/DwarfLinker.cpp | 71 |
4 files changed, 95 insertions, 35 deletions
diff --git a/llvm/test/tools/dsymutil/Inputs/modules-pruning/1.o b/llvm/test/tools/dsymutil/Inputs/modules-pruning/1.o Binary files differnew file mode 100644 index 00000000000..89cb1b467ed --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/modules-pruning/1.o diff --git a/llvm/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm b/llvm/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm Binary files differnew file mode 100644 index 00000000000..657a024a686 --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm 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 00000000000..7f331f183f0 --- /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 <<EOF + module Outer { + module Template { + header "template.h" + export * + } + } +EOF + clang++ -D TEMPLATE_H -E -o template.h modules-pruning.cpp + clang++ -c -fcxx-modules -fmodules -fmodule-map-file=modules.modulemap \ + -g -gmodules -fmodules-cache-path=. \ + -Xclang -fdisable-module-hash modules-pruning.cpp -o 1.o +*/ + +// CHECK: DW_TAG_compile_unit +// CHECK: DW_TAG_module +// CHECK: DW_TAG_module +// CHECK: DW_TAG_class +// CHECK: DW_TAG_member +// CHECK: DW_AT_name ("isRef") +// CHECK: DW_AT_declaration (true) +// CHECK: DW_AT_const_value (1) +// CHECK-NOT: DW_TAG + +#ifdef TEMPLATE_H + +namespace M { +struct false_type { + static const bool value = false; +}; +struct true_type { + static const bool value = true; +}; + +template <class T> struct is_reference : false_type {}; +template <class T> struct is_reference<T&> : true_type {}; + +template<class T> +class Template { +public: + static const bool isRef = is_reference<T>::value; + Template() {} +}; +} +#else + +#include "template.h" + +void foo() { + M::Template<bool&> TB1; + TB1.isRef; +} + +#endif diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index dae15c2aa32..74598741f9f 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] == '['); |

