1249259Sdim//===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===// 2249259Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6249259Sdim// 7249259Sdim//===----------------------------------------------------------------------===// 8249259Sdim 9276479Sdim#include "llvm/IR/DebugLoc.h" 10249259Sdim#include "LLVMContextImpl.h" 11341825Sdim#include "llvm/Config/llvm-config.h" 12276479Sdim#include "llvm/IR/DebugInfo.h" 13249259Sdimusing namespace llvm; 14249259Sdim 15249259Sdim//===----------------------------------------------------------------------===// 16249259Sdim// DebugLoc Implementation 17249259Sdim//===----------------------------------------------------------------------===// 18288943SdimDebugLoc::DebugLoc(const DILocation *L) : Loc(const_cast<DILocation *>(L)) {} 19288943SdimDebugLoc::DebugLoc(const MDNode *L) : Loc(const_cast<MDNode *>(L)) {} 20249259Sdim 21288943SdimDILocation *DebugLoc::get() const { 22288943Sdim return cast_or_null<DILocation>(Loc.get()); 23288943Sdim} 24249259Sdim 25288943Sdimunsigned DebugLoc::getLine() const { 26288943Sdim assert(get() && "Expected valid DebugLoc"); 27288943Sdim return get()->getLine(); 28288943Sdim} 29280031Sdim 30288943Sdimunsigned DebugLoc::getCol() const { 31288943Sdim assert(get() && "Expected valid DebugLoc"); 32288943Sdim return get()->getColumn(); 33249259Sdim} 34249259Sdim 35288943SdimMDNode *DebugLoc::getScope() const { 36288943Sdim assert(get() && "Expected valid DebugLoc"); 37288943Sdim return get()->getScope(); 38249259Sdim} 39249259Sdim 40288943SdimDILocation *DebugLoc::getInlinedAt() const { 41288943Sdim assert(get() && "Expected valid DebugLoc"); 42288943Sdim return get()->getInlinedAt(); 43276479Sdim} 44249259Sdim 45288943SdimMDNode *DebugLoc::getInlinedAtScope() const { 46288943Sdim return cast<DILocation>(Loc)->getInlinedAtScope(); 47288943Sdim} 48288943Sdim 49280031SdimDebugLoc DebugLoc::getFnDebugLoc() const { 50288943Sdim // FIXME: Add a method on \a DILocation that does this work. 51288943Sdim const MDNode *Scope = getInlinedAtScope(); 52288943Sdim if (auto *SP = getDISubprogram(Scope)) 53288943Sdim return DebugLoc::get(SP->getScopeLine(), 0, SP); 54276479Sdim 55276479Sdim return DebugLoc(); 56276479Sdim} 57276479Sdim 58344779Sdimbool DebugLoc::isImplicitCode() const { 59344779Sdim if (DILocation *Loc = get()) { 60344779Sdim return Loc->isImplicitCode(); 61344779Sdim } 62344779Sdim return true; 63344779Sdim} 64344779Sdim 65344779Sdimvoid DebugLoc::setImplicitCode(bool ImplicitCode) { 66344779Sdim if (DILocation *Loc = get()) { 67344779Sdim Loc->setImplicitCode(ImplicitCode); 68344779Sdim } 69344779Sdim} 70344779Sdim 71288943SdimDebugLoc DebugLoc::get(unsigned Line, unsigned Col, const MDNode *Scope, 72344779Sdim const MDNode *InlinedAt, bool ImplicitCode) { 73249259Sdim // If no scope is available, this is an unknown location. 74280031Sdim if (!Scope) 75280031Sdim return DebugLoc(); 76276479Sdim 77288943Sdim return DILocation::get(Scope->getContext(), Line, Col, 78288943Sdim const_cast<MDNode *>(Scope), 79344779Sdim const_cast<MDNode *>(InlinedAt), ImplicitCode); 80249259Sdim} 81249259Sdim 82321369SdimDebugLoc DebugLoc::appendInlinedAt(DebugLoc DL, DILocation *InlinedAt, 83321369Sdim LLVMContext &Ctx, 84321369Sdim DenseMap<const MDNode *, MDNode *> &Cache, 85321369Sdim bool ReplaceLast) { 86321369Sdim SmallVector<DILocation *, 3> InlinedAtLocations; 87321369Sdim DILocation *Last = InlinedAt; 88321369Sdim DILocation *CurInlinedAt = DL; 89321369Sdim 90321369Sdim // Gather all the inlined-at nodes. 91321369Sdim while (DILocation *IA = CurInlinedAt->getInlinedAt()) { 92321369Sdim // Skip any we've already built nodes for. 93321369Sdim if (auto *Found = Cache[IA]) { 94321369Sdim Last = cast<DILocation>(Found); 95321369Sdim break; 96321369Sdim } 97321369Sdim 98321369Sdim if (ReplaceLast && !IA->getInlinedAt()) 99321369Sdim break; 100321369Sdim InlinedAtLocations.push_back(IA); 101321369Sdim CurInlinedAt = IA; 102321369Sdim } 103321369Sdim 104321369Sdim // Starting from the top, rebuild the nodes to point to the new inlined-at 105321369Sdim // location (then rebuilding the rest of the chain behind it) and update the 106321369Sdim // map of already-constructed inlined-at nodes. 107321369Sdim for (const DILocation *MD : reverse(InlinedAtLocations)) 108321369Sdim Cache[MD] = Last = DILocation::getDistinct( 109321369Sdim Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last); 110321369Sdim 111321369Sdim return Last; 112321369Sdim} 113321369Sdim 114321369Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 115341825SdimLLVM_DUMP_METHOD void DebugLoc::dump() const { print(dbgs()); } 116249259Sdim#endif 117249259Sdim 118280031Sdimvoid DebugLoc::print(raw_ostream &OS) const { 119288943Sdim if (!Loc) 120288943Sdim return; 121288943Sdim 122288943Sdim // Print source line info. 123288943Sdim auto *Scope = cast<DIScope>(getScope()); 124288943Sdim OS << Scope->getFilename(); 125288943Sdim OS << ':' << getLine(); 126288943Sdim if (getCol() != 0) 127288943Sdim OS << ':' << getCol(); 128288943Sdim 129288943Sdim if (DebugLoc InlinedAtDL = getInlinedAt()) { 130288943Sdim OS << " @[ "; 131288943Sdim InlinedAtDL.print(OS); 132288943Sdim OS << " ]"; 133276479Sdim } 134276479Sdim} 135