Add CodeViewRecordIO for reading and writing.

Using a pattern similar to that of YamlIO, this allows
us to have a single codepath for translating codeview
records to and from serialized byte streams.  The
current patch only hooks this up to the reading of
CodeView type records.  A subsequent patch will hook
it up for writing of CodeView type records, and then a
third patch will hook up the reading and writing of
CodeView symbols.

Differential Revision: https://reviews.llvm.org/D26040

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285836 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zachary Turner 2016-11-02 17:05:19 +00:00
parent 08f7b24149
commit d7730478c0
18 changed files with 1192 additions and 1154 deletions

View File

@ -0,0 +1,135 @@
//===- CodeViewRecordIO.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/MSF/StreamReader.h"
#include "llvm/DebugInfo/MSF/StreamWriter.h"
#include "llvm/Support/Error.h"
#include <stdint.h>
#include <type_traits>
namespace llvm {
namespace msf {
class StreamReader;
class StreamWriter;
}
namespace codeview {
class CodeViewRecordIO {
struct ActiveRecord {
uint16_t Kind;
};
public:
explicit CodeViewRecordIO(msf::StreamReader &Reader) : Reader(&Reader) {}
explicit CodeViewRecordIO(msf::StreamWriter &Writer) : Writer(&Writer) {}
Error beginRecord(uint16_t Kind);
Error endRecord();
Error mapInteger(TypeIndex &TypeInd);
bool isReading() const { return Reader != nullptr; }
bool isWriting() const { return !isReading(); }
template <typename T> Error mapInteger(T &Value) {
if (isWriting())
return Writer->writeInteger(Value);
return Reader->readInteger(Value);
}
template <typename T> Error mapEnum(T &Value) {
using U = typename std::underlying_type<T>::type;
U X;
if (isWriting())
X = static_cast<U>(Value);
if (auto EC = mapInteger(X))
return EC;
if (isReading())
Value = static_cast<T>(X);
return Error::success();
}
Error mapEncodedInteger(int64_t &Value);
Error mapEncodedInteger(uint64_t &Value);
Error mapEncodedInteger(APSInt &Value);
Error mapStringZ(StringRef &Value);
Error mapGuid(StringRef &Guid);
template <typename SizeType, typename T, typename ElementMapper>
Error mapVectorN(T &Items, const ElementMapper &Mapper) {
SizeType Size;
if (isWriting()) {
Size = static_cast<SizeType>(Items.size());
if (auto EC = Writer->writeInteger(Size))
return EC;
for (auto &X : Items) {
if (auto EC = Mapper(*this, X))
return EC;
}
} else {
if (auto EC = Reader->readInteger(Size))
return EC;
for (SizeType I = 0; I < Size; ++I) {
typename T::value_type Item;
if (auto EC = Mapper(*this, Item))
return EC;
Items.push_back(Item);
}
}
return Error::success();
}
template <typename T, typename ElementMapper>
Error mapVectorTail(T &Items, const ElementMapper &Mapper) {
if (isWriting()) {
for (auto &Item : Items) {
if (auto EC = Mapper(*this, Item))
return EC;
}
} else {
typename T::value_type Field;
// Stop when we run out of bytes or we hit record padding bytes.
while (!Reader->empty() && Reader->peek() < LF_PAD0) {
if (auto EC = Mapper(*this, Field))
return EC;
Items.push_back(Field);
}
}
return Error::success();
}
Error mapByteVectorTail(ArrayRef<uint8_t> &Bytes);
Error skipPadding();
private:
Error writeEncodedSignedInteger(const int64_t &Value);
Error writeEncodedUnsignedInteger(const uint64_t &Value);
Optional<ActiveRecord> CurrentRecord;
msf::StreamReader *Reader = nullptr;
msf::StreamWriter *Writer = nullptr;
};
}
}
#endif

View File

@ -10,57 +10,108 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/DebugInfo/MSF/ByteStream.h"
#include "llvm/DebugInfo/MSF/StreamReader.h"
#include "llvm/DebugInfo/MSF/StreamWriter.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
class TypeDeserializer : public TypeVisitorCallbacks {
struct MappingInfo {
explicit MappingInfo(ArrayRef<uint8_t> RecordData)
: Stream(RecordData), Reader(Stream), Mapping(Reader) {}
msf::ByteStream Stream;
msf::StreamReader Reader;
TypeRecordMapping Mapping;
};
public:
TypeDeserializer() {}
Error visitTypeBegin(CVType &Record) override {
assert(!Mapping && "Already in a type mapping!");
Mapping = llvm::make_unique<MappingInfo>(Record.content());
return Mapping->Mapping.visitTypeBegin(Record);
}
Error visitTypeEnd(CVType &Record) override {
assert(Mapping && "Not in a type mapping!");
auto EC = Mapping->Mapping.visitTypeEnd(Record);
Mapping.reset();
return EC;
}
#define TYPE_RECORD(EnumName, EnumVal, Name) \
Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \
return defaultVisitKnownRecord(CVR, Record); \
return visitKnownRecordImpl<Name##Record>(CVR, Record); \
}
#define MEMBER_RECORD(EnumName, EnumVal, Name)
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "TypeRecords.def"
private:
template <typename RecordType>
Error visitKnownRecordImpl(CVType &CVR, RecordType &Record) {
return Mapping->Mapping.visitKnownRecord(CVR, Record);
}
std::unique_ptr<MappingInfo> Mapping;
};
class FieldListDeserializer : public TypeVisitorCallbacks {
struct MappingInfo {
explicit MappingInfo(msf::StreamReader &R)
: Reader(R), Mapping(Reader), StartOffset(0) {}
msf::StreamReader &Reader;
TypeRecordMapping Mapping;
uint32_t StartOffset;
};
public:
explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) {}
Error visitMemberBegin(CVMemberRecord &Record) override {
Mapping.StartOffset = Mapping.Reader.getOffset();
return Mapping.Mapping.visitMemberBegin(Record);
}
Error visitMemberEnd(CVMemberRecord &Record) override {
if (auto EC = Mapping.Mapping.visitMemberEnd(Record))
return EC;
return Error::success();
}
#define TYPE_RECORD(EnumName, EnumVal, Name)
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
return defaultVisitKnownMember(CVR, Record); \
return visitKnownMemberImpl<Name##Record>(CVR, Record); \
}
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "TypeRecords.def"
protected:
template <typename T>
Error deserializeRecord(msf::StreamReader &Reader, TypeLeafKind Kind,
T &Record) const {
TypeRecordKind RK = static_cast<TypeRecordKind>(Kind);
auto ExpectedRecord = T::deserialize(RK, Reader);
if (!ExpectedRecord)
return ExpectedRecord.takeError();
Record = std::move(*ExpectedRecord);
return Error::success();
}
private:
template <typename T> Error defaultVisitKnownRecord(CVType &CVR, T &Record) {
msf::ByteStream S(CVR.content());
msf::StreamReader SR(S);
if (auto EC = deserializeRecord(SR, CVR.Type, Record))
return EC;
return Error::success();
}
template <typename T>
Error defaultVisitKnownMember(CVMemberRecord &CVMR, T &Record) {
msf::ByteStream S(CVMR.Data);
msf::StreamReader SR(S);
if (auto EC = deserializeRecord(SR, CVMR.Kind, Record))
template <typename RecordType>
Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) {
if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record))
return EC;
uint32_t EndOffset = Mapping.Reader.getOffset();
uint32_t RecordLength = EndOffset - Mapping.StartOffset;
Mapping.Reader.setOffset(Mapping.StartOffset);
if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength))
return EC;
assert(Mapping.Reader.getOffset() == EndOffset);
return Error::success();
}
MappingInfo Mapping;
};
}
}

View File

