From f07202a7aa87c5e78152b84f2bbefc4875f6906a Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 15 Jun 2016 20:30:34 +0000 Subject: [PATCH] [codeview] Move deserialization methods out of line They aren't performance critical and don't need to be inline. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272829 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/CodeView/TypeRecord.h | 339 ++---------------- lib/DebugInfo/CodeView/TypeRecord.cpp | 356 +++++++++++++++++++ 2 files changed, 386 insertions(+), 309 deletions(-) diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index 59febb7b464..090922d79f1 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -15,8 +15,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/RecordSerialization.h" -#include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/Support/ErrorOr.h" #include @@ -85,17 +83,7 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static ErrorOr deserialize(ArrayRef &Data) { - const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) - return EC; - - TypeIndex T = L->ClassType; - uint16_t R = L->Representation; - PointerToMemberRepresentation PMR = - static_cast(R); - return MemberPointerInfo(T, PMR); - } + static ErrorOr deserialize(ArrayRef &Data); TypeIndex getContainingType() const { return ContainingType; } PointerToMemberRepresentation getRepresentation() const { @@ -135,16 +123,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) - return EC; - - TypeIndex M = L->ModifiedType; - uint16_t O = L->Modifiers; - ModifierOptions MO = static_cast(O); - return ModifierRecord(M, MO); - } + ArrayRef &Data); TypeIndex getModifiedType() const { return ModifiedType; } ModifierOptions getModifiers() const { return Modifiers; } @@ -174,14 +153,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) - return EC; - - return ProcedureRecord(L->ReturnType, L->CallConv, L->Options, - L->NumParameters, L->ArgListType); - } + ArrayRef &Data); static uint32_t getLayoutSize() { return 2 + sizeof(Layout); } @@ -225,14 +197,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - CV_DESERIALIZE(Data, L); - - return MemberFunctionRecord(L->ReturnType, L->ClassType, L->ThisType, - L->CallConv, L->Options, L->NumParameters, - L->ArgListType, L->ThisAdjustment); - } + ArrayRef &Data); TypeIndex getReturnType() const { return ReturnType; } TypeIndex getClassType() const { return ClassType; } @@ -278,14 +243,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Data, L, Name); - - return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name); - } - + ArrayRef &Data); TypeIndex getClassType() const { return ClassType; } TypeIndex getFunctionType() const { return FunctionType; } StringRef getName() const { return Name; } @@ -312,16 +270,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList) - return std::make_error_code(std::errc::illegal_byte_sequence); - - const Layout *L = nullptr; - ArrayRef Indices; - CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); - - return ArgListRecord(Kind, Indices); - } + ArrayRef &Data); ArrayRef getIndices() const { return StringIndices; } @@ -365,26 +314,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) - return EC; - - PointerKind PtrKind = L->getPtrKind(); - PointerMode Mode = L->getPtrMode(); - uint32_t Opts = L->Attrs; - PointerOptions Options = static_cast(Opts); - uint8_t Size = L->getPtrSize(); - - if (L->isPointerToMember()) { - auto E = MemberPointerInfo::deserialize(Data); - if (E.getError()) - return std::make_error_code(std::errc::illegal_byte_sequence); - return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size, *E); - } - - return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size); - } + ArrayRef &Data); TypeIndex getReferentType() const { return ReferentType; } PointerKind getPointerKind() const { return PtrKind; } @@ -460,13 +390,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Data, L, Name); - - return NestedTypeRecord(L->Type, Name); - } + ArrayRef &Data); TypeIndex getNestedType() const { return Type; } StringRef getName() const { return Name; } @@ -495,14 +419,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - uint64_t Size; - StringRef Name; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name); - - return ArrayRecord(L->ElementType, L->IndexType, Size, Name); - } + ArrayRef &Data); TypeIndex getElementType() const { return ElementType; } TypeIndex getIndexType() const { return IndexType; } @@ -570,26 +487,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - uint64_t Size = 0; - StringRef Name; - StringRef UniqueName; - uint16_t Props; - const Layout *L = nullptr; - - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name, - CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); - - Props = L->Properties; - uint16_t WrtValue = (Props & WinRTKindMask) >> WinRTKindShift; - WindowsRTClassKind WRT = static_cast(WrtValue); - uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift; - HfaKind Hfa = static_cast(HfaMask); - - ClassOptions Options = static_cast(Props); - return ClassRecord(Kind, L->MemberCount, Options, Hfa, WRT, L->FieldList, - L->DerivedFrom, L->VShape, Size, Name, UniqueName); - } + ArrayRef &Data); HfaKind getHfa() const { return Hfa; } WindowsRTClassKind getWinRTKind() const { return WinRTKind; } @@ -630,24 +528,7 @@ struct UnionRecord : public TagRecord { Hfa(Hfa), Size(Size) {} static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - uint64_t Size = 0; - StringRef Name; - StringRef UniqueName; - uint16_t Props; - - const Layout *L = nullptr; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name, - CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); - - Props = L->Properties; - - uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift; - HfaKind Hfa = static_cast(HfaMask); - ClassOptions Options = static_cast(Props); - return UnionRecord(L->MemberCount, Options, Hfa, L->FieldList, Size, Name, - UniqueName); - } + ArrayRef &Data); HfaKind getHfa() const { return Hfa; } uint64_t getSize() const { return Size; } @@ -683,16 +564,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Data, L, Name); - - uint16_t P = L->Properties; - ClassOptions Options = static_cast(P); - return EnumRecord(L->NumEnumerators, Options, L->FieldListType, Name, Name, - L->UnderlyingType); - } + ArrayRef &Data); TypeIndex getUnderlyingType() const { return UnderlyingType; } @@ -720,12 +592,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - CV_DESERIALIZE(Data, L); - - return BitFieldRecord(L->Type, L->BitSize, L->BitOffset); - } + ArrayRef &Data); TypeIndex getType() const { return Type; } uint8_t getBitOffset() const { return BitOffset; } @@ -756,30 +623,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) - return EC; - - std::vector Slots; - uint16_t Count = L->VFEntryCount; - while (Count > 0) { - if (Data.empty()) - return std::make_error_code(std::errc::illegal_byte_sequence); - - // Process up to 2 nibbles at a time (if there are at least 2 remaining) - uint8_t Value = Data[0] & 0x0F; - Slots.push_back(static_cast(Value)); - if (--Count > 0) { - Value = (Data[0] & 0xF0) >> 4; - Slots.push_back(static_cast(Value)); - --Count; - } - Data = Data.slice(1); - } - - return VFTableShapeRecord(Slots); - } + ArrayRef &Data); ArrayRef getSlots() const { if (!SlotsRef.empty()) @@ -814,13 +658,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Data, L, Name); - - return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name); - } + ArrayRef &Data); StringRef getGuid() const { return Guid; } @@ -851,13 +689,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Data, L, Name); - - return StringIdRecord(L->id, Name); - } + ArrayRef &Data); TypeIndex getId() const { return Id; } @@ -885,13 +717,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Data, L, Name); - - return FuncIdRecord(L->ParentScope, L->FunctionType, Name); - } + ArrayRef &Data); TypeIndex getParentScope() const { return ParentScope; } @@ -923,12 +749,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - CV_DESERIALIZE(Data, L); - - return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber); - } + ArrayRef &Data); TypeIndex getUDT() const { return UDT; } TypeIndex getSourceFile() const { return SourceFile; } @@ -958,13 +779,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - ArrayRef Indices; - CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); - - return BuildInfoRecord(Indices); - } + ArrayRef &Data); ArrayRef getArgs() const { return ArgIndices; } @@ -997,15 +812,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - std::vector Names; - CV_DESERIALIZE(Data, L, Name, CV_ARRAY_FIELD_TAIL(Names)); - - return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset, - Name, Names); - } + ArrayRef &Data); TypeIndex getCompleteClass() const { return CompleteClass; } TypeIndex getOverriddenVTable() const { return OverriddenVFTable; } @@ -1049,25 +856,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - int32_t VFTableOffset = -1; - - CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD( - VFTableOffset, L->Attrs.isIntroducedVirtual()), - Name); - - MethodOptions Options = L->Attrs.getFlags(); - MethodKind MethKind = L->Attrs.getMethodKind(); - MemberAccess Access = L->Attrs.getAccess(); - OneMethodRecord Method(L->Type, MethKind, Options, Access, VFTableOffset, - Name); - // Validate the vftable offset. - if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0) - return std::make_error_code(std::errc::illegal_byte_sequence); - return Method; - } + ArrayRef &Data); TypeIndex getType() const { return Type; } MethodKind getKind() const { return Kind; } @@ -1111,29 +900,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - std::vector Methods; - while (!Data.empty()) { - const Layout *L = nullptr; - int32_t VFTableOffset = -1; - CV_DESERIALIZE( - Data, L, - CV_CONDITIONAL_FIELD(VFTableOffset, L->Attrs.isIntroducedVirtual())); - - MethodOptions Options = L->Attrs.getFlags(); - MethodKind MethKind = L->Attrs.getMethodKind(); - MemberAccess Access = L->Attrs.getAccess(); - - Methods.emplace_back(L->Type, MethKind, Options, Access, VFTableOffset, - StringRef()); - - // Validate the vftable offset. - auto &Method = Methods.back(); - if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0) - return std::make_error_code(std::errc::illegal_byte_sequence); - } - return MethodOverloadListRecord(Methods); - } + ArrayRef &Data); ArrayRef getMethods() const { return Methods; } @@ -1163,13 +930,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Data, L, Name); - - return OverloadedMethodRecord(L->MethodCount, L->MethList, Name); - } + ArrayRef &Data); uint16_t getNumOverloads() const { return NumOverloads; } TypeIndex getMethodList() const { return MethodList; } @@ -1200,14 +961,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - uint64_t Offset; - StringRef Name; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset), Name); - - return DataMemberRecord(L->Attrs.getAccess(), L->Type, Offset, Name); - } + ArrayRef &Data); MemberAccess getAccess() const { return Access; } TypeIndex getType() const { return Type; } @@ -1240,13 +994,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Data, L, Name); - - return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name); - } + ArrayRef &Data); MemberAccess getAccess() const { return Access; } TypeIndex getType() const { return Type; } @@ -1276,14 +1024,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - APSInt Value; - StringRef Name; - CV_DESERIALIZE(Data, L, Value, Name); - - return EnumeratorRecord(L->Attrs.getAccess(), Value, Name); - } + ArrayRef &Data); MemberAccess getAccess() const { return Access; } APSInt getValue() const { return Value; } @@ -1311,14 +1052,8 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static ErrorOr - deserialize(TypeRecordKind Kind, ArrayRef &Data) { - const Layout *L = nullptr; - if (auto EC = consumeObject(Data, L)) - return EC; - - return VFPtrRecord(L->Type); - } + static ErrorOr deserialize(TypeRecordKind Kind, + ArrayRef &Data); TypeIndex getType() const { return Type; } @@ -1342,13 +1077,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - uint64_t Offset; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset)); - - return BaseClassRecord(L->Attrs.getAccess(), L->BaseType, Offset); - } + ArrayRef &Data); MemberAccess getAccess() const { return Access; } TypeIndex getBaseType() const { return Type; } @@ -1379,15 +1108,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); static ErrorOr deserialize(TypeRecordKind Kind, - ArrayRef &Data) { - const Layout *L = nullptr; - uint64_t Offset; - uint64_t Index; - CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset), CV_NUMERIC_FIELD(Index)); - - return VirtualBaseClassRecord(L->Attrs.getAccess(), L->BaseType, - L->VBPtrType, Offset, Index); - } + ArrayRef &Data); MemberAccess getAccess() const { return Access; } TypeIndex getBaseType() const { return BaseType; } diff --git a/lib/DebugInfo/CodeView/TypeRecord.cpp b/lib/DebugInfo/CodeView/TypeRecord.cpp index e9782978535..02bb3c1d34b 100644 --- a/lib/DebugInfo/CodeView/TypeRecord.cpp +++ b/lib/DebugInfo/CodeView/TypeRecord.cpp @@ -9,10 +9,366 @@ #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" using namespace llvm; using namespace llvm::codeview; +//===----------------------------------------------------------------------===// +// Type record deserialization +//===----------------------------------------------------------------------===// + +ErrorOr +MemberPointerInfo::deserialize(ArrayRef &Data) { + const Layout *L = nullptr; + if (auto EC = consumeObject(Data, L)) + return EC; + + TypeIndex T = L->ClassType; + uint16_t R = L->Representation; + PointerToMemberRepresentation PMR = + static_cast(R); + return MemberPointerInfo(T, PMR); +} + +ErrorOr ModifierRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + if (auto EC = consumeObject(Data, L)) + return EC; + + TypeIndex M = L->ModifiedType; + uint16_t O = L->Modifiers; + ModifierOptions MO = static_cast(O); + return ModifierRecord(M, MO); +} + +ErrorOr ProcedureRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + if (auto EC = consumeObject(Data, L)) + return EC; + return ProcedureRecord(L->ReturnType, L->CallConv, L->Options, + L->NumParameters, L->ArgListType); +} + +ErrorOr +MemberFunctionRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + CV_DESERIALIZE(Data, L); + return MemberFunctionRecord(L->ReturnType, L->ClassType, L->ThisType, + L->CallConv, L->Options, L->NumParameters, + L->ArgListType, L->ThisAdjustment); +} + +ErrorOr +MemberFuncIdRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, L, Name); + return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name); +} + +ErrorOr ArgListRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList) + return std::make_error_code(std::errc::illegal_byte_sequence); + + const Layout *L = nullptr; + ArrayRef Indices; + CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); + return ArgListRecord(Kind, Indices); +} + +ErrorOr PointerRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + if (auto EC = consumeObject(Data, L)) + return EC; + + PointerKind PtrKind = L->getPtrKind(); + PointerMode Mode = L->getPtrMode(); + uint32_t Opts = L->Attrs; + PointerOptions Options = static_cast(Opts); + uint8_t Size = L->getPtrSize(); + + if (L->isPointerToMember()) { + auto E = MemberPointerInfo::deserialize(Data); + if (E.getError()) + return std::make_error_code(std::errc::illegal_byte_sequence); + return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size, *E); + } + + return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size); +} + +ErrorOr +NestedTypeRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, L, Name); + return NestedTypeRecord(L->Type, Name); +} + +ErrorOr ArrayRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + uint64_t Size; + StringRef Name; + CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name); + return ArrayRecord(L->ElementType, L->IndexType, Size, Name); +} + +ErrorOr ClassRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + uint64_t Size = 0; + StringRef Name; + StringRef UniqueName; + uint16_t Props; + const Layout *L = nullptr; + + CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name, + CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); + + Props = L->Properties; + uint16_t WrtValue = (Props & WinRTKindMask) >> WinRTKindShift; + WindowsRTClassKind WRT = static_cast(WrtValue); + uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift; + HfaKind Hfa = static_cast(HfaMask); + + ClassOptions Options = static_cast(Props); + return ClassRecord(Kind, L->MemberCount, Options, Hfa, WRT, L->FieldList, + L->DerivedFrom, L->VShape, Size, Name, UniqueName); +} + +ErrorOr UnionRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + uint64_t Size = 0; + StringRef Name; + StringRef UniqueName; + uint16_t Props; + + const Layout *L = nullptr; + CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Size), Name, + CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); + + Props = L->Properties; + + uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift; + HfaKind Hfa = static_cast(HfaMask); + ClassOptions Options = static_cast(Props); + return UnionRecord(L->MemberCount, Options, Hfa, L->FieldList, Size, Name, + UniqueName); +} + +ErrorOr EnumRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, L, Name); + + uint16_t P = L->Properties; + ClassOptions Options = static_cast(P); + return EnumRecord(L->NumEnumerators, Options, L->FieldListType, Name, Name, + L->UnderlyingType); +} + +ErrorOr BitFieldRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + CV_DESERIALIZE(Data, L); + return BitFieldRecord(L->Type, L->BitSize, L->BitOffset); +} + +ErrorOr +VFTableShapeRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { + const Layout *L = nullptr; + if (auto EC = consumeObject(Data, L)) + return EC; + + std::vector Slots; + uint16_t Count = L->VFEntryCount; + while (Count > 0) { + if (Data.empty()) + return std::make_error_code(std::errc::illegal_byte_sequence); + + // Process up to 2 nibbles at a time (if there are at least 2 remaining) + uint8_t Value = Data[0] & 0x0F; + Slots.push_back(static_cast(Value)); + if (--Count > 0) { + Value = (Data[0] & 0xF0) >> 4; + Slots.push_back(static_cast(Value)); + --Count; + } + Data = Data.slice(1); + } + + return VFTableShapeRecord(Slots); +} + +ErrorOr +TypeServer2Record::deserialize(TypeRecordKind Kind, ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, L, Name); + return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name); +} + +ErrorOr StringIdRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, L, Name); + return StringIdRecord(L->id, Name); +} + +ErrorOr FuncIdRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, L, Name); + return FuncIdRecord(L->ParentScope, L->FunctionType, Name); +} + +ErrorOr +UdtSourceLineRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { + const Layout *L = nullptr; + CV_DESERIALIZE(Data, L); + return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber); +} + +ErrorOr BuildInfoRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + ArrayRef Indices; + CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); + return BuildInfoRecord(Indices); +} + +ErrorOr VFTableRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + std::vector Names; + CV_DESERIALIZE(Data, L, Name, CV_ARRAY_FIELD_TAIL(Names)); + return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset, + Name, Names); +} + +ErrorOr OneMethodRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + int32_t VFTableOffset = -1; + + CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD(VFTableOffset, + L->Attrs.isIntroducedVirtual()), + Name); + + MethodOptions Options = L->Attrs.getFlags(); + MethodKind MethKind = L->Attrs.getMethodKind(); + MemberAccess Access = L->Attrs.getAccess(); + OneMethodRecord Method(L->Type, MethKind, Options, Access, VFTableOffset, + Name); + // Validate the vftable offset. + if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0) + return std::make_error_code(std::errc::illegal_byte_sequence); + return Method; +} + +ErrorOr +MethodOverloadListRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + std::vector Methods; + while (!Data.empty()) { + const Layout *L = nullptr; + int32_t VFTableOffset = -1; + CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD( + VFTableOffset, L->Attrs.isIntroducedVirtual())); + + MethodOptions Options = L->Attrs.getFlags(); + MethodKind MethKind = L->Attrs.getMethodKind(); + MemberAccess Access = L->Attrs.getAccess(); + + Methods.emplace_back(L->Type, MethKind, Options, Access, VFTableOffset, + StringRef()); + + // Validate the vftable offset. + auto &Method = Methods.back(); + if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0) + return std::make_error_code(std::errc::illegal_byte_sequence); + } + return MethodOverloadListRecord(Methods); +} + +ErrorOr +OverloadedMethodRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, L, Name); + return OverloadedMethodRecord(L->MethodCount, L->MethList, Name); +} + +ErrorOr +DataMemberRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { + const Layout *L = nullptr; + uint64_t Offset; + StringRef Name; + CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset), Name); + return DataMemberRecord(L->Attrs.getAccess(), L->Type, Offset, Name); +} + +ErrorOr +StaticDataMemberRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + StringRef Name; + CV_DESERIALIZE(Data, L, Name); + return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name); +} + +ErrorOr +EnumeratorRecord::deserialize(TypeRecordKind Kind, ArrayRef &Data) { + const Layout *L = nullptr; + APSInt Value; + StringRef Name; + CV_DESERIALIZE(Data, L, Value, Name); + return EnumeratorRecord(L->Attrs.getAccess(), Value, Name); +} + +ErrorOr VFPtrRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + if (auto EC = consumeObject(Data, L)) + return EC; + return VFPtrRecord(L->Type); +} + +ErrorOr BaseClassRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + uint64_t Offset; + CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset)); + return BaseClassRecord(L->Attrs.getAccess(), L->BaseType, Offset); +} + +ErrorOr +VirtualBaseClassRecord::deserialize(TypeRecordKind Kind, + ArrayRef &Data) { + const Layout *L = nullptr; + uint64_t Offset; + uint64_t Index; + CV_DESERIALIZE(Data, L, CV_NUMERIC_FIELD(Offset), CV_NUMERIC_FIELD(Index)); + return VirtualBaseClassRecord(L->Attrs.getAccess(), L->BaseType, L->VBPtrType, + Offset, Index); +} + +//===----------------------------------------------------------------------===// +// Type index remapping +//===----------------------------------------------------------------------===// + static bool remapIndex(ArrayRef IndexMap, TypeIndex &Idx) { // Simple types are unchanged. if (Idx.isSimple()) -- 2.50.1