summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/CodeView
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/CodeView')
-rw-r--r--llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp36
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp53
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp78
3 files changed, 136 insertions, 31 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
index 0069ee3cc90..23f2c40543a 100644
--- a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
@@ -76,7 +76,7 @@ void CVTypeVisitor::addTypeServerHandler(TypeServerHandler &Handler) {
Handlers.push_back(&Handler);
}
-Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
+Expected<bool> CVTypeVisitor::handleTypeServer(CVType &Record) {
if (Record.Type == TypeLeafKind::LF_TYPESERVER2 && !Handlers.empty()) {
auto TS = deserializeTypeServerRecord(Record);
if (!TS)
@@ -90,16 +90,16 @@ Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
// If the handler processed the record, return success.
if (*ExpectedResult)
- return Error::success();
+ return true;
// Otherwise keep searching for a handler, eventually falling out and
// using the default record handler.
}
}
+ return false;
+}
- if (auto EC = Callbacks.visitTypeBegin(Record))
- return EC;
-
+Error CVTypeVisitor::finishVisitation(CVType &Record) {
switch (Record.Type) {
default:
if (auto EC = Callbacks.visitUnknownType(Record))
@@ -124,6 +124,32 @@ Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
return Error::success();
}
+Error CVTypeVisitor::visitTypeRecord(CVType &Record, TypeIndex Index) {
+ auto ExpectedResult = handleTypeServer(Record);
+ if (!ExpectedResult)
+ return ExpectedResult.takeError();
+ if (*ExpectedResult)
+ return Error::success();
+
+ if (auto EC = Callbacks.visitTypeBegin(Record, Index))
+ return EC;
+
+ return finishVisitation(Record);
+}
+
+Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
+ auto ExpectedResult = handleTypeServer(Record);
+ if (!ExpectedResult)
+ return ExpectedResult.takeError();
+ if (*ExpectedResult)
+ return Error::success();
+
+ if (auto EC = Callbacks.visitTypeBegin(Record))
+ return EC;
+
+ return finishVisitation(Record);
+}
+
static Error visitMemberRecord(CVMemberRecord &Record,
TypeVisitorCallbacks &Callbacks) {
if (auto EC = Callbacks.visitMemberBegin(Record))
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp b/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp
index 5b8841041f8..1f2a5d7b333 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp
@@ -112,16 +112,61 @@ StringRef TypeDatabase::getTypeName(TypeIndex Index) const {
}
const CVType &TypeDatabase::getTypeRecord(TypeIndex Index) const {
- return TypeRecords[Index.getIndex() - TypeIndex::FirstNonSimpleIndex];
+ return TypeRecords[toArrayIndex(Index)];
}
CVType &TypeDatabase::getTypeRecord(TypeIndex Index) {
- return TypeRecords[Index.getIndex() - TypeIndex::FirstNonSimpleIndex];
+ return TypeRecords[toArrayIndex(Index)];
}
bool TypeDatabase::containsTypeIndex(TypeIndex Index) const {
- uint32_t I = Index.getIndex() - TypeIndex::FirstNonSimpleIndex;
- return I < CVUDTNames.size();
+ return toArrayIndex(Index) < CVUDTNames.size();
}
uint32_t TypeDatabase::size() const { return CVUDTNames.size(); }
+
+uint32_t TypeDatabase::toArrayIndex(TypeIndex Index) const {
+ assert(Index.getIndex() >= TypeIndex::FirstNonSimpleIndex);
+ return Index.getIndex() - TypeIndex::FirstNonSimpleIndex;
+}
+
+RandomAccessTypeDatabase::RandomAccessTypeDatabase(uint32_t ExpectedSize)
+ : TypeDatabase(ExpectedSize) {
+ ValidRecords.resize(ExpectedSize);
+ CVUDTNames.resize(ExpectedSize);
+ TypeRecords.resize(ExpectedSize);
+}
+
+void RandomAccessTypeDatabase::recordType(StringRef Name, TypeIndex Index,
+ const CVType &Data) {
+ assert(!containsTypeIndex(Index));
+ uint32_t ZI = Index.getIndex() - TypeIndex::FirstNonSimpleIndex;
+
+ CVUDTNames[ZI] = Name;
+ TypeRecords[ZI] = Data;
+ ValidRecords.set(ZI);
+}
+
+StringRef RandomAccessTypeDatabase::getTypeName(TypeIndex Index) const {
+ assert(containsTypeIndex(Index));
+ return TypeDatabase::getTypeName(Index);
+}
+
+const CVType &RandomAccessTypeDatabase::getTypeRecord(TypeIndex Index) const {
+ assert(containsTypeIndex(Index));
+ return TypeDatabase::getTypeRecord(Index);
+}
+
+CVType &RandomAccessTypeDatabase::getTypeRecord(TypeIndex Index) {
+ assert(containsTypeIndex(Index));
+ return TypeDatabase::getTypeRecord(Index);
+}
+
+bool RandomAccessTypeDatabase::containsTypeIndex(TypeIndex Index) const {
+ if (Index.isSimple())
+ return true;
+
+ return ValidRecords.test(toArrayIndex(Index));
+}
+
+uint32_t RandomAccessTypeDatabase::size() const { return ValidRecords.count(); }
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp b/llvm/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp
index c234afd2288..8c1a651b653 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp
@@ -15,7 +15,9 @@ using namespace llvm;
using namespace llvm::codeview;
-Error TypeDatabaseVisitor::visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
+Error TypeDatabaseVisitor::visitTypeBegin(CVType &Record) {
+ assert(TypeDB.is<TypeDatabase *>());
+
assert(!IsInFieldList);
// Reset Name to the empty string. If the visitor sets it, we know it.
Name = "";
@@ -28,6 +30,34 @@ Error TypeDatabaseVisitor::visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
return Error::success();
}
+StringRef TypeDatabaseVisitor::getTypeName(TypeIndex Index) const {
+ if (auto DB = TypeDB.get<TypeDatabase *>())
+ return DB->getTypeName(Index);
+ else if (auto DB = TypeDB.get<RandomAccessTypeDatabase *>())
+ return DB->getTypeName(Index);
+
+ llvm_unreachable("Invalid TypeDB Kind!");
+}
+
+StringRef TypeDatabaseVisitor::saveTypeName(StringRef Name) {
+ if (auto DB = TypeDB.get<TypeDatabase *>())
+ return DB->saveTypeName(Name);
+ else if (auto DB = TypeDB.get<RandomAccessTypeDatabase *>())
+ return DB->saveTypeName(Name);
+
+ llvm_unreachable("Invalid TypeDB Kind!");
+}
+
+Error TypeDatabaseVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
+ assert(TypeDB.is<RandomAccessTypeDatabase *>());
+
+ if (auto EC = visitTypeBegin(Record))
+ return EC;
+
+ CurrentTypeIndex = Index;
+ return Error::success();
+}
+
Error TypeDatabaseVisitor::visitTypeEnd(CVType &CVR) {
if (CVR.Type == LF_FIELDLIST) {
assert(IsInFieldList);
@@ -39,7 +69,11 @@ Error TypeDatabaseVisitor::visitTypeEnd(CVType &CVR) {
// CVUDTNames is indexed by type index, and must have one entry for every
// type. Field list members are not recorded, and are only referenced by
// their containing field list record.
- TypeDB.recordType(Name, CVR);
+ if (auto DB = TypeDB.get<TypeDatabase *>())
+ DB->recordType(Name, CVR);
+ else if (auto DB = TypeDB.get<RandomAccessTypeDatabase *>())
+ DB->recordType(Name, CurrentTypeIndex, CVR);
+
return Error::success();
}
@@ -73,13 +107,13 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
uint32_t Size = Indices.size();
SmallString<256> TypeName("(");
for (uint32_t I = 0; I < Size; ++I) {
- StringRef ArgTypeName = TypeDB.getTypeName(Indices[I]);
+ StringRef ArgTypeName = getTypeName(Indices[I]);
TypeName.append(ArgTypeName);
if (I + 1 != Size)
TypeName.append(", ");
}
TypeName.push_back(')');
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
@@ -89,13 +123,13 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
uint32_t Size = Indices.size();
SmallString<256> TypeName("\"");
for (uint32_t I = 0; I < Size; ++I) {
- StringRef ArgTypeName = TypeDB.getTypeName(Indices[I]);
+ StringRef ArgTypeName = getTypeName(Indices[I]);
TypeName.append(ArgTypeName);
if (I + 1 != Size)
TypeName.append("\" \"");
}
TypeName.push_back('\"');
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
@@ -132,26 +166,26 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
ProcedureRecord &Proc) {
- StringRef ReturnTypeName = TypeDB.getTypeName(Proc.getReturnType());
- StringRef ArgListTypeName = TypeDB.getTypeName(Proc.getArgumentList());
+ StringRef ReturnTypeName = getTypeName(Proc.getReturnType());
+ StringRef ArgListTypeName = getTypeName(Proc.getArgumentList());
SmallString<256> TypeName(ReturnTypeName);
TypeName.push_back(' ');
TypeName.append(ArgListTypeName);
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
MemberFunctionRecord &MF) {
- StringRef ReturnTypeName = TypeDB.getTypeName(MF.getReturnType());
- StringRef ClassTypeName = TypeDB.getTypeName(MF.getClassType());
- StringRef ArgListTypeName = TypeDB.getTypeName(MF.getArgumentList());
+ StringRef ReturnTypeName = getTypeName(MF.getReturnType());
+ StringRef ClassTypeName = getTypeName(MF.getClassType());
+ StringRef ArgListTypeName = getTypeName(MF.getArgumentList());
SmallString<256> TypeName(ReturnTypeName);
TypeName.push_back(' ');
TypeName.append(ClassTypeName);
TypeName.append("::");
TypeName.append(ArgListTypeName);
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
@@ -171,13 +205,13 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
if (Ptr.isPointerToMember()) {
const MemberPointerInfo &MI = Ptr.getMemberInfo();
- StringRef PointeeName = TypeDB.getTypeName(Ptr.getReferentType());
- StringRef ClassName = TypeDB.getTypeName(MI.getContainingType());
+ StringRef PointeeName = getTypeName(Ptr.getReferentType());
+ StringRef ClassName = getTypeName(MI.getContainingType());
SmallString<256> TypeName(PointeeName);
TypeName.push_back(' ');
TypeName.append(ClassName);
TypeName.append("::*");
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
} else {
SmallString<256> TypeName;
if (Ptr.isConst())
@@ -187,7 +221,7 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
if (Ptr.isUnaligned())
TypeName.append("__unaligned ");
- TypeName.append(TypeDB.getTypeName(Ptr.getReferentType()));
+ TypeName.append(getTypeName(Ptr.getReferentType()));
if (Ptr.getMode() == PointerMode::LValueReference)
TypeName.append("&");
@@ -197,7 +231,7 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
TypeName.append("*");
if (!TypeName.empty())
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
}
return Error::success();
}
@@ -205,7 +239,7 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
- StringRef ModifiedName = TypeDB.getTypeName(Mod.getModifiedType());
+ StringRef ModifiedName = getTypeName(Mod.getModifiedType());
SmallString<256> TypeName;
if (Mods & uint16_t(ModifierOptions::Const))
TypeName.append("const ");
@@ -214,14 +248,14 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
if (Mods & uint16_t(ModifierOptions::Unaligned))
TypeName.append("__unaligned ");
TypeName.append(ModifiedName);
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
VFTableShapeRecord &Shape) {
- Name = TypeDB.saveTypeName("<vftable " + utostr(Shape.getEntryCount()) +
- " methods>");
+ Name =
+ saveTypeName("<vftable " + utostr(Shape.getEntryCount()) + " methods>");
return Error::success();
}
OpenPOWER on IntegriCloud