Debug Info: Rename DITypeRef to DIScopeRef.

A reference to a scope is more general than a reference to a type since
DIType is a subclass of DIScope.

A reference to a type can be either an identifier for the type or
the DIType itself, while a reference to a scope can be either an
identifier for the type (when the scope is indeed a type) or the
DIScope itself. A reference to a type and a reference to a scope
will be resolved in the same way. The only difference is in the
verifier when a field is a reference to a type (i.e. the containing
type field of a DICompositeType) or a field is a reference to a scope
(i.e. the context field of a DIType).

This is to get ready for switching DIType::getContext to return
DIScopeRef instead of DIScope.

Tighten up isTypeRef and isScopeRef to make sure the identifier is not
empty and the MDNode is DIType for TypeRef and DIScope for ScopeRef.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190322 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Manman Ren 2013-09-09 19:03:51 +00:00
parent 626a4b785b
commit c573305bce
4 changed files with 65 additions and 60 deletions

View File

@ -46,7 +46,7 @@ namespace llvm {
class DILexicalBlockFile; class DILexicalBlockFile;
class DIVariable; class DIVariable;
class DIType; class DIType;
class DITypeRef; class DIScopeRef;
class DIObjCProperty; class DIObjCProperty;
/// Maps from type identifier to the actual MDNode. /// 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 /// This should not be stored in a container, because the underlying MDNode
/// may change in certain situations. /// may change in certain situations.
class DIDescriptor { class DIDescriptor {
// Befriends DITypeRef so DITypeRef can befriend the protected member // Befriends DIScopeRef so DIScopeRef can befriend the protected member
// function: getFieldAs<DITypeRef>. // function: getFieldAs<DIScopeRef>.
friend class DITypeRef; friend class DIScopeRef;
public: public:
enum { enum {
FlagPrivate = 1 << 0, FlagPrivate = 1 << 0,
@ -151,9 +151,9 @@ namespace llvm {
void dump() const; void dump() const;
}; };
/// Specialize getFieldAs to handle fields that are references to DITypes. /// npecialize getFieldAs to handle fields that are references to DIScopes.
template <> template <>
DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const; DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;
/// DISubrange - This is used to represent ranges, for array bounds. /// DISubrange - This is used to represent ranges, for array bounds.
class DISubrange : public DIDescriptor { class DISubrange : public DIDescriptor {
@ -205,6 +205,25 @@ namespace llvm {
DIScope getContext() const; DIScope getContext() const;
StringRef getFilename() const; StringRef getFilename() const;
StringRef getDirectory() 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 <typename DescTy>
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<Value*>(Val); }
}; };
/// DIType - This is a wrapper for a type. /// DIType - This is a wrapper for a type.
@ -271,32 +290,12 @@ namespace llvm {
/// isUnsignedDIType - Return true if type encoding is unsigned. /// isUnsignedDIType - Return true if type encoding is unsigned.
bool isUnsignedDIType(); 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 /// replaceAllUsesWith - Replace all uses of debug info referenced by
/// this descriptor. /// this descriptor.
void replaceAllUsesWith(DIDescriptor &D); void replaceAllUsesWith(DIDescriptor &D);
void replaceAllUsesWith(MDNode *D); void replaceAllUsesWith(MDNode *D);
}; };
/// Represents reference to a DIType, abstracts over direct and
/// identifier-based metadata type references.
class DITypeRef {
template <typename DescTy>
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<Value*>(TypeVal); }
};
/// DIBasicType - A basic type, like 'int' or 'float'. /// DIBasicType - A basic type, like 'int' or 'float'.
class DIBasicType : public DIType { class DIBasicType : public DIType {
public: public:
@ -328,9 +327,9 @@ namespace llvm {
/// associated with one. /// associated with one.
MDNode *getObjCProperty() const; MDNode *getObjCProperty() const;
DITypeRef getClassType() const { DIScopeRef getClassType() const {
assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
return getFieldAs<DITypeRef>(10); return getFieldAs<DIScopeRef>(10);
} }
Constant *getConstant() const { Constant *getConstant() const {
@ -358,8 +357,8 @@ namespace llvm {
void setTypeArray(DIArray Elements, DIArray TParams = DIArray()); void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
void addMember(DIDescriptor D); void addMember(DIDescriptor D);
unsigned getRunTimeLang() const { return getUnsignedField(11); } unsigned getRunTimeLang() const { return getUnsignedField(11); }
DITypeRef getContainingType() const { DIScopeRef getContainingType() const {
return getFieldAs<DITypeRef>(12); return getFieldAs<DIScopeRef>(12);
} }
void setContainingType(DICompositeType ContainingType); void setContainingType(DICompositeType ContainingType);
DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); } DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
@ -426,8 +425,8 @@ namespace llvm {
unsigned getVirtuality() const { return getUnsignedField(10); } unsigned getVirtuality() const { return getUnsignedField(10); }
unsigned getVirtualIndex() const { return getUnsignedField(11); } unsigned getVirtualIndex() const { return getUnsignedField(11); }
DITypeRef getContainingType() const { DIScopeRef getContainingType() const {
return getFieldAs<DITypeRef>(12); return getFieldAs<DIScopeRef>(12);
} }
unsigned getFlags() const { unsigned getFlags() const {

View File

@ -2633,7 +2633,7 @@ void DwarfDebug::emitDebugStrDWO() {
OffSec, StrSym); OffSec, StrSym);
} }
/// Find the MDNode for the given type reference. /// Find the MDNode for the given scope reference.
MDNode *DwarfDebug::resolve(DITypeRef TRef) const { DIScope DwarfDebug::resolve(DIScopeRef SRef) const {
return TRef.resolve(TypeIdentifierMap); return SRef.resolve(TypeIdentifierMap);
} }

View File

@ -683,8 +683,8 @@ public:
/// Returns the Dwarf Version. /// Returns the Dwarf Version.
unsigned getDwarfVersion() const { return DwarfVersion; } unsigned getDwarfVersion() const { return DwarfVersion; }
/// Find the MDNode for the given type reference. /// Find the MDNode for the given scope reference.
MDNode *resolve(DITypeRef TRef) const; DIScope resolve(DIScopeRef SRef) const;
}; };
} // End of namespace llvm } // End of namespace llvm

View File

@ -426,17 +426,26 @@ static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) {
return !Fld || isa<MDString>(Fld); return !Fld || isa<MDString>(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) { static bool isTypeRef(const Value *Val) {
return !Val || isa<MDString>(Val) || isa<MDNode>(Val); return !Val ||
(isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
(isa<MDNode>(Val) && DIType(cast<MDNode>(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) { static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) {
Value *Fld = getField(DbgNode, Elt); Value *Fld = getField(DbgNode, Elt);
return isTypeRef(Fld); return isTypeRef(Fld);
} }
/// Check if a value can be a ScopeRef.
static bool isScopeRef(const Value *Val) {
return !Val ||
(isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
(isa<MDNode>(Val) && DIScope(cast<MDNode>(Val)).isScope());
}
/// Verify - Verify that a type descriptor is well formed. /// Verify - Verify that a type descriptor is well formed.
bool DIType::Verify() const { bool DIType::Verify() const {
if (!isType()) if (!isType())
@ -710,13 +719,13 @@ void DICompositeType::addMember(DIDescriptor D) {
/// Generate a reference to this DIType. Uses the type identifier instead /// Generate a reference to this DIType. Uses the type identifier instead
/// of the actual MDNode if possible, to help type uniquing. /// of the actual MDNode if possible, to help type uniquing.
DITypeRef DIType::generateRef() { Value *DIScope::generateRef() {
if (!isCompositeType()) if (!isCompositeType())
return DITypeRef(*this); return *this;
DICompositeType DTy(DbgNode); DICompositeType DTy(DbgNode);
if (!DTy.getIdentifier()) if (!DTy.getIdentifier())
return DITypeRef(*this); return *this;
return DITypeRef(DTy.getIdentifier()); return DTy.getIdentifier();
} }
/// \brief Set the containing type. /// \brief Set the containing type.
@ -1428,33 +1437,30 @@ void DIVariable::printExtendedName(raw_ostream &OS) const {
} }
} }
DITypeRef::DITypeRef(const Value *V) : TypeVal(V) { DIScopeRef::DIScopeRef(const Value *V) : Val(V) {
assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode"); assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode");
} }
/// Given a DITypeIdentifierMap, tries to find the corresponding /// Given a DITypeIdentifierMap, tries to find the corresponding
/// DIType for a DITypeRef. /// DIScope for a DIScopeRef.
DIType DITypeRef::resolve(const DITypeIdentifierMap &Map) const { DIScope DIScopeRef::resolve(const DITypeIdentifierMap &Map) const {
if (!TypeVal) if (!Val)
return NULL; return DIScope();
if (const MDNode *MD = dyn_cast<MDNode>(TypeVal)) { if (const MDNode *MD = dyn_cast<MDNode>(Val))
assert(DIType(MD).isType() && return DIScope(MD);
"MDNode in DITypeRef should be a DIType.");
return MD;
}
const MDString *MS = cast<MDString>(TypeVal); const MDString *MS = cast<MDString>(Val);
// Find the corresponding MDNode. // Find the corresponding MDNode.
DITypeIdentifierMap::const_iterator Iter = Map.find(MS); DITypeIdentifierMap::const_iterator Iter = Map.find(MS);
assert(Iter != Map.end() && "Identifier not in the type map?"); assert(Iter != Map.end() && "Identifier not in the type map?");
assert(DIType(Iter->second).isType() && assert(DIType(Iter->second).isType() &&
"MDNode in DITypeIdentifierMap should be a DIType."); "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 <> template <>
DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const { DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const {
return DITypeRef(getField(DbgNode, Elt)); return DIScopeRef(getField(DbgNode, Elt));
} }