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

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

llvm-svn: 292665
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
index f3508d6..62c6fb4 100644
--- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -113,6 +113,9 @@
   if (auto EC = dumpStreamBytes())
     return EC;
 
+  if (auto EC = dumpStringTable())
+    return EC;
+
   if (auto EC = dumpInfoStream())
     return EC;
 
@@ -456,6 +459,28 @@
   return Error::success();
 }
 
+Error LLVMOutputStyle::dumpStringTable() {
+  if (!opts::raw::DumpStringTable)
+    return Error::success();
+
+  auto IS = File.getStringTable();
+  if (!IS)
+    return IS.takeError();
+
+  DictScope D(P, "String Table");
+  for (uint32_t I : IS->name_ids()) {
+    StringRef S = IS->getStringForID(I);
+    if (!S.empty()) {
+      llvm::SmallString<32> Str;
+      Str.append("'");
+      Str.append(S);
+      Str.append("'");
+      P.printString(Str);
+    }
+  }
+  return Error::success();
+}
+
 Error LLVMOutputStyle::dumpInfoStream() {
   if (!opts::raw::DumpHeaders)
     return Error::success();
@@ -472,6 +497,11 @@
   P.printHex("Signature", IS->getSignature());
   P.printNumber("Age", IS->getAge());
   P.printObject("Guid", IS->getGuid());
+  {
+    DictScope DD(P, "Named Streams");
+    for (const auto &S : IS->getNamedStreams().entries())
+      P.printObject(S.getKey(), S.getValue());
+  }
   return Error::success();
 }
 
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h
index 816d591..4aef78d 100644
--- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h
+++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h
@@ -34,6 +34,7 @@
   Error dumpGlobalsStream();
   Error dumpStreamBytes();
   Error dumpStreamBlocks();
+  Error dumpStringTable();
   Error dumpInfoStream();
   Error dumpTpiStream(uint32_t StreamIdx);
   Error dumpDbiStream();
diff --git a/llvm/tools/llvm-pdbdump/PdbYaml.cpp b/llvm/tools/llvm-pdbdump/PdbYaml.cpp
index 34e0611..6a32080 100644
--- a/llvm/tools/llvm-pdbdump/PdbYaml.cpp
+++ b/llvm/tools/llvm-pdbdump/PdbYaml.cpp
@@ -140,6 +140,7 @@
   IO.mapOptional("MSF", Obj.Headers);
   IO.mapOptional("StreamSizes", Obj.StreamSizes);
   IO.mapOptional("StreamMap", Obj.StreamMap);
+  IO.mapOptional("StringTable", Obj.StringTable);
   IO.mapOptional("PdbStream", Obj.PdbStream);
   IO.mapOptional("DbiStream", Obj.DbiStream);
   IO.mapOptionalWithContext("TpiStream", Obj.TpiStream, Obj.Allocator);
@@ -176,7 +177,6 @@
   IO.mapRequired("Guid", Obj.Guid);
   IO.mapRequired("Signature", Obj.Signature);
   IO.mapRequired("Version", Obj.Version);
-  IO.mapRequired("NamedStreams", Obj.NamedStreams);
 }
 
 void MappingTraits<PdbDbiStream>::mapping(IO &IO, PdbDbiStream &Obj) {
diff --git a/llvm/tools/llvm-pdbdump/PdbYaml.h b/llvm/tools/llvm-pdbdump/PdbYaml.h
index 398186f..4bb9e89 100644
--- a/llvm/tools/llvm-pdbdump/PdbYaml.h
+++ b/llvm/tools/llvm-pdbdump/PdbYaml.h
@@ -107,6 +107,8 @@
   Optional<PdbTpiStream> TpiStream;
   Optional<PdbTpiStream> IpiStream;
 
+  Optional<std::vector<StringRef>> StringTable;
+
   BumpPtrAllocator &Allocator;
 };
 }
diff --git a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
index 3f2733d..f7ad328 100644
--- a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
@@ -45,6 +45,9 @@
   if (auto EC = dumpStreamDirectory())
     return EC;
 
+  if (auto EC = dumpStringTable())
+    return EC;
+
   if (auto EC = dumpPDBStream())
     return EC;
 
@@ -83,6 +86,24 @@
   return Error::success();
 }
 
