xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/DebugProgramInstruction.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===-- llvm/DebugProgramInstruction.h - Stream of debug info ---*- C++ -*-===//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric //
95f757f3fSDimitry Andric // Data structures for storing variable assignment information in LLVM. In the
105f757f3fSDimitry Andric // dbg.value design, a dbg.value intrinsic specifies the position in a block
115f757f3fSDimitry Andric // a source variable take on an LLVM Value:
125f757f3fSDimitry Andric //
135f757f3fSDimitry Andric //    %foo = add i32 1, %0
145f757f3fSDimitry Andric //    dbg.value(metadata i32 %foo, ...)
155f757f3fSDimitry Andric //    %bar = void call @ext(%foo);
165f757f3fSDimitry Andric //
175f757f3fSDimitry Andric // and all information is stored in the Value / Metadata hierachy defined
18*0fca6ea1SDimitry Andric // elsewhere in LLVM. In the "DbgRecord" design, each instruction /may/ have a
19*0fca6ea1SDimitry Andric // connection with a DbgMarker, which identifies a position immediately before
20*0fca6ea1SDimitry Andric // the instruction, and each DbgMarker /may/ then have connections to DbgRecords
21*0fca6ea1SDimitry Andric // which record the variable assignment information. To illustrate:
225f757f3fSDimitry Andric //
235f757f3fSDimitry Andric //    %foo = add i32 1, %0
24*0fca6ea1SDimitry Andric //       ; foo->DebugMarker == nullptr
255f757f3fSDimitry Andric //       ;; There are no variable assignments / debug records "in front" of
26*0fca6ea1SDimitry Andric //       ;; the instruction for %foo, therefore it has no DebugMarker.
275f757f3fSDimitry Andric //    %bar = void call @ext(%foo)
28*0fca6ea1SDimitry Andric //       ; bar->DebugMarker = {
29*0fca6ea1SDimitry Andric //       ;   StoredDbgRecords = {
30*0fca6ea1SDimitry Andric //       ;     DbgVariableRecord(metadata i32 %foo, ...)
315f757f3fSDimitry Andric //       ;   }
325f757f3fSDimitry Andric //       ; }
335f757f3fSDimitry Andric //       ;; There is a debug-info record in front of the %bar instruction,
34*0fca6ea1SDimitry Andric //       ;; thus it points at a DbgMarker object. That DbgMarker contains a
35*0fca6ea1SDimitry Andric //       ;; DbgVariableRecord in its ilist, storing the equivalent information
36*0fca6ea1SDimitry Andric //       ;; to the dbg.value above: the Value, DILocalVariable, etc.
375f757f3fSDimitry Andric //
385f757f3fSDimitry Andric // This structure separates the two concerns of the position of the debug-info
395f757f3fSDimitry Andric // in the function, and the Value that it refers to. It also creates a new
405f757f3fSDimitry Andric // "place" in-between the Value / Metadata hierachy where we can customise
415f757f3fSDimitry Andric // storage and allocation techniques to better suite debug-info workloads.
425f757f3fSDimitry Andric // NB: as of the initial prototype, none of that has actually been attempted
435f757f3fSDimitry Andric // yet.
445f757f3fSDimitry Andric //
455f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
465f757f3fSDimitry Andric 
475f757f3fSDimitry Andric #ifndef LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
485f757f3fSDimitry Andric #define LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
495f757f3fSDimitry Andric 
505f757f3fSDimitry Andric #include "llvm/ADT/ilist.h"
517a6dacacSDimitry Andric #include "llvm/ADT/ilist_node.h"
525f757f3fSDimitry Andric #include "llvm/ADT/iterator.h"
53*0fca6ea1SDimitry Andric #include "llvm/IR/DbgVariableFragmentInfo.h"
545f757f3fSDimitry Andric #include "llvm/IR/DebugLoc.h"
557a6dacacSDimitry Andric #include "llvm/IR/Instruction.h"
567a6dacacSDimitry Andric #include "llvm/IR/SymbolTableListTraits.h"
57*0fca6ea1SDimitry Andric #include "llvm/Support/Casting.h"
585f757f3fSDimitry Andric 
595f757f3fSDimitry Andric namespace llvm {
605f757f3fSDimitry Andric 
615f757f3fSDimitry Andric class Instruction;
625f757f3fSDimitry Andric class BasicBlock;
635f757f3fSDimitry Andric class MDNode;
645f757f3fSDimitry Andric class Module;
655f757f3fSDimitry Andric class DbgVariableIntrinsic;
66*0fca6ea1SDimitry Andric class DbgInfoIntrinsic;
67*0fca6ea1SDimitry Andric class DbgLabelInst;
687a6dacacSDimitry Andric class DIAssignID;
69*0fca6ea1SDimitry Andric class DbgMarker;
70*0fca6ea1SDimitry Andric class DbgVariableRecord;
715f757f3fSDimitry Andric class raw_ostream;
725f757f3fSDimitry Andric 
73*0fca6ea1SDimitry Andric /// A typed tracking MDNode reference that does not require a definition for its
74*0fca6ea1SDimitry Andric /// parameter type. Necessary to avoid including DebugInfoMetadata.h, which has
75*0fca6ea1SDimitry Andric /// a significant impact on compile times if included in this file.
76*0fca6ea1SDimitry Andric template <typename T> class DbgRecordParamRef {
77*0fca6ea1SDimitry Andric   TrackingMDNodeRef Ref;
785f757f3fSDimitry Andric 
795f757f3fSDimitry Andric public:
80*0fca6ea1SDimitry Andric public:
81*0fca6ea1SDimitry Andric   DbgRecordParamRef() = default;
825f757f3fSDimitry Andric 
83*0fca6ea1SDimitry Andric   /// Construct from the templated type.
84*0fca6ea1SDimitry Andric   DbgRecordParamRef(const T *Param);
85*0fca6ea1SDimitry Andric 
86*0fca6ea1SDimitry Andric   /// Construct from an \a MDNode.
87*0fca6ea1SDimitry Andric   ///
88*0fca6ea1SDimitry Andric   /// Note: if \c Param does not have the template type, a verifier check will
89*0fca6ea1SDimitry Andric   /// fail, and accessors will crash.  However, construction from other nodes
90*0fca6ea1SDimitry Andric   /// is supported in order to handle forward references when reading textual
91*0fca6ea1SDimitry Andric   /// IR.
92*0fca6ea1SDimitry Andric   explicit DbgRecordParamRef(const MDNode *Param);
93*0fca6ea1SDimitry Andric 
94*0fca6ea1SDimitry Andric   /// Get the underlying type.
95*0fca6ea1SDimitry Andric   ///
96*0fca6ea1SDimitry Andric   /// \pre !*this or \c isa<T>(getAsMDNode()).
97*0fca6ea1SDimitry Andric   /// @{
98*0fca6ea1SDimitry Andric   T *get() const;
99*0fca6ea1SDimitry Andric   operator T *() const { return get(); }
100*0fca6ea1SDimitry Andric   T *operator->() const { return get(); }
101*0fca6ea1SDimitry Andric   T &operator*() const { return *get(); }
102*0fca6ea1SDimitry Andric   /// @}
103*0fca6ea1SDimitry Andric 
104*0fca6ea1SDimitry Andric   /// Check for null.
105*0fca6ea1SDimitry Andric   ///
106*0fca6ea1SDimitry Andric   /// Check for null in a way that is safe with broken debug info.
107*0fca6ea1SDimitry Andric   explicit operator bool() const { return Ref; }
108*0fca6ea1SDimitry Andric 
109*0fca6ea1SDimitry Andric   /// Return \c this as a \a MDNode.
getAsMDNode()110*0fca6ea1SDimitry Andric   MDNode *getAsMDNode() const { return Ref; }
111*0fca6ea1SDimitry Andric 
112*0fca6ea1SDimitry Andric   bool operator==(const DbgRecordParamRef &Other) const {
113*0fca6ea1SDimitry Andric     return Ref == Other.Ref;
114*0fca6ea1SDimitry Andric   }
115*0fca6ea1SDimitry Andric   bool operator!=(const DbgRecordParamRef &Other) const {
116*0fca6ea1SDimitry Andric     return Ref != Other.Ref;
117*0fca6ea1SDimitry Andric   }
118*0fca6ea1SDimitry Andric };
119*0fca6ea1SDimitry Andric 
120*0fca6ea1SDimitry Andric /// Base class for non-instruction debug metadata records that have positions
121*0fca6ea1SDimitry Andric /// within IR. Features various methods copied across from the Instruction
122*0fca6ea1SDimitry Andric /// class to aid ease-of-use. DbgRecords should always be linked into a
123*0fca6ea1SDimitry Andric /// DbgMarker's StoredDbgRecords list. The marker connects a DbgRecord back to
124*0fca6ea1SDimitry Andric /// its position in the BasicBlock.
125*0fca6ea1SDimitry Andric ///
126*0fca6ea1SDimitry Andric /// We need a discriminator for dyn/isa casts. In order to avoid paying for a
127*0fca6ea1SDimitry Andric /// vtable for "virtual" functions too, subclasses must add a new discriminator
128*0fca6ea1SDimitry Andric /// value (RecordKind) and cases to a few functions in the base class:
129*0fca6ea1SDimitry Andric ///   deleteRecord
130*0fca6ea1SDimitry Andric ///   clone
131*0fca6ea1SDimitry Andric ///   isIdenticalToWhenDefined
132*0fca6ea1SDimitry Andric ///   both print methods
133*0fca6ea1SDimitry Andric ///   createDebugIntrinsic
134*0fca6ea1SDimitry Andric class DbgRecord : public ilist_node<DbgRecord> {
135*0fca6ea1SDimitry Andric public:
136*0fca6ea1SDimitry Andric   /// Marker that this DbgRecord is linked into.
137*0fca6ea1SDimitry Andric   DbgMarker *Marker = nullptr;
138*0fca6ea1SDimitry Andric   /// Subclass discriminator.
139*0fca6ea1SDimitry Andric   enum Kind : uint8_t { ValueKind, LabelKind };
140*0fca6ea1SDimitry Andric 
141*0fca6ea1SDimitry Andric protected:
142*0fca6ea1SDimitry Andric   DebugLoc DbgLoc;
143*0fca6ea1SDimitry Andric   Kind RecordKind; ///< Subclass discriminator.
144*0fca6ea1SDimitry Andric 
145*0fca6ea1SDimitry Andric public:
DbgRecord(Kind RecordKind,DebugLoc DL)146*0fca6ea1SDimitry Andric   DbgRecord(Kind RecordKind, DebugLoc DL)
147*0fca6ea1SDimitry Andric       : DbgLoc(DL), RecordKind(RecordKind) {}
148*0fca6ea1SDimitry Andric 
149*0fca6ea1SDimitry Andric   /// Methods that dispatch to subclass implementations. These need to be
150*0fca6ea1SDimitry Andric   /// manually updated when a new subclass is added.
151*0fca6ea1SDimitry Andric   ///@{
152*0fca6ea1SDimitry Andric   void deleteRecord();
153*0fca6ea1SDimitry Andric   DbgRecord *clone() const;
154*0fca6ea1SDimitry Andric   void print(raw_ostream &O, bool IsForDebug = false) const;
155*0fca6ea1SDimitry Andric   void print(raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug) const;
156*0fca6ea1SDimitry Andric   bool isIdenticalToWhenDefined(const DbgRecord &R) const;
157*0fca6ea1SDimitry Andric   /// Convert this DbgRecord back into an appropriate llvm.dbg.* intrinsic.
158*0fca6ea1SDimitry Andric   /// \p InsertBefore Optional position to insert this intrinsic.
159*0fca6ea1SDimitry Andric   /// \returns A new llvm.dbg.* intrinsic representiung this DbgRecord.
160*0fca6ea1SDimitry Andric   DbgInfoIntrinsic *createDebugIntrinsic(Module *M,
161*0fca6ea1SDimitry Andric                                          Instruction *InsertBefore) const;
162*0fca6ea1SDimitry Andric   ///@}
163*0fca6ea1SDimitry Andric 
164*0fca6ea1SDimitry Andric   /// Same as isIdenticalToWhenDefined but checks DebugLoc too.
165*0fca6ea1SDimitry Andric   bool isEquivalentTo(const DbgRecord &R) const;
166*0fca6ea1SDimitry Andric 
getRecordKind()167*0fca6ea1SDimitry Andric   Kind getRecordKind() const { return RecordKind; }
168*0fca6ea1SDimitry Andric 
setMarker(DbgMarker * M)169*0fca6ea1SDimitry Andric   void setMarker(DbgMarker *M) { Marker = M; }
170*0fca6ea1SDimitry Andric 
getMarker()171*0fca6ea1SDimitry Andric   DbgMarker *getMarker() { return Marker; }
getMarker()172*0fca6ea1SDimitry Andric   const DbgMarker *getMarker() const { return Marker; }
173*0fca6ea1SDimitry Andric 
174*0fca6ea1SDimitry Andric   BasicBlock *getBlock();
175*0fca6ea1SDimitry Andric   const BasicBlock *getBlock() const;
176*0fca6ea1SDimitry Andric 
177*0fca6ea1SDimitry Andric   Function *getFunction();
178*0fca6ea1SDimitry Andric   const Function *getFunction() const;
179*0fca6ea1SDimitry Andric 
180*0fca6ea1SDimitry Andric   Module *getModule();
181*0fca6ea1SDimitry Andric   const Module *getModule() const;
182*0fca6ea1SDimitry Andric 
183*0fca6ea1SDimitry Andric   LLVMContext &getContext();
184*0fca6ea1SDimitry Andric   const LLVMContext &getContext() const;
185*0fca6ea1SDimitry Andric 
186*0fca6ea1SDimitry Andric   const Instruction *getInstruction() const;
1875f757f3fSDimitry Andric   const BasicBlock *getParent() const;
1885f757f3fSDimitry Andric   BasicBlock *getParent();
189*0fca6ea1SDimitry Andric 
1905f757f3fSDimitry Andric   void removeFromParent();
1915f757f3fSDimitry Andric   void eraseFromParent();
1925f757f3fSDimitry Andric 
getNextNode()193*0fca6ea1SDimitry Andric   DbgRecord *getNextNode() { return &*std::next(getIterator()); }
getPrevNode()194*0fca6ea1SDimitry Andric   DbgRecord *getPrevNode() { return &*std::prev(getIterator()); }
195*0fca6ea1SDimitry Andric   void insertBefore(DbgRecord *InsertBefore);
196*0fca6ea1SDimitry Andric   void insertAfter(DbgRecord *InsertAfter);
197*0fca6ea1SDimitry Andric   void moveBefore(DbgRecord *MoveBefore);
198*0fca6ea1SDimitry Andric   void moveAfter(DbgRecord *MoveAfter);
1997a6dacacSDimitry Andric 
getDebugLoc()200*0fca6ea1SDimitry Andric   DebugLoc getDebugLoc() const { return DbgLoc; }
setDebugLoc(DebugLoc Loc)201*0fca6ea1SDimitry Andric   void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
2025f757f3fSDimitry Andric 
203*0fca6ea1SDimitry Andric   void dump() const;
204*0fca6ea1SDimitry Andric 
205*0fca6ea1SDimitry Andric   using self_iterator = simple_ilist<DbgRecord>::iterator;
206*0fca6ea1SDimitry Andric   using const_self_iterator = simple_ilist<DbgRecord>::const_iterator;
207*0fca6ea1SDimitry Andric 
208*0fca6ea1SDimitry Andric protected:
209*0fca6ea1SDimitry Andric   /// Similarly to Value, we avoid paying the cost of a vtable
210*0fca6ea1SDimitry Andric   /// by protecting the dtor and having deleteRecord dispatch
211*0fca6ea1SDimitry Andric   /// cleanup.
212*0fca6ea1SDimitry Andric   /// Use deleteRecord to delete a generic record.
213*0fca6ea1SDimitry Andric   ~DbgRecord() = default;
214*0fca6ea1SDimitry Andric };
215*0fca6ea1SDimitry Andric 
216*0fca6ea1SDimitry Andric inline raw_ostream &operator<<(raw_ostream &OS, const DbgRecord &R) {
217*0fca6ea1SDimitry Andric   R.print(OS);
218*0fca6ea1SDimitry Andric   return OS;
219*0fca6ea1SDimitry Andric }
220*0fca6ea1SDimitry Andric 
221*0fca6ea1SDimitry Andric /// Records a position in IR for a source label (DILabel). Corresponds to the
222*0fca6ea1SDimitry Andric /// llvm.dbg.label intrinsic.
223*0fca6ea1SDimitry Andric class DbgLabelRecord : public DbgRecord {
224*0fca6ea1SDimitry Andric   DbgRecordParamRef<DILabel> Label;
225*0fca6ea1SDimitry Andric 
226*0fca6ea1SDimitry Andric   /// This constructor intentionally left private, so that it is only called via
227*0fca6ea1SDimitry Andric   /// "createUnresolvedDbgLabelRecord", which clearly expresses that it is for
228*0fca6ea1SDimitry Andric   /// parsing only.
229*0fca6ea1SDimitry Andric   DbgLabelRecord(MDNode *Label, MDNode *DL);
230*0fca6ea1SDimitry Andric 
231*0fca6ea1SDimitry Andric public:
232*0fca6ea1SDimitry Andric   DbgLabelRecord(DILabel *Label, DebugLoc DL);
233*0fca6ea1SDimitry Andric 
234*0fca6ea1SDimitry Andric   /// For use during parsing; creates a DbgLabelRecord from as-of-yet unresolved
235*0fca6ea1SDimitry Andric   /// MDNodes. Trying to access the resulting DbgLabelRecord's fields before
236*0fca6ea1SDimitry Andric   /// they are resolved, or if they resolve to the wrong type, will result in a
237*0fca6ea1SDimitry Andric   /// crash.
238*0fca6ea1SDimitry Andric   static DbgLabelRecord *createUnresolvedDbgLabelRecord(MDNode *Label,
239*0fca6ea1SDimitry Andric                                                         MDNode *DL);
240*0fca6ea1SDimitry Andric 
241*0fca6ea1SDimitry Andric   DbgLabelRecord *clone() const;
242*0fca6ea1SDimitry Andric   void print(raw_ostream &O, bool IsForDebug = false) const;
243*0fca6ea1SDimitry Andric   void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
244*0fca6ea1SDimitry Andric   DbgLabelInst *createDebugIntrinsic(Module *M,
245*0fca6ea1SDimitry Andric                                      Instruction *InsertBefore) const;
246*0fca6ea1SDimitry Andric 
setLabel(DILabel * NewLabel)247*0fca6ea1SDimitry Andric   void setLabel(DILabel *NewLabel) { Label = NewLabel; }
getLabel()248*0fca6ea1SDimitry Andric   DILabel *getLabel() const { return Label.get(); }
getRawLabel()249*0fca6ea1SDimitry Andric   MDNode *getRawLabel() const { return Label.getAsMDNode(); };
250*0fca6ea1SDimitry Andric 
251*0fca6ea1SDimitry Andric   /// Support type inquiry through isa, cast, and dyn_cast.
classof(const DbgRecord * E)252*0fca6ea1SDimitry Andric   static bool classof(const DbgRecord *E) {
253*0fca6ea1SDimitry Andric     return E->getRecordKind() == LabelKind;
254*0fca6ea1SDimitry Andric   }
255*0fca6ea1SDimitry Andric };
256*0fca6ea1SDimitry Andric 
257*0fca6ea1SDimitry Andric /// Record of a variable value-assignment, aka a non instruction representation
258*0fca6ea1SDimitry Andric /// of the dbg.value intrinsic.
259*0fca6ea1SDimitry Andric ///
260*0fca6ea1SDimitry Andric /// This class inherits from DebugValueUser to allow LLVM's metadata facilities
261*0fca6ea1SDimitry Andric /// to update our references to metadata beneath our feet.
262*0fca6ea1SDimitry Andric class DbgVariableRecord : public DbgRecord, protected DebugValueUser {
263*0fca6ea1SDimitry Andric   friend class DebugValueUser;
264*0fca6ea1SDimitry Andric 
265*0fca6ea1SDimitry Andric public:
266*0fca6ea1SDimitry Andric   enum class LocationType : uint8_t {
2675f757f3fSDimitry Andric     Declare,
2685f757f3fSDimitry Andric     Value,
2697a6dacacSDimitry Andric     Assign,
2705f757f3fSDimitry Andric 
2715f757f3fSDimitry Andric     End, ///< Marks the end of the concrete types.
2725f757f3fSDimitry Andric     Any, ///< To indicate all LocationTypes in searches.
2735f757f3fSDimitry Andric   };
274*0fca6ea1SDimitry Andric   /// Classification of the debug-info record that this DbgVariableRecord
275*0fca6ea1SDimitry Andric   /// represents. Essentially, "does this correspond to a dbg.value,
276*0fca6ea1SDimitry Andric   /// dbg.declare, or dbg.assign?".
277*0fca6ea1SDimitry Andric   /// FIXME: We could use spare padding bits from DbgRecord for this.
2785f757f3fSDimitry Andric   LocationType Type;
2795f757f3fSDimitry Andric 
280*0fca6ea1SDimitry Andric   // NB: there is no explicit "Value" field in this class, it's effectively the
281*0fca6ea1SDimitry Andric   // DebugValueUser superclass instead. The referred to Value can either be a
282*0fca6ea1SDimitry Andric   // ValueAsMetadata or a DIArgList.
2835f757f3fSDimitry Andric 
284*0fca6ea1SDimitry Andric   DbgRecordParamRef<DILocalVariable> Variable;
285*0fca6ea1SDimitry Andric   DbgRecordParamRef<DIExpression> Expression;
286*0fca6ea1SDimitry Andric   DbgRecordParamRef<DIExpression> AddressExpression;
2877a6dacacSDimitry Andric 
288*0fca6ea1SDimitry Andric public:
289*0fca6ea1SDimitry Andric   /// Create a new DbgVariableRecord representing the intrinsic \p DVI, for
290*0fca6ea1SDimitry Andric   /// example the assignment represented by a dbg.value.
291*0fca6ea1SDimitry Andric   DbgVariableRecord(const DbgVariableIntrinsic *DVI);
292*0fca6ea1SDimitry Andric   DbgVariableRecord(const DbgVariableRecord &DVR);
293*0fca6ea1SDimitry Andric   /// Directly construct a new DbgVariableRecord representing a dbg.value
294*0fca6ea1SDimitry Andric   /// intrinsic assigning \p Location to the DV / Expr / DI variable.
295*0fca6ea1SDimitry Andric   DbgVariableRecord(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
296*0fca6ea1SDimitry Andric                     const DILocation *DI,
297*0fca6ea1SDimitry Andric                     LocationType Type = LocationType::Value);
298*0fca6ea1SDimitry Andric   DbgVariableRecord(Metadata *Value, DILocalVariable *Variable,
299*0fca6ea1SDimitry Andric                     DIExpression *Expression, DIAssignID *AssignID,
300*0fca6ea1SDimitry Andric                     Metadata *Address, DIExpression *AddressExpression,
3017a6dacacSDimitry Andric                     const DILocation *DI);
3027a6dacacSDimitry Andric 
303*0fca6ea1SDimitry Andric private:
304*0fca6ea1SDimitry Andric   /// Private constructor for creating new instances during parsing only. Only
305*0fca6ea1SDimitry Andric   /// called through `createUnresolvedDbgVariableRecord` below, which makes
306*0fca6ea1SDimitry Andric   /// clear that this is used for parsing only, and will later return a subclass
307*0fca6ea1SDimitry Andric   /// depending on which Type is passed.
308*0fca6ea1SDimitry Andric   DbgVariableRecord(LocationType Type, Metadata *Val, MDNode *Variable,
309*0fca6ea1SDimitry Andric                     MDNode *Expression, MDNode *AssignID, Metadata *Address,
310*0fca6ea1SDimitry Andric                     MDNode *AddressExpression, MDNode *DI);
311*0fca6ea1SDimitry Andric 
312*0fca6ea1SDimitry Andric public:
313*0fca6ea1SDimitry Andric   /// Used to create DbgVariableRecords during parsing, where some metadata
314*0fca6ea1SDimitry Andric   /// references may still be unresolved. Although for some fields a generic
315*0fca6ea1SDimitry Andric   /// `Metadata*` argument is accepted for forward type-references, the verifier
316*0fca6ea1SDimitry Andric   /// and accessors will reject incorrect types later on. The function is used
317*0fca6ea1SDimitry Andric   /// for all types of DbgVariableRecords for simplicity while parsing, but
318*0fca6ea1SDimitry Andric   /// asserts if any necessary fields are empty or unused fields are not empty,
319*0fca6ea1SDimitry Andric   /// i.e. if the #dbg_assign fields are used for a non-dbg-assign type.
320*0fca6ea1SDimitry Andric   static DbgVariableRecord *
321*0fca6ea1SDimitry Andric   createUnresolvedDbgVariableRecord(LocationType Type, Metadata *Val,
322*0fca6ea1SDimitry Andric                                     MDNode *Variable, MDNode *Expression,
323*0fca6ea1SDimitry Andric                                     MDNode *AssignID, Metadata *Address,
324*0fca6ea1SDimitry Andric                                     MDNode *AddressExpression, MDNode *DI);
325*0fca6ea1SDimitry Andric 
326*0fca6ea1SDimitry Andric   static DbgVariableRecord *
327*0fca6ea1SDimitry Andric   createDVRAssign(Value *Val, DILocalVariable *Variable,
328*0fca6ea1SDimitry Andric                   DIExpression *Expression, DIAssignID *AssignID,
329*0fca6ea1SDimitry Andric                   Value *Address, DIExpression *AddressExpression,
330*0fca6ea1SDimitry Andric                   const DILocation *DI);
331*0fca6ea1SDimitry Andric   static DbgVariableRecord *
332*0fca6ea1SDimitry Andric   createLinkedDVRAssign(Instruction *LinkedInstr, Value *Val,
333*0fca6ea1SDimitry Andric                         DILocalVariable *Variable, DIExpression *Expression,
334*0fca6ea1SDimitry Andric                         Value *Address, DIExpression *AddressExpression,
335*0fca6ea1SDimitry Andric                         const DILocation *DI);
336*0fca6ea1SDimitry Andric 
337*0fca6ea1SDimitry Andric   static DbgVariableRecord *createDbgVariableRecord(Value *Location,
338*0fca6ea1SDimitry Andric                                                     DILocalVariable *DV,
339*0fca6ea1SDimitry Andric                                                     DIExpression *Expr,
340*0fca6ea1SDimitry Andric                                                     const DILocation *DI);
341*0fca6ea1SDimitry Andric   static DbgVariableRecord *
342*0fca6ea1SDimitry Andric   createDbgVariableRecord(Value *Location, DILocalVariable *DV,
3437a6dacacSDimitry Andric                           DIExpression *Expr, const DILocation *DI,
344*0fca6ea1SDimitry Andric                           DbgVariableRecord &InsertBefore);
345*0fca6ea1SDimitry Andric   static DbgVariableRecord *createDVRDeclare(Value *Address,
346*0fca6ea1SDimitry Andric                                              DILocalVariable *DV,
347*0fca6ea1SDimitry Andric                                              DIExpression *Expr,
348*0fca6ea1SDimitry Andric                                              const DILocation *DI);
349*0fca6ea1SDimitry Andric   static DbgVariableRecord *
350*0fca6ea1SDimitry Andric   createDVRDeclare(Value *Address, DILocalVariable *DV, DIExpression *Expr,
351*0fca6ea1SDimitry Andric                    const DILocation *DI, DbgVariableRecord &InsertBefore);
3525f757f3fSDimitry Andric 
3535f757f3fSDimitry Andric   /// Iterator for ValueAsMetadata that internally uses direct pointer iteration
3545f757f3fSDimitry Andric   /// over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the
3555f757f3fSDimitry Andric   /// ValueAsMetadata .
3565f757f3fSDimitry Andric   class location_op_iterator
3575f757f3fSDimitry Andric       : public iterator_facade_base<location_op_iterator,
3585f757f3fSDimitry Andric                                     std::bidirectional_iterator_tag, Value *> {
3595f757f3fSDimitry Andric     PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
3605f757f3fSDimitry Andric 
3615f757f3fSDimitry Andric   public:
location_op_iterator(ValueAsMetadata * SingleIter)3625f757f3fSDimitry Andric     location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {}
location_op_iterator(ValueAsMetadata ** MultiIter)3635f757f3fSDimitry Andric     location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {}
3645f757f3fSDimitry Andric 
location_op_iterator(const location_op_iterator & R)3655f757f3fSDimitry Andric     location_op_iterator(const location_op_iterator &R) : I(R.I) {}
3665f757f3fSDimitry Andric     location_op_iterator &operator=(const location_op_iterator &R) {
3675f757f3fSDimitry Andric       I = R.I;
3685f757f3fSDimitry Andric       return *this;
3695f757f3fSDimitry Andric     }
3705f757f3fSDimitry Andric     bool operator==(const location_op_iterator &RHS) const {
3715f757f3fSDimitry Andric       return I == RHS.I;
3725f757f3fSDimitry Andric     }
3735f757f3fSDimitry Andric     const Value *operator*() const {
3745f757f3fSDimitry Andric       ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
3755f757f3fSDimitry Andric                                  ? I.get<ValueAsMetadata *>()
3765f757f3fSDimitry Andric                                  : *I.get<ValueAsMetadata **>();
3775f757f3fSDimitry Andric       return VAM->getValue();
3785f757f3fSDimitry Andric     };
3795f757f3fSDimitry Andric     Value *operator*() {
3805f757f3fSDimitry Andric       ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
3815f757f3fSDimitry Andric                                  ? I.get<ValueAsMetadata *>()
3825f757f3fSDimitry Andric                                  : *I.get<ValueAsMetadata **>();
3835f757f3fSDimitry Andric       return VAM->getValue();
3845f757f3fSDimitry Andric     }
3855f757f3fSDimitry Andric     location_op_iterator &operator++() {
3865f757f3fSDimitry Andric       if (I.is<ValueAsMetadata *>())
3875f757f3fSDimitry Andric         I = I.get<ValueAsMetadata *>() + 1;
3885f757f3fSDimitry Andric       else
3895f757f3fSDimitry Andric         I = I.get<ValueAsMetadata **>() + 1;
3905f757f3fSDimitry Andric       return *this;
3915f757f3fSDimitry Andric     }
3925f757f3fSDimitry Andric     location_op_iterator &operator--() {
3935f757f3fSDimitry Andric       if (I.is<ValueAsMetadata *>())
3945f757f3fSDimitry Andric         I = I.get<ValueAsMetadata *>() - 1;
3955f757f3fSDimitry Andric       else
3965f757f3fSDimitry Andric         I = I.get<ValueAsMetadata **>() - 1;
3975f757f3fSDimitry Andric       return *this;
3985f757f3fSDimitry Andric     }
3995f757f3fSDimitry Andric   };
4005f757f3fSDimitry Andric 
isDbgDeclare()4017a6dacacSDimitry Andric   bool isDbgDeclare() { return Type == LocationType::Declare; }
isDbgValue()4027a6dacacSDimitry Andric   bool isDbgValue() { return Type == LocationType::Value; }
4037a6dacacSDimitry Andric 
4045f757f3fSDimitry Andric   /// Get the locations corresponding to the variable referenced by the debug
4055f757f3fSDimitry Andric   /// info intrinsic.  Depending on the intrinsic, this could be the
4065f757f3fSDimitry Andric   /// variable's value or its address.
4075f757f3fSDimitry Andric   iterator_range<location_op_iterator> location_ops() const;
4085f757f3fSDimitry Andric 
4095f757f3fSDimitry Andric   Value *getVariableLocationOp(unsigned OpIdx) const;
4105f757f3fSDimitry Andric 
4115f757f3fSDimitry Andric   void replaceVariableLocationOp(Value *OldValue, Value *NewValue,
4125f757f3fSDimitry Andric                                  bool AllowEmpty = false);
4135f757f3fSDimitry Andric   void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue);
4145f757f3fSDimitry Andric   /// Adding a new location operand will always result in this intrinsic using
4155f757f3fSDimitry Andric   /// an ArgList, and must always be accompanied by a new expression that uses
4165f757f3fSDimitry Andric   /// the new operand.
4175f757f3fSDimitry Andric   void addVariableLocationOps(ArrayRef<Value *> NewValues,
4185f757f3fSDimitry Andric                               DIExpression *NewExpr);
4195f757f3fSDimitry Andric 
4205f757f3fSDimitry Andric   unsigned getNumVariableLocationOps() const;
4215f757f3fSDimitry Andric 
hasArgList()4225f757f3fSDimitry Andric   bool hasArgList() const { return isa<DIArgList>(getRawLocation()); }
423*0fca6ea1SDimitry Andric   /// Returns true if this DbgVariableRecord has no empty MDNodes in its
424*0fca6ea1SDimitry Andric   /// location list.
hasValidLocation()4255f757f3fSDimitry Andric   bool hasValidLocation() const { return getVariableLocationOp(0) != nullptr; }
4265f757f3fSDimitry Andric 
4275f757f3fSDimitry Andric   /// Does this describe the address of a local variable. True for dbg.addr
4285f757f3fSDimitry Andric   /// and dbg.declare, but not dbg.value, which describes its value.
isAddressOfVariable()4297a6dacacSDimitry Andric   bool isAddressOfVariable() const { return Type == LocationType::Declare; }
getType()4305f757f3fSDimitry Andric   LocationType getType() const { return Type; }
4315f757f3fSDimitry Andric 
4325f757f3fSDimitry Andric   void setKillLocation();
4335f757f3fSDimitry Andric   bool isKillLocation() const;
4345f757f3fSDimitry Andric 
setVariable(DILocalVariable * NewVar)435*0fca6ea1SDimitry Andric   void setVariable(DILocalVariable *NewVar) { Variable = NewVar; }
getVariable()436*0fca6ea1SDimitry Andric   DILocalVariable *getVariable() const { return Variable.get(); };
getRawVariable()437*0fca6ea1SDimitry Andric   MDNode *getRawVariable() const { return Variable.getAsMDNode(); }
4385f757f3fSDimitry Andric 
setExpression(DIExpression * NewExpr)439*0fca6ea1SDimitry Andric   void setExpression(DIExpression *NewExpr) { Expression = NewExpr; }
getExpression()440*0fca6ea1SDimitry Andric   DIExpression *getExpression() const { return Expression.get(); }
getRawExpression()441*0fca6ea1SDimitry Andric   MDNode *getRawExpression() const { return Expression.getAsMDNode(); }
4425f757f3fSDimitry Andric 
4437a6dacacSDimitry Andric   /// Returns the metadata operand for the first location description. i.e.,
4447a6dacacSDimitry Andric   /// dbg intrinsic dbg.value,declare operand and dbg.assign 1st location
4457a6dacacSDimitry Andric   /// operand (the "value componenet"). Note the operand (singular) may be
4467a6dacacSDimitry Andric   /// a DIArgList which is a list of values.
getRawLocation()4477a6dacacSDimitry Andric   Metadata *getRawLocation() const { return DebugValues[0]; }
4487a6dacacSDimitry Andric 
4497a6dacacSDimitry Andric   Value *getValue(unsigned OpIdx = 0) const {
4507a6dacacSDimitry Andric     return getVariableLocationOp(OpIdx);
4517a6dacacSDimitry Andric   }
4525f757f3fSDimitry Andric 
4535f757f3fSDimitry Andric   /// Use of this should generally be avoided; instead,
4545f757f3fSDimitry Andric   /// replaceVariableLocationOp and addVariableLocationOps should be used where
4555f757f3fSDimitry Andric   /// possible to avoid creating invalid state.
setRawLocation(Metadata * NewLocation)4565f757f3fSDimitry Andric   void setRawLocation(Metadata *NewLocation) {
457*0fca6ea1SDimitry Andric     assert((isa<ValueAsMetadata>(NewLocation) || isa<DIArgList>(NewLocation) ||
4585f757f3fSDimitry Andric             isa<MDNode>(NewLocation)) &&
459*0fca6ea1SDimitry Andric            "Location for a DbgVariableRecord must be either ValueAsMetadata or "
460*0fca6ea1SDimitry Andric            "DIArgList");
4617a6dacacSDimitry Andric     resetDebugValue(0, NewLocation);
4625f757f3fSDimitry Andric   }
4635f757f3fSDimitry Andric 
464*0fca6ea1SDimitry Andric   std::optional<DbgVariableFragmentInfo> getFragment() const;
465*0fca6ea1SDimitry Andric   /// Get the FragmentInfo for the variable if it exists, otherwise return a
466*0fca6ea1SDimitry Andric   /// FragmentInfo that covers the entire variable if the variable size is
467*0fca6ea1SDimitry Andric   /// known, otherwise return a zero-sized fragment.
getFragmentOrEntireVariable()468*0fca6ea1SDimitry Andric   DbgVariableFragmentInfo getFragmentOrEntireVariable() const {
469*0fca6ea1SDimitry Andric     if (auto Frag = getFragment())
470*0fca6ea1SDimitry Andric       return *Frag;
471*0fca6ea1SDimitry Andric     if (auto Sz = getFragmentSizeInBits())
472*0fca6ea1SDimitry Andric       return {*Sz, 0};
473*0fca6ea1SDimitry Andric     return {0, 0};
474*0fca6ea1SDimitry Andric   }
4755f757f3fSDimitry Andric   /// Get the size (in bits) of the variable, or fragment of the variable that
4765f757f3fSDimitry Andric   /// is described.
4775f757f3fSDimitry Andric   std::optional<uint64_t> getFragmentSizeInBits() const;
4785f757f3fSDimitry Andric 
isEquivalentTo(const DbgVariableRecord & Other)479*0fca6ea1SDimitry Andric   bool isEquivalentTo(const DbgVariableRecord &Other) const {
480*0fca6ea1SDimitry Andric     return DbgLoc == Other.DbgLoc && isIdenticalToWhenDefined(Other);
4817a6dacacSDimitry Andric   }
4827a6dacacSDimitry Andric   // Matches the definition of the Instruction version, equivalent to above but
4837a6dacacSDimitry Andric   // without checking DbgLoc.
isIdenticalToWhenDefined(const DbgVariableRecord & Other)484*0fca6ea1SDimitry Andric   bool isIdenticalToWhenDefined(const DbgVariableRecord &Other) const {
485*0fca6ea1SDimitry Andric     return std::tie(Type, DebugValues, Variable, Expression,
486*0fca6ea1SDimitry Andric                     AddressExpression) ==
4877a6dacacSDimitry Andric            std::tie(Other.Type, Other.DebugValues, Other.Variable,
488*0fca6ea1SDimitry Andric                     Other.Expression, Other.AddressExpression);
4897a6dacacSDimitry Andric   }
4907a6dacacSDimitry Andric 
4917a6dacacSDimitry Andric   /// @name DbgAssign Methods
4927a6dacacSDimitry Andric   /// @{
isDbgAssign()4937a6dacacSDimitry Andric   bool isDbgAssign() const { return getType() == LocationType::Assign; }
4947a6dacacSDimitry Andric 
4957a6dacacSDimitry Andric   Value *getAddress() const;
getRawAddress()4967a6dacacSDimitry Andric   Metadata *getRawAddress() const {
4977a6dacacSDimitry Andric     return isDbgAssign() ? DebugValues[1] : DebugValues[0];
4987a6dacacSDimitry Andric   }
getRawAssignID()4997a6dacacSDimitry Andric   Metadata *getRawAssignID() const { return DebugValues[2]; }
5007a6dacacSDimitry Andric   DIAssignID *getAssignID() const;
getAddressExpression()501*0fca6ea1SDimitry Andric   DIExpression *getAddressExpression() const { return AddressExpression.get(); }
getRawAddressExpression()502*0fca6ea1SDimitry Andric   MDNode *getRawAddressExpression() const {
503*0fca6ea1SDimitry Andric     return AddressExpression.getAsMDNode();
504*0fca6ea1SDimitry Andric   }
setAddressExpression(DIExpression * NewExpr)5057a6dacacSDimitry Andric   void setAddressExpression(DIExpression *NewExpr) {
5067a6dacacSDimitry Andric     AddressExpression = NewExpr;
5077a6dacacSDimitry Andric   }
5087a6dacacSDimitry Andric   void setAssignId(DIAssignID *New);
setAddress(Value * V)5097a6dacacSDimitry Andric   void setAddress(Value *V) { resetDebugValue(1, ValueAsMetadata::get(V)); }
5107a6dacacSDimitry Andric   /// Kill the address component.
5117a6dacacSDimitry Andric   void setKillAddress();
5127a6dacacSDimitry Andric   /// Check whether this kills the address component. This doesn't take into
5137a6dacacSDimitry Andric   /// account the position of the intrinsic, therefore a returned value of false
5147a6dacacSDimitry Andric   /// does not guarentee the address is a valid location for the variable at the
5157a6dacacSDimitry Andric   /// intrinsic's position in IR.
5167a6dacacSDimitry Andric   bool isKillAddress() const;
5177a6dacacSDimitry Andric 
5187a6dacacSDimitry Andric   /// @}
5197a6dacacSDimitry Andric 
520*0fca6ea1SDimitry Andric   DbgVariableRecord *clone() const;
521*0fca6ea1SDimitry Andric   /// Convert this DbgVariableRecord back into a dbg.value intrinsic.
5225f757f3fSDimitry Andric   /// \p InsertBefore Optional position to insert this intrinsic.
523*0fca6ea1SDimitry Andric   /// \returns A new dbg.value intrinsic representiung this DbgVariableRecord.
5245f757f3fSDimitry Andric   DbgVariableIntrinsic *createDebugIntrinsic(Module *M,
5255f757f3fSDimitry Andric                                              Instruction *InsertBefore) const;
5265f757f3fSDimitry Andric 
527*0fca6ea1SDimitry Andric   /// Handle changes to the location of the Value(s) that we refer to happening
528*0fca6ea1SDimitry Andric   /// "under our feet".
529*0fca6ea1SDimitry Andric   void handleChangedLocation(Metadata *NewLocation);
5307a6dacacSDimitry Andric 
5315f757f3fSDimitry Andric   void print(raw_ostream &O, bool IsForDebug = false) const;
5325f757f3fSDimitry Andric   void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
533*0fca6ea1SDimitry Andric 
534*0fca6ea1SDimitry Andric   /// Support type inquiry through isa, cast, and dyn_cast.
classof(const DbgRecord * E)535*0fca6ea1SDimitry Andric   static bool classof(const DbgRecord *E) {
536*0fca6ea1SDimitry Andric     return E->getRecordKind() == ValueKind;
537*0fca6ea1SDimitry Andric   }
5385f757f3fSDimitry Andric };
5395f757f3fSDimitry Andric 
540*0fca6ea1SDimitry Andric /// Filter the DbgRecord range to DbgVariableRecord types only and downcast.
541*0fca6ea1SDimitry Andric static inline auto
filterDbgVars(iterator_range<simple_ilist<DbgRecord>::iterator> R)542*0fca6ea1SDimitry Andric filterDbgVars(iterator_range<simple_ilist<DbgRecord>::iterator> R) {
543*0fca6ea1SDimitry Andric   return map_range(
544*0fca6ea1SDimitry Andric       make_filter_range(R,
545*0fca6ea1SDimitry Andric                         [](DbgRecord &E) { return isa<DbgVariableRecord>(E); }),
546*0fca6ea1SDimitry Andric       [](DbgRecord &E) { return std::ref(cast<DbgVariableRecord>(E)); });
547*0fca6ea1SDimitry Andric }
548*0fca6ea1SDimitry Andric 
5495f757f3fSDimitry Andric /// Per-instruction record of debug-info. If an Instruction is the position of
550*0fca6ea1SDimitry Andric /// some debugging information, it points at a DbgMarker storing that info. Each
5515f757f3fSDimitry Andric /// marker points back at the instruction that owns it. Various utilities are
552*0fca6ea1SDimitry Andric /// provided for manipulating the DbgRecords contained within this marker.
5535f757f3fSDimitry Andric ///
554*0fca6ea1SDimitry Andric /// This class has a rough surface area, because it's needed to preserve the
555*0fca6ea1SDimitry Andric /// one arefact that we can't yet eliminate from the intrinsic / dbg.value
556*0fca6ea1SDimitry Andric /// debug-info design: the order of records is significant, and duplicates can
557*0fca6ea1SDimitry Andric /// exist. Thus, if one has a run of debug-info records such as:
5585f757f3fSDimitry Andric ///    dbg.value(...
5595f757f3fSDimitry Andric ///    %foo = barinst
5605f757f3fSDimitry Andric ///    dbg.value(...
5615f757f3fSDimitry Andric /// and remove barinst, then the dbg.values must be preserved in the correct
5625f757f3fSDimitry Andric /// order. Hence, the use of iterators to select positions to insert things
5635f757f3fSDimitry Andric /// into, or the occasional InsertAtHead parameter indicating that new records
5645f757f3fSDimitry Andric /// should go at the start of the list.
5655f757f3fSDimitry Andric ///
5665f757f3fSDimitry Andric /// There are only five or six places in LLVM that truly rely on this ordering,
5675f757f3fSDimitry Andric /// which we can improve in the future. Additionally, many improvements in the
5685f757f3fSDimitry Andric /// way that debug-info is stored can be achieved in this class, at a future
5695f757f3fSDimitry Andric /// date.
570*0fca6ea1SDimitry Andric class DbgMarker {
5715f757f3fSDimitry Andric public:
DbgMarker()572*0fca6ea1SDimitry Andric   DbgMarker() {}
5735f757f3fSDimitry Andric   /// Link back to the Instruction that owns this marker. Can be null during
5745f757f3fSDimitry Andric   /// operations that move a marker from one instruction to another.
5755f757f3fSDimitry Andric   Instruction *MarkedInstr = nullptr;
5765f757f3fSDimitry Andric 
577*0fca6ea1SDimitry Andric   /// List of DbgRecords, the non-instruction equivalent of llvm.dbg.*
578*0fca6ea1SDimitry Andric   /// intrinsics. There is a one-to-one relationship between each debug
579*0fca6ea1SDimitry Andric   /// intrinsic in a block and each DbgRecord once the representation has been
580*0fca6ea1SDimitry Andric   /// converted, and the ordering is meaningful in the same way.
581*0fca6ea1SDimitry Andric   simple_ilist<DbgRecord> StoredDbgRecords;
empty()582*0fca6ea1SDimitry Andric   bool empty() const { return StoredDbgRecords.empty(); }
5835f757f3fSDimitry Andric 
5845f757f3fSDimitry Andric   const BasicBlock *getParent() const;
5855f757f3fSDimitry Andric   BasicBlock *getParent();
5865f757f3fSDimitry Andric 
5875f757f3fSDimitry Andric   /// Handle the removal of a marker: the position of debug-info has gone away,
5885f757f3fSDimitry Andric   /// but the stored debug records should not. Drop them onto the next
5895f757f3fSDimitry Andric   /// instruction, or otherwise work out what to do with them.
5905f757f3fSDimitry Andric   void removeMarker();
5915f757f3fSDimitry Andric   void dump() const;
5925f757f3fSDimitry Andric 
5935f757f3fSDimitry Andric   void removeFromParent();
5945f757f3fSDimitry Andric   void eraseFromParent();
5955f757f3fSDimitry Andric 
596*0fca6ea1SDimitry Andric   /// Implement operator<< on DbgMarker.
5975f757f3fSDimitry Andric   void print(raw_ostream &O, bool IsForDebug = false) const;
5985f757f3fSDimitry Andric   void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
5995f757f3fSDimitry Andric 
600*0fca6ea1SDimitry Andric   /// Produce a range over all the DbgRecords in this Marker.
601*0fca6ea1SDimitry Andric   iterator_range<simple_ilist<DbgRecord>::iterator> getDbgRecordRange();
602*0fca6ea1SDimitry Andric   iterator_range<simple_ilist<DbgRecord>::const_iterator>
603*0fca6ea1SDimitry Andric   getDbgRecordRange() const;
604*0fca6ea1SDimitry Andric   /// Transfer any DbgRecords from \p Src into this DbgMarker. If \p
605*0fca6ea1SDimitry Andric   /// InsertAtHead is true, place them before existing DbgRecords, otherwise
606*0fca6ea1SDimitry Andric   /// afterwards.
607*0fca6ea1SDimitry Andric   void absorbDebugValues(DbgMarker &Src, bool InsertAtHead);
608*0fca6ea1SDimitry Andric   /// Transfer the DbgRecords in \p Range from \p Src into this DbgMarker. If
609*0fca6ea1SDimitry Andric   /// \p InsertAtHead is true, place them before existing DbgRecords, otherwise
6105f757f3fSDimitry Andric   // afterwards.
611*0fca6ea1SDimitry Andric   void absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range,
612*0fca6ea1SDimitry Andric                          DbgMarker &Src, bool InsertAtHead);
613*0fca6ea1SDimitry Andric   /// Insert a DbgRecord into this DbgMarker, at the end of the list. If
6145f757f3fSDimitry Andric   /// \p InsertAtHead is true, at the start.
615*0fca6ea1SDimitry Andric   void insertDbgRecord(DbgRecord *New, bool InsertAtHead);
616*0fca6ea1SDimitry Andric   /// Insert a DbgRecord prior to a DbgRecord contained within this marker.
617*0fca6ea1SDimitry Andric   void insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore);
618*0fca6ea1SDimitry Andric   /// Insert a DbgRecord after a DbgRecord contained within this marker.
619*0fca6ea1SDimitry Andric   void insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter);
620*0fca6ea1SDimitry Andric   /// Clone all DbgMarkers from \p From into this marker. There are numerous
6215f757f3fSDimitry Andric   /// options to customise the source/destination, due to gnarliness, see class
6225f757f3fSDimitry Andric   /// comment.
623*0fca6ea1SDimitry Andric   /// \p FromHere If non-null, copy from FromHere to the end of From's
624*0fca6ea1SDimitry Andric   /// DbgRecords
625*0fca6ea1SDimitry Andric   /// \p InsertAtHead Place the cloned DbgRecords at the start of
626*0fca6ea1SDimitry Andric   /// StoredDbgRecords
627*0fca6ea1SDimitry Andric   /// \returns Range over all the newly cloned DbgRecords
628*0fca6ea1SDimitry Andric   iterator_range<simple_ilist<DbgRecord>::iterator>
629*0fca6ea1SDimitry Andric   cloneDebugInfoFrom(DbgMarker *From,
630*0fca6ea1SDimitry Andric                      std::optional<simple_ilist<DbgRecord>::iterator> FromHere,
6315f757f3fSDimitry Andric                      bool InsertAtHead = false);
632*0fca6ea1SDimitry Andric   /// Erase all DbgRecords in this DbgMarker.
633*0fca6ea1SDimitry Andric   void dropDbgRecords();
634*0fca6ea1SDimitry Andric   /// Erase a single DbgRecord from this marker. In an ideal future, we would
6355f757f3fSDimitry Andric   /// never erase an assignment in this way, but it's the equivalent to
636*0fca6ea1SDimitry Andric   /// erasing a debug intrinsic from a block.
637*0fca6ea1SDimitry Andric   void dropOneDbgRecord(DbgRecord *DR);
6385f757f3fSDimitry Andric 
639*0fca6ea1SDimitry Andric   /// We generally act like all llvm Instructions have a range of DbgRecords
640*0fca6ea1SDimitry Andric   /// attached to them, but in reality sometimes we don't allocate the DbgMarker
641*0fca6ea1SDimitry Andric   /// to save time and memory, but still have to return ranges of DbgRecords.
642*0fca6ea1SDimitry Andric   /// When we need to describe such an unallocated DbgRecord range, use this
643*0fca6ea1SDimitry Andric   /// static markers range instead. This will bite us if someone tries to insert
644*0fca6ea1SDimitry Andric   /// a DbgRecord in that range, but they should be using the Official (TM) API
645*0fca6ea1SDimitry Andric   /// for that.
646*0fca6ea1SDimitry Andric   static DbgMarker EmptyDbgMarker;
647*0fca6ea1SDimitry Andric   static iterator_range<simple_ilist<DbgRecord>::iterator>
getEmptyDbgRecordRange()648*0fca6ea1SDimitry Andric   getEmptyDbgRecordRange() {
649*0fca6ea1SDimitry Andric     return make_range(EmptyDbgMarker.StoredDbgRecords.end(),
650*0fca6ea1SDimitry Andric                       EmptyDbgMarker.StoredDbgRecords.end());
6515f757f3fSDimitry Andric   }
6525f757f3fSDimitry Andric };
6535f757f3fSDimitry Andric 
654*0fca6ea1SDimitry Andric inline raw_ostream &operator<<(raw_ostream &OS, const DbgMarker &Marker) {
6555f757f3fSDimitry Andric   Marker.print(OS);
6565f757f3fSDimitry Andric   return OS;
6575f757f3fSDimitry Andric }
6585f757f3fSDimitry Andric 
659*0fca6ea1SDimitry Andric /// Inline helper to return a range of DbgRecords attached to a marker. It needs
660*0fca6ea1SDimitry Andric /// to be inlined as it's frequently called, but also come after the declaration
661*0fca6ea1SDimitry Andric /// of DbgMarker. Thus: it's pre-declared by users like Instruction, then an
662*0fca6ea1SDimitry Andric /// inlineable body defined here.
663*0fca6ea1SDimitry Andric inline iterator_range<simple_ilist<DbgRecord>::iterator>
getDbgRecordRange(DbgMarker * DebugMarker)664*0fca6ea1SDimitry Andric getDbgRecordRange(DbgMarker *DebugMarker) {
665*0fca6ea1SDimitry Andric   if (!DebugMarker)
666*0fca6ea1SDimitry Andric     return DbgMarker::getEmptyDbgRecordRange();
667*0fca6ea1SDimitry Andric   return DebugMarker->getDbgRecordRange();
6685f757f3fSDimitry Andric }
6695f757f3fSDimitry Andric 
DEFINE_ISA_CONVERSION_FUNCTIONS(DbgRecord,LLVMDbgRecordRef)670*0fca6ea1SDimitry Andric DEFINE_ISA_CONVERSION_FUNCTIONS(DbgRecord, LLVMDbgRecordRef)
671*0fca6ea1SDimitry Andric 
672*0fca6ea1SDimitry Andric /// Used to temporarily set the debug info format of a function, module, or
673*0fca6ea1SDimitry Andric /// basic block for the duration of this object's lifetime, after which the
674*0fca6ea1SDimitry Andric /// prior state will be restored.
675*0fca6ea1SDimitry Andric template <typename T> class ScopedDbgInfoFormatSetter {
676*0fca6ea1SDimitry Andric   T &Obj;
677*0fca6ea1SDimitry Andric   bool OldState;
678*0fca6ea1SDimitry Andric 
679*0fca6ea1SDimitry Andric public:
680*0fca6ea1SDimitry Andric   ScopedDbgInfoFormatSetter(T &Obj, bool NewState)
681*0fca6ea1SDimitry Andric       : Obj(Obj), OldState(Obj.IsNewDbgInfoFormat) {
682*0fca6ea1SDimitry Andric     Obj.setIsNewDbgInfoFormat(NewState);
683*0fca6ea1SDimitry Andric   }
684*0fca6ea1SDimitry Andric   ~ScopedDbgInfoFormatSetter() { Obj.setIsNewDbgInfoFormat(OldState); }
685*0fca6ea1SDimitry Andric };
686*0fca6ea1SDimitry Andric 
687*0fca6ea1SDimitry Andric template <typename T>
688*0fca6ea1SDimitry Andric ScopedDbgInfoFormatSetter(T &Obj,
689*0fca6ea1SDimitry Andric                           bool NewState) -> ScopedDbgInfoFormatSetter<T>;
690*0fca6ea1SDimitry Andric 
6915f757f3fSDimitry Andric } // namespace llvm
6925f757f3fSDimitry Andric 
6935f757f3fSDimitry Andric #endif // LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
694