1 //===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
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 #include "llvm/Support/DebugLoc.h"
11 #include "LLVMContextImpl.h"
14 //===----------------------------------------------------------------------===//
15 // DebugLoc Implementation
16 //===----------------------------------------------------------------------===//
18 MDNode *NewDebugLoc::getScope(const LLVMContext &Ctx) const {
19 if (ScopeIdx == 0) return 0;
22 // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
23 // position specified.
24 assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
26 return Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
29 // Otherwise, the index is in the ScopeInlinedAtRecords array.
30 assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
32 return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
35 MDNode *NewDebugLoc::getInlinedAt(const LLVMContext &Ctx) const {
36 // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
37 // position specified. Zero is invalid.
38 if (ScopeIdx >= 0) return 0;
40 // Otherwise, the index is in the ScopeInlinedAtRecords array.
41 assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
43 return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
46 /// Return both the Scope and the InlinedAt values.
47 void NewDebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
48 const LLVMContext &Ctx) const {
55 // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at
56 // position specified.
57 assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() &&
59 Scope = Ctx.pImpl->ScopeRecords[ScopeIdx-1].get();
64 // Otherwise, the index is in the ScopeInlinedAtRecords array.
65 assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() &&
67 Scope = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get();
68 IA = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get();
72 NewDebugLoc NewDebugLoc::get(unsigned Line, unsigned Col,
73 MDNode *Scope, MDNode *InlinedAt) {
76 // If no scope is available, this is an unknown location.
77 if (Scope == 0) return Result;
79 // Saturate line and col to "unknown".
80 if (Col > 255) Col = 0;
81 if (Line >= (1 << 24)) Line = 0;
82 Result.LineCol = Line | (Col << 24);
84 LLVMContext &Ctx = Scope->getContext();
86 // If there is no inlined-at location, use the ScopeRecords array.
88 Result.ScopeIdx = Ctx.pImpl->getOrAddScopeRecordIdxEntry(Scope, 0);
90 Result.ScopeIdx = Ctx.pImpl->getOrAddScopeInlinedAtIdxEntry(Scope,
96 /// getAsMDNode - This method converts the compressed DebugLoc node into a
97 /// DILocation compatible MDNode.
98 MDNode *NewDebugLoc::getAsMDNode(const LLVMContext &Ctx) const {
99 if (isUnknown()) return 0;
102 getScopeAndInlinedAt(Scope, IA, Ctx);
103 assert(Scope && "If scope is null, this should be isUnknown()");
105 LLVMContext &Ctx2 = Scope->getContext();
106 const Type *Int32 = Type::getInt32Ty(Ctx2);
108 ConstantInt::get(Int32, getLine()), ConstantInt::get(Int32, getCol()),
111 return MDNode::get(Ctx2, &Elts[0], 4);
115 //===----------------------------------------------------------------------===//
116 // LLVMContextImpl Implementation
117 //===----------------------------------------------------------------------===//
119 int LLVMContextImpl::getOrAddScopeRecordIdxEntry(MDNode *Scope,
121 // If we already have an entry for this scope, return it.
122 int &Idx = ScopeRecordIdx[Scope];
125 // If we don't have an entry, but ExistingIdx is specified, use it.
127 return Idx = ExistingIdx;
129 // Otherwise add a new entry.
131 // Start out ScopeRecords with a minimal reasonable size to avoid
132 // excessive reallocation starting out.
133 if (ScopeRecords.empty())
134 ScopeRecords.reserve(128);
136 // Index is biased by 1 for index.
137 Idx = ScopeRecords.size()+1;
138 ScopeRecords.push_back(DebugRecVH(Scope, this, Idx));
142 int LLVMContextImpl::getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,
144 // If we already have an entry, return it.
145 int &Idx = ScopeInlinedAtIdx[std::make_pair(Scope, IA)];
148 // If we don't have an entry, but ExistingIdx is specified, use it.
150 return Idx = ExistingIdx;
152 // Start out ScopeInlinedAtRecords with a minimal reasonable size to avoid
153 // excessive reallocation starting out.
154 if (ScopeInlinedAtRecords.empty())
155 ScopeInlinedAtRecords.reserve(128);
157 // Index is biased by 1 and negated.
158 Idx = -ScopeInlinedAtRecords.size()-1;
159 ScopeInlinedAtRecords.push_back(std::make_pair(DebugRecVH(Scope, this, Idx),
160 DebugRecVH(IA, this, Idx)));
165 //===----------------------------------------------------------------------===//
166 // DebugRecVH Implementation
167 //===----------------------------------------------------------------------===//
169 /// deleted - The MDNode this is pointing to got deleted, so this pointer needs
170 /// to drop to null and we need remove our entry from the DenseMap.
171 void DebugRecVH::deleted() {
172 // If this is a non-canonical reference, just drop the value to null, we know
173 // it doesn't have a map entry.
181 // If the index is positive, it is an entry in ScopeRecords.
183 assert(Ctx->ScopeRecordIdx[Cur] == Idx && "Mapping out of date!");
184 Ctx->ScopeRecordIdx.erase(Cur);
185 // Reset this VH to null and we're done.
191 // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
192 // is the scope or the inlined-at record entry.
193 assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
194 std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
195 assert((this == &Entry.first || this == &Entry.second) &&
196 "Mapping out of date!");
198 MDNode *OldScope = Entry.first.get();
199 MDNode *OldInlinedAt = Entry.second.get();
200 assert(OldScope != 0 && OldInlinedAt != 0 &&
201 "Entry should be non-canonical if either val dropped to null");
203 // Otherwise, we do have an entry in it, nuke it and we're done.
204 assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
205 "Mapping out of date");
206 Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
208 // Reset this VH to null.
213 void DebugRecVH::allUsesReplacedWith(Value *NewVa) {
214 // If being replaced with a non-mdnode value (e.g. undef) handle this as if
215 // the mdnode got deleted.
216 MDNode *NewVal = dyn_cast<MDNode>(NewVa);
217 if (NewVal == 0) return deleted();
219 // If this is a non-canonical reference, just change it, we know it already
220 // doesn't have a map entry.
226 MDNode *OldVal = get();
227 assert(OldVal != NewVa && "Node replaced with self?");
229 // If the index is positive, it is an entry in ScopeRecords.
231 assert(Ctx->ScopeRecordIdx[OldVal] == Idx && "Mapping out of date!");
232 Ctx->ScopeRecordIdx.erase(OldVal);
235 int NewEntry = Ctx->getOrAddScopeRecordIdxEntry(NewVal, Idx);
237 // If NewVal already has an entry, this becomes a non-canonical reference,
238 // just drop Idx to 0 to signify this.
244 // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it
245 // is the scope or the inlined-at record entry.
246 assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size());
247 std::pair<DebugRecVH, DebugRecVH> &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1];
248 assert((this == &Entry.first || this == &Entry.second) &&
249 "Mapping out of date!");
251 MDNode *OldScope = Entry.first.get();
252 MDNode *OldInlinedAt = Entry.second.get();
253 assert(OldScope != 0 && OldInlinedAt != 0 &&
254 "Entry should be non-canonical if either val dropped to null");
256 // Otherwise, we do have an entry in it, nuke it and we're done.
257 assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&&
258 "Mapping out of date");
259 Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt));
261 // Reset this VH to the new value.
264 int NewIdx = Ctx->getOrAddScopeInlinedAtIdxEntry(Entry.first.get(),
265 Entry.second.get(), Idx);
266 // If NewVal already has an entry, this becomes a non-canonical reference,
267 // just drop Idx to 0 to signify this.