llvm-dis.cpp revision 7c0e022c5c4be4b11e199a53f73bbdd84e34aa80
1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// LLVM 'DIS' UTILITY 11// 12// This utility may be invoked in the following manner: 13// llvm-dis [options] - Read LLVM bytecode from stdin, write asm to stdout 14// llvm-dis [options] x.bc - Read LLVM bytecode from the x.bc file, write asm 15// to the x.ll file. 16// Options: 17// --help - Output information about command line switches 18// -c - Print C code instead of LLVM assembly 19// 20//===----------------------------------------------------------------------===// 21 22#include "llvm/Module.h" 23#include "llvm/PassManager.h" 24#include "llvm/Bytecode/Reader.h" 25#include "llvm/Assembly/CWriter.h" 26#include "llvm/Assembly/PrintModulePass.h" 27#include "Support/CommandLine.h" 28#include "Support/Signals.h" 29#include <fstream> 30#include <memory> 31 32// OutputMode - The different orderings to print basic blocks in... 33enum OutputMode { 34 llvm = 0, // Generate LLVM assembly (the default) 35 c, // Generate C code 36}; 37 38static cl::opt<std::string> 39InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-")); 40 41static cl::opt<std::string> 42OutputFilename("o", cl::desc("Override output filename"), 43 cl::value_desc("filename")); 44 45static cl::opt<bool> 46Force("f", cl::desc("Overwrite output files")); 47 48static cl::opt<enum OutputMode> 49WriteMode(cl::desc("Specify the output format:"), 50 cl::values(clEnumVal(llvm, "Output LLVM assembly"), 51 clEnumVal(c , "Output C code for program"), 52 0)); 53 54int main(int argc, char **argv) { 55 cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n"); 56 std::ostream *Out = &std::cout; // Default to printing to stdout... 57 std::string ErrorMessage; 58 59 std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename, &ErrorMessage)); 60 if (M.get() == 0) { 61 std::cerr << argv[0] << ": "; 62 if (ErrorMessage.size()) 63 std::cerr << ErrorMessage << "\n"; 64 else 65 std::cerr << "bytecode didn't read correctly.\n"; 66 return 1; 67 } 68 69 if (OutputFilename != "") { // Specified an output filename? 70 if (OutputFilename != "-") { // Not stdout? 71 if (!Force && std::ifstream(OutputFilename.c_str())) { 72 // If force is not specified, make sure not to overwrite a file! 73 std::cerr << argv[0] << ": error opening '" << OutputFilename 74 << "': file exists! Sending to standard output.\n"; 75 } else { 76 Out = new std::ofstream(OutputFilename.c_str()); 77 } 78 } 79 } else { 80 if (InputFilename == "-") { 81 OutputFilename = "-"; 82 } else { 83 std::string IFN = InputFilename; 84 int Len = IFN.length(); 85 if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { 86 // Source ends in .bc 87 OutputFilename = std::string(IFN.begin(), IFN.end()-3); 88 } else { 89 OutputFilename = IFN; // Append a .ll to it 90 } 91 if (WriteMode == c) 92 OutputFilename += ".c"; 93 else 94 OutputFilename += ".ll"; 95 96 if (!Force && std::ifstream(OutputFilename.c_str())) { 97 // If force is not specified, make sure not to overwrite a file! 98 std::cerr << argv[0] << ": error opening '" << OutputFilename 99 << "': file exists! Sending to standard output.\n"; 100 } else { 101 Out = new std::ofstream(OutputFilename.c_str()); 102 103 // Make sure that the Out file gets unlinked from the disk if we get a 104 // SIGINT 105 RemoveFileOnSignal(OutputFilename); 106 } 107 } 108 } 109 110 if (!Out->good()) { 111 std::cerr << argv[0] << ": error opening " << OutputFilename 112 << ": sending to stdout instead!\n"; 113 Out = &std::cout; 114 } 115 116 // All that dis does is write the assembly or C out to a file... 117 // 118 PassManager Passes; 119 120 switch (WriteMode) { 121 case llvm: // Output LLVM assembly 122 Passes.add(new PrintModulePass(Out)); 123 break; 124 case c: // Convert LLVM to C 125 Passes.add(createWriteToCPass(*Out)); 126 break; 127 } 128 129 Passes.run(*M.get()); 130 131 if (Out != &std::cout) { 132 ((std::ofstream*)Out)->close(); 133 delete Out; 134 } 135 return 0; 136} 137 138