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<DITypeRef> 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
This commit is contained in:
Manman Ren
2013-09-05 18:48:31 +00:00
parent 79916948e1
commit bc66071baa
7 changed files with 156 additions and 6 deletions
+70 -2
View File
@@ -425,6 +425,17 @@ static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) {
return !Fld || isa<MDString>(Fld);
}
/// Check if a value can be a TypeRef.
static bool isTypeRef(const Value *Val) {
return !Val || isa<MDString>(Val) || isa<MDNode>(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<DITypeIdentifierMap::iterator, bool> 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<MDNode>(TypeVal)) {
assert(DIType(MD).isType() &&
"MDNode in DITypeRef should be a DIType.");
return MD;
}
const MDString *MS = cast<MDString>(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<DITypeRef>(unsigned Elt) const {
return DITypeRef(getField(DbgNode, Elt));
}