llvm-dis.cpp revision 212793
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/Bitcode/ReaderWriter.h"
23#include "llvm/Assembly/AssemblyAnnotationWriter.h"
24#include "llvm/Support/CommandLine.h"
25#include "llvm/Support/FormattedStream.h"
26#include "llvm/Support/ManagedStatic.h"
27#include "llvm/Support/MemoryBuffer.h"
28#include "llvm/Support/PrettyStackTrace.h"
29#include "llvm/Support/raw_ostream.h"
30#include "llvm/System/Signals.h"
31using namespace llvm;
32
33static cl::opt<std::string>
34InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
35
36static cl::opt<std::string>
37OutputFilename("o", cl::desc("Override output filename"),
38               cl::value_desc("filename"));
39
40static cl::opt<bool>
41Force("f", cl::desc("Enable binary output on terminals"));
42
43static cl::opt<bool>
44DontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden);
45
46static cl::opt<bool>
47ShowAnnotations("show-annotations",
48                cl::desc("Add informational comments to the .ll file"));
49
50namespace {
51
52class CommentWriter : public AssemblyAnnotationWriter {
53public:
54  void emitFunctionAnnot(const Function *F,
55                         formatted_raw_ostream &OS) {
56    OS << "; [#uses=" << F->getNumUses() << ']';  // Output # uses
57    OS << '\n';
58  }
59  void printInfoComment(const Value &V, formatted_raw_ostream &OS) {
60    if (V.getType()->isVoidTy()) return;
61
62    OS.PadToColumn(50);
63    OS << "; [#uses=" << V.getNumUses() << ']';  // Output # uses
64  }
65};
66
67} // end anon namespace
68
69int main(int argc, char **argv) {
70  // Print a stack trace if we signal out.
71  sys::PrintStackTraceOnErrorSignal();
72  PrettyStackTraceProgram X(argc, argv);
73
74  LLVMContext &Context = getGlobalContext();
75  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
76
77
78  cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
79
80  std::string ErrorMessage;
81  std::auto_ptr<Module> M;
82
83  if (MemoryBuffer *Buffer
84         = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) {
85    M.reset(ParseBitcodeFile(Buffer, Context, &ErrorMessage));
86    delete Buffer;
87  }
88
89  if (M.get() == 0) {
90    errs() << argv[0] << ": ";
91    if (ErrorMessage.size())
92      errs() << ErrorMessage << "\n";
93    else
94      errs() << "bitcode didn't read correctly.\n";
95    return 1;
96  }
97
98  // Just use stdout.  We won't actually print anything on it.
99  if (DontPrint)
100    OutputFilename = "-";
101
102  if (OutputFilename.empty()) { // Unspecified output, infer it.
103    if (InputFilename == "-") {
104      OutputFilename = "-";
105    } else {
106      const std::string &IFN = InputFilename;
107      int Len = IFN.length();
108      // If the source ends in .bc, strip it off.
109      if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c')
110        OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
111      else
112        OutputFilename = IFN+".ll";
113    }
114  }
115
116  std::string ErrorInfo;
117  OwningPtr<tool_output_file>
118  Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
119                           raw_fd_ostream::F_Binary));
120  if (!ErrorInfo.empty()) {
121    errs() << ErrorInfo << '\n';
122    return 1;
123  }
124
125  OwningPtr<AssemblyAnnotationWriter> Annotator;
126  if (ShowAnnotations)
127    Annotator.reset(new CommentWriter());
128
129  // All that llvm-dis does is write the assembly to a file.
130  if (!DontPrint)
131    M->print(Out->os(), Annotator.get());
132
133  // Declare success.
134  Out->keep();
135
136  return 0;
137}
138
139