LCOV - code coverage report
Current view: top level - lib/Analysis - ModuleDebugInfoPrinter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 46 53 86.8 %
Date: 2018-10-20 13:21:21 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13