@ -101,6 +101,7 @@ public:
: Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {}
uint32_t getIndex() const { return Index; }
void setIndex(uint32_t I) { Index = I; }
bool isSimple() const { return Index < FirstNonSimpleIndex; }
bool isNoneType() const { return *this == None(); }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
//===- TypeRecordMapping.h --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORDMAPPING_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDMAPPING_H
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
class TypeRecordMapping : public TypeVisitorCallbacks {
public:
explicit TypeRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
Error visitTypeBegin(CVType &Record) override;
Error visitTypeEnd(CVType &Record) override;
Error visitMemberBegin(CVMemberRecord &Record) override;
Error visitMemberEnd(CVMemberRecord &Record) override;
#define TYPE_RECORD(EnumName, EnumVal, Name) \
Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "TypeRecords.def"
private:
Optional<TypeLeafKind> TypeKind;
CodeViewRecordIO IO;
};
}
}
#endif

View File

@ -25,11 +25,18 @@ namespace msf {
class StreamWriter {
public:
StreamWriter() {}
StreamWriter(WritableStreamRef Stream);
Error writeBytes(ArrayRef<uint8_t> Buffer);
Error writeInteger(uint8_t Int);
Error writeInteger(uint16_t Dest);
Error writeInteger(uint32_t Dest);
Error writeInteger(uint64_t Dest);
Error writeInteger(int8_t Int);
Error writeInteger(int16_t Dest);
Error writeInteger(int32_t Dest);
Error writeInteger(int64_t Dest);
Error writeZeroString(StringRef Str);
Error writeFixedString(StringRef Str);
Error writeStreamRef(ReadableStreamRef Ref);
@ -77,7 +84,7 @@ public:
private:
WritableStreamRef Stream;
uint32_t Offset;
uint32_t Offset = 0;
};
} // namespace msf
} // namespace llvm

View File

