1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

Allow llvm-dis to disassemble multiple files

Differential Revision: https://reviews.llvm.org/D101110
This commit is contained in:
Matthew Voss 2021-04-22 14:07:45 -07:00
parent ce786f30a4
commit 89fdd0e3a1
2 changed files with 75 additions and 55 deletions

View File

@ -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()

View File

@ -35,8 +35,8 @@
#include <system_error> #include <system_error>
using namespace llvm; using namespace llvm;
static cl::opt<std::string> static cl::list<std::string> InputFilenames(cl::Positional, cl::ZeroOrMore,
InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); cl::desc("[input bitcode]..."));
static cl::opt<std::string> static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"), OutputFilename("o", cl::desc("Override output filename"),
@ -156,72 +156,82 @@ int main(int argc, char **argv) {
std::make_unique<LLVMDisDiagnosticHandler>(argv[0])); std::make_unique<LLVMDisDiagnosticHandler>(argv[0]));
cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
std::unique_ptr<MemoryBuffer> MB = if (InputFilenames.size() < 1) {
ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename))); 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) const size_t N = IF.Mods.size();
if (OutputFilename == "-" && N > 1)
errs() << "only single module bitcode files can be written to stdout\n"; errs() << "only single module bitcode files can be written to stdout\n";
for (size_t i = 0; i < N; ++i) { for (size_t I = 0; I < N; ++I) {
BitcodeModule MB = IF.Mods[i]; BitcodeModule MB = IF.Mods[I];
std::unique_ptr<Module> M = ExitOnErr(MB.getLazyModule(Context, MaterializeMetadata, std::unique_ptr<Module> M = ExitOnErr(
SetImporting)); MB.getLazyModule(Context, MaterializeMetadata, SetImporting));
if (MaterializeMetadata) if (MaterializeMetadata)
ExitOnErr(M->materializeMetadata()); ExitOnErr(M->materializeMetadata());
else else
ExitOnErr(M->materializeAll()); ExitOnErr(M->materializeAll());
BitcodeLTOInfo LTOInfo = ExitOnErr(MB.getLTOInfo()); BitcodeLTOInfo LTOInfo = ExitOnErr(MB.getLTOInfo());
std::unique_ptr<ModuleSummaryIndex> Index; std::unique_ptr<ModuleSummaryIndex> Index;
if (LTOInfo.HasSummary) if (LTOInfo.HasSummary)
Index = ExitOnErr(MB.getSummary()); Index = ExitOnErr(MB.getSummary());
std::string FinalFilename(OutputFilename); std::string FinalFilename(OutputFilename);
// Just use stdout. We won't actually print anything on it. // Just use stdout. We won't actually print anything on it.
if (DontPrint) if (DontPrint)
FinalFilename = "-";
if (FinalFilename.empty()) { // Unspecified output, infer it.
if (InputFilename == "-") {
FinalFilename = "-"; 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 { } else {
StringRef IFN = InputFilename;
FinalFilename = (IFN.endswith(".bc") ? IFN.drop_back(3) : IFN).str();
if (N > 1) if (N > 1)
FinalFilename += std::string(".") + std::to_string(i); FinalFilename += std::string(".") + std::to_string(I);
FinalFilename += ".ll";
} }
} else {
if (N > 1) std::error_code EC;
FinalFilename += std::string(".") + std::to_string(i); 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());
// 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<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());
// 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; return 0;