llvm-dis.cpp revision c7a0985995631025fbe9a4fe9fc435c3ba7387e4
11d7b50b4f823012dc283e46c2bd8036d32b402f4Chris Lattner//===----------------------------------------------------------------------===//
2009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// LLVM 'DIS' UTILITY
3009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
4009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This utility may be invoked in the following manner:
5009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//  dis [options]      - Read LLVM bytecode from stdin, write assembly to stdout
6009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//  dis [options] x.bc - Read LLVM bytecode from the x.bc file, write assembly
7009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//                       to the x.ll file.
89bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner//  Options:
99bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner//      --help   - Output information about command line switches
10aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner//       -c      - Print C code instead of LLVM assembly
11009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
121d7b50b4f823012dc283e46c2bd8036d32b402f4Chris Lattner//===----------------------------------------------------------------------===//
13009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
14009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Module.h"
15009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Bytecode/Reader.h"
16221d688a5ef21a22c2368c9fff0e92d7966c95e5Chris Lattner#include "llvm/Support/CFG.h"
17cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/CommandLine.h"
1876d12299b5333d71bfc079614031f97c97aa5148Chris Lattner#include "Support/Signals.h"
199ddc86c6e51617d1170eed07a4320edf6679f655Sumant Kowshik#include "llvm/Assembly/CWriter.h"
20cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include <fstream>
21697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner#include <iostream>
22697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::cerr;
23009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
248f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner// OutputMode - The different orderings to print basic blocks in...
258f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerenum OutputMode {
26aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner  llvm = 0,           // Generate LLVM assembly (the default)
27aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner  c,                  // Generate C code
288f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner};
299bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner
30c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string>
315ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerInputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
325ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
33c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string>
345ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerOutputFilename("o", cl::desc("Override output filename"),
355ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner               cl::value_desc("filename"));
365ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
375ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool>
385ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerForce("f", cl::desc("Overwrite output files"));
395ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
405ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<enum OutputMode>
415ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerWriteMode(cl::desc("Specify the output format:"),
425ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner          cl::values(
435ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner                     clEnumVal(llvm, "Output LLVM assembly"),
445ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner                     clEnumVal(c   , "Output C code for program"),
455ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner                    0));
46009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
478f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerint main(int argc, char **argv) {
488f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner  cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n");
49697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::ostream *Out = &std::cout;  // Default to printing to stdout...
50009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
512fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner  Module *M = ParseBytecodeFile(InputFilename);
522fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner  if (M == 0) {
53009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    cerr << "bytecode didn't read correctly.\n";
54009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    return 1;
55009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
56009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
571e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner  if (OutputFilename != "") {   // Specified an output filename?
58888912dbe01c715aa5a0ddec19da6ef12f382ebfChris Lattner    if (!Force && std::ifstream(OutputFilename.c_str())) {
59697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      // If force is not specified, make sure not to overwrite a file!
60697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      cerr << "Error opening '" << OutputFilename
61697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner           << "': File exists! Sending to standard output.\n";
62697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner    } else {
63697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      Out = new std::ofstream(OutputFilename.c_str());
64697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner    }
658f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner  } else {
661e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner    if (InputFilename == "-") {
671e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner      OutputFilename = "-";
688f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner    } else {
69697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      std::string IFN = InputFilename;
708f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner      int Len = IFN.length();
718f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner      if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
728f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner	// Source ends in .bc
73697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner	OutputFilename = std::string(IFN.begin(), IFN.end()-3);
748f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner      } else {
751e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner	OutputFilename = IFN;   // Append a .ll to it
76009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      }
779ddc86c6e51617d1170eed07a4320edf6679f655Sumant Kowshik      if (WriteMode == c)
78aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner        OutputFilename += ".c";
799ddc86c6e51617d1170eed07a4320edf6679f655Sumant Kowshik      else
80aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner        OutputFilename += ".ll";
81697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner
82888912dbe01c715aa5a0ddec19da6ef12f382ebfChris Lattner      if (!Force && std::ifstream(OutputFilename.c_str())) {
83697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner        // If force is not specified, make sure not to overwrite a file!
84697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner        cerr << "Error opening '" << OutputFilename
85697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner             << "': File exists! Sending to standard output.\n";
86697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      } else {
87697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner        Out = new std::ofstream(OutputFilename.c_str());
8876d12299b5333d71bfc079614031f97c97aa5148Chris Lattner
8976d12299b5333d71bfc079614031f97c97aa5148Chris Lattner        // Make sure that the Out file gets unlink'd from the disk if we get a
9076d12299b5333d71bfc079614031f97c97aa5148Chris Lattner        // SIGINT
9176d12299b5333d71bfc079614031f97c97aa5148Chris Lattner        RemoveFileOnSignal(OutputFilename);
92697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      }
938f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner    }
94009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
958f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner
968f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner  if (!Out->good()) {
971e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner    cerr << "Error opening " << OutputFilename
988f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner	 << ": sending to stdout instead!\n";
99697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner    Out = &std::cout;
1008f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner  }
1018f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner
102aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner  // All that dis does is write the assembly or C out to a file...
103aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner  //
104aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner  switch (WriteMode) {
105aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner  case llvm:
106aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner    (*Out) << M;           // Output LLVM assembly
107aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner    break;
108aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner  case c:
109aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner    WriteToC(M, *Out);     // Convert LLVM to C
110aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner    break;
1119bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner  }
1122fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner  delete M;
113009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
114697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  if (Out != &std::cout) delete Out;
115009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  return 0;
116009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
1179ddc86c6e51617d1170eed07a4320edf6679f655Sumant Kowshik
118