@ -1690,9 +1690,9 @@ TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) {
ClassOptions CO =
ClassOptions::ForwardReference | getCommonClassOptions(Ty);
std::string FullName = getFullyQualifiedName(Ty);
TypeIndex FwdDeclTI = TypeTable.writeKnownType(ClassRecord(
Kind, 0, CO, HfaKind::None, WindowsRTClassKind::None, TypeIndex(),
TypeIndex(), TypeIndex(), 0, FullName, Ty->getIdentifier()));
TypeIndex FwdDeclTI = TypeTable.writeKnownType(
ClassRecord(Kind, 0, CO, TypeIndex(), TypeIndex(), TypeIndex(), 0,
FullName, Ty->getIdentifier()));
if (!Ty->isForwardDecl())
DeferredCompleteTypes.push_back(Ty);
return FwdDeclTI;
@ -1716,9 +1716,9 @@ TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) {
uint64_t SizeInBytes = Ty->getSizeInBits() / 8;
TypeIndex ClassTI = TypeTable.writeKnownType(ClassRecord(
Kind, FieldCount, CO, HfaKind::None, WindowsRTClassKind::None, FieldTI,
TypeIndex(), VShapeTI, SizeInBytes, FullName, Ty->getIdentifier()));
TypeIndex ClassTI = TypeTable.writeKnownType(
ClassRecord(Kind, FieldCount, CO, FieldTI, TypeIndex(), VShapeTI,
SizeInBytes, FullName, Ty->getIdentifier()));
TypeTable.writeKnownType(UdtSourceLineRecord(
ClassTI, TypeTable.writeKnownType(StringIdRecord(
@ -1734,8 +1734,8 @@ TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) {
ClassOptions CO =
ClassOptions::ForwardReference | getCommonClassOptions(Ty);
std::string FullName = getFullyQualifiedName(Ty);
TypeIndex FwdDeclTI = TypeTable.writeKnownType(UnionRecord(
0, CO, HfaKind::None, TypeIndex(), 0, FullName, Ty->getIdentifier()));
TypeIndex FwdDeclTI = TypeTable.writeKnownType(
UnionRecord(0, CO, TypeIndex(), 0, FullName, Ty->getIdentifier()));
if (!Ty->isForwardDecl())
DeferredCompleteTypes.push_back(Ty);
return FwdDeclTI;
@ -1755,9 +1755,8 @@ TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) {
uint64_t SizeInBytes = Ty->getSizeInBits() / 8;
std::string FullName = getFullyQualifiedName(Ty);
TypeIndex UnionTI = TypeTable.writeKnownType(
UnionRecord(FieldCount, CO, HfaKind::None, FieldTI, SizeInBytes, FullName,
Ty->getIdentifier()));
TypeIndex UnionTI = TypeTable.writeKnownType(UnionRecord(
FieldCount, CO, FieldTI, SizeInBytes, FullName, Ty->getIdentifier()));
TypeTable.writeKnownType(UdtSourceLineRecord(
UnionTI, TypeTable.writeKnownType(StringIdRecord(
@ -1858,11 +1857,10 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
if (Introduced)
VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes();
Methods.push_back(
OneMethodRecord(MethodType, translateMethodKindFlags(SP, Introduced),
translateMethodOptionFlags(SP),
translateAccessFlags(Ty->getTag(), SP->getFlags()),
VFTableOffset, Name));
Methods.push_back(OneMethodRecord(
MethodType, translateAccessFlags(Ty->getTag(), SP->getFlags()),
translateMethodKindFlags(SP, Introduced),
translateMethodOptionFlags(SP), VFTableOffset, Name));
MemberCount++;
}
assert(Methods.size() > 0 && "Empty methods map entry");

View File

@ -1,5 +1,6 @@
add_llvm_library(LLVMDebugInfoCodeView
CodeViewError.cpp
CodeViewRecordIO.cpp
CVSymbolVisitor.cpp
CVTypeVisitor.cpp
EnumTables.cpp
@ -15,6 +16,7 @@ add_llvm_library(LLVMDebugInfoCodeView
TypeDumper.cpp
TypeRecord.cpp
TypeRecordBuilder.cpp
TypeRecordMapping.cpp
TypeStreamMerger.cpp
TypeTableBuilder.cpp

View File

@ -10,44 +10,29 @@
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/MSF/ByteStream.h"
using namespace llvm;
using namespace llvm::codeview;
static Error skipPadding(msf::StreamReader &Reader) {
if (Reader.empty())
return Error::success();
uint8_t Leaf = Reader.peek();
if (Leaf < LF_PAD0)
return Error::success();
// Leaf is greater than 0xf0. We should advance by the number of bytes in
// the low 4 bits.
unsigned BytesToAdvance = Leaf & 0x0F;
return Reader.skip(BytesToAdvance);
}
template <typename T>
static Expected<CVMemberRecord>
deserializeMemberRecord(msf::StreamReader &Reader, TypeLeafKind Kind) {
msf::StreamReader OldReader = Reader;
TypeRecordKind RK = static_cast<TypeRecordKind>(Kind);
auto ExpectedRecord = T::deserialize(RK, Reader);
if (!ExpectedRecord)
return ExpectedRecord.takeError();
assert(Reader.bytesRemaining() < OldReader.bytesRemaining());
if (auto EC = skipPadding(Reader))
deserializeMemberRecord(FieldListDeserializer &Deserializer,
msf::StreamReader &Reader, TypeLeafKind Kind) {
T MR(static_cast<TypeRecordKind>(Kind));
CVMemberRecord CVR;
CVR.Kind = Kind;
if (auto EC = Deserializer.visitMemberBegin(CVR))
return std::move(EC);
if (auto EC = Deserializer.visitKnownMember(CVR, MR))
return std::move(EC);
if (auto EC = Deserializer.visitMemberEnd(CVR))
return std::move(EC);
CVMemberRecord CVMR;
CVMR.Kind = Kind;
uint32_t RecordLength = OldReader.bytesRemaining() - Reader.bytesRemaining();
if (auto EC = OldReader.readBytes(CVMR.Data, RecordLength))
return std::move(EC);
return CVMR;
return CVR;
}
CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
@ -138,22 +123,28 @@ Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) {
}
template <typename MR>
static Error visitKnownMember(msf::StreamReader &Reader, TypeLeafKind Leaf,
static Error visitKnownMember(FieldListDeserializer &Deserializer,
msf::StreamReader &Reader, TypeLeafKind Leaf,
TypeVisitorCallbacks &Callbacks) {
auto ExpectedRecord = deserializeMemberRecord<MR>(Reader, Leaf);
if (!ExpectedRecord)
return ExpectedRecord.takeError();
CVMemberRecord &Record = *ExpectedRecord;
if (auto EC = Callbacks.visitMemberBegin(Record))
MR Record(static_cast<TypeRecordKind>(Leaf));
CVMemberRecord CVR;
CVR.Kind = Leaf;
if (auto EC = Callbacks.visitMemberBegin(CVR))
return EC;
if (auto EC = visitKnownMember<MR>(Record, Callbacks))
if (auto EC = Callbacks.visitKnownMember(CVR, Record))
return EC;
if (auto EC = Callbacks.visitMemberEnd(Record))
if (auto EC = Callbacks.visitMemberEnd(CVR))
return EC;
return Error::success();
}
Error CVTypeVisitor::visitFieldListMemberStream(msf::StreamReader Reader) {
FieldListDeserializer Deserializer(Reader);
TypeVisitorCallbackPipeline Pipeline;
Pipeline.addCallbackToPipeline(Deserializer);
Pipeline.addCallbackToPipeline(Callbacks);
TypeLeafKind Leaf;
while (!Reader.empty()) {
if (auto EC = Reader.readEnum(Leaf))
@ -168,7 +159,8 @@ Error CVTypeVisitor::visitFieldListMemberStream(msf::StreamReader Reader) {
cv_error_code::unknown_member_record);
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
case EnumName: { \
if (auto EC = visitKnownMember<Name##Record>(Reader, Leaf, Callbacks)) \
if (auto EC = visitKnownMember<Name##Record>(Deserializer, Reader, Leaf, \
Pipeline)) \
return EC; \
break; \
}

View File

@ -0,0 +1,186 @@
//===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/MSF/StreamReader.h"
#include "llvm/DebugInfo/MSF/StreamWriter.h"
using namespace llvm;
using namespace llvm::codeview;
Error CodeViewRecordIO::beginRecord(uint16_t Kind) {
assert(!CurrentRecord.hasValue() && "There is already a record active!");
CurrentRecord.emplace();
CurrentRecord->Kind = Kind;
return Error::success();
}
Error CodeViewRecordIO::endRecord() {
assert(CurrentRecord.hasValue() && "Not in a record!");
CurrentRecord.reset();
return Error::success();
}
Error CodeViewRecordIO::skipPadding() {
assert(!isWriting() && "Cannot skip padding while writing!");
if (Reader->bytesRemaining() == 0)
return Error::success();
uint8_t Leaf = Reader->peek();
if (Leaf < LF_PAD0)
return Error::success();
// Leaf is greater than 0xf0. We should advance by the number of bytes in
// the low 4 bits.
unsigned BytesToAdvance = Leaf & 0x0F;
return Reader->skip(BytesToAdvance);
}
Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) {
if (isWriting()) {
if (auto EC = Writer->writeBytes(Bytes))
return EC;
} else {
if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
return EC;
}
return Error::success();
}
Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) {
if (isWriting()) {
if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
return EC;
return Error::success();
}
uint32_t I;
if (auto EC = Reader->readInteger(I))
return EC;
TypeInd.setIndex(I);
return Error::success();
}
Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) {
if (isWriting()) {
if (Value >= 0) {
if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value)))
return EC;
} else {
if (auto EC = writeEncodedSignedInteger(Value))
return EC;
}
} else {
APSInt N;
if (auto EC = consume(*Reader, N))
return EC;
Value = N.getExtValue();
}
return Error::success();
}
Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) {
if (isWriting()) {
if (auto EC = writeEncodedUnsignedInteger(Value))
return EC;
} else {
APSInt N;
if (auto EC = consume(*Reader, N))
return EC;
Value = N.getZExtValue();
}
return Error::success();
}
Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) {
if (isWriting()) {
if (Value.isSigned())
return writeEncodedSignedInteger(Value.getSExtValue());
return writeEncodedUnsignedInteger(Value.getZExtValue());
}
return consume(*Reader, Value);
}
Error CodeViewRecordIO::mapStringZ(StringRef &Value) {
if (isWriting()) {
if (auto EC = Writer->writeZeroString(Value))
return EC;
} else {
if (auto EC = Reader->readZeroString(Value))
return EC;
}
return Error::success();
}
Error CodeViewRecordIO::mapGuid(StringRef &Guid) {
if (isWriting()) {
assert(Guid.size() == 16 && "Invalid Guid Size!");
if (auto EC = Writer->writeFixedString(Guid))
return EC;
} else {
if (auto EC = Reader->readFixedString(Guid, 16))
return EC;
}
return Error::success();
}
Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
assert(Value < 0 && "Encoded integer is not signed!");
if (Value >= std::numeric_limits<int8_t>::min()) {
if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_CHAR)))
return EC;
if (auto EC = Writer->writeInteger(static_cast<int8_t>(Value)))
return EC;
} else if (Value >= std::numeric_limits<int16_t>::min()) {
if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_SHORT)))
return EC;
if (auto EC = Writer->writeInteger(static_cast<int16_t>(Value)))
return EC;
} else if (Value >= std::numeric_limits<int32_t>::min()) {
if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_LONG)))
return EC;
if (auto EC = Writer->writeInteger(static_cast<int32_t>(Value)))
return EC;
} else {
if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_QUADWORD)))
return EC;
if (auto EC = Writer->writeInteger(Value))
return EC;
}
return Error::success();
}
Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
if (Value < LF_NUMERIC) {
if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value)))
return EC;
} else if (Value <= std::numeric_limits<uint16_t>::max()) {
if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_USHORT)))
return EC;
if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value)))
return EC;
} else if (Value <= std::numeric_limits<uint32_t>::max()) {
if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_ULONG)))
return EC;
if (auto EC = Writer->writeInteger(static_cast<uint32_t>(Value)))
return EC;
} else {
if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_UQUADWORD)))
return EC;
if (auto EC = Writer->writeInteger(Value))
return EC;
}
return Error::success();
}

View File

