From 89fdd0e3a1be6c0f2cc798013f157a60baee28f5 Mon Sep 17 00:00:00 2001 From: Matthew Voss Date: Thu, 22 Apr 2021 14:07:45 -0700 Subject: [PATCH] Allow llvm-dis to disassemble multiple files Differential Revision: https://reviews.llvm.org/D101110 --- test/tools/llvm-dis/multiple-files.ll | 10 +++ tools/llvm-dis/llvm-dis.cpp | 120 ++++++++++++++------------ 2 files changed, 75 insertions(+), 55 deletions(-) create mode 100644 test/tools/llvm-dis/multiple-files.ll diff --git a/test/tools/llvm-dis/multiple-files.ll b/test/tools/llvm-dis/multiple-files.ll new file mode 100644 index 00000000000..e724e7fcbea --- /dev/null +++ b/test/tools/llvm-dis/multiple-files.ll @@ -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() diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index 2dcdbf0cf29..9bf45978db4 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -35,8 +35,8 @@ #include using namespace llvm; -static cl::opt -InputFilename(cl::Positional, cl::desc(""), cl::init("-")); +static cl::list InputFilenames(cl::Positional, cl::ZeroOrMore, + cl::desc("[input bitcode]...")); static cl::opt OutputFilename("o", cl::desc("Override output filename"), @@ -156,72 +156,82 @@ int main(int argc, char **argv) { std::make_unique(argv[0])); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); - std::unique_ptr 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 MB = ExitOnErr( + errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename))); - const size_t N = IF.Mods.size(); + BitcodeFileContents IF = ExitOnErr(llvm::getBitcodeFileContents(*MB)); - if (OutputFilename == "-" && N > 1) + const size_t N = IF.Mods.size(); + + if (OutputFilename == "-" && N > 1) errs() << "only single module bitcode files can be written to stdout\n"; - for (size_t i = 0; i < N; ++i) { - BitcodeModule MB = IF.Mods[i]; - std::unique_ptr M = ExitOnErr(MB.getLazyModule(Context, MaterializeMetadata, - SetImporting)); - if (MaterializeMetadata) - ExitOnErr(M->materializeMetadata()); - else - ExitOnErr(M->materializeAll()); + for (size_t I = 0; I < N; ++I) { + BitcodeModule MB = IF.Mods[I]; + std::unique_ptr M = ExitOnErr( + MB.getLazyModule(Context, MaterializeMetadata, SetImporting)); + if (MaterializeMetadata) + ExitOnErr(M->materializeMetadata()); + else + ExitOnErr(M->materializeAll()); - BitcodeLTOInfo LTOInfo = ExitOnErr(MB.getLTOInfo()); - std::unique_ptr Index; - if (LTOInfo.HasSummary) - Index = ExitOnErr(MB.getSummary()); + BitcodeLTOInfo LTOInfo = ExitOnErr(MB.getLTOInfo()); + std::unique_ptr Index; + if (LTOInfo.HasSummary) + Index = ExitOnErr(MB.getSummary()); - std::string FinalFilename(OutputFilename); + std::string FinalFilename(OutputFilename); - // Just use stdout. We won't actually print anything on it. - if (DontPrint) - FinalFilename = "-"; - - 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 Out( + new ToolOutputFile(FinalFilename, EC, sys::fs::OF_TextWithCRLF)); + if (EC) { + errs() << EC.message() << '\n'; + return 1; + } + + std::unique_ptr 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()); + } + + // Declare success. + Out->keep(); } - - std::error_code EC; - std::unique_ptr Out( - new ToolOutputFile(FinalFilename, EC, sys::fs::OF_TextWithCRLF)); - if (EC) { - errs() << EC.message() << '\n'; - return 1; - } - - std::unique_ptr 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()); - } - - // Declare success. - Out->keep(); } return 0;