1414#ifndef LLVM_IR_DEBUGLOC_H
1515#define LLVM_IR_DEBUGLOC_H
1616
17+ #include " llvm/Config/config.h"
1718#include " llvm/IR/TrackingMDRef.h"
1819#include " llvm/Support/DataTypes.h"
1920
@@ -22,6 +23,73 @@ namespace llvm {
2223 class LLVMContext ;
2324 class raw_ostream ;
2425 class DILocation ;
26+ class Function ;
27+
28+ #if ENABLE_DEBUGLOC_COVERAGE_TRACKING
29+ // Used to represent different "kinds" of DebugLoc, expressing that the
30+ // instruction it is part of is either normal and should contain a valid
31+ // DILocation, or otherwise describing the reason why the instruction does
32+ // not contain a valid DILocation.
33+ enum class DebugLocKind : uint8_t {
34+ // The instruction is expected to contain a valid DILocation.
35+ Normal,
36+ // The instruction is compiler-generated, i.e. it is not associated with any
37+ // line in the original source.
38+ CompilerGenerated,
39+ // The instruction has intentionally had its source location removed,
40+ // typically because it was moved outside of its original control-flow and
41+ // presenting the prior source location would be misleading for debuggers
42+ // or profilers.
43+ Dropped,
44+ // The instruction does not have a known or currently knowable source
45+ // location, e.g. the attribution is ambiguous in a way that can't be
46+ // represented, or determining the correct location is complicated and
47+ // requires future developer effort.
48+ Unknown,
49+ // DebugLoc is attached to an instruction that we don't expect to be
50+ // emitted, and so can omit a valid DILocation; we don't expect to ever try
51+ // and emit these into the line table, and trying to do so is a sign that
52+ // something has gone wrong (most likely a DebugLoc leaking from a transient
53+ // compiler-generated instruction).
54+ Temporary
55+ };
56+
57+ // Extends TrackingMDNodeRef to also store a DebugLocKind, allowing Debugify
58+ // to ignore intentionally-empty DebugLocs.
59+ class DILocAndCoverageTracking : public TrackingMDNodeRef {
60+ public:
61+ DebugLocKind Kind;
62+ // Default constructor for empty DebugLocs.
63+ DILocAndCoverageTracking ()
64+ : TrackingMDNodeRef(nullptr ), Kind(DebugLocKind::Normal) {}
65+ // Valid or nullptr MDNode*, normal DebugLocKind.
66+ DILocAndCoverageTracking (const MDNode *Loc)
67+ : TrackingMDNodeRef(const_cast <MDNode *>(Loc)),
68+ Kind (DebugLocKind::Normal) {}
69+ DILocAndCoverageTracking (const DILocation *Loc);
70+ // Explicit DebugLocKind, which always means a nullptr MDNode*.
71+ DILocAndCoverageTracking (DebugLocKind Kind)
72+ : TrackingMDNodeRef(nullptr ), Kind(Kind) {}
73+ };
74+ template <> struct simplify_type <DILocAndCoverageTracking> {
75+ using SimpleType = MDNode *;
76+
77+ static MDNode *getSimplifiedValue (DILocAndCoverageTracking &MD) {
78+ return MD.get ();
79+ }
80+ };
81+ template <> struct simplify_type <const DILocAndCoverageTracking> {
82+ using SimpleType = MDNode *;
83+
84+ static MDNode *getSimplifiedValue (const DILocAndCoverageTracking &MD) {
85+ return MD.get ();
86+ }
87+ };
88+
89+ using DebugLocTrackingRef = DILocAndCoverageTracking;
90+ #else
91+ using DebugLocTrackingRef = TrackingMDNodeRef;
92+ #endif // ENABLE_DEBUGLOC_COVERAGE_TRACKING
2593
2694 // / A debug info location.
2795 // /
@@ -31,7 +99,8 @@ namespace llvm {
3199 // / To avoid extra includes, \a DebugLoc doubles the \a DILocation API with a
32100 // / one based on relatively opaque \a MDNode pointers.
33101 class DebugLoc {
34- TrackingMDNodeRef Loc;
102+
103+ DebugLocTrackingRef Loc;
35104
36105 public:
37106 DebugLoc () = default ;
@@ -47,6 +116,31 @@ namespace llvm {
47116 // / IR.
48117 explicit DebugLoc (const MDNode *N);
49118
119+ #if ENABLE_DEBUGLOC_COVERAGE_TRACKING
120+ DebugLoc (DebugLocKind Kind) : Loc(Kind) {}
121+ DebugLocKind getKind () const { return Loc.Kind ; }
122+ #endif
123+
124+ #if ENABLE_DEBUGLOC_COVERAGE_TRACKING
125+ static inline DebugLoc getTemporary () {
126+ return DebugLoc (DebugLocKind::Temporary);
127+ }
128+ static inline DebugLoc getUnknown () {
129+ return DebugLoc (DebugLocKind::Unknown);
130+ }
131+ static inline DebugLoc getCompilerGenerated () {
132+ return DebugLoc (DebugLocKind::CompilerGenerated);
133+ }
134+ static inline DebugLoc getDropped () {
135+ return DebugLoc (DebugLocKind::Dropped);
136+ }
137+ #else
138+ static inline DebugLoc getTemporary () { return DebugLoc (); }
139+ static inline DebugLoc getUnknown () { return DebugLoc (); }
140+ static inline DebugLoc getCompilerGenerated () { return DebugLoc (); }
141+ static inline DebugLoc getDropped () { return DebugLoc (); }
142+ #endif // ENABLE_DEBUGLOC_COVERAGE_TRACKING
143+
50144 // / Get the underlying \a DILocation.
51145 // /
52146 // / \pre !*this or \c isa<DILocation>(getAsMDNode()).
0 commit comments