@ -268,12 +268,7 @@ Error CVTypeDumper::visitMemberEnd(CVMemberRecord &Record) {
Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
FieldListRecord &FieldList) {
TypeDeserializer Deserializer;
TypeVisitorCallbackPipeline Pipeline;
Pipeline.addCallbackToPipeline(Deserializer);
Pipeline.addCallbackToPipeline(*this);
CVTypeVisitor Visitor(Pipeline);
CVTypeVisitor Visitor(*this);
if (auto EC = Visitor.visitFieldListMemberStream(FieldList.Data))
return EC;

View File

@ -16,384 +16,6 @@
using namespace llvm;
using namespace llvm::codeview;
//===----------------------------------------------------------------------===//
// Type record deserialization
//===----------------------------------------------------------------------===//
Expected<MemberPointerInfo>
MemberPointerInfo::deserialize(msf::StreamReader &Reader) {
const Layout *L = nullptr;
if (auto EC = Reader.readObject(L))
return std::move(EC);
TypeIndex T = L->ClassType;
uint16_t R = L->Representation;
PointerToMemberRepresentation PMR =
static_cast<PointerToMemberRepresentation>(R);
return MemberPointerInfo(T, PMR);
}
Expected<ModifierRecord>
ModifierRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
if (auto EC = Reader.readObject(L))
return std::move(EC);
TypeIndex M = L->ModifiedType;
uint16_t O = L->Modifiers;
ModifierOptions MO = static_cast<ModifierOptions>(O);
return ModifierRecord(M, MO);
}
Expected<ProcedureRecord>
ProcedureRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
if (auto EC = Reader.readObject(L))
return std::move(EC);
return ProcedureRecord(L->ReturnType, L->CallConv, L->Options,
L->NumParameters, L->ArgListType);
}
Expected<MemberFunctionRecord>
MemberFunctionRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
CV_DESERIALIZE(Reader, L);
return MemberFunctionRecord(L->ReturnType, L->ClassType, L->ThisType,
L->CallConv, L->Options, L->NumParameters,
L->ArgListType, L->ThisAdjustment);
}
Expected<MemberFuncIdRecord>
MemberFuncIdRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Reader, L, Name);
return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name);
}
Expected<ArgListRecord> ArgListRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList)
return make_error<CodeViewError>(
cv_error_code::corrupt_record,
"ArgListRecord contains unexpected TypeRecordKind");
const Layout *L = nullptr;
ArrayRef<TypeIndex> Indices;
CV_DESERIALIZE(Reader, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
return ArgListRecord(Kind, Indices);
}
Expected<PointerRecord> PointerRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
if (auto EC = Reader.readObject(L))
return std::move(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()) {
if (auto ExpectedMPI = MemberPointerInfo::deserialize(Reader))
return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size,
*ExpectedMPI);
else
return ExpectedMPI.takeError();
}
return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size);
}
Expected<NestedTypeRecord>
NestedTypeRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Reader, L, Name);
return NestedTypeRecord(L->Type, Name);
}
Expected<FieldListRecord>
FieldListRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
ArrayRef<uint8_t> Data;
if (auto EC = Reader.readBytes(Data, Reader.bytesRemaining()))
return std::move(EC);
return FieldListRecord(Data);
}
Expected<ArrayRecord> ArrayRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
uint64_t Size;
StringRef Name;
CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Size), Name);
return ArrayRecord(L->ElementType, L->IndexType, Size, Name);
}
Expected<ClassRecord> ClassRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
uint64_t Size = 0;
StringRef Name;
StringRef UniqueName;
uint16_t Props;
const Layout *L = nullptr;
CV_DESERIALIZE(Reader, 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);
}
Expected<UnionRecord> UnionRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
uint64_t Size = 0;
StringRef Name;
StringRef UniqueName;
uint16_t Props;
const Layout *L = nullptr;
CV_DESERIALIZE(Reader, 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);
}
Expected<EnumRecord> EnumRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
StringRef UniqueName;
CV_DESERIALIZE(Reader, L, Name,
CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName()));
uint16_t P = L->Properties;
ClassOptions Options = static_cast<ClassOptions>(P);
return EnumRecord(L->NumEnumerators, Options, L->FieldListType, Name,
UniqueName, L->UnderlyingType);
}
Expected<BitFieldRecord>
BitFieldRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
CV_DESERIALIZE(Reader, L);
return BitFieldRecord(L->Type, L->BitSize, L->BitOffset);
}
Expected<VFTableShapeRecord>
VFTableShapeRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
if (auto EC = Reader.readObject(L))
return std::move(EC);
std::vector<VFTableSlotKind> Slots;
uint16_t Count = L->VFEntryCount;
while (Count > 0) {
// Process up to 2 nibbles at a time (if there are at least 2 remaining)
uint8_t Data;
if (auto EC = Reader.readInteger(Data))
return std::move(EC);
uint8_t Value = Data & 0x0F;
Slots.push_back(static_cast<VFTableSlotKind>(Value));
if (--Count > 0) {
Value = (Data & 0xF0) >> 4;
Slots.push_back(static_cast<VFTableSlotKind>(Value));
--Count;
}
}
return VFTableShapeRecord(Slots);
}
Expected<TypeServer2Record>
TypeServer2Record::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Reader, L, Name);
return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name);
}
Expected<StringIdRecord>
StringIdRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Reader, L, Name);
return StringIdRecord(L->id, Name);
}
Expected<FuncIdRecord> FuncIdRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Reader, L, Name);
return FuncIdRecord(L->ParentScope, L->FunctionType, Name);
}
Expected<UdtSourceLineRecord>
UdtSourceLineRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
CV_DESERIALIZE(Reader, L);
return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber);
}
Expected<BuildInfoRecord>
BuildInfoRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
ArrayRef<TypeIndex> Indices;
CV_DESERIALIZE(Reader, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
return BuildInfoRecord(Indices);
}
Expected<VFTableRecord> VFTableRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
std::vector<StringRef> Names;
CV_DESERIALIZE(Reader, L, Name, CV_ARRAY_FIELD_TAIL(Names));
return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset,
Name, Names);
}
Expected<OneMethodRecord>
OneMethodRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
int32_t VFTableOffset = -1;
CV_DESERIALIZE(Reader, 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 make_error<CodeViewError>(cv_error_code::corrupt_record,
"Invalid VFTableOffset");
return Method;
}
Expected<MethodOverloadListRecord>
MethodOverloadListRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
std::vector<OneMethodRecord> Methods;
while (!Reader.empty()) {
const Layout *L = nullptr;
int32_t VFTableOffset = -1;
CV_DESERIALIZE(
Reader, 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 make_error<CodeViewError>(cv_error_code::corrupt_record,
"Invalid VFTableOffset");
}
return MethodOverloadListRecord(Methods);
}
Expected<OverloadedMethodRecord>
OverloadedMethodRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Reader, L, Name);
return OverloadedMethodRecord(L->MethodCount, L->MethList, Name);
}
Expected<DataMemberRecord>
DataMemberRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
uint64_t Offset;
StringRef Name;
CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Offset), Name);
return DataMemberRecord(L->Attrs.getAccess(), L->Type, Offset, Name);
}
Expected<StaticDataMemberRecord>
StaticDataMemberRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
StringRef Name;
CV_DESERIALIZE(Reader, L, Name);
return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name);
}
Expected<EnumeratorRecord>
EnumeratorRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
APSInt Value;
StringRef Name;
CV_DESERIALIZE(Reader, L, Value, Name);
return EnumeratorRecord(L->Attrs.getAccess(), Value, Name);
}
Expected<VFPtrRecord> VFPtrRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
if (auto EC = Reader.readObject(L))
return std::move(EC);
return VFPtrRecord(L->Type);
}
Expected<BaseClassRecord>
BaseClassRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
const Layout *L = nullptr;
uint64_t Offset;
CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Offset));
return BaseClassRecord(L->Attrs.getAccess(), L->BaseType, Offset);
}
Expected<VirtualBaseClassRecord>
VirtualBaseClassRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
uint64_t Offset;
uint64_t Index;
CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Offset), CV_NUMERIC_FIELD(Index));
return VirtualBaseClassRecord(Kind, L->Attrs.getAccess(), L->BaseType,
L->VBPtrType, Offset, Index);
}
Expected<ListContinuationRecord>
ListContinuationRecord::deserialize(TypeRecordKind Kind,
msf::StreamReader &Reader) {
const Layout *L = nullptr;
CV_DESERIALIZE(Reader, L);
return ListContinuationRecord(L->ContinuationIndex);
}
//===----------------------------------------------------------------------===//
// Type index remapping
//===----------------------------------------------------------------------===//

View File

