xref: /aosp_15_r20/external/llvm/lib/Analysis/ModuleDebugInfoPrinter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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