Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/IR/DebugLoc.cpp
35233 views
1
//===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/IR/DebugLoc.h"
10
#include "llvm/Config/llvm-config.h"
11
#include "llvm/IR/DebugInfo.h"
12
using namespace llvm;
13
14
//===----------------------------------------------------------------------===//
15
// DebugLoc Implementation
16
//===----------------------------------------------------------------------===//
17
DebugLoc::DebugLoc(const DILocation *L) : Loc(const_cast<DILocation *>(L)) {}
18
DebugLoc::DebugLoc(const MDNode *L) : Loc(const_cast<MDNode *>(L)) {}
19
20
DILocation *DebugLoc::get() const {
21
return cast_or_null<DILocation>(Loc.get());
22
}
23
24
unsigned DebugLoc::getLine() const {
25
assert(get() && "Expected valid DebugLoc");
26
return get()->getLine();
27
}
28
29
unsigned DebugLoc::getCol() const {
30
assert(get() && "Expected valid DebugLoc");
31
return get()->getColumn();
32
}
33
34
MDNode *DebugLoc::getScope() const {
35
assert(get() && "Expected valid DebugLoc");
36
return get()->getScope();
37
}
38
39
DILocation *DebugLoc::getInlinedAt() const {
40
assert(get() && "Expected valid DebugLoc");
41
return get()->getInlinedAt();
42
}
43
44
MDNode *DebugLoc::getInlinedAtScope() const {
45
return cast<DILocation>(Loc)->getInlinedAtScope();
46
}
47
48
DebugLoc DebugLoc::getFnDebugLoc() const {
49
// FIXME: Add a method on \a DILocation that does this work.
50
const MDNode *Scope = getInlinedAtScope();
51
if (auto *SP = getDISubprogram(Scope))
52
return DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
53
54
return DebugLoc();
55
}
56
57
bool DebugLoc::isImplicitCode() const {
58
if (DILocation *Loc = get()) {
59
return Loc->isImplicitCode();
60
}
61
return true;
62
}
63
64
void DebugLoc::setImplicitCode(bool ImplicitCode) {
65
if (DILocation *Loc = get()) {
66
Loc->setImplicitCode(ImplicitCode);
67
}
68
}
69
70
DebugLoc DebugLoc::replaceInlinedAtSubprogram(
71
const DebugLoc &RootLoc, DISubprogram &NewSP, LLVMContext &Ctx,
72
DenseMap<const MDNode *, MDNode *> &Cache) {
73
SmallVector<DILocation *> LocChain;
74
DILocation *CachedResult = nullptr;
75
76
// Collect the inline chain, stopping if we find a location that has already
77
// been processed.
78
for (DILocation *Loc = RootLoc; Loc; Loc = Loc->getInlinedAt()) {
79
if (auto It = Cache.find(Loc); It != Cache.end()) {
80
CachedResult = cast<DILocation>(It->second);
81
break;
82
}
83
LocChain.push_back(Loc);
84
}
85
86
DILocation *UpdatedLoc = CachedResult;
87
if (!UpdatedLoc) {
88
// If no cache hits, then back() is the end of the inline chain, that is,
89
// the DILocation whose scope ends in the Subprogram to be replaced.
90
DILocation *LocToUpdate = LocChain.pop_back_val();
91
DIScope *NewScope = DILocalScope::cloneScopeForSubprogram(
92
*LocToUpdate->getScope(), NewSP, Ctx, Cache);
93
UpdatedLoc = DILocation::get(Ctx, LocToUpdate->getLine(),
94
LocToUpdate->getColumn(), NewScope);
95
Cache[LocToUpdate] = UpdatedLoc;
96
}
97
98
// Recreate the location chain, bottom-up, starting at the new scope (or a
99
// cached result).
100
for (const DILocation *LocToUpdate : reverse(LocChain)) {
101
UpdatedLoc =
102
DILocation::get(Ctx, LocToUpdate->getLine(), LocToUpdate->getColumn(),
103
LocToUpdate->getScope(), UpdatedLoc);
104
Cache[LocToUpdate] = UpdatedLoc;
105
}
106
107
return UpdatedLoc;
108
}
109
110
DebugLoc DebugLoc::appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt,
111
LLVMContext &Ctx,
112
DenseMap<const MDNode *, MDNode *> &Cache) {
113
SmallVector<DILocation *, 3> InlinedAtLocations;
114
DILocation *Last = InlinedAt;
115
DILocation *CurInlinedAt = DL;
116
117
// Gather all the inlined-at nodes.
118
while (DILocation *IA = CurInlinedAt->getInlinedAt()) {
119
// Skip any we've already built nodes for.
120
if (auto *Found = Cache[IA]) {
121
Last = cast<DILocation>(Found);
122
break;
123
}
124
125
InlinedAtLocations.push_back(IA);
126
CurInlinedAt = IA;
127
}
128
129
// Starting from the top, rebuild the nodes to point to the new inlined-at
130
// location (then rebuilding the rest of the chain behind it) and update the
131
// map of already-constructed inlined-at nodes.
132
for (const DILocation *MD : reverse(InlinedAtLocations))
133
Cache[MD] = Last = DILocation::getDistinct(
134
Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);
135
136
return Last;
137
}
138
139
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
140
LLVM_DUMP_METHOD void DebugLoc::dump() const { print(dbgs()); }
141
#endif
142
143
void DebugLoc::print(raw_ostream &OS) const {
144
if (!Loc)
145
return;
146
147
// Print source line info.
148
auto *Scope = cast<DIScope>(getScope());
149
OS << Scope->getFilename();
150
OS << ':' << getLine();
151
if (getCol() != 0)
152
OS << ':' << getCol();
153
154
if (DebugLoc InlinedAtDL = getInlinedAt()) {
155
OS << " @[ ";
156
InlinedAtDL.print(OS);
157
OS << " ]";
158
}
159
}
160
161