1//===- DbgInfoPrinter.cpp - Print debug info in a human readable form ------==//
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 file implements a pass that prints instructions, and associated debug
11// info:
12//
13//   - source/line/col information
14//   - original variable name
15//   - original type name
16//
17//===----------------------------------------------------------------------===//
18
19#include "llvm/DebugInfo.h"
20#include "llvm/Function.h"
21#include "llvm/IntrinsicInst.h"
22#include "llvm/Metadata.h"
23#include "llvm/Module.h"
24#include "llvm/Pass.h"
25#include "llvm/Analysis/Passes.h"
26#include "llvm/Assembly/Writer.h"
27#include "llvm/Support/CFG.h"
28#include "llvm/Support/CommandLine.h"
29#include "llvm/Support/raw_ostream.h"
30
31using namespace llvm;
32
33static cl::opt<bool>
34PrintDirectory("print-fullpath",
35               cl::desc("Print fullpath when printing debug info"),
36               cl::Hidden);
37
38namespace {
39  class PrintDbgInfo : public FunctionPass {
40    raw_ostream &Out;
41    void printVariableDeclaration(const Value *V);
42  public:
43    static char ID; // Pass identification
44    PrintDbgInfo() : FunctionPass(ID), Out(errs()) {
45      initializePrintDbgInfoPass(*PassRegistry::getPassRegistry());
46    }
47
48    virtual bool runOnFunction(Function &F);
49    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
50      AU.setPreservesAll();
51    }
52  };
53  char PrintDbgInfo::ID = 0;
54}
55
56INITIALIZE_PASS(PrintDbgInfo, "print-dbginfo",
57                "Print debug info in human readable form", false, false)
58
59FunctionPass *llvm::createDbgInfoPrinterPass() { return new PrintDbgInfo(); }
60
61/// Find the debug info descriptor corresponding to this global variable.
62static Value *findDbgGlobalDeclare(GlobalVariable *V) {
63  const Module *M = V->getParent();
64  NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv");
65  if (!NMD)
66    return 0;
67
68  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
69    DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
70    if (!DIG.isGlobalVariable())
71      continue;
72    if (DIGlobalVariable(DIG).getGlobal() == V)
73      return DIG;
74  }
75  return 0;
76}
77
78/// Find the debug info descriptor corresponding to this function.
79static Value *findDbgSubprogramDeclare(Function *V) {
80  const Module *M = V->getParent();
81  NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp");
82  if (!NMD)
83    return 0;
84
85  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
86    DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
87    if (!DIG.isSubprogram())
88      continue;
89    if (DISubprogram(DIG).getFunction() == V)
90      return DIG;
91  }
92  return 0;
93}
94
95/// Finds the llvm.dbg.declare intrinsic corresponding to this value if any.
96/// It looks through pointer casts too.
97static const DbgDeclareInst *findDbgDeclare(const Value *V) {
98  V = V->stripPointerCasts();
99
100  if (!isa<Instruction>(V) && !isa<Argument>(V))
101    return 0;
102
103  const Function *F = NULL;
104  if (const Instruction *I = dyn_cast<Instruction>(V))
105    F = I->getParent()->getParent();
106  else if (const Argument *A = dyn_cast<Argument>(V))
107    F = A->getParent();
108
109  for (Function::const_iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
110    for (BasicBlock::const_iterator BI = (*FI).begin(), BE = (*FI).end();
111         BI != BE; ++BI)
112      if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
113        if (DDI->getAddress() == V)
114          return DDI;
115
116  return 0;
117}
118
119static bool getLocationInfo(const Value *V, std::string &DisplayName,
120                            std::string &Type, unsigned &LineNo,
121                            std::string &File, std::string &Dir) {
122  DICompileUnit Unit;
123  DIType TypeD;
124
125  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) {
126    Value *DIGV = findDbgGlobalDeclare(GV);
127    if (!DIGV) return false;
128    DIGlobalVariable Var(cast<MDNode>(DIGV));
129
130    StringRef D = Var.getDisplayName();
131    if (!D.empty())
132      DisplayName = D;
133    LineNo = Var.getLineNumber();
134    Unit = Var.getCompileUnit();
135    TypeD = Var.getType();
136  } else if (Function *F = dyn_cast<Function>(const_cast<Value*>(V))){
137    Value *DIF = findDbgSubprogramDeclare(F);
138    if (!DIF) return false;
139    DISubprogram Var(cast<MDNode>(DIF));
140
141    StringRef D = Var.getDisplayName();
142    if (!D.empty())
143      DisplayName = D;
144    LineNo = Var.getLineNumber();
145    Unit = Var.getCompileUnit();
146    TypeD = Var.getType();
147  } else {
148    const DbgDeclareInst *DDI = findDbgDeclare(V);
149    if (!DDI) return false;
150    DIVariable Var(cast<MDNode>(DDI->getVariable()));
151
152    StringRef D = Var.getName();
153    if (!D.empty())
154      DisplayName = D;
155    LineNo = Var.getLineNumber();
156    Unit = Var.getCompileUnit();
157    TypeD = Var.getType();
158  }
159
160  StringRef T = TypeD.getName();
161  if (!T.empty())
162    Type = T;
163  StringRef F = Unit.getFilename();
164  if (!F.empty())
165    File = F;
166  StringRef D = Unit.getDirectory();
167  if (!D.empty())
168    Dir = D;
169  return true;
170}
171
172void PrintDbgInfo::printVariableDeclaration(const Value *V) {
173  std::string DisplayName, File, Directory, Type;
174  unsigned LineNo = 0;
175
176  if (!getLocationInfo(V, DisplayName, Type, LineNo, File, Directory))
177    return;
178
179  Out << "; ";
180  WriteAsOperand(Out, V, false, 0);
181  if (isa<Function>(V))
182    Out << " is function " << DisplayName
183        << " of type " << Type << " declared at ";
184  else
185    Out << " is variable " << DisplayName
186        << " of type " << Type << " declared at ";
187
188  if (PrintDirectory)
189    Out << Directory << "/";
190
191  Out << File << ":" << LineNo << "\n";
192}
193
194bool PrintDbgInfo::runOnFunction(Function &F) {
195  if (F.isDeclaration())
196    return false;
197
198  Out << "function " << F.getName() << "\n\n";
199
200  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
201    BasicBlock *BB = I;
202
203    if (I != F.begin() && (pred_begin(BB) == pred_end(BB)))
204      // Skip dead blocks.
205      continue;
206
207    Out << BB->getName();
208    Out << ":";
209
210    Out << "\n";
211
212    for (BasicBlock::const_iterator i = BB->begin(), e = BB->end();
213         i != e; ++i) {
214
215        printVariableDeclaration(i);
216
217        if (const User *U = dyn_cast<User>(i)) {
218          for(unsigned i=0;i<U->getNumOperands();i++)
219            printVariableDeclaration(U->getOperand(i));
220        }
221    }
222  }
223  return false;
224}
225