summaryrefslogtreecommitdiffstats
path: root/llvm/tools/dsymutil/DwarfLinker.cpp
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2018-08-30 21:21:16 +0000
committerAdrian Prantl <aprantl@apple.com>2018-08-30 21:21:16 +0000
commitbdffea12d0be98efbf6d6ec4dcba3267b8aa7dec (patch)
treed1ac2486e33f385cc3a609444639aacc4c776ae7 /llvm/tools/dsymutil/DwarfLinker.cpp
parenta1f57030c624f39d9e97008635e1d9efe67962bd (diff)
downloadbcm5719-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
Diffstat (limited to 'llvm/tools/dsymutil/DwarfLinker.cpp')
-rw-r--r--llvm/tools/dsymutil/DwarfLinker.cpp71
1 files changed, 36 insertions, 35 deletions
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] == '[');
OpenPOWER on IntegriCloud