1 //===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===// 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 #include "llvm/IR/DebugLoc.h" 11 #include "LLVMContextImpl.h" 12 #include "llvm/ADT/DenseMapInfo.h" 13 #include "llvm/IR/DebugInfo.h" 14 using namespace llvm; 15 16 //===----------------------------------------------------------------------===// 17 // DebugLoc Implementation 18 //===----------------------------------------------------------------------===// 19 20 unsigned DebugLoc::getLine() const { return DILocation(Loc).getLineNumber(); } 21 unsigned DebugLoc::getCol() const { return DILocation(Loc).getColumnNumber(); } 22 23 MDNode *DebugLoc::getScope() const { return DILocation(Loc).getScope(); } 24 25 MDNode *DebugLoc::getInlinedAt() const { 26 return DILocation(Loc).getOrigLocation(); 27 } 28 29 /// Return both the Scope and the InlinedAt values. 30 void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const { 31 Scope = getScope(); 32 IA = getInlinedAt(); 33 } 34 35 MDNode *DebugLoc::getScopeNode() const { 36 if (MDNode *InlinedAt = getInlinedAt()) 37 return DebugLoc::getFromDILocation(InlinedAt).getScopeNode(); 38 return getScope(); 39 } 40 41 DebugLoc DebugLoc::getFnDebugLoc() const { 42 const MDNode *Scope = getScopeNode(); 43 DISubprogram SP = getDISubprogram(Scope); 44 if (SP.isSubprogram()) 45 return DebugLoc::get(SP.getScopeLineNumber(), 0, SP); 46 47 return DebugLoc(); 48 } 49 50 DebugLoc DebugLoc::get(unsigned Line, unsigned Col, 51 MDNode *Scope, MDNode *InlinedAt) { 52 // If no scope is available, this is an unknown location. 53 if (!Scope) 54 return DebugLoc(); 55 56 // Saturate line and col to "unknown". 57 // FIXME: Allow 16-bits for columns. 58 if (Col > 255) Col = 0; 59 if (Line >= (1 << 24)) Line = 0; 60 61 return getFromDILocation( 62 MDLocation::get(Scope->getContext(), Line, Col, Scope, InlinedAt)); 63 } 64 65 /// getAsMDNode - This method converts the compressed DebugLoc node into a 66 /// DILocation-compatible MDNode. 67 MDNode *DebugLoc::getAsMDNode() const { return Loc; } 68 69 /// getFromDILocation - Translate the DILocation quad into a DebugLoc. 70 DebugLoc DebugLoc::getFromDILocation(MDNode *N) { 71 DebugLoc Loc; 72 Loc.Loc.reset(N); 73 return Loc; 74 } 75 76 /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc. 77 DebugLoc DebugLoc::getFromDILexicalBlock(MDNode *N) { 78 DILexicalBlock LexBlock(N); 79 MDNode *Scope = LexBlock.getContext(); 80 if (!Scope) return DebugLoc(); 81 return get(LexBlock.getLineNumber(), LexBlock.getColumnNumber(), Scope, 82 nullptr); 83 } 84 85 void DebugLoc::dump() const { 86 #ifndef NDEBUG 87 if (!isUnknown()) { 88 dbgs() << getLine(); 89 if (getCol() != 0) 90 dbgs() << ',' << getCol(); 91 DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt()); 92 if (!InlinedAtDL.isUnknown()) { 93 dbgs() << " @ "; 94 InlinedAtDL.dump(); 95 } else 96 dbgs() << "\n"; 97 } 98 #endif 99 } 100 101 void DebugLoc::print(raw_ostream &OS) const { 102 if (!isUnknown()) { 103 // Print source line info. 104 DIScope Scope(getScope()); 105 assert((!Scope || Scope.isScope()) && 106 "Scope of a DebugLoc should be null or a DIScope."); 107 if (Scope) 108 OS << Scope.getFilename(); 109 else 110 OS << "<unknown>"; 111 OS << ':' << getLine(); 112 if (getCol() != 0) 113 OS << ':' << getCol(); 114 DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt()); 115 if (!InlinedAtDL.isUnknown()) { 116 OS << " @[ "; 117 InlinedAtDL.print(OS); 118 OS << " ]"; 119 } 120 } 121 } 122