[llvm] [llvm-pdbutil] Support `--docnum` for yaml2pdb (PR #207058)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 1 11:54:59 PDT 2026


https://github.com/Nerixyz created https://github.com/llvm/llvm-project/pull/207058

I saw that yaml2obj has this option to select the nth yaml document. This makes it easy to group multiple outputs together. For example a COFF yaml + PDB yaml in one file. 

As a semi-related change, I also declared the yaml2pdb options in `llvm-pdbutil.h`. clang-tidy complains about them being only in the source file (could be static in that case).

>From 2a263e9b745310ffef578771b9cf034dc1213886 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Wed, 1 Jul 2026 20:45:47 +0200
Subject: [PATCH] [llvm-pdbutil] Support `--docnum` for yaml2pdb

---
 llvm/test/tools/llvm-pdbutil/opt-docnum.test | 60 ++++++++++++++++++++
 llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp     | 18 +++++-
 llvm/tools/llvm-pdbutil/llvm-pdbutil.h       |  6 ++
 3 files changed, 81 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/tools/llvm-pdbutil/opt-docnum.test

diff --git a/llvm/test/tools/llvm-pdbutil/opt-docnum.test b/llvm/test/tools/llvm-pdbutil/opt-docnum.test
new file mode 100644
index 0000000000000..9d3e5e2d2830e
--- /dev/null
+++ b/llvm/test/tools/llvm-pdbutil/opt-docnum.test
@@ -0,0 +1,60 @@
+# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t-first-default.pdb
+# RUN: llvm-pdbutil dump --publics %t-first-default.pdb | FileCheck --check-prefix=CHECK-FIRST %s
+
+# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t-first.pdb --docnum=1
+# RUN: llvm-pdbutil dump --publics %t-first.pdb | FileCheck --check-prefix=CHECK-FIRST %s
+
+# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t-second.pdb --docnum=2
+# RUN: llvm-pdbutil dump --publics %t-second.pdb | FileCheck --check-prefix=CHECK-SECOND %s
+
+# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t-third.pdb --docnum=3
+# RUN: llvm-pdbutil dump --publics %t-third.pdb | FileCheck --check-prefix=CHECK-THIRD %s
+
+# RUN: not llvm-pdbutil yaml2pdb %s --pdb=%t-err.pdb --docnum=4 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
+
+# CHECK-FIRST: S_PUB32 [size = 24] `firstDoc`
+# CHECK-FIRST-NOT: secondDoc
+# CHECK-FIRST-NOT: thirdDoc
+
+# CHECK-SECOND-NOT: firstDoc
+# CHECK-SECOND: S_PUB32 [size = 24] `secondDoc`
+# CHECK-SECOND-NOT: thirdDoc
+
+# CHECK-THIRD-NOT: firstDoc
+# CHECK-THIRD-NOT: secondDoc
+# CHECK-THIRD: S_PUB32 [size = 24] `thirdDoc`
+
+# CHECK-ERR: cannot find the 4th document
+
+---
+PublicsStream:
+  Records:
+    - Kind:            S_PUB32
+      PublicSym32:
+        Flags:           [ Function ]
+        Offset:          0
+        Segment:         1
+        Name:            'firstDoc'
+...
+
+---
+PublicsStream:
+  Records:
+    - Kind:            S_PUB32
+      PublicSym32:
+        Flags:           [ Function ]
+        Offset:          0
+        Segment:         1
+        Name:            'secondDoc'
+...
+
+---
+PublicsStream:
+  Records:
+    - Kind:            S_PUB32
+      PublicSym32:
+        Flags:           [ Function ]
+        Offset:          0
+        Segment:         1
+        Name:            'thirdDoc'
+...
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
index 18195a5861f27..8c4660b91d41d 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
@@ -81,6 +81,7 @@
 #include "llvm/Support/COM.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/ErrorExtras.h"
 #include "llvm/Support/FileOutputBuffer.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Format.h"
@@ -663,7 +664,12 @@ cl::opt<std::string>
 cl::opt<std::string> InputFilename(cl::Positional,
                                    cl::desc("<input YAML file>"), cl::Required,
                                    cl::sub(YamlToPdbSubcommand));
-}
+
+cl::opt<unsigned>
+    DocNum("docnum", cl::init(1),
+           cl::desc("Read specified document from input (default = 1)"),
+           cl::sub(YamlToPdbSubcommand));
+} // namespace yaml2pdb
 
 namespace pdb2yaml {
 cl::opt<bool> All("all",
@@ -797,7 +803,7 @@ cl::opt<bool> DXContainer("dxcontainer",
 
 static ExitOnError ExitOnErr;
 
-static void yamlToPdb(StringRef Path) {
+static void yamlToPdb(StringRef Path, unsigned DocNum) {
   BumpPtrAllocator Allocator;
   ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
       MemoryBuffer::getFileOrSTDIN(Path, /*IsText=*/false,
@@ -810,6 +816,12 @@ static void yamlToPdb(StringRef Path) {
   std::unique_ptr<MemoryBuffer> &Buffer = ErrorOrBuffer.get();
 
   llvm::yaml::Input In(Buffer->getBuffer());
+  for (unsigned CurrentDoc = 1; CurrentDoc < DocNum; ++CurrentDoc) {
+    if (!In.nextDocument())
+      ExitOnErr(createFileError(
+          Path, createStringErrorV("cannot find the {0}{1} document", DocNum,
+                                   getOrdinalSuffix(DocNum))));
+  }
   pdb::yaml::PdbObject YamlObj(Allocator);
   In >> YamlObj;
 
@@ -1713,7 +1725,7 @@ int main(int Argc, const char **Argv) {
       sys::path::replace_extension(OutputFilename, ".pdb");
       opts::yaml2pdb::YamlPdbOutputFile = std::string(OutputFilename);
     }
-    yamlToPdb(opts::yaml2pdb::InputFilename);
+    yamlToPdb(opts::yaml2pdb::InputFilename, opts::yaml2pdb::DocNum);
   } else if (opts::DiaDumpSubcommand) {
     llvm::for_each(opts::diadump::InputFilenames, dumpDia);
   } else if (opts::PrettySubcommand) {
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h
index b34436d9c23b4..34c6ce07964e6 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h
@@ -207,6 +207,12 @@ extern llvm::cl::opt<bool> DumpSectionContribs;
 extern llvm::cl::opt<bool> DXContainerStream;
 } // namespace pdb2yaml
 
+namespace yaml2pdb {
+extern llvm::cl::opt<std::string> YamlPdbOutputFile;
+extern llvm::cl::opt<std::string> InputFilename;
+extern llvm::cl::opt<unsigned> DocNum;
+} // namespace yaml2pdb
+
 namespace explain {
 enum class InputFileType { PDBFile, PDBStream, DBIStream, Names, ModuleStream };
 



More information about the llvm-commits mailing list