llvm-dis.cpp revision 234353
1//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This utility may be invoked in the following manner:
11//  llvm-dis [options]      - Read LLVM bitcode from stdin, write asm to stdout
12//  llvm-dis [options] x.bc - Read LLVM bitcode from the x.bc file, write asm
13//                            to the x.ll file.
14//  Options:
15//      --help   - Output information about command line switches
16//
17//===----------------------------------------------------------------------===//
18
19#include "llvm/LLVMContext.h"
20#include "llvm/Module.h"
21#include "llvm/Type.h"
22#include "llvm/IntrinsicInst.h"
23#include "llvm/Bitcode/ReaderWriter.h"
24#include "llvm/Analysis/DebugInfo.h"
25#include "llvm/Assembly/AssemblyAnnotationWriter.h"
26#include "llvm/Support/CommandLine.h"
27#include "llvm/Support/DataStream.h"
28#include "llvm/Support/FormattedStream.h"
29#include "llvm/Support/ManagedStatic.h"
30#include "llvm/Support/MemoryBuffer.h"
31#include "llvm/Support/PrettyStackTrace.h"
32#include "llvm/Support/ToolOutputFile.h"
33#include "llvm/Support/Signals.h"
34#include "llvm/Support/system_error.h"
35using namespace llvm;
36
37static cl::opt<std::string>
38InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
39
40static cl::opt<std::string>
41OutputFilename("o", cl::desc("Override output filename"),
42               cl::value_desc("filename"));
43
44static cl::opt<bool>
45Force("f", cl::desc("Enable binary output on terminals"));
46
47static cl::opt<bool>
48DontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden);
49
50static cl::opt<bool>
51ShowAnnotations("show-annotations",
52                cl::desc("Add informational comments to the .ll file"));
53
54namespace {
55
56static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
57  OS << DL.getLine() << ":" << DL.getCol();
58  if (MDNode *N = DL.getInlinedAt(getGlobalContext())) {
59    DebugLoc IDL = DebugLoc::getFromDILocation(N);
60    if (!IDL.isUnknown()) {
61      OS << "@";
62      printDebugLoc(IDL,OS);
63    }
64  }
65}
66class CommentWriter : public AssemblyAnnotationWriter {
67public:
68  void emitFunctionAnnot(const Function *F,
69                         formatted_raw_ostream &OS) {
70    OS << "; [#uses=" << F->getNumUses() << ']';  // Output # uses
71    OS << '\n';
72  }
73  void printInfoComment(const Value &V, formatted_raw_ostream &OS) {
74    bool Padded = false;
75    if (!V.getType()->isVoidTy()) {
76      OS.PadToColumn(50);
77      Padded = true;
78      OS << "; [#uses=" << V.getNumUses() << " type=" << *V.getType() << "]";  // Output # uses and type
79    }
80    if (const Instruction *I = dyn_cast<Instruction>(&V)) {
81      const DebugLoc &DL = I->getDebugLoc();
82      if (!DL.isUnknown()) {
83        if (!Padded) {
84          OS.PadToColumn(50);
85          Padded = true;
86          OS << ";";
87        }
88        OS << " [debug line = ";
89        printDebugLoc(DL,OS);
90        OS << "]";
91      }
92      if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) {
93        DIVariable Var(DDI->getVariable());
94        if (!Padded) {
95          OS.PadToColumn(50);
96          Padded = true;
97          OS << ";";
98        }
99        OS << " [debug variable = " << Var.getName() << "]";
100      }
101      else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) {
102        DIVariable Var(DVI->getVariable());
103        if (!Padded) {
104          OS.PadToColumn(50);
105          Padded = true;
106          OS << ";";
107        }
108        OS << " [debug variable = " << Var.getName() << "]";
109      }
110    }
111  }
112};
113
114} // end anon namespace
115
116int main(int argc, char **argv) {
117  // Print a stack trace if we signal out.
118  sys::PrintStackTraceOnErrorSignal();
119  PrettyStackTraceProgram X(argc, argv);
120
121  LLVMContext &Context = getGlobalContext();
122  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
123
124
125  cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
126
127  std::string ErrorMessage;
128  std::auto_ptr<Module> M;
129
130  // Use the bitcode streaming interface
131  DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage);
132  if (streamer) {
133    std::string DisplayFilename;
134    if (InputFilename == "-")
135      DisplayFilename = "<stdin>";
136    else
137      DisplayFilename = InputFilename;
138    M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context,
139                                     &ErrorMessage));
140    if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) {
141      M.reset();
142    }
143  }
144
145  if (M.get() == 0) {
146    errs() << argv[0] << ": ";
147    if (ErrorMessage.size())
148      errs() << ErrorMessage << "\n";
149    else
150      errs() << "bitcode didn't read correctly.\n";
151    return 1;
152  }
153
154  // Just use stdout.  We won't actually print anything on it.
155  if (DontPrint)
156    OutputFilename = "-";
157
158  if (OutputFilename.empty()) { // Unspecified output, infer it.
159    if (InputFilename == "-") {
160      OutputFilename = "-";
161    } else {
162      const std::string &IFN = InputFilename;
163      int Len = IFN.length();
164      // If the source ends in .bc, strip it off.
165      if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c')
166        OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
167      else
168        OutputFilename = IFN+".ll";
169    }
170  }
171
172  std::string ErrorInfo;
173  OwningPtr<tool_output_file>
174  Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
175                           raw_fd_ostream::F_Binary));
176  if (!ErrorInfo.empty()) {
177    errs() << ErrorInfo << '\n';
178    return 1;
179  }
180
181  OwningPtr<AssemblyAnnotationWriter> Annotator;
182  if (ShowAnnotations)
183    Annotator.reset(new CommentWriter());
184
185  // All that llvm-dis does is write the assembly to a file.
186  if (!DontPrint)
187    M->print(Out->os(), Annotator.get());
188
189  // Declare success.
190  Out->keep();
191
192  return 0;
193}
194