@ -0,0 +1,417 @@
//===- TypeRecordMapping.cpp ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
using namespace llvm;
using namespace llvm::codeview;
#define error(X) \
if (auto EC = X) \
return EC;
namespace {
struct MapStringZ {
Error operator()(CodeViewRecordIO &IO, StringRef &S) const {
return IO.mapStringZ(S);
}
};
struct MapInteger {
template <typename T> Error operator()(CodeViewRecordIO &IO, T &N) const {
return IO.mapInteger(N);
}
};
struct MapEnum {
template <typename T> Error operator()(CodeViewRecordIO &IO, T &N) const {
return IO.mapEnum(N);
}
};
struct MapOneMethodRecord {
explicit MapOneMethodRecord(bool IsFromOverloadList)
: IsFromOverloadList(IsFromOverloadList) {}
Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const {
error(IO.mapInteger(Method.Attrs.Attrs));
if (IsFromOverloadList) {
uint16_t Padding = 0;
error(IO.mapInteger(Padding));
}
error(IO.mapInteger(Method.Type));
if (Method.isIntroducingVirtual()) {
error(IO.mapInteger(Method.VFTableOffset));
} else if (!IO.isWriting())
Method.VFTableOffset = -1;
if (!IsFromOverloadList)
error(IO.mapStringZ(Method.Name));
return Error::success();
}
private:
bool IsFromOverloadList;
};
}
static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name,
StringRef &UniqueName, bool HasUniqueName) {
error(IO.mapStringZ(Name));
if (HasUniqueName)
error(IO.mapStringZ(UniqueName));
return Error::success();
}
Error TypeRecordMapping::visitTypeBegin(CVType &CVR) {
error(IO.beginRecord(CVR.Type));
TypeKind = CVR.Type;
return Error::success();
}
Error TypeRecordMapping::visitTypeEnd(CVType &Record) {
error(IO.endRecord());
TypeKind.reset();
return Error::success();
}
Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) {
return Error::success();
}
Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) {
if (!IO.isWriting()) {
if (auto EC = IO.skipPadding())
return EC;
}
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) {
error(IO.mapInteger(Record.ModifiedType));
error(IO.mapEnum(Record.Modifiers));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
ProcedureRecord &Record) {
error(IO.mapInteger(Record.ReturnType));
error(IO.mapEnum(Record.CallConv));
error(IO.mapEnum(Record.Options));
error(IO.mapInteger(Record.ParameterCount));
error(IO.mapInteger(Record.ArgumentList));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
MemberFunctionRecord &Record) {
error(IO.mapInteger(Record.ReturnType));
error(IO.mapInteger(Record.ClassType));
error(IO.mapInteger(Record.ThisType));
error(IO.mapEnum(Record.CallConv));
error(IO.mapEnum(Record.Options));
error(IO.mapInteger(Record.ParameterCount));
error(IO.mapInteger(Record.ArgumentList));
error(IO.mapInteger(Record.ThisPointerAdjustment));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArgListRecord &Record) {
error(IO.mapVectorN<uint32_t>(Record.StringIndices, MapInteger()));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) {
error(IO.mapInteger(Record.ReferentType));
error(IO.mapInteger(Record.Attrs));
if (Record.isPointerToMember()) {
if (!IO.isWriting())
Record.MemberInfo.emplace();
MemberPointerInfo &M = *Record.MemberInfo;
error(IO.mapInteger(M.ContainingType));
error(IO.mapEnum(M.Representation));
}
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArrayRecord &Record) {
error(IO.mapInteger(Record.ElementType));
error(IO.mapInteger(Record.IndexType));
error(IO.mapEncodedInteger(Record.Size));
error(IO.mapStringZ(Record.Name));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) {
assert((CVR.Type == TypeLeafKind::LF_STRUCTURE) ||
(CVR.Type == TypeLeafKind::LF_CLASS) ||
(CVR.Type == TypeLeafKind::LF_INTERFACE));
error(IO.mapInteger(Record.MemberCount));
error(IO.mapEnum(Record.Options));
error(IO.mapInteger(Record.FieldList));
error(IO.mapInteger(Record.DerivationList));
error(IO.mapInteger(Record.VTableShape));
error(IO.mapEncodedInteger(Record.Size));
error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
Record.hasUniqueName()));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) {
error(IO.mapInteger(Record.MemberCount));
error(IO.mapEnum(Record.Options));
error(IO.mapInteger(Record.FieldList));
error(IO.mapEncodedInteger(Record.Size));
error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
Record.hasUniqueName()));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) {
error(IO.mapInteger(Record.MemberCount));
error(IO.mapEnum(Record.Options));
error(IO.mapInteger(Record.UnderlyingType));
error(IO.mapInteger(Record.FieldList));
error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
Record.hasUniqueName()));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, BitFieldRecord &Record) {
error(IO.mapInteger(Record.Type));
error(IO.mapInteger(Record.BitSize));
error(IO.mapInteger(Record.BitOffset));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
VFTableShapeRecord &Record) {
uint16_t Size;
if (IO.isWriting()) {
ArrayRef<VFTableSlotKind> Slots = Record.getSlots();
Size = Slots.size();
error(IO.mapInteger(Size));
for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) {
uint8_t Byte = static_cast<uint8_t>(Slots[SlotIndex]) << 4;
if ((SlotIndex + 1) < Slots.size()) {
Byte |= static_cast<uint8_t>(Slots[SlotIndex + 1]);
}
error(IO.mapInteger(Byte));
}
} else {
error(IO.mapInteger(Size));
for (uint16_t I = 0; I < Size; I += 2) {
uint8_t Byte;
error(IO.mapInteger(Byte));
Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte & 0xF));
if ((I + 1) < Size)
Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte >> 4));
}
}
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, VFTableRecord &Record) {
error(IO.mapInteger(Record.CompleteClass));
error(IO.mapInteger(Record.OverriddenVFTable));
error(IO.mapInteger(Record.VFPtrOffset));
uint32_t NamesLen = 0;
if (IO.isWriting()) {
for (auto Name : Record.MethodNames)
NamesLen += Name.size() + 1;
}
error(IO.mapInteger(NamesLen));
error(IO.mapVectorTail(Record.MethodNames, MapStringZ()));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, StringIdRecord &Record) {
error(IO.mapInteger(Record.Id));
error(IO.mapStringZ(Record.String));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
UdtSourceLineRecord &Record) {
error(IO.mapInteger(Record.UDT));
error(IO.mapInteger(Record.SourceFile));
error(IO.mapInteger(Record.LineNumber));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
UdtModSourceLineRecord &Record) {
error(IO.mapInteger(Record.UDT));
error(IO.mapInteger(Record.SourceFile));
error(IO.mapInteger(Record.LineNumber));
error(IO.mapInteger(Record.Module));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, FuncIdRecord &Record) {
error(IO.mapInteger(Record.ParentScope));
error(IO.mapInteger(Record.FunctionType));
error(IO.mapStringZ(Record.Name));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
MemberFuncIdRecord &Record) {
error(IO.mapInteger(Record.ClassType));
error(IO.mapInteger(Record.FunctionType));
error(IO.mapStringZ(Record.Name));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
BuildInfoRecord &Record) {
error(IO.mapVectorN<uint16_t>(Record.ArgIndices, MapInteger()));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
MethodOverloadListRecord &Record) {
// TODO: Split the list into multiple records if it's longer than 64KB, using
// a subrecord of TypeRecordKind::Index to chain the records together.
error(IO.mapVectorTail(Record.Methods, MapOneMethodRecord(true)));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
FieldListRecord &Record) {
error(IO.mapByteVectorTail(Record.Data));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
TypeServer2Record &Record) {
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
BaseClassRecord &Record) {
error(IO.mapInteger(Record.Attrs.Attrs));
error(IO.mapInteger(Record.Type));
error(IO.mapEncodedInteger(Record.Offset));
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
EnumeratorRecord &Record) {
error(IO.mapInteger(Record.Attrs.Attrs));
// FIXME: Handle full APInt such as __int128.
error(IO.mapEncodedInteger(Record.Value));
error(IO.mapStringZ(Record.Name));
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
DataMemberRecord &Record) {
error(IO.mapInteger(Record.Attrs.Attrs));
error(IO.mapInteger(Record.Type));
error(IO.mapEncodedInteger(Record.FieldOffset));
error(IO.mapStringZ(Record.Name));
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
OverloadedMethodRecord &Record) {
error(IO.mapInteger(Record.NumOverloads));
error(IO.mapInteger(Record.MethodList));
error(IO.mapStringZ(Record.Name));
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
OneMethodRecord &Record) {
MapOneMethodRecord Mapper(false);
return Mapper(IO, Record);
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
NestedTypeRecord &Record) {
uint16_t Padding = 0;
error(IO.mapInteger(Padding));
error(IO.mapInteger(Record.Type));
error(IO.mapStringZ(Record.Name));
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
StaticDataMemberRecord &Record) {
error(IO.mapInteger(Record.Attrs.Attrs));
error(IO.mapInteger(Record.Type));
error(IO.mapStringZ(Record.Name));
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
VirtualBaseClassRecord &Record) {
error(IO.mapInteger(Record.Attrs.Attrs));
error(IO.mapInteger(Record.BaseType));
error(IO.mapInteger(Record.VBPtrType));
error(IO.mapEncodedInteger(Record.VBPtrOffset));
error(IO.mapEncodedInteger(Record.VTableIndex));
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
VFPtrRecord &Record) {
uint16_t Padding = 0;
error(IO.mapInteger(Padding));
error(IO.mapInteger(Record.Type));
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
ListContinuationRecord &Record) {
uint16_t Padding = 0;
error(IO.mapInteger(Padding));
error(IO.mapInteger(Record.ContinuationIndex));
return Error::success();
}

