diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-02-18 19:39:36 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-02-18 19:39:36 +0000 |
commit | 2a78e9bcb5b0f05e60e9a4820c40ca3c53664221 (patch) | |
tree | 0947d2b985d2ae0d4258114c9d07f7d2a5cc0608 /llvm/lib/IR/DebugInfo.cpp | |
parent | f5f9badbbeb905e8a979ee7813232233bc8bc2f1 (diff) | |
download | bcm5719-llvm-2a78e9bcb5b0f05e60e9a4820c40ca3c53664221.tar.gz bcm5719-llvm-2a78e9bcb5b0f05e60e9a4820c40ca3c53664221.zip |
IR: Avoid DIScopeRef in DIImportedEntity::getEntity()
`DIImportedEntity::getEntity()` currently returns a `DIScopeRef`, but
the nodes it references aren't always `DIScope`s. In particular, it can
reference global variables.
Introduce `DIDescriptorRef` to avoid the lie.
llvm-svn: 229733
Diffstat (limited to 'llvm/lib/IR/DebugInfo.cpp')
-rw-r--r-- | llvm/lib/IR/DebugInfo.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 9a7ff062de0..32521b160a2 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -426,6 +426,15 @@ static bool fieldIsScopeRef(const MDNode *DbgNode, unsigned Elt) { return isScopeRef(dyn_cast_or_null<Metadata>(getField(DbgNode, Elt))); } +/// \brief Check if a value can be a DescriptorRef. +static bool isDescriptorRef(const Metadata *MD) { + if (!MD) + return true; + if (auto *S = dyn_cast<MDString>(MD)) + return !S->getString().empty(); + return isa<MDNode>(MD); +} + bool DIType::Verify() const { if (!isType()) return false; @@ -1463,6 +1472,10 @@ void DIVariable::printExtendedName(raw_ostream &OS) const { } } +template <> DIRef<DIDescriptor>::DIRef(const Metadata *V) : Val(V) { + assert(isDescriptorRef(V) && + "DIDescriptorRef should be a MDString or MDNode"); +} template <> DIRef<DIScope>::DIRef(const Metadata *V) : Val(V) { assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode"); } @@ -1471,6 +1484,10 @@ template <> DIRef<DIType>::DIRef(const Metadata *V) : Val(V) { } template <> +DIDescriptorRef DIDescriptor::getFieldAs<DIDescriptorRef>(unsigned Elt) const { + return DIDescriptorRef(cast_or_null<Metadata>(getField(DbgNode, Elt))); +} +template <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const { return DIScopeRef(cast_or_null<Metadata>(getField(DbgNode, Elt))); } |