mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-21 23:17:16 +00:00
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:
+70
-2
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user