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

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 4 08:25:32 PDT 2026


Author: Nerixyz
Date: 2026-07-04T17:25:28+02:00
New Revision: 103f170a390e69a032fcb4333e6ed68e6112a3a5

URL: https://github.com/llvm/llvm-project/commit/103f170a390e69a032fcb4333e6ed68e6112a3a5
DIFF: https://github.com/llvm/llvm-project/commit/103f170a390e69a032fcb4333e6ed68e6112a3a5.diff

LOG: [llvm-pdbutil] Support `--docnum` for yaml2pdb (#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).

Added: 
    llvm/test/tools/llvm-pdbutil/opt-docnum.test

Modified: 
    llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
    llvm/tools/llvm-pdbutil/llvm-pdbutil.h

Removed: 
    


################################################################################
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..2591a2d53d5d9
--- /dev/null
+++ b/llvm/test/tools/llvm-pdbutil/opt-docnum.test
@@ -0,0 +1,62 @@
+# 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-4TH %s
+# RUN: not llvm-pdbutil yaml2pdb %s --pdb=%t-err.pdb --docnum=0 2>&1 | FileCheck --check-prefix=CHECK-ERR-0TH %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-0TH: document numbers are 1-based, there is no 0th document
+# CHECK-ERR-4TH: 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..77aed01ad498f 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,
@@ -807,9 +813,19 @@ static void yamlToPdb(StringRef Path) {
     ExitOnErr(createFileError(Path, errorCodeToError(ErrorOrBuffer.getError())));
   }
 
+  if (DocNum == 0)
+    ExitOnErr(createStringError(
+        "document numbers are 1-based, there is no 0th document"));
+
   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 +1729,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