summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-08-05 21:45:34 +0000
committerZachary Turner <zturner@google.com>2016-08-05 21:45:34 +0000
commit5e3e4bb26b4225156344eaa3ef538396a5993e3b (patch)
treeeb2f7e1d33242df6d3dac0293367f696213afb86 /llvm/lib/DebugInfo
parent9c3dac8efd19590fc88c531ac736a35475f3a486 (diff)
downloadbcm5719-llvm-5e3e4bb26b4225156344eaa3ef538396a5993e3b.tar.gz
bcm5719-llvm-5e3e4bb26b4225156344eaa3ef538396a5993e3b.zip
[CodeView] Decouple record deserialization from visitor dispatch.
Until now, our use case for the visitor has been to take a stream of bytes representing a type stream, deserialize the records in sequence, and do something with them, where "something" is determined by how the user implements a particular set of callbacks on an abstract class. For actually writing PDBs, however, we want to do the reverse. We have some kind of description of the list of records in their in-memory format, and we want to process each one. Perhaps by serializing them to a byte stream, or perhaps by converting them from one description format (Yaml) to another (in-memory representation). This was difficult in the current model because deserialization and invoking the callbacks were tightly coupled. With this patch we change this so that TypeDeserializer is itself an implementation of the particular set of callbacks. This decouples deserialization from the iteration over a list of records and invocation of the callbacks. TypeDeserializer is initialized with another implementation of the callback interface, so that upon deserialization it can pass the deserialized record through to the next set of callbacks. In a sense this is like an implementation of the Decorator design pattern, where the Deserializer is a decorator. This will be useful for writing Pdbs from yaml, where we have a description of the type records in Yaml format. In this case, the visitor implementation would have each visitation callback method implemented in such a way as to extract the proper set of fields from the Yaml, and it could maintain state that builds up a list of these records. Finally at the end we can pass this information through to another set of callbacks which serializes them into a byte stream. Reviewed By: majnemer, ruiu, rnk Differential Revision: https://reviews.llvm.org/D23177 llvm-svn: 277871
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/CodeView/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp88
-rw-r--r--llvm/lib/DebugInfo/CodeView/CodeViewError.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp18
-rw-r--r--llvm/lib/DebugInfo/CodeView/ListRecordBuilder.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp81
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeDumper.cpp106
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeRecord.cpp5
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp59
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp48
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp25
11 files changed, 264 insertions, 171 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
index d8c21953967..92ffd3d24d7 100644
--- a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
@@ -11,6 +11,7 @@ add_llvm_library(LLVMDebugInfoCodeView
ModuleSubstreamVisitor.cpp
RecordSerialization.cpp
SymbolDumper.cpp
+ TypeDeserializer.cpp
TypeDumper.cpp
TypeRecord.cpp
TypeRecordBuilder.cpp
diff --git a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
index a7b7f3a2793..01dd5d4591c 100644
--- a/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
@@ -8,47 +8,39 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/Msf/ByteStream.h"
using namespace llvm;
using namespace llvm::codeview;
+CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
+ : Callbacks(Callbacks) {}
+
template <typename T>
-static Error takeObject(ArrayRef<uint8_t> &Data, const T *&Res) {
- if (Data.size() < sizeof(*Res))
- return llvm::make_error<CodeViewError>(cv_error_code::insufficient_buffer);
- Res = reinterpret_cast<const T *>(Data.data());
- Data = Data.drop_front(sizeof(*Res));
+static Error visitKnownRecord(const CVRecord<TypeLeafKind> &Record,
+ TypeVisitorCallbacks &Callbacks) {
+ TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Type);
+ T KnownRecord(RK);
+ if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
+ return EC;
return Error::success();
}
-CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
- : Callbacks(Callbacks) {}
-
Error CVTypeVisitor::visitTypeRecord(const CVRecord<TypeLeafKind> &Record) {
ArrayRef<uint8_t> LeafData = Record.Data;
if (auto EC = Callbacks.visitTypeBegin(Record))
return EC;
+
switch (Record.Type) {
default:
if (auto EC = Callbacks.visitUnknownType(Record))
return EC;
break;
- case LF_FIELDLIST:
- if (auto EC = Callbacks.visitFieldListBegin(Record))
- return EC;
- if (auto EC = visitFieldList(Record))
- return EC;
- if (auto EC = Callbacks.visitFieldListEnd(Record))
- return EC;
- break;
#define TYPE_RECORD(EnumName, EnumVal, Name) \
case EnumName: { \
- TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
- auto ExpectedRecord = Name##Record::deserialize(RK, LeafData); \
- if (!ExpectedRecord) \
- return ExpectedRecord.takeError(); \
- if (auto EC = Callbacks.visit##Name(*ExpectedRecord)) \
+ if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks)) \
return EC; \
break; \
}
@@ -57,8 +49,10 @@ Error CVTypeVisitor::visitTypeRecord(const CVRecord<TypeLeafKind> &Record) {
#define MEMBER_RECORD(EnumName, EnumVal, Name)
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
}
+
if (auto EC = Callbacks.visitTypeEnd(Record))
return EC;
+
return Error::success();
}
@@ -70,55 +64,3 @@ Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) {
}
return Error::success();
}
-
-Error CVTypeVisitor::skipPadding(ArrayRef<uint8_t> &Data) {
- if (Data.empty())
- return Error::success();
- uint8_t Leaf = Data.front();
- if (Leaf < LF_PAD0)
- return Error::success();
- // Leaf is greater than 0xf0. We should advance by the number of bytes in
- // the low 4 bits.
- unsigned BytesToAdvance = Leaf & 0x0F;
- if (Data.size() < BytesToAdvance) {
- return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Invalid padding bytes!");
- }
- Data = Data.drop_front(BytesToAdvance);
- return Error::success();
-}
-
-/// Visits individual member records of a field list record. Member records do
-/// not describe their own length, and need special handling.
-Error CVTypeVisitor::visitFieldList(const CVRecord<TypeLeafKind> &Record) {
- ArrayRef<uint8_t> RecordData = Record.Data;
- while (!RecordData.empty()) {
- const ulittle16_t *LeafPtr;
- if (auto EC = takeObject(RecordData, LeafPtr))
- return EC;
- TypeLeafKind Leaf = TypeLeafKind(unsigned(*LeafPtr));
- switch (Leaf) {
- default:
- // Field list records do not describe their own length, so we cannot
- // continue parsing past an unknown member type.
- if (auto EC = Callbacks.visitUnknownMember(Record))
- return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record);
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- case EnumName: { \
- TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
- auto ExpectedRecord = Name##Record::deserialize(RK, RecordData); \
- if (!ExpectedRecord) \
- return ExpectedRecord.takeError(); \
- if (auto EC = Callbacks.visit##Name(*ExpectedRecord)) \
- return EC; \
- break; \
- }
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
- MEMBER_RECORD(EnumVal, EnumVal, AliasName)
-#include "llvm/DebugInfo/CodeView/TypeRecords.def"
- }
- if (auto EC = skipPadding(RecordData))
- return EC;
- }
- return Error::success();
-}
diff --git a/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp b/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp
index aad1d8b25cd..e9678db7a5b 100644
--- a/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp
@@ -33,6 +33,8 @@ public:
return "The CodeView record is corrupted.";
case cv_error_code::operation_unsupported:
return "The requested operation is not supported.";
+ case cv_error_code::unknown_member_record:
+ return "The member record is of an unknown type.";
}
llvm_unreachable("Unrecognized cv_error_code");
}
diff --git a/llvm/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp b/llvm/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp
index 5f229e3d9f9..ac2ef3972b6 100644
--- a/llvm/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp
+++ b/llvm/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp
@@ -15,7 +15,7 @@ using namespace codeview;
FieldListRecordBuilder::FieldListRecordBuilder()
: ListRecordBuilder(TypeRecordKind::FieldList) {}
-void FieldListRecordBuilder::writeBaseClass(const BaseClassRecord &Record) {
+void FieldListRecordBuilder::writeMemberType(const BaseClassRecord &Record) {
TypeRecordBuilder &Builder = getBuilder();
Builder.writeTypeRecordKind(TypeRecordKind::BaseClass);
@@ -26,7 +26,7 @@ void FieldListRecordBuilder::writeBaseClass(const BaseClassRecord &Record) {
finishSubRecord();
}
-void FieldListRecordBuilder::writeEnumerator(const EnumeratorRecord &Record) {
+void FieldListRecordBuilder::writeMemberType(const EnumeratorRecord &Record) {
TypeRecordBuilder &Builder = getBuilder();
Builder.writeTypeRecordKind(TypeRecordKind::Enumerator);
@@ -38,7 +38,7 @@ void FieldListRecordBuilder::writeEnumerator(const EnumeratorRecord &Record) {
finishSubRecord();
}
-void FieldListRecordBuilder::writeDataMember(const DataMemberRecord &Record) {
+void FieldListRecordBuilder::writeMemberType(const DataMemberRecord &Record) {
TypeRecordBuilder &Builder = getBuilder();
Builder.writeTypeRecordKind(Record.getKind());
@@ -50,7 +50,7 @@ void FieldListRecordBuilder::writeDataMember(const DataMemberRecord &Record) {
finishSubRecord();
}
-void FieldListRecordBuilder::writeOverloadedMethod(
+void FieldListRecordBuilder::writeMemberType(
const OverloadedMethodRecord &Record) {
TypeRecordBuilder &Builder = getBuilder();
@@ -62,7 +62,7 @@ void FieldListRecordBuilder::writeOverloadedMethod(
finishSubRecord();
}
-void FieldListRecordBuilder::writeOneMethod(const OneMethodRecord &Record) {
+void FieldListRecordBuilder::writeMemberType(const OneMethodRecord &Record) {
TypeRecordBuilder &Builder = getBuilder();
uint16_t Flags = static_cast<uint16_t>(Record.getAccess());
@@ -84,7 +84,7 @@ void FieldListRecordBuilder::writeOneMethod(const OneMethodRecord &Record) {
finishSubRecord();
}
-void FieldListRecordBuilder::writeNestedType(const NestedTypeRecord &Record) {
+void FieldListRecordBuilder::writeMemberType(const NestedTypeRecord &Record) {
TypeRecordBuilder &Builder = getBuilder();
Builder.writeTypeRecordKind(Record.getKind());
@@ -95,7 +95,7 @@ void FieldListRecordBuilder::writeNestedType(const NestedTypeRecord &Record) {
finishSubRecord();
}
-void FieldListRecordBuilder::writeStaticDataMember(
+void FieldListRecordBuilder::writeMemberType(
const StaticDataMemberRecord &Record) {
TypeRecordBuilder &Builder = getBuilder();
@@ -107,7 +107,7 @@ void FieldListRecordBuilder::writeStaticDataMember(
finishSubRecord();
}
-void FieldListRecordBuilder::writeVirtualBaseClass(
+void FieldListRecordBuilder::writeMemberType(
const VirtualBaseClassRecord &Record) {
TypeRecordBuilder &Builder = getBuilder();
@@ -121,7 +121,7 @@ void FieldListRecordBuilder::writeVirtualBaseClass(
finishSubRecord();
}
-void FieldListRecordBuilder::writeVFPtr(const VFPtrRecord &Record) {
+void FieldListRecordBuilder::writeMemberType(const VFPtrRecord &Record) {
TypeRecordBuilder &Builder = getBuilder();
Builder.writeTypeRecordKind(TypeRecordKind::VFPtr);
diff --git a/llvm/lib/DebugInfo/CodeView/ListRecordBuilder.cpp b/llvm/lib/DebugInfo/CodeView/ListRecordBuilder.cpp
index eb79e8ac9a3..ab019c44c5b 100644
--- a/llvm/lib/DebugInfo/CodeView/ListRecordBuilder.cpp
+++ b/llvm/lib/DebugInfo/CodeView/ListRecordBuilder.cpp
@@ -17,7 +17,7 @@ using namespace codeview;
ListRecordBuilder::ListRecordBuilder(TypeRecordKind Kind)
: Kind(Kind), Builder(Kind) {}
-void ListRecordBuilder::writeListContinuation(const ListContinuationRecord &R) {
+void ListRecordBuilder::writeMemberType(const ListContinuationRecord &R) {
TypeRecordBuilder &Builder = getBuilder();
assert(getLastContinuationSize() < 65535 - 8 && "continuation won't fit");
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp b/llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp
new file mode 100644
index 00000000000..3593458565f
--- /dev/null
+++ b/llvm/lib/DebugInfo/CodeView/TypeDeserializer.cpp
@@ -0,0 +1,81 @@
+//===- TypeDeserializer.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+template <typename T>
+static Error takeObject(ArrayRef<uint8_t> &Data, const T *&Res) {
+ if (Data.size() < sizeof(*Res))
+ return llvm::make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+ Res = reinterpret_cast<const T *>(Data.data());
+ Data = Data.drop_front(sizeof(*Res));
+ return Error::success();
+}
+
+Error TypeDeserializer::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ FieldListRecord &Record) {
+ ArrayRef<uint8_t> FieldListRecordData = CVR.Data;
+ auto ExpectedRecord = FieldListRecord::deserialize(TypeRecordKind::FieldList,
+ FieldListRecordData);
+ if (!ExpectedRecord)
+ return ExpectedRecord.takeError();
+
+ Record = *ExpectedRecord;
+ ArrayRef<uint8_t> MemberData = Record.getFieldListData();
+
+ while (!MemberData.empty()) {
+ const ulittle16_t *LeafPtr;
+ if (auto EC = takeObject(MemberData, LeafPtr))
+ return EC;
+ TypeLeafKind Leaf = TypeLeafKind(unsigned(*LeafPtr));
+ switch (Leaf) {
+ default:
+ // Field list records do not describe their own length, so we cannot
+ // continue parsing past a type that we don't know how to deserialize.
+ if (auto EC = Recipient.visitUnknownMember(CVR))
+ return EC;
+ return llvm::make_error<CodeViewError>(
+ cv_error_code::unknown_member_record);
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ case EnumName: { \
+ TypeRecordKind RK = static_cast<TypeRecordKind>(Leaf); \
+ Name##Record Member(RK); \
+ if (auto EC = visitKnownMember(MemberData, Leaf, Member)) \
+ return EC; \
+ break; \
+ }
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
+ MEMBER_RECORD(EnumVal, EnumVal, AliasName)
+#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+ }
+ if (auto EC = skipPadding(MemberData))
+ return EC;
+ }
+ return Error::success();
+}
+
+Error TypeDeserializer::skipPadding(ArrayRef<uint8_t> &Data) {
+ if (Data.empty())
+ return Error::success();
+ uint8_t Leaf = Data.front();
+ if (Leaf < LF_PAD0)
+ return Error::success();
+ // Leaf is greater than 0xf0. We should advance by the number of bytes in
+ // the low 4 bits.
+ unsigned BytesToAdvance = Leaf & 0x0F;
+ if (Data.size() < BytesToAdvance) {
+ return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Invalid padding bytes!");
+ }
+ Data = Data.drop_front(BytesToAdvance);
+ return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp b/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
index 5ceaa59a79e..e1ec5ce9802 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
@@ -10,6 +10,7 @@
#include "llvm/DebugInfo/CodeView/TypeDumper.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/MSF/ByteStream.h"
@@ -195,8 +196,6 @@ static StringRef getLeafTypeName(TypeLeafKind LT) {
case ename: \
return #name;
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
- case LF_FIELDLIST:
- return "FieldList";
default:
break;
}
@@ -231,7 +230,13 @@ Error CVTypeDumper::visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
return Error::success();
}
-Error CVTypeDumper::visitStringId(StringIdRecord &String) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ FieldListRecord &FieldList) {
+ return Error::success();
+}
+
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ StringIdRecord &String) {
printTypeIndex("Id", String.getId());
W->printString("StringData", String.getString());
// Put this in CVUDTNames so it gets printed with LF_UDT_SRC_LINE.
@@ -239,7 +244,8 @@ Error CVTypeDumper::visitStringId(StringIdRecord &String) {
return Error::success();
}
-Error CVTypeDumper::visitArgList(ArgListRecord &Args) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ ArgListRecord &Args) {
auto Indices = Args.getIndices();
uint32_t Size = Indices.size();
W->printNumber("NumArgs", Size);
@@ -257,7 +263,8 @@ Error CVTypeDumper::visitArgList(ArgListRecord &Args) {
return Error::success();
}
-Error CVTypeDumper::visitClass(ClassRecord &Class) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ ClassRecord &Class) {
uint16_t Props = static_cast<uint16_t>(Class.getOptions());
W->printNumber("MemberCount", Class.getMemberCount());
W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
@@ -272,7 +279,8 @@ Error CVTypeDumper::visitClass(ClassRecord &Class) {
return Error::success();
}
-Error CVTypeDumper::visitUnion(UnionRecord &Union) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ UnionRecord &Union) {
uint16_t Props = static_cast<uint16_t>(Union.getOptions());
W->printNumber("MemberCount", Union.getMemberCount());
W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
@@ -285,7 +293,8 @@ Error CVTypeDumper::visitUnion(UnionRecord &Union) {
return Error::success();
}
-Error CVTypeDumper::visitEnum(EnumRecord &Enum) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ EnumRecord &Enum) {
uint16_t Props = static_cast<uint16_t>(Enum.getOptions());
W->printNumber("NumEnumerators", Enum.getMemberCount());
W->printFlags("Properties", uint16_t(Enum.getOptions()),
@@ -299,7 +308,8 @@ Error CVTypeDumper::visitEnum(EnumRecord &Enum) {
return Error::success();
}
-Error CVTypeDumper::visitArray(ArrayRecord &AT) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ ArrayRecord &AT) {
printTypeIndex("ElementType", AT.getElementType());
printTypeIndex("IndexType", AT.getIndexType());
W->printNumber("SizeOf", AT.getSize());
@@ -308,7 +318,8 @@ Error CVTypeDumper::visitArray(ArrayRecord &AT) {
return Error::success();
}
-Error CVTypeDumper::visitVFTable(VFTableRecord &VFT) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ VFTableRecord &VFT) {
printTypeIndex("CompleteClass", VFT.getCompleteClass());
printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
W->printHex("VFPtrOffset", VFT.getVFPtrOffset());
@@ -319,7 +330,8 @@ Error CVTypeDumper::visitVFTable(VFTableRecord &VFT) {
return Error::success();
}
-Error CVTypeDumper::visitMemberFuncId(MemberFuncIdRecord &Id) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ MemberFuncIdRecord &Id) {
printTypeIndex("ClassType", Id.getClassType());
printTypeIndex("FunctionType", Id.getFunctionType());
W->printString("Name", Id.getName());
@@ -327,7 +339,8 @@ Error CVTypeDumper::visitMemberFuncId(MemberFuncIdRecord &Id) {
return Error::success();
}
-Error CVTypeDumper::visitProcedure(ProcedureRecord &Proc) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ ProcedureRecord &Proc) {
printTypeIndex("ReturnType", Proc.getReturnType());
W->printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
makeArrayRef(CallingConventions));
@@ -345,7 +358,8 @@ Error CVTypeDumper::visitProcedure(ProcedureRecord &Proc) {
return Error::success();
}
-Error CVTypeDumper::visitMemberFunction(MemberFunctionRecord &MF) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ MemberFunctionRecord &MF) {
printTypeIndex("ReturnType", MF.getReturnType());
printTypeIndex("ClassType", MF.getClassType());
printTypeIndex("ThisType", MF.getThisType());
@@ -369,8 +383,8 @@ Error CVTypeDumper::visitMemberFunction(MemberFunctionRecord &MF) {
return Error::success();
}
-Error CVTypeDumper::visitMethodOverloadList(
- MethodOverloadListRecord &MethodList) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ MethodOverloadListRecord &MethodList) {
for (auto &M : MethodList.getMethods()) {
ListScope S(*W, "Method");
printMemberAttributes(M.getAccess(), M.getKind(), M.getOptions());
@@ -381,7 +395,8 @@ Error CVTypeDumper::visitMethodOverloadList(
return Error::success();
}
-Error CVTypeDumper::visitFuncId(FuncIdRecord &Func) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ FuncIdRecord &Func) {
printTypeIndex("ParentScope", Func.getParentScope());
printTypeIndex("FunctionType", Func.getFunctionType());
W->printString("Name", Func.getName());
@@ -389,7 +404,8 @@ Error CVTypeDumper::visitFuncId(FuncIdRecord &Func) {
return Error::success();
}
-Error CVTypeDumper::visitTypeServer2(TypeServer2Record &TS) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ TypeServer2Record &TS) {
W->printBinary("Signature", TS.getGuid());
W->printNumber("Age", TS.getAge());
W->printString("Name", TS.getName());
@@ -397,7 +413,8 @@ Error CVTypeDumper::visitTypeServer2(TypeServer2Record &TS) {
return Error::success();
}
-Error CVTypeDumper::visitPointer(PointerRecord &Ptr) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ PointerRecord &Ptr) {
printTypeIndex("PointeeType", Ptr.getReferentType());
W->printHex("PointerAttributes", uint32_t(Ptr.getOptions()));
W->printEnum("PtrType", unsigned(Ptr.getPointerKind()),
@@ -448,7 +465,8 @@ Error CVTypeDumper::visitPointer(PointerRecord &Ptr) {
return Error::success();
}
-Error CVTypeDumper::visitModifier(ModifierRecord &Mod) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ ModifierRecord &Mod) {
uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
printTypeIndex("ModifiedType", Mod.getModifiedType());
W->printFlags("Modifiers", Mods, makeArrayRef(TypeModifierNames));
@@ -466,26 +484,30 @@ Error CVTypeDumper::visitModifier(ModifierRecord &Mod) {
return Error::success();
}
-Error CVTypeDumper::visitBitField(BitFieldRecord &BitField) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ BitFieldRecord &BitField) {
printTypeIndex("Type", BitField.getType());
W->printNumber("BitSize", BitField.getBitSize());
W->printNumber("BitOffset", BitField.getBitOffset());
return Error::success();
}
-Error CVTypeDumper::visitVFTableShape(VFTableShapeRecord &Shape) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ VFTableShapeRecord &Shape) {
W->printNumber("VFEntryCount", Shape.getEntryCount());
return Error::success();
}
-Error CVTypeDumper::visitUdtSourceLine(UdtSourceLineRecord &Line) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ UdtSourceLineRecord &Line) {
printTypeIndex("UDT", Line.getUDT());
printTypeIndex("SourceFile", Line.getSourceFile());
W->printNumber("LineNumber", Line.getLineNumber());
return Error::success();
}
-Error CVTypeDumper::visitUdtModSourceLine(UdtModSourceLineRecord &Line) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ UdtModSourceLineRecord &Line) {
printTypeIndex("UDT", Line.getUDT());
printTypeIndex("SourceFile", Line.getSourceFile());
W->printNumber("LineNumber", Line.getLineNumber());
@@ -493,7 +515,8 @@ Error CVTypeDumper::visitUdtModSourceLine(UdtModSourceLineRecord &Line) {
return Error::success();
}
-Error CVTypeDumper::visitBuildInfo(BuildInfoRecord &Args) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ BuildInfoRecord &Args) {
W->printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
ListScope Arguments(*W, "Arguments");
@@ -533,7 +556,8 @@ Error CVTypeDumper::visitUnknownType(const CVRecord<TypeLeafKind> &Record) {
return Error::success();
}
-Error CVTypeDumper::visitNestedType(NestedTypeRecord &Nested) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ NestedTypeRecord &Nested) {
DictScope S(*W, "NestedType");
printTypeIndex("Type", Nested.getNestedType());
W->printString("Name", Nested.getName());
@@ -541,7 +565,8 @@ Error CVTypeDumper::visitNestedType(NestedTypeRecord &Nested) {
return Error::success();
}
-Error CVTypeDumper::visitOneMethod(OneMethodRecord &Method) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ OneMethodRecord &Method) {
DictScope S(*W, "OneMethod");
MethodKind K = Method.getKind();
printMemberAttributes(Method.getAccess(), K, Method.getOptions());
@@ -554,7 +579,8 @@ Error CVTypeDumper::visitOneMethod(OneMethodRecord &Method) {
return Error::success();
}
-Error CVTypeDumper::visitOverloadedMethod(OverloadedMethodRecord &Method) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ OverloadedMethodRecord &Method) {
DictScope S(*W, "OverloadedMethod");
W->printHex("MethodCount", Method.getNumOverloads());
printTypeIndex("MethodListIndex", Method.getMethodList());
@@ -563,7 +589,8 @@ Error CVTypeDumper::visitOverloadedMethod(OverloadedMethodRecord &Method) {
return Error::success();
}
-Error CVTypeDumper::visitDataMember(DataMemberRecord &Field) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ DataMemberRecord &Field) {
DictScope S(*W, "DataMember");
printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
@@ -574,7 +601,8 @@ Error CVTypeDumper::visitDataMember(DataMemberRecord &Field) {
return Error::success();
}
-Error CVTypeDumper::visitStaticDataMember(StaticDataMemberRecord &Field) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ StaticDataMemberRecord &Field) {
DictScope S(*W, "StaticDataMember");
printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
@@ -584,13 +612,15 @@ Error CVTypeDumper::visitStaticDataMember(StaticDataMemberRecord &Field) {
return Error::success();
}
-Error CVTypeDumper::visitVFPtr(VFPtrRecord &VFTable) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ VFPtrRecord &VFTable) {
DictScope S(*W, "VFPtr");
printTypeIndex("Type", VFTable.getType());
return Error::success();
}
-Error CVTypeDumper::visitEnumerator(EnumeratorRecord &Enum) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ EnumeratorRecord &Enum) {
DictScope S(*W, "Enumerator");
printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
@@ -600,7 +630,8 @@ Error CVTypeDumper::visitEnumerator(EnumeratorRecord &Enum) {
return Error::success();
}
-Error CVTypeDumper::visitBaseClass(BaseClassRecord &Base) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ BaseClassRecord &Base) {
DictScope S(*W, "BaseClass");
printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
@@ -609,7 +640,8 @@ Error CVTypeDumper::visitBaseClass(BaseClassRecord &Base) {
return Error::success();
}
-Error CVTypeDumper::visitVirtualBaseClass(VirtualBaseClassRecord &Base) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ VirtualBaseClassRecord &Base) {
DictScope S(*W, "VirtualBaseClass");
printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
@@ -620,7 +652,8 @@ Error CVTypeDumper::visitVirtualBaseClass(VirtualBaseClassRecord &Base) {
return Error::success();
}
-Error CVTypeDumper::visitListContinuation(ListContinuationRecord &Cont) {
+Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ ListContinuationRecord &Cont) {
DictScope S(*W, "ListContinuation");
printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
return Error::success();
@@ -665,7 +698,8 @@ void CVTypeDumper::printTypeIndex(StringRef FieldName, TypeIndex TI) {
Error CVTypeDumper::dump(const CVRecord<TypeLeafKind> &Record) {
assert(W && "printer should not be null");
- CVTypeVisitor Visitor(*this);
+ TypeDeserializer Deserializer(*this);
+ CVTypeVisitor Visitor(Deserializer);
if (auto EC = Visitor.visitTypeRecord(Record))
return EC;
@@ -674,7 +708,9 @@ Error CVTypeDumper::dump(const CVRecord<TypeLeafKind> &Record) {
Error CVTypeDumper::dump(const CVTypeArray &Types) {
assert(W && "printer should not be null");
- CVTypeVisitor Visitor(*this);
+ TypeDeserializer Deserializer(*this);
+ CVTypeVisitor Visitor(Deserializer);
+
if (auto EC = Visitor.visitTypeStream(Types))
return EC;
return Error::success();
diff --git a/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp b/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp
index 4bbd2616bb5..e630be87345 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeRecord.cpp
@@ -114,6 +114,11 @@ NestedTypeRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
return NestedTypeRecord(L->Type, Name);
}
+Expected<FieldListRecord>
+FieldListRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
+ return FieldListRecord(Data);
+}
+
Expected<ArrayRecord> ArrayRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index 8c2bc072cd9..58c8c3fecb4 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
@@ -58,7 +59,8 @@ public:
/// TypeVisitorCallbacks overrides.
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visit##Name(Name##Record &Record) override;
+ Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
+ Name##Record &Record) override;
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
TYPE_RECORD(EnumName, EnumVal, Name)
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
@@ -70,11 +72,28 @@ public:
Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
- Error visitFieldListEnd(const CVRecord<TypeLeafKind> &Record) override;
-
bool mergeStream(const CVTypeArray &Types);
private:
+ template <typename RecordType>
+ Error visitKnownRecordImpl(RecordType &Record) {
+ FoundBadTypeIndex |= !Record.remapTypeIndices(IndexMap);
+ IndexMap.push_back(DestStream.writeKnownType(Record));
+ return Error::success();
+ }
+
+ Error visitKnownRecordImpl(FieldListRecord &Record) {
+ // Don't do anything, this will get written in the call to visitTypeEnd().
+ return Error::success();
+ }
+
+ template <typename RecordType>
+ Error visitKnownMemberRecordImpl(RecordType &Record) {
+ FoundBadTypeIndex |= !Record.remapTypeIndices(IndexMap);
+ FieldBuilder.writeMemberType(Record);
+ return Error::success();
+ }
+
bool hadError() { return FoundBadTypeIndex; }
bool FoundBadTypeIndex = false;
@@ -93,33 +112,31 @@ private:
} // end anonymous namespace
Error TypeStreamMerger::visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) {
- BeginIndexMapSize = IndexMap.size();
+ if (Rec.Type != TypeLeafKind::LF_FIELDLIST)
+ BeginIndexMapSize = IndexMap.size();
return Error::success();
}
Error TypeStreamMerger::visitTypeEnd(const CVRecord<TypeLeafKind> &Rec) {
- assert(IndexMap.size() == BeginIndexMapSize + 1);
- return Error::success();
-}
-
-Error TypeStreamMerger::visitFieldListEnd(const CVRecord<TypeLeafKind> &Rec) {
- IndexMap.push_back(DestStream.writeFieldList(FieldBuilder));
- FieldBuilder.reset();
+ if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {
+ IndexMap.push_back(DestStream.writeFieldList(FieldBuilder));
+ FieldBuilder.reset();
+ } else {
+ assert(IndexMap.size() == BeginIndexMapSize + 1);
+ }
return Error::success();
}
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error TypeStreamMerger::visit##Name(Name##Record &Record) { \
- FoundBadTypeIndex |= !Record.remapTypeIndices(IndexMap); \
- IndexMap.push_back(DestStream.write##Name(Record)); \
- return Error::success(); \
+ Error TypeStreamMerger::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
+ Name##Record &Record) { \
+ return visitKnownRecordImpl(Record); \
}
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- Error TypeStreamMerger::visit##Name(Name##Record &Record) { \
- FoundBadTypeIndex |= !Record.remapTypeIndices(IndexMap); \
- FieldBuilder.write##Name(Record); \
- return Error::success(); \
+ Error TypeStreamMerger::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
+ Name##Record &Record) { \
+ return visitKnownMemberRecordImpl(Record); \
}
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
@@ -133,7 +150,9 @@ Error TypeStreamMerger::visitUnknownType(const CVRecord<TypeLeafKind> &Rec) {
bool TypeStreamMerger::mergeStream(const CVTypeArray &Types) {
assert(IndexMap.empty());
- CVTypeVisitor Visitor(*this);
+ TypeDeserializer Deserializer(*this);
+ CVTypeVisitor Visitor(Deserializer);
+
if (auto EC = Visitor.visitTypeStream(Types)) {
consumeError(std::move(EC));
return false;
diff --git a/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp
index 647538ee8ce..0fcf4f92d43 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp
@@ -21,7 +21,7 @@ TypeTableBuilder::TypeTableBuilder() {}
TypeTableBuilder::~TypeTableBuilder() {}
-TypeIndex TypeTableBuilder::writeModifier(const ModifierRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const ModifierRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getModifiedType());
@@ -30,7 +30,7 @@ TypeIndex TypeTableBuilder::writeModifier(const ModifierRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeProcedure(const ProcedureRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const ProcedureRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getReturnType());
@@ -42,8 +42,7 @@ TypeIndex TypeTableBuilder::writeProcedure(const ProcedureRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex
-TypeTableBuilder::writeMemberFunction(const MemberFunctionRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const MemberFunctionRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getReturnType());
@@ -58,7 +57,7 @@ TypeTableBuilder::writeMemberFunction(const MemberFunctionRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeArgList(const ArgListRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const ArgListRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeUInt32(Record.getIndices().size());
@@ -69,7 +68,7 @@ TypeIndex TypeTableBuilder::writeArgList(const ArgListRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writePointer(const PointerRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const PointerRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getReferentType());
@@ -90,7 +89,7 @@ TypeIndex TypeTableBuilder::writePointer(const PointerRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeArray(const ArrayRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const ArrayRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getElementType());
@@ -101,7 +100,7 @@ TypeIndex TypeTableBuilder::writeArray(const ArrayRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeClass(const ClassRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const ClassRecord &Record) {
assert((Record.getKind() == TypeRecordKind::Struct) ||
(Record.getKind() == TypeRecordKind::Class) ||
(Record.getKind() == TypeRecordKind::Interface));
@@ -128,7 +127,7 @@ TypeIndex TypeTableBuilder::writeClass(const ClassRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeUnion(const UnionRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const UnionRecord &Record) {
TypeRecordBuilder Builder(TypeRecordKind::Union);
Builder.writeUInt16(Record.getMemberCount());
uint16_t Flags =
@@ -145,7 +144,7 @@ TypeIndex TypeTableBuilder::writeUnion(const UnionRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeEnum(const EnumRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const EnumRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeUInt16(Record.getMemberCount());
@@ -161,7 +160,7 @@ TypeIndex TypeTableBuilder::writeEnum(const EnumRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeBitField(const BitFieldRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const BitFieldRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getType());
@@ -171,8 +170,7 @@ TypeIndex TypeTableBuilder::writeBitField(const BitFieldRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex
-TypeTableBuilder::writeVFTableShape(const VFTableShapeRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const VFTableShapeRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
ArrayRef<VFTableSlotKind> Slots = Record.getSlots();
@@ -189,8 +187,7 @@ TypeTableBuilder::writeVFTableShape(const VFTableShapeRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex
-TypeTableBuilder::writeVFTable(const VFTableRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const VFTableRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getCompleteClass());
Builder.writeTypeIndex(Record.getOverriddenVTable());
@@ -209,15 +206,14 @@ TypeTableBuilder::writeVFTable(const VFTableRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeStringId(const StringIdRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const StringIdRecord &Record) {
TypeRecordBuilder Builder(TypeRecordKind::StringId);
Builder.writeTypeIndex(Record.getId());
Builder.writeNullTerminatedString(Record.getString());
return writeRecord(Builder);
}
-TypeIndex
-TypeTableBuilder::writeUdtSourceLine(const UdtSourceLineRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const UdtSourceLineRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getUDT());
Builder.writeTypeIndex(Record.getSourceFile());
@@ -226,7 +222,7 @@ TypeTableBuilder::writeUdtSourceLine(const UdtSourceLineRecord &Record) {
}
TypeIndex
-TypeTableBuilder::writeUdtModSourceLine(const UdtModSourceLineRecord &Record) {
+TypeTableBuilder::writeKnownType(const UdtModSourceLineRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getUDT());
Builder.writeTypeIndex(Record.getSourceFile());
@@ -235,7 +231,7 @@ TypeTableBuilder::writeUdtModSourceLine(const UdtModSourceLineRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeFuncId(const FuncIdRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const FuncIdRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getParentScope());
Builder.writeTypeIndex(Record.getFunctionType());
@@ -243,8 +239,7 @@ TypeIndex TypeTableBuilder::writeFuncId(const FuncIdRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex
-TypeTableBuilder::writeMemberFuncId(const MemberFuncIdRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const MemberFuncIdRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getClassType());
Builder.writeTypeIndex(Record.getFunctionType());
@@ -252,8 +247,7 @@ TypeTableBuilder::writeMemberFuncId(const MemberFuncIdRecord &Record) {
return writeRecord(Builder);
}
-TypeIndex
-TypeTableBuilder::writeBuildInfo(const BuildInfoRecord &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const BuildInfoRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
assert(Record.getArgs().size() <= UINT16_MAX);
Builder.writeUInt16(Record.getArgs().size());
@@ -270,8 +264,8 @@ TypeIndex TypeTableBuilder::writeFieldList(FieldListRecordBuilder &FieldList) {
return FieldList.writeListRecord(*this);
}
-TypeIndex TypeTableBuilder::writeMethodOverloadList(
- const MethodOverloadListRecord &Record) {
+TypeIndex
+TypeTableBuilder::writeKnownType(const MethodOverloadListRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
for (const OneMethodRecord &Method : Record.getMethods()) {
uint16_t Flags = static_cast<uint16_t>(Method.getAccess());
@@ -294,7 +288,7 @@ TypeIndex TypeTableBuilder::writeMethodOverloadList(
return writeRecord(Builder);
}
-TypeIndex TypeTableBuilder::writeTypeServer2(const TypeServer2Record &Record) {
+TypeIndex TypeTableBuilder::writeKnownType(const TypeServer2Record &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeGuid(Record.getGuid());
Builder.writeUInt32(Record.getAge());
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
index 1398628f231..424ef0ef441 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
@@ -11,6 +11,7 @@
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
@@ -96,17 +97,28 @@ public:
uint32_t NumHashBuckets)
: HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}
- Error visitUdtSourceLine(UdtSourceLineRecord &Rec) override {
+ Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ UdtSourceLineRecord &Rec) override {
return verifySourceLine(Rec);
}
- Error visitUdtModSourceLine(UdtModSourceLineRecord &Rec) override {
+ Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ UdtModSourceLineRecord &Rec) override {
return verifySourceLine(Rec);
}
- Error visitClass(ClassRecord &Rec) override { return verify(Rec); }
- Error visitEnum(EnumRecord &Rec) override { return verify(Rec); }
- Error visitUnion(UnionRecord &Rec) override { return verify(Rec); }
+ Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ ClassRecord &Rec) override {
+ return verify(Rec);
+ }
+ Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ EnumRecord &Rec) override {
+ return verify(Rec);
+ }
+ Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ UnionRecord &Rec) override {
+ return verify(Rec);
+ }
Error visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) override {
++Index;
@@ -148,7 +160,8 @@ private:
// Currently we only verify SRC_LINE records.
Error TpiStream::verifyHashValues() {
TpiHashVerifier Verifier(HashValues, Header->NumHashBuckets);
- CVTypeVisitor Visitor(Verifier);
+ TypeDeserializer Deserializer(Verifier);
+ CVTypeVisitor Visitor(Deserializer);
return Visitor.visitTypeStream(TypeRecords);
}
OpenPOWER on IntegriCloud