diff --git a/llvm/test/tools/llvm-dis/multiple-files.ll b/llvm/test/tools/llvm-dis/multiple-files.ll new file mode 100644 --- /dev/null +++ b/llvm/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/llvm/tools/llvm-dis/llvm-dis.cpp b/llvm/tools/llvm-dis/llvm-dis.cpp --- a/llvm/tools/llvm-dis/llvm-dis.cpp +++ b/llvm/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 @@ 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) - 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 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 Index; - if (LTOInfo.HasSummary) - Index = ExitOnErr(MB.getSummary()); + 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()); - std::string FinalFilename(OutputFilename); + BitcodeLTOInfo LTOInfo = ExitOnErr(MB.getLTOInfo()); + std::unique_ptr 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 Out( - new ToolOutputFile(FinalFilename, EC, sys::fs::OF_TextWithCRLF)); - if (EC) { - errs() << EC.message() << '\n'; - return 1; - } + 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()); + 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()); - } + // 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;