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
24class LLVMContext;
25class raw_ostream;
26class DILocation;
27class Function;
28
29#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
30#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
31struct 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
41struct 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.
49enum 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.
79class DILocAndCoverageTracking : public TrackingMDNodeRef, public DbgLocOrigin {
80public:
81 DebugLocKind Kind;
82 // Default constructor for empty DebugLocs.
83 DILocAndCoverageTracking()
84 : TrackingMDNodeRef(nullptr), DbgLocOrigin(true),
85 Kind(DebugLocKind::Normal) {}
86 // Valid or nullptr MDNode*, no annotative DebugLocKind.
87 DILocAndCoverageTracking(const MDNode *Loc)
88 : TrackingMDNodeRef(const_cast<MDNode *>(Loc)), DbgLocOrigin(!Loc),
89 Kind(DebugLocKind::Normal) {}
90 LLVM_ABI DILocAndCoverageTracking(const DILocation *Loc);
91 // Explicit DebugLocKind, which always means a nullptr MDNode*.
92 DILocAndCoverageTracking(DebugLocKind Kind)
93 : TrackingMDNodeRef(nullptr), DbgLocOrigin(Kind == DebugLocKind::Normal),
94 Kind(Kind) {}
95};
96template <> struct simplify_type<DILocAndCoverageTracking> {
97 using SimpleType = MDNode *;
98
99 static MDNode *getSimplifiedValue(DILocAndCoverageTracking &MD) {
100 return MD.get();
101 }
102};
103template <> struct simplify_type<const DILocAndCoverageTracking> {
104 using SimpleType = MDNode *;
105
106 static MDNode *getSimplifiedValue(const DILocAndCoverageTracking &MD) {
107 return MD.get();
108 }
109};
110
111using DebugLocTrackingRef = DILocAndCoverageTracking;
112#else
114#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
115
116/// A debug info location.
117///
118/// This class is a wrapper around a tracking reference to an \a DILocation
119/// pointer.
120///
121/// To avoid extra includes, \a DebugLoc doubles the \a DILocation API with a
122/// one based on relatively opaque \a MDNode pointers.
123class DebugLoc {
124
126
127public:
128 DebugLoc() = default;
129
130 /// Construct from an \a DILocation.
131 LLVM_ABI DebugLoc(const DILocation *L);
132
133 /// Construct from an \a MDNode.
134 ///
135 /// Note: if \c N is not an \a DILocation, a verifier check will fail, and
136 /// accessors will crash. However, construction from other nodes is
137 /// supported in order to handle forward references when reading textual
138 /// IR.
139 LLVM_ABI explicit DebugLoc(const MDNode *N);
140
141#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
142 DebugLoc(DebugLocKind Kind) : Loc(Kind) {}
143 DebugLocKind getKind() const { return Loc.Kind; }
144#endif
145
146#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
147 static inline DebugLoc getTemporary() {
148 return DebugLoc(DebugLocKind::Temporary);
149 }
150 static inline DebugLoc getUnknown() {
151 return DebugLoc(DebugLocKind::Unknown);
152 }
153 static inline DebugLoc getCompilerGenerated() {
154 return DebugLoc(DebugLocKind::CompilerGenerated);
155 }
156 static inline DebugLoc getDropped() {
157 return DebugLoc(DebugLocKind::Dropped);
158 }
159#else
160 static inline DebugLoc getTemporary() { return DebugLoc(); }
161 static inline DebugLoc getUnknown() { return DebugLoc(); }
162 static inline DebugLoc getCompilerGenerated() { return DebugLoc(); }
163 static inline DebugLoc getDropped() { return DebugLoc(); }
164#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
165
166 /// When two instructions are combined into a single instruction we also
167 /// need to combine the original locations into a single location.
168 /// When the locations are the same we can use either location.
169 /// When they differ, we need a third location which is distinct from
170 /// either. If they share a common scope, use this scope and compare the
171 /// line/column pair of the locations with the common scope:
172 /// * if both match, keep the line and column;
173 /// * if only the line number matches, keep the line and set the column as
174 /// 0;
175 /// * otherwise set line and column as 0.
176 /// If they do not share a common scope the location is ambiguous and can't
177 /// be represented in a line entry. In this case, set line and column as 0
178 /// and use the scope of any location.
179 ///
180 /// \p LocA \p LocB: The locations to be merged.
182
183 /// Try to combine the vector of locations passed as input in a single one.
184 /// This function applies getMergedLocation() repeatedly left-to-right.
185 ///
186 /// \p Locs: The locations to be merged.
188
189 /// If this DebugLoc is non-empty, returns this DebugLoc; otherwise, selects
190 /// \p Other.
191 /// In coverage-tracking builds, this also accounts for whether this or
192 /// \p Other have an annotative DebugLocKind applied, such that if both are
193 /// empty but exactly one has an annotation, we prefer that annotated
194 /// location.
196 if (*this)
197 return *this;
198#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
199 if (Other)
200 return Other;
201 if (getKind() != DebugLocKind::Normal)
202 return *this;
203 if (Other.getKind() != DebugLocKind::Normal)
204 return Other;
205 return *this;
206#else
207 return Other;
208#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
209 }
210
211#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
212 const DbgLocOrigin::StackTracesTy &getOriginStackTraces() const {
213 return Loc.getOriginStackTraces();
214 }
215 DebugLoc getCopied() const {
216 DebugLoc NewDL = *this;
217 NewDL.Loc.addTrace();
218 return NewDL;
219 }
220#else
221 DebugLoc getCopied() const { return *this; }
222#endif
223
224 /// Get the underlying \a DILocation.
225 ///
226 /// \pre !*this or \c isa<DILocation>(getAsMDNode()).
227 /// @{
228 LLVM_ABI DILocation *get() const;
229 operator DILocation *() const { return get(); }
230 DILocation *operator->() const { return get(); }
231 DILocation &operator*() const { return *get(); }
232 /// @}
233
234 /// Check for null.
235 ///
236 /// Check for null in a way that is safe with broken debug info. Unlike
237 /// the conversion to \c DILocation, this doesn't require that \c Loc is of
238 /// the right type. Important for cases like \a llvm::StripDebugInfo() and
239 /// \a Instruction::hasMetadata().
240 explicit operator bool() const { return Loc; }
241
242 /// Check whether this has a trivial destructor.
243 bool hasTrivialDestructor() const { return Loc.hasTrivialDestructor(); }
244
245 enum { ReplaceLastInlinedAt = true };
246 /// Rebuild the entire inlined-at chain for this instruction so that the top
247 /// of the chain now is inlined-at the new call site.
248 /// \param InlinedAt The new outermost inlined-at in the chain.
249 LLVM_ABI static DebugLoc
250 appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt, LLVMContext &Ctx,
252
253 /// Return true if the source locations match, ignoring isImplicitCode and
254 /// source atom info.
256 if (get() == Other.get())
257 return true;
258 return ((bool)*this == (bool)Other) && getLine() == Other.getLine() &&
259 getCol() == Other.getCol() && getScope() == Other.getScope() &&
260 getInlinedAt() == Other.getInlinedAt();
261 }
262
263 LLVM_ABI unsigned getLine() const;
264 LLVM_ABI unsigned getCol() const;
265 LLVM_ABI MDNode *getScope() const;
267
268 /// Get the fully inlined-at scope for a DebugLoc.
269 ///
270 /// Gets the inlined-at scope for a DebugLoc.
272
273 /// Rebuild the entire inline-at chain by replacing the subprogram at the
274 /// end of the chain with NewSP.
275 LLVM_ABI static DebugLoc
277 LLVMContext &Ctx,
279
280 /// Find the debug info location for the start of the function.
281 ///
282 /// Walk up the scope chain of given debug loc and find line number info
283 /// for the function.
284 ///
285 /// FIXME: Remove this. Users should use DILocation/DILocalScope API to
286 /// find the subprogram, and then DILocation::get().
288
289 /// Return \c this as a bar \a MDNode.
290 MDNode *getAsMDNode() const { return Loc; }
291
292 /// Check if the DebugLoc corresponds to an implicit code.
293 LLVM_ABI bool isImplicitCode() const;
294 LLVM_ABI void setImplicitCode(bool ImplicitCode);
295
296 bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; }
297 bool operator!=(const DebugLoc &DL) const { return Loc != DL.Loc; }
298
299 LLVM_ABI void dump() const;
300
301 /// prints source location /path/to/file.exe:line:col @[inlined at]
302 LLVM_ABI void print(raw_ostream &OS) const;
303};
304
305} // end namespace llvm
306
307#endif // LLVM_IR_DEBUGLOC_H
aarch64 promote const
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
basic Basic Alias true
#define LLVM_ABI
Definition Compiler.h:213
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Subprogram description. Uses SubclassData1.
A debug info location.
Definition DebugLoc.h:123
LLVM_ABI void setImplicitCode(bool ImplicitCode)
Definition DebugLoc.cpp:91
DILocation & operator*() const
Definition DebugLoc.h:231
bool isSameSourceLocation(const DebugLoc &Other) const
Return true if the source locations match, ignoring isImplicitCode and source atom info.
Definition DebugLoc.h:255
static DebugLoc getCompilerGenerated()
Definition DebugLoc.h:162
bool operator==(const DebugLoc &DL) const
Definition DebugLoc.h:296
DebugLoc()=default
LLVM_ABI unsigned getLine() const
Definition DebugLoc.cpp:52
DebugLoc orElse(DebugLoc Other) const
If this DebugLoc is non-empty, returns this DebugLoc; otherwise, selects Other.
Definition DebugLoc.h:195
LLVM_ABI DebugLoc getFnDebugLoc() const
Find the debug info location for the start of the function.
Definition DebugLoc.cpp:76
LLVM_ABI DILocation * get() const
Get the underlying DILocation.
Definition DebugLoc.cpp:48
LLVM_ABI MDNode * getScope() const
Definition DebugLoc.cpp:62
DebugLoc getCopied() const
Definition DebugLoc.h:221
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:136
DILocation * operator->() const
Definition DebugLoc.h:230
bool hasTrivialDestructor() const
Check whether this has a trivial destructor.
Definition DebugLoc.h:243
static DebugLoc getTemporary()
Definition DebugLoc.h:160
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:179
LLVM_ABI void print(raw_ostream &OS) const
prints source location /path/to/file.exe:line:col @[inlined at]
Definition DebugLoc.cpp:200
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:166
MDNode * getAsMDNode() const
Return this as a bar MDNode.
Definition DebugLoc.h:290
LLVM_ABI unsigned getCol() const
Definition DebugLoc.cpp:57
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:96
LLVM_ABI bool isImplicitCode() const
Check if the DebugLoc corresponds to an implicit code.
Definition DebugLoc.cpp:85
LLVM_ABI void dump() const
Definition DebugLoc.cpp:197
static DebugLoc getUnknown()
Definition DebugLoc.h:161
LLVM_ABI DILocation * getInlinedAt() const
Definition DebugLoc.cpp:67
static DebugLoc getDropped()
Definition DebugLoc.h:163
bool operator!=(const DebugLoc &DL) const
Definition DebugLoc.h:297
LLVM_ABI MDNode * getInlinedAtScope() const
Get the fully inlined-at scope for a DebugLoc.
Definition DebugLoc.cpp:72
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Metadata node.
Definition Metadata.h:1078
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.
TypedTrackingMDRef< MDNode > TrackingMDNodeRef
@ Other
Any other memory.
Definition ModRef.h:68
TrackingMDNodeRef DebugLocTrackingRef
Definition DebugLoc.h:113
#define N
Define a template that can be specialized by smart pointers to reflect the fact that they are automat...
Definition Casting.h:34
static SimpleType & getSimplifiedValue(From &Val)
Definition Casting.h:38