llvm-dis.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. #include "llvm/Bitcode/BitcodeReader.h"
  19. #include "llvm/IR/AssemblyAnnotationWriter.h"
  20. #include "llvm/IR/DebugInfo.h"
  21. #include "llvm/IR/DiagnosticInfo.h"
  22. #include "llvm/IR/DiagnosticPrinter.h"
  23. #include "llvm/IR/IntrinsicInst.h"
  24. #include "llvm/IR/LLVMContext.h"
  25. #include "llvm/IR/Module.h"
  26. #include "llvm/IR/Type.h"
  27. #include "llvm/Support/CommandLine.h"
  28. #include "llvm/Support/Error.h"
  29. #include "llvm/Support/FileSystem.h"
  30. #include "llvm/Support/FormattedStream.h"
  31. #include "llvm/Support/InitLLVM.h"
  32. #include "llvm/Support/MemoryBuffer.h"
  33. #include "llvm/Support/ToolOutputFile.h"
  34. #include "llvm/Support/WithColor.h"
  35. #include <system_error>
  36. using namespace llvm;
  37. static cl::opt<std::string>
  38. InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
  39. static cl::opt<std::string>
  40. OutputFilename("o", cl::desc("Override output filename"),
  41. cl::value_desc("filename"));
  42. static cl::opt<bool>
  43. Force("f", cl::desc("Enable binary output on terminals"));
  44. static cl::opt<bool>
  45. DontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden);
  46. static cl::opt<bool>
  47. SetImporting("set-importing",
  48. cl::desc("Set lazy loading to pretend to import a module"),
  49. cl::Hidden);
  50. static cl::opt<bool>
  51. ShowAnnotations("show-annotations",
  52. cl::desc("Add informational comments to the .ll file"));
  53. static cl::opt<bool> PreserveAssemblyUseListOrder(
  54. "preserve-ll-uselistorder",
  55. cl::desc("Preserve use-list order when writing LLVM assembly."),
  56. cl::init(false), cl::Hidden);
  57. static cl::opt<bool>
  58. MaterializeMetadata("materialize-metadata",
  59. cl::desc("Load module without materializing metadata, "
  60. "then materialize only the metadata"));
  61. namespace {
  62. static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
  63. OS << DL.getLine() << ":" << DL.getCol();
  64. if (DILocation *IDL = DL.getInlinedAt()) {
  65. OS << "@";
  66. printDebugLoc(IDL, OS);
  67. }
  68. }
  69. class CommentWriter : public AssemblyAnnotationWriter {
  70. public:
  71. void emitFunctionAnnot(const Function *F,
  72. formatted_raw_ostream &OS) override {
  73. OS << "; [#uses=" << F->getNumUses() << ']'; // Output # uses
  74. OS << '\n';
  75. }
  76. void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
  77. bool Padded = false;
  78. if (!V.getType()->isVoidTy()) {
  79. OS.PadToColumn(50);
  80. Padded = true;
  81. // Output # uses and type
  82. OS << "; [#uses=" << V.getNumUses() << " type=" << *V.getType() << "]";
  83. }
  84. if (const Instruction *I = dyn_cast<Instruction>(&V)) {
  85. if (const DebugLoc &DL = I->getDebugLoc()) {
  86. if (!Padded) {
  87. OS.PadToColumn(50);
  88. Padded = true;
  89. OS << ";";
  90. }
  91. OS << " [debug line = ";
  92. printDebugLoc(DL,OS);
  93. OS << "]";
  94. }
  95. if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) {
  96. if (!Padded) {
  97. OS.PadToColumn(50);
  98. OS << ";";
  99. }
  100. OS << " [debug variable = " << DDI->getVariable()->getName() << "]";
  101. }
  102. else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) {
  103. if (!Padded) {
  104. OS.PadToColumn(50);
  105. OS << ";";
  106. }
  107. OS << " [debug variable = " << DVI->getVariable()->getName() << "]";
  108. }
  109. }
  110. }
  111. };
  112. struct LLVMDisDiagnosticHandler : public DiagnosticHandler {
  113. char *Prefix;
  114. LLVMDisDiagnosticHandler(char *PrefixPtr) : Prefix(PrefixPtr) {}
  115. bool handleDiagnostics(const DiagnosticInfo &DI) override {
  116. raw_ostream &OS = errs();
  117. OS << Prefix << ": ";
  118. switch (DI.getSeverity()) {
  119. case DS_Error: WithColor::error(OS); break;
  120. case DS_Warning: WithColor::warning(OS); break;
  121. case DS_Remark: OS << "remark: "; break;
  122. case DS_Note: WithColor::note(OS); break;
  123. }
  124. DiagnosticPrinterRawOStream DP(OS);
  125. DI.print(DP);
  126. OS << '\n';
  127. if (DI.getSeverity() == DS_Error)
  128. exit(1);
  129. return true;
  130. }
  131. };
  132. } // end anon namespace
  133. static ExitOnError ExitOnErr;
  134. static std::unique_ptr<Module> openInputFile(LLVMContext &Context) {
  135. std::unique_ptr<MemoryBuffer> MB =
  136. ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename)));
  137. std::unique_ptr<Module> M = ExitOnErr(getOwningLazyBitcodeModule(
  138. std::move(MB), Context,
  139. /*ShouldLazyLoadMetadata=*/true, SetImporting));
  140. if (MaterializeMetadata)
  141. ExitOnErr(M->materializeMetadata());
  142. else
  143. ExitOnErr(M->materializeAll());
  144. return M;
  145. }
  146. int main(int argc, char **argv) {
  147. InitLLVM X(argc, argv);
  148. ExitOnErr.setBanner(std::string(argv[0]) + ": error: ");
  149. LLVMContext Context;
  150. Context.setDiagnosticHandler(
  151. llvm::make_unique<LLVMDisDiagnosticHandler>(argv[0]));
  152. cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
  153. std::unique_ptr<Module> M = openInputFile(Context);
  154. // Just use stdout. We won't actually print anything on it.
  155. if (DontPrint)
  156. OutputFilename = "-";
  157. if (OutputFilename.empty()) { // Unspecified output, infer it.
  158. if (InputFilename == "-") {
  159. OutputFilename = "-";
  160. } else {
  161. StringRef IFN = InputFilename;
  162. OutputFilename = (IFN.endswith(".bc") ? IFN.drop_back(3) : IFN).str();
  163. OutputFilename += ".ll";
  164. }
  165. }
  166. std::error_code EC;
  167. std::unique_ptr<ToolOutputFile> Out(
  168. new ToolOutputFile(OutputFilename, EC, sys::fs::F_None));
  169. if (EC) {
  170. errs() << EC.message() << '\n';
  171. return 1;
  172. }
  173. std::unique_ptr<AssemblyAnnotationWriter> Annotator;
  174. if (ShowAnnotations)
  175. Annotator.reset(new CommentWriter());
  176. // All that llvm-dis does is write the assembly to a file.
  177. if (!DontPrint)
  178. M->print(Out->os(), Annotator.get(), PreserveAssemblyUseListOrder);
  179. // Declare success.
  180. Out->keep();
  181. return 0;
  182. }