[pdb] Write the IPI stream.

The IPI stream is structurally identical to the TPI stream, but it
contains different record types.  So we just re-use the TPI writing
code.

llvm-svn: 281638
diff --git a/llvm/tools/llvm-pdbdump/PdbYaml.cpp b/llvm/tools/llvm-pdbdump/PdbYaml.cpp
index 3975bdf..fd1016b 100644
--- a/llvm/tools/llvm-pdbdump/PdbYaml.cpp
+++ b/llvm/tools/llvm-pdbdump/PdbYaml.cpp
@@ -138,6 +138,7 @@
   IO.mapOptional("PdbStream", Obj.PdbStream);
   IO.mapOptional("DbiStream", Obj.DbiStream);
   IO.mapOptionalWithContext("TpiStream", Obj.TpiStream, Obj.Allocator);
+  IO.mapOptionalWithContext("IpiStream", Obj.IpiStream, Obj.Allocator);
 }
 
 void MappingTraits<MSFHeaders>::mapping(IO &IO, MSFHeaders &Obj) {
diff --git a/llvm/tools/llvm-pdbdump/PdbYaml.h b/llvm/tools/llvm-pdbdump/PdbYaml.h
index 7ae1861..ffa194d 100644
--- a/llvm/tools/llvm-pdbdump/PdbYaml.h
+++ b/llvm/tools/llvm-pdbdump/PdbYaml.h
@@ -93,6 +93,7 @@
   Optional<PdbInfoStream> PdbStream;
   Optional<PdbDbiStream> DbiStream;
   Optional<PdbTpiStream> TpiStream;
+  Optional<PdbTpiStream> IpiStream;
 
   BumpPtrAllocator &Allocator;
 };
diff --git a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
index 0991d5c..ee1875c 100644
--- a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp
@@ -50,6 +50,9 @@
   if (auto EC = dumpTpiStream())
     return EC;
 
+  if (auto EC = dumpIpiStream())
+    return EC;
+
   flush();
   return Error::success();
 }
@@ -179,6 +182,26 @@
   return Error::success();
 }
 
+Error YAMLOutputStyle::dumpIpiStream() {
+  if (!opts::pdb2yaml::IpiStream)
+    return Error::success();
+
+  auto IpiS = File.getPDBIpiStream();
+  if (!IpiS)
+    return IpiS.takeError();
+
+  auto &IS = IpiS.get();
+  Obj.IpiStream.emplace();
+  Obj.IpiStream->Version = IS.getTpiVersion();
+  for (auto &Record : IS.types(nullptr)) {
+    yaml::PdbTpiRecord R;
+    R.Record = Record;
+    Obj.IpiStream->Records.push_back(R);
+  }
+
+  return Error::success();
+}
+
 void YAMLOutputStyle::flush() {
   Out << Obj;
   outs().flush();
diff --git a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
index 3204bdd..540dee4 100644
--- a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
+++ b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
@@ -32,6 +32,7 @@
   Error dumpPDBStream();
   Error dumpDbiStream();
   Error dumpTpiStream();
+  Error dumpIpiStream();
 
   void flush();
 
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
index d1858f0..ca46660 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -290,6 +290,10 @@
                         cl::desc("Dump the TPI Stream (Stream 3)"),
                         cl::sub(PdbToYamlSubcommand), cl::init(false));
 
+cl::opt<bool> IpiStream("ipi-stream",
+                        cl::desc("Dump the IPI Stream (Stream 5)"),
+                        cl::sub(PdbToYamlSubcommand), cl::init(false));
+
 cl::list<std::string> InputFilename(cl::Positional,
                                     cl::desc("<input PDB file>"), cl::Required,
                                     cl::sub(PdbToYamlSubcommand));
@@ -371,6 +375,13 @@
       TpiBuilder.addTypeRecord(R.Record);
   }
 
+  if (YamlObj.IpiStream.hasValue()) {
+    auto &IpiBuilder = Builder.getIpiBuilder();
+    IpiBuilder.setVersionHeader(YamlObj.IpiStream->Version);
+    for (const auto &R : YamlObj.IpiStream->Records)
+      IpiBuilder.addTypeRecord(R.Record);
+  }
+
   ExitOnErr(Builder.commit(*FileByteStream));
 }
 
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
index 74ce077..8f05ca7 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
@@ -73,6 +73,7 @@
 extern llvm::cl::opt<bool> DbiModuleInfo;
 extern llvm::cl::opt<bool> DbiModuleSourceFileInfo;
 extern llvm::cl::opt<bool> TpiStream;
+extern llvm::cl::opt<bool> IpiStream;
 extern llvm::cl::list<std::string> InputFilename;
 }
 }