[pdb] Write the Named Stream mapping to Yaml and binary.

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

llvm-svn: 292665
diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
index 9334d2a..9abcfbf 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
@@ -75,3 +75,7 @@
 uint32_t InfoStream::getAge() const { return Age; }
 
 PDB_UniqueId InfoStream::getGuid() const { return Guid; }
+
+const NamedStreamMap &InfoStream::getNamedStreams() const {
+  return NamedStreams;
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
index 4485c83..4d8eb85 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
@@ -13,6 +13,8 @@
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/MSF/StreamWriter.h"
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Raw/NamedStreamMap.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
 #include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
 
@@ -21,8 +23,10 @@
 using namespace llvm::msf;
 using namespace llvm::pdb;
 
-InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf)
-    : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0) {}
+InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf,
+                                     NamedStreamMap &NamedStreams)
+    : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0),
+      NamedStreams(NamedStreams) {}
 
 void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
 
@@ -32,10 +36,6 @@
 
 void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; }
 
-NamedStreamMap &InfoStreamBuilder::getNamedStreamsBuilder() {
-  return NamedStreams;
-}
-
 Error InfoStreamBuilder::finalizeMsfLayout() {
   uint32_t Length = sizeof(InfoStreamHeader) + NamedStreams.finalize();
   if (auto EC = Msf.setStreamSize(StreamPDB, Length))
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
index 6fec0e3..cfd5ba6 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
@@ -20,6 +20,7 @@
 #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
 #include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
 
@@ -44,7 +45,7 @@
 
 InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
   if (!Info)
-    Info = llvm::make_unique<InfoStreamBuilder>(*Msf);
+    Info = llvm::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
   return *Info;
 }
 
@@ -66,7 +67,26 @@
   return *Ipi;
 }
 
-Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() const {
+StringTableBuilder &PDBFileBuilder::getStringTableBuilder() { return Strings; }
+
+Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
+  auto ExpectedStream = Msf->addStream(Size);
+  if (!ExpectedStream)
+    return ExpectedStream.takeError();
+  NamedStreams.set(Name, *ExpectedStream);
+  return Error::success();
+}
+
+Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
+  uint32_t StringTableSize = Strings.finalize();
+
+  if (auto EC = addNamedStream("/names", StringTableSize))
+    return std::move(EC);
+  if (auto EC = addNamedStream("/LinkInfo", 0))
+    return std::move(EC);
+  if (auto EC = addNamedStream("/src/headerblock", 0))
+    return std::move(EC);
+
   if (Info) {
     if (auto EC = Info->finalizeMsfLayout())
       return std::move(EC);
@@ -124,6 +144,16 @@
       return EC;
   }
 
+  uint32_t StringTableStreamNo = 0;
+  if (!NamedStreams.get("/names", StringTableStreamNo))
+    return llvm::make_error<pdb::RawError>(raw_error_code::no_stream);
+
+  auto NS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
+                                                           StringTableStreamNo);
+  StreamWriter NSWriter(*NS);
+  if (auto EC = Strings.commit(NSWriter))
+    return EC;
+
   if (Info) {
     if (auto EC = Info->commit(Layout, Buffer))
       return EC;
diff --git a/llvm/lib/DebugInfo/PDB/Raw/StringTableBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/StringTableBuilder.cpp
index 7284582..5ae7447 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/StringTableBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/StringTableBuilder.cpp
@@ -38,16 +38,17 @@
   return (NumStrings + 1) * 1.25;
 }
 
-uint32_t StringTableBuilder::calculateSerializedLength() const {
+uint32_t StringTableBuilder::finalize() {
   uint32_t Size = 0;
   Size += sizeof(StringTableHeader);
   Size += StringSize;
-  Size += 4; // Hash table begins with 4-byte size field.
+  Size += sizeof(uint32_t); // Hash table begins with 4-byte size field.
 
   uint32_t BucketCount = computeBucketCount(Strings.size());
-  Size += BucketCount * 4;
+  Size += BucketCount * sizeof(uint32_t);
 
-  Size += 4; // The /names stream ends with the number of strings.
+  Size +=
+      sizeof(uint32_t); // The /names stream ends with the number of strings.
   return Size;
 }