Allow llvm-dis to disassemble multiple files
authorMatthew Voss <matthew.voss@sony.com>
Thu, 22 Apr 2021 21:07:45 +0000 (14:07 -0700)
committerMatthew Voss <matthew.voss@sony.com>
Thu, 6 May 2021 18:08:55 +0000 (11:08 -0700)
Differential Revision: https://reviews.llvm.org/D101110

llvm/test/tools/llvm-dis/multiple-files.ll [new file with mode: 0644]
llvm/tools/llvm-dis/llvm-dis.cpp

diff --git a/llvm/test/tools/llvm-dis/multiple-files.ll b/llvm/test/tools/llvm-dis/multiple-files.ll
new file mode 100644 (file)
index 0000000..e724e7f
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: llvm-as -o %t0 %s
+; RUN: cp %t0 %t1
+; RUN: not llvm-dis -o %t2 %t0 %t1 2>&1 | FileCheck %s --check-prefix ERROR
+; RUN: llvm-dis %t0 %t1
+; RUN: FileCheck %s < %t0.ll
+; RUN: FileCheck %s < %t1.ll
+; ERROR: error: output file name cannot be set for multiple input files
+
+; CHECK: declare void @foo
+declare void @foo() 
index 2dcdbf0..9bf4597 100644 (file)
@@ -35,8 +35,8 @@
 #include <system_error>
 using namespace llvm;
 
-static cl::opt<std::string>
-InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
+static cl::list<std::string> InputFilenames(cl::Positional, cl::ZeroOrMore,
+                                            cl::desc("[input bitcode]..."));
 
 static cl::opt<std::string>
 OutputFilename("o", cl::desc("Override output filename"),
@@ -156,72 +156,82 @@ int main(int argc, char **argv) {
       std::make_unique<LLVMDisDiagnosticHandler>(argv[0]));
   cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
 
-  std::unique_ptr<MemoryBuffer> MB =
-      ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename)));
+  if (InputFilenames.size() < 1) {
+    InputFilenames.push_back("-");
+  } else if (InputFilenames.size() > 1 && !OutputFilename.empty()) {
+    errs()
+        << "error: output file name cannot be set for multiple input files\n";
+    return 1;
+  }
 
-  BitcodeFileContents IF = ExitOnErr(llvm::getBitcodeFileContents(*MB));
+  for (std::string InputFilename : InputFilenames) {
+    std::unique_ptr<MemoryBuffer> MB = ExitOnErr(
+        errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename)));
 
-  const size_t N = IF.Mods.size();
+    BitcodeFileContents IF = ExitOnErr(llvm::getBitcodeFileContents(*MB));
 
-  if (OutputFilename == "-" && N > 1)
-      errs() << "only single module bitcode files can be written to stdout\n";
+    const size_t N = IF.Mods.size();
 
-  for (size_t i = 0; i < N; ++i) {
-    BitcodeModule MB = IF.Mods[i];
-    std::unique_ptr<Module> M = ExitOnErr(MB.getLazyModule(Context, MaterializeMetadata,
-                                          SetImporting));
-    if (MaterializeMetadata)
-      ExitOnErr(M->materializeMetadata());
-    else
-      ExitOnErr(M->materializeAll());
+    if (OutputFilename == "-" && N > 1)
+      errs() << "only single module bitcode files can be written to stdout\n";
 
-    BitcodeLTOInfo LTOInfo = ExitOnErr(MB.getLTOInfo());
-    std::unique_ptr<ModuleSummaryIndex> Index;
-    if (LTOInfo.HasSummary)
-      Index = ExitOnErr(MB.getSummary());
+    for (size_t I = 0; I < N; ++I) {
+      BitcodeModule MB = IF.Mods[I];
+      std::unique_ptr<Module> M = ExitOnErr(
+          MB.getLazyModule(Context, MaterializeMetadata, SetImporting));
+      if (MaterializeMetadata)
+        ExitOnErr(M->materializeMetadata());
+      else
+        ExitOnErr(M->materializeAll());
 
-    std::string FinalFilename(OutputFilename);
+      BitcodeLTOInfo LTOInfo = ExitOnErr(MB.getLTOInfo());
+      std::unique_ptr<ModuleSummaryIndex> Index;
+      if (LTOInfo.HasSummary)
+        Index = ExitOnErr(MB.getSummary());
 
-    // Just use stdout.  We won't actually print anything on it.
-    if (DontPrint)
-      FinalFilename = "-";
+      std::string FinalFilename(OutputFilename);
 
-    if (FinalFilename.empty()) { // Unspecified output, infer it.
-      if (InputFilename == "-") {
+      // Just use stdout.  We won't actually print anything on it.
+      if (DontPrint)
         FinalFilename = "-";
+
+      if (FinalFilename.empty()) { // Unspecified output, infer it.
+        if (InputFilename == "-") {
+          FinalFilename = "-";
+        } else {
+          StringRef IFN = InputFilename;
+          FinalFilename = (IFN.endswith(".bc") ? IFN.drop_back(3) : IFN).str();
+          if (N > 1)
+            FinalFilename += std::string(".") + std::to_string(I);
+          FinalFilename += ".ll";
+        }
       } else {
-        StringRef IFN = InputFilename;
-        FinalFilename = (IFN.endswith(".bc") ? IFN.drop_back(3) : IFN).str();
         if (N > 1)
-          FinalFilename += std::string(".") + std::to_string(i);
-        FinalFilename += ".ll";
+          FinalFilename += std::string(".") + std::to_string(I);
       }
-    } else {
-      if (N > 1)
-        FinalFilename += std::string(".") + std::to_string(i);
-    }
 
-    std::error_code EC;
-    std::unique_ptr<ToolOutputFile> Out(
-        new ToolOutputFile(FinalFilename, EC, sys::fs::OF_TextWithCRLF));
-    if (EC) {
-      errs() << EC.message() << '\n';
-      return 1;
-    }
+      std::error_code EC;
+      std::unique_ptr<ToolOutputFile> Out(
+          new ToolOutputFile(FinalFilename, EC, sys::fs::OF_TextWithCRLF));
+      if (EC) {
+        errs() << EC.message() << '\n';
+        return 1;
+      }
 
-    std::unique_ptr<AssemblyAnnotationWriter> Annotator;
-    if (ShowAnnotations)
-      Annotator.reset(new CommentWriter());
+      std::unique_ptr<AssemblyAnnotationWriter> Annotator;
+      if (ShowAnnotations)
+        Annotator.reset(new CommentWriter());
 
-    // All that llvm-dis does is write the assembly to a file.
-    if (!DontPrint) {
-      M->print(Out->os(), Annotator.get(), PreserveAssemblyUseListOrder);
-      if (Index)
-        Index->print(Out->os());
-    }
+      // All that llvm-dis does is write the assembly to a file.
+      if (!DontPrint) {
+        M->print(Out->os(), Annotator.get(), PreserveAssemblyUseListOrder);
+        if (Index)
+          Index->print(Out->os());
+      }
 
-    // Declare success.
-    Out->keep();
+      // Declare success.
+      Out->keep();
+    }
   }
 
   return 0;