mirror of
https://github.com/RPCSX/llvm.git
synced 2025-04-07 02:31:55 +00:00
[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
This commit is contained in:
parent
2df18c8dc0
commit
f07202a7aa
@ -15,8 +15,6 @@
|
|||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/DebugInfo/CodeView/CVRecord.h"
|
#include "llvm/DebugInfo/CodeView/CVRecord.h"
|
||||||
#include "llvm/DebugInfo/CodeView/CodeView.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/DebugInfo/CodeView/TypeIndex.h"
|
||||||
#include "llvm/Support/ErrorOr.h"
|
#include "llvm/Support/ErrorOr.h"
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
@ -85,17 +83,7 @@ public:
|
|||||||
/// is not in the map.
|
/// is not in the map.
|
||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<MemberPointerInfo> deserialize(ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getContainingType() const { return ContainingType; }
|
TypeIndex getContainingType() const { return ContainingType; }
|
||||||
PointerToMemberRepresentation getRepresentation() const {
|
PointerToMemberRepresentation getRepresentation() const {
|
||||||
@ -135,16 +123,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<ModifierRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<ModifierRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getModifiedType() const { return ModifiedType; }
|
TypeIndex getModifiedType() const { return ModifiedType; }
|
||||||
ModifierOptions getModifiers() const { return Modifiers; }
|
ModifierOptions getModifiers() const { return Modifiers; }
|
||||||
@ -174,14 +153,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<ProcedureRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<ProcedureRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
|
static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
|
||||||
|
|
||||||
@ -225,14 +197,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<MemberFunctionRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<MemberFunctionRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getReturnType() const { return ReturnType; }
|
TypeIndex getReturnType() const { return ReturnType; }
|
||||||
TypeIndex getClassType() const { return ClassType; }
|
TypeIndex getClassType() const { return ClassType; }
|
||||||
@ -278,14 +243,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<MemberFuncIdRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<MemberFuncIdRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
StringRef Name;
|
|
||||||
CV_DESERIALIZE(Data, L, Name);
|
|
||||||
|
|
||||||
return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getClassType() const { return ClassType; }
|
TypeIndex getClassType() const { return ClassType; }
|
||||||
TypeIndex getFunctionType() const { return FunctionType; }
|
TypeIndex getFunctionType() const { return FunctionType; }
|
||||||
StringRef getName() const { return Name; }
|
StringRef getName() const { return Name; }
|
||||||
@ -312,16 +270,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<ArgListRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<ArgListRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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<TypeIndex> getIndices() const { return StringIndices; }
|
ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
|
||||||
|
|
||||||
@ -365,26 +314,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<PointerRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<PointerRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getReferentType() const { return ReferentType; }
|
TypeIndex getReferentType() const { return ReferentType; }
|
||||||
PointerKind getPointerKind() const { return PtrKind; }
|
PointerKind getPointerKind() const { return PtrKind; }
|
||||||
@ -460,13 +390,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<NestedTypeRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<NestedTypeRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
StringRef Name;
|
|
||||||
CV_DESERIALIZE(Data, L, Name);
|
|
||||||
|
|
||||||
return NestedTypeRecord(L->Type, Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getNestedType() const { return Type; }
|
TypeIndex getNestedType() const { return Type; }
|
||||||
StringRef getName() const { return Name; }
|
StringRef getName() const { return Name; }
|
||||||
@ -495,14 +419,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<ArrayRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<ArrayRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getElementType() const { return ElementType; }
|
TypeIndex getElementType() const { return ElementType; }
|
||||||
TypeIndex getIndexType() const { return IndexType; }
|
TypeIndex getIndexType() const { return IndexType; }
|
||||||
@ -570,26 +487,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<ClassRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<ClassRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
HfaKind getHfa() const { return Hfa; }
|
HfaKind getHfa() const { return Hfa; }
|
||||||
WindowsRTClassKind getWinRTKind() const { return WinRTKind; }
|
WindowsRTClassKind getWinRTKind() const { return WinRTKind; }
|
||||||
@ -630,24 +528,7 @@ struct UnionRecord : public TagRecord {
|
|||||||
Hfa(Hfa), Size(Size) {}
|
Hfa(Hfa), Size(Size) {}
|
||||||
|
|
||||||
static ErrorOr<UnionRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<UnionRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
HfaKind getHfa() const { return Hfa; }
|
HfaKind getHfa() const { return Hfa; }
|
||||||
uint64_t getSize() const { return Size; }
|
uint64_t getSize() const { return Size; }
|
||||||
@ -683,16 +564,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<EnumRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<EnumRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getUnderlyingType() const { return UnderlyingType; }
|
TypeIndex getUnderlyingType() const { return UnderlyingType; }
|
||||||
|
|
||||||
@ -720,12 +592,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<BitFieldRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<BitFieldRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
CV_DESERIALIZE(Data, L);
|
|
||||||
|
|
||||||
return BitFieldRecord(L->Type, L->BitSize, L->BitOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getType() const { return Type; }
|
TypeIndex getType() const { return Type; }
|
||||||
uint8_t getBitOffset() const { return BitOffset; }
|
uint8_t getBitOffset() const { return BitOffset; }
|
||||||
@ -756,30 +623,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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<VFTableSlotKind> getSlots() const {
|
ArrayRef<VFTableSlotKind> getSlots() const {
|
||||||
if (!SlotsRef.empty())
|
if (!SlotsRef.empty())
|
||||||
@ -814,13 +658,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<TypeServer2Record> deserialize(TypeRecordKind Kind,
|
static ErrorOr<TypeServer2Record> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
StringRef Name;
|
|
||||||
CV_DESERIALIZE(Data, L, Name);
|
|
||||||
|
|
||||||
return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRef getGuid() const { return Guid; }
|
StringRef getGuid() const { return Guid; }
|
||||||
|
|
||||||
@ -851,13 +689,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<StringIdRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<StringIdRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
StringRef Name;
|
|
||||||
CV_DESERIALIZE(Data, L, Name);
|
|
||||||
|
|
||||||
return StringIdRecord(L->id, Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getId() const { return Id; }
|
TypeIndex getId() const { return Id; }
|
||||||
|
|
||||||
@ -885,13 +717,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<FuncIdRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<FuncIdRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
StringRef Name;
|
|
||||||
CV_DESERIALIZE(Data, L, Name);
|
|
||||||
|
|
||||||
return FuncIdRecord(L->ParentScope, L->FunctionType, Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getParentScope() const { return ParentScope; }
|
TypeIndex getParentScope() const { return ParentScope; }
|
||||||
|
|
||||||
@ -923,12 +749,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<UdtSourceLineRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<UdtSourceLineRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
CV_DESERIALIZE(Data, L);
|
|
||||||
|
|
||||||
return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getUDT() const { return UDT; }
|
TypeIndex getUDT() const { return UDT; }
|
||||||
TypeIndex getSourceFile() const { return SourceFile; }
|
TypeIndex getSourceFile() const { return SourceFile; }
|
||||||
@ -958,13 +779,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<BuildInfoRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<BuildInfoRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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<TypeIndex> getArgs() const { return ArgIndices; }
|
ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
|
||||||
|
|
||||||
@ -997,15 +812,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<VFTableRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<VFTableRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getCompleteClass() const { return CompleteClass; }
|
TypeIndex getCompleteClass() const { return CompleteClass; }
|
||||||
TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
|
TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
|
||||||
@ -1049,25 +856,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<OneMethodRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<OneMethodRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getType() const { return Type; }
|
TypeIndex getType() const { return Type; }
|
||||||
MethodKind getKind() const { return Kind; }
|
MethodKind getKind() const { return Kind; }
|
||||||
@ -1111,29 +900,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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<OneMethodRecord> getMethods() const { return Methods; }
|
ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
|
||||||
|
|
||||||
@ -1163,13 +930,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<OverloadedMethodRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<OverloadedMethodRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
StringRef Name;
|
|
||||||
CV_DESERIALIZE(Data, L, Name);
|
|
||||||
|
|
||||||
return OverloadedMethodRecord(L->MethodCount, L->MethList, Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t getNumOverloads() const { return NumOverloads; }
|
uint16_t getNumOverloads() const { return NumOverloads; }
|
||||||
TypeIndex getMethodList() const { return MethodList; }
|
TypeIndex getMethodList() const { return MethodList; }
|
||||||
@ -1200,14 +961,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<DataMemberRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<DataMemberRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemberAccess getAccess() const { return Access; }
|
MemberAccess getAccess() const { return Access; }
|
||||||
TypeIndex getType() const { return Type; }
|
TypeIndex getType() const { return Type; }
|
||||||
@ -1240,13 +994,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
StringRef Name;
|
|
||||||
CV_DESERIALIZE(Data, L, Name);
|
|
||||||
|
|
||||||
return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemberAccess getAccess() const { return Access; }
|
MemberAccess getAccess() const { return Access; }
|
||||||
TypeIndex getType() const { return Type; }
|
TypeIndex getType() const { return Type; }
|
||||||
@ -1276,14 +1024,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<EnumeratorRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<EnumeratorRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemberAccess getAccess() const { return Access; }
|
MemberAccess getAccess() const { return Access; }
|
||||||
APSInt getValue() const { return Value; }
|
APSInt getValue() const { return Value; }
|
||||||
@ -1311,14 +1052,8 @@ public:
|
|||||||
/// is not in the map.
|
/// is not in the map.
|
||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<VFPtrRecord>
|
static ErrorOr<VFPtrRecord> deserialize(TypeRecordKind Kind,
|
||||||
deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
|
ArrayRef<uint8_t> &Data);
|
||||||
const Layout *L = nullptr;
|
|
||||||
if (auto EC = consumeObject(Data, L))
|
|
||||||
return EC;
|
|
||||||
|
|
||||||
return VFPtrRecord(L->Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeIndex getType() const { return Type; }
|
TypeIndex getType() const { return Type; }
|
||||||
|
|
||||||
@ -1342,13 +1077,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<BaseClassRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<BaseClassRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemberAccess getAccess() const { return Access; }
|
MemberAccess getAccess() const { return Access; }
|
||||||
TypeIndex getBaseType() const { return Type; }
|
TypeIndex getBaseType() const { return Type; }
|
||||||
@ -1379,15 +1108,7 @@ public:
|
|||||||
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
|
||||||
|
|
||||||
static ErrorOr<VirtualBaseClassRecord> deserialize(TypeRecordKind Kind,
|
static ErrorOr<VirtualBaseClassRecord> deserialize(TypeRecordKind Kind,
|
||||||
ArrayRef<uint8_t> &Data) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemberAccess getAccess() const { return Access; }
|
MemberAccess getAccess() const { return Access; }
|
||||||
TypeIndex getBaseType() const { return BaseType; }
|
TypeIndex getBaseType() const { return BaseType; }
|
||||||
|
@ -9,10 +9,366 @@
|
|||||||
|
|
||||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||||
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::codeview;
|
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) {
|
static bool remapIndex(ArrayRef<TypeIndex> IndexMap, TypeIndex &Idx) {
|
||||||
// Simple types are unchanged.
|
// Simple types are unchanged.
|
||||||
if (Idx.isSimple())
|
if (Idx.isSimple())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user