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

Generated by: LCOV version 1.13