1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 11:33:24 +02:00

[codeview] Move deserialization methods out of line

They aren't performance critical and don't need to be inline.

llvm-svn: 272829
This commit is contained in:
Reid Kleckner 2016-06-15 20:30:34 +00:00
parent 02e6e237fa
commit 2eba5b5cb6
2 changed files with 386 additions and 309 deletions

View File

@ -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 <cinttypes>
@ -85,17 +83,7 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<MemberPointerInfo> deserialize(ArrayRef<uint8_t> &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<PointerToMemberRepresentation>(R);
return MemberPointerInfo(T, PMR);
}
static ErrorOr<MemberPointerInfo> deserialize(ArrayRef<uint8_t> &Data);
TypeIndex getContainingType() const { return ContainingType; }
PointerToMemberRepresentation getRepresentation() const {
@ -135,16 +123,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<ModifierRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<ModifierOptions>(O);
return ModifierRecord(M, MO);
}
ArrayRef<uint8_t> &Data);
TypeIndex getModifiedType() const { return ModifiedType; }
ModifierOptions getModifiers() const { return Modifiers; }
@ -174,14 +153,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<ProcedureRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<uint8_t> &Data);
static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
@ -225,14 +197,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<MemberFunctionRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<uint8_t> &Data);
TypeIndex getReturnType() const { return ReturnType; }
TypeIndex getClassType() const { return ClassType; }
@ -278,14 +243,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<MemberFuncIdRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name);
}
ArrayRef<uint8_t> &Data);
TypeIndex getClassType() const { return ClassType; }
TypeIndex getFunctionType() const { return FunctionType; }
StringRef getName() const { return Name; }
@ -312,16 +270,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<ArgListRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList)
return std::make_error_code(std::errc::illegal_byte_sequence);
const Layout *L = nullptr;
ArrayRef<TypeIndex> Indices;
CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
return ArgListRecord(Kind, Indices);
}
ArrayRef<uint8_t> &Data);
ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
@ -365,26 +314,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<PointerRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<PointerOptions>(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<uint8_t> &Data);
TypeIndex getReferentType() const { return ReferentType; }
PointerKind getPointerKind() const { return PtrKind; }
@ -460,13 +390,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<NestedTypeRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return NestedTypeRecord(L->Type, Name);
}
ArrayRef<uint8_t> &Data);
TypeIndex getNestedType() const { return Type; }
StringRef getName() const { return Name; }
@ -495,14 +419,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<ArrayRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<uint8_t> &Data);
TypeIndex getElementType() const { return ElementType; }
TypeIndex getIndexType() const { return IndexType; }
@ -570,26 +487,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<ClassRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<WindowsRTClassKind>(WrtValue);
uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift;
HfaKind Hfa = static_cast<HfaKind>(HfaMask);
ClassOptions Options = static_cast<ClassOptions>(Props);
return ClassRecord(Kind, L->MemberCount, Options, Hfa, WRT, L->FieldList,
L->DerivedFrom, L->VShape, Size, Name, UniqueName);
}
ArrayRef<uint8_t> &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<UnionRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<HfaKind>(HfaMask);
ClassOptions Options = static_cast<ClassOptions>(Props);
return UnionRecord(L->MemberCount, Options, Hfa, L->FieldList, Size, Name,
UniqueName);
}
ArrayRef<uint8_t> &Data);
HfaKind getHfa() const { return Hfa; }
uint64_t getSize() const { return Size; }
@ -683,16 +564,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<EnumRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
uint16_t P = L->Properties;
ClassOptions Options = static_cast<ClassOptions>(P);
return EnumRecord(L->NumEnumerators, Options, L->FieldListType, Name, Name,
L->UnderlyingType);
}
ArrayRef<uint8_t> &Data);
TypeIndex getUnderlyingType() const { return UnderlyingType; }
@ -720,12 +592,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<BitFieldRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
CV_DESERIALIZE(Data, L);
return BitFieldRecord(L->Type, L->BitSize, L->BitOffset);
}
ArrayRef<uint8_t> &Data);
TypeIndex getType() const { return Type; }
uint8_t getBitOffset() const { return BitOffset; }
@ -756,30 +623,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
return EC;
std::vector<VFTableSlotKind> 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<VFTableSlotKind>(Value));
if (--Count > 0) {
Value = (Data[0] & 0xF0) >> 4;
Slots.push_back(static_cast<VFTableSlotKind>(Value));
--Count;
}
Data = Data.slice(1);
}
return VFTableShapeRecord(Slots);
}
ArrayRef<uint8_t> &Data);
ArrayRef<VFTableSlotKind> getSlots() const {
if (!SlotsRef.empty())
@ -814,13 +658,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<TypeServer2Record> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name);
}
ArrayRef<uint8_t> &Data);
StringRef getGuid() const { return Guid; }
@ -851,13 +689,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<StringIdRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return StringIdRecord(L->id, Name);
}
ArrayRef<uint8_t> &Data);
TypeIndex getId() const { return Id; }
@ -885,13 +717,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<FuncIdRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return FuncIdRecord(L->ParentScope, L->FunctionType, Name);
}
ArrayRef<uint8_t> &Data);
TypeIndex getParentScope() const { return ParentScope; }
@ -923,12 +749,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<UdtSourceLineRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
CV_DESERIALIZE(Data, L);
return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber);
}
ArrayRef<uint8_t> &Data);
TypeIndex getUDT() const { return UDT; }
TypeIndex getSourceFile() const { return SourceFile; }
@ -958,13 +779,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<BuildInfoRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
ArrayRef<TypeIndex> Indices;
CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
return BuildInfoRecord(Indices);
}
ArrayRef<uint8_t> &Data);
ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
@ -997,15 +812,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<VFTableRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
std::vector<StringRef> Names;
CV_DESERIALIZE(Data, L, Name, CV_ARRAY_FIELD_TAIL(Names));
return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset,
Name, Names);
}
ArrayRef<uint8_t> &Data);
TypeIndex getCompleteClass() const { return CompleteClass; }
TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
@ -1049,25 +856,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<OneMethodRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<uint8_t> &Data);
TypeIndex getType() const { return Type; }
MethodKind getKind() const { return Kind; }
@ -1111,29 +900,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
std::vector<OneMethodRecord> 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<uint8_t> &Data);
ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
@ -1163,13 +930,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<OverloadedMethodRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return OverloadedMethodRecord(L->MethodCount, L->MethList, Name);
}
ArrayRef<uint8_t> &Data);
uint16_t getNumOverloads() const { return NumOverloads; }
TypeIndex getMethodList() const { return MethodList; }
@ -1200,14 +961,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<DataMemberRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
TypeIndex getType() const { return Type; }
@ -1240,13 +994,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name);
}
ArrayRef<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
TypeIndex getType() const { return Type; }
@ -1276,14 +1024,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<EnumeratorRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
APSInt Value;
StringRef Name;
CV_DESERIALIZE(Data, L, Value, Name);
return EnumeratorRecord(L->Attrs.getAccess(), Value, Name);
}
ArrayRef<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
APSInt getValue() const { return Value; }
@ -1311,14 +1052,8 @@ public:
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<VFPtrRecord>
deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
return EC;
return VFPtrRecord(L->Type);
}
static ErrorOr<VFPtrRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data);
TypeIndex getType() const { return Type; }
@ -1342,13 +1077,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<BaseClassRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
TypeIndex getBaseType() const { return Type; }
@ -1379,15 +1108,7 @@ public:
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
static ErrorOr<VirtualBaseClassRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<uint8_t> &Data);
MemberAccess getAccess() const { return Access; }
TypeIndex getBaseType() const { return BaseType; }

