From bc66071baa3153ba95d673b8084383835221eef6 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Thu, 5 Sep 2013 18:48:31 +0000 Subject: Debug Info: Use identifier to reference DIType in base type field of ptr_to_member. We introduce a new class DITypeRef that represents a reference to a DIType. It wraps around a Value*, which can be either an identifier in MDString or an actual MDNode. The class has a helper function "resolve" that finds the actual MDNode for a given DITypeRef. We specialize getFieldAs to return a field that is a reference to a DIType. To correctly access the base type field of ptr_to_member, getClassType now calls getFieldAs to return a DITypeRef. Also add a typedef for DITypeIdentifierMap and a helper generateDITypeIdentifierMap in DebugInfo.h. In DwarfDebug.cpp, we keep a DITypeIdentifierMap and call generateDITypeIdentifierMap to actually populate the map. Verifier is updated accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190081 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/DebugInfo.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) (limited to 'lib/IR/DebugInfo.cpp') diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index 9684bd73f4..d3207cae35 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -425,6 +425,17 @@ static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) { return !Fld || isa(Fld); } +/// Check if a value can be a TypeRef. +static bool isTypeRef(const Value *Val) { + return !Val || isa(Val) || isa(Val); +} + +/// Check if a field at position Elt of a MDNode can be a TypeRef. +static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) { + Value *Fld = getField(DbgNode, Elt); + return isTypeRef(Fld); +} + /// Verify - Verify that a type descriptor is well formed. bool DIType::Verify() const { if (!isType()) @@ -470,8 +481,8 @@ bool DIDerivedType::Verify() const { if (!fieldIsMDNode(DbgNode, 9)) return false; if (getTag() == dwarf::DW_TAG_ptr_to_member_type) - // Make sure ClassType @ field 10 is MDNode. - if (!fieldIsMDNode(DbgNode, 10)) + // Make sure ClassType @ field 10 is a TypeRef. + if (!fieldIsTypeRef(DbgNode, 10)) return false; return isDerivedType() && DbgNode->getNumOperands() >= 10 && @@ -923,6 +934,32 @@ bool llvm::isSubprogramContext(const MDNode *Context) { return false; } +/// Update DITypeIdentifierMap by going through retained types of each CU. +DITypeIdentifierMap llvm::generateDITypeIdentifierMap( + const NamedMDNode *CU_Nodes) { + DITypeIdentifierMap Map; + for (unsigned CUi = 0, CUe = CU_Nodes->getNumOperands(); CUi != CUe; ++CUi) { + DICompileUnit CU(CU_Nodes->getOperand(CUi)); + DIArray Retain = CU.getRetainedTypes(); + for (unsigned Ti = 0, Te = Retain.getNumElements(); Ti != Te; ++Ti) { + if (!Retain.getElement(Ti).isCompositeType()) + continue; + DICompositeType Ty(Retain.getElement(Ti)); + if (MDString *TypeId = Ty.getIdentifier()) { + // Definition has priority over declaration. + // Try to insert (TypeId, Ty) to Map. + std::pair P = + Map.insert(std::make_pair(TypeId, Ty)); + // If TypeId already exists in Map and this is a definition, replace + // whatever we had (declaration or definition) with the definition. + if (!P.second && !Ty.isForwardDecl()) + P.first->second = Ty; + } + } + } + return Map; +} + //===----------------------------------------------------------------------===// // DebugInfoFinder implementations. //===----------------------------------------------------------------------===// @@ -1378,3 +1415,34 @@ void DIVariable::printExtendedName(raw_ostream &OS) const { } } } + +DITypeRef::DITypeRef(const Value *V) : TypeVal(V) { + assert(isTypeRef(V) && "DITypeRef 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; + + if (const MDNode *MD = dyn_cast(TypeVal)) { + assert(DIType(MD).isType() && + "MDNode in DITypeRef should be a DIType."); + return MD; + } + + const MDString *MS = cast(TypeVal); + // 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; +} + +/// Specialize getFieldAs to handle fields that are references to DITypes. +template <> +DITypeRef DIDescriptor::getFieldAs(unsigned Elt) const { + return DITypeRef(getField(DbgNode, Elt)); +} -- cgit v1.2.3