1 //===-- ModuleDebugInfoPrinter.cpp - Prints module debug info metadata ----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This pass decodes the debug info metadata in a module and prints in a
10 // (sufficiently-prepared-) human-readable form.
12 // For example, run this pass from opt along with the -analyze option, and
13 // it'll print to standard output.
15 //===----------------------------------------------------------------------===//
17 #include "llvm/Analysis/ModuleDebugInfoPrinter.h"
18 #include "llvm/BinaryFormat/Dwarf.h"
19 #include "llvm/IR/DebugInfo.h"
20 #include "llvm/IR/PassManager.h"
21 #include "llvm/Pass.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/raw_ostream.h"
26 static void printFile(raw_ostream
&O
, StringRef Filename
, StringRef Directory
,
32 if (!Directory
.empty())
33 O
<< Directory
<< "/";
39 static void printModuleDebugInfo(raw_ostream
&O
, const Module
*M
,
40 const DebugInfoFinder
&Finder
) {
41 // Printing the nodes directly isn't particularly helpful (since they
42 // reference other nodes that won't be printed, particularly for the
43 // filenames), so just print a few useful things.
44 for (DICompileUnit
*CU
: Finder
.compile_units()) {
45 O
<< "Compile unit: ";
46 auto Lang
= dwarf::LanguageString(CU
->getSourceLanguage());
50 O
<< "unknown-language(" << CU
->getSourceLanguage() << ")";
51 printFile(O
, CU
->getFilename(), CU
->getDirectory());
55 for (DISubprogram
*S
: Finder
.subprograms()) {
56 O
<< "Subprogram: " << S
->getName();
57 printFile(O
, S
->getFilename(), S
->getDirectory(), S
->getLine());
58 if (!S
->getLinkageName().empty())
59 O
<< " ('" << S
->getLinkageName() << "')";
63 for (auto *GVU
: Finder
.global_variables()) {
64 const auto *GV
= GVU
->getVariable();
65 O
<< "Global variable: " << GV
->getName();
66 printFile(O
, GV
->getFilename(), GV
->getDirectory(), GV
->getLine());
67 if (!GV
->getLinkageName().empty())
68 O
<< " ('" << GV
->getLinkageName() << "')";
72 for (const DIType
*T
: Finder
.types()) {
74 if (!T
->getName().empty())
75 O
<< ' ' << T
->getName();
76 printFile(O
, T
->getFilename(), T
->getDirectory(), T
->getLine());
77 if (auto *BT
= dyn_cast
<DIBasicType
>(T
)) {
79 auto Encoding
= dwarf::AttributeEncodingString(BT
->getEncoding());
80 if (!Encoding
.empty())
83 O
<< "unknown-encoding(" << BT
->getEncoding() << ')';
86 auto Tag
= dwarf::TagString(T
->getTag());
90 O
<< "unknown-tag(" << T
->getTag() << ")";
92 if (auto *CT
= dyn_cast
<DICompositeType
>(T
)) {
93 if (auto *S
= CT
->getRawIdentifier())
94 O
<< " (identifier: '" << S
->getString() << "')";
100 ModuleDebugInfoPrinterPass::ModuleDebugInfoPrinterPass(raw_ostream
&OS
)
103 PreservedAnalyses
ModuleDebugInfoPrinterPass::run(Module
&M
,
104 ModuleAnalysisManager
&AM
) {
105 Finder
.processModule(M
);
106 printModuleDebugInfo(OS
, &M
, Finder
);
107 return PreservedAnalyses::all();