LLVM 22.0.0git
DebugLoc.h
Go to the documentation of this file.
1//===- DebugLoc.h - Debug Location Information ------------------*- C++ -*-===//
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// This file defines a number of light weight data structures used
10// to describe and track debug location information.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_IR_DEBUGLOC_H
15#define LLVM_IR_DEBUGLOC_H
16
17#include "llvm/Config/llvm-config.h"
21
22namespace llvm {
23
24 class LLVMContext;
25 class raw_ostream;
26 class DILocation;
27 class Function;
28
29#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
30#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
31 struct DbgLocOrigin {
32 static constexpr unsigned long MaxDepth = 16;
33 using StackTracesTy =
34 SmallVector<std::pair<int, std::array<void *, MaxDepth>>, 0>;
35 StackTracesTy StackTraces;
36 DbgLocOrigin(bool ShouldCollectTrace);
37 void addTrace();
38 const StackTracesTy &getOriginStackTraces() const { return StackTraces; };
39 };
40#else
41 struct DbgLocOrigin {
42 DbgLocOrigin(bool) {}
43 };
44#endif
45 // Used to represent different "kinds" of DebugLoc, expressing that the
46 // instruction it is part of is either normal and should contain a valid
47 // DILocation, or otherwise describing the reason why the instruction does
48 // not contain a valid DILocation.
49 enum class DebugLocKind : uint8_t {
50 // The instruction is expected to contain a valid DILocation.
51 Normal,
52 // The instruction is compiler-generated, i.e. it is not associated with any
53 // line in the original source.
55 // The instruction has intentionally had its source location removed,
56 // typically because it was moved outside of its original control-flow and
57 // presenting the prior source location would be misleading for debuggers
58 // or profilers.
59 Dropped,
60 // The instruction does not have a known or currently knowable source
61 // location, e.g. the attribution is ambiguous in a way that can't be
62 // represented, or determining the correct location is complicated and
63 // requires future developer effort.
64 Unknown,
65 // DebugLoc is attached to an instruction that we don't expect to be
66 // emitted, and so can omit a valid DILocation; we don't expect to ever try
67 // and emit these into the line table, and trying to do so is a sign that
68 // something has gone wrong (most likely a DebugLoc leaking from a transient
69 // compiler-generated instruction).
70 Temporary
71 };
72
73 // Extends TrackingMDNodeRef to also store a DebugLocKind and Origin,
74 // allowing Debugify to ignore intentionally-empty DebugLocs and display the
75 // code responsible for generating unintentionally-empty DebugLocs.
76 // Currently we only need to track the Origin of this DILoc when using a
77 // DebugLoc that is not annotated (i.e. has DebugLocKind::Normal) and has a
78 // null DILocation, so only collect the origin stacktrace in those cases.
79 class DILocAndCoverageTracking : public TrackingMDNodeRef,
80 public DbgLocOrigin {
81 public:
82 DebugLocKind Kind;
83 // Default constructor for empty DebugLocs.
84 DILocAndCoverageTracking()
85 : TrackingMDNodeRef(nullptr), DbgLocOrigin(true),
86 Kind(DebugLocKind::Normal) {}
87 // Valid or nullptr MDNode*, no annotative DebugLocKind.
88 DILocAndCoverageTracking(const MDNode *Loc)
89 : TrackingMDNodeRef(const_cast<MDNode *>(Loc)), DbgLocOrigin(!Loc),
90 Kind(DebugLocKind::Normal) {}
91 LLVM_ABI DILocAndCoverageTracking(const DILocation *Loc);
92 // Explicit DebugLocKind, which always means a nullptr MDNode*.
93 DILocAndCoverageTracking(DebugLocKind Kind)
94 : TrackingMDNodeRef(nullptr),
95 DbgLocOrigin(Kind == DebugLocKind::Normal), Kind(Kind) {}
96 };
97 template <> struct simplify_type<DILocAndCoverageTracking> {
98 using SimpleType = MDNode *;
99
100 static MDNode *getSimplifiedValue(DILocAndCoverageTracking &MD) {
101 return MD.get();
102 }
103 };
104 template <> struct simplify_type<const DILocAndCoverageTracking> {
105 using SimpleType = MDNode *;
106
107 static MDNode *getSimplifiedValue(const DILocAndCoverageTracking &MD) {
108 return MD.get();
109 }
110 };
111
112 using DebugLocTrackingRef = DILocAndCoverageTracking;
113#else
115#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
116
117 /// A debug info location.
118 ///
119 /// This class is a wrapper around a tracking reference to an \a DILocation
120 /// pointer.
121 ///
122 /// To avoid extra includes, \a DebugLoc doubles the \a DILocation API with a
123 /// one based on relatively opaque \a MDNode pointers.
124 class DebugLoc {
125
127
128 public:
129 DebugLoc() = default;
130
131 /// Construct from an \a DILocation.
132 LLVM_ABI DebugLoc(const DILocation *L);
133
134 /// Construct from an \a MDNode.
135 ///
136 /// Note: if \c N is not an \a DILocation, a verifier check will fail, and
137 /// accessors will crash. However, construction from other nodes is
138 /// supported in order to handle forward references when reading textual
139 /// IR.
140 LLVM_ABI explicit DebugLoc(const MDNode *N);
141
142#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
143 DebugLoc(DebugLocKind Kind) : Loc(Kind) {}
144 DebugLocKind getKind() const { return Loc.Kind; }
145#endif
146
147#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
148 static inline DebugLoc getTemporary() {
149 return DebugLoc(DebugLocKind::Temporary);
150 }
151 static inline DebugLoc getUnknown() {
152 return DebugLoc(DebugLocKind::Unknown);
153 }
154 static inline DebugLoc getCompilerGenerated() {
155 return DebugLoc(DebugLocKind::CompilerGenerated);
156 }
157 static inline DebugLoc getDropped() {
158 return DebugLoc(DebugLocKind::Dropped);
159 }
160#else
161 static inline DebugLoc getTemporary() { return DebugLoc(); }
162 static inline DebugLoc getUnknown() { return DebugLoc(); }
163 static inline DebugLoc getCompilerGenerated() { return DebugLoc(); }
164 static inline DebugLoc getDropped() { return DebugLoc(); }
165#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
166
167 /// When two instructions are combined into a single instruction we also
168 /// need to combine the original locations into a single location.
169 /// When the locations are the same we can use either location.
170 /// When they differ, we need a third location which is distinct from
171 /// either. If they share a common scope, use this scope and compare the
172 /// line/column pair of the locations with the common scope:
173 /// * if both match, keep the line and column;
174 /// * if only the line number matches, keep the line and set the column as
175 /// 0;
176 /// * otherwise set line and column as 0.
177 /// If they do not share a common scope the location is ambiguous and can't
178 /// be represented in a line entry. In this case, set line and column as 0
179 /// and use the scope of any location.
180 ///
181 /// \p LocA \p LocB: The locations to be merged.
183
184 /// Try to combine the vector of locations passed as input in a single one.
185 /// This function applies getMergedLocation() repeatedly left-to-right.
186 ///
187 /// \p Locs: The locations to be merged.
189
190 /// If this DebugLoc is non-empty, returns this DebugLoc; otherwise, selects
191 /// \p Other.
192 /// In coverage-tracking builds, this also accounts for whether this or
193 /// \p Other have an annotative DebugLocKind applied, such that if both are
194 /// empty but exactly one has an annotation, we prefer that annotated
195 /// location.
197 if (*this)
198 return *this;
199#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
200 if (Other)
201 return Other;
202 if (getKind() != DebugLocKind::Normal)
203 return *this;
204 if (Other.getKind() != DebugLocKind::Normal)
205 return Other;
206 return *this;
207#else
208 return Other;
209#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
210 }
211
212#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
213 const DbgLocOrigin::StackTracesTy &getOriginStackTraces() const {
214 return Loc.getOriginStackTraces();
215 }
216 DebugLoc getCopied() const {
217 DebugLoc NewDL = *this;
218 NewDL.Loc.addTrace();
219 return NewDL;
220 }
221#else
222 DebugLoc getCopied() const { return *this; }
223#endif
224
225 /// Get the underlying \a DILocation.
226 ///
227 /// \pre !*this or \c isa<DILocation>(getAsMDNode()).
228 /// @{
229 LLVM_ABI DILocation *get() const;
230 operator DILocation *() const { return get(); }
231 DILocation *operator->() const { return get(); }
232 DILocation &operator*() const { return *get(); }
233 /// @}
234
235 /// Check for null.
236 ///
237 /// Check for null in a way that is safe with broken debug info. Unlike
238 /// the conversion to \c DILocation, this doesn't require that \c Loc is of
239 /// the right type. Important for cases like \a llvm::StripDebugInfo() and
240 /// \a Instruction::hasMetadata().
241 explicit operator bool() const { return Loc; }
242
243 /// Check whether this has a trivial destructor.
244 bool hasTrivialDestructor() const { return Loc.hasTrivialDestructor(); }
245
246 enum { ReplaceLastInlinedAt = true };
247 /// Rebuild the entire inlined-at chain for this instruction so that the top of
248 /// the chain now is inlined-at the new call site.
249 /// \param InlinedAt The new outermost inlined-at in the chain.
250 LLVM_ABI static DebugLoc
251 appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt, LLVMContext &Ctx,
253
254 /// Return true if the source locations match, ignoring isImplicitCode and
255 /// source atom info.
257 if (get() == Other.get())
258 return true;
259 return ((bool)*this == (bool)Other) && getLine() == Other.getLine() &&
260 getCol() == Other.getCol() && getScope() == Other.getScope() &&
261 getInlinedAt() == Other.getInlinedAt();
262 }
263
264 LLVM_ABI unsigned getLine() const;
265 LLVM_ABI unsigned getCol() const;
266 LLVM_ABI MDNode *getScope() const;
268
269 /// Get the fully inlined-at scope for a DebugLoc.
270 ///
271 /// Gets the inlined-at scope for a DebugLoc.
273
274 /// Rebuild the entire inline-at chain by replacing the subprogram at the
275 /// end of the chain with NewSP.
276 LLVM_ABI static DebugLoc
278 LLVMContext &Ctx,
280
281 /// Find the debug info location for the start of the function.
282 ///
283 /// Walk up the scope chain of given debug loc and find line number info
284 /// for the function.
285 ///
286 /// FIXME: Remove this. Users should use DILocation/DILocalScope API to
287 /// find the subprogram, and then DILocation::get().
289
290 /// Return \c this as a bar \a MDNode.
291 MDNode *getAsMDNode() const { return Loc; }
292
293 /// Check if the DebugLoc corresponds to an implicit code.
294 LLVM_ABI bool isImplicitCode() const;
295 LLVM_ABI void setImplicitCode(bool ImplicitCode);
296
297 bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; }
298 bool operator!=(const DebugLoc &DL) const { return Loc != DL.Loc; }
299
300 LLVM_ABI void dump() const;
301
302 /// prints source location /path/to/file.exe:line:col @[inlined at]
303 LLVM_ABI void print(raw_ostream &OS) const;
304 };
305
306} // end namespace llvm
307
308#endif // LLVM_IR_DEBUGLOC_H
aarch64 promote const
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_ABI
Definition: Compiler.h:213
raw_pwrite_stream & OS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Debug location.
Subprogram description. Uses SubclassData1.
A debug info location.
Definition: DebugLoc.h:124
LLVM_ABI void setImplicitCode(bool ImplicitCode)
Definition: DebugLoc.cpp:94
DILocation & operator*() const
Definition: DebugLoc.h:232
bool isSameSourceLocation(const DebugLoc &Other) const
Return true if the source locations match, ignoring isImplicitCode and source atom info.
Definition: DebugLoc.h:256
static DebugLoc getCompilerGenerated()
Definition: DebugLoc.h:163
bool operator==(const DebugLoc &DL) const
Definition: DebugLoc.h:297
DebugLoc()=default
LLVM_ABI unsigned getLine() const
Definition: DebugLoc.cpp:54
DebugLoc orElse(DebugLoc Other) const
If this DebugLoc is non-empty, returns this DebugLoc; otherwise, selects Other.
Definition: DebugLoc.h:196
LLVM_ABI DebugLoc getFnDebugLoc() const
Find the debug info location for the start of the function.
Definition: DebugLoc.cpp:78
LLVM_ABI DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:50
LLVM_ABI MDNode * getScope() const
Definition: DebugLoc.cpp:64
DebugLoc getCopied() const
Definition: DebugLoc.h:222
static LLVM_ABI DebugLoc appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt, LLVMContext &Ctx, DenseMap< const MDNode *, MDNode * > &Cache)
Rebuild the entire inlined-at chain for this instruction so that the top of the chain now is inlined-...
Definition: DebugLoc.cpp:140
DILocation * operator->() const
Definition: DebugLoc.h:231
bool hasTrivialDestructor() const
Check whether this has a trivial destructor.
Definition: DebugLoc.h:244
static DebugLoc getTemporary()
Definition: DebugLoc.h:161
static LLVM_ABI DebugLoc getMergedLocation(DebugLoc LocA, DebugLoc LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
Definition: DebugLoc.cpp:183
LLVM_ABI void print(raw_ostream &OS) const
prints source location /path/to/file.exe:line:col @[inlined at]
Definition: DebugLoc.cpp:195
static LLVM_ABI DebugLoc getMergedLocations(ArrayRef< DebugLoc > Locs)
Try to combine the vector of locations passed as input in a single one.
Definition: DebugLoc.cpp:170
MDNode * getAsMDNode() const
Return this as a bar MDNode.
Definition: DebugLoc.h:291
LLVM_ABI unsigned getCol() const
Definition: DebugLoc.cpp:59
static LLVM_ABI DebugLoc replaceInlinedAtSubprogram(const DebugLoc &DL, DISubprogram &NewSP, LLVMContext &Ctx, DenseMap< const MDNode *, MDNode * > &Cache)
Rebuild the entire inline-at chain by replacing the subprogram at the end of the chain with NewSP.
Definition: DebugLoc.cpp:100
LLVM_ABI bool isImplicitCode() const
Check if the DebugLoc corresponds to an implicit code.
Definition: DebugLoc.cpp:87
LLVM_ABI void dump() const
Definition: DebugLoc.cpp:192
static DebugLoc getUnknown()
Definition: DebugLoc.h:162
LLVM_ABI DILocation * getInlinedAt() const
Definition: DebugLoc.cpp:69
@ ReplaceLastInlinedAt
Definition: DebugLoc.h:246
static DebugLoc getDropped()
Definition: DebugLoc.h:164
bool operator!=(const DebugLoc &DL) const
Definition: DebugLoc.h:298
LLVM_ABI MDNode * getInlinedAtScope() const
Get the fully inlined-at scope for a DebugLoc.
Definition: DebugLoc.cpp:74
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
Metadata node.
Definition: Metadata.h:1077
bool hasTrivialDestructor() const
Check whether this has a trivial destructor.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
TypedTrackingMDRef< MDNode > TrackingMDNodeRef
@ Other
Any other memory.
TrackingMDNodeRef DebugLocTrackingRef
Definition: DebugLoc.h:114
#define N
static SimpleType & getSimplifiedValue(From &Val)
Definition: Casting.h:38