LLVM API Documentation
00001 //===- DbgInfoPrinter.cpp - Print debug info in a human readable form -----==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements a pass that prints instructions, and associated debug 00011 // info: 00012 // - source/line/col information 00013 // - original variable name 00014 // - original type name 00015 // 00016 //===----------------------------------------------------------------------===// 00017 #include "llvm/Pass.h" 00018 #include "llvm/Function.h" 00019 #include "llvm/Module.h" 00020 #include "llvm/Value.h" 00021 #include "llvm/IntrinsicInst.h" 00022 #include "llvm/Analysis/DebugInfo.h" 00023 #include "llvm/Analysis/Passes.h" 00024 #include "llvm/Analysis/ValueTracking.h" 00025 #include "llvm/Support/CFG.h" 00026 #include "llvm/Support/Compiler.h" 00027 #include "llvm/Support/CommandLine.h" 00028 #include "llvm/Support/raw_ostream.h" 00029 using namespace llvm; 00030 00031 static cl::opt<bool> 00032 PrintDirectory("print-fullpath", cl::desc("Print fullpath when printing debug info"), cl::Hidden); 00033 00034 namespace { 00035 struct VISIBILITY_HIDDEN PrintDbgInfo : public FunctionPass { 00036 private: 00037 raw_ostream &Out; 00038 void printStopPoint(const DbgStopPointInst *DSI); 00039 void printFuncStart(const DbgFuncStartInst *FS); 00040 void printVariableDeclaration(const Value *V); 00041 public: 00042 static char ID; // Pass identification 00043 PrintDbgInfo() : FunctionPass(&ID), Out(outs()) {} 00044 00045 virtual bool runOnFunction(Function &F); 00046 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00047 AU.setPreservesAll(); 00048 } 00049 00050 }; 00051 char PrintDbgInfo::ID = 0; 00052 static RegisterPass<PrintDbgInfo> X("print-dbginfo", 00053 "Print debug info in human readable form"); 00054 } 00055 00056 FunctionPass *llvm::createDbgInfoPrinterPass() { return new PrintDbgInfo(); } 00057 00058 void PrintDbgInfo::printVariableDeclaration(const Value *V) 00059 { 00060 if(const DbgDeclareInst* DDI = findDbgDeclare(V)) { 00061 DIVariable Var(cast<GlobalVariable>(DDI->getVariable())); 00062 Out << "; variable " << Var.getName() 00063 << " of type " << Var.getType().getName() 00064 << " at line " << Var.getLineNumber() << "\n"; 00065 } 00066 } 00067 00068 void PrintDbgInfo::printStopPoint(const DbgStopPointInst *DSI) 00069 { 00070 if (PrintDirectory) { 00071 std::string dir; 00072 GetConstantStringInfo(DSI->getDirectory(), dir); 00073 Out << dir << "/"; 00074 } 00075 std::string file; 00076 GetConstantStringInfo(DSI->getFileName(), file); 00077 Out << file << ":" << DSI->getLine(); 00078 if (unsigned Col = DSI->getColumn()) { 00079 Out << ":" << Col; 00080 } 00081 } 00082 00083 void PrintDbgInfo::printFuncStart(const DbgFuncStartInst *FS) 00084 { 00085 DISubprogram Subprogram(cast<GlobalVariable>(FS->getSubprogram())); 00086 Out << ";fully qualified function name: " << Subprogram.getDisplayName() 00087 << " return type: " << Subprogram.getType().getName() 00088 << " at line " << Subprogram.getLineNumber() 00089 << "\n\n"; 00090 } 00091 00092 bool PrintDbgInfo::runOnFunction(Function &F) 00093 { 00094 if (F.isDeclaration()) 00095 return false; 00096 Out << "function " << F.getName() << "\n\n"; 00097 for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { 00098 BasicBlock *BB = I; 00099 if (I != F.begin() && (pred_begin(BB) == pred_end(BB))) 00100 // Skip dead blocks. 00101 continue; 00102 const DbgStopPointInst *DSI = findBBStopPoint(BB); 00103 Out << BB->getName(); 00104 Out << ":"; 00105 if (DSI) { 00106 Out << "; ("; 00107 printStopPoint(DSI); 00108 Out << ")"; 00109 } 00110 Out << "\n"; 00111 // A dbgstoppoint's information is valid until we encounter a new one. 00112 const DbgStopPointInst *LastDSP = DSI; 00113 bool printed = DSI != 0; 00114 for (BasicBlock::const_iterator i = BB->begin(), e = BB->end(); i != e; ++i) { 00115 if (isa<DbgInfoIntrinsic>(i)) { 00116 if ((DSI = dyn_cast<DbgStopPointInst>(i))) { 00117 00118 if (DSI->getContext() == LastDSP->getContext() && 00119 DSI->getLineValue() == LastDSP->getLineValue() && 00120 DSI->getColumnValue() == LastDSP->getColumnValue()) { 00121 // Don't print same location twice. 00122 continue; 00123 } 00124 LastDSP = cast<DbgStopPointInst>(i); 00125 // Don't print consecutive stoppoints, use a flag 00126 // to know which one we printed. 00127 printed = false; 00128 00129 } else if (const DbgFuncStartInst *FS = dyn_cast<DbgFuncStartInst>(i)) { 00130 printFuncStart(FS); 00131 } 00132 } else { 00133 if (!printed && LastDSP) { 00134 Out << "; "; 00135 printStopPoint(LastDSP); 00136 Out << "\n"; 00137 printed = true; 00138 } 00139 Out << *i; 00140 printVariableDeclaration(i); 00141 } 00142 } 00143 } 00144 return false; 00145 }