1 //===- DbgInfoPrinter.cpp - Print debug info in a human readable form -----==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements a pass that prints instructions, and associated debug
12 // - source/line/col information
13 // - original variable name
14 // - original type name
16 //===----------------------------------------------------------------------===//
17 #include "llvm/Pass.h"
18 #include "llvm/Function.h"
19 #include "llvm/Module.h"
20 #include "llvm/Value.h"
21 #include "llvm/IntrinsicInst.h"
22 #include "llvm/Assembly/Writer.h"
23 #include "llvm/Analysis/DebugInfo.h"
24 #include "llvm/Analysis/Passes.h"
25 #include "llvm/Analysis/ValueTracking.h"
26 #include "llvm/Support/CFG.h"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/CommandLine.h"
29 #include "llvm/Support/raw_ostream.h"
33 PrintDirectory("print-fullpath", cl::desc("Print fullpath when printing debug info"), cl::Hidden
);
36 struct VISIBILITY_HIDDEN PrintDbgInfo
: public FunctionPass
{
39 void printStopPoint(const DbgStopPointInst
*DSI
);
40 void printFuncStart(const DbgFuncStartInst
*FS
);
41 void printVariableDeclaration(const Value
*V
);
43 static char ID
; // Pass identification
44 PrintDbgInfo() : FunctionPass(&ID
), Out(outs()) {}
46 virtual bool runOnFunction(Function
&F
);
47 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const {
52 char PrintDbgInfo::ID
= 0;
53 static RegisterPass
<PrintDbgInfo
> X("print-dbginfo",
54 "Print debug info in human readable form");
57 FunctionPass
*llvm::createDbgInfoPrinterPass() { return new PrintDbgInfo(); }
59 void PrintDbgInfo::printVariableDeclaration(const Value
*V
)
61 std::string DisplayName
, File
, Directory
, Type
;
63 if (getLocationInfo(V
, DisplayName
, Type
, LineNo
, File
, Directory
)) {
65 WriteAsOperand(Out
, V
, false, 0);
66 Out
<< " is variable " << DisplayName
67 << " of type " << Type
<< " declared at ";
69 Out
<< Directory
<< "/";
71 Out
<< File
<< ":" << LineNo
<< "\n";
75 void PrintDbgInfo::printStopPoint(const DbgStopPointInst
*DSI
)
79 GetConstantStringInfo(DSI
->getDirectory(), dir
);
83 GetConstantStringInfo(DSI
->getFileName(), file
);
84 Out
<< file
<< ":" << DSI
->getLine();
85 if (unsigned Col
= DSI
->getColumn()) {
90 void PrintDbgInfo::printFuncStart(const DbgFuncStartInst
*FS
)
92 DISubprogram
Subprogram(cast
<GlobalVariable
>(FS
->getSubprogram()));
93 std::string Res1
, Res2
;
94 Out
<< ";fully qualified function name: " << Subprogram
.getDisplayName(Res1
)
95 << " return type: " << Subprogram
.getType().getName(Res2
)
96 << " at line " << Subprogram
.getLineNumber()
100 bool PrintDbgInfo::runOnFunction(Function
&F
)
102 if (F
.isDeclaration())
104 Out
<< "function " << F
.getName() << "\n\n";
105 for (Function::iterator I
= F
.begin(), E
= F
.end(); I
!= E
; ++I
) {
107 if (I
!= F
.begin() && (pred_begin(BB
) == pred_end(BB
)))
110 const DbgStopPointInst
*DSI
= findBBStopPoint(BB
);
111 Out
<< BB
->getName();
119 // A dbgstoppoint's information is valid until we encounter a new one.
120 const DbgStopPointInst
*LastDSP
= DSI
;
121 bool printed
= DSI
!= 0;
122 for (BasicBlock::const_iterator i
= BB
->begin(), e
= BB
->end(); i
!= e
; ++i
) {
123 if (isa
<DbgInfoIntrinsic
>(i
)) {
124 if ((DSI
= dyn_cast
<DbgStopPointInst
>(i
))) {
126 if (DSI
->getContext() == LastDSP
->getContext() &&
127 DSI
->getLineValue() == LastDSP
->getLineValue() &&
128 DSI
->getColumnValue() == LastDSP
->getColumnValue()) {
129 // Don't print same location twice.
132 LastDSP
= cast
<DbgStopPointInst
>(i
);
133 // Don't print consecutive stoppoints, use a flag
134 // to know which one we printed.
137 } else if (const DbgFuncStartInst
*FS
= dyn_cast
<DbgFuncStartInst
>(i
)) {
141 if (!printed
&& LastDSP
) {
143 printStopPoint(LastDSP
);
148 printVariableDeclaration(i
);
149 if (const User
*U
= dyn_cast
<User
>(i
)) {
150 for(unsigned i
=0;i
<U
->getNumOperands();i
++) {
151 printVariableDeclaration(U
->getOperand(i
));