10b57cec5SDimitry Andric //===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Declarations for metadata specific to debug info.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_IR_DEBUGINFOMETADATA_H
140b57cec5SDimitry Andric #define LLVM_IR_DEBUGINFOMETADATA_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
170b57cec5SDimitry Andric #include "llvm/ADT/BitmaskEnum.h"
180b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h"
190b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
210b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
220b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
230b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
240b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
255f757f3fSDimitry Andric #include "llvm/IR/PseudoProbe.h"
260b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
27fe6060f1SDimitry Andric #include "llvm/Support/CommandLine.h"
28fe6060f1SDimitry Andric #include "llvm/Support/Discriminator.h"
290b57cec5SDimitry Andric #include <cassert>
300b57cec5SDimitry Andric #include <climits>
310b57cec5SDimitry Andric #include <cstddef>
320b57cec5SDimitry Andric #include <cstdint>
330b57cec5SDimitry Andric #include <iterator>
34bdd1243dSDimitry Andric #include <optional>
350b57cec5SDimitry Andric #include <vector>
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric // Helper macros for defining get() overrides.
380b57cec5SDimitry Andric #define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
390b57cec5SDimitry Andric #define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
400b57cec5SDimitry Andric #define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)              \
410b57cec5SDimitry Andric   static CLASS *getDistinct(LLVMContext &Context,                              \
420b57cec5SDimitry Andric                             DEFINE_MDNODE_GET_UNPACK(FORMAL)) {                \
430b57cec5SDimitry Andric     return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct);         \
440b57cec5SDimitry Andric   }                                                                            \
450b57cec5SDimitry Andric   static Temp##CLASS getTemporary(LLVMContext &Context,                        \
460b57cec5SDimitry Andric                                   DEFINE_MDNODE_GET_UNPACK(FORMAL)) {          \
470b57cec5SDimitry Andric     return Temp##CLASS(                                                        \
480b57cec5SDimitry Andric         getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary));          \
490b57cec5SDimitry Andric   }
500b57cec5SDimitry Andric #define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS)                                 \
510b57cec5SDimitry Andric   static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) {  \
520b57cec5SDimitry Andric     return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued);          \
530b57cec5SDimitry Andric   }                                                                            \
540b57cec5SDimitry Andric   static CLASS *getIfExists(LLVMContext &Context,                              \
550b57cec5SDimitry Andric                             DEFINE_MDNODE_GET_UNPACK(FORMAL)) {                \
560b57cec5SDimitry Andric     return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued,           \
570b57cec5SDimitry Andric                    /* ShouldCreate */ false);                                  \
580b57cec5SDimitry Andric   }                                                                            \
590b57cec5SDimitry Andric   DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric namespace llvm {
620b57cec5SDimitry Andric 
6381ad6265SDimitry Andric namespace dwarf {
6481ad6265SDimitry Andric enum Tag : uint16_t;
6581ad6265SDimitry Andric }
6681ad6265SDimitry Andric 
67bdd1243dSDimitry Andric class DbgVariableIntrinsic;
685f757f3fSDimitry Andric class DPValue;
69bdd1243dSDimitry Andric 
70fe6060f1SDimitry Andric extern cl::opt<bool> EnableFSDiscriminator;
71fe6060f1SDimitry Andric 
720b57cec5SDimitry Andric class DITypeRefArray {
730b57cec5SDimitry Andric   const MDTuple *N = nullptr;
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric public:
760b57cec5SDimitry Andric   DITypeRefArray() = default;
DITypeRefArray(const MDTuple * N)770b57cec5SDimitry Andric   DITypeRefArray(const MDTuple *N) : N(N) {}
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   explicit operator bool() const { return get(); }
800b57cec5SDimitry Andric   explicit operator MDTuple *() const { return get(); }
810b57cec5SDimitry Andric 
get()820b57cec5SDimitry Andric   MDTuple *get() const { return const_cast<MDTuple *>(N); }
830b57cec5SDimitry Andric   MDTuple *operator->() const { return get(); }
840b57cec5SDimitry Andric   MDTuple &operator*() const { return *get(); }
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   // FIXME: Fix callers and remove condition on N.
size()870b57cec5SDimitry Andric   unsigned size() const { return N ? N->getNumOperands() : 0u; }
880b57cec5SDimitry Andric   DIType *operator[](unsigned I) const {
890b57cec5SDimitry Andric     return cast_or_null<DIType>(N->getOperand(I));
900b57cec5SDimitry Andric   }
910b57cec5SDimitry Andric 
92fe6060f1SDimitry Andric   class iterator {
930b57cec5SDimitry Andric     MDNode::op_iterator I = nullptr;
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   public:
96fe6060f1SDimitry Andric     using iterator_category = std::input_iterator_tag;
97fe6060f1SDimitry Andric     using value_type = DIType *;
98fe6060f1SDimitry Andric     using difference_type = std::ptrdiff_t;
99fe6060f1SDimitry Andric     using pointer = void;
100fe6060f1SDimitry Andric     using reference = DIType *;
101fe6060f1SDimitry Andric 
1020b57cec5SDimitry Andric     iterator() = default;
iterator(MDNode::op_iterator I)1030b57cec5SDimitry Andric     explicit iterator(MDNode::op_iterator I) : I(I) {}
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric     DIType *operator*() const { return cast_or_null<DIType>(*I); }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric     iterator &operator++() {
1080b57cec5SDimitry Andric       ++I;
1090b57cec5SDimitry Andric       return *this;
1100b57cec5SDimitry Andric     }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric     iterator operator++(int) {
1130b57cec5SDimitry Andric       iterator Temp(*this);
1140b57cec5SDimitry Andric       ++I;
1150b57cec5SDimitry Andric       return Temp;
1160b57cec5SDimitry Andric     }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric     bool operator==(const iterator &X) const { return I == X.I; }
1190b57cec5SDimitry Andric     bool operator!=(const iterator &X) const { return I != X.I; }
1200b57cec5SDimitry Andric   };
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   // FIXME: Fix callers and remove condition on N.
begin()1230b57cec5SDimitry Andric   iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
end()1240b57cec5SDimitry Andric   iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
1250b57cec5SDimitry Andric };
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric /// Tagged DWARF-like metadata node.
1280b57cec5SDimitry Andric ///
1290b57cec5SDimitry Andric /// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
1300b57cec5SDimitry Andric /// defined in llvm/BinaryFormat/Dwarf.h).  Called \a DINode because it's
1310b57cec5SDimitry Andric /// potentially used for non-DWARF output.
1325f757f3fSDimitry Andric ///
1335f757f3fSDimitry Andric /// Uses the SubclassData16 Metadata slot.
1340b57cec5SDimitry Andric class DINode : public MDNode {
1350b57cec5SDimitry Andric   friend class LLVMContextImpl;
1360b57cec5SDimitry Andric   friend class MDNode;
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric protected:
1390b57cec5SDimitry Andric   DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
140bdd1243dSDimitry Andric          ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = std::nullopt)
MDNode(C,ID,Storage,Ops1,Ops2)1410b57cec5SDimitry Andric       : MDNode(C, ID, Storage, Ops1, Ops2) {
1420b57cec5SDimitry Andric     assert(Tag < 1u << 16);
1430b57cec5SDimitry Andric     SubclassData16 = Tag;
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric   ~DINode() = default;
1460b57cec5SDimitry Andric 
getOperandAs(unsigned I)1470b57cec5SDimitry Andric   template <class Ty> Ty *getOperandAs(unsigned I) const {
1480b57cec5SDimitry Andric     return cast_or_null<Ty>(getOperand(I));
1490b57cec5SDimitry Andric   }
1500b57cec5SDimitry Andric 
getStringOperand(unsigned I)1510b57cec5SDimitry Andric   StringRef getStringOperand(unsigned I) const {
1520b57cec5SDimitry Andric     if (auto *S = getOperandAs<MDString>(I))
1530b57cec5SDimitry Andric       return S->getString();
1540b57cec5SDimitry Andric     return StringRef();
1550b57cec5SDimitry Andric   }
1560b57cec5SDimitry Andric 
getCanonicalMDString(LLVMContext & Context,StringRef S)1570b57cec5SDimitry Andric   static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
1580b57cec5SDimitry Andric     if (S.empty())
1590b57cec5SDimitry Andric       return nullptr;
1600b57cec5SDimitry Andric     return MDString::get(Context, S);
1610b57cec5SDimitry Andric   }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   /// Allow subclasses to mutate the tag.
setTag(unsigned Tag)1640b57cec5SDimitry Andric   void setTag(unsigned Tag) { SubclassData16 = Tag; }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric public:
16781ad6265SDimitry Andric   dwarf::Tag getTag() const;
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   /// Debug info flags.
1700b57cec5SDimitry Andric   ///
1710b57cec5SDimitry Andric   /// The three accessibility flags are mutually exclusive and rolled together
1720b57cec5SDimitry Andric   /// in the first two bits.
1730b57cec5SDimitry Andric   enum DIFlags : uint32_t {
1740b57cec5SDimitry Andric #define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
1750b57cec5SDimitry Andric #define DI_FLAG_LARGEST_NEEDED
1760b57cec5SDimitry Andric #include "llvm/IR/DebugInfoFlags.def"
1770b57cec5SDimitry Andric     FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic,
1780b57cec5SDimitry Andric     FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance |
1790b57cec5SDimitry Andric                          FlagVirtualInheritance,
1800b57cec5SDimitry Andric     LLVM_MARK_AS_BITMASK_ENUM(FlagLargest)
1810b57cec5SDimitry Andric   };
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   static DIFlags getFlag(StringRef Flag);
1840b57cec5SDimitry Andric   static StringRef getFlagString(DIFlags Flag);
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   /// Split up a flags bitfield.
1870b57cec5SDimitry Andric   ///
1880b57cec5SDimitry Andric   /// Split \c Flags into \c SplitFlags, a vector of its components.  Returns
1890b57cec5SDimitry Andric   /// any remaining (unrecognized) bits.
1900b57cec5SDimitry Andric   static DIFlags splitFlags(DIFlags Flags,
1910b57cec5SDimitry Andric                             SmallVectorImpl<DIFlags> &SplitFlags);
1920b57cec5SDimitry Andric 
classof(const Metadata * MD)1930b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
1940b57cec5SDimitry Andric     switch (MD->getMetadataID()) {
1950b57cec5SDimitry Andric     default:
1960b57cec5SDimitry Andric       return false;
1970b57cec5SDimitry Andric     case GenericDINodeKind:
1980b57cec5SDimitry Andric     case DISubrangeKind:
1990b57cec5SDimitry Andric     case DIEnumeratorKind:
2000b57cec5SDimitry Andric     case DIBasicTypeKind:
201e8d8bef9SDimitry Andric     case DIStringTypeKind:
2020b57cec5SDimitry Andric     case DIDerivedTypeKind:
2030b57cec5SDimitry Andric     case DICompositeTypeKind:
2040b57cec5SDimitry Andric     case DISubroutineTypeKind:
2050b57cec5SDimitry Andric     case DIFileKind:
2060b57cec5SDimitry Andric     case DICompileUnitKind:
2070b57cec5SDimitry Andric     case DISubprogramKind:
2080b57cec5SDimitry Andric     case DILexicalBlockKind:
2090b57cec5SDimitry Andric     case DILexicalBlockFileKind:
2100b57cec5SDimitry Andric     case DINamespaceKind:
2110b57cec5SDimitry Andric     case DICommonBlockKind:
2120b57cec5SDimitry Andric     case DITemplateTypeParameterKind:
2130b57cec5SDimitry Andric     case DITemplateValueParameterKind:
2140b57cec5SDimitry Andric     case DIGlobalVariableKind:
2150b57cec5SDimitry Andric     case DILocalVariableKind:
2160b57cec5SDimitry Andric     case DILabelKind:
2170b57cec5SDimitry Andric     case DIObjCPropertyKind:
2180b57cec5SDimitry Andric     case DIImportedEntityKind:
2190b57cec5SDimitry Andric     case DIModuleKind:
220e8d8bef9SDimitry Andric     case DIGenericSubrangeKind:
221bdd1243dSDimitry Andric     case DIAssignIDKind:
2220b57cec5SDimitry Andric       return true;
2230b57cec5SDimitry Andric     }
2240b57cec5SDimitry Andric   }
2250b57cec5SDimitry Andric };
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric /// Generic tagged DWARF-like metadata node.
2280b57cec5SDimitry Andric ///
2290b57cec5SDimitry Andric /// An un-specialized DWARF-like metadata node.  The first operand is a
2300b57cec5SDimitry Andric /// (possibly empty) null-separated \a MDString header that contains arbitrary
2310b57cec5SDimitry Andric /// fields.  The remaining operands are \a dwarf_operands(), and are pointers
2320b57cec5SDimitry Andric /// to other metadata.
2335f757f3fSDimitry Andric ///
2345f757f3fSDimitry Andric /// Uses the SubclassData32 Metadata slot.
2350b57cec5SDimitry Andric class GenericDINode : public DINode {
2360b57cec5SDimitry Andric   friend class LLVMContextImpl;
2370b57cec5SDimitry Andric   friend class MDNode;
2380b57cec5SDimitry Andric 
GenericDINode(LLVMContext & C,StorageType Storage,unsigned Hash,unsigned Tag,ArrayRef<Metadata * > Ops1,ArrayRef<Metadata * > Ops2)2390b57cec5SDimitry Andric   GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
2400b57cec5SDimitry Andric                 unsigned Tag, ArrayRef<Metadata *> Ops1,
2410b57cec5SDimitry Andric                 ArrayRef<Metadata *> Ops2)
2420b57cec5SDimitry Andric       : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
2430b57cec5SDimitry Andric     setHash(Hash);
2440b57cec5SDimitry Andric   }
~GenericDINode()2450b57cec5SDimitry Andric   ~GenericDINode() { dropAllReferences(); }
2460b57cec5SDimitry Andric 
setHash(unsigned Hash)2470b57cec5SDimitry Andric   void setHash(unsigned Hash) { SubclassData32 = Hash; }
2480b57cec5SDimitry Andric   void recalculateHash();
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric   static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
2510b57cec5SDimitry Andric                                 StringRef Header, ArrayRef<Metadata *> DwarfOps,
2520b57cec5SDimitry Andric                                 StorageType Storage, bool ShouldCreate = true) {
2530b57cec5SDimitry Andric     return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
2540b57cec5SDimitry Andric                    DwarfOps, Storage, ShouldCreate);
2550b57cec5SDimitry Andric   }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric   static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
2580b57cec5SDimitry Andric                                 MDString *Header, ArrayRef<Metadata *> DwarfOps,
2590b57cec5SDimitry Andric                                 StorageType Storage, bool ShouldCreate = true);
2600b57cec5SDimitry Andric 
cloneImpl()2610b57cec5SDimitry Andric   TempGenericDINode cloneImpl() const {
262e8d8bef9SDimitry Andric     return getTemporary(getContext(), getTag(), getHeader(),
263e8d8bef9SDimitry Andric                         SmallVector<Metadata *, 4>(dwarf_operands()));
2640b57cec5SDimitry Andric   }
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric public:
getHash()2670b57cec5SDimitry Andric   unsigned getHash() const { return SubclassData32; }
2680b57cec5SDimitry Andric 
269349cc55cSDimitry Andric   DEFINE_MDNODE_GET(GenericDINode,
270349cc55cSDimitry Andric                     (unsigned Tag, StringRef Header,
2710b57cec5SDimitry Andric                      ArrayRef<Metadata *> DwarfOps),
2720b57cec5SDimitry Andric                     (Tag, Header, DwarfOps))
273349cc55cSDimitry Andric   DEFINE_MDNODE_GET(GenericDINode,
274349cc55cSDimitry Andric                     (unsigned Tag, MDString *Header,
2750b57cec5SDimitry Andric                      ArrayRef<Metadata *> DwarfOps),
2760b57cec5SDimitry Andric                     (Tag, Header, DwarfOps))
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric   /// Return a (temporary) clone of this.
clone()2790b57cec5SDimitry Andric   TempGenericDINode clone() const { return cloneImpl(); }
2800b57cec5SDimitry Andric 
28181ad6265SDimitry Andric   dwarf::Tag getTag() const;
getHeader()2820b57cec5SDimitry Andric   StringRef getHeader() const { return getStringOperand(0); }
getRawHeader()2830b57cec5SDimitry Andric   MDString *getRawHeader() const { return getOperandAs<MDString>(0); }
2840b57cec5SDimitry Andric 
dwarf_op_begin()2850b57cec5SDimitry Andric   op_iterator dwarf_op_begin() const { return op_begin() + 1; }
dwarf_op_end()2860b57cec5SDimitry Andric   op_iterator dwarf_op_end() const { return op_end(); }
dwarf_operands()2870b57cec5SDimitry Andric   op_range dwarf_operands() const {
2880b57cec5SDimitry Andric     return op_range(dwarf_op_begin(), dwarf_op_end());
2890b57cec5SDimitry Andric   }
2900b57cec5SDimitry Andric 
getNumDwarfOperands()2910b57cec5SDimitry Andric   unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
getDwarfOperand(unsigned I)2920b57cec5SDimitry Andric   const MDOperand &getDwarfOperand(unsigned I) const {
2930b57cec5SDimitry Andric     return getOperand(I + 1);
2940b57cec5SDimitry Andric   }
replaceDwarfOperandWith(unsigned I,Metadata * New)2950b57cec5SDimitry Andric   void replaceDwarfOperandWith(unsigned I, Metadata *New) {
2960b57cec5SDimitry Andric     replaceOperandWith(I + 1, New);
2970b57cec5SDimitry Andric   }
2980b57cec5SDimitry Andric 
classof(const Metadata * MD)2990b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
3000b57cec5SDimitry Andric     return MD->getMetadataID() == GenericDINodeKind;
3010b57cec5SDimitry Andric   }
3020b57cec5SDimitry Andric };
3030b57cec5SDimitry Andric 
304bdd1243dSDimitry Andric /// Assignment ID.
305bdd1243dSDimitry Andric /// Used to link stores (as an attachment) and dbg.assigns (as an operand).
306bdd1243dSDimitry Andric /// DIAssignID metadata is never uniqued as we compare instances using
307bdd1243dSDimitry Andric /// referential equality (the instance/address is the ID).
308bdd1243dSDimitry Andric class DIAssignID : public MDNode {
309bdd1243dSDimitry Andric   friend class LLVMContextImpl;
310bdd1243dSDimitry Andric   friend class MDNode;
311bdd1243dSDimitry Andric 
DIAssignID(LLVMContext & C,StorageType Storage)312bdd1243dSDimitry Andric   DIAssignID(LLVMContext &C, StorageType Storage)
313bdd1243dSDimitry Andric       : MDNode(C, DIAssignIDKind, Storage, std::nullopt) {}
314bdd1243dSDimitry Andric 
~DIAssignID()315bdd1243dSDimitry Andric   ~DIAssignID() { dropAllReferences(); }
316bdd1243dSDimitry Andric 
317bdd1243dSDimitry Andric   static DIAssignID *getImpl(LLVMContext &Context, StorageType Storage,
318bdd1243dSDimitry Andric                              bool ShouldCreate = true);
319bdd1243dSDimitry Andric 
cloneImpl()320bdd1243dSDimitry Andric   TempDIAssignID cloneImpl() const { return getTemporary(getContext()); }
321bdd1243dSDimitry Andric 
322bdd1243dSDimitry Andric public:
323bdd1243dSDimitry Andric   // This node has no operands to replace.
324bdd1243dSDimitry Andric   void replaceOperandWith(unsigned I, Metadata *New) = delete;
325bdd1243dSDimitry Andric 
getAllDPValueUsers()3267a6dacacSDimitry Andric   SmallVector<DPValue *> getAllDPValueUsers() {
3277a6dacacSDimitry Andric     return Context.getReplaceableUses()->getAllDPValueUsers();
3287a6dacacSDimitry Andric   }
3297a6dacacSDimitry Andric 
getDistinct(LLVMContext & Context)330bdd1243dSDimitry Andric   static DIAssignID *getDistinct(LLVMContext &Context) {
331bdd1243dSDimitry Andric     return getImpl(Context, Distinct);
332bdd1243dSDimitry Andric   }
getTemporary(LLVMContext & Context)333bdd1243dSDimitry Andric   static TempDIAssignID getTemporary(LLVMContext &Context) {
334bdd1243dSDimitry Andric     return TempDIAssignID(getImpl(Context, Temporary));
335bdd1243dSDimitry Andric   }
336bdd1243dSDimitry Andric   // NOTE: Do not define get(LLVMContext&) - see class comment.
337bdd1243dSDimitry Andric 
classof(const Metadata * MD)338bdd1243dSDimitry Andric   static bool classof(const Metadata *MD) {
339bdd1243dSDimitry Andric     return MD->getMetadataID() == DIAssignIDKind;
340bdd1243dSDimitry Andric   }
341bdd1243dSDimitry Andric };
342bdd1243dSDimitry Andric 
3430b57cec5SDimitry Andric /// Array subrange.
3440b57cec5SDimitry Andric ///
3450b57cec5SDimitry Andric /// TODO: Merge into node for DW_TAG_array_type, which should have a custom
3460b57cec5SDimitry Andric /// type.
3470b57cec5SDimitry Andric class DISubrange : public DINode {
3480b57cec5SDimitry Andric   friend class LLVMContextImpl;
3490b57cec5SDimitry Andric   friend class MDNode;
3500b57cec5SDimitry Andric 
35181ad6265SDimitry Andric   DISubrange(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops);
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric   ~DISubrange() = default;
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric   static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
3560b57cec5SDimitry Andric                              int64_t LowerBound, StorageType Storage,
3570b57cec5SDimitry Andric                              bool ShouldCreate = true);
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
3600b57cec5SDimitry Andric                              int64_t LowerBound, StorageType Storage,
3610b57cec5SDimitry Andric                              bool ShouldCreate = true);
3620b57cec5SDimitry Andric 
3635ffd83dbSDimitry Andric   static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
3645ffd83dbSDimitry Andric                              Metadata *LowerBound, Metadata *UpperBound,
3655ffd83dbSDimitry Andric                              Metadata *Stride, StorageType Storage,
3665ffd83dbSDimitry Andric                              bool ShouldCreate = true);
3675ffd83dbSDimitry Andric 
cloneImpl()3680b57cec5SDimitry Andric   TempDISubrange cloneImpl() const {
3695ffd83dbSDimitry Andric     return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
3705ffd83dbSDimitry Andric                         getRawUpperBound(), getRawStride());
3710b57cec5SDimitry Andric   }
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric public:
3740b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
3750b57cec5SDimitry Andric                     (Count, LowerBound))
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DISubrange, (Metadata * CountNode, int64_t LowerBound = 0),
3780b57cec5SDimitry Andric                     (CountNode, LowerBound))
3790b57cec5SDimitry Andric 
3805ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(DISubrange,
3815ffd83dbSDimitry Andric                     (Metadata * CountNode, Metadata *LowerBound,
3825ffd83dbSDimitry Andric                      Metadata *UpperBound, Metadata *Stride),
3835ffd83dbSDimitry Andric                     (CountNode, LowerBound, UpperBound, Stride))
3840b57cec5SDimitry Andric 
clone()3855ffd83dbSDimitry Andric   TempDISubrange clone() const { return cloneImpl(); }
3860b57cec5SDimitry Andric 
getRawCountNode()387349cc55cSDimitry Andric   Metadata *getRawCountNode() const { return getOperand(0).get(); }
3880b57cec5SDimitry Andric 
getRawLowerBound()3895ffd83dbSDimitry Andric   Metadata *getRawLowerBound() const { return getOperand(1).get(); }
3905ffd83dbSDimitry Andric 
getRawUpperBound()3915ffd83dbSDimitry Andric   Metadata *getRawUpperBound() const { return getOperand(2).get(); }
3925ffd83dbSDimitry Andric 
getRawStride()3935ffd83dbSDimitry Andric   Metadata *getRawStride() const { return getOperand(3).get(); }
3945ffd83dbSDimitry Andric 
3955ffd83dbSDimitry Andric   typedef PointerUnion<ConstantInt *, DIVariable *, DIExpression *> BoundType;
3960b57cec5SDimitry Andric 
397fe6060f1SDimitry Andric   BoundType getCount() const;
3980b57cec5SDimitry Andric 
3995ffd83dbSDimitry Andric   BoundType getLowerBound() const;
4000b57cec5SDimitry Andric 
4015ffd83dbSDimitry Andric   BoundType getUpperBound() const;
4025ffd83dbSDimitry Andric 
4035ffd83dbSDimitry Andric   BoundType getStride() const;
4040b57cec5SDimitry Andric 
classof(const Metadata * MD)4050b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
4060b57cec5SDimitry Andric     return MD->getMetadataID() == DISubrangeKind;
4070b57cec5SDimitry Andric   }
4080b57cec5SDimitry Andric };
4090b57cec5SDimitry Andric 
410e8d8bef9SDimitry Andric class DIGenericSubrange : public DINode {
411e8d8bef9SDimitry Andric   friend class LLVMContextImpl;
412e8d8bef9SDimitry Andric   friend class MDNode;
413e8d8bef9SDimitry Andric 
414e8d8bef9SDimitry Andric   DIGenericSubrange(LLVMContext &C, StorageType Storage,
41581ad6265SDimitry Andric                     ArrayRef<Metadata *> Ops);
416e8d8bef9SDimitry Andric 
417e8d8bef9SDimitry Andric   ~DIGenericSubrange() = default;
418e8d8bef9SDimitry Andric 
419e8d8bef9SDimitry Andric   static DIGenericSubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
420e8d8bef9SDimitry Andric                                     Metadata *LowerBound, Metadata *UpperBound,
421e8d8bef9SDimitry Andric                                     Metadata *Stride, StorageType Storage,
422e8d8bef9SDimitry Andric                                     bool ShouldCreate = true);
423e8d8bef9SDimitry Andric 
cloneImpl()424e8d8bef9SDimitry Andric   TempDIGenericSubrange cloneImpl() const {
425e8d8bef9SDimitry Andric     return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
426e8d8bef9SDimitry Andric                         getRawUpperBound(), getRawStride());
427e8d8bef9SDimitry Andric   }
428e8d8bef9SDimitry Andric 
429e8d8bef9SDimitry Andric public:
430e8d8bef9SDimitry Andric   DEFINE_MDNODE_GET(DIGenericSubrange,
431e8d8bef9SDimitry Andric                     (Metadata * CountNode, Metadata *LowerBound,
432e8d8bef9SDimitry Andric                      Metadata *UpperBound, Metadata *Stride),
433e8d8bef9SDimitry Andric                     (CountNode, LowerBound, UpperBound, Stride))
434e8d8bef9SDimitry Andric 
clone()435e8d8bef9SDimitry Andric   TempDIGenericSubrange clone() const { return cloneImpl(); }
436e8d8bef9SDimitry Andric 
getRawCountNode()437e8d8bef9SDimitry Andric   Metadata *getRawCountNode() const { return getOperand(0).get(); }
getRawLowerBound()438e8d8bef9SDimitry Andric   Metadata *getRawLowerBound() const { return getOperand(1).get(); }
getRawUpperBound()439e8d8bef9SDimitry Andric   Metadata *getRawUpperBound() const { return getOperand(2).get(); }
getRawStride()440e8d8bef9SDimitry Andric   Metadata *getRawStride() const { return getOperand(3).get(); }
441e8d8bef9SDimitry Andric 
442e8d8bef9SDimitry Andric   using BoundType = PointerUnion<DIVariable *, DIExpression *>;
443e8d8bef9SDimitry Andric 
444e8d8bef9SDimitry Andric   BoundType getCount() const;
445e8d8bef9SDimitry Andric   BoundType getLowerBound() const;
446e8d8bef9SDimitry Andric   BoundType getUpperBound() const;
447e8d8bef9SDimitry Andric   BoundType getStride() const;
448e8d8bef9SDimitry Andric 
classof(const Metadata * MD)449e8d8bef9SDimitry Andric   static bool classof(const Metadata *MD) {
450e8d8bef9SDimitry Andric     return MD->getMetadataID() == DIGenericSubrangeKind;
451e8d8bef9SDimitry Andric   }
452e8d8bef9SDimitry Andric };
453e8d8bef9SDimitry Andric 
4540b57cec5SDimitry Andric /// Enumeration value.
4550b57cec5SDimitry Andric ///
4560b57cec5SDimitry Andric /// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
4570b57cec5SDimitry Andric /// longer creates a type cycle.
4580b57cec5SDimitry Andric class DIEnumerator : public DINode {
4590b57cec5SDimitry Andric   friend class LLVMContextImpl;
4600b57cec5SDimitry Andric   friend class MDNode;
4610b57cec5SDimitry Andric 
4625ffd83dbSDimitry Andric   APInt Value;
4635ffd83dbSDimitry Andric   DIEnumerator(LLVMContext &C, StorageType Storage, const APInt &Value,
46481ad6265SDimitry Andric                bool IsUnsigned, ArrayRef<Metadata *> Ops);
DIEnumerator(LLVMContext & C,StorageType Storage,int64_t Value,bool IsUnsigned,ArrayRef<Metadata * > Ops)4655ffd83dbSDimitry Andric   DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
4665ffd83dbSDimitry Andric                bool IsUnsigned, ArrayRef<Metadata *> Ops)
4675ffd83dbSDimitry Andric       : DIEnumerator(C, Storage, APInt(64, Value, !IsUnsigned), IsUnsigned,
4685ffd83dbSDimitry Andric                      Ops) {}
4690b57cec5SDimitry Andric   ~DIEnumerator() = default;
4700b57cec5SDimitry Andric 
4715ffd83dbSDimitry Andric   static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
4720b57cec5SDimitry Andric                                bool IsUnsigned, StringRef Name,
4730b57cec5SDimitry Andric                                StorageType Storage, bool ShouldCreate = true) {
4740b57cec5SDimitry Andric     return getImpl(Context, Value, IsUnsigned,
4750b57cec5SDimitry Andric                    getCanonicalMDString(Context, Name), Storage, ShouldCreate);
4760b57cec5SDimitry Andric   }
4775ffd83dbSDimitry Andric   static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
4780b57cec5SDimitry Andric                                bool IsUnsigned, MDString *Name,
4790b57cec5SDimitry Andric                                StorageType Storage, bool ShouldCreate = true);
4800b57cec5SDimitry Andric 
cloneImpl()4810b57cec5SDimitry Andric   TempDIEnumerator cloneImpl() const {
4820b57cec5SDimitry Andric     return getTemporary(getContext(), getValue(), isUnsigned(), getName());
4830b57cec5SDimitry Andric   }
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric public:
4865ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(DIEnumerator,
4875ffd83dbSDimitry Andric                     (int64_t Value, bool IsUnsigned, StringRef Name),
4885ffd83dbSDimitry Andric                     (APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
4895ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(DIEnumerator,
4905ffd83dbSDimitry Andric                     (int64_t Value, bool IsUnsigned, MDString *Name),
4915ffd83dbSDimitry Andric                     (APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
4925ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(DIEnumerator,
4935ffd83dbSDimitry Andric                     (APInt Value, bool IsUnsigned, StringRef Name),
4940b57cec5SDimitry Andric                     (Value, IsUnsigned, Name))
4955ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(DIEnumerator,
4965ffd83dbSDimitry Andric                     (APInt Value, bool IsUnsigned, MDString *Name),
4970b57cec5SDimitry Andric                     (Value, IsUnsigned, Name))
4980b57cec5SDimitry Andric 
clone()4990b57cec5SDimitry Andric   TempDIEnumerator clone() const { return cloneImpl(); }
5000b57cec5SDimitry Andric 
getValue()5015ffd83dbSDimitry Andric   const APInt &getValue() const { return Value; }
isUnsigned()5020b57cec5SDimitry Andric   bool isUnsigned() const { return SubclassData32; }
getName()5030b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(0); }
5040b57cec5SDimitry Andric 
getRawName()5050b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(0); }
5060b57cec5SDimitry Andric 
classof(const Metadata * MD)5070b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
5080b57cec5SDimitry Andric     return MD->getMetadataID() == DIEnumeratorKind;
5090b57cec5SDimitry Andric   }
5100b57cec5SDimitry Andric };
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric /// Base class for scope-like contexts.
5130b57cec5SDimitry Andric ///
5140b57cec5SDimitry Andric /// Base class for lexical scopes and types (which are also declaration
5150b57cec5SDimitry Andric /// contexts).
5160b57cec5SDimitry Andric ///
5170b57cec5SDimitry Andric /// TODO: Separate the concepts of declaration contexts and lexical scopes.
5180b57cec5SDimitry Andric class DIScope : public DINode {
5190b57cec5SDimitry Andric protected:
DIScope(LLVMContext & C,unsigned ID,StorageType Storage,unsigned Tag,ArrayRef<Metadata * > Ops)5200b57cec5SDimitry Andric   DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
5210b57cec5SDimitry Andric           ArrayRef<Metadata *> Ops)
5220b57cec5SDimitry Andric       : DINode(C, ID, Storage, Tag, Ops) {}
5230b57cec5SDimitry Andric   ~DIScope() = default;
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric public:
getFile()5260b57cec5SDimitry Andric   DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric   inline StringRef getFilename() const;
5290b57cec5SDimitry Andric   inline StringRef getDirectory() const;
530bdd1243dSDimitry Andric   inline std::optional<StringRef> getSource() const;
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric   StringRef getName() const;
5330b57cec5SDimitry Andric   DIScope *getScope() const;
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric   /// Return the raw underlying file.
5360b57cec5SDimitry Andric   ///
5370b57cec5SDimitry Andric   /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file (it
5380b57cec5SDimitry Andric   /// \em is the file).  If \c this is an \a DIFile, we need to return \c this.
5390b57cec5SDimitry Andric   /// Otherwise, return the first operand, which is where all other subclasses
5400b57cec5SDimitry Andric   /// store their file pointer.
getRawFile()5410b57cec5SDimitry Andric   Metadata *getRawFile() const {
5420b57cec5SDimitry Andric     return isa<DIFile>(this) ? const_cast<DIScope *>(this)
5430b57cec5SDimitry Andric                              : static_cast<Metadata *>(getOperand(0));
5440b57cec5SDimitry Andric   }
5450b57cec5SDimitry Andric 
classof(const Metadata * MD)5460b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
5470b57cec5SDimitry Andric     switch (MD->getMetadataID()) {
5480b57cec5SDimitry Andric     default:
5490b57cec5SDimitry Andric       return false;
5500b57cec5SDimitry Andric     case DIBasicTypeKind:
551e8d8bef9SDimitry Andric     case DIStringTypeKind:
5520b57cec5SDimitry Andric     case DIDerivedTypeKind:
5530b57cec5SDimitry Andric     case DICompositeTypeKind:
5540b57cec5SDimitry Andric     case DISubroutineTypeKind:
5550b57cec5SDimitry Andric     case DIFileKind:
5560b57cec5SDimitry Andric     case DICompileUnitKind:
5570b57cec5SDimitry Andric     case DISubprogramKind:
5580b57cec5SDimitry Andric     case DILexicalBlockKind:
5590b57cec5SDimitry Andric     case DILexicalBlockFileKind:
5600b57cec5SDimitry Andric     case DINamespaceKind:
5610b57cec5SDimitry Andric     case DICommonBlockKind:
5620b57cec5SDimitry Andric     case DIModuleKind:
5630b57cec5SDimitry Andric       return true;
5640b57cec5SDimitry Andric     }
5650b57cec5SDimitry Andric   }
5660b57cec5SDimitry Andric };
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric /// File.
5690b57cec5SDimitry Andric ///
5700b57cec5SDimitry Andric /// TODO: Merge with directory/file node (including users).
5710b57cec5SDimitry Andric /// TODO: Canonicalize paths on creation.
5720b57cec5SDimitry Andric class DIFile : public DIScope {
5730b57cec5SDimitry Andric   friend class LLVMContextImpl;
5740b57cec5SDimitry Andric   friend class MDNode;
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric public:
5770b57cec5SDimitry Andric   /// Which algorithm (e.g. MD5) a checksum was generated with.
5780b57cec5SDimitry Andric   ///
5790b57cec5SDimitry Andric   /// The encoding is explicit because it is used directly in Bitcode. The
5800b57cec5SDimitry Andric   /// value 0 is reserved to indicate the absence of a checksum in Bitcode.
5810b57cec5SDimitry Andric   enum ChecksumKind {
5820b57cec5SDimitry Andric     // The first variant was originally CSK_None, encoded as 0. The new
5830b57cec5SDimitry Andric     // internal representation removes the need for this by wrapping the
5840b57cec5SDimitry Andric     // ChecksumInfo in an Optional, but to preserve Bitcode compatibility the 0
5850b57cec5SDimitry Andric     // encoding is reserved.
5860b57cec5SDimitry Andric     CSK_MD5 = 1,
5870b57cec5SDimitry Andric     CSK_SHA1 = 2,
5885ffd83dbSDimitry Andric     CSK_SHA256 = 3,
5895ffd83dbSDimitry Andric     CSK_Last = CSK_SHA256 // Should be last enumeration.
5900b57cec5SDimitry Andric   };
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric   /// A single checksum, represented by a \a Kind and a \a Value (a string).
593349cc55cSDimitry Andric   template <typename T> struct ChecksumInfo {
5940b57cec5SDimitry Andric     /// The kind of checksum which \a Value encodes.
5950b57cec5SDimitry Andric     ChecksumKind Kind;
5960b57cec5SDimitry Andric     /// The string value of the checksum.
5970b57cec5SDimitry Andric     T Value;
5980b57cec5SDimitry Andric 
ChecksumInfoChecksumInfo5990b57cec5SDimitry Andric     ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) {}
6000b57cec5SDimitry Andric     ~ChecksumInfo() = default;
6010b57cec5SDimitry Andric     bool operator==(const ChecksumInfo<T> &X) const {
6020b57cec5SDimitry Andric       return Kind == X.Kind && Value == X.Value;
6030b57cec5SDimitry Andric     }
6040b57cec5SDimitry Andric     bool operator!=(const ChecksumInfo<T> &X) const { return !(*this == X); }
getKindAsStringChecksumInfo6050b57cec5SDimitry Andric     StringRef getKindAsString() const { return getChecksumKindAsString(Kind); }
6060b57cec5SDimitry Andric   };
6070b57cec5SDimitry Andric 
6080b57cec5SDimitry Andric private:
609bdd1243dSDimitry Andric   std::optional<ChecksumInfo<MDString *>> Checksum;
610bdd1243dSDimitry Andric   /// An optional source. A nullptr means none.
611bdd1243dSDimitry Andric   MDString *Source;
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric   DIFile(LLVMContext &C, StorageType Storage,
614bdd1243dSDimitry Andric          std::optional<ChecksumInfo<MDString *>> CS, MDString *Src,
61581ad6265SDimitry Andric          ArrayRef<Metadata *> Ops);
6160b57cec5SDimitry Andric   ~DIFile() = default;
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric   static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
6190b57cec5SDimitry Andric                          StringRef Directory,
620bdd1243dSDimitry Andric                          std::optional<ChecksumInfo<StringRef>> CS,
621bdd1243dSDimitry Andric                          std::optional<StringRef> Source, StorageType Storage,
622349cc55cSDimitry Andric                          bool ShouldCreate = true) {
623bdd1243dSDimitry Andric     std::optional<ChecksumInfo<MDString *>> MDChecksum;
6240b57cec5SDimitry Andric     if (CS)
6250b57cec5SDimitry Andric       MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value));
626bdd1243dSDimitry Andric     return getImpl(Context, getCanonicalMDString(Context, Filename),
6270b57cec5SDimitry Andric                    getCanonicalMDString(Context, Directory), MDChecksum,
628bdd1243dSDimitry Andric                    Source ? MDString::get(Context, *Source) : nullptr, Storage,
629bdd1243dSDimitry Andric                    ShouldCreate);
6300b57cec5SDimitry Andric   }
6310b57cec5SDimitry Andric   static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
6320b57cec5SDimitry Andric                          MDString *Directory,
633bdd1243dSDimitry Andric                          std::optional<ChecksumInfo<MDString *>> CS,
634bdd1243dSDimitry Andric                          MDString *Source, StorageType Storage,
6350b57cec5SDimitry Andric                          bool ShouldCreate = true);
6360b57cec5SDimitry Andric 
cloneImpl()6370b57cec5SDimitry Andric   TempDIFile cloneImpl() const {
6380b57cec5SDimitry Andric     return getTemporary(getContext(), getFilename(), getDirectory(),
6390b57cec5SDimitry Andric                         getChecksum(), getSource());
6400b57cec5SDimitry Andric   }
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric public:
643349cc55cSDimitry Andric   DEFINE_MDNODE_GET(DIFile,
644349cc55cSDimitry Andric                     (StringRef Filename, StringRef Directory,
645bdd1243dSDimitry Andric                      std::optional<ChecksumInfo<StringRef>> CS = std::nullopt,
646bdd1243dSDimitry Andric                      std::optional<StringRef> Source = std::nullopt),
6470b57cec5SDimitry Andric                     (Filename, Directory, CS, Source))
648349cc55cSDimitry Andric   DEFINE_MDNODE_GET(DIFile,
649349cc55cSDimitry Andric                     (MDString * Filename, MDString *Directory,
650bdd1243dSDimitry Andric                      std::optional<ChecksumInfo<MDString *>> CS = std::nullopt,
651bdd1243dSDimitry Andric                      MDString *Source = nullptr),
6520b57cec5SDimitry Andric                     (Filename, Directory, CS, Source))
6530b57cec5SDimitry Andric 
clone()6540b57cec5SDimitry Andric   TempDIFile clone() const { return cloneImpl(); }
6550b57cec5SDimitry Andric 
getFilename()6560b57cec5SDimitry Andric   StringRef getFilename() const { return getStringOperand(0); }
getDirectory()6570b57cec5SDimitry Andric   StringRef getDirectory() const { return getStringOperand(1); }
getChecksum()658bdd1243dSDimitry Andric   std::optional<ChecksumInfo<StringRef>> getChecksum() const {
659bdd1243dSDimitry Andric     std::optional<ChecksumInfo<StringRef>> StringRefChecksum;
6600b57cec5SDimitry Andric     if (Checksum)
6610b57cec5SDimitry Andric       StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString());
6620b57cec5SDimitry Andric     return StringRefChecksum;
6630b57cec5SDimitry Andric   }
getSource()664bdd1243dSDimitry Andric   std::optional<StringRef> getSource() const {
665bdd1243dSDimitry Andric     return Source ? std::optional<StringRef>(Source->getString())
666bdd1243dSDimitry Andric                   : std::nullopt;
6670b57cec5SDimitry Andric   }
6680b57cec5SDimitry Andric 
getRawFilename()6690b57cec5SDimitry Andric   MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
getRawDirectory()6700b57cec5SDimitry Andric   MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
getRawChecksum()671bdd1243dSDimitry Andric   std::optional<ChecksumInfo<MDString *>> getRawChecksum() const {
672bdd1243dSDimitry Andric     return Checksum;
673bdd1243dSDimitry Andric   }
getRawSource()674bdd1243dSDimitry Andric   MDString *getRawSource() const { return Source; }
6750b57cec5SDimitry Andric 
6760b57cec5SDimitry Andric   static StringRef getChecksumKindAsString(ChecksumKind CSKind);
677bdd1243dSDimitry Andric   static std::optional<ChecksumKind> getChecksumKind(StringRef CSKindStr);
6780b57cec5SDimitry Andric 
classof(const Metadata * MD)6790b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
6800b57cec5SDimitry Andric     return MD->getMetadataID() == DIFileKind;
6810b57cec5SDimitry Andric   }
6820b57cec5SDimitry Andric };
6830b57cec5SDimitry Andric 
getFilename()6840b57cec5SDimitry Andric StringRef DIScope::getFilename() const {
6850b57cec5SDimitry Andric   if (auto *F = getFile())
6860b57cec5SDimitry Andric     return F->getFilename();
6870b57cec5SDimitry Andric   return "";
6880b57cec5SDimitry Andric }
6890b57cec5SDimitry Andric 
getDirectory()6900b57cec5SDimitry Andric StringRef DIScope::getDirectory() const {
6910b57cec5SDimitry Andric   if (auto *F = getFile())
6920b57cec5SDimitry Andric     return F->getDirectory();
6930b57cec5SDimitry Andric   return "";
6940b57cec5SDimitry Andric }
6950b57cec5SDimitry Andric 
getSource()696bdd1243dSDimitry Andric std::optional<StringRef> DIScope::getSource() const {
6970b57cec5SDimitry Andric   if (auto *F = getFile())
6980b57cec5SDimitry Andric     return F->getSource();
699bdd1243dSDimitry Andric   return std::nullopt;
7000b57cec5SDimitry Andric }
7010b57cec5SDimitry Andric 
7020b57cec5SDimitry Andric /// Base class for types.
7030b57cec5SDimitry Andric ///
7040b57cec5SDimitry Andric /// TODO: Remove the hardcoded name and context, since many types don't use
7050b57cec5SDimitry Andric /// them.
7060b57cec5SDimitry Andric /// TODO: Split up flags.
7075f757f3fSDimitry Andric ///
7085f757f3fSDimitry Andric /// Uses the SubclassData32 Metadata slot.
7090b57cec5SDimitry Andric class DIType : public DIScope {
7100b57cec5SDimitry Andric   unsigned Line;
7110b57cec5SDimitry Andric   DIFlags Flags;
7120b57cec5SDimitry Andric   uint64_t SizeInBits;
7130b57cec5SDimitry Andric   uint64_t OffsetInBits;
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric protected:
DIType(LLVMContext & C,unsigned ID,StorageType Storage,unsigned Tag,unsigned Line,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,DIFlags Flags,ArrayRef<Metadata * > Ops)7160b57cec5SDimitry Andric   DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
7170b57cec5SDimitry Andric          unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
7180b57cec5SDimitry Andric          uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
7190b57cec5SDimitry Andric       : DIScope(C, ID, Storage, Tag, Ops) {
7200b57cec5SDimitry Andric     init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
7210b57cec5SDimitry Andric   }
7220b57cec5SDimitry Andric   ~DIType() = default;
7230b57cec5SDimitry Andric 
init(unsigned Line,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,DIFlags Flags)7240b57cec5SDimitry Andric   void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
7250b57cec5SDimitry Andric             uint64_t OffsetInBits, DIFlags Flags) {
7260b57cec5SDimitry Andric     this->Line = Line;
7270b57cec5SDimitry Andric     this->Flags = Flags;
7280b57cec5SDimitry Andric     this->SizeInBits = SizeInBits;
7295f757f3fSDimitry Andric     this->SubclassData32 = AlignInBits;
7300b57cec5SDimitry Andric     this->OffsetInBits = OffsetInBits;
7310b57cec5SDimitry Andric   }
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric   /// Change fields in place.
mutate(unsigned Tag,unsigned Line,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,DIFlags Flags)7340b57cec5SDimitry Andric   void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
7350b57cec5SDimitry Andric               uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) {
7360b57cec5SDimitry Andric     assert(isDistinct() && "Only distinct nodes can mutate");
7370b57cec5SDimitry Andric     setTag(Tag);
7380b57cec5SDimitry Andric     init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
7390b57cec5SDimitry Andric   }
7400b57cec5SDimitry Andric 
7410b57cec5SDimitry Andric public:
clone()7420b57cec5SDimitry Andric   TempDIType clone() const {
7430b57cec5SDimitry Andric     return TempDIType(cast<DIType>(MDNode::clone().release()));
7440b57cec5SDimitry Andric   }
7450b57cec5SDimitry Andric 
getLine()7460b57cec5SDimitry Andric   unsigned getLine() const { return Line; }
getSizeInBits()7470b57cec5SDimitry Andric   uint64_t getSizeInBits() const { return SizeInBits; }
getAlignInBits()7485f757f3fSDimitry Andric   uint32_t getAlignInBits() const { return SubclassData32; }
getAlignInBytes()7490b57cec5SDimitry Andric   uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
getOffsetInBits()7500b57cec5SDimitry Andric   uint64_t getOffsetInBits() const { return OffsetInBits; }
getFlags()7510b57cec5SDimitry Andric   DIFlags getFlags() const { return Flags; }
7520b57cec5SDimitry Andric 
getScope()7530b57cec5SDimitry Andric   DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
getName()7540b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(2); }
7550b57cec5SDimitry Andric 
getRawScope()7560b57cec5SDimitry Andric   Metadata *getRawScope() const { return getOperand(1); }
getRawName()7570b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(2); }
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric   /// Returns a new temporary DIType with updated Flags
cloneWithFlags(DIFlags NewFlags)7600b57cec5SDimitry Andric   TempDIType cloneWithFlags(DIFlags NewFlags) const {
7610b57cec5SDimitry Andric     auto NewTy = clone();
7620b57cec5SDimitry Andric     NewTy->Flags = NewFlags;
7630b57cec5SDimitry Andric     return NewTy;
7640b57cec5SDimitry Andric   }
7650b57cec5SDimitry Andric 
isPrivate()7660b57cec5SDimitry Andric   bool isPrivate() const {
7670b57cec5SDimitry Andric     return (getFlags() & FlagAccessibility) == FlagPrivate;
7680b57cec5SDimitry Andric   }
isProtected()7690b57cec5SDimitry Andric   bool isProtected() const {
7700b57cec5SDimitry Andric     return (getFlags() & FlagAccessibility) == FlagProtected;
7710b57cec5SDimitry Andric   }
isPublic()7720b57cec5SDimitry Andric   bool isPublic() const {
7730b57cec5SDimitry Andric     return (getFlags() & FlagAccessibility) == FlagPublic;
7740b57cec5SDimitry Andric   }
isForwardDecl()7750b57cec5SDimitry Andric   bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
isAppleBlockExtension()7760b57cec5SDimitry Andric   bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
isVirtual()7770b57cec5SDimitry Andric   bool isVirtual() const { return getFlags() & FlagVirtual; }
isArtificial()7780b57cec5SDimitry Andric   bool isArtificial() const { return getFlags() & FlagArtificial; }
isObjectPointer()7790b57cec5SDimitry Andric   bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
isObjcClassComplete()7800b57cec5SDimitry Andric   bool isObjcClassComplete() const {
7810b57cec5SDimitry Andric     return getFlags() & FlagObjcClassComplete;
7820b57cec5SDimitry Andric   }
isVector()7830b57cec5SDimitry Andric   bool isVector() const { return getFlags() & FlagVector; }
isBitField()7840b57cec5SDimitry Andric   bool isBitField() const { return getFlags() & FlagBitField; }
isStaticMember()7850b57cec5SDimitry Andric   bool isStaticMember() const { return getFlags() & FlagStaticMember; }
isLValueReference()7860b57cec5SDimitry Andric   bool isLValueReference() const { return getFlags() & FlagLValueReference; }
isRValueReference()7870b57cec5SDimitry Andric   bool isRValueReference() const { return getFlags() & FlagRValueReference; }
isTypePassByValue()7880b57cec5SDimitry Andric   bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; }
isTypePassByReference()7890b57cec5SDimitry Andric   bool isTypePassByReference() const {
7900b57cec5SDimitry Andric     return getFlags() & FlagTypePassByReference;
7910b57cec5SDimitry Andric   }
isBigEndian()7920b57cec5SDimitry Andric   bool isBigEndian() const { return getFlags() & FlagBigEndian; }
isLittleEndian()7930b57cec5SDimitry Andric   bool isLittleEndian() const { return getFlags() & FlagLittleEndian; }
getExportSymbols()7948bcb0991SDimitry Andric   bool getExportSymbols() const { return getFlags() & FlagExportSymbols; }
7950b57cec5SDimitry Andric 
classof(const Metadata * MD)7960b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
7970b57cec5SDimitry Andric     switch (MD->getMetadataID()) {
7980b57cec5SDimitry Andric     default:
7990b57cec5SDimitry Andric       return false;
8000b57cec5SDimitry Andric     case DIBasicTypeKind:
801e8d8bef9SDimitry Andric     case DIStringTypeKind:
8020b57cec5SDimitry Andric     case DIDerivedTypeKind:
8030b57cec5SDimitry Andric     case DICompositeTypeKind:
8040b57cec5SDimitry Andric     case DISubroutineTypeKind:
8050b57cec5SDimitry Andric       return true;
8060b57cec5SDimitry Andric     }
8070b57cec5SDimitry Andric   }
8080b57cec5SDimitry Andric };
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric /// Basic type, like 'int' or 'float'.
8110b57cec5SDimitry Andric ///
8120b57cec5SDimitry Andric /// TODO: Split out DW_TAG_unspecified_type.
8130b57cec5SDimitry Andric /// TODO: Drop unused accessors.
8140b57cec5SDimitry Andric class DIBasicType : public DIType {
8150b57cec5SDimitry Andric   friend class LLVMContextImpl;
8160b57cec5SDimitry Andric   friend class MDNode;
8170b57cec5SDimitry Andric 
8180b57cec5SDimitry Andric   unsigned Encoding;
8190b57cec5SDimitry Andric 
DIBasicType(LLVMContext & C,StorageType Storage,unsigned Tag,uint64_t SizeInBits,uint32_t AlignInBits,unsigned Encoding,DIFlags Flags,ArrayRef<Metadata * > Ops)8200b57cec5SDimitry Andric   DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
8210b57cec5SDimitry Andric               uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
8220b57cec5SDimitry Andric               DIFlags Flags, ArrayRef<Metadata *> Ops)
8230b57cec5SDimitry Andric       : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
8240b57cec5SDimitry Andric                Flags, Ops),
8250b57cec5SDimitry Andric         Encoding(Encoding) {}
8260b57cec5SDimitry Andric   ~DIBasicType() = default;
8270b57cec5SDimitry Andric 
8280b57cec5SDimitry Andric   static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
8290b57cec5SDimitry Andric                               StringRef Name, uint64_t SizeInBits,
8300b57cec5SDimitry Andric                               uint32_t AlignInBits, unsigned Encoding,
8310b57cec5SDimitry Andric                               DIFlags Flags, StorageType Storage,
8320b57cec5SDimitry Andric                               bool ShouldCreate = true) {
8330b57cec5SDimitry Andric     return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
8340b57cec5SDimitry Andric                    SizeInBits, AlignInBits, Encoding, Flags, Storage,
8350b57cec5SDimitry Andric                    ShouldCreate);
8360b57cec5SDimitry Andric   }
8370b57cec5SDimitry Andric   static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
8380b57cec5SDimitry Andric                               MDString *Name, uint64_t SizeInBits,
8390b57cec5SDimitry Andric                               uint32_t AlignInBits, unsigned Encoding,
8400b57cec5SDimitry Andric                               DIFlags Flags, StorageType Storage,
8410b57cec5SDimitry Andric                               bool ShouldCreate = true);
8420b57cec5SDimitry Andric 
cloneImpl()8430b57cec5SDimitry Andric   TempDIBasicType cloneImpl() const {
8440b57cec5SDimitry Andric     return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
8450b57cec5SDimitry Andric                         getAlignInBits(), getEncoding(), getFlags());
8460b57cec5SDimitry Andric   }
8470b57cec5SDimitry Andric 
8480b57cec5SDimitry Andric public:
8490b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
8500b57cec5SDimitry Andric                     (Tag, Name, 0, 0, 0, FlagZero))
8510b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIBasicType,
852e8d8bef9SDimitry Andric                     (unsigned Tag, StringRef Name, uint64_t SizeInBits),
853e8d8bef9SDimitry Andric                     (Tag, Name, SizeInBits, 0, 0, FlagZero))
854e8d8bef9SDimitry Andric   DEFINE_MDNODE_GET(DIBasicType,
855e8d8bef9SDimitry Andric                     (unsigned Tag, MDString *Name, uint64_t SizeInBits),
856e8d8bef9SDimitry Andric                     (Tag, Name, SizeInBits, 0, 0, FlagZero))
857e8d8bef9SDimitry Andric   DEFINE_MDNODE_GET(DIBasicType,
8580b57cec5SDimitry Andric                     (unsigned Tag, StringRef Name, uint64_t SizeInBits,
8590b57cec5SDimitry Andric                      uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
8600b57cec5SDimitry Andric                     (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
8610b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIBasicType,
8620b57cec5SDimitry Andric                     (unsigned Tag, MDString *Name, uint64_t SizeInBits,
8630b57cec5SDimitry Andric                      uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
8640b57cec5SDimitry Andric                     (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
8650b57cec5SDimitry Andric 
clone()8660b57cec5SDimitry Andric   TempDIBasicType clone() const { return cloneImpl(); }
8670b57cec5SDimitry Andric 
getEncoding()8680b57cec5SDimitry Andric   unsigned getEncoding() const { return Encoding; }
8690b57cec5SDimitry Andric 
8700b57cec5SDimitry Andric   enum class Signedness { Signed, Unsigned };
8710b57cec5SDimitry Andric 
872bdd1243dSDimitry Andric   /// Return the signedness of this type, or std::nullopt if this type is
873bdd1243dSDimitry Andric   /// neither signed nor unsigned.
874bdd1243dSDimitry Andric   std::optional<Signedness> getSignedness() const;
8750b57cec5SDimitry Andric 
classof(const Metadata * MD)8760b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
8770b57cec5SDimitry Andric     return MD->getMetadataID() == DIBasicTypeKind;
8780b57cec5SDimitry Andric   }
8790b57cec5SDimitry Andric };
8800b57cec5SDimitry Andric 
881e8d8bef9SDimitry Andric /// String type, Fortran CHARACTER(n)
882e8d8bef9SDimitry Andric class DIStringType : public DIType {
883e8d8bef9SDimitry Andric   friend class LLVMContextImpl;
884e8d8bef9SDimitry Andric   friend class MDNode;
885e8d8bef9SDimitry Andric 
886e8d8bef9SDimitry Andric   unsigned Encoding;
887e8d8bef9SDimitry Andric 
DIStringType(LLVMContext & C,StorageType Storage,unsigned Tag,uint64_t SizeInBits,uint32_t AlignInBits,unsigned Encoding,ArrayRef<Metadata * > Ops)888e8d8bef9SDimitry Andric   DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag,
889e8d8bef9SDimitry Andric                uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
890e8d8bef9SDimitry Andric                ArrayRef<Metadata *> Ops)
891e8d8bef9SDimitry Andric       : DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
892e8d8bef9SDimitry Andric                FlagZero, Ops),
893e8d8bef9SDimitry Andric         Encoding(Encoding) {}
894e8d8bef9SDimitry Andric   ~DIStringType() = default;
895e8d8bef9SDimitry Andric 
896e8d8bef9SDimitry Andric   static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
897e8d8bef9SDimitry Andric                                StringRef Name, Metadata *StringLength,
89804eeddc0SDimitry Andric                                Metadata *StrLenExp, Metadata *StrLocationExp,
89904eeddc0SDimitry Andric                                uint64_t SizeInBits, uint32_t AlignInBits,
90004eeddc0SDimitry Andric                                unsigned Encoding, StorageType Storage,
90104eeddc0SDimitry Andric                                bool ShouldCreate = true) {
902e8d8bef9SDimitry Andric     return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
90304eeddc0SDimitry Andric                    StringLength, StrLenExp, StrLocationExp, SizeInBits,
90404eeddc0SDimitry Andric                    AlignInBits, Encoding, Storage, ShouldCreate);
905e8d8bef9SDimitry Andric   }
906e8d8bef9SDimitry Andric   static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
907e8d8bef9SDimitry Andric                                MDString *Name, Metadata *StringLength,
90804eeddc0SDimitry Andric                                Metadata *StrLenExp, Metadata *StrLocationExp,
90904eeddc0SDimitry Andric                                uint64_t SizeInBits, uint32_t AlignInBits,
91004eeddc0SDimitry Andric                                unsigned Encoding, StorageType Storage,
91104eeddc0SDimitry Andric                                bool ShouldCreate = true);
912e8d8bef9SDimitry Andric 
cloneImpl()913e8d8bef9SDimitry Andric   TempDIStringType cloneImpl() const {
914e8d8bef9SDimitry Andric     return getTemporary(getContext(), getTag(), getRawName(),
915e8d8bef9SDimitry Andric                         getRawStringLength(), getRawStringLengthExp(),
91604eeddc0SDimitry Andric                         getRawStringLocationExp(), getSizeInBits(),
91704eeddc0SDimitry Andric                         getAlignInBits(), getEncoding());
918e8d8bef9SDimitry Andric   }
919e8d8bef9SDimitry Andric 
920e8d8bef9SDimitry Andric public:
921e8d8bef9SDimitry Andric   DEFINE_MDNODE_GET(DIStringType,
922e8d8bef9SDimitry Andric                     (unsigned Tag, StringRef Name, uint64_t SizeInBits,
923e8d8bef9SDimitry Andric                      uint32_t AlignInBits),
92404eeddc0SDimitry Andric                     (Tag, Name, nullptr, nullptr, nullptr, SizeInBits,
92504eeddc0SDimitry Andric                      AlignInBits, 0))
926e8d8bef9SDimitry Andric   DEFINE_MDNODE_GET(DIStringType,
927e8d8bef9SDimitry Andric                     (unsigned Tag, MDString *Name, Metadata *StringLength,
92804eeddc0SDimitry Andric                      Metadata *StringLengthExp, Metadata *StringLocationExp,
92904eeddc0SDimitry Andric                      uint64_t SizeInBits, uint32_t AlignInBits,
93004eeddc0SDimitry Andric                      unsigned Encoding),
93104eeddc0SDimitry Andric                     (Tag, Name, StringLength, StringLengthExp,
93204eeddc0SDimitry Andric                      StringLocationExp, SizeInBits, AlignInBits, Encoding))
933e8d8bef9SDimitry Andric   DEFINE_MDNODE_GET(DIStringType,
934e8d8bef9SDimitry Andric                     (unsigned Tag, StringRef Name, Metadata *StringLength,
93504eeddc0SDimitry Andric                      Metadata *StringLengthExp, Metadata *StringLocationExp,
93604eeddc0SDimitry Andric                      uint64_t SizeInBits, uint32_t AlignInBits,
93704eeddc0SDimitry Andric                      unsigned Encoding),
93804eeddc0SDimitry Andric                     (Tag, Name, StringLength, StringLengthExp,
93904eeddc0SDimitry Andric                      StringLocationExp, SizeInBits, AlignInBits, Encoding))
940e8d8bef9SDimitry Andric 
clone()941e8d8bef9SDimitry Andric   TempDIStringType clone() const { return cloneImpl(); }
942e8d8bef9SDimitry Andric 
classof(const Metadata * MD)943e8d8bef9SDimitry Andric   static bool classof(const Metadata *MD) {
944e8d8bef9SDimitry Andric     return MD->getMetadataID() == DIStringTypeKind;
945e8d8bef9SDimitry Andric   }
946e8d8bef9SDimitry Andric 
getStringLength()947e8d8bef9SDimitry Andric   DIVariable *getStringLength() const {
948e8d8bef9SDimitry Andric     return cast_or_null<DIVariable>(getRawStringLength());
949e8d8bef9SDimitry Andric   }
950e8d8bef9SDimitry Andric 
getStringLengthExp()951e8d8bef9SDimitry Andric   DIExpression *getStringLengthExp() const {
952e8d8bef9SDimitry Andric     return cast_or_null<DIExpression>(getRawStringLengthExp());
953e8d8bef9SDimitry Andric   }
954e8d8bef9SDimitry Andric 
getStringLocationExp()95504eeddc0SDimitry Andric   DIExpression *getStringLocationExp() const {
95604eeddc0SDimitry Andric     return cast_or_null<DIExpression>(getRawStringLocationExp());
95704eeddc0SDimitry Andric   }
95804eeddc0SDimitry Andric 
getEncoding()959e8d8bef9SDimitry Andric   unsigned getEncoding() const { return Encoding; }
960e8d8bef9SDimitry Andric 
getRawStringLength()961e8d8bef9SDimitry Andric   Metadata *getRawStringLength() const { return getOperand(3); }
962e8d8bef9SDimitry Andric 
getRawStringLengthExp()963e8d8bef9SDimitry Andric   Metadata *getRawStringLengthExp() const { return getOperand(4); }
96404eeddc0SDimitry Andric 
getRawStringLocationExp()96504eeddc0SDimitry Andric   Metadata *getRawStringLocationExp() const { return getOperand(5); }
966e8d8bef9SDimitry Andric };
967e8d8bef9SDimitry Andric 
9680b57cec5SDimitry Andric /// Derived types.
9690b57cec5SDimitry Andric ///
9700b57cec5SDimitry Andric /// This includes qualified types, pointers, references, friends, typedefs, and
9710b57cec5SDimitry Andric /// class members.
9720b57cec5SDimitry Andric ///
9730b57cec5SDimitry Andric /// TODO: Split out members (inheritance, fields, methods, etc.).
9740b57cec5SDimitry Andric class DIDerivedType : public DIType {
9750b57cec5SDimitry Andric   friend class LLVMContextImpl;
9760b57cec5SDimitry Andric   friend class MDNode;
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   /// The DWARF address space of the memory pointed to or referenced by a
9790b57cec5SDimitry Andric   /// pointer or reference type respectively.
980bdd1243dSDimitry Andric   std::optional<unsigned> DWARFAddressSpace;
9810b57cec5SDimitry Andric 
DIDerivedType(LLVMContext & C,StorageType Storage,unsigned Tag,unsigned Line,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,std::optional<unsigned> DWARFAddressSpace,DIFlags Flags,ArrayRef<Metadata * > Ops)9820b57cec5SDimitry Andric   DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
9830b57cec5SDimitry Andric                 unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
984bdd1243dSDimitry Andric                 uint64_t OffsetInBits,
985bdd1243dSDimitry Andric                 std::optional<unsigned> DWARFAddressSpace, DIFlags Flags,
986bdd1243dSDimitry Andric                 ArrayRef<Metadata *> Ops)
9870b57cec5SDimitry Andric       : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
9880b57cec5SDimitry Andric                AlignInBits, OffsetInBits, Flags, Ops),
9890b57cec5SDimitry Andric         DWARFAddressSpace(DWARFAddressSpace) {}
9900b57cec5SDimitry Andric   ~DIDerivedType() = default;
9910b57cec5SDimitry Andric   static DIDerivedType *
9920b57cec5SDimitry Andric   getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File,
9930b57cec5SDimitry Andric           unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
9940b57cec5SDimitry Andric           uint32_t AlignInBits, uint64_t OffsetInBits,
995bdd1243dSDimitry Andric           std::optional<unsigned> DWARFAddressSpace, DIFlags Flags,
996349cc55cSDimitry Andric           Metadata *ExtraData, DINodeArray Annotations, StorageType Storage,
997349cc55cSDimitry Andric           bool ShouldCreate = true) {
9980b57cec5SDimitry Andric     return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
9990b57cec5SDimitry Andric                    Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
1000349cc55cSDimitry Andric                    DWARFAddressSpace, Flags, ExtraData, Annotations.get(),
1001349cc55cSDimitry Andric                    Storage, ShouldCreate);
10020b57cec5SDimitry Andric   }
1003349cc55cSDimitry Andric   static DIDerivedType *
1004349cc55cSDimitry Andric   getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1005349cc55cSDimitry Andric           unsigned Line, Metadata *Scope, Metadata *BaseType,
1006349cc55cSDimitry Andric           uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
1007bdd1243dSDimitry Andric           std::optional<unsigned> DWARFAddressSpace, DIFlags Flags,
1008349cc55cSDimitry Andric           Metadata *ExtraData, Metadata *Annotations, StorageType Storage,
1009349cc55cSDimitry Andric           bool ShouldCreate = true);
10100b57cec5SDimitry Andric 
cloneImpl()10110b57cec5SDimitry Andric   TempDIDerivedType cloneImpl() const {
1012349cc55cSDimitry Andric     return getTemporary(
1013349cc55cSDimitry Andric         getContext(), getTag(), getName(), getFile(), getLine(), getScope(),
1014349cc55cSDimitry Andric         getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(),
1015349cc55cSDimitry Andric         getDWARFAddressSpace(), getFlags(), getExtraData(), getAnnotations());
10160b57cec5SDimitry Andric   }
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric public:
1019349cc55cSDimitry Andric   DEFINE_MDNODE_GET(
1020349cc55cSDimitry Andric       DIDerivedType,
1021349cc55cSDimitry Andric       (unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
1022349cc55cSDimitry Andric        Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
1023349cc55cSDimitry Andric        uint32_t AlignInBits, uint64_t OffsetInBits,
1024bdd1243dSDimitry Andric        std::optional<unsigned> DWARFAddressSpace, DIFlags Flags,
1025349cc55cSDimitry Andric        Metadata *ExtraData = nullptr, Metadata *Annotations = nullptr),
1026349cc55cSDimitry Andric       (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
1027349cc55cSDimitry Andric        OffsetInBits, DWARFAddressSpace, Flags, ExtraData, Annotations))
10280b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIDerivedType,
10290b57cec5SDimitry Andric                     (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
10300b57cec5SDimitry Andric                      DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
10310b57cec5SDimitry Andric                      uint32_t AlignInBits, uint64_t OffsetInBits,
1032bdd1243dSDimitry Andric                      std::optional<unsigned> DWARFAddressSpace, DIFlags Flags,
1033349cc55cSDimitry Andric                      Metadata *ExtraData = nullptr,
1034349cc55cSDimitry Andric                      DINodeArray Annotations = nullptr),
10350b57cec5SDimitry Andric                     (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
10360b57cec5SDimitry Andric                      AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
1037349cc55cSDimitry Andric                      ExtraData, Annotations))
10380b57cec5SDimitry Andric 
clone()10390b57cec5SDimitry Andric   TempDIDerivedType clone() const { return cloneImpl(); }
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   /// Get the base type this is derived from.
getBaseType()10420b57cec5SDimitry Andric   DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
getRawBaseType()10430b57cec5SDimitry Andric   Metadata *getRawBaseType() const { return getOperand(3); }
10440b57cec5SDimitry Andric 
10450b57cec5SDimitry Andric   /// \returns The DWARF address space of the memory pointed to or referenced by
10460b57cec5SDimitry Andric   /// a pointer or reference type respectively.
getDWARFAddressSpace()1047bdd1243dSDimitry Andric   std::optional<unsigned> getDWARFAddressSpace() const {
1048bdd1243dSDimitry Andric     return DWARFAddressSpace;
1049bdd1243dSDimitry Andric   }
10500b57cec5SDimitry Andric 
10510b57cec5SDimitry Andric   /// Get extra data associated with this derived type.
10520b57cec5SDimitry Andric   ///
10530b57cec5SDimitry Andric   /// Class type for pointer-to-members, objective-c property node for ivars,
10540b57cec5SDimitry Andric   /// global constant wrapper for static members, or virtual base pointer offset
10550b57cec5SDimitry Andric   /// for inheritance.
10560b57cec5SDimitry Andric   ///
10570b57cec5SDimitry Andric   /// TODO: Separate out types that need this extra operand: pointer-to-member
10580b57cec5SDimitry Andric   /// types and member fields (static members and ivars).
getExtraData()10590b57cec5SDimitry Andric   Metadata *getExtraData() const { return getRawExtraData(); }
getRawExtraData()10600b57cec5SDimitry Andric   Metadata *getRawExtraData() const { return getOperand(4); }
10610b57cec5SDimitry Andric 
1062349cc55cSDimitry Andric   /// Get annotations associated with this derived type.
getAnnotations()1063349cc55cSDimitry Andric   DINodeArray getAnnotations() const {
1064349cc55cSDimitry Andric     return cast_or_null<MDTuple>(getRawAnnotations());
1065349cc55cSDimitry Andric   }
getRawAnnotations()1066349cc55cSDimitry Andric   Metadata *getRawAnnotations() const { return getOperand(5); }
1067349cc55cSDimitry Andric 
10680b57cec5SDimitry Andric   /// Get casted version of extra data.
10690b57cec5SDimitry Andric   /// @{
107081ad6265SDimitry Andric   DIType *getClassType() const;
10710b57cec5SDimitry Andric 
getObjCProperty()10720b57cec5SDimitry Andric   DIObjCProperty *getObjCProperty() const {
10730b57cec5SDimitry Andric     return dyn_cast_or_null<DIObjCProperty>(getExtraData());
10740b57cec5SDimitry Andric   }
10750b57cec5SDimitry Andric 
107681ad6265SDimitry Andric   uint32_t getVBPtrOffset() const;
10770b57cec5SDimitry Andric 
107881ad6265SDimitry Andric   Constant *getStorageOffsetInBits() const;
10790b57cec5SDimitry Andric 
108081ad6265SDimitry Andric   Constant *getConstant() const;
108181ad6265SDimitry Andric 
108281ad6265SDimitry Andric   Constant *getDiscriminantValue() const;
10830b57cec5SDimitry Andric   /// @}
10840b57cec5SDimitry Andric 
classof(const Metadata * MD)10850b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
10860b57cec5SDimitry Andric     return MD->getMetadataID() == DIDerivedTypeKind;
10870b57cec5SDimitry Andric   }
10880b57cec5SDimitry Andric };
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric /// Composite types.
10910b57cec5SDimitry Andric ///
10920b57cec5SDimitry Andric /// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
10930b57cec5SDimitry Andric /// TODO: Create a custom, unrelated node for DW_TAG_array_type.
10940b57cec5SDimitry Andric class DICompositeType : public DIType {
10950b57cec5SDimitry Andric   friend class LLVMContextImpl;
10960b57cec5SDimitry Andric   friend class MDNode;
10970b57cec5SDimitry Andric 
10980b57cec5SDimitry Andric   unsigned RuntimeLang;
10990b57cec5SDimitry Andric 
DICompositeType(LLVMContext & C,StorageType Storage,unsigned Tag,unsigned Line,unsigned RuntimeLang,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,DIFlags Flags,ArrayRef<Metadata * > Ops)11000b57cec5SDimitry Andric   DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
11010b57cec5SDimitry Andric                   unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
11020b57cec5SDimitry Andric                   uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
11030b57cec5SDimitry Andric                   ArrayRef<Metadata *> Ops)
11040b57cec5SDimitry Andric       : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
11050b57cec5SDimitry Andric                AlignInBits, OffsetInBits, Flags, Ops),
11060b57cec5SDimitry Andric         RuntimeLang(RuntimeLang) {}
11070b57cec5SDimitry Andric   ~DICompositeType() = default;
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric   /// Change fields in place.
mutate(unsigned Tag,unsigned Line,unsigned RuntimeLang,uint64_t SizeInBits,uint32_t AlignInBits,uint64_t OffsetInBits,DIFlags Flags)11100b57cec5SDimitry Andric   void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
1111349cc55cSDimitry Andric               uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
1112349cc55cSDimitry Andric               DIFlags Flags) {
11130b57cec5SDimitry Andric     assert(isDistinct() && "Only distinct nodes can mutate");
11140b57cec5SDimitry Andric     assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
11150b57cec5SDimitry Andric     this->RuntimeLang = RuntimeLang;
11160b57cec5SDimitry Andric     DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
11170b57cec5SDimitry Andric   }
11180b57cec5SDimitry Andric 
11190b57cec5SDimitry Andric   static DICompositeType *
11200b57cec5SDimitry Andric   getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
11210b57cec5SDimitry Andric           unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
11220b57cec5SDimitry Andric           uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
11230b57cec5SDimitry Andric           DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
11240b57cec5SDimitry Andric           DITemplateParameterArray TemplateParams, StringRef Identifier,
11255ffd83dbSDimitry Andric           DIDerivedType *Discriminator, Metadata *DataLocation,
1126e8d8bef9SDimitry Andric           Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1127349cc55cSDimitry Andric           DINodeArray Annotations, StorageType Storage,
1128349cc55cSDimitry Andric           bool ShouldCreate = true) {
1129e8d8bef9SDimitry Andric     return getImpl(
1130e8d8bef9SDimitry Andric         Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
1131e8d8bef9SDimitry Andric         BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
1132e8d8bef9SDimitry Andric         RuntimeLang, VTableHolder, TemplateParams.get(),
1133e8d8bef9SDimitry Andric         getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
1134349cc55cSDimitry Andric         Associated, Allocated, Rank, Annotations.get(), Storage, ShouldCreate);
11350b57cec5SDimitry Andric   }
11360b57cec5SDimitry Andric   static DICompositeType *
11370b57cec5SDimitry Andric   getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
11380b57cec5SDimitry Andric           unsigned Line, Metadata *Scope, Metadata *BaseType,
11390b57cec5SDimitry Andric           uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
11400b57cec5SDimitry Andric           DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
11410b57cec5SDimitry Andric           Metadata *VTableHolder, Metadata *TemplateParams,
11425ffd83dbSDimitry Andric           MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
1143e8d8bef9SDimitry Andric           Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1144349cc55cSDimitry Andric           Metadata *Annotations, StorageType Storage, bool ShouldCreate = true);
11450b57cec5SDimitry Andric 
cloneImpl()11460b57cec5SDimitry Andric   TempDICompositeType cloneImpl() const {
1147349cc55cSDimitry Andric     return getTemporary(
1148349cc55cSDimitry Andric         getContext(), getTag(), getName(), getFile(), getLine(), getScope(),
1149349cc55cSDimitry Andric         getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(),
1150349cc55cSDimitry Andric         getFlags(), getElements(), getRuntimeLang(), getVTableHolder(),
1151349cc55cSDimitry Andric         getTemplateParams(), getIdentifier(), getDiscriminator(),
1152349cc55cSDimitry Andric         getRawDataLocation(), getRawAssociated(), getRawAllocated(),
1153349cc55cSDimitry Andric         getRawRank(), getAnnotations());
11540b57cec5SDimitry Andric   }
11550b57cec5SDimitry Andric 
11560b57cec5SDimitry Andric public:
11575ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(
11585ffd83dbSDimitry Andric       DICompositeType,
11590b57cec5SDimitry Andric       (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
11600b57cec5SDimitry Andric        DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
11610b57cec5SDimitry Andric        uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
11625ffd83dbSDimitry Andric        DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
11630b57cec5SDimitry Andric        DITemplateParameterArray TemplateParams = nullptr,
11645ffd83dbSDimitry Andric        StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
1165e8d8bef9SDimitry Andric        Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
1166349cc55cSDimitry Andric        Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
1167349cc55cSDimitry Andric        DINodeArray Annotations = nullptr),
11685ffd83dbSDimitry Andric       (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
11695ffd83dbSDimitry Andric        OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
1170349cc55cSDimitry Andric        Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
1171349cc55cSDimitry Andric        Annotations))
11725ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(
11735ffd83dbSDimitry Andric       DICompositeType,
11745ffd83dbSDimitry Andric       (unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
11755ffd83dbSDimitry Andric        Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
11765ffd83dbSDimitry Andric        uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
11775ffd83dbSDimitry Andric        Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
11785ffd83dbSDimitry Andric        Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
1179e8d8bef9SDimitry Andric        Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
1180e8d8bef9SDimitry Andric        Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
1181349cc55cSDimitry Andric        Metadata *Rank = nullptr, Metadata *Annotations = nullptr),
11825ffd83dbSDimitry Andric       (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
11835ffd83dbSDimitry Andric        OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
1184349cc55cSDimitry Andric        Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
1185349cc55cSDimitry Andric        Annotations))
11860b57cec5SDimitry Andric 
clone()11870b57cec5SDimitry Andric   TempDICompositeType clone() const { return cloneImpl(); }
11880b57cec5SDimitry Andric 
11890b57cec5SDimitry Andric   /// Get a DICompositeType with the given ODR identifier.
11900b57cec5SDimitry Andric   ///
11910b57cec5SDimitry Andric   /// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
11920b57cec5SDimitry Andric   /// DICompositeType for the given ODR \c Identifier.  If none exists, creates
11930b57cec5SDimitry Andric   /// a new node.
11940b57cec5SDimitry Andric   ///
11950b57cec5SDimitry Andric   /// Else, returns \c nullptr.
11960b57cec5SDimitry Andric   static DICompositeType *
11970b57cec5SDimitry Andric   getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
11980b57cec5SDimitry Andric              MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
11990b57cec5SDimitry Andric              Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
12000b57cec5SDimitry Andric              uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
12010b57cec5SDimitry Andric              unsigned RuntimeLang, Metadata *VTableHolder,
12025ffd83dbSDimitry Andric              Metadata *TemplateParams, Metadata *Discriminator,
1203e8d8bef9SDimitry Andric              Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1204349cc55cSDimitry Andric              Metadata *Rank, Metadata *Annotations);
12050b57cec5SDimitry Andric   static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
12060b57cec5SDimitry Andric                                              MDString &Identifier);
12070b57cec5SDimitry Andric 
12080b57cec5SDimitry Andric   /// Build a DICompositeType with the given ODR identifier.
12090b57cec5SDimitry Andric   ///
12100b57cec5SDimitry Andric   /// Looks up the mapped DICompositeType for the given ODR \c Identifier.  If
12110b57cec5SDimitry Andric   /// it doesn't exist, creates a new one.  If it does exist and \a
12120b57cec5SDimitry Andric   /// isForwardDecl(), and the new arguments would be a definition, mutates the
12130b57cec5SDimitry Andric   /// the type in place.  In either case, returns the type.
12140b57cec5SDimitry Andric   ///
12150b57cec5SDimitry Andric   /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
12160b57cec5SDimitry Andric   /// nullptr.
12170b57cec5SDimitry Andric   static DICompositeType *
12180b57cec5SDimitry Andric   buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
12190b57cec5SDimitry Andric                MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
12200b57cec5SDimitry Andric                Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
12210b57cec5SDimitry Andric                uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
12220b57cec5SDimitry Andric                unsigned RuntimeLang, Metadata *VTableHolder,
12235ffd83dbSDimitry Andric                Metadata *TemplateParams, Metadata *Discriminator,
1224e8d8bef9SDimitry Andric                Metadata *DataLocation, Metadata *Associated,
1225349cc55cSDimitry Andric                Metadata *Allocated, Metadata *Rank, Metadata *Annotations);
12260b57cec5SDimitry Andric 
getBaseType()12270b57cec5SDimitry Andric   DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
getElements()12280b57cec5SDimitry Andric   DINodeArray getElements() const {
12290b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawElements());
12300b57cec5SDimitry Andric   }
getVTableHolder()12310b57cec5SDimitry Andric   DIType *getVTableHolder() const {
12320b57cec5SDimitry Andric     return cast_or_null<DIType>(getRawVTableHolder());
12330b57cec5SDimitry Andric   }
getTemplateParams()12340b57cec5SDimitry Andric   DITemplateParameterArray getTemplateParams() const {
12350b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawTemplateParams());
12360b57cec5SDimitry Andric   }
getIdentifier()12370b57cec5SDimitry Andric   StringRef getIdentifier() const { return getStringOperand(7); }
getRuntimeLang()12380b57cec5SDimitry Andric   unsigned getRuntimeLang() const { return RuntimeLang; }
12390b57cec5SDimitry Andric 
getRawBaseType()12400b57cec5SDimitry Andric   Metadata *getRawBaseType() const { return getOperand(3); }
getRawElements()12410b57cec5SDimitry Andric   Metadata *getRawElements() const { return getOperand(4); }
getRawVTableHolder()12420b57cec5SDimitry Andric   Metadata *getRawVTableHolder() const { return getOperand(5); }
getRawTemplateParams()12430b57cec5SDimitry Andric   Metadata *getRawTemplateParams() const { return getOperand(6); }
getRawIdentifier()12440b57cec5SDimitry Andric   MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
getRawDiscriminator()12450b57cec5SDimitry Andric   Metadata *getRawDiscriminator() const { return getOperand(8); }
getDiscriminator()1246349cc55cSDimitry Andric   DIDerivedType *getDiscriminator() const {
1247349cc55cSDimitry Andric     return getOperandAs<DIDerivedType>(8);
1248349cc55cSDimitry Andric   }
getRawDataLocation()12495ffd83dbSDimitry Andric   Metadata *getRawDataLocation() const { return getOperand(9); }
getDataLocation()12505ffd83dbSDimitry Andric   DIVariable *getDataLocation() const {
12515ffd83dbSDimitry Andric     return dyn_cast_or_null<DIVariable>(getRawDataLocation());
12525ffd83dbSDimitry Andric   }
getDataLocationExp()12535ffd83dbSDimitry Andric   DIExpression *getDataLocationExp() const {
12545ffd83dbSDimitry Andric     return dyn_cast_or_null<DIExpression>(getRawDataLocation());
12555ffd83dbSDimitry Andric   }
getRawAssociated()1256e8d8bef9SDimitry Andric   Metadata *getRawAssociated() const { return getOperand(10); }
getAssociated()1257e8d8bef9SDimitry Andric   DIVariable *getAssociated() const {
1258e8d8bef9SDimitry Andric     return dyn_cast_or_null<DIVariable>(getRawAssociated());
1259e8d8bef9SDimitry Andric   }
getAssociatedExp()1260e8d8bef9SDimitry Andric   DIExpression *getAssociatedExp() const {
1261e8d8bef9SDimitry Andric     return dyn_cast_or_null<DIExpression>(getRawAssociated());
1262e8d8bef9SDimitry Andric   }
getRawAllocated()1263e8d8bef9SDimitry Andric   Metadata *getRawAllocated() const { return getOperand(11); }
getAllocated()1264e8d8bef9SDimitry Andric   DIVariable *getAllocated() const {
1265e8d8bef9SDimitry Andric     return dyn_cast_or_null<DIVariable>(getRawAllocated());
1266e8d8bef9SDimitry Andric   }
getAllocatedExp()1267e8d8bef9SDimitry Andric   DIExpression *getAllocatedExp() const {
1268e8d8bef9SDimitry Andric     return dyn_cast_or_null<DIExpression>(getRawAllocated());
1269e8d8bef9SDimitry Andric   }
getRawRank()1270e8d8bef9SDimitry Andric   Metadata *getRawRank() const { return getOperand(12); }
getRankConst()1271e8d8bef9SDimitry Andric   ConstantInt *getRankConst() const {
1272e8d8bef9SDimitry Andric     if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
1273e8d8bef9SDimitry Andric       return dyn_cast_or_null<ConstantInt>(MD->getValue());
1274e8d8bef9SDimitry Andric     return nullptr;
1275e8d8bef9SDimitry Andric   }
getRankExp()1276e8d8bef9SDimitry Andric   DIExpression *getRankExp() const {
1277e8d8bef9SDimitry Andric     return dyn_cast_or_null<DIExpression>(getRawRank());
1278e8d8bef9SDimitry Andric   }
12790b57cec5SDimitry Andric 
getRawAnnotations()1280349cc55cSDimitry Andric   Metadata *getRawAnnotations() const { return getOperand(13); }
getAnnotations()1281349cc55cSDimitry Andric   DINodeArray getAnnotations() const {
1282349cc55cSDimitry Andric     return cast_or_null<MDTuple>(getRawAnnotations());
1283349cc55cSDimitry Andric   }
1284349cc55cSDimitry Andric 
12850b57cec5SDimitry Andric   /// Replace operands.
12860b57cec5SDimitry Andric   ///
12870b57cec5SDimitry Andric   /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
12880b57cec5SDimitry Andric   /// this will be RAUW'ed and deleted.  Use a \a TrackingMDRef to keep track
12890b57cec5SDimitry Andric   /// of its movement if necessary.
12900b57cec5SDimitry Andric   /// @{
replaceElements(DINodeArray Elements)12910b57cec5SDimitry Andric   void replaceElements(DINodeArray Elements) {
12920b57cec5SDimitry Andric #ifndef NDEBUG
12930b57cec5SDimitry Andric     for (DINode *Op : getElements())
12940b57cec5SDimitry Andric       assert(is_contained(Elements->operands(), Op) &&
12950b57cec5SDimitry Andric              "Lost a member during member list replacement");
12960b57cec5SDimitry Andric #endif
12970b57cec5SDimitry Andric     replaceOperandWith(4, Elements.get());
12980b57cec5SDimitry Andric   }
12990b57cec5SDimitry Andric 
replaceVTableHolder(DIType * VTableHolder)13000b57cec5SDimitry Andric   void replaceVTableHolder(DIType *VTableHolder) {
13010b57cec5SDimitry Andric     replaceOperandWith(5, VTableHolder);
13020b57cec5SDimitry Andric   }
13030b57cec5SDimitry Andric 
replaceTemplateParams(DITemplateParameterArray TemplateParams)13040b57cec5SDimitry Andric   void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
13050b57cec5SDimitry Andric     replaceOperandWith(6, TemplateParams.get());
13060b57cec5SDimitry Andric   }
13070b57cec5SDimitry Andric   /// @}
13080b57cec5SDimitry Andric 
classof(const Metadata * MD)13090b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
13100b57cec5SDimitry Andric     return MD->getMetadataID() == DICompositeTypeKind;
13110b57cec5SDimitry Andric   }
13120b57cec5SDimitry Andric };
13130b57cec5SDimitry Andric 
13140b57cec5SDimitry Andric /// Type array for a subprogram.
13150b57cec5SDimitry Andric ///
13160b57cec5SDimitry Andric /// TODO: Fold the array of types in directly as operands.
13170b57cec5SDimitry Andric class DISubroutineType : public DIType {
13180b57cec5SDimitry Andric   friend class LLVMContextImpl;
13190b57cec5SDimitry Andric   friend class MDNode;
13200b57cec5SDimitry Andric 
13210b57cec5SDimitry Andric   /// The calling convention used with DW_AT_calling_convention. Actually of
13220b57cec5SDimitry Andric   /// type dwarf::CallingConvention.
13230b57cec5SDimitry Andric   uint8_t CC;
13240b57cec5SDimitry Andric 
13250b57cec5SDimitry Andric   DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags,
132681ad6265SDimitry Andric                    uint8_t CC, ArrayRef<Metadata *> Ops);
13270b57cec5SDimitry Andric   ~DISubroutineType() = default;
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric   static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
13300b57cec5SDimitry Andric                                    uint8_t CC, DITypeRefArray TypeArray,
13310b57cec5SDimitry Andric                                    StorageType Storage,
13320b57cec5SDimitry Andric                                    bool ShouldCreate = true) {
13330b57cec5SDimitry Andric     return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
13340b57cec5SDimitry Andric   }
13350b57cec5SDimitry Andric   static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
13360b57cec5SDimitry Andric                                    uint8_t CC, Metadata *TypeArray,
13370b57cec5SDimitry Andric                                    StorageType Storage,
13380b57cec5SDimitry Andric                                    bool ShouldCreate = true);
13390b57cec5SDimitry Andric 
cloneImpl()13400b57cec5SDimitry Andric   TempDISubroutineType cloneImpl() const {
13410b57cec5SDimitry Andric     return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
13420b57cec5SDimitry Andric   }
13430b57cec5SDimitry Andric 
13440b57cec5SDimitry Andric public:
13450b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DISubroutineType,
13460b57cec5SDimitry Andric                     (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
13470b57cec5SDimitry Andric                     (Flags, CC, TypeArray))
13480b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DISubroutineType,
13490b57cec5SDimitry Andric                     (DIFlags Flags, uint8_t CC, Metadata *TypeArray),
13500b57cec5SDimitry Andric                     (Flags, CC, TypeArray))
13510b57cec5SDimitry Andric 
clone()13520b57cec5SDimitry Andric   TempDISubroutineType clone() const { return cloneImpl(); }
135381ad6265SDimitry Andric   // Returns a new temporary DISubroutineType with updated CC
cloneWithCC(uint8_t CC)135481ad6265SDimitry Andric   TempDISubroutineType cloneWithCC(uint8_t CC) const {
135581ad6265SDimitry Andric     auto NewTy = clone();
135681ad6265SDimitry Andric     NewTy->CC = CC;
135781ad6265SDimitry Andric     return NewTy;
135881ad6265SDimitry Andric   }
13590b57cec5SDimitry Andric 
getCC()13600b57cec5SDimitry Andric   uint8_t getCC() const { return CC; }
13610b57cec5SDimitry Andric 
getTypeArray()13620b57cec5SDimitry Andric   DITypeRefArray getTypeArray() const {
13630b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawTypeArray());
13640b57cec5SDimitry Andric   }
13650b57cec5SDimitry Andric 
getRawTypeArray()13660b57cec5SDimitry Andric   Metadata *getRawTypeArray() const { return getOperand(3); }
13670b57cec5SDimitry Andric 
classof(const Metadata * MD)13680b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
13690b57cec5SDimitry Andric     return MD->getMetadataID() == DISubroutineTypeKind;
13700b57cec5SDimitry Andric   }
13710b57cec5SDimitry Andric };
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric /// Compile unit.
13740b57cec5SDimitry Andric class DICompileUnit : public DIScope {
13750b57cec5SDimitry Andric   friend class LLVMContextImpl;
13760b57cec5SDimitry Andric   friend class MDNode;
13770b57cec5SDimitry Andric 
13780b57cec5SDimitry Andric public:
13790b57cec5SDimitry Andric   enum DebugEmissionKind : unsigned {
13800b57cec5SDimitry Andric     NoDebug = 0,
13810b57cec5SDimitry Andric     FullDebug,
13820b57cec5SDimitry Andric     LineTablesOnly,
13830b57cec5SDimitry Andric     DebugDirectivesOnly,
13840b57cec5SDimitry Andric     LastEmissionKind = DebugDirectivesOnly
13850b57cec5SDimitry Andric   };
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric   enum class DebugNameTableKind : unsigned {
13880b57cec5SDimitry Andric     Default = 0,
13890b57cec5SDimitry Andric     GNU = 1,
13900b57cec5SDimitry Andric     None = 2,
139106c3fb27SDimitry Andric     Apple = 3,
139206c3fb27SDimitry Andric     LastDebugNameTableKind = Apple
13930b57cec5SDimitry Andric   };
13940b57cec5SDimitry Andric 
1395bdd1243dSDimitry Andric   static std::optional<DebugEmissionKind> getEmissionKind(StringRef Str);
13960b57cec5SDimitry Andric   static const char *emissionKindString(DebugEmissionKind EK);
1397bdd1243dSDimitry Andric   static std::optional<DebugNameTableKind> getNameTableKind(StringRef Str);
13980b57cec5SDimitry Andric   static const char *nameTableKindString(DebugNameTableKind PK);
13990b57cec5SDimitry Andric 
14000b57cec5SDimitry Andric private:
14010b57cec5SDimitry Andric   unsigned SourceLanguage;
14020b57cec5SDimitry Andric   unsigned RuntimeVersion;
14030b57cec5SDimitry Andric   uint64_t DWOId;
14045f757f3fSDimitry Andric   unsigned EmissionKind;
14055f757f3fSDimitry Andric   unsigned NameTableKind;
14065f757f3fSDimitry Andric   bool IsOptimized;
14070b57cec5SDimitry Andric   bool SplitDebugInlining;
14080b57cec5SDimitry Andric   bool DebugInfoForProfiling;
14090b57cec5SDimitry Andric   bool RangesBaseAddress;
14100b57cec5SDimitry Andric 
14110b57cec5SDimitry Andric   DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
14120b57cec5SDimitry Andric                 bool IsOptimized, unsigned RuntimeVersion,
14130b57cec5SDimitry Andric                 unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
14140b57cec5SDimitry Andric                 bool DebugInfoForProfiling, unsigned NameTableKind,
141581ad6265SDimitry Andric                 bool RangesBaseAddress, ArrayRef<Metadata *> Ops);
14160b57cec5SDimitry Andric   ~DICompileUnit() = default;
14170b57cec5SDimitry Andric 
14180b57cec5SDimitry Andric   static DICompileUnit *
14190b57cec5SDimitry Andric   getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
14200b57cec5SDimitry Andric           StringRef Producer, bool IsOptimized, StringRef Flags,
14210b57cec5SDimitry Andric           unsigned RuntimeVersion, StringRef SplitDebugFilename,
14220b57cec5SDimitry Andric           unsigned EmissionKind, DICompositeTypeArray EnumTypes,
14230b57cec5SDimitry Andric           DIScopeArray RetainedTypes,
14240b57cec5SDimitry Andric           DIGlobalVariableExpressionArray GlobalVariables,
14250b57cec5SDimitry Andric           DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
14260b57cec5SDimitry Andric           uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
14275ffd83dbSDimitry Andric           unsigned NameTableKind, bool RangesBaseAddress, StringRef SysRoot,
14285ffd83dbSDimitry Andric           StringRef SDK, StorageType Storage, bool ShouldCreate = true) {
14295ffd83dbSDimitry Andric     return getImpl(
14305ffd83dbSDimitry Andric         Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
14315ffd83dbSDimitry Andric         IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
14325ffd83dbSDimitry Andric         getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
14335ffd83dbSDimitry Andric         EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(),
14345ffd83dbSDimitry Andric         ImportedEntities.get(), Macros.get(), DWOId, SplitDebugInlining,
14355ffd83dbSDimitry Andric         DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
14365ffd83dbSDimitry Andric         getCanonicalMDString(Context, SysRoot),
14375ffd83dbSDimitry Andric         getCanonicalMDString(Context, SDK), Storage, ShouldCreate);
14380b57cec5SDimitry Andric   }
14390b57cec5SDimitry Andric   static DICompileUnit *
14400b57cec5SDimitry Andric   getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
14410b57cec5SDimitry Andric           MDString *Producer, bool IsOptimized, MDString *Flags,
14420b57cec5SDimitry Andric           unsigned RuntimeVersion, MDString *SplitDebugFilename,
14430b57cec5SDimitry Andric           unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
14440b57cec5SDimitry Andric           Metadata *GlobalVariables, Metadata *ImportedEntities,
14450b57cec5SDimitry Andric           Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
14460b57cec5SDimitry Andric           bool DebugInfoForProfiling, unsigned NameTableKind,
14475ffd83dbSDimitry Andric           bool RangesBaseAddress, MDString *SysRoot, MDString *SDK,
14485ffd83dbSDimitry Andric           StorageType Storage, bool ShouldCreate = true);
14490b57cec5SDimitry Andric 
cloneImpl()14500b57cec5SDimitry Andric   TempDICompileUnit cloneImpl() const {
14510b57cec5SDimitry Andric     return getTemporary(
14520b57cec5SDimitry Andric         getContext(), getSourceLanguage(), getFile(), getProducer(),
14530b57cec5SDimitry Andric         isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
14540b57cec5SDimitry Andric         getEmissionKind(), getEnumTypes(), getRetainedTypes(),
14550b57cec5SDimitry Andric         getGlobalVariables(), getImportedEntities(), getMacros(), DWOId,
14560b57cec5SDimitry Andric         getSplitDebugInlining(), getDebugInfoForProfiling(), getNameTableKind(),
14575ffd83dbSDimitry Andric         getRangesBaseAddress(), getSysRoot(), getSDK());
14580b57cec5SDimitry Andric   }
14590b57cec5SDimitry Andric 
14600b57cec5SDimitry Andric public:
14610b57cec5SDimitry Andric   static void get() = delete;
14620b57cec5SDimitry Andric   static void getIfExists() = delete;
14630b57cec5SDimitry Andric 
14640b57cec5SDimitry Andric   DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
14650b57cec5SDimitry Andric       DICompileUnit,
14660b57cec5SDimitry Andric       (unsigned SourceLanguage, DIFile *File, StringRef Producer,
14670b57cec5SDimitry Andric        bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
14680b57cec5SDimitry Andric        StringRef SplitDebugFilename, DebugEmissionKind EmissionKind,
14690b57cec5SDimitry Andric        DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
14700b57cec5SDimitry Andric        DIGlobalVariableExpressionArray GlobalVariables,
14710b57cec5SDimitry Andric        DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
14720b57cec5SDimitry Andric        uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
14735ffd83dbSDimitry Andric        DebugNameTableKind NameTableKind, bool RangesBaseAddress,
14745ffd83dbSDimitry Andric        StringRef SysRoot, StringRef SDK),
14750b57cec5SDimitry Andric       (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
14760b57cec5SDimitry Andric        SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
14770b57cec5SDimitry Andric        GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
14785ffd83dbSDimitry Andric        DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress,
14795ffd83dbSDimitry Andric        SysRoot, SDK))
14800b57cec5SDimitry Andric   DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
14810b57cec5SDimitry Andric       DICompileUnit,
14820b57cec5SDimitry Andric       (unsigned SourceLanguage, Metadata *File, MDString *Producer,
14830b57cec5SDimitry Andric        bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
14840b57cec5SDimitry Andric        MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
14850b57cec5SDimitry Andric        Metadata *RetainedTypes, Metadata *GlobalVariables,
14860b57cec5SDimitry Andric        Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
14870b57cec5SDimitry Andric        bool SplitDebugInlining, bool DebugInfoForProfiling,
14885ffd83dbSDimitry Andric        unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
14895ffd83dbSDimitry Andric        MDString *SDK),
14900b57cec5SDimitry Andric       (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
14910b57cec5SDimitry Andric        SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
14920b57cec5SDimitry Andric        GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
14935ffd83dbSDimitry Andric        DebugInfoForProfiling, NameTableKind, RangesBaseAddress, SysRoot, SDK))
14940b57cec5SDimitry Andric 
clone()14950b57cec5SDimitry Andric   TempDICompileUnit clone() const { return cloneImpl(); }
14960b57cec5SDimitry Andric 
getSourceLanguage()14970b57cec5SDimitry Andric   unsigned getSourceLanguage() const { return SourceLanguage; }
isOptimized()14980b57cec5SDimitry Andric   bool isOptimized() const { return IsOptimized; }
getRuntimeVersion()14990b57cec5SDimitry Andric   unsigned getRuntimeVersion() const { return RuntimeVersion; }
getEmissionKind()15000b57cec5SDimitry Andric   DebugEmissionKind getEmissionKind() const {
15010b57cec5SDimitry Andric     return (DebugEmissionKind)EmissionKind;
15020b57cec5SDimitry Andric   }
isDebugDirectivesOnly()15030b57cec5SDimitry Andric   bool isDebugDirectivesOnly() const {
15040b57cec5SDimitry Andric     return EmissionKind == DebugDirectivesOnly;
15050b57cec5SDimitry Andric   }
getDebugInfoForProfiling()15060b57cec5SDimitry Andric   bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
getNameTableKind()15070b57cec5SDimitry Andric   DebugNameTableKind getNameTableKind() const {
15080b57cec5SDimitry Andric     return (DebugNameTableKind)NameTableKind;
15090b57cec5SDimitry Andric   }
getRangesBaseAddress()15105ffd83dbSDimitry Andric   bool getRangesBaseAddress() const { return RangesBaseAddress; }
getProducer()15115ffd83dbSDimitry Andric   StringRef getProducer() const { return getStringOperand(1); }
getFlags()15125ffd83dbSDimitry Andric   StringRef getFlags() const { return getStringOperand(2); }
getSplitDebugFilename()15135ffd83dbSDimitry Andric   StringRef getSplitDebugFilename() const { return getStringOperand(3); }
getEnumTypes()15140b57cec5SDimitry Andric   DICompositeTypeArray getEnumTypes() const {
15150b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawEnumTypes());
15160b57cec5SDimitry Andric   }
getRetainedTypes()15170b57cec5SDimitry Andric   DIScopeArray getRetainedTypes() const {
15180b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawRetainedTypes());
15190b57cec5SDimitry Andric   }
getGlobalVariables()15200b57cec5SDimitry Andric   DIGlobalVariableExpressionArray getGlobalVariables() const {
15210b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawGlobalVariables());
15220b57cec5SDimitry Andric   }
getImportedEntities()15230b57cec5SDimitry Andric   DIImportedEntityArray getImportedEntities() const {
15240b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawImportedEntities());
15250b57cec5SDimitry Andric   }
getMacros()15260b57cec5SDimitry Andric   DIMacroNodeArray getMacros() const {
15270b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawMacros());
15280b57cec5SDimitry Andric   }
getDWOId()15290b57cec5SDimitry Andric   uint64_t getDWOId() const { return DWOId; }
setDWOId(uint64_t DwoId)15300b57cec5SDimitry Andric   void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
getSplitDebugInlining()15310b57cec5SDimitry Andric   bool getSplitDebugInlining() const { return SplitDebugInlining; }
setSplitDebugInlining(bool SplitDebugInlining)15320b57cec5SDimitry Andric   void setSplitDebugInlining(bool SplitDebugInlining) {
15330b57cec5SDimitry Andric     this->SplitDebugInlining = SplitDebugInlining;
15340b57cec5SDimitry Andric   }
getSysRoot()15355ffd83dbSDimitry Andric   StringRef getSysRoot() const { return getStringOperand(9); }
getSDK()15365ffd83dbSDimitry Andric   StringRef getSDK() const { return getStringOperand(10); }
15370b57cec5SDimitry Andric 
getRawProducer()15380b57cec5SDimitry Andric   MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
getRawFlags()15390b57cec5SDimitry Andric   MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
getRawSplitDebugFilename()15400b57cec5SDimitry Andric   MDString *getRawSplitDebugFilename() const {
15410b57cec5SDimitry Andric     return getOperandAs<MDString>(3);
15420b57cec5SDimitry Andric   }
getRawEnumTypes()15430b57cec5SDimitry Andric   Metadata *getRawEnumTypes() const { return getOperand(4); }
getRawRetainedTypes()15440b57cec5SDimitry Andric   Metadata *getRawRetainedTypes() const { return getOperand(5); }
getRawGlobalVariables()15450b57cec5SDimitry Andric   Metadata *getRawGlobalVariables() const { return getOperand(6); }
getRawImportedEntities()15460b57cec5SDimitry Andric   Metadata *getRawImportedEntities() const { return getOperand(7); }
getRawMacros()15470b57cec5SDimitry Andric   Metadata *getRawMacros() const { return getOperand(8); }
getRawSysRoot()15485ffd83dbSDimitry Andric   MDString *getRawSysRoot() const { return getOperandAs<MDString>(9); }
getRawSDK()15495ffd83dbSDimitry Andric   MDString *getRawSDK() const { return getOperandAs<MDString>(10); }
15500b57cec5SDimitry Andric 
15510b57cec5SDimitry Andric   /// Replace arrays.
15520b57cec5SDimitry Andric   ///
15530b57cec5SDimitry Andric   /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
15540b57cec5SDimitry Andric   /// deleted on a uniquing collision.  In practice, uniquing collisions on \a
15550b57cec5SDimitry Andric   /// DICompileUnit should be fairly rare.
15560b57cec5SDimitry Andric   /// @{
replaceEnumTypes(DICompositeTypeArray N)15570b57cec5SDimitry Andric   void replaceEnumTypes(DICompositeTypeArray N) {
15580b57cec5SDimitry Andric     replaceOperandWith(4, N.get());
15590b57cec5SDimitry Andric   }
replaceRetainedTypes(DITypeArray N)1560349cc55cSDimitry Andric   void replaceRetainedTypes(DITypeArray N) { replaceOperandWith(5, N.get()); }
replaceGlobalVariables(DIGlobalVariableExpressionArray N)15610b57cec5SDimitry Andric   void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
15620b57cec5SDimitry Andric     replaceOperandWith(6, N.get());
15630b57cec5SDimitry Andric   }
replaceImportedEntities(DIImportedEntityArray N)15640b57cec5SDimitry Andric   void replaceImportedEntities(DIImportedEntityArray N) {
15650b57cec5SDimitry Andric     replaceOperandWith(7, N.get());
15660b57cec5SDimitry Andric   }
replaceMacros(DIMacroNodeArray N)15670b57cec5SDimitry Andric   void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
15680b57cec5SDimitry Andric   /// @}
15690b57cec5SDimitry Andric 
classof(const Metadata * MD)15700b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
15710b57cec5SDimitry Andric     return MD->getMetadataID() == DICompileUnitKind;
15720b57cec5SDimitry Andric   }
15730b57cec5SDimitry Andric };
15740b57cec5SDimitry Andric 
15750b57cec5SDimitry Andric /// A scope for locals.
15760b57cec5SDimitry Andric ///
15770b57cec5SDimitry Andric /// A legal scope for lexical blocks, local variables, and debug info
15780b57cec5SDimitry Andric /// locations.  Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
15790b57cec5SDimitry Andric /// DILexicalBlockFile.
15800b57cec5SDimitry Andric class DILocalScope : public DIScope {
15810b57cec5SDimitry Andric protected:
DILocalScope(LLVMContext & C,unsigned ID,StorageType Storage,unsigned Tag,ArrayRef<Metadata * > Ops)15820b57cec5SDimitry Andric   DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
15830b57cec5SDimitry Andric                ArrayRef<Metadata *> Ops)
15840b57cec5SDimitry Andric       : DIScope(C, ID, Storage, Tag, Ops) {}
15850b57cec5SDimitry Andric   ~DILocalScope() = default;
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric public:
15880b57cec5SDimitry Andric   /// Get the subprogram for this scope.
15890b57cec5SDimitry Andric   ///
15900b57cec5SDimitry Andric   /// Return this if it's an \a DISubprogram; otherwise, look up the scope
15910b57cec5SDimitry Andric   /// chain.
15920b57cec5SDimitry Andric   DISubprogram *getSubprogram() const;
15930b57cec5SDimitry Andric 
1594bdd1243dSDimitry Andric   /// Traverses the scope chain rooted at RootScope until it hits a Subprogram,
1595bdd1243dSDimitry Andric   /// recreating the chain with "NewSP" instead.
1596bdd1243dSDimitry Andric   static DILocalScope *
1597bdd1243dSDimitry Andric   cloneScopeForSubprogram(DILocalScope &RootScope, DISubprogram &NewSP,
1598bdd1243dSDimitry Andric                           LLVMContext &Ctx,
1599bdd1243dSDimitry Andric                           DenseMap<const MDNode *, MDNode *> &Cache);
1600bdd1243dSDimitry Andric 
16010b57cec5SDimitry Andric   /// Get the first non DILexicalBlockFile scope of this scope.
16020b57cec5SDimitry Andric   ///
16030b57cec5SDimitry Andric   /// Return this if it's not a \a DILexicalBlockFIle; otherwise, look up the
16040b57cec5SDimitry Andric   /// scope chain.
16050b57cec5SDimitry Andric   DILocalScope *getNonLexicalBlockFileScope() const;
16060b57cec5SDimitry Andric 
classof(const Metadata * MD)16070b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
16080b57cec5SDimitry Andric     return MD->getMetadataID() == DISubprogramKind ||
16090b57cec5SDimitry Andric            MD->getMetadataID() == DILexicalBlockKind ||
16100b57cec5SDimitry Andric            MD->getMetadataID() == DILexicalBlockFileKind;
16110b57cec5SDimitry Andric   }
16120b57cec5SDimitry Andric };
16130b57cec5SDimitry Andric 
16140b57cec5SDimitry Andric /// Subprogram description.
16150b57cec5SDimitry Andric class DISubprogram : public DILocalScope {
16160b57cec5SDimitry Andric   friend class LLVMContextImpl;
16170b57cec5SDimitry Andric   friend class MDNode;
16180b57cec5SDimitry Andric 
16190b57cec5SDimitry Andric   unsigned Line;
16200b57cec5SDimitry Andric   unsigned ScopeLine;
16210b57cec5SDimitry Andric   unsigned VirtualIndex;
16220b57cec5SDimitry Andric 
16230b57cec5SDimitry Andric   /// In the MS ABI, the implicit 'this' parameter is adjusted in the prologue
16240b57cec5SDimitry Andric   /// of method overrides from secondary bases by this amount. It may be
16250b57cec5SDimitry Andric   /// negative.
16260b57cec5SDimitry Andric   int ThisAdjustment;
16270b57cec5SDimitry Andric 
16280b57cec5SDimitry Andric public:
16290b57cec5SDimitry Andric   /// Debug info subprogram flags.
16300b57cec5SDimitry Andric   enum DISPFlags : uint32_t {
16310b57cec5SDimitry Andric #define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID,
16320b57cec5SDimitry Andric #define DISP_FLAG_LARGEST_NEEDED
16330b57cec5SDimitry Andric #include "llvm/IR/DebugInfoFlags.def"
16340b57cec5SDimitry Andric     SPFlagNonvirtual = SPFlagZero,
16350b57cec5SDimitry Andric     SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
16360b57cec5SDimitry Andric     LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
16370b57cec5SDimitry Andric   };
16380b57cec5SDimitry Andric 
16390b57cec5SDimitry Andric   static DISPFlags getFlag(StringRef Flag);
16400b57cec5SDimitry Andric   static StringRef getFlagString(DISPFlags Flag);
16410b57cec5SDimitry Andric 
16420b57cec5SDimitry Andric   /// Split up a flags bitfield for easier printing.
16430b57cec5SDimitry Andric   ///
16440b57cec5SDimitry Andric   /// Split \c Flags into \c SplitFlags, a vector of its components.  Returns
16450b57cec5SDimitry Andric   /// any remaining (unrecognized) bits.
16460b57cec5SDimitry Andric   static DISPFlags splitFlags(DISPFlags Flags,
16470b57cec5SDimitry Andric                               SmallVectorImpl<DISPFlags> &SplitFlags);
16480b57cec5SDimitry Andric 
16490b57cec5SDimitry Andric   // Helper for converting old bitfields to new flags word.
16500b57cec5SDimitry Andric   static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
16510b57cec5SDimitry Andric                              bool IsOptimized,
16520b57cec5SDimitry Andric                              unsigned Virtuality = SPFlagNonvirtual,
165381ad6265SDimitry Andric                              bool IsMainSubprogram = false);
16540b57cec5SDimitry Andric 
16550b57cec5SDimitry Andric private:
16560b57cec5SDimitry Andric   DIFlags Flags;
16570b57cec5SDimitry Andric   DISPFlags SPFlags;
16580b57cec5SDimitry Andric 
16590b57cec5SDimitry Andric   DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
16600b57cec5SDimitry Andric                unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment,
166181ad6265SDimitry Andric                DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops);
16620b57cec5SDimitry Andric   ~DISubprogram() = default;
16630b57cec5SDimitry Andric 
16640b57cec5SDimitry Andric   static DISubprogram *
16650b57cec5SDimitry Andric   getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
16660b57cec5SDimitry Andric           StringRef LinkageName, DIFile *File, unsigned Line,
16670b57cec5SDimitry Andric           DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType,
16680b57cec5SDimitry Andric           unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
16690b57cec5SDimitry Andric           DISPFlags SPFlags, DICompileUnit *Unit,
16700b57cec5SDimitry Andric           DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
16710b57cec5SDimitry Andric           DINodeArray RetainedNodes, DITypeArray ThrownTypes,
167281ad6265SDimitry Andric           DINodeArray Annotations, StringRef TargetFuncName,
167381ad6265SDimitry Andric           StorageType Storage, bool ShouldCreate = true) {
16740b57cec5SDimitry Andric     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
16750b57cec5SDimitry Andric                    getCanonicalMDString(Context, LinkageName), File, Line, Type,
16760b57cec5SDimitry Andric                    ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
16770b57cec5SDimitry Andric                    Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
1678349cc55cSDimitry Andric                    RetainedNodes.get(), ThrownTypes.get(), Annotations.get(),
167981ad6265SDimitry Andric                    getCanonicalMDString(Context, TargetFuncName),
1680349cc55cSDimitry Andric                    Storage, ShouldCreate);
16810b57cec5SDimitry Andric   }
1682349cc55cSDimitry Andric   static DISubprogram *
1683349cc55cSDimitry Andric   getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1684349cc55cSDimitry Andric           MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
1685349cc55cSDimitry Andric           unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
1686349cc55cSDimitry Andric           int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
16870b57cec5SDimitry Andric           Metadata *TemplateParams, Metadata *Declaration,
1688349cc55cSDimitry Andric           Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations,
168981ad6265SDimitry Andric           MDString *TargetFuncName, StorageType Storage,
169081ad6265SDimitry Andric           bool ShouldCreate = true);
16910b57cec5SDimitry Andric 
cloneImpl()16920b57cec5SDimitry Andric   TempDISubprogram cloneImpl() const {
16930b57cec5SDimitry Andric     return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
16940b57cec5SDimitry Andric                         getFile(), getLine(), getType(), getScopeLine(),
16950b57cec5SDimitry Andric                         getContainingType(), getVirtualIndex(),
16960b57cec5SDimitry Andric                         getThisAdjustment(), getFlags(), getSPFlags(),
16970b57cec5SDimitry Andric                         getUnit(), getTemplateParams(), getDeclaration(),
169881ad6265SDimitry Andric                         getRetainedNodes(), getThrownTypes(), getAnnotations(),
169981ad6265SDimitry Andric                         getTargetFuncName());
17000b57cec5SDimitry Andric   }
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric public:
17030b57cec5SDimitry Andric   DEFINE_MDNODE_GET(
17040b57cec5SDimitry Andric       DISubprogram,
17050b57cec5SDimitry Andric       (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File,
17060b57cec5SDimitry Andric        unsigned Line, DISubroutineType *Type, unsigned ScopeLine,
17070b57cec5SDimitry Andric        DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
17080b57cec5SDimitry Andric        DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit,
17090b57cec5SDimitry Andric        DITemplateParameterArray TemplateParams = nullptr,
17100b57cec5SDimitry Andric        DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
171181ad6265SDimitry Andric        DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr,
171281ad6265SDimitry Andric        StringRef TargetFuncName = ""),
17130b57cec5SDimitry Andric       (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
17140b57cec5SDimitry Andric        VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
171581ad6265SDimitry Andric        Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName))
17160b57cec5SDimitry Andric 
17170b57cec5SDimitry Andric   DEFINE_MDNODE_GET(
17180b57cec5SDimitry Andric       DISubprogram,
17190b57cec5SDimitry Andric       (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
17200b57cec5SDimitry Andric        unsigned Line, Metadata *Type, unsigned ScopeLine,
17210b57cec5SDimitry Andric        Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
17220b57cec5SDimitry Andric        DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
17230b57cec5SDimitry Andric        Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr,
1724349cc55cSDimitry Andric        Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr,
172581ad6265SDimitry Andric        Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr),
17260b57cec5SDimitry Andric       (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
17270b57cec5SDimitry Andric        VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
172881ad6265SDimitry Andric        Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName))
17290b57cec5SDimitry Andric 
clone()17300b57cec5SDimitry Andric   TempDISubprogram clone() const { return cloneImpl(); }
17310b57cec5SDimitry Andric 
17320b57cec5SDimitry Andric   /// Returns a new temporary DISubprogram with updated Flags
cloneWithFlags(DIFlags NewFlags)17330b57cec5SDimitry Andric   TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
17340b57cec5SDimitry Andric     auto NewSP = clone();
17350b57cec5SDimitry Andric     NewSP->Flags = NewFlags;
17360b57cec5SDimitry Andric     return NewSP;
17370b57cec5SDimitry Andric   }
17380b57cec5SDimitry Andric 
17390b57cec5SDimitry Andric public:
getLine()17400b57cec5SDimitry Andric   unsigned getLine() const { return Line; }
getVirtuality()17410b57cec5SDimitry Andric   unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
getVirtualIndex()17420b57cec5SDimitry Andric   unsigned getVirtualIndex() const { return VirtualIndex; }
getThisAdjustment()17430b57cec5SDimitry Andric   int getThisAdjustment() const { return ThisAdjustment; }
getScopeLine()17440b57cec5SDimitry Andric   unsigned getScopeLine() const { return ScopeLine; }
setScopeLine(unsigned L)1745349cc55cSDimitry Andric   void setScopeLine(unsigned L) {
1746349cc55cSDimitry Andric     assert(isDistinct());
1747349cc55cSDimitry Andric     ScopeLine = L;
1748349cc55cSDimitry Andric   }
getFlags()17490b57cec5SDimitry Andric   DIFlags getFlags() const { return Flags; }
getSPFlags()17500b57cec5SDimitry Andric   DISPFlags getSPFlags() const { return SPFlags; }
isLocalToUnit()17510b57cec5SDimitry Andric   bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; }
isDefinition()17520b57cec5SDimitry Andric   bool isDefinition() const { return getSPFlags() & SPFlagDefinition; }
isOptimized()17530b57cec5SDimitry Andric   bool isOptimized() const { return getSPFlags() & SPFlagOptimized; }
isMainSubprogram()17540b57cec5SDimitry Andric   bool isMainSubprogram() const { return getSPFlags() & SPFlagMainSubprogram; }
17550b57cec5SDimitry Andric 
isArtificial()17560b57cec5SDimitry Andric   bool isArtificial() const { return getFlags() & FlagArtificial; }
isPrivate()17570b57cec5SDimitry Andric   bool isPrivate() const {
17580b57cec5SDimitry Andric     return (getFlags() & FlagAccessibility) == FlagPrivate;
17590b57cec5SDimitry Andric   }
isProtected()17600b57cec5SDimitry Andric   bool isProtected() const {
17610b57cec5SDimitry Andric     return (getFlags() & FlagAccessibility) == FlagProtected;
17620b57cec5SDimitry Andric   }
isPublic()17630b57cec5SDimitry Andric   bool isPublic() const {
17640b57cec5SDimitry Andric     return (getFlags() & FlagAccessibility) == FlagPublic;
17650b57cec5SDimitry Andric   }
isExplicit()17660b57cec5SDimitry Andric   bool isExplicit() const { return getFlags() & FlagExplicit; }
isPrototyped()17670b57cec5SDimitry Andric   bool isPrototyped() const { return getFlags() & FlagPrototyped; }
areAllCallsDescribed()17680b57cec5SDimitry Andric   bool areAllCallsDescribed() const {
17690b57cec5SDimitry Andric     return getFlags() & FlagAllCallsDescribed;
17700b57cec5SDimitry Andric   }
isPure()17710b57cec5SDimitry Andric   bool isPure() const { return getSPFlags() & SPFlagPure; }
isElemental()17720b57cec5SDimitry Andric   bool isElemental() const { return getSPFlags() & SPFlagElemental; }
isRecursive()17730b57cec5SDimitry Andric   bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
isObjCDirect()1774480093f4SDimitry Andric   bool isObjCDirect() const { return getSPFlags() & SPFlagObjCDirect; }
1775480093f4SDimitry Andric 
1776480093f4SDimitry Andric   /// Check if this is deleted member function.
1777480093f4SDimitry Andric   ///
1778480093f4SDimitry Andric   /// Return true if this subprogram is a C++11 special
1779480093f4SDimitry Andric   /// member function declared deleted.
isDeleted()1780480093f4SDimitry Andric   bool isDeleted() const { return getSPFlags() & SPFlagDeleted; }
17810b57cec5SDimitry Andric 
17820b57cec5SDimitry Andric   /// Check if this is reference-qualified.
17830b57cec5SDimitry Andric   ///
17840b57cec5SDimitry Andric   /// Return true if this subprogram is a C++11 reference-qualified non-static
17850b57cec5SDimitry Andric   /// member function (void foo() &).
isLValueReference()17860b57cec5SDimitry Andric   bool isLValueReference() const { return getFlags() & FlagLValueReference; }
17870b57cec5SDimitry Andric 
17880b57cec5SDimitry Andric   /// Check if this is rvalue-reference-qualified.
17890b57cec5SDimitry Andric   ///
17900b57cec5SDimitry Andric   /// Return true if this subprogram is a C++11 rvalue-reference-qualified
17910b57cec5SDimitry Andric   /// non-static member function (void foo() &&).
isRValueReference()17920b57cec5SDimitry Andric   bool isRValueReference() const { return getFlags() & FlagRValueReference; }
17930b57cec5SDimitry Andric 
17940b57cec5SDimitry Andric   /// Check if this is marked as noreturn.
17950b57cec5SDimitry Andric   ///
17960b57cec5SDimitry Andric   /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
isNoReturn()17970b57cec5SDimitry Andric   bool isNoReturn() const { return getFlags() & FlagNoReturn; }
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric   // Check if this routine is a compiler-generated thunk.
18000b57cec5SDimitry Andric   //
18010b57cec5SDimitry Andric   // Returns true if this subprogram is a thunk generated by the compiler.
isThunk()18020b57cec5SDimitry Andric   bool isThunk() const { return getFlags() & FlagThunk; }
18030b57cec5SDimitry Andric 
getScope()18040b57cec5SDimitry Andric   DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
18050b57cec5SDimitry Andric 
getName()18060b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(2); }
getLinkageName()18070b57cec5SDimitry Andric   StringRef getLinkageName() const { return getStringOperand(3); }
1808fe6060f1SDimitry Andric   /// Only used by clients of CloneFunction, and only right after the cloning.
replaceLinkageName(MDString * LN)1809fe6060f1SDimitry Andric   void replaceLinkageName(MDString *LN) { replaceOperandWith(3, LN); }
18100b57cec5SDimitry Andric 
getType()18110b57cec5SDimitry Andric   DISubroutineType *getType() const {
18120b57cec5SDimitry Andric     return cast_or_null<DISubroutineType>(getRawType());
18130b57cec5SDimitry Andric   }
getContainingType()18140b57cec5SDimitry Andric   DIType *getContainingType() const {
18150b57cec5SDimitry Andric     return cast_or_null<DIType>(getRawContainingType());
18160b57cec5SDimitry Andric   }
replaceType(DISubroutineType * Ty)181781ad6265SDimitry Andric   void replaceType(DISubroutineType *Ty) {
181881ad6265SDimitry Andric     assert(isDistinct() && "Only distinct nodes can mutate");
181981ad6265SDimitry Andric     replaceOperandWith(4, Ty);
182081ad6265SDimitry Andric   }
18210b57cec5SDimitry Andric 
getUnit()18220b57cec5SDimitry Andric   DICompileUnit *getUnit() const {
18230b57cec5SDimitry Andric     return cast_or_null<DICompileUnit>(getRawUnit());
18240b57cec5SDimitry Andric   }
replaceUnit(DICompileUnit * CU)18250b57cec5SDimitry Andric   void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
getTemplateParams()18260b57cec5SDimitry Andric   DITemplateParameterArray getTemplateParams() const {
18270b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawTemplateParams());
18280b57cec5SDimitry Andric   }
getDeclaration()18290b57cec5SDimitry Andric   DISubprogram *getDeclaration() const {
18300b57cec5SDimitry Andric     return cast_or_null<DISubprogram>(getRawDeclaration());
18310b57cec5SDimitry Andric   }
replaceDeclaration(DISubprogram * Decl)18325f757f3fSDimitry Andric   void replaceDeclaration(DISubprogram *Decl) { replaceOperandWith(6, Decl); }
getRetainedNodes()18330b57cec5SDimitry Andric   DINodeArray getRetainedNodes() const {
18340b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawRetainedNodes());
18350b57cec5SDimitry Andric   }
getThrownTypes()18360b57cec5SDimitry Andric   DITypeArray getThrownTypes() const {
18370b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawThrownTypes());
18380b57cec5SDimitry Andric   }
getAnnotations()1839349cc55cSDimitry Andric   DINodeArray getAnnotations() const {
1840349cc55cSDimitry Andric     return cast_or_null<MDTuple>(getRawAnnotations());
1841349cc55cSDimitry Andric   }
getTargetFuncName()184281ad6265SDimitry Andric   StringRef getTargetFuncName() const {
184381ad6265SDimitry Andric     return (getRawTargetFuncName()) ? getStringOperand(12) : StringRef();
184481ad6265SDimitry Andric   }
18450b57cec5SDimitry Andric 
getRawScope()18460b57cec5SDimitry Andric   Metadata *getRawScope() const { return getOperand(1); }
getRawName()18470b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(2); }
getRawLinkageName()18480b57cec5SDimitry Andric   MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
getRawType()18490b57cec5SDimitry Andric   Metadata *getRawType() const { return getOperand(4); }
getRawUnit()18500b57cec5SDimitry Andric   Metadata *getRawUnit() const { return getOperand(5); }
getRawDeclaration()18510b57cec5SDimitry Andric   Metadata *getRawDeclaration() const { return getOperand(6); }
getRawRetainedNodes()18520b57cec5SDimitry Andric   Metadata *getRawRetainedNodes() const { return getOperand(7); }
getRawContainingType()18530b57cec5SDimitry Andric   Metadata *getRawContainingType() const {
18540b57cec5SDimitry Andric     return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
18550b57cec5SDimitry Andric   }
getRawTemplateParams()18560b57cec5SDimitry Andric   Metadata *getRawTemplateParams() const {
18570b57cec5SDimitry Andric     return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
18580b57cec5SDimitry Andric   }
getRawThrownTypes()18590b57cec5SDimitry Andric   Metadata *getRawThrownTypes() const {
18600b57cec5SDimitry Andric     return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
18610b57cec5SDimitry Andric   }
getRawAnnotations()1862349cc55cSDimitry Andric   Metadata *getRawAnnotations() const {
1863349cc55cSDimitry Andric     return getNumOperands() > 11 ? getOperandAs<Metadata>(11) : nullptr;
1864349cc55cSDimitry Andric   }
getRawTargetFuncName()186581ad6265SDimitry Andric   MDString *getRawTargetFuncName() const {
186681ad6265SDimitry Andric     return getNumOperands() > 12 ? getOperandAs<MDString>(12) : nullptr;
186781ad6265SDimitry Andric   }
18680b57cec5SDimitry Andric 
replaceRawLinkageName(MDString * LinkageName)1869e8d8bef9SDimitry Andric   void replaceRawLinkageName(MDString *LinkageName) {
1870e8d8bef9SDimitry Andric     replaceOperandWith(3, LinkageName);
1871e8d8bef9SDimitry Andric   }
replaceRetainedNodes(DINodeArray N)187206c3fb27SDimitry Andric   void replaceRetainedNodes(DINodeArray N) {
187306c3fb27SDimitry Andric     replaceOperandWith(7, N.get());
187406c3fb27SDimitry Andric   }
1875e8d8bef9SDimitry Andric 
18760b57cec5SDimitry Andric   /// Check if this subprogram describes the given function.
18770b57cec5SDimitry Andric   ///
18780b57cec5SDimitry Andric   /// FIXME: Should this be looking through bitcasts?
18790b57cec5SDimitry Andric   bool describes(const Function *F) const;
18800b57cec5SDimitry Andric 
classof(const Metadata * MD)18810b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
18820b57cec5SDimitry Andric     return MD->getMetadataID() == DISubprogramKind;
18830b57cec5SDimitry Andric   }
18840b57cec5SDimitry Andric };
18850b57cec5SDimitry Andric 
188606c3fb27SDimitry Andric /// Debug location.
188706c3fb27SDimitry Andric ///
188806c3fb27SDimitry Andric /// A debug location in source code, used for debug info and otherwise.
18895f757f3fSDimitry Andric ///
18905f757f3fSDimitry Andric /// Uses the SubclassData1, SubclassData16 and SubclassData32
18915f757f3fSDimitry Andric /// Metadata slots.
18925f757f3fSDimitry Andric 
189306c3fb27SDimitry Andric class DILocation : public MDNode {
189406c3fb27SDimitry Andric   friend class LLVMContextImpl;
189506c3fb27SDimitry Andric   friend class MDNode;
189606c3fb27SDimitry Andric 
189706c3fb27SDimitry Andric   DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
189806c3fb27SDimitry Andric              unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode);
~DILocation()189906c3fb27SDimitry Andric   ~DILocation() { dropAllReferences(); }
190006c3fb27SDimitry Andric 
190106c3fb27SDimitry Andric   static DILocation *getImpl(LLVMContext &Context, unsigned Line,
190206c3fb27SDimitry Andric                              unsigned Column, Metadata *Scope,
190306c3fb27SDimitry Andric                              Metadata *InlinedAt, bool ImplicitCode,
190406c3fb27SDimitry Andric                              StorageType Storage, bool ShouldCreate = true);
190506c3fb27SDimitry Andric   static DILocation *getImpl(LLVMContext &Context, unsigned Line,
190606c3fb27SDimitry Andric                              unsigned Column, DILocalScope *Scope,
190706c3fb27SDimitry Andric                              DILocation *InlinedAt, bool ImplicitCode,
190806c3fb27SDimitry Andric                              StorageType Storage, bool ShouldCreate = true) {
190906c3fb27SDimitry Andric     return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
191006c3fb27SDimitry Andric                    static_cast<Metadata *>(InlinedAt), ImplicitCode, Storage,
191106c3fb27SDimitry Andric                    ShouldCreate);
191206c3fb27SDimitry Andric   }
191306c3fb27SDimitry Andric 
cloneImpl()191406c3fb27SDimitry Andric   TempDILocation cloneImpl() const {
191506c3fb27SDimitry Andric     // Get the raw scope/inlinedAt since it is possible to invoke this on
191606c3fb27SDimitry Andric     // a DILocation containing temporary metadata.
191706c3fb27SDimitry Andric     return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
191806c3fb27SDimitry Andric                         getRawInlinedAt(), isImplicitCode());
191906c3fb27SDimitry Andric   }
192006c3fb27SDimitry Andric 
192106c3fb27SDimitry Andric public:
192206c3fb27SDimitry Andric   // Disallow replacing operands.
192306c3fb27SDimitry Andric   void replaceOperandWith(unsigned I, Metadata *New) = delete;
192406c3fb27SDimitry Andric 
192506c3fb27SDimitry Andric   DEFINE_MDNODE_GET(DILocation,
192606c3fb27SDimitry Andric                     (unsigned Line, unsigned Column, Metadata *Scope,
192706c3fb27SDimitry Andric                      Metadata *InlinedAt = nullptr, bool ImplicitCode = false),
192806c3fb27SDimitry Andric                     (Line, Column, Scope, InlinedAt, ImplicitCode))
192906c3fb27SDimitry Andric   DEFINE_MDNODE_GET(DILocation,
193006c3fb27SDimitry Andric                     (unsigned Line, unsigned Column, DILocalScope *Scope,
193106c3fb27SDimitry Andric                      DILocation *InlinedAt = nullptr,
193206c3fb27SDimitry Andric                      bool ImplicitCode = false),
193306c3fb27SDimitry Andric                     (Line, Column, Scope, InlinedAt, ImplicitCode))
193406c3fb27SDimitry Andric 
193506c3fb27SDimitry Andric   /// Return a (temporary) clone of this.
clone()193606c3fb27SDimitry Andric   TempDILocation clone() const { return cloneImpl(); }
193706c3fb27SDimitry Andric 
getLine()193806c3fb27SDimitry Andric   unsigned getLine() const { return SubclassData32; }
getColumn()193906c3fb27SDimitry Andric   unsigned getColumn() const { return SubclassData16; }
getScope()194006c3fb27SDimitry Andric   DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
194106c3fb27SDimitry Andric 
194206c3fb27SDimitry Andric   /// Return the linkage name of Subprogram. If the linkage name is empty,
194306c3fb27SDimitry Andric   /// return scope name (the demangled name).
getSubprogramLinkageName()194406c3fb27SDimitry Andric   StringRef getSubprogramLinkageName() const {
194506c3fb27SDimitry Andric     DISubprogram *SP = getScope()->getSubprogram();
194606c3fb27SDimitry Andric     if (!SP)
194706c3fb27SDimitry Andric       return "";
194806c3fb27SDimitry Andric     auto Name = SP->getLinkageName();
194906c3fb27SDimitry Andric     if (!Name.empty())
195006c3fb27SDimitry Andric       return Name;
195106c3fb27SDimitry Andric     return SP->getName();
195206c3fb27SDimitry Andric   }
195306c3fb27SDimitry Andric 
getInlinedAt()195406c3fb27SDimitry Andric   DILocation *getInlinedAt() const {
195506c3fb27SDimitry Andric     return cast_or_null<DILocation>(getRawInlinedAt());
195606c3fb27SDimitry Andric   }
195706c3fb27SDimitry Andric 
195806c3fb27SDimitry Andric   /// Check if the location corresponds to an implicit code.
195906c3fb27SDimitry Andric   /// When the ImplicitCode flag is true, it means that the Instruction
196006c3fb27SDimitry Andric   /// with this DILocation has been added by the front-end but it hasn't been
196106c3fb27SDimitry Andric   /// written explicitly by the user (e.g. cleanup stuff in C++ put on a closing
196206c3fb27SDimitry Andric   /// bracket). It's useful for code coverage to not show a counter on "empty"
196306c3fb27SDimitry Andric   /// lines.
isImplicitCode()196406c3fb27SDimitry Andric   bool isImplicitCode() const { return SubclassData1; }
setImplicitCode(bool ImplicitCode)196506c3fb27SDimitry Andric   void setImplicitCode(bool ImplicitCode) { SubclassData1 = ImplicitCode; }
196606c3fb27SDimitry Andric 
getFile()196706c3fb27SDimitry Andric   DIFile *getFile() const { return getScope()->getFile(); }
getFilename()196806c3fb27SDimitry Andric   StringRef getFilename() const { return getScope()->getFilename(); }
getDirectory()196906c3fb27SDimitry Andric   StringRef getDirectory() const { return getScope()->getDirectory(); }
getSource()197006c3fb27SDimitry Andric   std::optional<StringRef> getSource() const { return getScope()->getSource(); }
197106c3fb27SDimitry Andric 
197206c3fb27SDimitry Andric   /// Get the scope where this is inlined.
197306c3fb27SDimitry Andric   ///
197406c3fb27SDimitry Andric   /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
197506c3fb27SDimitry Andric   /// location.
getInlinedAtScope()197606c3fb27SDimitry Andric   DILocalScope *getInlinedAtScope() const {
197706c3fb27SDimitry Andric     if (auto *IA = getInlinedAt())
197806c3fb27SDimitry Andric       return IA->getInlinedAtScope();
197906c3fb27SDimitry Andric     return getScope();
198006c3fb27SDimitry Andric   }
198106c3fb27SDimitry Andric 
198206c3fb27SDimitry Andric   /// Get the DWARF discriminator.
198306c3fb27SDimitry Andric   ///
198406c3fb27SDimitry Andric   /// DWARF discriminators distinguish identical file locations between
198506c3fb27SDimitry Andric   /// instructions that are on different basic blocks.
198606c3fb27SDimitry Andric   ///
198706c3fb27SDimitry Andric   /// There are 3 components stored in discriminator, from lower bits:
198806c3fb27SDimitry Andric   ///
198906c3fb27SDimitry Andric   /// Base discriminator: assigned by AddDiscriminators pass to identify IRs
199006c3fb27SDimitry Andric   ///                     that are defined by the same source line, but
199106c3fb27SDimitry Andric   ///                     different basic blocks.
199206c3fb27SDimitry Andric   /// Duplication factor: assigned by optimizations that will scale down
199306c3fb27SDimitry Andric   ///                     the execution frequency of the original IR.
199406c3fb27SDimitry Andric   /// Copy Identifier: assigned by optimizations that clones the IR.
199506c3fb27SDimitry Andric   ///                  Each copy of the IR will be assigned an identifier.
199606c3fb27SDimitry Andric   ///
199706c3fb27SDimitry Andric   /// Encoding:
199806c3fb27SDimitry Andric   ///
199906c3fb27SDimitry Andric   /// The above 3 components are encoded into a 32bit unsigned integer in
200006c3fb27SDimitry Andric   /// order. If the lowest bit is 1, the current component is empty, and the
200106c3fb27SDimitry Andric   /// next component will start in the next bit. Otherwise, the current
200206c3fb27SDimitry Andric   /// component is non-empty, and its content starts in the next bit. The
200306c3fb27SDimitry Andric   /// value of each components is either 5 bit or 12 bit: if the 7th bit
200406c3fb27SDimitry Andric   /// is 0, the bit 2~6 (5 bits) are used to represent the component; if the
200506c3fb27SDimitry Andric   /// 7th bit is 1, the bit 2~6 (5 bits) and 8~14 (7 bits) are combined to
200606c3fb27SDimitry Andric   /// represent the component. Thus, the number of bits used for a component
200706c3fb27SDimitry Andric   /// is either 0 (if it and all the next components are empty); 1 - if it is
200806c3fb27SDimitry Andric   /// empty; 7 - if its value is up to and including 0x1f (lsb and msb are both
200906c3fb27SDimitry Andric   /// 0); or 14, if its value is up to and including 0x1ff. Note that the last
201006c3fb27SDimitry Andric   /// component is also capped at 0x1ff, even in the case when both first
201106c3fb27SDimitry Andric   /// components are 0, and we'd technically have 29 bits available.
201206c3fb27SDimitry Andric   ///
201306c3fb27SDimitry Andric   /// For precise control over the data being encoded in the discriminator,
201406c3fb27SDimitry Andric   /// use encodeDiscriminator/decodeDiscriminator.
201506c3fb27SDimitry Andric 
201606c3fb27SDimitry Andric   inline unsigned getDiscriminator() const;
201706c3fb27SDimitry Andric 
201806c3fb27SDimitry Andric   // For the regular discriminator, it stands for all empty components if all
201906c3fb27SDimitry Andric   // the lowest 3 bits are non-zero and all higher 29 bits are unused(zero by
202006c3fb27SDimitry Andric   // default). Here we fully leverage the higher 29 bits for pseudo probe use.
202106c3fb27SDimitry Andric   // This is the format:
202206c3fb27SDimitry Andric   // [2:0] - 0x7
202306c3fb27SDimitry Andric   // [31:3] - pseudo probe fields guaranteed to be non-zero as a whole
202406c3fb27SDimitry Andric   // So if the lower 3 bits is non-zero and the others has at least one
202506c3fb27SDimitry Andric   // non-zero bit, it guarantees to be a pseudo probe discriminator
isPseudoProbeDiscriminator(unsigned Discriminator)202606c3fb27SDimitry Andric   inline static bool isPseudoProbeDiscriminator(unsigned Discriminator) {
202706c3fb27SDimitry Andric     return ((Discriminator & 0x7) == 0x7) && (Discriminator & 0xFFFFFFF8);
202806c3fb27SDimitry Andric   }
202906c3fb27SDimitry Andric 
203006c3fb27SDimitry Andric   /// Returns a new DILocation with updated \p Discriminator.
203106c3fb27SDimitry Andric   inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
203206c3fb27SDimitry Andric 
203306c3fb27SDimitry Andric   /// Returns a new DILocation with updated base discriminator \p BD. Only the
203406c3fb27SDimitry Andric   /// base discriminator is set in the new DILocation, the other encoded values
203506c3fb27SDimitry Andric   /// are elided.
203606c3fb27SDimitry Andric   /// If the discriminator cannot be encoded, the function returns std::nullopt.
203706c3fb27SDimitry Andric   inline std::optional<const DILocation *>
203806c3fb27SDimitry Andric   cloneWithBaseDiscriminator(unsigned BD) const;
203906c3fb27SDimitry Andric 
204006c3fb27SDimitry Andric   /// Returns the duplication factor stored in the discriminator, or 1 if no
204106c3fb27SDimitry Andric   /// duplication factor (or 0) is encoded.
204206c3fb27SDimitry Andric   inline unsigned getDuplicationFactor() const;
204306c3fb27SDimitry Andric 
204406c3fb27SDimitry Andric   /// Returns the copy identifier stored in the discriminator.
204506c3fb27SDimitry Andric   inline unsigned getCopyIdentifier() const;
204606c3fb27SDimitry Andric 
204706c3fb27SDimitry Andric   /// Returns the base discriminator stored in the discriminator.
204806c3fb27SDimitry Andric   inline unsigned getBaseDiscriminator() const;
204906c3fb27SDimitry Andric 
205006c3fb27SDimitry Andric   /// Returns a new DILocation with duplication factor \p DF * current
205106c3fb27SDimitry Andric   /// duplication factor encoded in the discriminator. The current duplication
205206c3fb27SDimitry Andric   /// factor is as defined by getDuplicationFactor().
205306c3fb27SDimitry Andric   /// Returns std::nullopt if encoding failed.
205406c3fb27SDimitry Andric   inline std::optional<const DILocation *>
205506c3fb27SDimitry Andric   cloneByMultiplyingDuplicationFactor(unsigned DF) const;
205606c3fb27SDimitry Andric 
205706c3fb27SDimitry Andric   /// When two instructions are combined into a single instruction we also
205806c3fb27SDimitry Andric   /// need to combine the original locations into a single location.
205906c3fb27SDimitry Andric   /// When the locations are the same we can use either location.
206006c3fb27SDimitry Andric   /// When they differ, we need a third location which is distinct from either.
206106c3fb27SDimitry Andric   /// If they share a common scope, use this scope and compare the line/column
206206c3fb27SDimitry Andric   /// pair of the locations with the common scope:
206306c3fb27SDimitry Andric   /// * if both match, keep the line and column;
206406c3fb27SDimitry Andric   /// * if only the line number matches, keep the line and set the column as 0;
206506c3fb27SDimitry Andric   /// * otherwise set line and column as 0.
206606c3fb27SDimitry Andric   /// If they do not share a common scope the location is ambiguous and can't be
206706c3fb27SDimitry Andric   /// represented in a line entry. In this case, set line and column as 0 and
206806c3fb27SDimitry Andric   /// use the scope of any location.
206906c3fb27SDimitry Andric   ///
207006c3fb27SDimitry Andric   /// \p LocA \p LocB: The locations to be merged.
207106c3fb27SDimitry Andric   static DILocation *getMergedLocation(DILocation *LocA, DILocation *LocB);
207206c3fb27SDimitry Andric 
207306c3fb27SDimitry Andric   /// Try to combine the vector of locations passed as input in a single one.
207406c3fb27SDimitry Andric   /// This function applies getMergedLocation() repeatedly left-to-right.
207506c3fb27SDimitry Andric   ///
207606c3fb27SDimitry Andric   /// \p Locs: The locations to be merged.
207706c3fb27SDimitry Andric   static DILocation *getMergedLocations(ArrayRef<DILocation *> Locs);
207806c3fb27SDimitry Andric 
207906c3fb27SDimitry Andric   /// Return the masked discriminator value for an input discrimnator value D
208006c3fb27SDimitry Andric   /// (i.e. zero out the (B+1)-th and above bits for D (B is 0-base).
208106c3fb27SDimitry Andric   // Example: an input of (0x1FF, 7) returns 0xFF.
getMaskedDiscriminator(unsigned D,unsigned B)208206c3fb27SDimitry Andric   static unsigned getMaskedDiscriminator(unsigned D, unsigned B) {
208306c3fb27SDimitry Andric     return (D & getN1Bits(B));
208406c3fb27SDimitry Andric   }
208506c3fb27SDimitry Andric 
208606c3fb27SDimitry Andric   /// Return the bits used for base discriminators.
getBaseDiscriminatorBits()208706c3fb27SDimitry Andric   static unsigned getBaseDiscriminatorBits() { return getBaseFSBitEnd(); }
208806c3fb27SDimitry Andric 
208906c3fb27SDimitry Andric   /// Returns the base discriminator for a given encoded discriminator \p D.
209006c3fb27SDimitry Andric   static unsigned
209106c3fb27SDimitry Andric   getBaseDiscriminatorFromDiscriminator(unsigned D,
209206c3fb27SDimitry Andric                                         bool IsFSDiscriminator = false) {
20935f757f3fSDimitry Andric     // Return the probe id instead of zero for a pseudo probe discriminator.
20945f757f3fSDimitry Andric     // This should help differenciate callsites with same line numbers to
20955f757f3fSDimitry Andric     // achieve a decent AutoFDO profile under -fpseudo-probe-for-profiling,
20965f757f3fSDimitry Andric     // where the original callsite dwarf discriminator is overwritten by
20975f757f3fSDimitry Andric     // callsite probe information.
20985f757f3fSDimitry Andric     if (isPseudoProbeDiscriminator(D))
20995f757f3fSDimitry Andric       return PseudoProbeDwarfDiscriminator::extractProbeIndex(D);
21005f757f3fSDimitry Andric 
210106c3fb27SDimitry Andric     if (IsFSDiscriminator)
210206c3fb27SDimitry Andric       return getMaskedDiscriminator(D, getBaseDiscriminatorBits());
210306c3fb27SDimitry Andric     return getUnsignedFromPrefixEncoding(D);
210406c3fb27SDimitry Andric   }
210506c3fb27SDimitry Andric 
210606c3fb27SDimitry Andric   /// Raw encoding of the discriminator. APIs such as cloneWithDuplicationFactor
210706c3fb27SDimitry Andric   /// have certain special case behavior (e.g. treating empty duplication factor
210806c3fb27SDimitry Andric   /// as the value '1').
210906c3fb27SDimitry Andric   /// This API, in conjunction with cloneWithDiscriminator, may be used to
211006c3fb27SDimitry Andric   /// encode the raw values provided.
211106c3fb27SDimitry Andric   ///
211206c3fb27SDimitry Andric   /// \p BD: base discriminator
211306c3fb27SDimitry Andric   /// \p DF: duplication factor
211406c3fb27SDimitry Andric   /// \p CI: copy index
211506c3fb27SDimitry Andric   ///
211606c3fb27SDimitry Andric   /// The return is std::nullopt if the values cannot be encoded in 32 bits -
211706c3fb27SDimitry Andric   /// for example, values for BD or DF larger than 12 bits. Otherwise, the
211806c3fb27SDimitry Andric   /// return is the encoded value.
211906c3fb27SDimitry Andric   static std::optional<unsigned> encodeDiscriminator(unsigned BD, unsigned DF,
212006c3fb27SDimitry Andric                                                      unsigned CI);
212106c3fb27SDimitry Andric 
212206c3fb27SDimitry Andric   /// Raw decoder for values in an encoded discriminator D.
212306c3fb27SDimitry Andric   static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
212406c3fb27SDimitry Andric                                   unsigned &CI);
212506c3fb27SDimitry Andric 
212606c3fb27SDimitry Andric   /// Returns the duplication factor for a given encoded discriminator \p D, or
212706c3fb27SDimitry Andric   /// 1 if no value or 0 is encoded.
getDuplicationFactorFromDiscriminator(unsigned D)212806c3fb27SDimitry Andric   static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
212906c3fb27SDimitry Andric     if (EnableFSDiscriminator)
213006c3fb27SDimitry Andric       return 1;
213106c3fb27SDimitry Andric     D = getNextComponentInDiscriminator(D);
213206c3fb27SDimitry Andric     unsigned Ret = getUnsignedFromPrefixEncoding(D);
213306c3fb27SDimitry Andric     if (Ret == 0)
213406c3fb27SDimitry Andric       return 1;
213506c3fb27SDimitry Andric     return Ret;
213606c3fb27SDimitry Andric   }
213706c3fb27SDimitry Andric 
213806c3fb27SDimitry Andric   /// Returns the copy identifier for a given encoded discriminator \p D.
getCopyIdentifierFromDiscriminator(unsigned D)213906c3fb27SDimitry Andric   static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
214006c3fb27SDimitry Andric     return getUnsignedFromPrefixEncoding(
214106c3fb27SDimitry Andric         getNextComponentInDiscriminator(getNextComponentInDiscriminator(D)));
214206c3fb27SDimitry Andric   }
214306c3fb27SDimitry Andric 
getRawScope()214406c3fb27SDimitry Andric   Metadata *getRawScope() const { return getOperand(0); }
getRawInlinedAt()214506c3fb27SDimitry Andric   Metadata *getRawInlinedAt() const {
214606c3fb27SDimitry Andric     if (getNumOperands() == 2)
214706c3fb27SDimitry Andric       return getOperand(1);
214806c3fb27SDimitry Andric     return nullptr;
214906c3fb27SDimitry Andric   }
215006c3fb27SDimitry Andric 
classof(const Metadata * MD)215106c3fb27SDimitry Andric   static bool classof(const Metadata *MD) {
215206c3fb27SDimitry Andric     return MD->getMetadataID() == DILocationKind;
215306c3fb27SDimitry Andric   }
215406c3fb27SDimitry Andric };
215506c3fb27SDimitry Andric 
21560b57cec5SDimitry Andric class DILexicalBlockBase : public DILocalScope {
21570b57cec5SDimitry Andric protected:
21580b57cec5SDimitry Andric   DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
215981ad6265SDimitry Andric                      ArrayRef<Metadata *> Ops);
21600b57cec5SDimitry Andric   ~DILexicalBlockBase() = default;
21610b57cec5SDimitry Andric 
21620b57cec5SDimitry Andric public:
getScope()21630b57cec5SDimitry Andric   DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
21640b57cec5SDimitry Andric 
getRawScope()21650b57cec5SDimitry Andric   Metadata *getRawScope() const { return getOperand(1); }
21660b57cec5SDimitry Andric 
replaceScope(DIScope * Scope)2167bdd1243dSDimitry Andric   void replaceScope(DIScope *Scope) {
2168bdd1243dSDimitry Andric     assert(!isUniqued());
2169bdd1243dSDimitry Andric     setOperand(1, Scope);
2170bdd1243dSDimitry Andric   }
2171bdd1243dSDimitry Andric 
classof(const Metadata * MD)21720b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
21730b57cec5SDimitry Andric     return MD->getMetadataID() == DILexicalBlockKind ||
21740b57cec5SDimitry Andric            MD->getMetadataID() == DILexicalBlockFileKind;
21750b57cec5SDimitry Andric   }
21760b57cec5SDimitry Andric };
21770b57cec5SDimitry Andric 
21785f757f3fSDimitry Andric /// Debug lexical block.
21795f757f3fSDimitry Andric ///
21805f757f3fSDimitry Andric /// Uses the SubclassData32 Metadata slot.
21810b57cec5SDimitry Andric class DILexicalBlock : public DILexicalBlockBase {
21820b57cec5SDimitry Andric   friend class LLVMContextImpl;
21830b57cec5SDimitry Andric   friend class MDNode;
21840b57cec5SDimitry Andric 
21850b57cec5SDimitry Andric   uint16_t Column;
21860b57cec5SDimitry Andric 
DILexicalBlock(LLVMContext & C,StorageType Storage,unsigned Line,unsigned Column,ArrayRef<Metadata * > Ops)21870b57cec5SDimitry Andric   DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
21880b57cec5SDimitry Andric                  unsigned Column, ArrayRef<Metadata *> Ops)
21895f757f3fSDimitry Andric       : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops),
21900b57cec5SDimitry Andric         Column(Column) {
21915f757f3fSDimitry Andric     SubclassData32 = Line;
21920b57cec5SDimitry Andric     assert(Column < (1u << 16) && "Expected 16-bit column");
21930b57cec5SDimitry Andric   }
21940b57cec5SDimitry Andric   ~DILexicalBlock() = default;
21950b57cec5SDimitry Andric 
21960b57cec5SDimitry Andric   static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
21970b57cec5SDimitry Andric                                  DIFile *File, unsigned Line, unsigned Column,
21980b57cec5SDimitry Andric                                  StorageType Storage,
21990b57cec5SDimitry Andric                                  bool ShouldCreate = true) {
22000b57cec5SDimitry Andric     return getImpl(Context, static_cast<Metadata *>(Scope),
22010b57cec5SDimitry Andric                    static_cast<Metadata *>(File), Line, Column, Storage,
22020b57cec5SDimitry Andric                    ShouldCreate);
22030b57cec5SDimitry Andric   }
22040b57cec5SDimitry Andric 
22050b57cec5SDimitry Andric   static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
22060b57cec5SDimitry Andric                                  Metadata *File, unsigned Line, unsigned Column,
22070b57cec5SDimitry Andric                                  StorageType Storage, bool ShouldCreate = true);
22080b57cec5SDimitry Andric 
cloneImpl()22090b57cec5SDimitry Andric   TempDILexicalBlock cloneImpl() const {
22100b57cec5SDimitry Andric     return getTemporary(getContext(), getScope(), getFile(), getLine(),
22110b57cec5SDimitry Andric                         getColumn());
22120b57cec5SDimitry Andric   }
22130b57cec5SDimitry Andric 
22140b57cec5SDimitry Andric public:
2215349cc55cSDimitry Andric   DEFINE_MDNODE_GET(DILexicalBlock,
2216349cc55cSDimitry Andric                     (DILocalScope * Scope, DIFile *File, unsigned Line,
2217349cc55cSDimitry Andric                      unsigned Column),
22180b57cec5SDimitry Andric                     (Scope, File, Line, Column))
2219349cc55cSDimitry Andric   DEFINE_MDNODE_GET(DILexicalBlock,
2220349cc55cSDimitry Andric                     (Metadata * Scope, Metadata *File, unsigned Line,
2221349cc55cSDimitry Andric                      unsigned Column),
22220b57cec5SDimitry Andric                     (Scope, File, Line, Column))
22230b57cec5SDimitry Andric 
clone()22240b57cec5SDimitry Andric   TempDILexicalBlock clone() const { return cloneImpl(); }
22250b57cec5SDimitry Andric 
getLine()22265f757f3fSDimitry Andric   unsigned getLine() const { return SubclassData32; }
getColumn()22270b57cec5SDimitry Andric   unsigned getColumn() const { return Column; }
22280b57cec5SDimitry Andric 
classof(const Metadata * MD)22290b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
22300b57cec5SDimitry Andric     return MD->getMetadataID() == DILexicalBlockKind;
22310b57cec5SDimitry Andric   }
22320b57cec5SDimitry Andric };
22330b57cec5SDimitry Andric 
22340b57cec5SDimitry Andric class DILexicalBlockFile : public DILexicalBlockBase {
22350b57cec5SDimitry Andric   friend class LLVMContextImpl;
22360b57cec5SDimitry Andric   friend class MDNode;
22370b57cec5SDimitry Andric 
DILexicalBlockFile(LLVMContext & C,StorageType Storage,unsigned Discriminator,ArrayRef<Metadata * > Ops)22380b57cec5SDimitry Andric   DILexicalBlockFile(LLVMContext &C, StorageType Storage,
22390b57cec5SDimitry Andric                      unsigned Discriminator, ArrayRef<Metadata *> Ops)
22405f757f3fSDimitry Andric       : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops) {
22415f757f3fSDimitry Andric     SubclassData32 = Discriminator;
22425f757f3fSDimitry Andric   }
22430b57cec5SDimitry Andric   ~DILexicalBlockFile() = default;
22440b57cec5SDimitry Andric 
22450b57cec5SDimitry Andric   static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
22460b57cec5SDimitry Andric                                      DIFile *File, unsigned Discriminator,
22470b57cec5SDimitry Andric                                      StorageType Storage,
22480b57cec5SDimitry Andric                                      bool ShouldCreate = true) {
22490b57cec5SDimitry Andric     return getImpl(Context, static_cast<Metadata *>(Scope),
22500b57cec5SDimitry Andric                    static_cast<Metadata *>(File), Discriminator, Storage,
22510b57cec5SDimitry Andric                    ShouldCreate);
22520b57cec5SDimitry Andric   }
22530b57cec5SDimitry Andric 
22540b57cec5SDimitry Andric   static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
22550b57cec5SDimitry Andric                                      Metadata *File, unsigned Discriminator,
22560b57cec5SDimitry Andric                                      StorageType Storage,
22570b57cec5SDimitry Andric                                      bool ShouldCreate = true);
22580b57cec5SDimitry Andric 
cloneImpl()22590b57cec5SDimitry Andric   TempDILexicalBlockFile cloneImpl() const {
22600b57cec5SDimitry Andric     return getTemporary(getContext(), getScope(), getFile(),
22610b57cec5SDimitry Andric                         getDiscriminator());
22620b57cec5SDimitry Andric   }
22630b57cec5SDimitry Andric 
22640b57cec5SDimitry Andric public:
2265349cc55cSDimitry Andric   DEFINE_MDNODE_GET(DILexicalBlockFile,
2266349cc55cSDimitry Andric                     (DILocalScope * Scope, DIFile *File,
22670b57cec5SDimitry Andric                      unsigned Discriminator),
22680b57cec5SDimitry Andric                     (Scope, File, Discriminator))
22690b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DILexicalBlockFile,
22700b57cec5SDimitry Andric                     (Metadata * Scope, Metadata *File, unsigned Discriminator),
22710b57cec5SDimitry Andric                     (Scope, File, Discriminator))
22720b57cec5SDimitry Andric 
clone()22730b57cec5SDimitry Andric   TempDILexicalBlockFile clone() const { return cloneImpl(); }
getDiscriminator()22745f757f3fSDimitry Andric   unsigned getDiscriminator() const { return SubclassData32; }
22750b57cec5SDimitry Andric 
classof(const Metadata * MD)22760b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
22770b57cec5SDimitry Andric     return MD->getMetadataID() == DILexicalBlockFileKind;
22780b57cec5SDimitry Andric   }
22790b57cec5SDimitry Andric };
22800b57cec5SDimitry Andric 
getDiscriminator()22810b57cec5SDimitry Andric unsigned DILocation::getDiscriminator() const {
22820b57cec5SDimitry Andric   if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
22830b57cec5SDimitry Andric     return F->getDiscriminator();
22840b57cec5SDimitry Andric   return 0;
22850b57cec5SDimitry Andric }
22860b57cec5SDimitry Andric 
22870b57cec5SDimitry Andric const DILocation *
cloneWithDiscriminator(unsigned Discriminator)22880b57cec5SDimitry Andric DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
22890b57cec5SDimitry Andric   DIScope *Scope = getScope();
22900b57cec5SDimitry Andric   // Skip all parent DILexicalBlockFile that already have a discriminator
22910b57cec5SDimitry Andric   // assigned. We do not want to have nested DILexicalBlockFiles that have
22920b57cec5SDimitry Andric   // mutliple discriminators because only the leaf DILexicalBlockFile's
22930b57cec5SDimitry Andric   // dominator will be used.
22940b57cec5SDimitry Andric   for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
22950b57cec5SDimitry Andric        LBF && LBF->getDiscriminator() != 0;
22960b57cec5SDimitry Andric        LBF = dyn_cast<DILexicalBlockFile>(Scope))
22970b57cec5SDimitry Andric     Scope = LBF->getScope();
22980b57cec5SDimitry Andric   DILexicalBlockFile *NewScope =
22990b57cec5SDimitry Andric       DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
23000b57cec5SDimitry Andric   return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
23010b57cec5SDimitry Andric                          getInlinedAt());
23020b57cec5SDimitry Andric }
23030b57cec5SDimitry Andric 
getBaseDiscriminator()23040b57cec5SDimitry Andric unsigned DILocation::getBaseDiscriminator() const {
2305fe6060f1SDimitry Andric   return getBaseDiscriminatorFromDiscriminator(getDiscriminator(),
2306fe6060f1SDimitry Andric                                                EnableFSDiscriminator);
23070b57cec5SDimitry Andric }
23080b57cec5SDimitry Andric 
getDuplicationFactor()23090b57cec5SDimitry Andric unsigned DILocation::getDuplicationFactor() const {
23100b57cec5SDimitry Andric   return getDuplicationFactorFromDiscriminator(getDiscriminator());
23110b57cec5SDimitry Andric }
23120b57cec5SDimitry Andric 
getCopyIdentifier()23130b57cec5SDimitry Andric unsigned DILocation::getCopyIdentifier() const {
23140b57cec5SDimitry Andric   return getCopyIdentifierFromDiscriminator(getDiscriminator());
23150b57cec5SDimitry Andric }
23160b57cec5SDimitry Andric 
2317bdd1243dSDimitry Andric std::optional<const DILocation *>
cloneWithBaseDiscriminator(unsigned D)2318349cc55cSDimitry Andric DILocation::cloneWithBaseDiscriminator(unsigned D) const {
23190b57cec5SDimitry Andric   unsigned BD, DF, CI;
2320fe6060f1SDimitry Andric 
2321fe6060f1SDimitry Andric   if (EnableFSDiscriminator) {
2322fe6060f1SDimitry Andric     BD = getBaseDiscriminator();
2323fe6060f1SDimitry Andric     if (D == BD)
2324fe6060f1SDimitry Andric       return this;
2325fe6060f1SDimitry Andric     return cloneWithDiscriminator(D);
2326fe6060f1SDimitry Andric   }
2327fe6060f1SDimitry Andric 
23280b57cec5SDimitry Andric   decodeDiscriminator(getDiscriminator(), BD, DF, CI);
23290b57cec5SDimitry Andric   if (D == BD)
23300b57cec5SDimitry Andric     return this;
2331bdd1243dSDimitry Andric   if (std::optional<unsigned> Encoded = encodeDiscriminator(D, DF, CI))
23320b57cec5SDimitry Andric     return cloneWithDiscriminator(*Encoded);
2333bdd1243dSDimitry Andric   return std::nullopt;
23340b57cec5SDimitry Andric }
23350b57cec5SDimitry Andric 
2336bdd1243dSDimitry Andric std::optional<const DILocation *>
cloneByMultiplyingDuplicationFactor(unsigned DF)2337349cc55cSDimitry Andric DILocation::cloneByMultiplyingDuplicationFactor(unsigned DF) const {
2338fe6060f1SDimitry Andric   assert(!EnableFSDiscriminator && "FSDiscriminator should not call this.");
233906c3fb27SDimitry Andric   // Do no interfere with pseudo probes. Pseudo probe doesn't need duplication
234006c3fb27SDimitry Andric   // factor support as samples collected on cloned probes will be aggregated.
234106c3fb27SDimitry Andric   // Also pseudo probe at a callsite uses the dwarf discriminator to store
234206c3fb27SDimitry Andric   // pseudo probe related information, such as the probe id.
234306c3fb27SDimitry Andric   if (isPseudoProbeDiscriminator(getDiscriminator()))
234406c3fb27SDimitry Andric     return this;
2345fe6060f1SDimitry Andric 
23460b57cec5SDimitry Andric   DF *= getDuplicationFactor();
23470b57cec5SDimitry Andric   if (DF <= 1)
23480b57cec5SDimitry Andric     return this;
23490b57cec5SDimitry Andric 
23500b57cec5SDimitry Andric   unsigned BD = getBaseDiscriminator();
23510b57cec5SDimitry Andric   unsigned CI = getCopyIdentifier();
2352bdd1243dSDimitry Andric   if (std::optional<unsigned> D = encodeDiscriminator(BD, DF, CI))
23530b57cec5SDimitry Andric     return cloneWithDiscriminator(*D);
2354bdd1243dSDimitry Andric   return std::nullopt;
23550b57cec5SDimitry Andric }
23560b57cec5SDimitry Andric 
23575f757f3fSDimitry Andric /// Debug lexical block.
23585f757f3fSDimitry Andric ///
23595f757f3fSDimitry Andric /// Uses the SubclassData1 Metadata slot.
23600b57cec5SDimitry Andric class DINamespace : public DIScope {
23610b57cec5SDimitry Andric   friend class LLVMContextImpl;
23620b57cec5SDimitry Andric   friend class MDNode;
23630b57cec5SDimitry Andric 
23640b57cec5SDimitry Andric   DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
236581ad6265SDimitry Andric               ArrayRef<Metadata *> Ops);
23660b57cec5SDimitry Andric   ~DINamespace() = default;
23670b57cec5SDimitry Andric 
23680b57cec5SDimitry Andric   static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
23690b57cec5SDimitry Andric                               StringRef Name, bool ExportSymbols,
23700b57cec5SDimitry Andric                               StorageType Storage, bool ShouldCreate = true) {
23710b57cec5SDimitry Andric     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
23720b57cec5SDimitry Andric                    ExportSymbols, Storage, ShouldCreate);
23730b57cec5SDimitry Andric   }
23740b57cec5SDimitry Andric   static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
23750b57cec5SDimitry Andric                               MDString *Name, bool ExportSymbols,
23760b57cec5SDimitry Andric                               StorageType Storage, bool ShouldCreate = true);
23770b57cec5SDimitry Andric 
cloneImpl()23780b57cec5SDimitry Andric   TempDINamespace cloneImpl() const {
23790b57cec5SDimitry Andric     return getTemporary(getContext(), getScope(), getName(),
23800b57cec5SDimitry Andric                         getExportSymbols());
23810b57cec5SDimitry Andric   }
23820b57cec5SDimitry Andric 
23830b57cec5SDimitry Andric public:
23840b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DINamespace,
23850b57cec5SDimitry Andric                     (DIScope * Scope, StringRef Name, bool ExportSymbols),
23860b57cec5SDimitry Andric                     (Scope, Name, ExportSymbols))
23870b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DINamespace,
23880b57cec5SDimitry Andric                     (Metadata * Scope, MDString *Name, bool ExportSymbols),
23890b57cec5SDimitry Andric                     (Scope, Name, ExportSymbols))
23900b57cec5SDimitry Andric 
clone()23910b57cec5SDimitry Andric   TempDINamespace clone() const { return cloneImpl(); }
23920b57cec5SDimitry Andric 
getExportSymbols()23935f757f3fSDimitry Andric   bool getExportSymbols() const { return SubclassData1; }
getScope()23940b57cec5SDimitry Andric   DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
getName()23950b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(2); }
23960b57cec5SDimitry Andric 
getRawScope()23970b57cec5SDimitry Andric   Metadata *getRawScope() const { return getOperand(1); }
getRawName()23980b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(2); }
23990b57cec5SDimitry Andric 
classof(const Metadata * MD)24000b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
24010b57cec5SDimitry Andric     return MD->getMetadataID() == DINamespaceKind;
24020b57cec5SDimitry Andric   }
24030b57cec5SDimitry Andric };
24040b57cec5SDimitry Andric 
24055ffd83dbSDimitry Andric /// Represents a module in the programming language, for example, a Clang
24065ffd83dbSDimitry Andric /// module, or a Fortran module.
24075f757f3fSDimitry Andric ///
24085f757f3fSDimitry Andric /// Uses the SubclassData1 and SubclassData32 Metadata slots.
24090b57cec5SDimitry Andric class DIModule : public DIScope {
24100b57cec5SDimitry Andric   friend class LLVMContextImpl;
24110b57cec5SDimitry Andric   friend class MDNode;
24120b57cec5SDimitry Andric 
24135ffd83dbSDimitry Andric   DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
241481ad6265SDimitry Andric            bool IsDecl, ArrayRef<Metadata *> Ops);
24150b57cec5SDimitry Andric   ~DIModule() = default;
24160b57cec5SDimitry Andric 
24175ffd83dbSDimitry Andric   static DIModule *getImpl(LLVMContext &Context, DIFile *File, DIScope *Scope,
24180b57cec5SDimitry Andric                            StringRef Name, StringRef ConfigurationMacros,
24195ffd83dbSDimitry Andric                            StringRef IncludePath, StringRef APINotesFile,
2420e8d8bef9SDimitry Andric                            unsigned LineNo, bool IsDecl, StorageType Storage,
24215ffd83dbSDimitry Andric                            bool ShouldCreate = true) {
24225ffd83dbSDimitry Andric     return getImpl(Context, File, Scope, getCanonicalMDString(Context, Name),
24230b57cec5SDimitry Andric                    getCanonicalMDString(Context, ConfigurationMacros),
24240b57cec5SDimitry Andric                    getCanonicalMDString(Context, IncludePath),
2425e8d8bef9SDimitry Andric                    getCanonicalMDString(Context, APINotesFile), LineNo, IsDecl,
2426e8d8bef9SDimitry Andric                    Storage, ShouldCreate);
24270b57cec5SDimitry Andric   }
24285ffd83dbSDimitry Andric   static DIModule *getImpl(LLVMContext &Context, Metadata *File,
24295ffd83dbSDimitry Andric                            Metadata *Scope, MDString *Name,
24305ffd83dbSDimitry Andric                            MDString *ConfigurationMacros, MDString *IncludePath,
2431e8d8bef9SDimitry Andric                            MDString *APINotesFile, unsigned LineNo, bool IsDecl,
24320b57cec5SDimitry Andric                            StorageType Storage, bool ShouldCreate = true);
24330b57cec5SDimitry Andric 
cloneImpl()24340b57cec5SDimitry Andric   TempDIModule cloneImpl() const {
24355ffd83dbSDimitry Andric     return getTemporary(getContext(), getFile(), getScope(), getName(),
24360b57cec5SDimitry Andric                         getConfigurationMacros(), getIncludePath(),
2437e8d8bef9SDimitry Andric                         getAPINotesFile(), getLineNo(), getIsDecl());
24380b57cec5SDimitry Andric   }
24390b57cec5SDimitry Andric 
24400b57cec5SDimitry Andric public:
24410b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIModule,
24425ffd83dbSDimitry Andric                     (DIFile * File, DIScope *Scope, StringRef Name,
24435ffd83dbSDimitry Andric                      StringRef ConfigurationMacros, StringRef IncludePath,
2444e8d8bef9SDimitry Andric                      StringRef APINotesFile, unsigned LineNo,
2445e8d8bef9SDimitry Andric                      bool IsDecl = false),
24465ffd83dbSDimitry Andric                     (File, Scope, Name, ConfigurationMacros, IncludePath,
2447e8d8bef9SDimitry Andric                      APINotesFile, LineNo, IsDecl))
24485ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(DIModule,
24495ffd83dbSDimitry Andric                     (Metadata * File, Metadata *Scope, MDString *Name,
24505ffd83dbSDimitry Andric                      MDString *ConfigurationMacros, MDString *IncludePath,
2451e8d8bef9SDimitry Andric                      MDString *APINotesFile, unsigned LineNo,
2452e8d8bef9SDimitry Andric                      bool IsDecl = false),
24535ffd83dbSDimitry Andric                     (File, Scope, Name, ConfigurationMacros, IncludePath,
2454e8d8bef9SDimitry Andric                      APINotesFile, LineNo, IsDecl))
24550b57cec5SDimitry Andric 
clone()24560b57cec5SDimitry Andric   TempDIModule clone() const { return cloneImpl(); }
24570b57cec5SDimitry Andric 
getScope()24580b57cec5SDimitry Andric   DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
getName()24595ffd83dbSDimitry Andric   StringRef getName() const { return getStringOperand(2); }
getConfigurationMacros()24605ffd83dbSDimitry Andric   StringRef getConfigurationMacros() const { return getStringOperand(3); }
getIncludePath()24615ffd83dbSDimitry Andric   StringRef getIncludePath() const { return getStringOperand(4); }
getAPINotesFile()24625ffd83dbSDimitry Andric   StringRef getAPINotesFile() const { return getStringOperand(5); }
getLineNo()24635f757f3fSDimitry Andric   unsigned getLineNo() const { return SubclassData32; }
getIsDecl()24645f757f3fSDimitry Andric   bool getIsDecl() const { return SubclassData1; }
24650b57cec5SDimitry Andric 
getRawScope()24665ffd83dbSDimitry Andric   Metadata *getRawScope() const { return getOperand(1); }
getRawName()24675ffd83dbSDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(2); }
getRawConfigurationMacros()24685ffd83dbSDimitry Andric   MDString *getRawConfigurationMacros() const {
24695ffd83dbSDimitry Andric     return getOperandAs<MDString>(3);
24705ffd83dbSDimitry Andric   }
getRawIncludePath()24715ffd83dbSDimitry Andric   MDString *getRawIncludePath() const { return getOperandAs<MDString>(4); }
getRawAPINotesFile()24725ffd83dbSDimitry Andric   MDString *getRawAPINotesFile() const { return getOperandAs<MDString>(5); }
24730b57cec5SDimitry Andric 
classof(const Metadata * MD)24740b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
24750b57cec5SDimitry Andric     return MD->getMetadataID() == DIModuleKind;
24760b57cec5SDimitry Andric   }
24770b57cec5SDimitry Andric };
24780b57cec5SDimitry Andric 
24790b57cec5SDimitry Andric /// Base class for template parameters.
24805f757f3fSDimitry Andric ///
24815f757f3fSDimitry Andric /// Uses the SubclassData1 Metadata slot.
24820b57cec5SDimitry Andric class DITemplateParameter : public DINode {
24830b57cec5SDimitry Andric protected:
DITemplateParameter(LLVMContext & Context,unsigned ID,StorageType Storage,unsigned Tag,bool IsDefault,ArrayRef<Metadata * > Ops)24840b57cec5SDimitry Andric   DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
24855ffd83dbSDimitry Andric                       unsigned Tag, bool IsDefault, ArrayRef<Metadata *> Ops)
24865f757f3fSDimitry Andric       : DINode(Context, ID, Storage, Tag, Ops) {
24875f757f3fSDimitry Andric     SubclassData1 = IsDefault;
24885f757f3fSDimitry Andric   }
24890b57cec5SDimitry Andric   ~DITemplateParameter() = default;
24900b57cec5SDimitry Andric 
24910b57cec5SDimitry Andric public:
getName()24920b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(0); }
getType()24930b57cec5SDimitry Andric   DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
24940b57cec5SDimitry Andric 
getRawName()24950b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(0); }
getRawType()24960b57cec5SDimitry Andric   Metadata *getRawType() const { return getOperand(1); }
isDefault()24975f757f3fSDimitry Andric   bool isDefault() const { return SubclassData1; }
24980b57cec5SDimitry Andric 
classof(const Metadata * MD)24990b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
25000b57cec5SDimitry Andric     return MD->getMetadataID() == DITemplateTypeParameterKind ||
25010b57cec5SDimitry Andric            MD->getMetadataID() == DITemplateValueParameterKind;
25020b57cec5SDimitry Andric   }
25030b57cec5SDimitry Andric };
25040b57cec5SDimitry Andric 
25050b57cec5SDimitry Andric class DITemplateTypeParameter : public DITemplateParameter {
25060b57cec5SDimitry Andric   friend class LLVMContextImpl;
25070b57cec5SDimitry Andric   friend class MDNode;
25080b57cec5SDimitry Andric 
25090b57cec5SDimitry Andric   DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
251081ad6265SDimitry Andric                           bool IsDefault, ArrayRef<Metadata *> Ops);
25110b57cec5SDimitry Andric   ~DITemplateTypeParameter() = default;
25120b57cec5SDimitry Andric 
25130b57cec5SDimitry Andric   static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
25145ffd83dbSDimitry Andric                                           DIType *Type, bool IsDefault,
25155ffd83dbSDimitry Andric                                           StorageType Storage,
25160b57cec5SDimitry Andric                                           bool ShouldCreate = true) {
25175ffd83dbSDimitry Andric     return getImpl(Context, getCanonicalMDString(Context, Name), Type,
25185ffd83dbSDimitry Andric                    IsDefault, Storage, ShouldCreate);
25190b57cec5SDimitry Andric   }
25200b57cec5SDimitry Andric   static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
25215ffd83dbSDimitry Andric                                           Metadata *Type, bool IsDefault,
25225ffd83dbSDimitry Andric                                           StorageType Storage,
25230b57cec5SDimitry Andric                                           bool ShouldCreate = true);
25240b57cec5SDimitry Andric 
cloneImpl()25250b57cec5SDimitry Andric   TempDITemplateTypeParameter cloneImpl() const {
25265ffd83dbSDimitry Andric     return getTemporary(getContext(), getName(), getType(), isDefault());
25270b57cec5SDimitry Andric   }
25280b57cec5SDimitry Andric 
25290b57cec5SDimitry Andric public:
25305ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(DITemplateTypeParameter,
25315ffd83dbSDimitry Andric                     (StringRef Name, DIType *Type, bool IsDefault),
25325ffd83dbSDimitry Andric                     (Name, Type, IsDefault))
25335ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(DITemplateTypeParameter,
25345ffd83dbSDimitry Andric                     (MDString * Name, Metadata *Type, bool IsDefault),
25355ffd83dbSDimitry Andric                     (Name, Type, IsDefault))
25360b57cec5SDimitry Andric 
clone()25370b57cec5SDimitry Andric   TempDITemplateTypeParameter clone() const { return cloneImpl(); }
25380b57cec5SDimitry Andric 
classof(const Metadata * MD)25390b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
25400b57cec5SDimitry Andric     return MD->getMetadataID() == DITemplateTypeParameterKind;
25410b57cec5SDimitry Andric   }
25420b57cec5SDimitry Andric };
25430b57cec5SDimitry Andric 
25440b57cec5SDimitry Andric class DITemplateValueParameter : public DITemplateParameter {
25450b57cec5SDimitry Andric   friend class LLVMContextImpl;
25460b57cec5SDimitry Andric   friend class MDNode;
25470b57cec5SDimitry Andric 
DITemplateValueParameter(LLVMContext & Context,StorageType Storage,unsigned Tag,bool IsDefault,ArrayRef<Metadata * > Ops)25480b57cec5SDimitry Andric   DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
25495ffd83dbSDimitry Andric                            unsigned Tag, bool IsDefault,
25505ffd83dbSDimitry Andric                            ArrayRef<Metadata *> Ops)
25510b57cec5SDimitry Andric       : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
25525ffd83dbSDimitry Andric                             IsDefault, Ops) {}
25530b57cec5SDimitry Andric   ~DITemplateValueParameter() = default;
25540b57cec5SDimitry Andric 
25550b57cec5SDimitry Andric   static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
25560b57cec5SDimitry Andric                                            StringRef Name, DIType *Type,
25575ffd83dbSDimitry Andric                                            bool IsDefault, Metadata *Value,
25585ffd83dbSDimitry Andric                                            StorageType Storage,
25590b57cec5SDimitry Andric                                            bool ShouldCreate = true) {
25600b57cec5SDimitry Andric     return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
25615ffd83dbSDimitry Andric                    IsDefault, Value, Storage, ShouldCreate);
25620b57cec5SDimitry Andric   }
25630b57cec5SDimitry Andric   static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
25640b57cec5SDimitry Andric                                            MDString *Name, Metadata *Type,
25655ffd83dbSDimitry Andric                                            bool IsDefault, Metadata *Value,
25665ffd83dbSDimitry Andric                                            StorageType Storage,
25670b57cec5SDimitry Andric                                            bool ShouldCreate = true);
25680b57cec5SDimitry Andric 
cloneImpl()25690b57cec5SDimitry Andric   TempDITemplateValueParameter cloneImpl() const {
25700b57cec5SDimitry Andric     return getTemporary(getContext(), getTag(), getName(), getType(),
25715ffd83dbSDimitry Andric                         isDefault(), getValue());
25720b57cec5SDimitry Andric   }
25730b57cec5SDimitry Andric 
25740b57cec5SDimitry Andric public:
25750b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DITemplateValueParameter,
25765ffd83dbSDimitry Andric                     (unsigned Tag, StringRef Name, DIType *Type, bool IsDefault,
25770b57cec5SDimitry Andric                      Metadata *Value),
25785ffd83dbSDimitry Andric                     (Tag, Name, Type, IsDefault, Value))
25795ffd83dbSDimitry Andric   DEFINE_MDNODE_GET(DITemplateValueParameter,
25805ffd83dbSDimitry Andric                     (unsigned Tag, MDString *Name, Metadata *Type,
25815ffd83dbSDimitry Andric                      bool IsDefault, Metadata *Value),
25825ffd83dbSDimitry Andric                     (Tag, Name, Type, IsDefault, Value))
25830b57cec5SDimitry Andric 
clone()25840b57cec5SDimitry Andric   TempDITemplateValueParameter clone() const { return cloneImpl(); }
25850b57cec5SDimitry Andric 
getValue()25860b57cec5SDimitry Andric   Metadata *getValue() const { return getOperand(2); }
25870b57cec5SDimitry Andric 
classof(const Metadata * MD)25880b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
25890b57cec5SDimitry Andric     return MD->getMetadataID() == DITemplateValueParameterKind;
25900b57cec5SDimitry Andric   }
25910b57cec5SDimitry Andric };
25920b57cec5SDimitry Andric 
25930b57cec5SDimitry Andric /// Base class for variables.
25945f757f3fSDimitry Andric ///
25955f757f3fSDimitry Andric /// Uses the SubclassData32 Metadata slot.
25960b57cec5SDimitry Andric class DIVariable : public DINode {
25970b57cec5SDimitry Andric   unsigned Line;
25980b57cec5SDimitry Andric 
25990b57cec5SDimitry Andric protected:
260081ad6265SDimitry Andric   DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line,
260181ad6265SDimitry Andric              ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0);
26020b57cec5SDimitry Andric   ~DIVariable() = default;
26030b57cec5SDimitry Andric 
26040b57cec5SDimitry Andric public:
getLine()26050b57cec5SDimitry Andric   unsigned getLine() const { return Line; }
getScope()26060b57cec5SDimitry Andric   DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
getName()26070b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(1); }
getFile()26080b57cec5SDimitry Andric   DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
getType()26090b57cec5SDimitry Andric   DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
getAlignInBits()26105f757f3fSDimitry Andric   uint32_t getAlignInBits() const { return SubclassData32; }
getAlignInBytes()26110b57cec5SDimitry Andric   uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
26120b57cec5SDimitry Andric   /// Determines the size of the variable's type.
2613bdd1243dSDimitry Andric   std::optional<uint64_t> getSizeInBits() const;
26140b57cec5SDimitry Andric 
2615bdd1243dSDimitry Andric   /// Return the signedness of this variable's type, or std::nullopt if this
2616bdd1243dSDimitry Andric   /// type is neither signed nor unsigned.
getSignedness()2617bdd1243dSDimitry Andric   std::optional<DIBasicType::Signedness> getSignedness() const {
26180b57cec5SDimitry Andric     if (auto *BT = dyn_cast<DIBasicType>(getType()))
26190b57cec5SDimitry Andric       return BT->getSignedness();
2620bdd1243dSDimitry Andric     return std::nullopt;
26210b57cec5SDimitry Andric   }
26220b57cec5SDimitry Andric 
getFilename()26230b57cec5SDimitry Andric   StringRef getFilename() const {
26240b57cec5SDimitry Andric     if (auto *F = getFile())
26250b57cec5SDimitry Andric       return F->getFilename();
26260b57cec5SDimitry Andric     return "";
26270b57cec5SDimitry Andric   }
26280b57cec5SDimitry Andric 
getDirectory()26290b57cec5SDimitry Andric   StringRef getDirectory() const {
26300b57cec5SDimitry Andric     if (auto *F = getFile())
26310b57cec5SDimitry Andric       return F->getDirectory();
26320b57cec5SDimitry Andric     return "";
26330b57cec5SDimitry Andric   }
26340b57cec5SDimitry Andric 
getSource()2635bdd1243dSDimitry Andric   std::optional<StringRef> getSource() const {
26360b57cec5SDimitry Andric     if (auto *F = getFile())
26370b57cec5SDimitry Andric       return F->getSource();
2638bdd1243dSDimitry Andric     return std::nullopt;
26390b57cec5SDimitry Andric   }
26400b57cec5SDimitry Andric 
getRawScope()26410b57cec5SDimitry Andric   Metadata *getRawScope() const { return getOperand(0); }
getRawName()26420b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(1); }
getRawFile()26430b57cec5SDimitry Andric   Metadata *getRawFile() const { return getOperand(2); }
getRawType()26440b57cec5SDimitry Andric   Metadata *getRawType() const { return getOperand(3); }
26450b57cec5SDimitry Andric 
classof(const Metadata * MD)26460b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
26470b57cec5SDimitry Andric     return MD->getMetadataID() == DILocalVariableKind ||
26480b57cec5SDimitry Andric            MD->getMetadataID() == DIGlobalVariableKind;
26490b57cec5SDimitry Andric   }
26500b57cec5SDimitry Andric };
26510b57cec5SDimitry Andric 
26520b57cec5SDimitry Andric /// DWARF expression.
26530b57cec5SDimitry Andric ///
26540b57cec5SDimitry Andric /// This is (almost) a DWARF expression that modifies the location of a
26550b57cec5SDimitry Andric /// variable, or the location of a single piece of a variable, or (when using
26560b57cec5SDimitry Andric /// DW_OP_stack_value) is the constant variable value.
26570b57cec5SDimitry Andric ///
26580b57cec5SDimitry Andric /// TODO: Co-allocate the expression elements.
26590b57cec5SDimitry Andric /// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
26600b57cec5SDimitry Andric /// storage types.
26610b57cec5SDimitry Andric class DIExpression : public MDNode {
26620b57cec5SDimitry Andric   friend class LLVMContextImpl;
26630b57cec5SDimitry Andric   friend class MDNode;
26640b57cec5SDimitry Andric 
26650b57cec5SDimitry Andric   std::vector<uint64_t> Elements;
26660b57cec5SDimitry Andric 
DIExpression(LLVMContext & C,StorageType Storage,ArrayRef<uint64_t> Elements)26670b57cec5SDimitry Andric   DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
2668bdd1243dSDimitry Andric       : MDNode(C, DIExpressionKind, Storage, std::nullopt),
26690b57cec5SDimitry Andric         Elements(Elements.begin(), Elements.end()) {}
26700b57cec5SDimitry Andric   ~DIExpression() = default;
26710b57cec5SDimitry Andric 
26720b57cec5SDimitry Andric   static DIExpression *getImpl(LLVMContext &Context,
26730b57cec5SDimitry Andric                                ArrayRef<uint64_t> Elements, StorageType Storage,
26740b57cec5SDimitry Andric                                bool ShouldCreate = true);
26750b57cec5SDimitry Andric 
cloneImpl()26760b57cec5SDimitry Andric   TempDIExpression cloneImpl() const {
26770b57cec5SDimitry Andric     return getTemporary(getContext(), getElements());
26780b57cec5SDimitry Andric   }
26790b57cec5SDimitry Andric 
26800b57cec5SDimitry Andric public:
26810b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
26820b57cec5SDimitry Andric 
clone()26830b57cec5SDimitry Andric   TempDIExpression clone() const { return cloneImpl(); }
26840b57cec5SDimitry Andric 
getElements()26850b57cec5SDimitry Andric   ArrayRef<uint64_t> getElements() const { return Elements; }
26860b57cec5SDimitry Andric 
getNumElements()26870b57cec5SDimitry Andric   unsigned getNumElements() const { return Elements.size(); }
26880b57cec5SDimitry Andric 
getElement(unsigned I)26890b57cec5SDimitry Andric   uint64_t getElement(unsigned I) const {
26900b57cec5SDimitry Andric     assert(I < Elements.size() && "Index out of range");
26910b57cec5SDimitry Andric     return Elements[I];
26920b57cec5SDimitry Andric   }
26930b57cec5SDimitry Andric 
2694fe6060f1SDimitry Andric   enum SignedOrUnsignedConstant { SignedConstant, UnsignedConstant };
2695fe6060f1SDimitry Andric   /// Determine whether this represents a constant value, if so
2696fe6060f1SDimitry Andric   // return it's sign information.
2697bdd1243dSDimitry Andric   std::optional<SignedOrUnsignedConstant> isConstant() const;
26980b57cec5SDimitry Andric 
2699fe6060f1SDimitry Andric   /// Return the number of unique location operands referred to (via
2700fe6060f1SDimitry Andric   /// DW_OP_LLVM_arg) in this expression; this is not necessarily the number of
2701fe6060f1SDimitry Andric   /// instances of DW_OP_LLVM_arg within the expression.
2702fe6060f1SDimitry Andric   /// For example, for the expression:
2703fe6060f1SDimitry Andric   ///   (DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_plus,
2704fe6060f1SDimitry Andric   ///    DW_OP_LLVM_arg 0, DW_OP_mul)
2705fe6060f1SDimitry Andric   /// This function would return 2, as there are two unique location operands
2706fe6060f1SDimitry Andric   /// (0 and 1).
2707fe6060f1SDimitry Andric   uint64_t getNumLocationOperands() const;
2708e8d8bef9SDimitry Andric 
27090b57cec5SDimitry Andric   using element_iterator = ArrayRef<uint64_t>::iterator;
27100b57cec5SDimitry Andric 
elements_begin()27110b57cec5SDimitry Andric   element_iterator elements_begin() const { return getElements().begin(); }
elements_end()27120b57cec5SDimitry Andric   element_iterator elements_end() const { return getElements().end(); }
27130b57cec5SDimitry Andric 
27140b57cec5SDimitry Andric   /// A lightweight wrapper around an expression operand.
27150b57cec5SDimitry Andric   ///
27160b57cec5SDimitry Andric   /// TODO: Store arguments directly and change \a DIExpression to store a
27170b57cec5SDimitry Andric   /// range of these.
27180b57cec5SDimitry Andric   class ExprOperand {
27190b57cec5SDimitry Andric     const uint64_t *Op = nullptr;
27200b57cec5SDimitry Andric 
27210b57cec5SDimitry Andric   public:
27220b57cec5SDimitry Andric     ExprOperand() = default;
ExprOperand(const uint64_t * Op)27230b57cec5SDimitry Andric     explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
27240b57cec5SDimitry Andric 
get()27250b57cec5SDimitry Andric     const uint64_t *get() const { return Op; }
27260b57cec5SDimitry Andric 
27270b57cec5SDimitry Andric     /// Get the operand code.
getOp()27280b57cec5SDimitry Andric     uint64_t getOp() const { return *Op; }
27290b57cec5SDimitry Andric 
27300b57cec5SDimitry Andric     /// Get an argument to the operand.
27310b57cec5SDimitry Andric     ///
27320b57cec5SDimitry Andric     /// Never returns the operand itself.
getArg(unsigned I)27330b57cec5SDimitry Andric     uint64_t getArg(unsigned I) const { return Op[I + 1]; }
27340b57cec5SDimitry Andric 
getNumArgs()27350b57cec5SDimitry Andric     unsigned getNumArgs() const { return getSize() - 1; }
27360b57cec5SDimitry Andric 
27370b57cec5SDimitry Andric     /// Return the size of the operand.
27380b57cec5SDimitry Andric     ///
27390b57cec5SDimitry Andric     /// Return the number of elements in the operand (1 + args).
27400b57cec5SDimitry Andric     unsigned getSize() const;
27410b57cec5SDimitry Andric 
27420b57cec5SDimitry Andric     /// Append the elements of this operand to \p V.
appendToVector(SmallVectorImpl<uint64_t> & V)27430b57cec5SDimitry Andric     void appendToVector(SmallVectorImpl<uint64_t> &V) const {
27440b57cec5SDimitry Andric       V.append(get(), get() + getSize());
27450b57cec5SDimitry Andric     }
27460b57cec5SDimitry Andric   };
27470b57cec5SDimitry Andric 
27480b57cec5SDimitry Andric   /// An iterator for expression operands.
2749fe6060f1SDimitry Andric   class expr_op_iterator {
27500b57cec5SDimitry Andric     ExprOperand Op;
27510b57cec5SDimitry Andric 
27520b57cec5SDimitry Andric   public:
2753fe6060f1SDimitry Andric     using iterator_category = std::input_iterator_tag;
2754fe6060f1SDimitry Andric     using value_type = ExprOperand;
2755fe6060f1SDimitry Andric     using difference_type = std::ptrdiff_t;
2756fe6060f1SDimitry Andric     using pointer = value_type *;
2757fe6060f1SDimitry Andric     using reference = value_type &;
2758fe6060f1SDimitry Andric 
27590b57cec5SDimitry Andric     expr_op_iterator() = default;
expr_op_iterator(element_iterator I)27600b57cec5SDimitry Andric     explicit expr_op_iterator(element_iterator I) : Op(I) {}
27610b57cec5SDimitry Andric 
getBase()27620b57cec5SDimitry Andric     element_iterator getBase() const { return Op.get(); }
27630b57cec5SDimitry Andric     const ExprOperand &operator*() const { return Op; }
27640b57cec5SDimitry Andric     const ExprOperand *operator->() const { return &Op; }
27650b57cec5SDimitry Andric 
27660b57cec5SDimitry Andric     expr_op_iterator &operator++() {
27670b57cec5SDimitry Andric       increment();
27680b57cec5SDimitry Andric       return *this;
27690b57cec5SDimitry Andric     }
27700b57cec5SDimitry Andric     expr_op_iterator operator++(int) {
27710b57cec5SDimitry Andric       expr_op_iterator T(*this);
27720b57cec5SDimitry Andric       increment();
27730b57cec5SDimitry Andric       return T;
27740b57cec5SDimitry Andric     }
27750b57cec5SDimitry Andric 
27760b57cec5SDimitry Andric     /// Get the next iterator.
27770b57cec5SDimitry Andric     ///
27780b57cec5SDimitry Andric     /// \a std::next() doesn't work because this is technically an
27790b57cec5SDimitry Andric     /// input_iterator, but it's a perfectly valid operation.  This is an
27800b57cec5SDimitry Andric     /// accessor to provide the same functionality.
getNext()27810b57cec5SDimitry Andric     expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
27820b57cec5SDimitry Andric 
27830b57cec5SDimitry Andric     bool operator==(const expr_op_iterator &X) const {
27840b57cec5SDimitry Andric       return getBase() == X.getBase();
27850b57cec5SDimitry Andric     }
27860b57cec5SDimitry Andric     bool operator!=(const expr_op_iterator &X) const {
27870b57cec5SDimitry Andric       return getBase() != X.getBase();
27880b57cec5SDimitry Andric     }
27890b57cec5SDimitry Andric 
27900b57cec5SDimitry Andric   private:
increment()27910b57cec5SDimitry Andric     void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
27920b57cec5SDimitry Andric   };
27930b57cec5SDimitry Andric 
27940b57cec5SDimitry Andric   /// Visit the elements via ExprOperand wrappers.
27950b57cec5SDimitry Andric   ///
27960b57cec5SDimitry Andric   /// These range iterators visit elements through \a ExprOperand wrappers.
27970b57cec5SDimitry Andric   /// This is not guaranteed to be a valid range unless \a isValid() gives \c
27980b57cec5SDimitry Andric   /// true.
27990b57cec5SDimitry Andric   ///
28000b57cec5SDimitry Andric   /// \pre \a isValid() gives \c true.
28010b57cec5SDimitry Andric   /// @{
expr_op_begin()28020b57cec5SDimitry Andric   expr_op_iterator expr_op_begin() const {
28030b57cec5SDimitry Andric     return expr_op_iterator(elements_begin());
28040b57cec5SDimitry Andric   }
expr_op_end()28050b57cec5SDimitry Andric   expr_op_iterator expr_op_end() const {
28060b57cec5SDimitry Andric     return expr_op_iterator(elements_end());
28070b57cec5SDimitry Andric   }
expr_ops()28080b57cec5SDimitry Andric   iterator_range<expr_op_iterator> expr_ops() const {
28090b57cec5SDimitry Andric     return {expr_op_begin(), expr_op_end()};
28100b57cec5SDimitry Andric   }
28110b57cec5SDimitry Andric   /// @}
28120b57cec5SDimitry Andric 
28130b57cec5SDimitry Andric   bool isValid() const;
28140b57cec5SDimitry Andric 
classof(const Metadata * MD)28150b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
28160b57cec5SDimitry Andric     return MD->getMetadataID() == DIExpressionKind;
28170b57cec5SDimitry Andric   }
28180b57cec5SDimitry Andric 
28190b57cec5SDimitry Andric   /// Return whether the first element a DW_OP_deref.
282081ad6265SDimitry Andric   bool startsWithDeref() const;
28210b57cec5SDimitry Andric 
282206c3fb27SDimitry Andric   /// Return whether there is exactly one operator and it is a DW_OP_deref;
282306c3fb27SDimitry Andric   bool isDeref() const;
282406c3fb27SDimitry Andric 
28250b57cec5SDimitry Andric   /// Holds the characteristics of one fragment of a larger variable.
28260b57cec5SDimitry Andric   struct FragmentInfo {
282706c3fb27SDimitry Andric     FragmentInfo() = default;
FragmentInfoFragmentInfo282806c3fb27SDimitry Andric     FragmentInfo(uint64_t SizeInBits, uint64_t OffsetInBits)
282906c3fb27SDimitry Andric         : SizeInBits(SizeInBits), OffsetInBits(OffsetInBits) {}
28300b57cec5SDimitry Andric     uint64_t SizeInBits;
28310b57cec5SDimitry Andric     uint64_t OffsetInBits;
283206c3fb27SDimitry Andric     /// Return the index of the first bit of the fragment.
startInBitsFragmentInfo283306c3fb27SDimitry Andric     uint64_t startInBits() const { return OffsetInBits; }
283406c3fb27SDimitry Andric     /// Return the index of the bit after the end of the fragment, e.g. for
283506c3fb27SDimitry Andric     /// fragment offset=16 and size=32 return their sum, 48.
endInBitsFragmentInfo283606c3fb27SDimitry Andric     uint64_t endInBits() const { return OffsetInBits + SizeInBits; }
283706c3fb27SDimitry Andric 
283806c3fb27SDimitry Andric     /// Returns a zero-sized fragment if A and B don't intersect.
intersectFragmentInfo283906c3fb27SDimitry Andric     static DIExpression::FragmentInfo intersect(DIExpression::FragmentInfo A,
284006c3fb27SDimitry Andric                                                 DIExpression::FragmentInfo B) {
284106c3fb27SDimitry Andric       uint64_t StartInBits = std::max(A.OffsetInBits, B.OffsetInBits);
284206c3fb27SDimitry Andric       uint64_t EndInBits = std::min(A.endInBits(), B.endInBits());
284306c3fb27SDimitry Andric       if (EndInBits <= StartInBits)
284406c3fb27SDimitry Andric         return {0, 0};
284506c3fb27SDimitry Andric       return DIExpression::FragmentInfo(EndInBits - StartInBits, StartInBits);
284606c3fb27SDimitry Andric     }
28470b57cec5SDimitry Andric   };
28480b57cec5SDimitry Andric 
28490b57cec5SDimitry Andric   /// Retrieve the details of this fragment expression.
2850bdd1243dSDimitry Andric   static std::optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
28510b57cec5SDimitry Andric                                                      expr_op_iterator End);
28520b57cec5SDimitry Andric 
28530b57cec5SDimitry Andric   /// Retrieve the details of this fragment expression.
getFragmentInfo()2854bdd1243dSDimitry Andric   std::optional<FragmentInfo> getFragmentInfo() const {
28550b57cec5SDimitry Andric     return getFragmentInfo(expr_op_begin(), expr_op_end());
28560b57cec5SDimitry Andric   }
28570b57cec5SDimitry Andric 
28580b57cec5SDimitry Andric   /// Return whether this is a piece of an aggregate variable.
isFragment()285981ad6265SDimitry Andric   bool isFragment() const { return getFragmentInfo().has_value(); }
28600b57cec5SDimitry Andric 
28610b57cec5SDimitry Andric   /// Return whether this is an implicit location description.
28620b57cec5SDimitry Andric   bool isImplicit() const;
28630b57cec5SDimitry Andric 
28640b57cec5SDimitry Andric   /// Return whether the location is computed on the expression stack, meaning
28650b57cec5SDimitry Andric   /// it cannot be a simple register location.
28660b57cec5SDimitry Andric   bool isComplex() const;
28670b57cec5SDimitry Andric 
2868bdd1243dSDimitry Andric   /// Return whether the evaluated expression makes use of a single location at
2869bdd1243dSDimitry Andric   /// the start of the expression, i.e. if it contains only a single
2870bdd1243dSDimitry Andric   /// DW_OP_LLVM_arg op as its first operand, or if it contains none.
2871bdd1243dSDimitry Andric   bool isSingleLocationExpression() const;
2872bdd1243dSDimitry Andric 
28735f757f3fSDimitry Andric   /// Returns a reference to the elements contained in this expression, skipping
28745f757f3fSDimitry Andric   /// past the leading `DW_OP_LLVM_arg, 0` if one is present.
28755f757f3fSDimitry Andric   /// Similar to `convertToNonVariadicExpression`, but faster and cheaper - it
28765f757f3fSDimitry Andric   /// does not check whether the expression is a single-location expression, and
28775f757f3fSDimitry Andric   /// it returns elements rather than creating a new DIExpression.
28785f757f3fSDimitry Andric   std::optional<ArrayRef<uint64_t>> getSingleLocationExpressionElements() const;
28795f757f3fSDimitry Andric 
2880bdd1243dSDimitry Andric   /// Removes all elements from \p Expr that do not apply to an undef debug
2881bdd1243dSDimitry Andric   /// value, which includes every operator that computes the value/location on
2882bdd1243dSDimitry Andric   /// the DWARF stack, including any DW_OP_LLVM_arg elements (making the result
2883bdd1243dSDimitry Andric   /// of this function always a single-location expression) while leaving
2884bdd1243dSDimitry Andric   /// everything that defines what the computed value applies to, i.e. the
2885bdd1243dSDimitry Andric   /// fragment information.
2886bdd1243dSDimitry Andric   static const DIExpression *convertToUndefExpression(const DIExpression *Expr);
2887bdd1243dSDimitry Andric 
2888bdd1243dSDimitry Andric   /// If \p Expr is a non-variadic expression (i.e. one that does not contain
2889bdd1243dSDimitry Andric   /// DW_OP_LLVM_arg), returns \p Expr converted to variadic form by adding a
2890bdd1243dSDimitry Andric   /// leading [DW_OP_LLVM_arg, 0] to the expression; otherwise returns \p Expr.
2891bdd1243dSDimitry Andric   static const DIExpression *
2892bdd1243dSDimitry Andric   convertToVariadicExpression(const DIExpression *Expr);
2893bdd1243dSDimitry Andric 
2894bdd1243dSDimitry Andric   /// If \p Expr is a valid single-location expression, i.e. it refers to only a
2895bdd1243dSDimitry Andric   /// single debug operand at the start of the expression, then return that
2896bdd1243dSDimitry Andric   /// expression in a non-variadic form by removing DW_OP_LLVM_arg from the
2897bdd1243dSDimitry Andric   /// expression if it is present; otherwise returns std::nullopt.
28985f757f3fSDimitry Andric   /// See also `getSingleLocationExpressionElements` above, which skips
28995f757f3fSDimitry Andric   /// checking `isSingleLocationExpression` and returns a list of elements
29005f757f3fSDimitry Andric   /// rather than a DIExpression.
2901bdd1243dSDimitry Andric   static std::optional<const DIExpression *>
2902bdd1243dSDimitry Andric   convertToNonVariadicExpression(const DIExpression *Expr);
2903bdd1243dSDimitry Andric 
2904bdd1243dSDimitry Andric   /// Inserts the elements of \p Expr into \p Ops modified to a canonical form,
2905bdd1243dSDimitry Andric   /// which uses DW_OP_LLVM_arg (i.e. is a variadic expression) and folds the
2906bdd1243dSDimitry Andric   /// implied derefence from the \p IsIndirect flag into the expression. This
2907bdd1243dSDimitry Andric   /// allows us to check equivalence between expressions with differing
2908bdd1243dSDimitry Andric   /// directness or variadicness.
2909bdd1243dSDimitry Andric   static void canonicalizeExpressionOps(SmallVectorImpl<uint64_t> &Ops,
2910bdd1243dSDimitry Andric                                         const DIExpression *Expr,
2911bdd1243dSDimitry Andric                                         bool IsIndirect);
2912bdd1243dSDimitry Andric 
2913bdd1243dSDimitry Andric   /// Determines whether two debug values should produce equivalent DWARF
2914bdd1243dSDimitry Andric   /// expressions, using their DIExpressions and directness, ignoring the
2915bdd1243dSDimitry Andric   /// differences between otherwise identical expressions in variadic and
2916bdd1243dSDimitry Andric   /// non-variadic form and not considering the debug operands.
2917bdd1243dSDimitry Andric   /// \p FirstExpr is the DIExpression for the first debug value.
2918bdd1243dSDimitry Andric   /// \p FirstIndirect should be true if the first debug value is indirect; in
291906c3fb27SDimitry Andric   /// IR this should be true for dbg.declare intrinsics and false for
292006c3fb27SDimitry Andric   /// dbg.values, and in MIR this should be true only for DBG_VALUE instructions
292106c3fb27SDimitry Andric   /// whose second operand is an immediate value.
2922bdd1243dSDimitry Andric   /// \p SecondExpr and \p SecondIndirect have the same meaning as the prior
2923bdd1243dSDimitry Andric   /// arguments, but apply to the second debug value.
2924bdd1243dSDimitry Andric   static bool isEqualExpression(const DIExpression *FirstExpr,
2925bdd1243dSDimitry Andric                                 bool FirstIndirect,
2926bdd1243dSDimitry Andric                                 const DIExpression *SecondExpr,
2927bdd1243dSDimitry Andric                                 bool SecondIndirect);
2928bdd1243dSDimitry Andric 
29290b57cec5SDimitry Andric   /// Append \p Ops with operations to apply the \p Offset.
29300b57cec5SDimitry Andric   static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
29310b57cec5SDimitry Andric 
29320b57cec5SDimitry Andric   /// If this is a constant offset, extract it. If there is no expression,
29330b57cec5SDimitry Andric   /// return true with an offset of zero.
29340b57cec5SDimitry Andric   bool extractIfOffset(int64_t &Offset) const;
29350b57cec5SDimitry Andric 
2936fe6060f1SDimitry Andric   /// Returns true iff this DIExpression contains at least one instance of
2937fe6060f1SDimitry Andric   /// `DW_OP_LLVM_arg, n` for all n in [0, N).
2938fe6060f1SDimitry Andric   bool hasAllLocationOps(unsigned N) const;
2939fe6060f1SDimitry Andric 
29400b57cec5SDimitry Andric   /// Checks if the last 4 elements of the expression are DW_OP_constu <DWARF
29410b57cec5SDimitry Andric   /// Address Space> DW_OP_swap DW_OP_xderef and extracts the <DWARF Address
29420b57cec5SDimitry Andric   /// Space>.
29430b57cec5SDimitry Andric   static const DIExpression *extractAddressClass(const DIExpression *Expr,
29440b57cec5SDimitry Andric                                                  unsigned &AddrClass);
29450b57cec5SDimitry Andric 
29460b57cec5SDimitry Andric   /// Used for DIExpression::prepend.
29470b57cec5SDimitry Andric   enum PrependOps : uint8_t {
29480b57cec5SDimitry Andric     ApplyOffset = 0,
29490b57cec5SDimitry Andric     DerefBefore = 1 << 0,
29500b57cec5SDimitry Andric     DerefAfter = 1 << 1,
29510b57cec5SDimitry Andric     StackValue = 1 << 2,
29520b57cec5SDimitry Andric     EntryValue = 1 << 3
29530b57cec5SDimitry Andric   };
29540b57cec5SDimitry Andric 
29550b57cec5SDimitry Andric   /// Prepend \p DIExpr with a deref and offset operation and optionally turn it
29560b57cec5SDimitry Andric   /// into a stack value or/and an entry value.
29570b57cec5SDimitry Andric   static DIExpression *prepend(const DIExpression *Expr, uint8_t Flags,
29580b57cec5SDimitry Andric                                int64_t Offset = 0);
29590b57cec5SDimitry Andric 
29600b57cec5SDimitry Andric   /// Prepend \p DIExpr with the given opcodes and optionally turn it into a
29610b57cec5SDimitry Andric   /// stack value.
29620b57cec5SDimitry Andric   static DIExpression *prependOpcodes(const DIExpression *Expr,
29630b57cec5SDimitry Andric                                       SmallVectorImpl<uint64_t> &Ops,
29640b57cec5SDimitry Andric                                       bool StackValue = false,
29650b57cec5SDimitry Andric                                       bool EntryValue = false);
29660b57cec5SDimitry Andric 
29670b57cec5SDimitry Andric   /// Append the opcodes \p Ops to \p DIExpr. Unlike \ref appendToStack, the
29680b57cec5SDimitry Andric   /// returned expression is a stack value only if \p DIExpr is a stack value.
29690b57cec5SDimitry Andric   /// If \p DIExpr describes a fragment, the returned expression will describe
29700b57cec5SDimitry Andric   /// the same fragment.
29710b57cec5SDimitry Andric   static DIExpression *append(const DIExpression *Expr, ArrayRef<uint64_t> Ops);
29720b57cec5SDimitry Andric 
29730b57cec5SDimitry Andric   /// Convert \p DIExpr into a stack value if it isn't one already by appending
29740b57cec5SDimitry Andric   /// DW_OP_deref if needed, and appending \p Ops to the resulting expression.
29750b57cec5SDimitry Andric   /// If \p DIExpr describes a fragment, the returned expression will describe
29760b57cec5SDimitry Andric   /// the same fragment.
29770b57cec5SDimitry Andric   static DIExpression *appendToStack(const DIExpression *Expr,
29780b57cec5SDimitry Andric                                      ArrayRef<uint64_t> Ops);
29790b57cec5SDimitry Andric 
2980fe6060f1SDimitry Andric   /// Create a copy of \p Expr by appending the given list of \p Ops to each
2981fe6060f1SDimitry Andric   /// instance of the operand `DW_OP_LLVM_arg, \p ArgNo`. This is used to
2982fe6060f1SDimitry Andric   /// modify a specific location used by \p Expr, such as when salvaging that
2983fe6060f1SDimitry Andric   /// location.
2984fe6060f1SDimitry Andric   static DIExpression *appendOpsToArg(const DIExpression *Expr,
2985fe6060f1SDimitry Andric                                       ArrayRef<uint64_t> Ops, unsigned ArgNo,
2986fe6060f1SDimitry Andric                                       bool StackValue = false);
2987fe6060f1SDimitry Andric 
2988fe6060f1SDimitry Andric   /// Create a copy of \p Expr with each instance of
2989fe6060f1SDimitry Andric   /// `DW_OP_LLVM_arg, \p OldArg` replaced with `DW_OP_LLVM_arg, \p NewArg`,
2990fe6060f1SDimitry Andric   /// and each instance of `DW_OP_LLVM_arg, Arg` with `DW_OP_LLVM_arg, Arg - 1`
2991fe6060f1SDimitry Andric   /// for all Arg > \p OldArg.
2992fe6060f1SDimitry Andric   /// This is used when replacing one of the operands of a debug value list
2993fe6060f1SDimitry Andric   /// with another operand in the same list and deleting the old operand.
2994fe6060f1SDimitry Andric   static DIExpression *replaceArg(const DIExpression *Expr, uint64_t OldArg,
2995fe6060f1SDimitry Andric                                   uint64_t NewArg);
2996fe6060f1SDimitry Andric 
29970b57cec5SDimitry Andric   /// Create a DIExpression to describe one part of an aggregate variable that
29980b57cec5SDimitry Andric   /// is fragmented across multiple Values. The DW_OP_LLVM_fragment operation
29990b57cec5SDimitry Andric   /// will be appended to the elements of \c Expr. If \c Expr already contains
30000b57cec5SDimitry Andric   /// a \c DW_OP_LLVM_fragment \c OffsetInBits is interpreted as an offset
30010b57cec5SDimitry Andric   /// into the existing fragment.
30020b57cec5SDimitry Andric   ///
30030b57cec5SDimitry Andric   /// \param OffsetInBits Offset of the piece in bits.
30040b57cec5SDimitry Andric   /// \param SizeInBits   Size of the piece in bits.
30050b57cec5SDimitry Andric   /// \return             Creating a fragment expression may fail if \c Expr
3006349cc55cSDimitry Andric   ///                     contains arithmetic operations that would be
3007349cc55cSDimitry Andric   ///                     truncated.
3008bdd1243dSDimitry Andric   static std::optional<DIExpression *>
30090b57cec5SDimitry Andric   createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,
30100b57cec5SDimitry Andric                            unsigned SizeInBits);
30110b57cec5SDimitry Andric 
30120b57cec5SDimitry Andric   /// Determine the relative position of the fragments passed in.
30130b57cec5SDimitry Andric   /// Returns -1 if this is entirely before Other, 0 if this and Other overlap,
30140b57cec5SDimitry Andric   /// 1 if this is entirely after Other.
fragmentCmp(const FragmentInfo & A,const FragmentInfo & B)30150b57cec5SDimitry Andric   static int fragmentCmp(const FragmentInfo &A, const FragmentInfo &B) {
30160b57cec5SDimitry Andric     uint64_t l1 = A.OffsetInBits;
30170b57cec5SDimitry Andric     uint64_t l2 = B.OffsetInBits;
30180b57cec5SDimitry Andric     uint64_t r1 = l1 + A.SizeInBits;
30190b57cec5SDimitry Andric     uint64_t r2 = l2 + B.SizeInBits;
30200b57cec5SDimitry Andric     if (r1 <= l2)
30210b57cec5SDimitry Andric       return -1;
30220b57cec5SDimitry Andric     else if (r2 <= l1)
30230b57cec5SDimitry Andric       return 1;
30240b57cec5SDimitry Andric     else
30250b57cec5SDimitry Andric       return 0;
30260b57cec5SDimitry Andric   }
30270b57cec5SDimitry Andric 
3028480093f4SDimitry Andric   using ExtOps = std::array<uint64_t, 6>;
3029480093f4SDimitry Andric 
3030480093f4SDimitry Andric   /// Returns the ops for a zero- or sign-extension in a DIExpression.
3031480093f4SDimitry Andric   static ExtOps getExtOps(unsigned FromSize, unsigned ToSize, bool Signed);
3032480093f4SDimitry Andric 
3033480093f4SDimitry Andric   /// Append a zero- or sign-extension to \p Expr. Converts the expression to a
3034480093f4SDimitry Andric   /// stack value if it isn't one already.
3035480093f4SDimitry Andric   static DIExpression *appendExt(const DIExpression *Expr, unsigned FromSize,
3036480093f4SDimitry Andric                                  unsigned ToSize, bool Signed);
3037480093f4SDimitry Andric 
30380b57cec5SDimitry Andric   /// Check if fragments overlap between a pair of FragmentInfos.
fragmentsOverlap(const FragmentInfo & A,const FragmentInfo & B)30390b57cec5SDimitry Andric   static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B) {
30400b57cec5SDimitry Andric     return fragmentCmp(A, B) == 0;
30410b57cec5SDimitry Andric   }
30420b57cec5SDimitry Andric 
30430b57cec5SDimitry Andric   /// Determine the relative position of the fragments described by this
30440b57cec5SDimitry Andric   /// DIExpression and \p Other. Calls static fragmentCmp implementation.
fragmentCmp(const DIExpression * Other)30450b57cec5SDimitry Andric   int fragmentCmp(const DIExpression *Other) const {
30460b57cec5SDimitry Andric     auto Fragment1 = *getFragmentInfo();
30470b57cec5SDimitry Andric     auto Fragment2 = *Other->getFragmentInfo();
30480b57cec5SDimitry Andric     return fragmentCmp(Fragment1, Fragment2);
30490b57cec5SDimitry Andric   }
30500b57cec5SDimitry Andric 
30510b57cec5SDimitry Andric   /// Check if fragments overlap between this DIExpression and \p Other.
fragmentsOverlap(const DIExpression * Other)30520b57cec5SDimitry Andric   bool fragmentsOverlap(const DIExpression *Other) const {
30530b57cec5SDimitry Andric     if (!isFragment() || !Other->isFragment())
30540b57cec5SDimitry Andric       return true;
30550b57cec5SDimitry Andric     return fragmentCmp(Other) == 0;
30560b57cec5SDimitry Andric   }
30570b57cec5SDimitry Andric 
30580b57cec5SDimitry Andric   /// Check if the expression consists of exactly one entry value operand.
30590b57cec5SDimitry Andric   /// (This is the only configuration of entry values that is supported.)
306081ad6265SDimitry Andric   bool isEntryValue() const;
3061349cc55cSDimitry Andric 
3062349cc55cSDimitry Andric   /// Try to shorten an expression with an initial constant operand.
3063349cc55cSDimitry Andric   /// Returns a new expression and constant on success, or the original
3064349cc55cSDimitry Andric   /// expression and constant on failure.
3065349cc55cSDimitry Andric   std::pair<DIExpression *, const ConstantInt *>
3066349cc55cSDimitry Andric   constantFold(const ConstantInt *CI);
30670b57cec5SDimitry Andric };
30680b57cec5SDimitry Andric 
30690b57cec5SDimitry Andric inline bool operator==(const DIExpression::FragmentInfo &A,
30700b57cec5SDimitry Andric                        const DIExpression::FragmentInfo &B) {
30710b57cec5SDimitry Andric   return std::tie(A.SizeInBits, A.OffsetInBits) ==
30720b57cec5SDimitry Andric          std::tie(B.SizeInBits, B.OffsetInBits);
30730b57cec5SDimitry Andric }
30740b57cec5SDimitry Andric 
30750b57cec5SDimitry Andric inline bool operator<(const DIExpression::FragmentInfo &A,
30760b57cec5SDimitry Andric                       const DIExpression::FragmentInfo &B) {
30770b57cec5SDimitry Andric   return std::tie(A.SizeInBits, A.OffsetInBits) <
30780b57cec5SDimitry Andric          std::tie(B.SizeInBits, B.OffsetInBits);
30790b57cec5SDimitry Andric }
30800b57cec5SDimitry Andric 
30810b57cec5SDimitry Andric template <> struct DenseMapInfo<DIExpression::FragmentInfo> {
30820b57cec5SDimitry Andric   using FragInfo = DIExpression::FragmentInfo;
30830b57cec5SDimitry Andric   static const uint64_t MaxVal = std::numeric_limits<uint64_t>::max();
30840b57cec5SDimitry Andric 
30850b57cec5SDimitry Andric   static inline FragInfo getEmptyKey() { return {MaxVal, MaxVal}; }
30860b57cec5SDimitry Andric 
30870b57cec5SDimitry Andric   static inline FragInfo getTombstoneKey() { return {MaxVal - 1, MaxVal - 1}; }
30880b57cec5SDimitry Andric 
30890b57cec5SDimitry Andric   static unsigned getHashValue(const FragInfo &Frag) {
30900b57cec5SDimitry Andric     return (Frag.SizeInBits & 0xffff) << 16 | (Frag.OffsetInBits & 0xffff);
30910b57cec5SDimitry Andric   }
30920b57cec5SDimitry Andric 
30930b57cec5SDimitry Andric   static bool isEqual(const FragInfo &A, const FragInfo &B) { return A == B; }
30940b57cec5SDimitry Andric };
30950b57cec5SDimitry Andric 
30960b57cec5SDimitry Andric /// Global variables.
30970b57cec5SDimitry Andric ///
30980b57cec5SDimitry Andric /// TODO: Remove DisplayName.  It's always equal to Name.
30990b57cec5SDimitry Andric class DIGlobalVariable : public DIVariable {
31000b57cec5SDimitry Andric   friend class LLVMContextImpl;
31010b57cec5SDimitry Andric   friend class MDNode;
31020b57cec5SDimitry Andric 
31030b57cec5SDimitry Andric   bool IsLocalToUnit;
31040b57cec5SDimitry Andric   bool IsDefinition;
31050b57cec5SDimitry Andric 
31060b57cec5SDimitry Andric   DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
31070b57cec5SDimitry Andric                    bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
31080b57cec5SDimitry Andric                    ArrayRef<Metadata *> Ops)
31090b57cec5SDimitry Andric       : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
31100b57cec5SDimitry Andric         IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
31110b57cec5SDimitry Andric   ~DIGlobalVariable() = default;
31120b57cec5SDimitry Andric 
31130b57cec5SDimitry Andric   static DIGlobalVariable *
31140b57cec5SDimitry Andric   getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
31150b57cec5SDimitry Andric           StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type,
31160b57cec5SDimitry Andric           bool IsLocalToUnit, bool IsDefinition,
31170b57cec5SDimitry Andric           DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
3118349cc55cSDimitry Andric           uint32_t AlignInBits, DINodeArray Annotations, StorageType Storage,
3119349cc55cSDimitry Andric           bool ShouldCreate = true) {
31200b57cec5SDimitry Andric     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
31210b57cec5SDimitry Andric                    getCanonicalMDString(Context, LinkageName), File, Line, Type,
31220b57cec5SDimitry Andric                    IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
3123349cc55cSDimitry Andric                    cast_or_null<Metadata>(TemplateParams), AlignInBits,
3124349cc55cSDimitry Andric                    Annotations.get(), Storage, ShouldCreate);
31250b57cec5SDimitry Andric   }
31260b57cec5SDimitry Andric   static DIGlobalVariable *
31270b57cec5SDimitry Andric   getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
31280b57cec5SDimitry Andric           MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
31290b57cec5SDimitry Andric           bool IsLocalToUnit, bool IsDefinition,
31300b57cec5SDimitry Andric           Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
3131349cc55cSDimitry Andric           uint32_t AlignInBits, Metadata *Annotations, StorageType Storage,
3132349cc55cSDimitry Andric           bool ShouldCreate = true);
31330b57cec5SDimitry Andric 
31340b57cec5SDimitry Andric   TempDIGlobalVariable cloneImpl() const {
31350b57cec5SDimitry Andric     return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
31360b57cec5SDimitry Andric                         getFile(), getLine(), getType(), isLocalToUnit(),
31370b57cec5SDimitry Andric                         isDefinition(), getStaticDataMemberDeclaration(),
3138349cc55cSDimitry Andric                         getTemplateParams(), getAlignInBits(),
3139349cc55cSDimitry Andric                         getAnnotations());
31400b57cec5SDimitry Andric   }
31410b57cec5SDimitry Andric 
31420b57cec5SDimitry Andric public:
3143349cc55cSDimitry Andric   DEFINE_MDNODE_GET(
3144349cc55cSDimitry Andric       DIGlobalVariable,
3145349cc55cSDimitry Andric       (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File,
3146349cc55cSDimitry Andric        unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition,
3147349cc55cSDimitry Andric        DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
3148349cc55cSDimitry Andric        uint32_t AlignInBits, DINodeArray Annotations),
3149349cc55cSDimitry Andric       (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
3150349cc55cSDimitry Andric        StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations))
3151349cc55cSDimitry Andric   DEFINE_MDNODE_GET(
3152349cc55cSDimitry Andric       DIGlobalVariable,
3153349cc55cSDimitry Andric       (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
3154349cc55cSDimitry Andric        unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
3155349cc55cSDimitry Andric        Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
3156349cc55cSDimitry Andric        uint32_t AlignInBits, Metadata *Annotations),
3157349cc55cSDimitry Andric       (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
3158349cc55cSDimitry Andric        StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations))
31590b57cec5SDimitry Andric 
31600b57cec5SDimitry Andric   TempDIGlobalVariable clone() const { return cloneImpl(); }
31610b57cec5SDimitry Andric 
31620b57cec5SDimitry Andric   bool isLocalToUnit() const { return IsLocalToUnit; }
31630b57cec5SDimitry Andric   bool isDefinition() const { return IsDefinition; }
31640b57cec5SDimitry Andric   StringRef getDisplayName() const { return getStringOperand(4); }
31650b57cec5SDimitry Andric   StringRef getLinkageName() const { return getStringOperand(5); }
31660b57cec5SDimitry Andric   DIDerivedType *getStaticDataMemberDeclaration() const {
31670b57cec5SDimitry Andric     return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
31680b57cec5SDimitry Andric   }
3169349cc55cSDimitry Andric   DINodeArray getAnnotations() const {
3170349cc55cSDimitry Andric     return cast_or_null<MDTuple>(getRawAnnotations());
3171349cc55cSDimitry Andric   }
31720b57cec5SDimitry Andric 
31730b57cec5SDimitry Andric   MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
31740b57cec5SDimitry Andric   Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
31750b57cec5SDimitry Andric   Metadata *getRawTemplateParams() const { return getOperand(7); }
31760b57cec5SDimitry Andric   MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); }
3177349cc55cSDimitry Andric   Metadata *getRawAnnotations() const { return getOperand(8); }
31780b57cec5SDimitry Andric 
31790b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
31800b57cec5SDimitry Andric     return MD->getMetadataID() == DIGlobalVariableKind;
31810b57cec5SDimitry Andric   }
31820b57cec5SDimitry Andric };
31830b57cec5SDimitry Andric 
31845f757f3fSDimitry Andric /// Debug common block.
31855f757f3fSDimitry Andric ///
31865f757f3fSDimitry Andric /// Uses the SubclassData32 Metadata slot.
31870b57cec5SDimitry Andric class DICommonBlock : public DIScope {
31880b57cec5SDimitry Andric   friend class LLVMContextImpl;
31890b57cec5SDimitry Andric   friend class MDNode;
31900b57cec5SDimitry Andric 
31910b57cec5SDimitry Andric   DICommonBlock(LLVMContext &Context, StorageType Storage, unsigned LineNo,
319281ad6265SDimitry Andric                 ArrayRef<Metadata *> Ops);
31930b57cec5SDimitry Andric 
31940b57cec5SDimitry Andric   static DICommonBlock *getImpl(LLVMContext &Context, DIScope *Scope,
31950b57cec5SDimitry Andric                                 DIGlobalVariable *Decl, StringRef Name,
31960b57cec5SDimitry Andric                                 DIFile *File, unsigned LineNo,
3197349cc55cSDimitry Andric                                 StorageType Storage, bool ShouldCreate = true) {
31980b57cec5SDimitry Andric     return getImpl(Context, Scope, Decl, getCanonicalMDString(Context, Name),
31990b57cec5SDimitry Andric                    File, LineNo, Storage, ShouldCreate);
32000b57cec5SDimitry Andric   }
32010b57cec5SDimitry Andric   static DICommonBlock *getImpl(LLVMContext &Context, Metadata *Scope,
32020b57cec5SDimitry Andric                                 Metadata *Decl, MDString *Name, Metadata *File,
3203349cc55cSDimitry Andric                                 unsigned LineNo, StorageType Storage,
3204349cc55cSDimitry Andric                                 bool ShouldCreate = true);
32050b57cec5SDimitry Andric 
32060b57cec5SDimitry Andric   TempDICommonBlock cloneImpl() const {
32070b57cec5SDimitry Andric     return getTemporary(getContext(), getScope(), getDecl(), getName(),
32080b57cec5SDimitry Andric                         getFile(), getLineNo());
32090b57cec5SDimitry Andric   }
32100b57cec5SDimitry Andric 
32110b57cec5SDimitry Andric public:
32120b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DICommonBlock,
32130b57cec5SDimitry Andric                     (DIScope * Scope, DIGlobalVariable *Decl, StringRef Name,
32140b57cec5SDimitry Andric                      DIFile *File, unsigned LineNo),
32150b57cec5SDimitry Andric                     (Scope, Decl, Name, File, LineNo))
32160b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DICommonBlock,
32170b57cec5SDimitry Andric                     (Metadata * Scope, Metadata *Decl, MDString *Name,
32180b57cec5SDimitry Andric                      Metadata *File, unsigned LineNo),
32190b57cec5SDimitry Andric                     (Scope, Decl, Name, File, LineNo))
32200b57cec5SDimitry Andric 
32210b57cec5SDimitry Andric   TempDICommonBlock clone() const { return cloneImpl(); }
32220b57cec5SDimitry Andric 
32230b57cec5SDimitry Andric   DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
32240b57cec5SDimitry Andric   DIGlobalVariable *getDecl() const {
32250b57cec5SDimitry Andric     return cast_or_null<DIGlobalVariable>(getRawDecl());
32260b57cec5SDimitry Andric   }
32270b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(2); }
32280b57cec5SDimitry Andric   DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
32295f757f3fSDimitry Andric   unsigned getLineNo() const { return SubclassData32; }
32300b57cec5SDimitry Andric 
32310b57cec5SDimitry Andric   Metadata *getRawScope() const { return getOperand(0); }
32320b57cec5SDimitry Andric   Metadata *getRawDecl() const { return getOperand(1); }
32330b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(2); }
32340b57cec5SDimitry Andric   Metadata *getRawFile() const { return getOperand(3); }
32350b57cec5SDimitry Andric 
32360b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
32370b57cec5SDimitry Andric     return MD->getMetadataID() == DICommonBlockKind;
32380b57cec5SDimitry Andric   }
32390b57cec5SDimitry Andric };
32400b57cec5SDimitry Andric 
32410b57cec5SDimitry Andric /// Local variable.
32420b57cec5SDimitry Andric ///
32430b57cec5SDimitry Andric /// TODO: Split up flags.
32440b57cec5SDimitry Andric class DILocalVariable : public DIVariable {
32450b57cec5SDimitry Andric   friend class LLVMContextImpl;
32460b57cec5SDimitry Andric   friend class MDNode;
32470b57cec5SDimitry Andric 
32480b57cec5SDimitry Andric   unsigned Arg : 16;
32490b57cec5SDimitry Andric   DIFlags Flags;
32500b57cec5SDimitry Andric 
32510b57cec5SDimitry Andric   DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
32520b57cec5SDimitry Andric                   unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
32530b57cec5SDimitry Andric                   ArrayRef<Metadata *> Ops)
32540b57cec5SDimitry Andric       : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
32550b57cec5SDimitry Andric         Arg(Arg), Flags(Flags) {
32560b57cec5SDimitry Andric     assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
32570b57cec5SDimitry Andric   }
32580b57cec5SDimitry Andric   ~DILocalVariable() = default;
32590b57cec5SDimitry Andric 
32600b57cec5SDimitry Andric   static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
32610b57cec5SDimitry Andric                                   StringRef Name, DIFile *File, unsigned Line,
32620b57cec5SDimitry Andric                                   DIType *Type, unsigned Arg, DIFlags Flags,
3263349cc55cSDimitry Andric                                   uint32_t AlignInBits, DINodeArray Annotations,
3264349cc55cSDimitry Andric                                   StorageType Storage,
32650b57cec5SDimitry Andric                                   bool ShouldCreate = true) {
32660b57cec5SDimitry Andric     return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
3267349cc55cSDimitry Andric                    Line, Type, Arg, Flags, AlignInBits, Annotations.get(),
3268349cc55cSDimitry Andric                    Storage, ShouldCreate);
32690b57cec5SDimitry Andric   }
32700b57cec5SDimitry Andric   static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
32710b57cec5SDimitry Andric                                   MDString *Name, Metadata *File, unsigned Line,
32720b57cec5SDimitry Andric                                   Metadata *Type, unsigned Arg, DIFlags Flags,
3273349cc55cSDimitry Andric                                   uint32_t AlignInBits, Metadata *Annotations,
3274349cc55cSDimitry Andric                                   StorageType Storage,
32750b57cec5SDimitry Andric                                   bool ShouldCreate = true);
32760b57cec5SDimitry Andric 
32770b57cec5SDimitry Andric   TempDILocalVariable cloneImpl() const {
32780b57cec5SDimitry Andric     return getTemporary(getContext(), getScope(), getName(), getFile(),
32790b57cec5SDimitry Andric                         getLine(), getType(), getArg(), getFlags(),
3280349cc55cSDimitry Andric                         getAlignInBits(), getAnnotations());
32810b57cec5SDimitry Andric   }
32820b57cec5SDimitry Andric 
32830b57cec5SDimitry Andric public:
32840b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DILocalVariable,
32850b57cec5SDimitry Andric                     (DILocalScope * Scope, StringRef Name, DIFile *File,
32860b57cec5SDimitry Andric                      unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags,
3287349cc55cSDimitry Andric                      uint32_t AlignInBits, DINodeArray Annotations),
3288349cc55cSDimitry Andric                     (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
3289349cc55cSDimitry Andric                      Annotations))
32900b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DILocalVariable,
32910b57cec5SDimitry Andric                     (Metadata * Scope, MDString *Name, Metadata *File,
3292349cc55cSDimitry Andric                      unsigned Line, Metadata *Type, unsigned Arg, DIFlags Flags,
3293349cc55cSDimitry Andric                      uint32_t AlignInBits, Metadata *Annotations),
3294349cc55cSDimitry Andric                     (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
3295349cc55cSDimitry Andric                      Annotations))
32960b57cec5SDimitry Andric 
32970b57cec5SDimitry Andric   TempDILocalVariable clone() const { return cloneImpl(); }
32980b57cec5SDimitry Andric 
32990b57cec5SDimitry Andric   /// Get the local scope for this variable.
33000b57cec5SDimitry Andric   ///
33010b57cec5SDimitry Andric   /// Variables must be defined in a local scope.
33020b57cec5SDimitry Andric   DILocalScope *getScope() const {
33030b57cec5SDimitry Andric     return cast<DILocalScope>(DIVariable::getScope());
33040b57cec5SDimitry Andric   }
33050b57cec5SDimitry Andric 
33060b57cec5SDimitry Andric   bool isParameter() const { return Arg; }
33070b57cec5SDimitry Andric   unsigned getArg() const { return Arg; }
33080b57cec5SDimitry Andric   DIFlags getFlags() const { return Flags; }
33090b57cec5SDimitry Andric 
3310349cc55cSDimitry Andric   DINodeArray getAnnotations() const {
3311349cc55cSDimitry Andric     return cast_or_null<MDTuple>(getRawAnnotations());
3312349cc55cSDimitry Andric   }
3313349cc55cSDimitry Andric   Metadata *getRawAnnotations() const { return getOperand(4); }
3314349cc55cSDimitry Andric 
33150b57cec5SDimitry Andric   bool isArtificial() const { return getFlags() & FlagArtificial; }
33160b57cec5SDimitry Andric   bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
33170b57cec5SDimitry Andric 
33180b57cec5SDimitry Andric   /// Check that a location is valid for this variable.
33190b57cec5SDimitry Andric   ///
33200b57cec5SDimitry Andric   /// Check that \c DL exists, is in the same subprogram, and has the same
33210b57cec5SDimitry Andric   /// inlined-at location as \c this.  (Otherwise, it's not a valid attachment
33220b57cec5SDimitry Andric   /// to a \a DbgInfoIntrinsic.)
33230b57cec5SDimitry Andric   bool isValidLocationForIntrinsic(const DILocation *DL) const {
33240b57cec5SDimitry Andric     return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
33250b57cec5SDimitry Andric   }
33260b57cec5SDimitry Andric 
33270b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
33280b57cec5SDimitry Andric     return MD->getMetadataID() == DILocalVariableKind;
33290b57cec5SDimitry Andric   }
33300b57cec5SDimitry Andric };
33310b57cec5SDimitry Andric 
33320b57cec5SDimitry Andric /// Label.
33330b57cec5SDimitry Andric ///
33345f757f3fSDimitry Andric /// Uses the SubclassData32 Metadata slot.
33350b57cec5SDimitry Andric class DILabel : public DINode {
33360b57cec5SDimitry Andric   friend class LLVMContextImpl;
33370b57cec5SDimitry Andric   friend class MDNode;
33380b57cec5SDimitry Andric 
33390b57cec5SDimitry Andric   DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
334081ad6265SDimitry Andric           ArrayRef<Metadata *> Ops);
33410b57cec5SDimitry Andric   ~DILabel() = default;
33420b57cec5SDimitry Andric 
3343349cc55cSDimitry Andric   static DILabel *getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
3344349cc55cSDimitry Andric                           DIFile *File, unsigned Line, StorageType Storage,
33450b57cec5SDimitry Andric                           bool ShouldCreate = true) {
33460b57cec5SDimitry Andric     return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
33470b57cec5SDimitry Andric                    Line, Storage, ShouldCreate);
33480b57cec5SDimitry Andric   }
3349349cc55cSDimitry Andric   static DILabel *getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
3350349cc55cSDimitry Andric                           Metadata *File, unsigned Line, StorageType Storage,
33510b57cec5SDimitry Andric                           bool ShouldCreate = true);
33520b57cec5SDimitry Andric 
33530b57cec5SDimitry Andric   TempDILabel cloneImpl() const {
33540b57cec5SDimitry Andric     return getTemporary(getContext(), getScope(), getName(), getFile(),
33550b57cec5SDimitry Andric                         getLine());
33560b57cec5SDimitry Andric   }
33570b57cec5SDimitry Andric 
33580b57cec5SDimitry Andric public:
33590b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DILabel,
33600b57cec5SDimitry Andric                     (DILocalScope * Scope, StringRef Name, DIFile *File,
33610b57cec5SDimitry Andric                      unsigned Line),
33620b57cec5SDimitry Andric                     (Scope, Name, File, Line))
33630b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DILabel,
33640b57cec5SDimitry Andric                     (Metadata * Scope, MDString *Name, Metadata *File,
33650b57cec5SDimitry Andric                      unsigned Line),
33660b57cec5SDimitry Andric                     (Scope, Name, File, Line))
33670b57cec5SDimitry Andric 
33680b57cec5SDimitry Andric   TempDILabel clone() const { return cloneImpl(); }
33690b57cec5SDimitry Andric 
33700b57cec5SDimitry Andric   /// Get the local scope for this label.
33710b57cec5SDimitry Andric   ///
33720b57cec5SDimitry Andric   /// Labels must be defined in a local scope.
33730b57cec5SDimitry Andric   DILocalScope *getScope() const {
33740b57cec5SDimitry Andric     return cast_or_null<DILocalScope>(getRawScope());
33750b57cec5SDimitry Andric   }
33765f757f3fSDimitry Andric   unsigned getLine() const { return SubclassData32; }
33770b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(1); }
33780b57cec5SDimitry Andric   DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
33790b57cec5SDimitry Andric 
33800b57cec5SDimitry Andric   Metadata *getRawScope() const { return getOperand(0); }
33810b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(1); }
33820b57cec5SDimitry Andric   Metadata *getRawFile() const { return getOperand(2); }
33830b57cec5SDimitry Andric 
33840b57cec5SDimitry Andric   /// Check that a location is valid for this label.
33850b57cec5SDimitry Andric   ///
33860b57cec5SDimitry Andric   /// Check that \c DL exists, is in the same subprogram, and has the same
33870b57cec5SDimitry Andric   /// inlined-at location as \c this.  (Otherwise, it's not a valid attachment
33880b57cec5SDimitry Andric   /// to a \a DbgInfoIntrinsic.)
33890b57cec5SDimitry Andric   bool isValidLocationForIntrinsic(const DILocation *DL) const {
33900b57cec5SDimitry Andric     return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
33910b57cec5SDimitry Andric   }
33920b57cec5SDimitry Andric 
33930b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
33940b57cec5SDimitry Andric     return MD->getMetadataID() == DILabelKind;
33950b57cec5SDimitry Andric   }
33960b57cec5SDimitry Andric };
33970b57cec5SDimitry Andric 
33980b57cec5SDimitry Andric class DIObjCProperty : public DINode {
33990b57cec5SDimitry Andric   friend class LLVMContextImpl;
34000b57cec5SDimitry Andric   friend class MDNode;
34010b57cec5SDimitry Andric 
34020b57cec5SDimitry Andric   unsigned Line;
34030b57cec5SDimitry Andric   unsigned Attributes;
34040b57cec5SDimitry Andric 
34050b57cec5SDimitry Andric   DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
340681ad6265SDimitry Andric                  unsigned Attributes, ArrayRef<Metadata *> Ops);
34070b57cec5SDimitry Andric   ~DIObjCProperty() = default;
34080b57cec5SDimitry Andric 
34090b57cec5SDimitry Andric   static DIObjCProperty *
34100b57cec5SDimitry Andric   getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
34110b57cec5SDimitry Andric           StringRef GetterName, StringRef SetterName, unsigned Attributes,
34120b57cec5SDimitry Andric           DIType *Type, StorageType Storage, bool ShouldCreate = true) {
34130b57cec5SDimitry Andric     return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
34140b57cec5SDimitry Andric                    getCanonicalMDString(Context, GetterName),
34150b57cec5SDimitry Andric                    getCanonicalMDString(Context, SetterName), Attributes, Type,
34160b57cec5SDimitry Andric                    Storage, ShouldCreate);
34170b57cec5SDimitry Andric   }
34180b57cec5SDimitry Andric   static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
34190b57cec5SDimitry Andric                                  Metadata *File, unsigned Line,
34200b57cec5SDimitry Andric                                  MDString *GetterName, MDString *SetterName,
34210b57cec5SDimitry Andric                                  unsigned Attributes, Metadata *Type,
34220b57cec5SDimitry Andric                                  StorageType Storage, bool ShouldCreate = true);
34230b57cec5SDimitry Andric 
34240b57cec5SDimitry Andric   TempDIObjCProperty cloneImpl() const {
34250b57cec5SDimitry Andric     return getTemporary(getContext(), getName(), getFile(), getLine(),
34260b57cec5SDimitry Andric                         getGetterName(), getSetterName(), getAttributes(),
34270b57cec5SDimitry Andric                         getType());
34280b57cec5SDimitry Andric   }
34290b57cec5SDimitry Andric 
34300b57cec5SDimitry Andric public:
34310b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIObjCProperty,
34320b57cec5SDimitry Andric                     (StringRef Name, DIFile *File, unsigned Line,
34330b57cec5SDimitry Andric                      StringRef GetterName, StringRef SetterName,
34340b57cec5SDimitry Andric                      unsigned Attributes, DIType *Type),
34350b57cec5SDimitry Andric                     (Name, File, Line, GetterName, SetterName, Attributes,
34360b57cec5SDimitry Andric                      Type))
34370b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIObjCProperty,
34380b57cec5SDimitry Andric                     (MDString * Name, Metadata *File, unsigned Line,
34390b57cec5SDimitry Andric                      MDString *GetterName, MDString *SetterName,
34400b57cec5SDimitry Andric                      unsigned Attributes, Metadata *Type),
34410b57cec5SDimitry Andric                     (Name, File, Line, GetterName, SetterName, Attributes,
34420b57cec5SDimitry Andric                      Type))
34430b57cec5SDimitry Andric 
34440b57cec5SDimitry Andric   TempDIObjCProperty clone() const { return cloneImpl(); }
34450b57cec5SDimitry Andric 
34460b57cec5SDimitry Andric   unsigned getLine() const { return Line; }
34470b57cec5SDimitry Andric   unsigned getAttributes() const { return Attributes; }
34480b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(0); }
34490b57cec5SDimitry Andric   DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
34500b57cec5SDimitry Andric   StringRef getGetterName() const { return getStringOperand(2); }
34510b57cec5SDimitry Andric   StringRef getSetterName() const { return getStringOperand(3); }
34520b57cec5SDimitry Andric   DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
34530b57cec5SDimitry Andric 
34540b57cec5SDimitry Andric   StringRef getFilename() const {
34550b57cec5SDimitry Andric     if (auto *F = getFile())
34560b57cec5SDimitry Andric       return F->getFilename();
34570b57cec5SDimitry Andric     return "";
34580b57cec5SDimitry Andric   }
34590b57cec5SDimitry Andric 
34600b57cec5SDimitry Andric   StringRef getDirectory() const {
34610b57cec5SDimitry Andric     if (auto *F = getFile())
34620b57cec5SDimitry Andric       return F->getDirectory();
34630b57cec5SDimitry Andric     return "";
34640b57cec5SDimitry Andric   }
34650b57cec5SDimitry Andric 
34660b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(0); }
34670b57cec5SDimitry Andric   Metadata *getRawFile() const { return getOperand(1); }
34680b57cec5SDimitry Andric   MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
34690b57cec5SDimitry Andric   MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
34700b57cec5SDimitry Andric   Metadata *getRawType() const { return getOperand(4); }
34710b57cec5SDimitry Andric 
34720b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
34730b57cec5SDimitry Andric     return MD->getMetadataID() == DIObjCPropertyKind;
34740b57cec5SDimitry Andric   }
34750b57cec5SDimitry Andric };
34760b57cec5SDimitry Andric 
34770b57cec5SDimitry Andric /// An imported module (C++ using directive or similar).
34785f757f3fSDimitry Andric ///
34795f757f3fSDimitry Andric /// Uses the SubclassData32 Metadata slot.
34800b57cec5SDimitry Andric class DIImportedEntity : public DINode {
34810b57cec5SDimitry Andric   friend class LLVMContextImpl;
34820b57cec5SDimitry Andric   friend class MDNode;
34830b57cec5SDimitry Andric 
34840b57cec5SDimitry Andric   DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
34850b57cec5SDimitry Andric                    unsigned Line, ArrayRef<Metadata *> Ops)
34865f757f3fSDimitry Andric       : DINode(C, DIImportedEntityKind, Storage, Tag, Ops) {
34875f757f3fSDimitry Andric     SubclassData32 = Line;
34885f757f3fSDimitry Andric   }
34890b57cec5SDimitry Andric   ~DIImportedEntity() = default;
34900b57cec5SDimitry Andric 
34910b57cec5SDimitry Andric   static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
34920b57cec5SDimitry Andric                                    DIScope *Scope, DINode *Entity, DIFile *File,
34930b57cec5SDimitry Andric                                    unsigned Line, StringRef Name,
3494349cc55cSDimitry Andric                                    DINodeArray Elements, StorageType Storage,
34950b57cec5SDimitry Andric                                    bool ShouldCreate = true) {
34960b57cec5SDimitry Andric     return getImpl(Context, Tag, Scope, Entity, File, Line,
3497349cc55cSDimitry Andric                    getCanonicalMDString(Context, Name), Elements.get(), Storage,
3498349cc55cSDimitry Andric                    ShouldCreate);
34990b57cec5SDimitry Andric   }
3500349cc55cSDimitry Andric   static DIImportedEntity *
3501349cc55cSDimitry Andric   getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, Metadata *Entity,
3502349cc55cSDimitry Andric           Metadata *File, unsigned Line, MDString *Name, Metadata *Elements,
3503349cc55cSDimitry Andric           StorageType Storage, bool ShouldCreate = true);
35040b57cec5SDimitry Andric 
35050b57cec5SDimitry Andric   TempDIImportedEntity cloneImpl() const {
35060b57cec5SDimitry Andric     return getTemporary(getContext(), getTag(), getScope(), getEntity(),
3507349cc55cSDimitry Andric                         getFile(), getLine(), getName(), getElements());
35080b57cec5SDimitry Andric   }
35090b57cec5SDimitry Andric 
35100b57cec5SDimitry Andric public:
35110b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIImportedEntity,
35120b57cec5SDimitry Andric                     (unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File,
3513349cc55cSDimitry Andric                      unsigned Line, StringRef Name = "",
3514349cc55cSDimitry Andric                      DINodeArray Elements = nullptr),
3515349cc55cSDimitry Andric                     (Tag, Scope, Entity, File, Line, Name, Elements))
35160b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIImportedEntity,
35170b57cec5SDimitry Andric                     (unsigned Tag, Metadata *Scope, Metadata *Entity,
3518349cc55cSDimitry Andric                      Metadata *File, unsigned Line, MDString *Name,
3519349cc55cSDimitry Andric                      Metadata *Elements = nullptr),
3520349cc55cSDimitry Andric                     (Tag, Scope, Entity, File, Line, Name, Elements))
35210b57cec5SDimitry Andric 
35220b57cec5SDimitry Andric   TempDIImportedEntity clone() const { return cloneImpl(); }
35230b57cec5SDimitry Andric 
35245f757f3fSDimitry Andric   unsigned getLine() const { return SubclassData32; }
35250b57cec5SDimitry Andric   DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
35260b57cec5SDimitry Andric   DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); }
35270b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(2); }
35280b57cec5SDimitry Andric   DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3529349cc55cSDimitry Andric   DINodeArray getElements() const {
3530349cc55cSDimitry Andric     return cast_or_null<MDTuple>(getRawElements());
3531349cc55cSDimitry Andric   }
35320b57cec5SDimitry Andric 
35330b57cec5SDimitry Andric   Metadata *getRawScope() const { return getOperand(0); }
35340b57cec5SDimitry Andric   Metadata *getRawEntity() const { return getOperand(1); }
35350b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(2); }
35360b57cec5SDimitry Andric   Metadata *getRawFile() const { return getOperand(3); }
3537349cc55cSDimitry Andric   Metadata *getRawElements() const { return getOperand(4); }
35380b57cec5SDimitry Andric 
35390b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
35400b57cec5SDimitry Andric     return MD->getMetadataID() == DIImportedEntityKind;
35410b57cec5SDimitry Andric   }
35420b57cec5SDimitry Andric };
35430b57cec5SDimitry Andric 
35440b57cec5SDimitry Andric /// A pair of DIGlobalVariable and DIExpression.
35450b57cec5SDimitry Andric class DIGlobalVariableExpression : public MDNode {
35460b57cec5SDimitry Andric   friend class LLVMContextImpl;
35470b57cec5SDimitry Andric   friend class MDNode;
35480b57cec5SDimitry Andric 
35490b57cec5SDimitry Andric   DIGlobalVariableExpression(LLVMContext &C, StorageType Storage,
35500b57cec5SDimitry Andric                              ArrayRef<Metadata *> Ops)
35510b57cec5SDimitry Andric       : MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
35520b57cec5SDimitry Andric   ~DIGlobalVariableExpression() = default;
35530b57cec5SDimitry Andric 
35540b57cec5SDimitry Andric   static DIGlobalVariableExpression *
35550b57cec5SDimitry Andric   getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
35560b57cec5SDimitry Andric           StorageType Storage, bool ShouldCreate = true);
35570b57cec5SDimitry Andric 
35580b57cec5SDimitry Andric   TempDIGlobalVariableExpression cloneImpl() const {
35590b57cec5SDimitry Andric     return getTemporary(getContext(), getVariable(), getExpression());
35600b57cec5SDimitry Andric   }
35610b57cec5SDimitry Andric 
35620b57cec5SDimitry Andric public:
35630b57cec5SDimitry Andric   DEFINE_MDNODE_GET(DIGlobalVariableExpression,
35640b57cec5SDimitry Andric                     (Metadata * Variable, Metadata *Expression),
35650b57cec5SDimitry Andric                     (Variable, Expression))
35660b57cec5SDimitry Andric 
35670b57cec5SDimitry Andric   TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
35680b57cec5SDimitry Andric 
35690b57cec5SDimitry Andric   Metadata *getRawVariable() const { return getOperand(0); }
35700b57cec5SDimitry Andric 
35710b57cec5SDimitry Andric   DIGlobalVariable *getVariable() const {
35720b57cec5SDimitry Andric     return cast_or_null<DIGlobalVariable>(getRawVariable());
35730b57cec5SDimitry Andric   }
35740b57cec5SDimitry Andric 
35750b57cec5SDimitry Andric   Metadata *getRawExpression() const { return getOperand(1); }
35760b57cec5SDimitry Andric 
35770b57cec5SDimitry Andric   DIExpression *getExpression() const {
35780b57cec5SDimitry Andric     return cast<DIExpression>(getRawExpression());
35790b57cec5SDimitry Andric   }
35800b57cec5SDimitry Andric 
35810b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
35820b57cec5SDimitry Andric     return MD->getMetadataID() == DIGlobalVariableExpressionKind;
35830b57cec5SDimitry Andric   }
35840b57cec5SDimitry Andric };
35850b57cec5SDimitry Andric 
35860b57cec5SDimitry Andric /// Macro Info DWARF-like metadata node.
35870b57cec5SDimitry Andric ///
35880b57cec5SDimitry Andric /// A metadata node with a DWARF macro info (i.e., a constant named
35890b57cec5SDimitry Andric /// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h).  Called \a
35900b57cec5SDimitry Andric /// DIMacroNode
35910b57cec5SDimitry Andric /// because it's potentially used for non-DWARF output.
35925f757f3fSDimitry Andric ///
35935f757f3fSDimitry Andric /// Uses the SubclassData16 Metadata slot.
35940b57cec5SDimitry Andric class DIMacroNode : public MDNode {
35950b57cec5SDimitry Andric   friend class LLVMContextImpl;
35960b57cec5SDimitry Andric   friend class MDNode;
35970b57cec5SDimitry Andric 
35980b57cec5SDimitry Andric protected:
35990b57cec5SDimitry Andric   DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
3600bdd1243dSDimitry Andric               ArrayRef<Metadata *> Ops1,
3601bdd1243dSDimitry Andric               ArrayRef<Metadata *> Ops2 = std::nullopt)
36020b57cec5SDimitry Andric       : MDNode(C, ID, Storage, Ops1, Ops2) {
36030b57cec5SDimitry Andric     assert(MIType < 1u << 16);
36040b57cec5SDimitry Andric     SubclassData16 = MIType;
36050b57cec5SDimitry Andric   }
36060b57cec5SDimitry Andric   ~DIMacroNode() = default;
36070b57cec5SDimitry Andric 
36080b57cec5SDimitry Andric   template <class Ty> Ty *getOperandAs(unsigned I) const {
36090b57cec5SDimitry Andric     return cast_or_null<Ty>(getOperand(I));
36100b57cec5SDimitry Andric   }
36110b57cec5SDimitry Andric 
36120b57cec5SDimitry Andric   StringRef getStringOperand(unsigned I) const {
36130b57cec5SDimitry Andric     if (auto *S = getOperandAs<MDString>(I))
36140b57cec5SDimitry Andric       return S->getString();
36150b57cec5SDimitry Andric     return StringRef();
36160b57cec5SDimitry Andric   }
36170b57cec5SDimitry Andric 
36180b57cec5SDimitry Andric   static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
36190b57cec5SDimitry Andric     if (S.empty())
36200b57cec5SDimitry Andric       return nullptr;
36210b57cec5SDimitry Andric     return MDString::get(Context, S);
36220b57cec5SDimitry Andric   }
36230b57cec5SDimitry Andric 
36240b57cec5SDimitry Andric public:
36250b57cec5SDimitry Andric   unsigned getMacinfoType() const { return SubclassData16; }
36260b57cec5SDimitry Andric 
36270b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
36280b57cec5SDimitry Andric     switch (MD->getMetadataID()) {
36290b57cec5SDimitry Andric     default:
36300b57cec5SDimitry Andric       return false;
36310b57cec5SDimitry Andric     case DIMacroKind:
36320b57cec5SDimitry Andric     case DIMacroFileKind:
36330b57cec5SDimitry Andric       return true;
36340b57cec5SDimitry Andric     }
36350b57cec5SDimitry Andric   }
36360b57cec5SDimitry Andric };
36370b57cec5SDimitry Andric 
36385f757f3fSDimitry Andric /// Macro
36395f757f3fSDimitry Andric ///
36405f757f3fSDimitry Andric /// Uses the SubclassData32 Metadata slot.
36410b57cec5SDimitry Andric class DIMacro : public DIMacroNode {
36420b57cec5SDimitry Andric   friend class LLVMContextImpl;
36430b57cec5SDimitry Andric   friend class MDNode;
36440b57cec5SDimitry Andric 
36450b57cec5SDimitry Andric   DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
36460b57cec5SDimitry Andric           ArrayRef<Metadata *> Ops)
36475f757f3fSDimitry Andric       : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops) {
36485f757f3fSDimitry Andric     SubclassData32 = Line;
36495f757f3fSDimitry Andric   }
36500b57cec5SDimitry Andric   ~DIMacro() = default;
36510b57cec5SDimitry Andric 
36520b57cec5SDimitry Andric   static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
36530b57cec5SDimitry Andric                           StringRef Name, StringRef Value, StorageType Storage,
36540b57cec5SDimitry Andric                           bool ShouldCreate = true) {
36550b57cec5SDimitry Andric     return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
36560b57cec5SDimitry Andric                    getCanonicalMDString(Context, Value), Storage, ShouldCreate);
36570b57cec5SDimitry Andric   }
36580b57cec5SDimitry Andric   static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
36590b57cec5SDimitry Andric                           MDString *Name, MDString *Value, StorageType Storage,
36600b57cec5SDimitry Andric                           bool ShouldCreate = true);
36610b57cec5SDimitry Andric 
36620b57cec5SDimitry Andric   TempDIMacro cloneImpl() const {
36630b57cec5SDimitry Andric     return getTemporary(getContext(), getMacinfoType(), getLine(), getName(),
36640b57cec5SDimitry Andric                         getValue());
36650b57cec5SDimitry Andric   }
36660b57cec5SDimitry Andric 
36670b57cec5SDimitry Andric public:
3668349cc55cSDimitry Andric   DEFINE_MDNODE_GET(DIMacro,
3669349cc55cSDimitry Andric                     (unsigned MIType, unsigned Line, StringRef Name,
36700b57cec5SDimitry Andric                      StringRef Value = ""),
36710b57cec5SDimitry Andric                     (MIType, Line, Name, Value))
3672349cc55cSDimitry Andric   DEFINE_MDNODE_GET(DIMacro,
3673349cc55cSDimitry Andric                     (unsigned MIType, unsigned Line, MDString *Name,
36740b57cec5SDimitry Andric                      MDString *Value),
36750b57cec5SDimitry Andric                     (MIType, Line, Name, Value))
36760b57cec5SDimitry Andric 
36770b57cec5SDimitry Andric   TempDIMacro clone() const { return cloneImpl(); }
36780b57cec5SDimitry Andric 
36795f757f3fSDimitry Andric   unsigned getLine() const { return SubclassData32; }
36800b57cec5SDimitry Andric 
36810b57cec5SDimitry Andric   StringRef getName() const { return getStringOperand(0); }
36820b57cec5SDimitry Andric   StringRef getValue() const { return getStringOperand(1); }
36830b57cec5SDimitry Andric 
36840b57cec5SDimitry Andric   MDString *getRawName() const { return getOperandAs<MDString>(0); }
36850b57cec5SDimitry Andric   MDString *getRawValue() const { return getOperandAs<MDString>(1); }
36860b57cec5SDimitry Andric 
36870b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
36880b57cec5SDimitry Andric     return MD->getMetadataID() == DIMacroKind;
36890b57cec5SDimitry Andric   }
36900b57cec5SDimitry Andric };
36910b57cec5SDimitry Andric 
36925f757f3fSDimitry Andric /// Macro file
36935f757f3fSDimitry Andric ///
36945f757f3fSDimitry Andric /// Uses the SubclassData32 Metadata slot.
36950b57cec5SDimitry Andric class DIMacroFile : public DIMacroNode {
36960b57cec5SDimitry Andric   friend class LLVMContextImpl;
36970b57cec5SDimitry Andric   friend class MDNode;
36980b57cec5SDimitry Andric 
36990b57cec5SDimitry Andric   DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
37000b57cec5SDimitry Andric               unsigned Line, ArrayRef<Metadata *> Ops)
37015f757f3fSDimitry Andric       : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops) {
37025f757f3fSDimitry Andric     SubclassData32 = Line;
37035f757f3fSDimitry Andric   }
37040b57cec5SDimitry Andric   ~DIMacroFile() = default;
37050b57cec5SDimitry Andric 
37060b57cec5SDimitry Andric   static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
37070b57cec5SDimitry Andric                               unsigned Line, DIFile *File,
37080b57cec5SDimitry Andric                               DIMacroNodeArray Elements, StorageType Storage,
37090b57cec5SDimitry Andric                               bool ShouldCreate = true) {
37100b57cec5SDimitry Andric     return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
37110b57cec5SDimitry Andric                    Elements.get(), Storage, ShouldCreate);
37120b57cec5SDimitry Andric   }
37130b57cec5SDimitry Andric 
37140b57cec5SDimitry Andric   static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
37150b57cec5SDimitry Andric                               unsigned Line, Metadata *File, Metadata *Elements,
37160b57cec5SDimitry Andric                               StorageType Storage, bool ShouldCreate = true);
37170b57cec5SDimitry Andric 
37180b57cec5SDimitry Andric   TempDIMacroFile cloneImpl() const {
37190b57cec5SDimitry Andric     return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(),
37200b57cec5SDimitry Andric                         getElements());
37210b57cec5SDimitry Andric   }
37220b57cec5SDimitry Andric 
37230b57cec5SDimitry Andric public:
3724349cc55cSDimitry Andric   DEFINE_MDNODE_GET(DIMacroFile,
3725349cc55cSDimitry Andric                     (unsigned MIType, unsigned Line, DIFile *File,
37260b57cec5SDimitry Andric                      DIMacroNodeArray Elements),
37270b57cec5SDimitry Andric                     (MIType, Line, File, Elements))
3728349cc55cSDimitry Andric   DEFINE_MDNODE_GET(DIMacroFile,
3729349cc55cSDimitry Andric                     (unsigned MIType, unsigned Line, Metadata *File,
3730349cc55cSDimitry Andric                      Metadata *Elements),
37310b57cec5SDimitry Andric                     (MIType, Line, File, Elements))
37320b57cec5SDimitry Andric 
37330b57cec5SDimitry Andric   TempDIMacroFile clone() const { return cloneImpl(); }
37340b57cec5SDimitry Andric 
37350b57cec5SDimitry Andric   void replaceElements(DIMacroNodeArray Elements) {
37360b57cec5SDimitry Andric #ifndef NDEBUG
37370b57cec5SDimitry Andric     for (DIMacroNode *Op : getElements())
37380b57cec5SDimitry Andric       assert(is_contained(Elements->operands(), Op) &&
37390b57cec5SDimitry Andric              "Lost a macro node during macro node list replacement");
37400b57cec5SDimitry Andric #endif
37410b57cec5SDimitry Andric     replaceOperandWith(1, Elements.get());
37420b57cec5SDimitry Andric   }
37430b57cec5SDimitry Andric 
37445f757f3fSDimitry Andric   unsigned getLine() const { return SubclassData32; }
37450b57cec5SDimitry Andric   DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
37460b57cec5SDimitry Andric 
37470b57cec5SDimitry Andric   DIMacroNodeArray getElements() const {
37480b57cec5SDimitry Andric     return cast_or_null<MDTuple>(getRawElements());
37490b57cec5SDimitry Andric   }
37500b57cec5SDimitry Andric 
37510b57cec5SDimitry Andric   Metadata *getRawFile() const { return getOperand(0); }
37520b57cec5SDimitry Andric   Metadata *getRawElements() const { return getOperand(1); }
37530b57cec5SDimitry Andric 
37540b57cec5SDimitry Andric   static bool classof(const Metadata *MD) {
37550b57cec5SDimitry Andric     return MD->getMetadataID() == DIMacroFileKind;
37560b57cec5SDimitry Andric   }
37570b57cec5SDimitry Andric };
37580b57cec5SDimitry Andric 
3759fe6060f1SDimitry Andric /// List of ValueAsMetadata, to be used as an argument to a dbg.value
3760fe6060f1SDimitry Andric /// intrinsic.
37615f757f3fSDimitry Andric class DIArgList : public Metadata, ReplaceableMetadataImpl {
37625f757f3fSDimitry Andric   friend class ReplaceableMetadataImpl;
3763fe6060f1SDimitry Andric   friend class LLVMContextImpl;
3764fe6060f1SDimitry Andric   using iterator = SmallVectorImpl<ValueAsMetadata *>::iterator;
3765fe6060f1SDimitry Andric 
3766fe6060f1SDimitry Andric   SmallVector<ValueAsMetadata *, 4> Args;
3767fe6060f1SDimitry Andric 
37685f757f3fSDimitry Andric   DIArgList(LLVMContext &Context, ArrayRef<ValueAsMetadata *> Args)
37695f757f3fSDimitry Andric       : Metadata(DIArgListKind, Uniqued), ReplaceableMetadataImpl(Context),
3770fe6060f1SDimitry Andric         Args(Args.begin(), Args.end()) {
3771fe6060f1SDimitry Andric     track();
3772fe6060f1SDimitry Andric   }
3773fe6060f1SDimitry Andric   ~DIArgList() { untrack(); }
3774fe6060f1SDimitry Andric 
3775fe6060f1SDimitry Andric   void track();
3776fe6060f1SDimitry Andric   void untrack();
37775f757f3fSDimitry Andric   void dropAllReferences(bool Untrack);
3778fe6060f1SDimitry Andric 
3779fe6060f1SDimitry Andric public:
37805f757f3fSDimitry Andric   static DIArgList *get(LLVMContext &Context, ArrayRef<ValueAsMetadata *> Args);
3781fe6060f1SDimitry Andric 
3782fe6060f1SDimitry Andric   ArrayRef<ValueAsMetadata *> getArgs() const { return Args; }
3783fe6060f1SDimitry Andric 
3784fe6060f1SDimitry Andric   iterator args_begin() { return Args.begin(); }
3785fe6060f1SDimitry Andric   iterator args_end() { return Args.end(); }
3786fe6060f1SDimitry Andric 
3787fe6060f1SDimitry Andric   static bool classof(const Metadata *MD) {
3788fe6060f1SDimitry Andric     return MD->getMetadataID() == DIArgListKind;
3789fe6060f1SDimitry Andric   }
3790fe6060f1SDimitry Andric 
37915f757f3fSDimitry Andric   SmallVector<DPValue *> getAllDPValueUsers() {
37925f757f3fSDimitry Andric     return ReplaceableMetadataImpl::getAllDPValueUsers();
37935f757f3fSDimitry Andric   }
37945f757f3fSDimitry Andric 
3795fe6060f1SDimitry Andric   void handleChangedOperand(void *Ref, Metadata *New);
3796fe6060f1SDimitry Andric };
3797fe6060f1SDimitry Andric 
3798480093f4SDimitry Andric /// Identifies a unique instance of a variable.
3799480093f4SDimitry Andric ///
3800480093f4SDimitry Andric /// Storage for identifying a potentially inlined instance of a variable,
3801480093f4SDimitry Andric /// or a fragment thereof. This guarantees that exactly one variable instance
3802480093f4SDimitry Andric /// may be identified by this class, even when that variable is a fragment of
3803480093f4SDimitry Andric /// an aggregate variable and/or there is another inlined instance of the same
3804480093f4SDimitry Andric /// source code variable nearby.
3805480093f4SDimitry Andric /// This class does not necessarily uniquely identify that variable: it is
3806480093f4SDimitry Andric /// possible that a DebugVariable with different parameters may point to the
3807480093f4SDimitry Andric /// same variable instance, but not that one DebugVariable points to multiple
3808480093f4SDimitry Andric /// variable instances.
3809480093f4SDimitry Andric class DebugVariable {
3810480093f4SDimitry Andric   using FragmentInfo = DIExpression::FragmentInfo;
3811480093f4SDimitry Andric 
3812480093f4SDimitry Andric   const DILocalVariable *Variable;
3813bdd1243dSDimitry Andric   std::optional<FragmentInfo> Fragment;
3814480093f4SDimitry Andric   const DILocation *InlinedAt;
3815480093f4SDimitry Andric 
3816480093f4SDimitry Andric   /// Fragment that will overlap all other fragments. Used as default when
3817480093f4SDimitry Andric   /// caller demands a fragment.
3818480093f4SDimitry Andric   static const FragmentInfo DefaultFragment;
3819480093f4SDimitry Andric 
3820480093f4SDimitry Andric public:
3821bdd1243dSDimitry Andric   DebugVariable(const DbgVariableIntrinsic *DII);
38225f757f3fSDimitry Andric   DebugVariable(const DPValue *DPV);
3823bdd1243dSDimitry Andric 
3824bdd1243dSDimitry Andric   DebugVariable(const DILocalVariable *Var,
3825bdd1243dSDimitry Andric                 std::optional<FragmentInfo> FragmentInfo,
3826480093f4SDimitry Andric                 const DILocation *InlinedAt)
3827480093f4SDimitry Andric       : Variable(Var), Fragment(FragmentInfo), InlinedAt(InlinedAt) {}
3828480093f4SDimitry Andric 
3829480093f4SDimitry Andric   DebugVariable(const DILocalVariable *Var, const DIExpression *DIExpr,
3830480093f4SDimitry Andric                 const DILocation *InlinedAt)
3831480093f4SDimitry Andric       : Variable(Var),
3832bdd1243dSDimitry Andric         Fragment(DIExpr ? DIExpr->getFragmentInfo() : std::nullopt),
3833480093f4SDimitry Andric         InlinedAt(InlinedAt) {}
3834480093f4SDimitry Andric 
3835480093f4SDimitry Andric   const DILocalVariable *getVariable() const { return Variable; }
3836bdd1243dSDimitry Andric   std::optional<FragmentInfo> getFragment() const { return Fragment; }
3837480093f4SDimitry Andric   const DILocation *getInlinedAt() const { return InlinedAt; }
3838480093f4SDimitry Andric 
3839fe6060f1SDimitry Andric   FragmentInfo getFragmentOrDefault() const {
384081ad6265SDimitry Andric     return Fragment.value_or(DefaultFragment);
3841480093f4SDimitry Andric   }
3842480093f4SDimitry Andric 
3843480093f4SDimitry Andric   static bool isDefaultFragment(const FragmentInfo F) {
3844480093f4SDimitry Andric     return F == DefaultFragment;
3845480093f4SDimitry Andric   }
3846480093f4SDimitry Andric 
3847480093f4SDimitry Andric   bool operator==(const DebugVariable &Other) const {
3848480093f4SDimitry Andric     return std::tie(Variable, Fragment, InlinedAt) ==
3849480093f4SDimitry Andric            std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
3850480093f4SDimitry Andric   }
3851480093f4SDimitry Andric 
3852480093f4SDimitry Andric   bool operator<(const DebugVariable &Other) const {
3853480093f4SDimitry Andric     return std::tie(Variable, Fragment, InlinedAt) <
3854480093f4SDimitry Andric            std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
3855480093f4SDimitry Andric   }
3856480093f4SDimitry Andric };
3857480093f4SDimitry Andric 
3858480093f4SDimitry Andric template <> struct DenseMapInfo<DebugVariable> {
3859480093f4SDimitry Andric   using FragmentInfo = DIExpression::FragmentInfo;
3860480093f4SDimitry Andric 
3861480093f4SDimitry Andric   /// Empty key: no key should be generated that has no DILocalVariable.
3862480093f4SDimitry Andric   static inline DebugVariable getEmptyKey() {
3863bdd1243dSDimitry Andric     return DebugVariable(nullptr, std::nullopt, nullptr);
3864480093f4SDimitry Andric   }
3865480093f4SDimitry Andric 
3866480093f4SDimitry Andric   /// Difference in tombstone is that the Optional is meaningful.
3867480093f4SDimitry Andric   static inline DebugVariable getTombstoneKey() {
3868480093f4SDimitry Andric     return DebugVariable(nullptr, {{0, 0}}, nullptr);
3869480093f4SDimitry Andric   }
3870480093f4SDimitry Andric 
3871480093f4SDimitry Andric   static unsigned getHashValue(const DebugVariable &D) {
3872480093f4SDimitry Andric     unsigned HV = 0;
3873bdd1243dSDimitry Andric     const std::optional<FragmentInfo> Fragment = D.getFragment();
3874480093f4SDimitry Andric     if (Fragment)
3875480093f4SDimitry Andric       HV = DenseMapInfo<FragmentInfo>::getHashValue(*Fragment);
3876480093f4SDimitry Andric 
3877480093f4SDimitry Andric     return hash_combine(D.getVariable(), HV, D.getInlinedAt());
3878480093f4SDimitry Andric   }
3879480093f4SDimitry Andric 
3880480093f4SDimitry Andric   static bool isEqual(const DebugVariable &A, const DebugVariable &B) {
3881480093f4SDimitry Andric     return A == B;
3882480093f4SDimitry Andric   }
3883480093f4SDimitry Andric };
3884480093f4SDimitry Andric 
388506c3fb27SDimitry Andric /// Identifies a unique instance of a whole variable (discards/ignores fragment
388606c3fb27SDimitry Andric /// information).
388706c3fb27SDimitry Andric class DebugVariableAggregate : public DebugVariable {
388806c3fb27SDimitry Andric public:
388906c3fb27SDimitry Andric   DebugVariableAggregate(const DbgVariableIntrinsic *DVI);
389006c3fb27SDimitry Andric   DebugVariableAggregate(const DebugVariable &V)
389106c3fb27SDimitry Andric       : DebugVariable(V.getVariable(), std::nullopt, V.getInlinedAt()) {}
389206c3fb27SDimitry Andric };
389306c3fb27SDimitry Andric 
389406c3fb27SDimitry Andric template <>
389506c3fb27SDimitry Andric struct DenseMapInfo<DebugVariableAggregate>
389606c3fb27SDimitry Andric     : public DenseMapInfo<DebugVariable> {};
38970b57cec5SDimitry Andric } // end namespace llvm
38980b57cec5SDimitry Andric 
38990b57cec5SDimitry Andric #undef DEFINE_MDNODE_GET_UNPACK_IMPL
39000b57cec5SDimitry Andric #undef DEFINE_MDNODE_GET_UNPACK
39010b57cec5SDimitry Andric #undef DEFINE_MDNODE_GET
39020b57cec5SDimitry Andric 
39030b57cec5SDimitry Andric #endif // LLVM_IR_DEBUGINFOMETADATA_H
3904