2
0

ModuleDebugInfoPrinter.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //===-- ModuleDebugInfoPrinter.cpp - Prints module debug info metadata ----===//
  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 pass decodes the debug info metadata in a module and prints in a
  11. // (sufficiently-prepared-) human-readable form.
  12. //
  13. // For example, run this pass from opt along with the -analyze option, and
  14. // it'll print to standard output.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #include "llvm/Analysis/Passes.h"
  18. #include "llvm/ADT/Statistic.h"
  19. #include "llvm/IR/DebugInfo.h"
  20. #include "llvm/IR/Function.h"
  21. #include "llvm/Pass.h"
  22. #include "llvm/Support/ErrorHandling.h"
  23. #include "llvm/Support/raw_ostream.h"
  24. using namespace llvm;
  25. namespace {
  26. class ModuleDebugInfoPrinter : public ModulePass {
  27. DebugInfoFinder Finder;
  28. public:
  29. static char ID; // Pass identification, replacement for typeid
  30. ModuleDebugInfoPrinter() : ModulePass(ID) {
  31. initializeModuleDebugInfoPrinterPass(*PassRegistry::getPassRegistry());
  32. }
  33. bool runOnModule(Module &M) override;
  34. void getAnalysisUsage(AnalysisUsage &AU) const override {
  35. AU.setPreservesAll();
  36. }
  37. void print(raw_ostream &O, const Module *M) const override;
  38. };
  39. }
  40. char ModuleDebugInfoPrinter::ID = 0;
  41. INITIALIZE_PASS(ModuleDebugInfoPrinter, "module-debuginfo",
  42. "Decodes module-level debug info", false, true)
  43. ModulePass *llvm::createModuleDebugInfoPrinterPass() {
  44. return new ModuleDebugInfoPrinter();
  45. }
  46. bool ModuleDebugInfoPrinter::runOnModule(Module &M) {
  47. Finder.processModule(M);
  48. return false;
  49. }
  50. static void printFile(raw_ostream &O, StringRef Filename, StringRef Directory,
  51. unsigned Line = 0) {
  52. if (Filename.empty())
  53. return;
  54. O << " from ";
  55. if (!Directory.empty())
  56. O << Directory << "/";
  57. O << Filename;
  58. if (Line)
  59. O << ":" << Line;
  60. }
  61. void ModuleDebugInfoPrinter::print(raw_ostream &O, const Module *M) const {
  62. // Printing the nodes directly isn't particularly helpful (since they
  63. // reference other nodes that won't be printed, particularly for the
  64. // filenames), so just print a few useful things.
  65. for (DICompileUnit *CU : Finder.compile_units()) {
  66. O << "Compile unit: ";
  67. if (const char *Lang = dwarf::LanguageString(CU->getSourceLanguage()))
  68. O << Lang;
  69. else
  70. O << "unknown-language(" << CU->getSourceLanguage() << ")";
  71. printFile(O, CU->getFilename(), CU->getDirectory());
  72. O << '\n';
  73. }
  74. for (DISubprogram *S : Finder.subprograms()) {
  75. O << "Subprogram: " << S->getName();
  76. printFile(O, S->getFilename(), S->getDirectory(), S->getLine());
  77. if (!S->getLinkageName().empty())
  78. O << " ('" << S->getLinkageName() << "')";
  79. O << '\n';
  80. }
  81. for (const DIGlobalVariable *GV : Finder.global_variables()) {
  82. O << "Global variable: " << GV->getName();
  83. printFile(O, GV->getFilename(), GV->getDirectory(), GV->getLine());
  84. if (!GV->getLinkageName().empty())
  85. O << " ('" << GV->getLinkageName() << "')";
  86. O << '\n';
  87. }
  88. for (const DIType *T : Finder.types()) {
  89. O << "Type:";
  90. if (!T->getName().empty())
  91. O << ' ' << T->getName();
  92. printFile(O, T->getFilename(), T->getDirectory(), T->getLine());
  93. if (auto *BT = dyn_cast<DIBasicType>(T)) {
  94. O << " ";
  95. if (const char *Encoding =
  96. dwarf::AttributeEncodingString(BT->getEncoding()))
  97. O << Encoding;
  98. else
  99. O << "unknown-encoding(" << BT->getEncoding() << ')';
  100. } else {
  101. O << ' ';
  102. if (const char *Tag = dwarf::TagString(T->getTag()))
  103. O << Tag;
  104. else
  105. O << "unknown-tag(" << T->getTag() << ")";
  106. }
  107. if (auto *CT = dyn_cast<DICompositeType>(T)) {
  108. if (auto *S = CT->getRawIdentifier())
  109. O << " (identifier: '" << S->getString() << "')";
  110. }
  111. O << '\n';
  112. }
  113. }