View File

@ -84,14 +84,7 @@ private:
}
Error visitKnownRecordImpl(FieldListRecord &Record) {
// Don't do anything, this will get written in the call to visitTypeEnd().
TypeVisitorCallbackPipeline Pipeline;
TypeDeserializer Deserializer;
Pipeline.addCallbackToPipeline(Deserializer);
Pipeline.addCallbackToPipeline(*this);
CVTypeVisitor Visitor(Pipeline);
CVTypeVisitor Visitor(*this);
if (auto EC = Visitor.visitFieldListMemberStream(Record.Data))
return EC;

View File

@ -72,13 +72,7 @@ TypeIndex TypeTableBuilder::writeKnownType(const PointerRecord &Record) {
TypeRecordBuilder Builder(Record.getKind());
Builder.writeTypeIndex(Record.getReferentType());
uint32_t flags = static_cast<uint32_t>(Record.getOptions()) |
(Record.getSize() << PointerRecord::PointerSizeShift) |
(static_cast<uint32_t>(Record.getMode())
<< PointerRecord::PointerModeShift) |
(static_cast<uint32_t>(Record.getPointerKind())
<< PointerRecord::PointerKindShift);
Builder.writeUInt32(flags);
Builder.writeUInt32(Record.Attrs);
if (Record.isPointerToMember()) {
const MemberPointerInfo &M = Record.getMemberInfo();

View File

@ -25,6 +25,8 @@ Error StreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {
return Error::success();
}
Error StreamWriter::writeInteger(uint8_t Int) { return writeObject(Int); }
Error StreamWriter::writeInteger(uint16_t Int) {
return writeObject(support::ulittle16_t(Int));
}
@ -33,6 +35,24 @@ Error StreamWriter::writeInteger(uint32_t Int) {
return writeObject(support::ulittle32_t(Int));
}
Error StreamWriter::writeInteger(uint64_t Int) {
return writeObject(support::ulittle64_t(Int));
}
Error StreamWriter::writeInteger(int8_t Int) { return writeObject(Int); }
Error StreamWriter::writeInteger(int16_t Int) {
return writeObject(support::little16_t(Int));
}
Error StreamWriter::writeInteger(int32_t Int) {
return writeObject(support::little32_t(Int));
}
Error StreamWriter::writeInteger(int64_t Int) {
return writeObject(support::little64_t(Int));
}
Error StreamWriter::writeZeroString(StringRef Str) {
if (auto EC = writeFixedString(Str))
return EC;

View File

@ -31,27 +31,27 @@ YAML: - Kind: LF_FIELDLIST
YAML: FieldList:
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 1
YAML: Name: apartment
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 2
YAML: Name: single
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 3
YAML: Name: free
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 4
YAML: Name: neutral
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 5
YAML: Name: both
YAML: - Kind: LF_ENUM
@ -69,18 +69,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ]
YAML: FieldList: 0
YAML: Name: '__vc_attributes::threadingAttribute'
YAML: UniqueName: '.?AUthreadingAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 0
YAML: - Kind: LF_POINTER
YAML: Pointer:
YAML: ReferentType: 4100
YAML: PtrKind: Near32
YAML: Mode: Pointer
YAML: Options: [ None, Const ]
YAML: Size: 4
YAML: Attrs: 33802
YAML: - Kind: LF_ARGLIST
YAML: ArgList:
YAML: ArgIndices: [ 4099 ]
@ -108,15 +103,11 @@ YAML: - Kind: LF_METHODLIST
YAML: MethodOverloadList:
YAML: Methods:
YAML: - Type: 4103
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Type: 4104
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Kind: LF_FIELDLIST
@ -132,7 +123,7 @@ YAML: MethodList: 4105
YAML: Name: threadingAttribute
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4099
YAML: FieldOffset: 0
YAML: Name: value
@ -143,8 +134,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste
YAML: FieldList: 4106
YAML: Name: '__vc_attributes::threadingAttribute'
YAML: UniqueName: '.?AUthreadingAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 4
@ -152,17 +141,17 @@ YAML: - Kind: LF_FIELDLIST
YAML: FieldList:
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 0
YAML: Name: native
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 1
YAML: Name: com
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 2
YAML: Name: managed
YAML: - Kind: LF_ENUM
@ -180,18 +169,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ]
YAML: FieldList: 0
YAML: Name: '__vc_attributes::event_receiverAttribute'
YAML: UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 0
YAML: - Kind: LF_POINTER
YAML: Pointer:
YAML: ReferentType: 4110
YAML: PtrKind: Near32
YAML: Mode: Pointer
YAML: Options: [ None, Const ]
YAML: Size: 4
YAML: Attrs: 33802
YAML: - Kind: LF_ARGLIST
YAML: ArgList:
YAML: ArgIndices: [ 4109, 48 ]
@ -232,21 +216,15 @@ YAML: - Kind: LF_METHODLIST
YAML: MethodOverloadList:
YAML: Methods:
YAML: - Type: 4113
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Type: 4115
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Type: 4116
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Kind: LF_FIELDLIST
@ -262,13 +240,13 @@ YAML: MethodList: 4117
YAML: Name: event_receiverAttribute
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4109
YAML: FieldOffset: 0
YAML: Name: type
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 48
YAML: FieldOffset: 4
YAML: Name: layout_dependent
@ -279,8 +257,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste
YAML: FieldList: 4118
YAML: Name: '__vc_attributes::event_receiverAttribute'
YAML: UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 8
@ -288,17 +264,17 @@ YAML: - Kind: LF_FIELDLIST
YAML: FieldList:
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 0
YAML: Name: never
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 1
YAML: Name: allowed
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 2
YAML: Name: always
YAML: - Kind: LF_ENUM
@ -316,18 +292,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ]
YAML: FieldList: 0
YAML: Name: '__vc_attributes::aggregatableAttribute'
YAML: UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 0
YAML: - Kind: LF_POINTER
YAML: Pointer:
YAML: ReferentType: 4122
YAML: PtrKind: Near32
YAML: Mode: Pointer
YAML: Options: [ None, Const ]
YAML: Size: 4
YAML: Attrs: 33802
YAML: - Kind: LF_ARGLIST
YAML: ArgList:
YAML: ArgIndices: [ 4121 ]
@ -355,15 +326,11 @@ YAML: - Kind: LF_METHODLIST
YAML: MethodOverloadList:
YAML: Methods:
YAML: - Type: 4125
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Type: 4126
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Kind: LF_FIELDLIST
@ -379,7 +346,7 @@ YAML: MethodList: 4127
YAML: Name: aggregatableAttribute
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4121
YAML: FieldOffset: 0
YAML: Name: type
@ -390,8 +357,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste
YAML: FieldList: 4128
YAML: Name: '__vc_attributes::aggregatableAttribute'
YAML: UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 4
@ -407,12 +372,12 @@ YAML: - Kind: LF_FIELDLIST
YAML: FieldList:
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 0
YAML: Name: speed
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 1
YAML: Name: size
YAML: - Kind: LF_ENUM
@ -430,18 +395,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ]
YAML: FieldList: 0
YAML: Name: '__vc_attributes::event_sourceAttribute'
YAML: UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 0
YAML: - Kind: LF_POINTER
YAML: Pointer:
YAML: ReferentType: 4133
YAML: PtrKind: Near32
YAML: Mode: Pointer
YAML: Options: [ None, Const ]
YAML: Size: 4
YAML: Attrs: 33802
YAML: - Kind: LF_ARGLIST
YAML: ArgList:
YAML: ArgIndices: [ 4130 ]
@ -469,15 +429,11 @@ YAML: - Kind: LF_METHODLIST
YAML: MethodOverloadList:
YAML: Methods:
YAML: - Type: 4136
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Type: 4137
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Kind: LF_FIELDLIST
@ -497,19 +453,19 @@ YAML: MethodList: 4138
YAML: Name: event_sourceAttribute
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4130
YAML: FieldOffset: 0
YAML: Name: type
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4132
YAML: FieldOffset: 4
YAML: Name: optimize
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 48
YAML: FieldOffset: 8
YAML: Name: decorate
@ -520,8 +476,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste
YAML: FieldList: 4139
YAML: Name: '__vc_attributes::event_sourceAttribute'
YAML: UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 12
@ -529,32 +483,32 @@ YAML: - Kind: LF_FIELDLIST
YAML: FieldList:
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 1
YAML: Name: dll
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 2
YAML: Name: exe
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 3
YAML: Name: service
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 4
YAML: Name: unspecified
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 2
YAML: Name: EXE
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 3
YAML: Name: SERVICE
YAML: - Kind: LF_ENUM
@ -572,18 +526,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ]
YAML: FieldList: 0
YAML: Name: '__vc_attributes::moduleAttribute'
YAML: UniqueName: '.?AUmoduleAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 0
YAML: - Kind: LF_POINTER
YAML: Pointer:
YAML: ReferentType: 4143
YAML: PtrKind: Near32
YAML: Mode: Pointer
YAML: Options: [ None, Const ]
YAML: Size: 4
YAML: Attrs: 33802
YAML: - Kind: LF_MODIFIER
YAML: Modifier:
YAML: ModifiedType: 112
@ -591,10 +540,7 @@ YAML: Modifiers: [ None, Const ]
YAML: - Kind: LF_POINTER
YAML: Pointer:
YAML: ReferentType: 4145
YAML: PtrKind: Near32
YAML: Mode: Pointer
YAML: Options: [ None ]
YAML: Size: 4
YAML: Attrs: 32778
YAML: - Kind: LF_ARGLIST
YAML: ArgList:
YAML: ArgIndices: [ 4142, 4146, 4146, 4146, 116, 48, 4146, 116,
@ -636,21 +582,15 @@ YAML: - Kind: LF_METHODLIST
YAML: MethodOverloadList:
YAML: Methods:
YAML: - Type: 4148
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Type: 4150
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Type: 4151
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: ''
YAML: - Kind: LF_FIELDLIST
@ -666,91 +606,91 @@ YAML: MethodList: 4152
YAML: Name: moduleAttribute
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4142
YAML: FieldOffset: 0
YAML: Name: type
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4146
YAML: FieldOffset: 4
YAML: Name: name
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4146
YAML: FieldOffset: 8
YAML: Name: version
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4146
YAML: FieldOffset: 12
YAML: Name: uuid
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 116
YAML: FieldOffset: 16
YAML: Name: lcid
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 48
YAML: FieldOffset: 20
YAML: Name: control
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4146
YAML: FieldOffset: 24
YAML: Name: helpstring
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 116
YAML: FieldOffset: 28
YAML: Name: helpstringcontext
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4146
YAML: FieldOffset: 32
YAML: Name: helpstringdll
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4146
YAML: FieldOffset: 36
YAML: Name: helpfile
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 116
YAML: FieldOffset: 40
YAML: Name: helpcontext
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 48
YAML: FieldOffset: 44
YAML: Name: hidden
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 48
YAML: FieldOffset: 45
YAML: Name: restricted
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4146
YAML: FieldOffset: 48
YAML: Name: custom
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4146
YAML: FieldOffset: 52
YAML: Name: resource_name
@ -761,8 +701,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste
YAML: FieldList: 4153
YAML: Name: '__vc_attributes::moduleAttribute'
YAML: UniqueName: '.?AUmoduleAttribute@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 56
@ -770,152 +708,152 @@ YAML: - Kind: LF_FIELDLIST
YAML: FieldList:
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 0
YAML: Name: eAnyUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 1
YAML: Name: eCoClassUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 2
YAML: Name: eCOMInterfaceUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 6
YAML: Name: eInterfaceUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 8
YAML: Name: eMemberUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 16
YAML: Name: eMethodUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 32
YAML: Name: eInterfaceMethodUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 64
YAML: Name: eInterfaceMemberUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 128
YAML: Name: eCoClassMemberUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 256
YAML: Name: eCoClassMethodUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 768
YAML: Name: eGlobalMethodUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 1024
YAML: Name: eGlobalDataUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 2048
YAML: Name: eClassUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 4096
YAML: Name: eInterfaceParameterUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 12288
YAML: Name: eMethodParameterUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 16384
YAML: Name: eIDLModuleUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: -32768
YAML: Name: eAnonymousUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 65536
YAML: Name: eTypedefUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 131072
YAML: Name: eUnionUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 262144
YAML: Name: eEnumUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 524288
YAML: Name: eDefineTagUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 1048576
YAML: Name: eStructUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 2097152
YAML: Name: eLocalUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 4194304
YAML: Name: ePropertyUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 8388608
YAML: Name: eEventUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 16777216
YAML: Name: eTemplateUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 16777216
YAML: Name: eModuleUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 33554432
YAML: Name: eIllegalUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 67108864
YAML: Name: eAsynchronousUsage
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 4161535
YAML: Name: eAnyIDLUsage
YAML: - Kind: LF_ENUM
@ -933,18 +871,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ]
YAML: FieldList: 0
YAML: Name: '__vc_attributes::helper_attributes::usageAttribute'
YAML: UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 0
YAML: - Kind: LF_POINTER
YAML: Pointer:
YAML: ReferentType: 4157
YAML: PtrKind: Near32
YAML: Mode: Pointer
YAML: Options: [ None, Const ]
YAML: Size: 4
YAML: Attrs: 33802
YAML: - Kind: LF_ARGLIST
YAML: ArgList:
YAML: ArgIndices: [ 117 ]
@ -967,14 +900,12 @@ YAML: Name: usage_e
YAML: - Kind: LF_ONEMETHOD
YAML: OneMethod:
YAML: Type: 4160
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: usageAttribute
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 117
YAML: FieldOffset: 0
YAML: Name: value
@ -985,8 +916,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste
YAML: FieldList: 4161
YAML: Name: '__vc_attributes::helper_attributes::usageAttribute'
YAML: UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 4
@ -994,22 +923,22 @@ YAML: - Kind: LF_FIELDLIST
YAML: FieldList:
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 0
YAML: Name: eBoolean
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 1
YAML: Name: eInteger
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 2
YAML: Name: eFloat
YAML: - Kind: LF_ENUMERATE
YAML: Enumerator:
YAML: Access: Public
YAML: Attrs: 3
YAML: Value: 3
YAML: Name: eDouble
YAML: - Kind: LF_ENUM
@ -1027,18 +956,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ]
YAML: FieldList: 0
YAML: Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute'
YAML: UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 0
YAML: - Kind: LF_POINTER
YAML: Pointer:
YAML: ReferentType: 4165
YAML: PtrKind: Near32
YAML: Mode: Pointer
YAML: Options: [ None, Const ]
YAML: Size: 4
YAML: Attrs: 33802
YAML: - Kind: LF_ARGLIST
YAML: ArgList:
YAML: ArgIndices: [ 4164 ]
@ -1061,14 +985,12 @@ YAML: Name: type_e
YAML: - Kind: LF_ONEMETHOD
YAML: OneMethod:
YAML: Type: 4168
YAML: Kind: Vanilla
YAML: Options: [ None ]
YAML: Access: Public
YAML: Attrs: 3
YAML: VFTableOffset: -1
YAML: Name: v1_alttypeAttribute
YAML: - Kind: LF_MEMBER
YAML: DataMember:
YAML: Access: Public
YAML: Attrs: 3
YAML: Type: 4164
YAML: FieldOffset: 0
YAML: Name: type
@ -1079,8 +1001,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste
YAML: FieldList: 4169
YAML: Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute'
YAML: UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@'
YAML: Hfa: None
YAML: WinRTKind: None
YAML: DerivationList: 0
YAML: VTableShape: 0
YAML: Size: 4

