From: Duncan P. N. Exon Smith Date: Wed, 18 Feb 2015 19:39:36 +0000 (+0000) Subject: IR: Avoid DIScopeRef in DIImportedEntity::getEntity() X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=1cfad01081d0a846107995d498c75a2c8a954eac;p=oota-llvm.git 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229733 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index 73b4b1693b0..44c9ddf803b 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/include/llvm/IR/DebugInfo.h @@ -294,6 +294,7 @@ public: }; template class DIRef; +typedef DIRef DIDescriptorRef; typedef DIRef DIScopeRef; typedef DIRef DITypeRef; typedef DITypedArray DITypeArray; @@ -383,6 +384,12 @@ template StringRef DIRef::getName() const { return MS->getString(); } +/// \brief Handle fields that are references to DIDescriptors. +template <> +DIDescriptorRef DIDescriptor::getFieldAs(unsigned Elt) const; +/// \brief Specialize DIRef constructor for DIDescriptorRef. +template <> DIRef::DIRef(const Metadata *V); + /// \brief Handle fields that are references to DIScopes. template <> DIScopeRef DIDescriptor::getFieldAs(unsigned Elt) const; /// \brief Specialize DIRef constructor for DIScopeRef. @@ -1029,7 +1036,7 @@ class DIImportedEntity : public DIDescriptor { public: explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {} DIScope getContext() const { return getFieldAs(1); } - DIScopeRef getEntity() const { return getFieldAs(2); } + DIDescriptorRef getEntity() const { return getFieldAs(2); } unsigned getLineNumber() const { return getHeaderFieldAs(1); } StringRef getName() const { return getHeaderField(2); } bool Verify() const; diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index 9a7ff062de0..32521b160a2 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -426,6 +426,15 @@ static bool fieldIsScopeRef(const MDNode *DbgNode, unsigned Elt) { return isScopeRef(dyn_cast_or_null(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(MD)) + return !S->getString().empty(); + return isa(MD); +} + bool DIType::Verify() const { if (!isType()) return false; @@ -1463,6 +1472,10 @@ void DIVariable::printExtendedName(raw_ostream &OS) const { } } +template <> DIRef::DIRef(const Metadata *V) : Val(V) { + assert(isDescriptorRef(V) && + "DIDescriptorRef should be a MDString or MDNode"); +} template <> DIRef::DIRef(const Metadata *V) : Val(V) { assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode"); } @@ -1470,6 +1483,10 @@ template <> DIRef::DIRef(const Metadata *V) : Val(V) { assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode"); } +template <> +DIDescriptorRef DIDescriptor::getFieldAs(unsigned Elt) const { + return DIDescriptorRef(cast_or_null(getField(DbgNode, Elt))); +} template <> DIScopeRef DIDescriptor::getFieldAs(unsigned Elt) const { return DIScopeRef(cast_or_null(getField(DbgNode, Elt)));