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