llvm-dis.cpp revision ebe69fe11e48d322045d5949c83283927a0d790b
11dd27b157bbe7d9e44fa72abbc8b0f08eba804ecChris Lattner//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//                     The LLVM Compiler Infrastructure
47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source
621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// License. See LICENSE.TXT for details.
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===//
9009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
10009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This utility may be invoked in the following manner:
11a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif//  llvm-dis [options]      - Read LLVM bitcode from stdin, write asm to stdout
12a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif//  llvm-dis [options] x.bc - Read LLVM bitcode from the x.bc file, write asm
13ad0bf0fc0cead2c714d6a0e164d3bdb2864eb8e1Misha Brukman//                            to the x.ll file.
149bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner//  Options:
159bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner//      --help   - Output information about command line switches
16009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
171d7b50b4f823012dc283e46c2bd8036d32b402f4Chris Lattner//===----------------------------------------------------------------------===//
18009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
20f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Bitcode/ReaderWriter.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/AssemblyAnnotationWriter.h"
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugInfo.h"
23ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DiagnosticInfo.h"
24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DiagnosticPrinter.h"
250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h"
260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h"
28551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h"
292ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff#include "llvm/Support/DataStream.h"
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/FileSystem.h"
316cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner#include "llvm/Support/FormattedStream.h"
32c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner#include "llvm/Support/ManagedStatic.h"
33c453f76e2b4d7fd1e042b5b6d4c20556779186dfChris Lattner#include "llvm/Support/MemoryBuffer.h"
34cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner#include "llvm/Support/PrettyStackTrace.h"
351f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Signals.h"
36f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/ToolOutputFile.h"
37c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error>
38d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm;
39d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
40c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string>
41a99be51bf5cdac1438069d4b01766c47704961c8Gabor GreifInputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
425ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
43c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string>
443da94aec4d429b2ba0f65fa040c33650cade196bMisha BrukmanOutputFilename("o", cl::desc("Override output filename"),
455ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner               cl::value_desc("filename"));
465ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
475ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool>
48baa26395ccf17fc988bb9cf62d6659ca8415ece9Dan GohmanForce("f", cl::desc("Enable binary output on terminals"));
495ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
504d544cd646440fb99131206d6f074fa32dc308dcChris Lattnerstatic cl::opt<bool>
514d544cd646440fb99131206d6f074fa32dc308dcChris LattnerDontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden);
524d544cd646440fb99131206d6f074fa32dc308dcChris Lattner
536cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattnerstatic cl::opt<bool>
546cd71f0c4026217a501e09dcc2198c6c7a462e44Chris LattnerShowAnnotations("show-annotations",
556cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner                cl::desc("Add informational comments to the .ll file"));
566cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner
576cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattnernamespace {
587aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer
59027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patelstatic void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
60027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel  OS << DL.getLine() << ":" << DL.getCol();
61027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel  if (MDNode *N = DL.getInlinedAt(getGlobalContext())) {
62027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel    DebugLoc IDL = DebugLoc::getFromDILocation(N);
63027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel    if (!IDL.isUnknown()) {
64027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      OS << "@";
65027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      printDebugLoc(IDL,OS);
66027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel    }
67027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel  }
68027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel}
696cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattnerclass CommentWriter : public AssemblyAnnotationWriter {
706cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattnerpublic:
716cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner  void emitFunctionAnnot(const Function *F,
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         formatted_raw_ostream &OS) override {
736cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner    OS << "; [#uses=" << F->getNumUses() << ']';  // Output # uses
746cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner    OS << '\n';
756cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner  }
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
77027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel    bool Padded = false;
78027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel    if (!V.getType()->isVoidTy()) {
79027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      OS.PadToColumn(50);
80027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      Padded = true;
810cd0d881604775f3f97048645f040b2ef4f61e4bChris Lattner      OS << "; [#uses=" << V.getNumUses() << " type=" << *V.getType() << "]";  // Output # uses and type
82027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel    }
83027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel    if (const Instruction *I = dyn_cast<Instruction>(&V)) {
84027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      const DebugLoc &DL = I->getDebugLoc();
85027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      if (!DL.isUnknown()) {
86027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        if (!Padded) {
87027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel          OS.PadToColumn(50);
88027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel          Padded = true;
89027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel          OS << ";";
90027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        }
91027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        OS << " [debug line = ";
92027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        printDebugLoc(DL,OS);
93027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        OS << "]";
94027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      }
95027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) {
96027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        DIVariable Var(DDI->getVariable());
97027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        if (!Padded) {
98027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel          OS.PadToColumn(50);
99027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel          OS << ";";
100027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        }
101027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        OS << " [debug variable = " << Var.getName() << "]";
102027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      }
103027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) {
104027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        DIVariable Var(DVI->getVariable());
105027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        if (!Padded) {
106027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel          OS.PadToColumn(50);
107027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel          OS << ";";
108027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        }
109027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel        OS << " [debug variable = " << Var.getName() << "]";
110027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel      }
111027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel    }
1126cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner  }
1136cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner};
1147aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer
1156cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner} // end anon namespace
1166cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner
117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  raw_ostream &OS = errs();
119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  OS << (char *)Context << ": ";
120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  switch (DI.getSeverity()) {
121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case DS_Error: OS << "error: "; break;
122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case DS_Warning: OS << "warning: "; break;
123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case DS_Remark: OS << "remark: "; break;
124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case DS_Note: OS << "note: "; break;
125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DiagnosticPrinterRawOStream DP(OS);
128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DI.print(DP);
129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  OS << '\n';
130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (DI.getSeverity() == DS_Error)
132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    exit(1);
133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1358f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerint main(int argc, char **argv) {
136cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  // Print a stack trace if we signal out.
137cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  sys::PrintStackTraceOnErrorSignal();
138cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  PrettyStackTraceProgram X(argc, argv);
1397aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer
1400d7c695c74ae6d5f68cc07378c17491915e607d3Owen Anderson  LLVMContext &Context = getGlobalContext();
141cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
1427aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer
143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Context.setDiagnosticHandler(diagnosticHandler, argv[0]);
1447aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer
14517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
146009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
14717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  std::string ErrorMessage;
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<Module> M;
149333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer
1502ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff  // Use the bitcode streaming interface
151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DataStreamer *Streamer = getDataFileStreamer(InputFilename, &ErrorMessage);
152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Streamer) {
1532ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff    std::string DisplayFilename;
1542ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff    if (InputFilename == "-")
1552ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff      DisplayFilename = "<stdin>";
156c448aa66565252298028dec1a5fbc23ab6e24440Michael J. Spencer    else
1572ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff      DisplayFilename = InputFilename;
158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ErrorOr<std::unique_ptr<Module>> MOrErr =
159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        getStreamedBitcodeModule(DisplayFilename, Streamer, Context);
160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    M = std::move(*MOrErr);
161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    M->materializeAllPermanently();
16217e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  }
1637aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer
16417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  // Just use stdout.  We won't actually print anything on it.
16517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (DontPrint)
16617e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    OutputFilename = "-";
1677aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer
16817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (OutputFilename.empty()) { // Unspecified output, infer it.
16917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    if (InputFilename == "-") {
17017e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      OutputFilename = "-";
1711ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer    } else {
17217e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      const std::string &IFN = InputFilename;
17317e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      int Len = IFN.length();
17417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      // If the source ends in .bc, strip it off.
17517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c')
17617e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner        OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
17717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      else
17817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner        OutputFilename = IFN+".ll";
1791ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer    }
18017e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  }
181ec080467f5b322441055de1f6cd4f08edc23d7dfDan Gohman
18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::error_code EC;
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<tool_output_file> Out(
18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      new tool_output_file(OutputFilename, EC, sys::fs::F_None));
18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (EC) {
18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << EC.message() << '\n';
18717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    return 1;
18817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  }
1898f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<AssemblyAnnotationWriter> Annotator;
1916cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner  if (ShowAnnotations)
1926cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner    Annotator.reset(new CommentWriter());
1937aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer
19417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  // All that llvm-dis does is write the assembly to a file.
19504fc8c8d335af7c54d9a4fb8409748d2c84402f3Dan Gohman  if (!DontPrint)
1966cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner    M->print(Out->os(), Annotator.get());
197c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner
198d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman  // Declare success.
199d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman  Out->keep();
200d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman
20117e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  return 0;
202009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
203