diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h index a3a231ba809..e8cc79381fa 100644 --- a/include/llvm/DebugInfo.h +++ b/include/llvm/DebugInfo.h @@ -46,7 +46,7 @@ namespace llvm { class DILexicalBlockFile; class DIVariable; class DIType; - class DITypeRef; + class DIScopeRef; class DIObjCProperty; /// Maps from type identifier to the actual MDNode. @@ -56,9 +56,9 @@ namespace llvm { /// This should not be stored in a container, because the underlying MDNode /// may change in certain situations. class DIDescriptor { - // Befriends DITypeRef so DITypeRef can befriend the protected member - // function: getFieldAs. - friend class DITypeRef; + // Befriends DIScopeRef so DIScopeRef can befriend the protected member + // function: getFieldAs. + friend class DIScopeRef; public: enum { FlagPrivate = 1 << 0, @@ -151,9 +151,9 @@ namespace llvm { void dump() const; }; - /// Specialize getFieldAs to handle fields that are references to DITypes. + /// npecialize getFieldAs to handle fields that are references to DIScopes. template <> - DITypeRef DIDescriptor::getFieldAs(unsigned Elt) const; + DIScopeRef DIDescriptor::getFieldAs(unsigned Elt) const; /// DISubrange - This is used to represent ranges, for array bounds. class DISubrange : public DIDescriptor { @@ -205,6 +205,25 @@ namespace llvm { DIScope getContext() const; StringRef getFilename() const; StringRef getDirectory() const; + + /// Generate a reference to this DIScope. Uses the type identifier instead + /// of the actual MDNode if possible, to help type uniquing. + Value *generateRef(); + }; + + /// Represents reference to a DIScope, abstracts over direct and + /// identifier-based metadata scope references. + class DIScopeRef { + template + friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const; + + /// Val can be either a MDNode or a MDString, in the latter, + /// MDString specifies the type identifier. + const Value *Val; + explicit DIScopeRef(const Value *V); + public: + DIScope resolve(const DITypeIdentifierMap &Map) const; + operator Value *() const { return const_cast(Val); } }; /// DIType - This is a wrapper for a type. @@ -271,32 +290,12 @@ namespace llvm { /// isUnsignedDIType - Return true if type encoding is unsigned. bool isUnsignedDIType(); - /// Generate a reference to this DIType. Uses the type identifier instead - /// of the actual MDNode if possible, to help type uniquing. - DITypeRef generateRef(); - /// replaceAllUsesWith - Replace all uses of debug info referenced by /// this descriptor. void replaceAllUsesWith(DIDescriptor &D); void replaceAllUsesWith(MDNode *D); }; - /// Represents reference to a DIType, abstracts over direct and - /// identifier-based metadata type references. - class DITypeRef { - template - friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const; - friend DITypeRef DIType::generateRef(); - - /// TypeVal can be either a MDNode or a MDString, in the latter, - /// MDString specifies the type identifier. - const Value *TypeVal; - explicit DITypeRef(const Value *V); - public: - DIType resolve(const DITypeIdentifierMap &Map) const; - operator Value *() const { return const_cast(TypeVal); } - }; - /// DIBasicType - A basic type, like 'int' or 'float'. class DIBasicType : public DIType { public: @@ -328,9 +327,9 @@ namespace llvm { /// associated with one. MDNode *getObjCProperty() const; - DITypeRef getClassType() const { + DIScopeRef getClassType() const { assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); - return getFieldAs(10); + return getFieldAs(10); } Constant *getConstant() const { @@ -358,8 +357,8 @@ namespace llvm { void setTypeArray(DIArray Elements, DIArray TParams = DIArray()); void addMember(DIDescriptor D); unsigned getRunTimeLang() const { return getUnsignedField(11); } - DITypeRef getContainingType() const { - return getFieldAs(12); + DIScopeRef getContainingType() const { + return getFieldAs(12); } void setContainingType(DICompositeType ContainingType); DIArray getTemplateParams() const { return getFieldAs(13); } @@ -426,8 +425,8 @@ namespace llvm { unsigned getVirtuality() const { return getUnsignedField(10); } unsigned getVirtualIndex() const { return getUnsignedField(11); } - DITypeRef getContainingType() const { - return getFieldAs(12); + DIScopeRef getContainingType() const { + return getFieldAs(12); } unsigned getFlags() const { diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 57ad489970d..885d4ba5cdc 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2633,7 +2633,7 @@ void DwarfDebug::emitDebugStrDWO() { OffSec, StrSym); } -/// Find the MDNode for the given type reference. -MDNode *DwarfDebug::resolve(DITypeRef TRef) const { - return TRef.resolve(TypeIdentifierMap); +/// Find the MDNode for the given scope reference. +DIScope DwarfDebug::resolve(DIScopeRef SRef) const { + return SRef.resolve(TypeIdentifierMap); } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 0258fdc3dbb..5ccaf0fa484 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -683,8 +683,8 @@ public: /// Returns the Dwarf Version. unsigned getDwarfVersion() const { return DwarfVersion; } - /// Find the MDNode for the given type reference. - MDNode *resolve(DITypeRef TRef) const; + /// Find the MDNode for the given scope reference. + DIScope resolve(DIScopeRef SRef) const; }; } // End of namespace llvm diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index d0667cd6db5..7f56f2fb1f9 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -426,17 +426,26 @@ static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) { return !Fld || isa(Fld); } -/// Check if a value can be a TypeRef. +/// Check if a value can be a reference to a type. static bool isTypeRef(const Value *Val) { - return !Val || isa(Val) || isa(Val); + return !Val || + (isa(Val) && !cast(Val)->getString().empty()) || + (isa(Val) && DIType(cast(Val)).isType()); } -/// Check if a field at position Elt of a MDNode can be a TypeRef. +/// Check if a field at position Elt of a MDNode can be a reference to a type. static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) { Value *Fld = getField(DbgNode, Elt); return isTypeRef(Fld); } +/// Check if a value can be a ScopeRef. +static bool isScopeRef(const Value *Val) { + return !Val || + (isa(Val) && !cast(Val)->getString().empty()) || + (isa(Val) && DIScope(cast(Val)).isScope()); +} + /// Verify - Verify that a type descriptor is well formed. bool DIType::Verify() const { if (!isType()) @@ -710,13 +719,13 @@ void DICompositeType::addMember(DIDescriptor D) { /// Generate a reference to this DIType. Uses the type identifier instead /// of the actual MDNode if possible, to help type uniquing. -DITypeRef DIType::generateRef() { +Value *DIScope::generateRef() { if (!isCompositeType()) - return DITypeRef(*this); + return *this; DICompositeType DTy(DbgNode); if (!DTy.getIdentifier()) - return DITypeRef(*this); - return DITypeRef(DTy.getIdentifier()); + return *this; + return DTy.getIdentifier(); } /// \brief Set the containing type. @@ -1428,33 +1437,30 @@ void DIVariable::printExtendedName(raw_ostream &OS) const { } } -DITypeRef::DITypeRef(const Value *V) : TypeVal(V) { - assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode"); +DIScopeRef::DIScopeRef(const Value *V) : Val(V) { + assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode"); } /// Given a DITypeIdentifierMap, tries to find the corresponding -/// DIType for a DITypeRef. -DIType DITypeRef::resolve(const DITypeIdentifierMap &Map) const { - if (!TypeVal) - return NULL; +/// DIScope for a DIScopeRef. +DIScope DIScopeRef::resolve(const DITypeIdentifierMap &Map) const { + if (!Val) + return DIScope(); - if (const MDNode *MD = dyn_cast(TypeVal)) { - assert(DIType(MD).isType() && - "MDNode in DITypeRef should be a DIType."); - return MD; - } + if (const MDNode *MD = dyn_cast(Val)) + return DIScope(MD); - const MDString *MS = cast(TypeVal); + const MDString *MS = cast(Val); // Find the corresponding MDNode. DITypeIdentifierMap::const_iterator Iter = Map.find(MS); assert(Iter != Map.end() && "Identifier not in the type map?"); assert(DIType(Iter->second).isType() && "MDNode in DITypeIdentifierMap should be a DIType."); - return Iter->second; + return DIScope(Iter->second); } -/// Specialize getFieldAs to handle fields that are references to DITypes. +/// Specialize getFieldAs to handle fields that are references to DIScopes. template <> -DITypeRef DIDescriptor::getFieldAs(unsigned Elt) const { - return DITypeRef(getField(DbgNode, Elt)); +DIScopeRef DIDescriptor::getFieldAs(unsigned Elt) const { + return DIScopeRef(getField(DbgNode, Elt)); }