View File

@ -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>
MemberPointerInfo::deserialize(ArrayRef<uint8_t> &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<PointerToMemberRepresentation>(R);
return MemberPointerInfo(T, PMR);
}
ErrorOr<ModifierRecord> ModifierRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<ModifierOptions>(O);
return ModifierRecord(M, MO);
}
ErrorOr<ProcedureRecord> ProcedureRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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>
MemberFunctionRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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>
MemberFuncIdRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name);
}
ErrorOr<ArgListRecord> ArgListRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList)
return std::make_error_code(std::errc::illegal_byte_sequence);
const Layout *L = nullptr;
ArrayRef<TypeIndex> Indices;
CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
return ArgListRecord(Kind, Indices);
}
ErrorOr<PointerRecord> PointerRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<PointerOptions>(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>
NestedTypeRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return NestedTypeRecord(L->Type, Name);
}
ErrorOr<ArrayRecord> ArrayRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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> ClassRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<WindowsRTClassKind>(WrtValue);
uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift;
HfaKind Hfa = static_cast<HfaKind>(HfaMask);
ClassOptions Options = static_cast<ClassOptions>(Props);
return ClassRecord(Kind, L->MemberCount, Options, Hfa, WRT, L->FieldList,
L->DerivedFrom, L->VShape, Size, Name, UniqueName);
}
ErrorOr<UnionRecord> UnionRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<HfaKind>(HfaMask);
ClassOptions Options = static_cast<ClassOptions>(Props);
return UnionRecord(L->MemberCount, Options, Hfa, L->FieldList, Size, Name,
UniqueName);
}
ErrorOr<EnumRecord> EnumRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
uint16_t P = L->Properties;
ClassOptions Options = static_cast<ClassOptions>(P);
return EnumRecord(L->NumEnumerators, Options, L->FieldListType, Name, Name,
L->UnderlyingType);
}
ErrorOr<BitFieldRecord> BitFieldRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
CV_DESERIALIZE(Data, L);
return BitFieldRecord(L->Type, L->BitSize, L->BitOffset);
}
ErrorOr<VFTableShapeRecord>
VFTableShapeRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
return EC;
std::vector<VFTableSlotKind> 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<VFTableSlotKind>(Value));
if (--Count > 0) {
Value = (Data[0] & 0xF0) >> 4;
Slots.push_back(static_cast<VFTableSlotKind>(Value));
--Count;
}
Data = Data.slice(1);
}
return VFTableShapeRecord(Slots);
}
ErrorOr<TypeServer2Record>
TypeServer2Record::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name);
}
ErrorOr<StringIdRecord> StringIdRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return StringIdRecord(L->id, Name);
}
ErrorOr<FuncIdRecord> FuncIdRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return FuncIdRecord(L->ParentScope, L->FunctionType, Name);
}
ErrorOr<UdtSourceLineRecord>
UdtSourceLineRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
CV_DESERIALIZE(Data, L);
return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber);
}
ErrorOr<BuildInfoRecord> BuildInfoRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
ArrayRef<TypeIndex> Indices;
CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
return BuildInfoRecord(Indices);
}
ErrorOr<VFTableRecord> VFTableRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
std::vector<StringRef> Names;
CV_DESERIALIZE(Data, L, Name, CV_ARRAY_FIELD_TAIL(Names));
return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset,
Name, Names);
}
ErrorOr<OneMethodRecord> OneMethodRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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>
MethodOverloadListRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
std::vector<OneMethodRecord> 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>
OverloadedMethodRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return OverloadedMethodRecord(L->MethodCount, L->MethList, Name);
}
ErrorOr<DataMemberRecord>
DataMemberRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &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>
StaticDataMemberRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Data, L, Name);
return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name);
}
ErrorOr<EnumeratorRecord>
EnumeratorRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
APSInt Value;
StringRef Name;
CV_DESERIALIZE(Data, L, Value, Name);
return EnumeratorRecord(L->Attrs.getAccess(), Value, Name);
}
ErrorOr<VFPtrRecord> VFPtrRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr;
if (auto EC = consumeObject(Data, L))
return EC;
return VFPtrRecord(L->Type);
}
ErrorOr<BaseClassRecord> BaseClassRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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>
VirtualBaseClassRecord::deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &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<TypeIndex> IndexMap, TypeIndex &Idx) {
// Simple types are unchanged.
if (Idx.isSimple())