Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[pdb] Write PDB TPI Stream from Yaml.
This writes the full sequence of type records described in Yaml to the TPI stream of the PDB file. Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D24316 llvm-svn: 281063
- Loading branch information
Zachary Turner
committed
Sep 9, 2016
1 parent
d938dfb
commit c6d54da
Showing
30 changed files
with
635 additions
and
148 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
llvm/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
//===- TypeSerializationVisitor.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_TYPESERIALIZATIONVISITOR_H | ||
#define LLVM_DEBUGINFO_CODEVIEW_TYPESERIALIZATIONVISITOR_H | ||
|
||
#include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h" | ||
#include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h" | ||
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" | ||
|
||
#include "llvm/ADT/StringRef.h" | ||
|
||
namespace llvm { | ||
namespace codeview { | ||
|
||
class TypeSerializationVisitor : public TypeVisitorCallbacks { | ||
public: | ||
TypeSerializationVisitor(FieldListRecordBuilder &FieldListBuilder, | ||
MemoryTypeTableBuilder &TypeTableBuilder) | ||
: FieldListBuilder(FieldListBuilder), TypeTableBuilder(TypeTableBuilder) { | ||
} | ||
|
||
virtual Expected<TypeLeafKind> visitTypeBegin(const CVType &Record) override { | ||
if (Record.Type == TypeLeafKind::LF_FIELDLIST) | ||
FieldListBuilder.reset(); | ||
return Record.Type; | ||
} | ||
|
||
virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override { | ||
if (Record.Type == TypeLeafKind::LF_FIELDLIST) | ||
TypeTableBuilder.writeFieldList(FieldListBuilder); | ||
return Error::success(); | ||
} | ||
|
||
#define TYPE_RECORD(EnumName, EnumVal, Name) \ | ||
virtual Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \ | ||
Name##Record &Record) override { \ | ||
visitKnownRecordImpl(Record); \ | ||
return Error::success(); \ | ||
} | ||
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) | ||
#define MEMBER_RECORD(EnumName, EnumVal, Name) \ | ||
virtual Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR, \ | ||
Name##Record &Record) override { \ | ||
visitMemberRecordImpl(Record); \ | ||
return Error::success(); \ | ||
} | ||
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) | ||
#include "llvm/DebugInfo/CodeView/TypeRecords.def" | ||
|
||
private: | ||
template <typename RecordKind> void visitKnownRecordImpl(RecordKind &Record) { | ||
TypeTableBuilder.writeKnownType(Record); | ||
} | ||
template <typename RecordKind> | ||
void visitMemberRecordImpl(RecordKind &Record) { | ||
FieldListBuilder.writeMemberType(Record); | ||
} | ||
|
||
void visitKnownRecordImpl(FieldListRecord &FieldList) {} | ||
|
||
FieldListRecordBuilder &FieldListBuilder; | ||
MemoryTypeTableBuilder &TypeTableBuilder; | ||
}; | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
//===- SequencedItemStream.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_MSF_SEQUENCEDITEMSTREAM_H | ||
#define LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H | ||
|
||
#include "llvm/ADT/ArrayRef.h" | ||
#include "llvm/DebugInfo/MSF/MSFError.h" | ||
#include "llvm/DebugInfo/MSF/StreamInterface.h" | ||
#include "llvm/Support/Error.h" | ||
#include <cstdint> | ||
#include <memory> | ||
#include <type_traits> | ||
|
||
namespace llvm { | ||
namespace msf { | ||
template <typename T> struct SequencedItemTraits { | ||
static size_t length(const T &Item) = delete; | ||
static ArrayRef<uint8_t> bytes(const T &Item) = delete; | ||
}; | ||
|
||
/// SequencedItemStream represents a sequence of objects stored in a | ||
/// standard container but for which it is useful to view as a stream of | ||
/// contiguous bytes. An example of this might be if you have a std::vector | ||
/// of TPI records, where each record contains a byte sequence that | ||
/// represents that one record serialized, but where each consecutive item | ||
/// might not be allocated immediately after the previous item. Using a | ||
/// SequencedItemStream, we can adapt the VarStreamArray class to trivially | ||
/// extract one item at a time, allowing the data to be used anywhere a | ||
/// VarStreamArray could be used. | ||
template <typename T, typename Traits = SequencedItemTraits<T>> | ||
class SequencedItemStream : public ReadableStream { | ||
public: | ||
SequencedItemStream() {} | ||
|
||
Error readBytes(uint32_t Offset, uint32_t Size, | ||
ArrayRef<uint8_t> &Buffer) const override { | ||
auto ExpectedIndex = translateOffsetIndex(Offset); | ||
if (!ExpectedIndex) | ||
return ExpectedIndex.takeError(); | ||
const auto &Item = Items[*ExpectedIndex]; | ||
if (Size > Traits::length(Item)) | ||
return make_error<MSFError>(msf_error_code::insufficient_buffer); | ||
Buffer = Traits::bytes(Item).take_front(Size); | ||
return Error::success(); | ||
} | ||
|
||
Error readLongestContiguousChunk(uint32_t Offset, | ||
ArrayRef<uint8_t> &Buffer) const override { | ||
auto ExpectedIndex = translateOffsetIndex(Offset); | ||
if (!ExpectedIndex) | ||
return ExpectedIndex.takeError(); | ||
Buffer = Traits::bytes(Items[*ExpectedIndex]); | ||
return Error::success(); | ||
} | ||
|
||
void setItems(ArrayRef<T> ItemArray) { Items = ItemArray; } | ||
|
||
uint32_t getLength() const override { | ||
uint32_t Size = 0; | ||
for (const auto &Item : Items) | ||
Size += Traits::length(Item); | ||
return Size; | ||
} | ||
|
||
private: | ||
Expected<uint32_t> translateOffsetIndex(uint32_t Offset) const { | ||
uint32_t CurrentOffset = 0; | ||
uint32_t CurrentIndex = 0; | ||
for (const auto &Item : Items) { | ||
if (CurrentOffset >= Offset) | ||
break; | ||
CurrentOffset += Traits::length(Item); | ||
++CurrentIndex; | ||
} | ||
if (CurrentOffset != Offset) | ||
return make_error<MSFError>(msf_error_code::insufficient_buffer); | ||
return CurrentIndex; | ||
} | ||
ArrayRef<T> Items; | ||
}; | ||
} // end namespace msf | ||
} // end namespace llvm | ||
|
||
#endif // LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
//===- TpiStreamBuilder.h - PDB Tpi Stream Creation -------------*- 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_PDB_RAW_PDBTPISTREAMBUILDER_H | ||
#define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAMBUILDER_H | ||
|
||
#include "llvm/ADT/Optional.h" | ||
#include "llvm/DebugInfo/CodeView/TypeRecord.h" | ||
#include "llvm/DebugInfo/MSF/ByteStream.h" | ||
#include "llvm/DebugInfo/MSF/SequencedItemStream.h" | ||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" | ||
#include "llvm/Support/Allocator.h" | ||
#include "llvm/Support/Error.h" | ||
|
||
#include <vector> | ||
|
||
namespace llvm { | ||
namespace codeview { | ||
class TypeRecord; | ||
} | ||
namespace msf { | ||
struct MSFLayout; | ||
class ReadableStreamRef; | ||
class WritableStream; | ||
|
||
template <> struct SequencedItemTraits<llvm::codeview::CVType> { | ||
static size_t length(const codeview::CVType &Item) { return Item.Length; } | ||
static ArrayRef<uint8_t> bytes(const codeview::CVType &Item) { | ||
return Item.RawData; | ||
} | ||
}; | ||
} | ||
namespace pdb { | ||
class PDBFile; | ||
class TpiStream; | ||
struct TpiStreamHeader; | ||
|
||
class TpiStreamBuilder { | ||
public: | ||
explicit TpiStreamBuilder(BumpPtrAllocator &Allocator); | ||
~TpiStreamBuilder(); | ||
|
||
TpiStreamBuilder(const TpiStreamBuilder &) = delete; | ||
TpiStreamBuilder &operator=(const TpiStreamBuilder &) = delete; | ||
|
||
void setVersionHeader(PdbRaw_TpiVer Version); | ||
void addTypeRecord(const codeview::CVType &Record); | ||
|
||
Expected<std::unique_ptr<TpiStream>> build(PDBFile &File, | ||
const msf::WritableStream &Buffer); | ||
|
||
Error commit(const msf::MSFLayout &Layout, const msf::WritableStream &Buffer); | ||
|
||
uint32_t calculateSerializedLength() const; | ||
|
||
private: | ||
Error finalize(); | ||
|
||
BumpPtrAllocator &Allocator; | ||
|
||
Optional<PdbRaw_TpiVer> VerHeader; | ||
std::vector<codeview::CVType> TypeRecords; | ||
msf::SequencedItemStream<codeview::CVType> TypeRecordStream; | ||
|
||
const TpiStreamHeader *Header; | ||
}; | ||
} | ||
} | ||
|
||
#endif |
Oops, something went wrong.