1*9880d681SAndroid Build Coastguard Worker //===--- DebugInfo.cpp - Debug Information Helper Classes -----------------===//
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 file implements the helper classes used to build and interpret debug
11*9880d681SAndroid Build Coastguard Worker // information in LLVM IR form.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "LLVMContextImpl.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DIBuilder.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GVMaterializer.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Intrinsics.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/ValueHandle.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Dwarf.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
31*9880d681SAndroid Build Coastguard Worker using namespace llvm;
32*9880d681SAndroid Build Coastguard Worker using namespace llvm::dwarf;
33*9880d681SAndroid Build Coastguard Worker
getDISubprogram(const MDNode * Scope)34*9880d681SAndroid Build Coastguard Worker DISubprogram *llvm::getDISubprogram(const MDNode *Scope) {
35*9880d681SAndroid Build Coastguard Worker if (auto *LocalScope = dyn_cast_or_null<DILocalScope>(Scope))
36*9880d681SAndroid Build Coastguard Worker return LocalScope->getSubprogram();
37*9880d681SAndroid Build Coastguard Worker return nullptr;
38*9880d681SAndroid Build Coastguard Worker }
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
41*9880d681SAndroid Build Coastguard Worker // DebugInfoFinder implementations.
42*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
43*9880d681SAndroid Build Coastguard Worker
reset()44*9880d681SAndroid Build Coastguard Worker void DebugInfoFinder::reset() {
45*9880d681SAndroid Build Coastguard Worker CUs.clear();
46*9880d681SAndroid Build Coastguard Worker SPs.clear();
47*9880d681SAndroid Build Coastguard Worker GVs.clear();
48*9880d681SAndroid Build Coastguard Worker TYs.clear();
49*9880d681SAndroid Build Coastguard Worker Scopes.clear();
50*9880d681SAndroid Build Coastguard Worker NodesSeen.clear();
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker
processModule(const Module & M)53*9880d681SAndroid Build Coastguard Worker void DebugInfoFinder::processModule(const Module &M) {
54*9880d681SAndroid Build Coastguard Worker for (auto *CU : M.debug_compile_units()) {
55*9880d681SAndroid Build Coastguard Worker addCompileUnit(CU);
56*9880d681SAndroid Build Coastguard Worker for (auto *DIG : CU->getGlobalVariables()) {
57*9880d681SAndroid Build Coastguard Worker if (addGlobalVariable(DIG)) {
58*9880d681SAndroid Build Coastguard Worker processScope(DIG->getScope());
59*9880d681SAndroid Build Coastguard Worker processType(DIG->getType().resolve());
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker for (auto *ET : CU->getEnumTypes())
63*9880d681SAndroid Build Coastguard Worker processType(ET);
64*9880d681SAndroid Build Coastguard Worker for (auto *RT : CU->getRetainedTypes())
65*9880d681SAndroid Build Coastguard Worker if (auto *T = dyn_cast<DIType>(RT))
66*9880d681SAndroid Build Coastguard Worker processType(T);
67*9880d681SAndroid Build Coastguard Worker else
68*9880d681SAndroid Build Coastguard Worker processSubprogram(cast<DISubprogram>(RT));
69*9880d681SAndroid Build Coastguard Worker for (auto *Import : CU->getImportedEntities()) {
70*9880d681SAndroid Build Coastguard Worker auto *Entity = Import->getEntity().resolve();
71*9880d681SAndroid Build Coastguard Worker if (auto *T = dyn_cast<DIType>(Entity))
72*9880d681SAndroid Build Coastguard Worker processType(T);
73*9880d681SAndroid Build Coastguard Worker else if (auto *SP = dyn_cast<DISubprogram>(Entity))
74*9880d681SAndroid Build Coastguard Worker processSubprogram(SP);
75*9880d681SAndroid Build Coastguard Worker else if (auto *NS = dyn_cast<DINamespace>(Entity))
76*9880d681SAndroid Build Coastguard Worker processScope(NS->getScope());
77*9880d681SAndroid Build Coastguard Worker else if (auto *M = dyn_cast<DIModule>(Entity))
78*9880d681SAndroid Build Coastguard Worker processScope(M->getScope());
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker for (auto &F : M.functions())
82*9880d681SAndroid Build Coastguard Worker if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram()))
83*9880d681SAndroid Build Coastguard Worker processSubprogram(SP);
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker
processLocation(const Module & M,const DILocation * Loc)86*9880d681SAndroid Build Coastguard Worker void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) {
87*9880d681SAndroid Build Coastguard Worker if (!Loc)
88*9880d681SAndroid Build Coastguard Worker return;
89*9880d681SAndroid Build Coastguard Worker processScope(Loc->getScope());
90*9880d681SAndroid Build Coastguard Worker processLocation(M, Loc->getInlinedAt());
91*9880d681SAndroid Build Coastguard Worker }
92*9880d681SAndroid Build Coastguard Worker
processType(DIType * DT)93*9880d681SAndroid Build Coastguard Worker void DebugInfoFinder::processType(DIType *DT) {
94*9880d681SAndroid Build Coastguard Worker if (!addType(DT))
95*9880d681SAndroid Build Coastguard Worker return;
96*9880d681SAndroid Build Coastguard Worker processScope(DT->getScope().resolve());
97*9880d681SAndroid Build Coastguard Worker if (auto *ST = dyn_cast<DISubroutineType>(DT)) {
98*9880d681SAndroid Build Coastguard Worker for (DITypeRef Ref : ST->getTypeArray())
99*9880d681SAndroid Build Coastguard Worker processType(Ref.resolve());
100*9880d681SAndroid Build Coastguard Worker return;
101*9880d681SAndroid Build Coastguard Worker }
102*9880d681SAndroid Build Coastguard Worker if (auto *DCT = dyn_cast<DICompositeType>(DT)) {
103*9880d681SAndroid Build Coastguard Worker processType(DCT->getBaseType().resolve());
104*9880d681SAndroid Build Coastguard Worker for (Metadata *D : DCT->getElements()) {
105*9880d681SAndroid Build Coastguard Worker if (auto *T = dyn_cast<DIType>(D))
106*9880d681SAndroid Build Coastguard Worker processType(T);
107*9880d681SAndroid Build Coastguard Worker else if (auto *SP = dyn_cast<DISubprogram>(D))
108*9880d681SAndroid Build Coastguard Worker processSubprogram(SP);
109*9880d681SAndroid Build Coastguard Worker }
110*9880d681SAndroid Build Coastguard Worker return;
111*9880d681SAndroid Build Coastguard Worker }
112*9880d681SAndroid Build Coastguard Worker if (auto *DDT = dyn_cast<DIDerivedType>(DT)) {
113*9880d681SAndroid Build Coastguard Worker processType(DDT->getBaseType().resolve());
114*9880d681SAndroid Build Coastguard Worker }
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker
processScope(DIScope * Scope)117*9880d681SAndroid Build Coastguard Worker void DebugInfoFinder::processScope(DIScope *Scope) {
118*9880d681SAndroid Build Coastguard Worker if (!Scope)
119*9880d681SAndroid Build Coastguard Worker return;
120*9880d681SAndroid Build Coastguard Worker if (auto *Ty = dyn_cast<DIType>(Scope)) {
121*9880d681SAndroid Build Coastguard Worker processType(Ty);
122*9880d681SAndroid Build Coastguard Worker return;
123*9880d681SAndroid Build Coastguard Worker }
124*9880d681SAndroid Build Coastguard Worker if (auto *CU = dyn_cast<DICompileUnit>(Scope)) {
125*9880d681SAndroid Build Coastguard Worker addCompileUnit(CU);
126*9880d681SAndroid Build Coastguard Worker return;
127*9880d681SAndroid Build Coastguard Worker }
128*9880d681SAndroid Build Coastguard Worker if (auto *SP = dyn_cast<DISubprogram>(Scope)) {
129*9880d681SAndroid Build Coastguard Worker processSubprogram(SP);
130*9880d681SAndroid Build Coastguard Worker return;
131*9880d681SAndroid Build Coastguard Worker }
132*9880d681SAndroid Build Coastguard Worker if (!addScope(Scope))
133*9880d681SAndroid Build Coastguard Worker return;
134*9880d681SAndroid Build Coastguard Worker if (auto *LB = dyn_cast<DILexicalBlockBase>(Scope)) {
135*9880d681SAndroid Build Coastguard Worker processScope(LB->getScope());
136*9880d681SAndroid Build Coastguard Worker } else if (auto *NS = dyn_cast<DINamespace>(Scope)) {
137*9880d681SAndroid Build Coastguard Worker processScope(NS->getScope());
138*9880d681SAndroid Build Coastguard Worker } else if (auto *M = dyn_cast<DIModule>(Scope)) {
139*9880d681SAndroid Build Coastguard Worker processScope(M->getScope());
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker }
142*9880d681SAndroid Build Coastguard Worker
processSubprogram(DISubprogram * SP)143*9880d681SAndroid Build Coastguard Worker void DebugInfoFinder::processSubprogram(DISubprogram *SP) {
144*9880d681SAndroid Build Coastguard Worker if (!addSubprogram(SP))
145*9880d681SAndroid Build Coastguard Worker return;
146*9880d681SAndroid Build Coastguard Worker processScope(SP->getScope().resolve());
147*9880d681SAndroid Build Coastguard Worker processType(SP->getType());
148*9880d681SAndroid Build Coastguard Worker for (auto *Element : SP->getTemplateParams()) {
149*9880d681SAndroid Build Coastguard Worker if (auto *TType = dyn_cast<DITemplateTypeParameter>(Element)) {
150*9880d681SAndroid Build Coastguard Worker processType(TType->getType().resolve());
151*9880d681SAndroid Build Coastguard Worker } else if (auto *TVal = dyn_cast<DITemplateValueParameter>(Element)) {
152*9880d681SAndroid Build Coastguard Worker processType(TVal->getType().resolve());
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker
processDeclare(const Module & M,const DbgDeclareInst * DDI)157*9880d681SAndroid Build Coastguard Worker void DebugInfoFinder::processDeclare(const Module &M,
158*9880d681SAndroid Build Coastguard Worker const DbgDeclareInst *DDI) {
159*9880d681SAndroid Build Coastguard Worker auto *N = dyn_cast<MDNode>(DDI->getVariable());
160*9880d681SAndroid Build Coastguard Worker if (!N)
161*9880d681SAndroid Build Coastguard Worker return;
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker auto *DV = dyn_cast<DILocalVariable>(N);
164*9880d681SAndroid Build Coastguard Worker if (!DV)
165*9880d681SAndroid Build Coastguard Worker return;
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker if (!NodesSeen.insert(DV).second)
168*9880d681SAndroid Build Coastguard Worker return;
169*9880d681SAndroid Build Coastguard Worker processScope(DV->getScope());
170*9880d681SAndroid Build Coastguard Worker processType(DV->getType().resolve());
171*9880d681SAndroid Build Coastguard Worker }
172*9880d681SAndroid Build Coastguard Worker
processValue(const Module & M,const DbgValueInst * DVI)173*9880d681SAndroid Build Coastguard Worker void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
174*9880d681SAndroid Build Coastguard Worker auto *N = dyn_cast<MDNode>(DVI->getVariable());
175*9880d681SAndroid Build Coastguard Worker if (!N)
176*9880d681SAndroid Build Coastguard Worker return;
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker auto *DV = dyn_cast<DILocalVariable>(N);
179*9880d681SAndroid Build Coastguard Worker if (!DV)
180*9880d681SAndroid Build Coastguard Worker return;
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker if (!NodesSeen.insert(DV).second)
183*9880d681SAndroid Build Coastguard Worker return;
184*9880d681SAndroid Build Coastguard Worker processScope(DV->getScope());
185*9880d681SAndroid Build Coastguard Worker processType(DV->getType().resolve());
186*9880d681SAndroid Build Coastguard Worker }
187*9880d681SAndroid Build Coastguard Worker
addType(DIType * DT)188*9880d681SAndroid Build Coastguard Worker bool DebugInfoFinder::addType(DIType *DT) {
189*9880d681SAndroid Build Coastguard Worker if (!DT)
190*9880d681SAndroid Build Coastguard Worker return false;
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker if (!NodesSeen.insert(DT).second)
193*9880d681SAndroid Build Coastguard Worker return false;
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker TYs.push_back(const_cast<DIType *>(DT));
196*9880d681SAndroid Build Coastguard Worker return true;
197*9880d681SAndroid Build Coastguard Worker }
198*9880d681SAndroid Build Coastguard Worker
addCompileUnit(DICompileUnit * CU)199*9880d681SAndroid Build Coastguard Worker bool DebugInfoFinder::addCompileUnit(DICompileUnit *CU) {
200*9880d681SAndroid Build Coastguard Worker if (!CU)
201*9880d681SAndroid Build Coastguard Worker return false;
202*9880d681SAndroid Build Coastguard Worker if (!NodesSeen.insert(CU).second)
203*9880d681SAndroid Build Coastguard Worker return false;
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker CUs.push_back(CU);
206*9880d681SAndroid Build Coastguard Worker return true;
207*9880d681SAndroid Build Coastguard Worker }
208*9880d681SAndroid Build Coastguard Worker
addGlobalVariable(DIGlobalVariable * DIG)209*9880d681SAndroid Build Coastguard Worker bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable *DIG) {
210*9880d681SAndroid Build Coastguard Worker if (!DIG)
211*9880d681SAndroid Build Coastguard Worker return false;
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Worker if (!NodesSeen.insert(DIG).second)
214*9880d681SAndroid Build Coastguard Worker return false;
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker GVs.push_back(DIG);
217*9880d681SAndroid Build Coastguard Worker return true;
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker
addSubprogram(DISubprogram * SP)220*9880d681SAndroid Build Coastguard Worker bool DebugInfoFinder::addSubprogram(DISubprogram *SP) {
221*9880d681SAndroid Build Coastguard Worker if (!SP)
222*9880d681SAndroid Build Coastguard Worker return false;
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Worker if (!NodesSeen.insert(SP).second)
225*9880d681SAndroid Build Coastguard Worker return false;
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker SPs.push_back(SP);
228*9880d681SAndroid Build Coastguard Worker return true;
229*9880d681SAndroid Build Coastguard Worker }
230*9880d681SAndroid Build Coastguard Worker
addScope(DIScope * Scope)231*9880d681SAndroid Build Coastguard Worker bool DebugInfoFinder::addScope(DIScope *Scope) {
232*9880d681SAndroid Build Coastguard Worker if (!Scope)
233*9880d681SAndroid Build Coastguard Worker return false;
234*9880d681SAndroid Build Coastguard Worker // FIXME: Ocaml binding generates a scope with no content, we treat it
235*9880d681SAndroid Build Coastguard Worker // as null for now.
236*9880d681SAndroid Build Coastguard Worker if (Scope->getNumOperands() == 0)
237*9880d681SAndroid Build Coastguard Worker return false;
238*9880d681SAndroid Build Coastguard Worker if (!NodesSeen.insert(Scope).second)
239*9880d681SAndroid Build Coastguard Worker return false;
240*9880d681SAndroid Build Coastguard Worker Scopes.push_back(Scope);
241*9880d681SAndroid Build Coastguard Worker return true;
242*9880d681SAndroid Build Coastguard Worker }
243*9880d681SAndroid Build Coastguard Worker
stripDebugInfo(Function & F)244*9880d681SAndroid Build Coastguard Worker bool llvm::stripDebugInfo(Function &F) {
245*9880d681SAndroid Build Coastguard Worker bool Changed = false;
246*9880d681SAndroid Build Coastguard Worker if (F.getSubprogram()) {
247*9880d681SAndroid Build Coastguard Worker Changed = true;
248*9880d681SAndroid Build Coastguard Worker F.setSubprogram(nullptr);
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker for (BasicBlock &BB : F) {
252*9880d681SAndroid Build Coastguard Worker for (auto II = BB.begin(), End = BB.end(); II != End;) {
253*9880d681SAndroid Build Coastguard Worker Instruction &I = *II++; // We may delete the instruction, increment now.
254*9880d681SAndroid Build Coastguard Worker if (isa<DbgInfoIntrinsic>(&I)) {
255*9880d681SAndroid Build Coastguard Worker I.eraseFromParent();
256*9880d681SAndroid Build Coastguard Worker Changed = true;
257*9880d681SAndroid Build Coastguard Worker continue;
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker if (I.getDebugLoc()) {
260*9880d681SAndroid Build Coastguard Worker Changed = true;
261*9880d681SAndroid Build Coastguard Worker I.setDebugLoc(DebugLoc());
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker }
264*9880d681SAndroid Build Coastguard Worker }
265*9880d681SAndroid Build Coastguard Worker return Changed;
266*9880d681SAndroid Build Coastguard Worker }
267*9880d681SAndroid Build Coastguard Worker
StripDebugInfo(Module & M)268*9880d681SAndroid Build Coastguard Worker bool llvm::StripDebugInfo(Module &M) {
269*9880d681SAndroid Build Coastguard Worker bool Changed = false;
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker for (Module::named_metadata_iterator NMI = M.named_metadata_begin(),
272*9880d681SAndroid Build Coastguard Worker NME = M.named_metadata_end(); NMI != NME;) {
273*9880d681SAndroid Build Coastguard Worker NamedMDNode *NMD = &*NMI;
274*9880d681SAndroid Build Coastguard Worker ++NMI;
275*9880d681SAndroid Build Coastguard Worker if (NMD->getName().startswith("llvm.dbg.")) {
276*9880d681SAndroid Build Coastguard Worker NMD->eraseFromParent();
277*9880d681SAndroid Build Coastguard Worker Changed = true;
278*9880d681SAndroid Build Coastguard Worker }
279*9880d681SAndroid Build Coastguard Worker }
280*9880d681SAndroid Build Coastguard Worker
281*9880d681SAndroid Build Coastguard Worker for (Function &F : M)
282*9880d681SAndroid Build Coastguard Worker Changed |= stripDebugInfo(F);
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker if (GVMaterializer *Materializer = M.getMaterializer())
285*9880d681SAndroid Build Coastguard Worker Materializer->setStripDebugInfo();
286*9880d681SAndroid Build Coastguard Worker
287*9880d681SAndroid Build Coastguard Worker return Changed;
288*9880d681SAndroid Build Coastguard Worker }
289*9880d681SAndroid Build Coastguard Worker
getDebugMetadataVersionFromModule(const Module & M)290*9880d681SAndroid Build Coastguard Worker unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
291*9880d681SAndroid Build Coastguard Worker if (auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(
292*9880d681SAndroid Build Coastguard Worker M.getModuleFlag("Debug Info Version")))
293*9880d681SAndroid Build Coastguard Worker return Val->getZExtValue();
294*9880d681SAndroid Build Coastguard Worker return 0;
295*9880d681SAndroid Build Coastguard Worker }
296