aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-09-09 17:46:17 +0000
committerZachary Turner <zturner@google.com>2016-09-09 17:46:17 +0000
commitc6d54da891b5b7f6634d41a1c59eab4d5e226711 (patch)
tree5d14cccb65e640255902a1280afc4ff91ee13245 /llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp
parentd938dfb308fe288605c6a24773ab77db8334c54a (diff)
downloadllvm-c6d54da891b5b7f6634d41a1c59eab4d5e226711.zip
llvm-c6d54da891b5b7f6634d41a1c59eab4d5e226711.tar.gz
llvm-c6d54da891b5b7f6634d41a1c59eab4d5e226711.tar.bz2
[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
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp')
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp95
1 files changed, 95 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp
new file mode 100644
index 0000000..5591df59
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp
@@ -0,0 +1,95 @@
+#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
+
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/MSF/StreamWriter.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
+#include "llvm/Support/Allocator.h"
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+using namespace llvm::support;
+
+TpiStreamBuilder::TpiStreamBuilder(BumpPtrAllocator &Allocator)
+ : Allocator(Allocator), Header(nullptr) {}
+
+TpiStreamBuilder::~TpiStreamBuilder() {}
+
+void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) {
+ VerHeader = Version;
+}
+
+void TpiStreamBuilder::addTypeRecord(const codeview::CVType &Record) {
+ TypeRecords.push_back(Record);
+ TypeRecordStream.setItems(TypeRecords);
+}
+
+Error TpiStreamBuilder::finalize() {
+ if (Header)
+ return Error::success();
+
+ TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>();
+
+ uint32_t Count = TypeRecords.size();
+
+ H->Version = *VerHeader;
+ H->HeaderSize = sizeof(TpiStreamHeader);
+ H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex;
+ H->TypeIndexEnd = H->TypeIndexBegin + Count;
+ H->TypeRecordBytes = TypeRecordStream.getLength();
+
+ H->HashStreamIndex = kInvalidStreamIndex;
+ H->HashAuxStreamIndex = kInvalidStreamIndex;
+ H->HashKeySize = sizeof(ulittle32_t);
+ H->NumHashBuckets = MinTpiHashBuckets;
+
+ H->HashValueBuffer.Length = 0;
+ H->HashAdjBuffer.Length = 0;
+ H->IndexOffsetBuffer.Length = 0;
+
+ Header = H;
+ return Error::success();
+}
+
+uint32_t TpiStreamBuilder::calculateSerializedLength() const {
+ return sizeof(TpiStreamHeader) + TypeRecordStream.getLength();
+}
+
+Expected<std::unique_ptr<TpiStream>>
+TpiStreamBuilder::build(PDBFile &File, const msf::WritableStream &Buffer) {
+ if (!VerHeader.hasValue())
+ return make_error<RawError>(raw_error_code::unspecified,
+ "Missing TPI Stream Version");
+ if (auto EC = finalize())
+ return std::move(EC);
+
+ auto StreamData = MappedBlockStream::createIndexedStream(File.getMsfLayout(),
+ Buffer, StreamTPI);
+ auto Tpi = llvm::make_unique<TpiStream>(File, std::move(StreamData));
+ Tpi->Header = Header;
+ Tpi->TypeRecords = VarStreamArray<codeview::CVType>(TypeRecordStream);
+ return std::move(Tpi);
+}
+
+Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
+ const msf::WritableStream &Buffer) {
+ if (auto EC = finalize())
+ return EC;
+
+ auto InfoS =
+ WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamTPI);
+
+ StreamWriter Writer(*InfoS);
+ if (auto EC = Writer.writeObject(*Header))
+ return EC;
+
+ auto RecordArray = VarStreamArray<codeview::CVType>(TypeRecordStream);
+ if (auto EC = Writer.writeArray(RecordArray))
+ return EC;
+
+ return Error::success();
+}