+Error YAMLOutputStyle::dumpStringTable() {
+  if (!opts::pdb2yaml::StringTable)
+    return Error::success();
+
+  Obj.StringTable.emplace();
+  auto ExpectedST = File.getStringTable();
+  if (!ExpectedST)
+    return ExpectedST.takeError();
+
+  const auto &ST = ExpectedST.get();
+  for (auto ID : ST.name_ids()) {
+    StringRef S = ST.getStringForID(ID);
+    if (!S.empty())
+      Obj.StringTable->push_back(S);
+  }
+  return Error::success();
+}
+
 Error YAMLOutputStyle::dumpStreamMetadata() {
   if (!opts::pdb2yaml::StreamMetadata)
     return Error::success();
@@ -122,12 +143,6 @@
   Obj.PdbStream->Guid = InfoS.getGuid();
   Obj.PdbStream->Signature = InfoS.getSignature();
   Obj.PdbStream->Version = InfoS.getVersion();
-  for (auto &NS : InfoS.named_streams()) {
-    yaml::NamedStreamMapping Mapping;
-    Mapping.StreamName = NS.getKey();
-    Mapping.StreamNumber = NS.getValue();
-    Obj.PdbStream->NamedStreams.push_back(Mapping);
-  }
 
   return Error::success();
 }
diff --git a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
index 3cd603a..db9868d 100644
--- a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
+++ b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
@@ -26,6 +26,7 @@
   Error dump() override;
 
 private:
+  Error dumpStringTable();
   Error dumpFileHeaders();
   Error dumpStreamMetadata();
   Error dumpStreamDirectory();
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
index 762af6d..ccab7fe 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -50,6 +50,7 @@
 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
 #include "llvm/DebugInfo/PDB/Raw/RawSession.h"
+#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
 #include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
 #include "llvm/Support/COM.h"
@@ -232,6 +233,9 @@
                        cl::cat(SymbolOptions), cl::sub(RawSubcommand));
 
 // MISCELLANEOUS OPTIONS
+cl::opt<bool> DumpStringTable("string-table", cl::desc("dump PDB String Table"),
+                              cl::cat(MiscOptions), cl::sub(RawSubcommand));
+
 cl::opt<bool> DumpSectionContribs("section-contribs",
                                   cl::desc("dump section contributions"),
                                   cl::cat(MiscOptions), cl::sub(RawSubcommand));
@@ -279,6 +283,10 @@
 cl::opt<bool> PdbStream("pdb-stream",
                         cl::desc("Dump the PDB Stream (Stream 1)"),
                         cl::sub(PdbToYamlSubcommand), cl::init(false));
+
+cl::opt<bool> StringTable("string-table", cl::desc("Dump the PDB String Table"),
+                          cl::sub(PdbToYamlSubcommand), cl::init(false));
+
 cl::opt<bool> DbiStream("dbi-stream",
                         cl::desc("Dump the DBI Stream (Stream 2)"),
                         cl::sub(PdbToYamlSubcommand), cl::init(false));
@@ -345,14 +353,18 @@
   for (uint32_t I = 0; I < kSpecialStreamCount; ++I)
     ExitOnErr(Builder.getMsfBuilder().addStream(0));
 
+  if (YamlObj.StringTable.hasValue()) {
+    auto &Strings = Builder.getStringTableBuilder();
+    for (auto S : *YamlObj.StringTable)
+      Strings.insert(S);
+  }
+
   if (YamlObj.PdbStream.hasValue()) {
     auto &InfoBuilder = Builder.getInfoBuilder();
     InfoBuilder.setAge(YamlObj.PdbStream->Age);
     InfoBuilder.setGuid(YamlObj.PdbStream->Guid);
     InfoBuilder.setSignature(YamlObj.PdbStream->Signature);
     InfoBuilder.setVersion(YamlObj.PdbStream->Version);
-    for (auto &NM : YamlObj.PdbStream->NamedStreams)
-      InfoBuilder.getNamedStreamsBuilder().set(NM.StreamName, NM.StreamNumber);
   }
 
   if (YamlObj.DbiStream.hasValue()) {
@@ -579,6 +591,7 @@
       opts::raw::DumpSectionContribs = true;
       opts::raw::DumpLineInfo = true;
       opts::raw::DumpFpo = true;
+      opts::raw::DumpStringTable = true;
     }
 
     if (opts::raw::CompactRecords &&
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
index 869ebf2..d4f082c 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
@@ -64,12 +64,14 @@
 extern llvm::cl::opt<bool> DumpSymRecordBytes;
 extern llvm::cl::opt<bool> DumpSectionHeaders;
 extern llvm::cl::opt<bool> DumpFpo;
+extern llvm::cl::opt<bool> DumpStringTable;
 }
 
 namespace pdb2yaml {
 extern llvm::cl::opt<bool> NoFileHeaders;
 extern llvm::cl::opt<bool> StreamMetadata;
 extern llvm::cl::opt<bool> StreamDirectory;
+extern llvm::cl::opt<bool> StringTable;
 extern llvm::cl::opt<bool> PdbStream;
 extern llvm::cl::opt<bool> DbiStream;
 extern llvm::cl::opt<bool> DbiModuleInfo;