Index: llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -23,7 +23,7 @@ public: explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks); - Error visitTypeRecord(const CVRecord &Record); + Error visitTypeRecord(CVRecord &Record); /// Visits the type records in Data. Sets the error flag on parse failures. Error visitTypeStream(const CVTypeArray &Types); Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -20,8 +20,8 @@ TypeDeserializer() {} #define TYPE_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownRecord(const CVRecord &CVR, \ - Name##Record &Record) override { \ + Error visitKnownRecord(CVRecord &CVR, Name##Record &Record) \ + override { \ return defaultVisitKnownRecord(CVR, Record); \ } #define MEMBER_RECORD(EnumName, EnumVal, Name) \ @@ -45,7 +45,7 @@ private: template - Error defaultVisitKnownRecord(const CVRecord &CVR, T &Record) { + Error defaultVisitKnownRecord(CVRecord &CVR, T &Record) { ArrayRef RD = CVR.Data; if (auto EC = deserializeRecord(RD, CVR.Type, Record)) return EC; Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h @@ -63,18 +63,17 @@ ScopedPrinter *getPrinter() { return W; } /// Action to take on unknown types. By default, they are ignored. - Error visitUnknownType(const CVRecord &Record) override; - Error visitUnknownMember(const CVRecord &Record) override; + Error visitUnknownType(CVRecord &Record) override; + Error visitUnknownMember(CVRecord &Record) override; /// Paired begin/end actions for all types. Receives all record data, /// including the fixed-length record prefix. - Expected - visitTypeBegin(const CVRecord &Record) override; - Error visitTypeEnd(const CVRecord &Record) override; + Error visitTypeBegin(CVRecord &Record) override; + Error visitTypeEnd(CVRecord &Record) override; #define TYPE_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownRecord(const CVRecord &CVR, \ - Name##Record &Record) override; + Error visitKnownRecord(CVRecord &CVR, Name##Record &Record) \ + override; #define MEMBER_RECORD(EnumName, EnumVal, Name) \ TYPE_RECORD(EnumName, EnumVal, Name) #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h @@ -15,6 +15,7 @@ #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" namespace llvm { namespace codeview { @@ -26,27 +27,35 @@ : FieldListBuilder(FieldListBuilder), TypeTableBuilder(TypeTableBuilder) { } - virtual Expected 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 &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 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 &CVR, \ + virtual Error visitKnownRecord(CVRecord &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 &CVR, \ + virtual Error visitKnownRecord(CVRecord &CVR, \ Name##Record &Record) override { \ visitMemberRecordImpl(Record); \ return Error::success(); \ Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h @@ -22,8 +22,7 @@ public: TypeVisitorCallbackPipeline() {} - virtual Error - visitUnknownType(const CVRecord &Record) override { + virtual Error visitUnknownType(CVRecord &Record) override { for (auto Visitor : Pipeline) { if (auto EC = Visitor->visitUnknownType(Record)) return EC; @@ -31,8 +30,7 @@ return Error::success(); } - virtual Error - visitUnknownMember(const CVRecord &Record) override { + virtual Error visitUnknownMember(CVRecord &Record) override { for (auto Visitor : Pipeline) { if (auto EC = Visitor->visitUnknownMember(Record)) return EC; @@ -40,23 +38,14 @@ return Error::success(); } - virtual Expected - visitTypeBegin(const CVRecord &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 RecordCopy = Record; + virtual Error visitTypeBegin(CVRecord &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 &Record) override { + virtual Error visitTypeEnd(CVRecord &Record) override { for (auto Visitor : Pipeline) { if (auto EC = Visitor->visitTypeEnd(Record)) return EC; @@ -69,8 +58,8 @@ } #define TYPE_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownRecord(const CVRecord &CVR, \ - Name##Record &Record) override { \ + Error visitKnownRecord(CVRecord &CVR, Name##Record &Record) \ + override { \ for (auto Visitor : Pipeline) { \ if (auto EC = Visitor->visitKnownRecord(CVR, Record)) \ return EC; \ Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h @@ -25,26 +25,25 @@ virtual ~TypeVisitorCallbacks() {} /// Action to take on unknown types. By default, they are ignored. - virtual Error visitUnknownType(const CVRecord &Record) { + virtual Error visitUnknownType(CVRecord &Record) { return Error::success(); } - virtual Error visitUnknownMember(const CVRecord &Record) { + virtual Error visitUnknownMember(CVRecord &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 - visitTypeBegin(const CVRecord &Record) { - return Record.Type; + virtual Error visitTypeBegin(CVRecord &Record) { + return Error::success(); } - virtual Error visitTypeEnd(const CVRecord &Record) { + virtual Error visitTypeEnd(CVRecord &Record) { return Error::success(); } #define TYPE_RECORD(EnumName, EnumVal, Name) \ - virtual Error visitKnownRecord(const CVRecord &CVR, \ + virtual Error visitKnownRecord(CVRecord &CVR, \ Name##Record &Record) { \ return Error::success(); \ } Index: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h @@ -30,7 +30,9 @@ class WritableStream; template <> struct SequencedItemTraits { - 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 bytes(const codeview::CVType &Item) { return Item.RawData; } Index: llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp @@ -65,7 +65,7 @@ : Callbacks(Callbacks) {} template -static Error visitKnownRecord(const CVRecord &Record, +static Error visitKnownRecord(CVRecord &Record, TypeVisitorCallbacks &Callbacks) { TypeRecordKind RK = static_cast(Record.Type); T KnownRecord(RK); @@ -74,24 +74,18 @@ return Error::success(); } -Error CVTypeVisitor::visitTypeRecord(const CVRecord &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 &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(RecordCopy, Callbacks)) \ + if (auto EC = visitKnownRecord(Record, Callbacks)) \ return EC; \ break; \ } @@ -104,7 +98,7 @@ #include "llvm/DebugInfo/CodeView/TypeRecords.def" } - if (auto EC = Callbacks.visitTypeEnd(RecordCopy)) + if (auto EC = Callbacks.visitTypeEnd(Record)) return EC; return Error::success(); @@ -112,13 +106,29 @@ /// 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 +static Error visitKnownMember(ArrayRef &Data, TypeLeafKind Leaf, + TypeVisitorCallbacks &Callbacks) { + auto ExpectedRecord = deserializeMemberRecord(Data, Leaf); + if (!ExpectedRecord) + return ExpectedRecord.takeError(); + CVType &Record = *ExpectedRecord; + if (auto EC = Callbacks.visitTypeBegin(Record)) + return EC; + if (auto EC = visitKnownRecord(Record, Callbacks)) + return EC; + if (auto EC = Callbacks.visitTypeEnd(Record)) + return EC; + return Error::success(); +} + Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef Data) { while (!Data.empty()) { const support::ulittle16_t *LeafValue; @@ -135,16 +145,7 @@ cv_error_code::unknown_member_record); #define MEMBER_RECORD(EnumName, EnumVal, Name) \ case EnumName: { \ - auto ExpectedRecord = deserializeMemberRecord(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(Record, Callbacks)) \ - return EC; \ - if (auto EC = Callbacks.visitTypeEnd(Record)) \ + if (auto EC = visitKnownMember(Data, Leaf, Callbacks)) \ return EC; \ break; \ } Index: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp @@ -203,8 +203,7 @@ return "UnknownLeaf"; } -Expected -CVTypeDumper::visitTypeBegin(const CVRecord &Record) { +Error CVTypeDumper::visitTypeBegin(CVRecord &Record) { // Reset Name to the empty string. If the visitor sets it, we know it. Name = ""; @@ -224,10 +223,10 @@ assert(!IsInFieldList); IsInFieldList = true; } - return Record.Type; + return Error::success(); } -Error CVTypeDumper::visitTypeEnd(const CVRecord &Record) { +Error CVTypeDumper::visitTypeEnd(CVRecord &Record) { if (Record.Type == LF_FIELDLIST) { assert(IsInFieldList); IsInFieldList = false; @@ -249,7 +248,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, FieldListRecord &FieldList) { TypeDeserializer Deserializer; TypeVisitorCallbackPipeline Pipeline; @@ -264,7 +263,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, StringIdRecord &String) { printTypeIndex("Id", String.getId()); W->printString("StringData", String.getString()); @@ -273,7 +272,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, ArgListRecord &Args) { auto Indices = Args.getIndices(); uint32_t Size = Indices.size(); @@ -292,7 +291,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, ClassRecord &Class) { uint16_t Props = static_cast(Class.getOptions()); W->printNumber("MemberCount", Class.getMemberCount()); @@ -308,7 +307,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, UnionRecord &Union) { uint16_t Props = static_cast(Union.getOptions()); W->printNumber("MemberCount", Union.getMemberCount()); @@ -322,7 +321,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, EnumRecord &Enum) { uint16_t Props = static_cast(Enum.getOptions()); W->printNumber("NumEnumerators", Enum.getMemberCount()); @@ -337,7 +336,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, ArrayRecord &AT) { printTypeIndex("ElementType", AT.getElementType()); printTypeIndex("IndexType", AT.getIndexType()); @@ -347,7 +346,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, VFTableRecord &VFT) { printTypeIndex("CompleteClass", VFT.getCompleteClass()); printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable()); @@ -359,7 +358,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, MemberFuncIdRecord &Id) { printTypeIndex("ClassType", Id.getClassType()); printTypeIndex("FunctionType", Id.getFunctionType()); @@ -368,7 +367,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, ProcedureRecord &Proc) { printTypeIndex("ReturnType", Proc.getReturnType()); W->printEnum("CallingConvention", uint8_t(Proc.getCallConv()), @@ -387,7 +386,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, MemberFunctionRecord &MF) { printTypeIndex("ReturnType", MF.getReturnType()); printTypeIndex("ClassType", MF.getClassType()); @@ -412,7 +411,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, MethodOverloadListRecord &MethodList) { for (auto &M : MethodList.getMethods()) { ListScope S(*W, "Method"); @@ -424,7 +423,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, FuncIdRecord &Func) { printTypeIndex("ParentScope", Func.getParentScope()); printTypeIndex("FunctionType", Func.getFunctionType()); @@ -433,7 +432,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, TypeServer2Record &TS) { W->printBinary("Signature", TS.getGuid()); W->printNumber("Age", TS.getAge()); @@ -442,7 +441,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, PointerRecord &Ptr) { printTypeIndex("PointeeType", Ptr.getReferentType()); W->printHex("PointerAttributes", uint32_t(Ptr.getOptions())); @@ -494,7 +493,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, ModifierRecord &Mod) { uint16_t Mods = static_cast(Mod.getModifiers()); printTypeIndex("ModifiedType", Mod.getModifiedType()); @@ -513,7 +512,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, BitFieldRecord &BitField) { printTypeIndex("Type", BitField.getType()); W->printNumber("BitSize", BitField.getBitSize()); @@ -521,14 +520,14 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, VFTableShapeRecord &Shape) { W->printNumber("VFEntryCount", Shape.getEntryCount()); Name = saveName(""); return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, UdtSourceLineRecord &Line) { printTypeIndex("UDT", Line.getUDT()); printTypeIndex("SourceFile", Line.getSourceFile()); @@ -536,7 +535,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, UdtModSourceLineRecord &Line) { printTypeIndex("UDT", Line.getUDT()); printTypeIndex("SourceFile", Line.getSourceFile()); @@ -545,7 +544,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, BuildInfoRecord &Args) { W->printNumber("NumArgs", static_cast(Args.getArgs().size())); @@ -574,18 +573,18 @@ } } -Error CVTypeDumper::visitUnknownMember(const CVRecord &Record) { +Error CVTypeDumper::visitUnknownMember(CVRecord &Record) { W->printHex("UnknownMember", unsigned(Record.Type)); return Error::success(); } -Error CVTypeDumper::visitUnknownType(const CVRecord &Record) { +Error CVTypeDumper::visitUnknownType(CVRecord &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 &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, NestedTypeRecord &Nested) { printTypeIndex("Type", Nested.getNestedType()); W->printString("Name", Nested.getName()); @@ -593,7 +592,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, OneMethodRecord &Method) { MethodKind K = Method.getKind(); printMemberAttributes(Method.getAccess(), K, Method.getOptions()); @@ -606,7 +605,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, OverloadedMethodRecord &Method) { W->printHex("MethodCount", Method.getNumOverloads()); printTypeIndex("MethodListIndex", Method.getMethodList()); @@ -615,7 +614,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, DataMemberRecord &Field) { printMemberAttributes(Field.getAccess(), MethodKind::Vanilla, MethodOptions::None); @@ -626,7 +625,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, StaticDataMemberRecord &Field) { printMemberAttributes(Field.getAccess(), MethodKind::Vanilla, MethodOptions::None); @@ -636,13 +635,13 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, VFPtrRecord &VFTable) { printTypeIndex("Type", VFTable.getType()); return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, EnumeratorRecord &Enum) { printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla, MethodOptions::None); @@ -652,7 +651,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, BaseClassRecord &Base) { printMemberAttributes(Base.getAccess(), MethodKind::Vanilla, MethodOptions::None); @@ -661,7 +660,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, VirtualBaseClassRecord &Base) { printMemberAttributes(Base.getAccess(), MethodKind::Vanilla, MethodOptions::None); @@ -672,7 +671,7 @@ return Error::success(); } -Error CVTypeDumper::visitKnownRecord(const CVRecord &CVR, +Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, ListContinuationRecord &Cont) { printTypeIndex("ContinuationIndex", Cont.getContinuationIndex()); return Error::success(); @@ -724,7 +723,8 @@ CVTypeVisitor Visitor(Pipeline); - if (auto EC = Visitor.visitTypeRecord(Record)) + CVRecord RecordCopy = Record; + if (auto EC = Visitor.visitTypeRecord(RecordCopy)) return EC; return Error::success(); } Index: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -60,19 +60,18 @@ /// TypeVisitorCallbacks overrides. #define TYPE_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownRecord(const CVRecord &CVR, \ - Name##Record &Record) override; + Error visitKnownRecord(CVRecord &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 &Record) override; + Error visitUnknownType(CVRecord &Record) override; - Expected - visitTypeBegin(const CVRecord &Record) override; - Error visitTypeEnd(const CVRecord &Record) override; + Error visitTypeBegin(CVRecord &Record) override; + Error visitTypeEnd(CVRecord &Record) override; bool mergeStream(const CVTypeArray &Types); @@ -124,17 +123,16 @@ } // end anonymous namespace -Expected -TypeStreamMerger::visitTypeBegin(const CVRecord &Rec) { +Error TypeStreamMerger::visitTypeBegin(CVRecord &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 &Rec) { +Error TypeStreamMerger::visitTypeEnd(CVRecord &Rec) { if (Rec.Type == TypeLeafKind::LF_FIELDLIST) { IndexMap.push_back(DestStream.writeFieldList(FieldBuilder)); FieldBuilder.reset(); @@ -146,20 +144,20 @@ } #define TYPE_RECORD(EnumName, EnumVal, Name) \ - Error TypeStreamMerger::visitKnownRecord(const CVRecord &CVR, \ + Error TypeStreamMerger::visitKnownRecord(CVRecord &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 &CVR, \ + Error TypeStreamMerger::visitKnownRecord(CVRecord &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 &Rec) { +Error TypeStreamMerger::visitUnknownType(CVRecord &Rec) { // We failed to translate a type. Translate this index as "not translated". IndexMap.push_back( TypeIndex(SimpleTypeKind::NotTranslated, SimpleTypeMode::Direct)); Index: llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp @@ -263,7 +263,9 @@ } TypeIndex TypeTableBuilder::writeFieldList(FieldListRecordBuilder &FieldList) { - return FieldList.writeListRecord(*this); + TypeIndex I = FieldList.writeListRecord(*this); + RecordKinds.push_back(TypeRecordKind::FieldList); + return I; } TypeIndex Index: llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp @@ -69,34 +69,33 @@ uint32_t NumHashBuckets) : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {} - Error visitKnownRecord(const CVRecord &CVR, + Error visitKnownRecord(CVRecord &CVR, UdtSourceLineRecord &Rec) override { return verifySourceLine(Rec); } - Error visitKnownRecord(const CVRecord &CVR, + Error visitKnownRecord(CVRecord &CVR, UdtModSourceLineRecord &Rec) override { return verifySourceLine(Rec); } - Error visitKnownRecord(const CVRecord &CVR, + Error visitKnownRecord(CVRecord &CVR, ClassRecord &Rec) override { return verify(Rec); } - Error visitKnownRecord(const CVRecord &CVR, + Error visitKnownRecord(CVRecord &CVR, EnumRecord &Rec) override { return verify(Rec); } - Error visitKnownRecord(const CVRecord &CVR, + Error visitKnownRecord(CVRecord &CVR, UnionRecord &Rec) override { return verify(Rec); } - Expected - visitTypeBegin(const CVRecord &Rec) override { + Error visitTypeBegin(CVRecord &Rec) override { ++Index; RawRecord = Rec; - return Rec.Type; + return Error::success(); } private: Index: llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.h =================================================================== --- llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.h +++ llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.h @@ -29,12 +29,11 @@ llvm::pdb::yaml::SerializationContext &Context) : YamlIO(IO), Context(Context) {} - virtual Expected - visitTypeBegin(const CVRecord &Record) override; + virtual Error visitTypeBegin(CVRecord &Record) override; #define TYPE_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownRecord(const CVRecord &CVR, \ - Name##Record &Record) override { \ + Error visitKnownRecord(CVRecord &CVR, Name##Record &Record) \ + override { \ visitKnownRecordImpl(#Name, CVR, Record); \ return Error::success(); \ } @@ -46,11 +45,11 @@ private: template - 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; Index: llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp +++ llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp @@ -40,14 +40,14 @@ #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)); @@ -524,19 +524,14 @@ } } -Expected -llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin( - const CVRecord &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 &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 FieldListRecords; if (YamlIO.outputting()) { // If we are outputting, then `FieldList.Data` contains a huge chunk of data Index: llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp +++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp @@ -230,19 +230,4 @@ 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 Records = Context.TypeTableBuilder.getRecords(); - ArrayRef Kinds = - Context.TypeTableBuilder.getRecordKinds(); - - StringRef ThisRecord = Records.back(); - Obj.Record.Type = static_cast(Kinds.back()); - Obj.Record.Data = - ArrayRef(ThisRecord.bytes_begin(), ThisRecord.bytes_end()); - Obj.Record.RawData = Obj.Record.Data; - Obj.Record.Length = ThisRecord.size(); - } }