View File

@ -300,8 +300,6 @@ void MappingTraits<ClassRecord>::mapping(IO &IO, ClassRecord &Class) {
IO.mapRequired("FieldList", Class.FieldList);
IO.mapRequired("Name", Class.Name);
IO.mapRequired("UniqueName", Class.UniqueName);
IO.mapRequired("Hfa", Class.Hfa);
IO.mapRequired("WinRTKind", Class.WinRTKind);
IO.mapRequired("DerivationList", Class.DerivationList);
IO.mapRequired("VTableShape", Class.VTableShape);
IO.mapRequired("Size", Class.Size);
@ -313,7 +311,6 @@ void MappingTraits<UnionRecord>::mapping(IO &IO, UnionRecord &Union) {
IO.mapRequired("FieldList", Union.FieldList);
IO.mapRequired("Name", Union.Name);
IO.mapRequired("UniqueName", Union.UniqueName);
IO.mapRequired("Hfa", Union.Hfa);
IO.mapRequired("Size", Union.Size);
}
@ -337,7 +334,6 @@ void MappingTraits<VFTableRecord>::mapping(IO &IO, VFTableRecord &VFT) {
IO.mapRequired("CompleteClass", VFT.CompleteClass);
IO.mapRequired("OverriddenVFTable", VFT.OverriddenVFTable);
IO.mapRequired("VFPtrOffset", VFT.VFPtrOffset);
IO.mapRequired("Name", VFT.Name);
IO.mapRequired("MethodNames", VFT.MethodNames);
}
@ -387,10 +383,7 @@ void MappingTraits<TypeServer2Record>::mapping(IO &IO, TypeServer2Record &TS) {
void MappingTraits<PointerRecord>::mapping(IO &IO, PointerRecord &Ptr) {
IO.mapRequired("ReferentType", Ptr.ReferentType);
IO.mapRequired("PtrKind", Ptr.PtrKind);
IO.mapRequired("Mode", Ptr.Mode);
IO.mapRequired("Options", Ptr.Options);
IO.mapRequired("Size", Ptr.Size);
IO.mapRequired("Attrs", Ptr.Attrs);
IO.mapOptional("MemberInfo", Ptr.MemberInfo);
}
@ -442,9 +435,7 @@ void MappingTraits<NestedTypeRecord>::mapping(IO &IO,
void MappingTraits<OneMethodRecord>::mapping(IO &IO, OneMethodRecord &Method) {
IO.mapRequired("Type", Method.Type);
IO.mapRequired("Kind", Method.Kind);
IO.mapRequired("Options", Method.Options);
IO.mapRequired("Access", Method.Access);
IO.mapRequired("Attrs", Method.Attrs.Attrs);
IO.mapRequired("VFTableOffset", Method.VFTableOffset);
IO.mapRequired("Name", Method.Name);
}
@ -457,7 +448,7 @@ void MappingTraits<OverloadedMethodRecord>::mapping(
}
void MappingTraits<DataMemberRecord>::mapping(IO &IO, DataMemberRecord &Field) {
IO.mapRequired("Access", Field.Access);
IO.mapRequired("Attrs", Field.Attrs.Attrs);
IO.mapRequired("Type", Field.Type);
IO.mapRequired("FieldOffset", Field.FieldOffset);
IO.mapRequired("Name", Field.Name);
@ -465,7 +456,7 @@ void MappingTraits<DataMemberRecord>::mapping(IO &IO, DataMemberRecord &Field) {
void MappingTraits<StaticDataMemberRecord>::mapping(
IO &IO, StaticDataMemberRecord &Field) {
IO.mapRequired("Access", Field.Access);
IO.mapRequired("Attrs", Field.Attrs.Attrs);
IO.mapRequired("Type", Field.Type);
IO.mapRequired("Name", Field.Name);
}
@ -475,20 +466,20 @@ void MappingTraits<VFPtrRecord>::mapping(IO &IO, VFPtrRecord &VFTable) {
}
void MappingTraits<EnumeratorRecord>::mapping(IO &IO, EnumeratorRecord &Enum) {
IO.mapRequired("Access", Enum.Access);
IO.mapRequired("Attrs", Enum.Attrs.Attrs);
IO.mapRequired("Value", Enum.Value);
IO.mapRequired("Name", Enum.Name);
}
void MappingTraits<BaseClassRecord>::mapping(IO &IO, BaseClassRecord &Base) {
IO.mapRequired("Access", Base.Access);
IO.mapRequired("Attrs", Base.Attrs.Attrs);
IO.mapRequired("Type", Base.Type);
IO.mapRequired("Offset", Base.Offset);
}
void MappingTraits<VirtualBaseClassRecord>::mapping(
IO &IO, VirtualBaseClassRecord &Base) {
IO.mapRequired("Access", Base.Access);
IO.mapRequired("Attrs", Base.Attrs.Attrs);
IO.mapRequired("BaseType", Base.BaseType);
IO.mapRequired("VBPtrType", Base.VBPtrType);
IO.mapRequired("VBPtrOffset", Base.VBPtrOffset);
@ -568,7 +559,10 @@ struct MappingContextTraits<pdb::yaml::PdbTpiFieldListRecord,
static void mapping(IO &IO, pdb::yaml::PdbTpiFieldListRecord &Obj,
pdb::yaml::SerializationContext &Context) {
codeview::TypeVisitorCallbackPipeline Pipeline;
codeview::TypeDeserializer Deserializer;
msf::ByteStream Data(Obj.Record.Data);
msf::StreamReader FieldReader(Data);
codeview::FieldListDeserializer Deserializer(FieldReader);
codeview::TypeSerializationVisitor Serializer(Context.FieldListBuilder,
Context.TypeTableBuilder);
pdb::TpiHashUpdater Hasher;