public:
explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
- Error visitTypeRecord(const CVRecord<TypeLeafKind> &Record);
+ Error visitTypeRecord(CVRecord<TypeLeafKind> &Record);
/// Visits the type records in Data. Sets the error flag on parse failures.
Error visitTypeStream(const CVTypeArray &Types);
TypeDeserializer() {}
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
- Name##Record &Record) override { \
+ Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record) \
+ override { \
return defaultVisitKnownRecord(CVR, Record); \
}
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
private:
template <typename T>
- Error defaultVisitKnownRecord(const CVRecord<TypeLeafKind> &CVR, T &Record) {
+ Error defaultVisitKnownRecord(CVRecord<TypeLeafKind> &CVR, T &Record) {
ArrayRef<uint8_t> RD = CVR.Data;
if (auto EC = deserializeRecord(RD, CVR.Type, Record))
return EC;
ScopedPrinter *getPrinter() { return W; }
/// Action to take on unknown types. By default, they are ignored.
- Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) override;
- Error visitUnknownMember(const CVRecord<TypeLeafKind> &Record) override;
+ Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override;
+ Error visitUnknownMember(CVRecord<TypeLeafKind> &Record) override;
/// Paired begin/end actions for all types. Receives all record data,
/// including the fixed-length record prefix.
- Expected<TypeLeafKind>
- visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
- Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
+ Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override;
+ Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) override;
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
- Name##Record &Record) override;
+ Error visitKnownRecord(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)
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
: FieldListBuilder(FieldListBuilder), TypeTableBuilder(TypeTableBuilder) {
}
- virtual Expected<TypeLeafKind> visitTypeBegin(const CVType &Record) override {
+ virtual Error visitTypeBegin(CVType &Record) override {
if (Record.Type == TypeLeafKind::LF_FIELDLIST)
FieldListBuilder.reset();
- return Record.Type;
+ return Error::success();
}
- virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override {
+ virtual Error visitTypeEnd(CVType &Record) override {
+ // Since this visitor's purpose is to serialize the record, fill out the
+ // fields of `Record` with the bytes of the record.
if (Record.Type == TypeLeafKind::LF_FIELDLIST)
TypeTableBuilder.writeFieldList(FieldListBuilder);
+
+ StringRef S = TypeTableBuilder.getRecords().back();
+ ArrayRef<uint8_t> Data(S.bytes_begin(), S.bytes_end());
+ Record.RawData = Data;
+ Record.Data = Record.RawData.drop_front(sizeof(RecordPrefix));
+ Record.Length = Data.size() - sizeof(ulittle16_t);
return Error::success();
}
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- virtual Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
+ virtual Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, \
Name##Record &Record) override { \
visitKnownRecordImpl(Record); \
return Error::success(); \
}
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- virtual Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
+ virtual Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, \
Name##Record &Record) override { \
visitMemberRecordImpl(Record); \
return Error::success(); \
public:
TypeVisitorCallbackPipeline() {}
- virtual Error
- visitUnknownType(const CVRecord<TypeLeafKind> &Record) override {
+ virtual Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override {
for (auto Visitor : Pipeline) {
if (auto EC = Visitor->visitUnknownType(Record))
return EC;
return Error::success();
}
- virtual Error
- visitUnknownMember(const CVRecord<TypeLeafKind> &Record) override {
+ virtual Error visitUnknownMember(CVRecord<TypeLeafKind> &Record) override {
for (auto Visitor : Pipeline) {
if (auto EC = Visitor->visitUnknownMember(Record))
return EC;
return Error::success();
}
- virtual Expected<TypeLeafKind>
- visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override {
- // An implementation can calculate of visitTypeBegin() can calculate the
- // kind based on an arbitrary factor, including the Type that is already
- // specified in the Record. So, as we go through the pipeline invoking
- // each visitor, update the state in a copy of the record so that each
- // visitor in the pipeline sees the most recently value of the type.
- CVRecord<TypeLeafKind> RecordCopy = Record;
+ virtual Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override {
for (auto Visitor : Pipeline) {
- if (auto ExpectedKind = Visitor->visitTypeBegin(RecordCopy)) {
- RecordCopy.Type = *ExpectedKind;
- } else
- return ExpectedKind.takeError();
+ if (auto EC = Visitor->visitTypeBegin(Record))
+ return EC;
}
- return RecordCopy.Type;
+ return Error::success();
}
- virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override {
+ virtual Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) override {
for (auto Visitor : Pipeline) {
if (auto EC = Visitor->visitTypeEnd(Record))
return EC;
}
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
- Name##Record &Record) override { \
+ Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record) \
+ override { \
for (auto Visitor : Pipeline) { \
if (auto EC = Visitor->visitKnownRecord(CVR, Record)) \
return EC; \
virtual ~TypeVisitorCallbacks() {}
/// Action to take on unknown types. By default, they are ignored.
- virtual Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) {
+ virtual Error visitUnknownType(CVRecord<TypeLeafKind> &Record) {
return Error::success();
}
- virtual Error visitUnknownMember(const CVRecord<TypeLeafKind> &Record) {
+ virtual Error visitUnknownMember(CVRecord<TypeLeafKind> &Record) {
return Error::success();
}
/// Paired begin/end actions for all types. Receives all record data,
/// including the fixed-length record prefix. visitTypeBegin() should return
/// the type of the Record, or an error if it cannot be determined.
- virtual Expected<TypeLeafKind>
- visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
- return Record.Type;
+ virtual Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
+ return Error::success();
}
- virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
+ virtual Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) {
return Error::success();
}
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- virtual Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
+ virtual Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, \
Name##Record &Record) { \
return Error::success(); \
}
class WritableStream;
template <> struct SequencedItemTraits<llvm::codeview::CVType> {
- static size_t length(const codeview::CVType &Item) { return Item.Length; }
+ static size_t length(const codeview::CVType &Item) {
+ return Item.RawData.size();
+ }
static ArrayRef<uint8_t> bytes(const codeview::CVType &Item) {
return Item.RawData;
}
: Callbacks(Callbacks) {}
template <typename T>
-static Error visitKnownRecord(const CVRecord<TypeLeafKind> &Record,
+static Error visitKnownRecord(CVRecord<TypeLeafKind> &Record,
TypeVisitorCallbacks &Callbacks) {
TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Type);
T KnownRecord(RK);
return Error::success();
}
-Error CVTypeVisitor::visitTypeRecord(const CVRecord<TypeLeafKind> &Record) {
- TypeLeafKind Kind;
- if (auto ExpectedKind = Callbacks.visitTypeBegin(Record))
- Kind = *ExpectedKind;
- else
- return ExpectedKind.takeError();
-
- CVType RecordCopy = Record;
- RecordCopy.Type = Kind;
+Error CVTypeVisitor::visitTypeRecord(CVRecord<TypeLeafKind> &Record) {
+ if (auto EC = Callbacks.visitTypeBegin(Record))
+ return EC;
- switch (Kind) {
+ switch (Record.Type) {
default:
- if (auto EC = Callbacks.visitUnknownType(RecordCopy))
+ if (auto EC = Callbacks.visitUnknownType(Record))
return EC;
break;
#define TYPE_RECORD(EnumName, EnumVal, Name) \
case EnumName: { \
- if (auto EC = visitKnownRecord<Name##Record>(RecordCopy, Callbacks)) \
+ if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks)) \
return EC; \
break; \
}
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
}
- if (auto EC = Callbacks.visitTypeEnd(RecordCopy))
+ if (auto EC = Callbacks.visitTypeEnd(Record))
return EC;
return Error::success();
/// Visits the type records in Data. Sets the error flag on parse failures.
Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) {
- for (const auto &I : Types) {
+ for (auto I : Types) {
if (auto EC = visitTypeRecord(I))
return EC;
}
return Error::success();
}
+template <typename MR>
+static Error visitKnownMember(ArrayRef<uint8_t> &Data, TypeLeafKind Leaf,
+ TypeVisitorCallbacks &Callbacks) {
+ auto ExpectedRecord = deserializeMemberRecord<MR>(Data, Leaf);
+ if (!ExpectedRecord)
+ return ExpectedRecord.takeError();
+ CVType &Record = *ExpectedRecord;
+ if (auto EC = Callbacks.visitTypeBegin(Record))
+ return EC;
+ if (auto EC = visitKnownRecord<MR>(Record, Callbacks))
+ return EC;
+ if (auto EC = Callbacks.visitTypeEnd(Record))
+ return EC;
+ return Error::success();
+}
+
Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef<uint8_t> Data) {
while (!Data.empty()) {
const support::ulittle16_t *LeafValue;
cv_error_code::unknown_member_record);
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
case EnumName: { \
- auto ExpectedRecord = deserializeMemberRecord<Name##Record>(Data, Leaf); \
- if (!ExpectedRecord) \
- return ExpectedRecord.takeError(); \
- auto &Record = *ExpectedRecord; \
- auto ExpectedKind = Callbacks.visitTypeBegin(Record); \
- if (!ExpectedKind || *ExpectedKind != Leaf) \
- return ExpectedKind.takeError(); \
- if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks)) \
- return EC; \
- if (auto EC = Callbacks.visitTypeEnd(Record)) \
+ if (auto EC = visitKnownMember<Name##Record>(Data, Leaf, Callbacks)) \
return EC; \
break; \
}
return "UnknownLeaf";
}
-Expected<TypeLeafKind>
-CVTypeDumper::visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
+Error CVTypeDumper::visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
// Reset Name to the empty string. If the visitor sets it, we know it.
Name = "";
assert(!IsInFieldList);
IsInFieldList = true;
}
- return Record.Type;
+ return Error::success();
}
-Error CVTypeDumper::visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
+Error CVTypeDumper::visitTypeEnd(CVRecord<TypeLeafKind> &Record) {
if (Record.Type == LF_FIELDLIST) {
assert(IsInFieldList);
IsInFieldList = false;
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
FieldListRecord &FieldList) {
TypeDeserializer Deserializer;
TypeVisitorCallbackPipeline Pipeline;
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
StringIdRecord &String) {
printTypeIndex("Id", String.getId());
W->printString("StringData", String.getString());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
ArgListRecord &Args) {
auto Indices = Args.getIndices();
uint32_t Size = Indices.size();
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
ClassRecord &Class) {
uint16_t Props = static_cast<uint16_t>(Class.getOptions());
W->printNumber("MemberCount", Class.getMemberCount());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
UnionRecord &Union) {
uint16_t Props = static_cast<uint16_t>(Union.getOptions());
W->printNumber("MemberCount", Union.getMemberCount());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
EnumRecord &Enum) {
uint16_t Props = static_cast<uint16_t>(Enum.getOptions());
W->printNumber("NumEnumerators", Enum.getMemberCount());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
ArrayRecord &AT) {
printTypeIndex("ElementType", AT.getElementType());
printTypeIndex("IndexType", AT.getIndexType());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
VFTableRecord &VFT) {
printTypeIndex("CompleteClass", VFT.getCompleteClass());
printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
MemberFuncIdRecord &Id) {
printTypeIndex("ClassType", Id.getClassType());
printTypeIndex("FunctionType", Id.getFunctionType());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
ProcedureRecord &Proc) {
printTypeIndex("ReturnType", Proc.getReturnType());
W->printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
MemberFunctionRecord &MF) {
printTypeIndex("ReturnType", MF.getReturnType());
printTypeIndex("ClassType", MF.getClassType());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
MethodOverloadListRecord &MethodList) {
for (auto &M : MethodList.getMethods()) {
ListScope S(*W, "Method");
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
FuncIdRecord &Func) {
printTypeIndex("ParentScope", Func.getParentScope());
printTypeIndex("FunctionType", Func.getFunctionType());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
TypeServer2Record &TS) {
W->printBinary("Signature", TS.getGuid());
W->printNumber("Age", TS.getAge());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
PointerRecord &Ptr) {
printTypeIndex("PointeeType", Ptr.getReferentType());
W->printHex("PointerAttributes", uint32_t(Ptr.getOptions()));
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
ModifierRecord &Mod) {
uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
printTypeIndex("ModifiedType", Mod.getModifiedType());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
BitFieldRecord &BitField) {
printTypeIndex("Type", BitField.getType());
W->printNumber("BitSize", BitField.getBitSize());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
VFTableShapeRecord &Shape) {
W->printNumber("VFEntryCount", Shape.getEntryCount());
Name = saveName("<vftable " + utostr(Shape.getEntryCount()) + " methods>");
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
UdtSourceLineRecord &Line) {
printTypeIndex("UDT", Line.getUDT());
printTypeIndex("SourceFile", Line.getSourceFile());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
UdtModSourceLineRecord &Line) {
printTypeIndex("UDT", Line.getUDT());
printTypeIndex("SourceFile", Line.getSourceFile());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
BuildInfoRecord &Args) {
W->printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
}
}
-Error CVTypeDumper::visitUnknownMember(const CVRecord<TypeLeafKind> &Record) {
+Error CVTypeDumper::visitUnknownMember(CVRecord<TypeLeafKind> &Record) {
W->printHex("UnknownMember", unsigned(Record.Type));
return Error::success();
}
-Error CVTypeDumper::visitUnknownType(const CVRecord<TypeLeafKind> &Record) {
+Error CVTypeDumper::visitUnknownType(CVRecord<TypeLeafKind> &Record) {
W->printEnum("Kind", uint16_t(Record.Type), makeArrayRef(LeafTypeNames));
W->printNumber("Length", uint32_t(Record.Data.size()));
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
NestedTypeRecord &Nested) {
printTypeIndex("Type", Nested.getNestedType());
W->printString("Name", Nested.getName());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
OneMethodRecord &Method) {
MethodKind K = Method.getKind();
printMemberAttributes(Method.getAccess(), K, Method.getOptions());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
OverloadedMethodRecord &Method) {
W->printHex("MethodCount", Method.getNumOverloads());
printTypeIndex("MethodListIndex", Method.getMethodList());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
DataMemberRecord &Field) {
printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
StaticDataMemberRecord &Field) {
printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
VFPtrRecord &VFTable) {
printTypeIndex("Type", VFTable.getType());
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
EnumeratorRecord &Enum) {
printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
BaseClassRecord &Base) {
printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
VirtualBaseClassRecord &Base) {
printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
MethodOptions::None);
return Error::success();
}
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
ListContinuationRecord &Cont) {
printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
return Error::success();
CVTypeVisitor Visitor(Pipeline);
- if (auto EC = Visitor.visitTypeRecord(Record))
+ CVRecord<TypeLeafKind> RecordCopy = Record;
+ if (auto EC = Visitor.visitTypeRecord(RecordCopy))
return EC;
return Error::success();
}
/// TypeVisitorCallbacks overrides.
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
- Name##Record &Record) override;
+ Error visitKnownRecord(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)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
- Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) override;
+ Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override;
- Expected<TypeLeafKind>
- visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
- Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
+ Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override;
+ Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) override;
bool mergeStream(const CVTypeArray &Types);
} // end anonymous namespace
-Expected<TypeLeafKind>
-TypeStreamMerger::visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) {
+Error TypeStreamMerger::visitTypeBegin(CVRecord<TypeLeafKind> &Rec) {
if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {
assert(!IsInFieldList);
IsInFieldList = true;
} else
BeginIndexMapSize = IndexMap.size();
- return Rec.Type;
+ return Error::success();
}
-Error TypeStreamMerger::visitTypeEnd(const CVRecord<TypeLeafKind> &Rec) {
+Error TypeStreamMerger::visitTypeEnd(CVRecord<TypeLeafKind> &Rec) {
if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {
IndexMap.push_back(DestStream.writeFieldList(FieldBuilder));
FieldBuilder.reset();
}
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error TypeStreamMerger::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
+ Error TypeStreamMerger::visitKnownRecord(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::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
+ Error TypeStreamMerger::visitKnownRecord(CVRecord<TypeLeafKind> &CVR, \
Name##Record &Record) { \
return visitKnownMemberRecordImpl(Record); \
}
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
-Error TypeStreamMerger::visitUnknownType(const CVRecord<TypeLeafKind> &Rec) {
+Error TypeStreamMerger::visitUnknownType(CVRecord<TypeLeafKind> &Rec) {
// We failed to translate a type. Translate this index as "not translated".
IndexMap.push_back(
TypeIndex(SimpleTypeKind::NotTranslated, SimpleTypeMode::Direct));
}
TypeIndex TypeTableBuilder::writeFieldList(FieldListRecordBuilder &FieldList) {
- return FieldList.writeListRecord(*this);
+ TypeIndex I = FieldList.writeListRecord(*this);
+ RecordKinds.push_back(TypeRecordKind::FieldList);
+ return I;
}
TypeIndex
uint32_t NumHashBuckets)
: HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
UdtSourceLineRecord &Rec) override {
return verifySourceLine(Rec);
}
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
UdtModSourceLineRecord &Rec) override {
return verifySourceLine(Rec);
}
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
ClassRecord &Rec) override {
return verify(Rec);
}
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
EnumRecord &Rec) override {
return verify(Rec);
}
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+ Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
UnionRecord &Rec) override {
return verify(Rec);
}
- Expected<TypeLeafKind>
- visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) override {
+ Error visitTypeBegin(CVRecord<TypeLeafKind> &Rec) override {
++Index;
RawRecord = Rec;
- return Rec.Type;
+ return Error::success();
}
private:
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(const CVType &CVT, Name##Record &Record) override { \
+ Error visitKnownRecord(CVType &CVT, Name##Record &Record) override { \
visitKnownRecordImpl(CVT); \
return Error::success(); \
}
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
private:
- void visitKnownRecordImpl(const CVType &CVT) {
+ void visitKnownRecordImpl(CVType &CVT) {
llvm::pdb::yaml::PdbTpiRecord R;
R.Record = CVT;
Records.push_back(std::move(R));
}
}
-Expected<TypeLeafKind>
-llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin(
- const CVRecord<TypeLeafKind> &CVR) {
- // When we're outputting, `CVR.Type` already has the right value in it. But
- // when we're inputting, we need to read the value. Since `CVR.Type` is const
- // we do it into a temp variable.
- TypeLeafKind K = CVR.Type;
- YamlIO.mapRequired("Kind", K);
- return K;
+Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin(
+ CVRecord<TypeLeafKind> &CVR) {
+ YamlIO.mapRequired("Kind", CVR.Type);
+ return Error::success();
}
void llvm::codeview::yaml::YamlTypeDumperCallbacks::visitKnownRecordImpl(
- const char *Name, const CVType &CVR, FieldListRecord &FieldList) {
+ const char *Name, CVType &CVR, FieldListRecord &FieldList) {
std::vector<llvm::pdb::yaml::PdbTpiRecord> FieldListRecords;
if (YamlIO.outputting()) {
// If we are outputting, then `FieldList.Data` contains a huge chunk of data
llvm::pdb::yaml::SerializationContext &Context)
: YamlIO(IO), Context(Context) {}
- virtual Expected<TypeLeafKind>
- visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
+ virtual Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override;
#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \
- Name##Record &Record) override { \
+ Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record) \
+ override { \
visitKnownRecordImpl(#Name, CVR, Record); \
return Error::success(); \
}
private:
template <typename T>
- void visitKnownRecordImpl(const char *Name, const CVType &Type, T &Record) {
+ void visitKnownRecordImpl(const char *Name, CVType &Type, T &Record) {
YamlIO.mapRequired(Name, Record);
}
- void visitKnownRecordImpl(const char *Name, const CVType &CVR,
+ void visitKnownRecordImpl(const char *Name, CVType &CVR,
FieldListRecord &FieldList);
llvm::yaml::IO &YamlIO;
codeview::CVTypeVisitor Visitor(Pipeline);
consumeError(Visitor.visitTypeRecord(Obj.Record));
-
- if (!IO.outputting()) {
- // For Yaml to PDB, we need to update the input Object with the bytes for
- // this record.
- ArrayRef<StringRef> Records = Context.TypeTableBuilder.getRecords();
- ArrayRef<codeview::TypeRecordKind> Kinds =
- Context.TypeTableBuilder.getRecordKinds();
-
- StringRef ThisRecord = Records.back();
- Obj.Record.Type = static_cast<codeview::TypeLeafKind>(Kinds.back());
- Obj.Record.Data =
- ArrayRef<uint8_t>(ThisRecord.bytes_begin(), ThisRecord.bytes_end());
- Obj.Record.RawData = Obj.Record.Data;
- Obj.Record.Length = ThisRecord.size();
- }
}