109467b48Spatrick //===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick
909467b48Spatrick #include "llvm/IR/DebugLoc.h"
1009467b48Spatrick #include "llvm/Config/llvm-config.h"
1109467b48Spatrick #include "llvm/IR/DebugInfo.h"
1209467b48Spatrick using namespace llvm;
1309467b48Spatrick
1409467b48Spatrick //===----------------------------------------------------------------------===//
1509467b48Spatrick // DebugLoc Implementation
1609467b48Spatrick //===----------------------------------------------------------------------===//
DebugLoc(const DILocation * L)1709467b48Spatrick DebugLoc::DebugLoc(const DILocation *L) : Loc(const_cast<DILocation *>(L)) {}
DebugLoc(const MDNode * L)1809467b48Spatrick DebugLoc::DebugLoc(const MDNode *L) : Loc(const_cast<MDNode *>(L)) {}
1909467b48Spatrick
get() const2009467b48Spatrick DILocation *DebugLoc::get() const {
2109467b48Spatrick return cast_or_null<DILocation>(Loc.get());
2209467b48Spatrick }
2309467b48Spatrick
getLine() const2409467b48Spatrick unsigned DebugLoc::getLine() const {
2509467b48Spatrick assert(get() && "Expected valid DebugLoc");
2609467b48Spatrick return get()->getLine();
2709467b48Spatrick }
2809467b48Spatrick
getCol() const2909467b48Spatrick unsigned DebugLoc::getCol() const {
3009467b48Spatrick assert(get() && "Expected valid DebugLoc");
3109467b48Spatrick return get()->getColumn();
3209467b48Spatrick }
3309467b48Spatrick
getScope() const3409467b48Spatrick MDNode *DebugLoc::getScope() const {
3509467b48Spatrick assert(get() && "Expected valid DebugLoc");
3609467b48Spatrick return get()->getScope();
3709467b48Spatrick }
3809467b48Spatrick
getInlinedAt() const3909467b48Spatrick DILocation *DebugLoc::getInlinedAt() const {
4009467b48Spatrick assert(get() && "Expected valid DebugLoc");
4109467b48Spatrick return get()->getInlinedAt();
4209467b48Spatrick }
4309467b48Spatrick
getInlinedAtScope() const4409467b48Spatrick MDNode *DebugLoc::getInlinedAtScope() const {
4509467b48Spatrick return cast<DILocation>(Loc)->getInlinedAtScope();
4609467b48Spatrick }
4709467b48Spatrick
getFnDebugLoc() const4809467b48Spatrick DebugLoc DebugLoc::getFnDebugLoc() const {
4909467b48Spatrick // FIXME: Add a method on \a DILocation that does this work.
5009467b48Spatrick const MDNode *Scope = getInlinedAtScope();
5109467b48Spatrick if (auto *SP = getDISubprogram(Scope))
5273471bf0Spatrick return DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
5309467b48Spatrick
5409467b48Spatrick return DebugLoc();
5509467b48Spatrick }
5609467b48Spatrick
isImplicitCode() const5709467b48Spatrick bool DebugLoc::isImplicitCode() const {
5809467b48Spatrick if (DILocation *Loc = get()) {
5909467b48Spatrick return Loc->isImplicitCode();
6009467b48Spatrick }
6109467b48Spatrick return true;
6209467b48Spatrick }
6309467b48Spatrick
setImplicitCode(bool ImplicitCode)6409467b48Spatrick void DebugLoc::setImplicitCode(bool ImplicitCode) {
6509467b48Spatrick if (DILocation *Loc = get()) {
6609467b48Spatrick Loc->setImplicitCode(ImplicitCode);
6709467b48Spatrick }
6809467b48Spatrick }
6909467b48Spatrick
replaceInlinedAtSubprogram(const DebugLoc & RootLoc,DISubprogram & NewSP,LLVMContext & Ctx,DenseMap<const MDNode *,MDNode * > & Cache)70*d415bd75Srobert DebugLoc DebugLoc::replaceInlinedAtSubprogram(
71*d415bd75Srobert const DebugLoc &RootLoc, DISubprogram &NewSP, LLVMContext &Ctx,
72*d415bd75Srobert DenseMap<const MDNode *, MDNode *> &Cache) {
73*d415bd75Srobert SmallVector<DILocation *> LocChain;
74*d415bd75Srobert DILocation *CachedResult = nullptr;
75*d415bd75Srobert
76*d415bd75Srobert // Collect the inline chain, stopping if we find a location that has already
77*d415bd75Srobert // been processed.
78*d415bd75Srobert for (DILocation *Loc = RootLoc; Loc; Loc = Loc->getInlinedAt()) {
79*d415bd75Srobert if (auto It = Cache.find(Loc); It != Cache.end()) {
80*d415bd75Srobert CachedResult = cast<DILocation>(It->second);
81*d415bd75Srobert break;
82*d415bd75Srobert }
83*d415bd75Srobert LocChain.push_back(Loc);
84*d415bd75Srobert }
85*d415bd75Srobert
86*d415bd75Srobert DILocation *UpdatedLoc = CachedResult;
87*d415bd75Srobert if (!UpdatedLoc) {
88*d415bd75Srobert // If no cache hits, then back() is the end of the inline chain, that is,
89*d415bd75Srobert // the DILocation whose scope ends in the Subprogram to be replaced.
90*d415bd75Srobert DILocation *LocToUpdate = LocChain.pop_back_val();
91*d415bd75Srobert DIScope *NewScope = DILocalScope::cloneScopeForSubprogram(
92*d415bd75Srobert *LocToUpdate->getScope(), NewSP, Ctx, Cache);
93*d415bd75Srobert UpdatedLoc = DILocation::get(Ctx, LocToUpdate->getLine(),
94*d415bd75Srobert LocToUpdate->getColumn(), NewScope);
95*d415bd75Srobert Cache[LocToUpdate] = UpdatedLoc;
96*d415bd75Srobert }
97*d415bd75Srobert
98*d415bd75Srobert // Recreate the location chain, bottom-up, starting at the new scope (or a
99*d415bd75Srobert // cached result).
100*d415bd75Srobert for (const DILocation *LocToUpdate : reverse(LocChain)) {
101*d415bd75Srobert UpdatedLoc =
102*d415bd75Srobert DILocation::get(Ctx, LocToUpdate->getLine(), LocToUpdate->getColumn(),
103*d415bd75Srobert LocToUpdate->getScope(), UpdatedLoc);
104*d415bd75Srobert Cache[LocToUpdate] = UpdatedLoc;
105*d415bd75Srobert }
106*d415bd75Srobert
107*d415bd75Srobert return UpdatedLoc;
108*d415bd75Srobert }
109*d415bd75Srobert
appendInlinedAt(const DebugLoc & DL,DILocation * InlinedAt,LLVMContext & Ctx,DenseMap<const MDNode *,MDNode * > & Cache)110097a140dSpatrick DebugLoc DebugLoc::appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt,
11109467b48Spatrick LLVMContext &Ctx,
11273471bf0Spatrick DenseMap<const MDNode *, MDNode *> &Cache) {
11309467b48Spatrick SmallVector<DILocation *, 3> InlinedAtLocations;
11409467b48Spatrick DILocation *Last = InlinedAt;
11509467b48Spatrick DILocation *CurInlinedAt = DL;
11609467b48Spatrick
11709467b48Spatrick // Gather all the inlined-at nodes.
11809467b48Spatrick while (DILocation *IA = CurInlinedAt->getInlinedAt()) {
11909467b48Spatrick // Skip any we've already built nodes for.
12009467b48Spatrick if (auto *Found = Cache[IA]) {
12109467b48Spatrick Last = cast<DILocation>(Found);
12209467b48Spatrick break;
12309467b48Spatrick }
12409467b48Spatrick
12509467b48Spatrick InlinedAtLocations.push_back(IA);
12609467b48Spatrick CurInlinedAt = IA;
12709467b48Spatrick }
12809467b48Spatrick
12909467b48Spatrick // Starting from the top, rebuild the nodes to point to the new inlined-at
13009467b48Spatrick // location (then rebuilding the rest of the chain behind it) and update the
13109467b48Spatrick // map of already-constructed inlined-at nodes.
13209467b48Spatrick for (const DILocation *MD : reverse(InlinedAtLocations))
13309467b48Spatrick Cache[MD] = Last = DILocation::getDistinct(
13409467b48Spatrick Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);
13509467b48Spatrick
13609467b48Spatrick return Last;
13709467b48Spatrick }
13809467b48Spatrick
13909467b48Spatrick #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const14009467b48Spatrick LLVM_DUMP_METHOD void DebugLoc::dump() const { print(dbgs()); }
14109467b48Spatrick #endif
14209467b48Spatrick
print(raw_ostream & OS) const14309467b48Spatrick void DebugLoc::print(raw_ostream &OS) const {
14409467b48Spatrick if (!Loc)
14509467b48Spatrick return;
14609467b48Spatrick
14709467b48Spatrick // Print source line info.
14809467b48Spatrick auto *Scope = cast<DIScope>(getScope());
14909467b48Spatrick OS << Scope->getFilename();
15009467b48Spatrick OS << ':' << getLine();
15109467b48Spatrick if (getCol() != 0)
15209467b48Spatrick OS << ':' << getCol();
15309467b48Spatrick
15409467b48Spatrick if (DebugLoc InlinedAtDL = getInlinedAt()) {
15509467b48Spatrick OS << " @[ ";
15609467b48Spatrick InlinedAtDL.print(OS);
15709467b48Spatrick OS << " ]";
15809467b48Spatrick }
15909467b48Spatrick }
160