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