#ifndef LLVM_IR_DEBUGINFOMETADATA_H
#define LLVM_IR_DEBUGINFOMETADATA_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Discriminator.h"
#include <cassert>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <vector>
#define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
#define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) \
static CLASS *getDistinct(LLVMContext &Context, \
DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \
} \
static Temp##CLASS getTemporary(LLVMContext &Context, \
DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
return Temp##CLASS( \
getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \
}
#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \
static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \
} \
static CLASS *getIfExists(LLVMContext &Context, \
DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \
false); \
} \
DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS)
namespace llvm {
namespace dwarf {
enum Tag : uint16_t;
}
extern cl::opt<bool> EnableFSDiscriminator;
class DITypeRefArray {
const MDTuple *N = nullptr;
public:
DITypeRefArray() = default;
DITypeRefArray(const MDTuple *N) : N(N) {}
explicit operator bool() const { return get(); }
explicit operator MDTuple *() const { return get(); }
MDTuple *get() const { return const_cast<MDTuple *>(N); }
MDTuple *operator->() const { return get(); }
MDTuple &operator*() const { return *get(); }
unsigned size() const { return N ? N->getNumOperands() : 0u; }
DIType *operator[](unsigned I) const {
return cast_or_null<DIType>(N->getOperand(I));
}
class iterator {
MDNode::op_iterator I = nullptr;
public:
using iterator_category = std::input_iterator_tag;
using value_type = DIType *;
using difference_type = std::ptrdiff_t;
using pointer = void;
using reference = DIType *;
iterator() = default;
explicit iterator(MDNode::op_iterator I) : I(I) {}
DIType *operator*() const { return cast_or_null<DIType>(*I); }
iterator &operator++() {
++I;
return *this;
}
iterator operator++(int) {
iterator Temp(*this);
++I;
return Temp;
}
bool operator==(const iterator &X) const { return I == X.I; }
bool operator!=(const iterator &X) const { return I != X.I; }
};
iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
};
class DINode : public MDNode {
friend class LLVMContextImpl;
friend class MDNode;
protected:
DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
: MDNode(C, ID, Storage, Ops1, Ops2) {
assert(Tag < 1u << 16);
SubclassData16 = Tag;
}
~DINode() = default;
template <class Ty> Ty *getOperandAs(unsigned I) const {
return cast_or_null<Ty>(getOperand(I));
}
StringRef getStringOperand(unsigned I) const {
if (auto *S = getOperandAs<MDString>(I))
return S->getString();
return StringRef();
}
static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
if (S.empty())
return nullptr;
return MDString::get(Context, S);
}
void setTag(unsigned Tag) { SubclassData16 = Tag; }
public:
dwarf::Tag getTag() const;
enum DIFlags : uint32_t {
#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
#define DI_FLAG_LARGEST_NEEDED
#include "llvm/IR/DebugInfoFlags.def"
FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic,
FlagPtrToMemberRep = FlagSingleInheritance | FlagMultipleInheritance |
FlagVirtualInheritance,
LLVM_MARK_AS_BITMASK_ENUM(FlagLargest)
};
static DIFlags getFlag(StringRef Flag);
static StringRef getFlagString(DIFlags Flag);
static DIFlags splitFlags(DIFlags Flags,
SmallVectorImpl<DIFlags> &SplitFlags);
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
return false;
case GenericDINodeKind:
case DISubrangeKind:
case DIEnumeratorKind:
case DIBasicTypeKind:
case DIStringTypeKind:
case DIDerivedTypeKind:
case DICompositeTypeKind:
case DISubroutineTypeKind:
case DIFileKind:
case DICompileUnitKind:
case DISubprogramKind:
case DILexicalBlockKind:
case DILexicalBlockFileKind:
case DINamespaceKind:
case DICommonBlockKind:
case DITemplateTypeParameterKind:
case DITemplateValueParameterKind:
case DIGlobalVariableKind:
case DILocalVariableKind:
case DILabelKind:
case DIObjCPropertyKind:
case DIImportedEntityKind:
case DIModuleKind:
case DIGenericSubrangeKind:
return true;
}
}
};
class GenericDINode : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
unsigned Tag, ArrayRef<Metadata *> Ops1,
ArrayRef<Metadata *> Ops2)
: DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
setHash(Hash);
}
~GenericDINode() { dropAllReferences(); }
void setHash(unsigned Hash) { SubclassData32 = Hash; }
void recalculateHash();
static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Header, ArrayRef<Metadata *> DwarfOps,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
DwarfOps, Storage, ShouldCreate);
}
static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
MDString *Header, ArrayRef<Metadata *> DwarfOps,
StorageType Storage, bool ShouldCreate = true);
TempGenericDINode cloneImpl() const {
return getTemporary(getContext(), getTag(), getHeader(),
SmallVector<Metadata *, 4>(dwarf_operands()));
}
public:
unsigned getHash() const { return SubclassData32; }
DEFINE_MDNODE_GET(GenericDINode,
(unsigned Tag, StringRef Header,
ArrayRef<Metadata *> DwarfOps),
(Tag, Header, DwarfOps))
DEFINE_MDNODE_GET(GenericDINode,
(unsigned Tag, MDString *Header,
ArrayRef<Metadata *> DwarfOps),
(Tag, Header, DwarfOps))
TempGenericDINode clone() const { return cloneImpl(); }
dwarf::Tag getTag() const;
StringRef getHeader() const { return getStringOperand(0); }
MDString *getRawHeader() const { return getOperandAs<MDString>(0); }
op_iterator dwarf_op_begin() const { return op_begin() + 1; }
op_iterator dwarf_op_end() const { return op_end(); }
op_range dwarf_operands() const {
return op_range(dwarf_op_begin(), dwarf_op_end());
}
unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
const MDOperand &getDwarfOperand(unsigned I) const {
return getOperand(I + 1);
}
void replaceDwarfOperandWith(unsigned I, Metadata *New) {
replaceOperandWith(I + 1, New);
}
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == GenericDINodeKind;
}
};
class DISubrange : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
DISubrange(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops);
~DISubrange() = default;
static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
int64_t LowerBound, StorageType Storage,
bool ShouldCreate = true);
static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
int64_t LowerBound, StorageType Storage,
bool ShouldCreate = true);
static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
Metadata *LowerBound, Metadata *UpperBound,
Metadata *Stride, StorageType Storage,
bool ShouldCreate = true);
TempDISubrange cloneImpl() const {
return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
getRawUpperBound(), getRawStride());
}
public:
DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
(Count, LowerBound))
DEFINE_MDNODE_GET(DISubrange, (Metadata * CountNode, int64_t LowerBound = 0),
(CountNode, LowerBound))
DEFINE_MDNODE_GET(DISubrange,
(Metadata * CountNode, Metadata *LowerBound,
Metadata *UpperBound, Metadata *Stride),
(CountNode, LowerBound, UpperBound, Stride))
TempDISubrange clone() const { return cloneImpl(); }
Metadata *getRawCountNode() const { return getOperand(0).get(); }
Metadata *getRawLowerBound() const { return getOperand(1).get(); }
Metadata *getRawUpperBound() const { return getOperand(2).get(); }
Metadata *getRawStride() const { return getOperand(3).get(); }
typedef PointerUnion<ConstantInt *, DIVariable *, DIExpression *> BoundType;
BoundType getCount() const;
BoundType getLowerBound() const;
BoundType getUpperBound() const;
BoundType getStride() const;
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DISubrangeKind;
}
};
class DIGenericSubrange : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
DIGenericSubrange(LLVMContext &C, StorageType Storage,
ArrayRef<Metadata *> Ops);
~DIGenericSubrange() = default;
static DIGenericSubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
Metadata *LowerBound, Metadata *UpperBound,
Metadata *Stride, StorageType Storage,
bool ShouldCreate = true);
TempDIGenericSubrange cloneImpl() const {
return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
getRawUpperBound(), getRawStride());
}
public:
DEFINE_MDNODE_GET(DIGenericSubrange,
(Metadata * CountNode, Metadata *LowerBound,
Metadata *UpperBound, Metadata *Stride),
(CountNode, LowerBound, UpperBound, Stride))
TempDIGenericSubrange clone() const { return cloneImpl(); }
Metadata *getRawCountNode() const { return getOperand(0).get(); }
Metadata *getRawLowerBound() const { return getOperand(1).get(); }
Metadata *getRawUpperBound() const { return getOperand(2).get(); }
Metadata *getRawStride() const { return getOperand(3).get(); }
using BoundType = PointerUnion<DIVariable *, DIExpression *>;
BoundType getCount() const;
BoundType getLowerBound() const;
BoundType getUpperBound() const;
BoundType getStride() const;
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIGenericSubrangeKind;
}
};
class DIEnumerator : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
APInt Value;
DIEnumerator(LLVMContext &C, StorageType Storage, const APInt &Value,
bool IsUnsigned, ArrayRef<Metadata *> Ops);
DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
bool IsUnsigned, ArrayRef<Metadata *> Ops)
: DIEnumerator(C, Storage, APInt(64, Value, !IsUnsigned), IsUnsigned,
Ops) {}
~DIEnumerator() = default;
static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
bool IsUnsigned, StringRef Name,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Value, IsUnsigned,
getCanonicalMDString(Context, Name), Storage, ShouldCreate);
}
static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
bool IsUnsigned, MDString *Name,
StorageType Storage, bool ShouldCreate = true);
TempDIEnumerator cloneImpl() const {
return getTemporary(getContext(), getValue(), isUnsigned(), getName());
}
public:
DEFINE_MDNODE_GET(DIEnumerator,
(int64_t Value, bool IsUnsigned, StringRef Name),
(APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
DEFINE_MDNODE_GET(DIEnumerator,
(int64_t Value, bool IsUnsigned, MDString *Name),
(APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
DEFINE_MDNODE_GET(DIEnumerator,
(APInt Value, bool IsUnsigned, StringRef Name),
(Value, IsUnsigned, Name))
DEFINE_MDNODE_GET(DIEnumerator,
(APInt Value, bool IsUnsigned, MDString *Name),
(Value, IsUnsigned, Name))
TempDIEnumerator clone() const { return cloneImpl(); }
const APInt &getValue() const { return Value; }
bool isUnsigned() const { return SubclassData32; }
StringRef getName() const { return getStringOperand(0); }
MDString *getRawName() const { return getOperandAs<MDString>(0); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIEnumeratorKind;
}
};
class DIScope : public DINode {
protected:
DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
ArrayRef<Metadata *> Ops)
: DINode(C, ID, Storage, Tag, Ops) {}
~DIScope() = default;
public:
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
inline StringRef getFilename() const;
inline StringRef getDirectory() const;
inline Optional<StringRef> getSource() const;
StringRef getName() const;
DIScope *getScope() const;
Metadata *getRawFile() const {
return isa<DIFile>(this) ? const_cast<DIScope *>(this)
: static_cast<Metadata *>(getOperand(0));
}
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
return false;
case DIBasicTypeKind:
case DIStringTypeKind:
case DIDerivedTypeKind:
case DICompositeTypeKind:
case DISubroutineTypeKind:
case DIFileKind:
case DICompileUnitKind:
case DISubprogramKind:
case DILexicalBlockKind:
case DILexicalBlockFileKind:
case DINamespaceKind:
case DICommonBlockKind:
case DIModuleKind:
return true;
}
}
};
class DIFile : public DIScope {
friend class LLVMContextImpl;
friend class MDNode;
public:
enum ChecksumKind {
CSK_MD5 = 1,
CSK_SHA1 = 2,
CSK_SHA256 = 3,
CSK_Last = CSK_SHA256 };
template <typename T> struct ChecksumInfo {
ChecksumKind Kind;
T Value;
ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) {}
~ChecksumInfo() = default;
bool operator==(const ChecksumInfo<T> &X) const {
return Kind == X.Kind && Value == X.Value;
}
bool operator!=(const ChecksumInfo<T> &X) const { return !(*this == X); }
StringRef getKindAsString() const { return getChecksumKindAsString(Kind); }
};
private:
Optional<ChecksumInfo<MDString *>> Checksum;
Optional<MDString *> Source;
DIFile(LLVMContext &C, StorageType Storage,
Optional<ChecksumInfo<MDString *>> CS, Optional<MDString *> Src,
ArrayRef<Metadata *> Ops);
~DIFile() = default;
static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
StringRef Directory,
Optional<ChecksumInfo<StringRef>> CS,
Optional<StringRef> Source, StorageType Storage,
bool ShouldCreate = true) {
Optional<ChecksumInfo<MDString *>> MDChecksum;
if (CS)
MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value));
return getImpl(
Context, getCanonicalMDString(Context, Filename),
getCanonicalMDString(Context, Directory), MDChecksum,
Source ? Optional<MDString *>(getCanonicalMDString(Context, *Source))
: None,
Storage, ShouldCreate);
}
static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
MDString *Directory,
Optional<ChecksumInfo<MDString *>> CS,
Optional<MDString *> Source, StorageType Storage,
bool ShouldCreate = true);
TempDIFile cloneImpl() const {
return getTemporary(getContext(), getFilename(), getDirectory(),
getChecksum(), getSource());
}
public:
DEFINE_MDNODE_GET(DIFile,
(StringRef Filename, StringRef Directory,
Optional<ChecksumInfo<StringRef>> CS = None,
Optional<StringRef> Source = None),
(Filename, Directory, CS, Source))
DEFINE_MDNODE_GET(DIFile,
(MDString * Filename, MDString *Directory,
Optional<ChecksumInfo<MDString *>> CS = None,
Optional<MDString *> Source = None),
(Filename, Directory, CS, Source))
TempDIFile clone() const { return cloneImpl(); }
StringRef getFilename() const { return getStringOperand(0); }
StringRef getDirectory() const { return getStringOperand(1); }
Optional<ChecksumInfo<StringRef>> getChecksum() const {
Optional<ChecksumInfo<StringRef>> StringRefChecksum;
if (Checksum)
StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString());
return StringRefChecksum;
}
Optional<StringRef> getSource() const {
return Source ? Optional<StringRef>((*Source)->getString()) : None;
}
MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
Optional<ChecksumInfo<MDString *>> getRawChecksum() const { return Checksum; }
Optional<MDString *> getRawSource() const { return Source; }
static StringRef getChecksumKindAsString(ChecksumKind CSKind);
static Optional<ChecksumKind> getChecksumKind(StringRef CSKindStr);
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIFileKind;
}
};
StringRef DIScope::getFilename() const {
if (auto *F = getFile())
return F->getFilename();
return "";
}
StringRef DIScope::getDirectory() const {
if (auto *F = getFile())
return F->getDirectory();
return "";
}
Optional<StringRef> DIScope::getSource() const {
if (auto *F = getFile())
return F->getSource();
return None;
}
class DIType : public DIScope {
unsigned Line;
DIFlags Flags;
uint64_t SizeInBits;
uint64_t OffsetInBits;
uint32_t AlignInBits;
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)
: DIScope(C, ID, Storage, Tag, Ops) {
init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
}
~DIType() = default;
void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags) {
this->Line = Line;
this->Flags = Flags;
this->SizeInBits = SizeInBits;
this->AlignInBits = AlignInBits;
this->OffsetInBits = OffsetInBits;
}
void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags) {
assert(isDistinct() && "Only distinct nodes can mutate");
setTag(Tag);
init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
}
public:
TempDIType clone() const {
return TempDIType(cast<DIType>(MDNode::clone().release()));
}
unsigned getLine() const { return Line; }
uint64_t getSizeInBits() const { return SizeInBits; }
uint32_t getAlignInBits() const { return AlignInBits; }
uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
uint64_t getOffsetInBits() const { return OffsetInBits; }
DIFlags getFlags() const { return Flags; }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
TempDIType cloneWithFlags(DIFlags NewFlags) const {
auto NewTy = clone();
NewTy->Flags = NewFlags;
return NewTy;
}
bool isPrivate() const {
return (getFlags() & FlagAccessibility) == FlagPrivate;
}
bool isProtected() const {
return (getFlags() & FlagAccessibility) == FlagProtected;
}
bool isPublic() const {
return (getFlags() & FlagAccessibility) == FlagPublic;
}
bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
bool isVirtual() const { return getFlags() & FlagVirtual; }
bool isArtificial() const { return getFlags() & FlagArtificial; }
bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
bool isObjcClassComplete() const {
return getFlags() & FlagObjcClassComplete;
}
bool isVector() const { return getFlags() & FlagVector; }
bool isBitField() const { return getFlags() & FlagBitField; }
bool isStaticMember() const { return getFlags() & FlagStaticMember; }
bool isLValueReference() const { return getFlags() & FlagLValueReference; }
bool isRValueReference() const { return getFlags() & FlagRValueReference; }
bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; }
bool isTypePassByReference() const {
return getFlags() & FlagTypePassByReference;
}
bool isBigEndian() const { return getFlags() & FlagBigEndian; }
bool isLittleEndian() const { return getFlags() & FlagLittleEndian; }
bool getExportSymbols() const { return getFlags() & FlagExportSymbols; }
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
return false;
case DIBasicTypeKind:
case DIStringTypeKind:
case DIDerivedTypeKind:
case DICompositeTypeKind:
case DISubroutineTypeKind:
return true;
}
}
};
class DIBasicType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Encoding;
DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
DIFlags Flags, ArrayRef<Metadata *> Ops)
: DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
Flags, Ops),
Encoding(Encoding) {}
~DIBasicType() = default;
static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
DIFlags Flags, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
SizeInBits, AlignInBits, Encoding, Flags, Storage,
ShouldCreate);
}
static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
DIFlags Flags, StorageType Storage,
bool ShouldCreate = true);
TempDIBasicType cloneImpl() const {
return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
getAlignInBits(), getEncoding(), getFlags());
}
public:
DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
(Tag, Name, 0, 0, 0, FlagZero))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits),
(Tag, Name, SizeInBits, 0, 0, FlagZero))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, MDString *Name, uint64_t SizeInBits),
(Tag, Name, SizeInBits, 0, 0, FlagZero))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, MDString *Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
TempDIBasicType clone() const { return cloneImpl(); }
unsigned getEncoding() const { return Encoding; }
enum class Signedness { Signed, Unsigned };
Optional<Signedness> getSignedness() const;
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIBasicTypeKind;
}
};
class DIStringType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Encoding;
DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag,
uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
ArrayRef<Metadata *> Ops)
: DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
FlagZero, Ops),
Encoding(Encoding) {}
~DIStringType() = default;
static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, Metadata *StringLength,
Metadata *StrLenExp, Metadata *StrLocationExp,
uint64_t SizeInBits, uint32_t AlignInBits,
unsigned Encoding, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
StringLength, StrLenExp, StrLocationExp, SizeInBits,
AlignInBits, Encoding, Storage, ShouldCreate);
}
static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, Metadata *StringLength,
Metadata *StrLenExp, Metadata *StrLocationExp,
uint64_t SizeInBits, uint32_t AlignInBits,
unsigned Encoding, StorageType Storage,
bool ShouldCreate = true);
TempDIStringType cloneImpl() const {
return getTemporary(getContext(), getTag(), getRawName(),
getRawStringLength(), getRawStringLengthExp(),
getRawStringLocationExp(), getSizeInBits(),
getAlignInBits(), getEncoding());
}
public:
DEFINE_MDNODE_GET(DIStringType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint32_t AlignInBits),
(Tag, Name, nullptr, nullptr, nullptr, SizeInBits,
AlignInBits, 0))
DEFINE_MDNODE_GET(DIStringType,
(unsigned Tag, MDString *Name, Metadata *StringLength,
Metadata *StringLengthExp, Metadata *StringLocationExp,
uint64_t SizeInBits, uint32_t AlignInBits,
unsigned Encoding),
(Tag, Name, StringLength, StringLengthExp,
StringLocationExp, SizeInBits, AlignInBits, Encoding))
DEFINE_MDNODE_GET(DIStringType,
(unsigned Tag, StringRef Name, Metadata *StringLength,
Metadata *StringLengthExp, Metadata *StringLocationExp,
uint64_t SizeInBits, uint32_t AlignInBits,
unsigned Encoding),
(Tag, Name, StringLength, StringLengthExp,
StringLocationExp, SizeInBits, AlignInBits, Encoding))
TempDIStringType clone() const { return cloneImpl(); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIStringTypeKind;
}
DIVariable *getStringLength() const {
return cast_or_null<DIVariable>(getRawStringLength());
}
DIExpression *getStringLengthExp() const {
return cast_or_null<DIExpression>(getRawStringLengthExp());
}
DIExpression *getStringLocationExp() const {
return cast_or_null<DIExpression>(getRawStringLocationExp());
}
unsigned getEncoding() const { return Encoding; }
Metadata *getRawStringLength() const { return getOperand(3); }
Metadata *getRawStringLengthExp() const { return getOperand(4); }
Metadata *getRawStringLocationExp() const { return getOperand(5); }
};
class DIDerivedType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
Optional<unsigned> DWARFAddressSpace;
DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
DIFlags Flags, ArrayRef<Metadata *> Ops)
: DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
AlignInBits, OffsetInBits, Flags, Ops),
DWARFAddressSpace(DWARFAddressSpace) {}
~DIDerivedType() = default;
static DIDerivedType *
getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File,
unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits,
Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Metadata *ExtraData, DINodeArray Annotations, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
DWARFAddressSpace, Flags, ExtraData, Annotations.get(),
Storage, ShouldCreate);
}
static DIDerivedType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
unsigned Line, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Metadata *ExtraData, Metadata *Annotations, StorageType Storage,
bool ShouldCreate = true);
TempDIDerivedType cloneImpl() const {
return getTemporary(
getContext(), getTag(), getName(), getFile(), getLine(), getScope(),
getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(),
getDWARFAddressSpace(), getFlags(), getExtraData(), getAnnotations());
}
public:
DEFINE_MDNODE_GET(
DIDerivedType,
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits,
Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Metadata *ExtraData = nullptr, Metadata *Annotations = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
OffsetInBits, DWARFAddressSpace, Flags, ExtraData, Annotations))
DEFINE_MDNODE_GET(DIDerivedType,
(unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits,
Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Metadata *ExtraData = nullptr,
DINodeArray Annotations = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
ExtraData, Annotations))
TempDIDerivedType clone() const { return cloneImpl(); }
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
Metadata *getRawBaseType() const { return getOperand(3); }
Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }
Metadata *getExtraData() const { return getRawExtraData(); }
Metadata *getRawExtraData() const { return getOperand(4); }
DINodeArray getAnnotations() const {
return cast_or_null<MDTuple>(getRawAnnotations());
}
Metadata *getRawAnnotations() const { return getOperand(5); }
DIType *getClassType() const;
DIObjCProperty *getObjCProperty() const {
return dyn_cast_or_null<DIObjCProperty>(getExtraData());
}
uint32_t getVBPtrOffset() const;
Constant *getStorageOffsetInBits() const;
Constant *getConstant() const;
Constant *getDiscriminantValue() const;
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIDerivedTypeKind;
}
};
class DICompositeType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
unsigned RuntimeLang;
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)
: DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
AlignInBits, OffsetInBits, Flags, Ops),
RuntimeLang(RuntimeLang) {}
~DICompositeType() = default;
void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags) {
assert(isDistinct() && "Only distinct nodes can mutate");
assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
this->RuntimeLang = RuntimeLang;
DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags);
}
static DICompositeType *
getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
DITemplateParameterArray TemplateParams, StringRef Identifier,
DIDerivedType *Discriminator, Metadata *DataLocation,
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
DINodeArray Annotations, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(
Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
RuntimeLang, VTableHolder, TemplateParams.get(),
getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
Associated, Allocated, Rank, Annotations.get(), Storage, ShouldCreate);
}
static DICompositeType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
unsigned Line, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Metadata *VTableHolder, Metadata *TemplateParams,
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
Metadata *Annotations, StorageType Storage, bool ShouldCreate = true);
TempDICompositeType cloneImpl() const {
return getTemporary(
getContext(), getTag(), getName(), getFile(), getLine(), getScope(),
getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(),
getFlags(), getElements(), getRuntimeLang(), getVTableHolder(),
getTemplateParams(), getIdentifier(), getDiscriminator(),
getRawDataLocation(), getRawAssociated(), getRawAllocated(),
getRawRank(), getAnnotations());
}
public:
DEFINE_MDNODE_GET(
DICompositeType,
(unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
DITemplateParameterArray TemplateParams = nullptr,
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
DINodeArray Annotations = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
Annotations))
DEFINE_MDNODE_GET(
DICompositeType,
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
Metadata *Rank = nullptr, Metadata *Annotations = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
Annotations))
TempDICompositeType clone() const { return cloneImpl(); }
static DICompositeType *
getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams, Metadata *Discriminator,
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
Metadata *Rank, Metadata *Annotations);
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
MDString &Identifier);
static DICompositeType *
buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
unsigned RuntimeLang, Metadata *VTableHolder,
Metadata *TemplateParams, Metadata *Discriminator,
Metadata *DataLocation, Metadata *Associated,
Metadata *Allocated, Metadata *Rank, Metadata *Annotations);
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
DINodeArray getElements() const {
return cast_or_null<MDTuple>(getRawElements());
}
DIType *getVTableHolder() const {
return cast_or_null<DIType>(getRawVTableHolder());
}
DITemplateParameterArray getTemplateParams() const {
return cast_or_null<MDTuple>(getRawTemplateParams());
}
StringRef getIdentifier() const { return getStringOperand(7); }
unsigned getRuntimeLang() const { return RuntimeLang; }
Metadata *getRawBaseType() const { return getOperand(3); }
Metadata *getRawElements() const { return getOperand(4); }
Metadata *getRawVTableHolder() const { return getOperand(5); }
Metadata *getRawTemplateParams() const { return getOperand(6); }
MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
Metadata *getRawDiscriminator() const { return getOperand(8); }
DIDerivedType *getDiscriminator() const {
return getOperandAs<DIDerivedType>(8);
}
Metadata *getRawDataLocation() const { return getOperand(9); }
DIVariable *getDataLocation() const {
return dyn_cast_or_null<DIVariable>(getRawDataLocation());
}
DIExpression *getDataLocationExp() const {
return dyn_cast_or_null<DIExpression>(getRawDataLocation());
}
Metadata *getRawAssociated() const { return getOperand(10); }
DIVariable *getAssociated() const {
return dyn_cast_or_null<DIVariable>(getRawAssociated());
}
DIExpression *getAssociatedExp() const {
return dyn_cast_or_null<DIExpression>(getRawAssociated());
}
Metadata *getRawAllocated() const { return getOperand(11); }
DIVariable *getAllocated() const {
return dyn_cast_or_null<DIVariable>(getRawAllocated());
}
DIExpression *getAllocatedExp() const {
return dyn_cast_or_null<DIExpression>(getRawAllocated());
}
Metadata *getRawRank() const { return getOperand(12); }
ConstantInt *getRankConst() const {
if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
return dyn_cast_or_null<ConstantInt>(MD->getValue());
return nullptr;
}
DIExpression *getRankExp() const {
return dyn_cast_or_null<DIExpression>(getRawRank());
}
Metadata *getRawAnnotations() const { return getOperand(13); }
DINodeArray getAnnotations() const {
return cast_or_null<MDTuple>(getRawAnnotations());
}
void replaceElements(DINodeArray Elements) {
#ifndef NDEBUG
for (DINode *Op : getElements())
assert(is_contained(Elements->operands(), Op) &&
"Lost a member during member list replacement");
#endif
replaceOperandWith(4, Elements.get());
}
void replaceVTableHolder(DIType *VTableHolder) {
replaceOperandWith(5, VTableHolder);
}
void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
replaceOperandWith(6, TemplateParams.get());
}
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DICompositeTypeKind;
}
};
class DISubroutineType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
uint8_t CC;
DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags,
uint8_t CC, ArrayRef<Metadata *> Ops);
~DISubroutineType() = default;
static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
uint8_t CC, DITypeRefArray TypeArray,
StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Flags, CC, TypeArray.get(), Storage, ShouldCreate);
}
static DISubroutineType *getImpl(LLVMContext &Context, DIFlags Flags,
uint8_t CC, Metadata *TypeArray,
StorageType Storage,
bool ShouldCreate = true);
TempDISubroutineType cloneImpl() const {
return getTemporary(getContext(), getFlags(), getCC(), getTypeArray());
}
public:
DEFINE_MDNODE_GET(DISubroutineType,
(DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray),
(Flags, CC, TypeArray))
DEFINE_MDNODE_GET(DISubroutineType,
(DIFlags Flags, uint8_t CC, Metadata *TypeArray),
(Flags, CC, TypeArray))
TempDISubroutineType clone() const { return cloneImpl(); }
TempDISubroutineType cloneWithCC(uint8_t CC) const {
auto NewTy = clone();
NewTy->CC = CC;
return NewTy;
}
uint8_t getCC() const { return CC; }
DITypeRefArray getTypeArray() const {
return cast_or_null<MDTuple>(getRawTypeArray());
}
Metadata *getRawTypeArray() const { return getOperand(3); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DISubroutineTypeKind;
}
};
class DICompileUnit : public DIScope {
friend class LLVMContextImpl;
friend class MDNode;
public:
enum DebugEmissionKind : unsigned {
NoDebug = 0,
FullDebug,
LineTablesOnly,
DebugDirectivesOnly,
LastEmissionKind = DebugDirectivesOnly
};
enum class DebugNameTableKind : unsigned {
Default = 0,
GNU = 1,
None = 2,
LastDebugNameTableKind = None
};
static Optional<DebugEmissionKind> getEmissionKind(StringRef Str);
static const char *emissionKindString(DebugEmissionKind EK);
static Optional<DebugNameTableKind> getNameTableKind(StringRef Str);
static const char *nameTableKindString(DebugNameTableKind PK);
private:
unsigned SourceLanguage;
bool IsOptimized;
unsigned RuntimeVersion;
unsigned EmissionKind;
uint64_t DWOId;
bool SplitDebugInlining;
bool DebugInfoForProfiling;
unsigned NameTableKind;
bool RangesBaseAddress;
DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
bool IsOptimized, unsigned RuntimeVersion,
unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining,
bool DebugInfoForProfiling, unsigned NameTableKind,
bool RangesBaseAddress, ArrayRef<Metadata *> Ops);
~DICompileUnit() = default;
static DICompileUnit *
getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
StringRef Producer, bool IsOptimized, StringRef Flags,
unsigned RuntimeVersion, StringRef SplitDebugFilename,
unsigned EmissionKind, DICompositeTypeArray EnumTypes,
DIScopeArray RetainedTypes,
DIGlobalVariableExpressionArray GlobalVariables,
DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
unsigned NameTableKind, bool RangesBaseAddress, StringRef SysRoot,
StringRef SDK, StorageType Storage, bool ShouldCreate = true) {
return getImpl(
Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(),
ImportedEntities.get(), Macros.get(), DWOId, SplitDebugInlining,
DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
getCanonicalMDString(Context, SysRoot),
getCanonicalMDString(Context, SDK), Storage, ShouldCreate);
}
static DICompileUnit *
getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
MDString *Producer, bool IsOptimized, MDString *Flags,
unsigned RuntimeVersion, MDString *SplitDebugFilename,
unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
Metadata *GlobalVariables, Metadata *ImportedEntities,
Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
bool DebugInfoForProfiling, unsigned NameTableKind,
bool RangesBaseAddress, MDString *SysRoot, MDString *SDK,
StorageType Storage, bool ShouldCreate = true);
TempDICompileUnit cloneImpl() const {
return getTemporary(
getContext(), getSourceLanguage(), getFile(), getProducer(),
isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
getEmissionKind(), getEnumTypes(), getRetainedTypes(),
getGlobalVariables(), getImportedEntities(), getMacros(), DWOId,
getSplitDebugInlining(), getDebugInfoForProfiling(), getNameTableKind(),
getRangesBaseAddress(), getSysRoot(), getSDK());
}
public:
static void get() = delete;
static void getIfExists() = delete;
DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
DICompileUnit,
(unsigned SourceLanguage, DIFile *File, StringRef Producer,
bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
StringRef SplitDebugFilename, DebugEmissionKind EmissionKind,
DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes,
DIGlobalVariableExpressionArray GlobalVariables,
DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
DebugNameTableKind NameTableKind, bool RangesBaseAddress,
StringRef SysRoot, StringRef SDK),
(SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress,
SysRoot, SDK))
DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
DICompileUnit,
(unsigned SourceLanguage, Metadata *File, MDString *Producer,
bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
Metadata *RetainedTypes, Metadata *GlobalVariables,
Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
bool SplitDebugInlining, bool DebugInfoForProfiling,
unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
MDString *SDK),
(SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
DebugInfoForProfiling, NameTableKind, RangesBaseAddress, SysRoot, SDK))
TempDICompileUnit clone() const { return cloneImpl(); }
unsigned getSourceLanguage() const { return SourceLanguage; }
bool isOptimized() const { return IsOptimized; }
unsigned getRuntimeVersion() const { return RuntimeVersion; }
DebugEmissionKind getEmissionKind() const {
return (DebugEmissionKind)EmissionKind;
}
bool isDebugDirectivesOnly() const {
return EmissionKind == DebugDirectivesOnly;
}
bool getDebugInfoForProfiling() const { return DebugInfoForProfiling; }
DebugNameTableKind getNameTableKind() const {
return (DebugNameTableKind)NameTableKind;
}
bool getRangesBaseAddress() const { return RangesBaseAddress; }
StringRef getProducer() const { return getStringOperand(1); }
StringRef getFlags() const { return getStringOperand(2); }
StringRef getSplitDebugFilename() const { return getStringOperand(3); }
DICompositeTypeArray getEnumTypes() const {
return cast_or_null<MDTuple>(getRawEnumTypes());
}
DIScopeArray getRetainedTypes() const {
return cast_or_null<MDTuple>(getRawRetainedTypes());
}
DIGlobalVariableExpressionArray getGlobalVariables() const {
return cast_or_null<MDTuple>(getRawGlobalVariables());
}
DIImportedEntityArray getImportedEntities() const {
return cast_or_null<MDTuple>(getRawImportedEntities());
}
DIMacroNodeArray getMacros() const {
return cast_or_null<MDTuple>(getRawMacros());
}
uint64_t getDWOId() const { return DWOId; }
void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
bool getSplitDebugInlining() const { return SplitDebugInlining; }
void setSplitDebugInlining(bool SplitDebugInlining) {
this->SplitDebugInlining = SplitDebugInlining;
}
StringRef getSysRoot() const { return getStringOperand(9); }
StringRef getSDK() const { return getStringOperand(10); }
MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
MDString *getRawSplitDebugFilename() const {
return getOperandAs<MDString>(3);
}
Metadata *getRawEnumTypes() const { return getOperand(4); }
Metadata *getRawRetainedTypes() const { return getOperand(5); }
Metadata *getRawGlobalVariables() const { return getOperand(6); }
Metadata *getRawImportedEntities() const { return getOperand(7); }
Metadata *getRawMacros() const { return getOperand(8); }
MDString *getRawSysRoot() const { return getOperandAs<MDString>(9); }
MDString *getRawSDK() const { return getOperandAs<MDString>(10); }
void replaceEnumTypes(DICompositeTypeArray N) {
replaceOperandWith(4, N.get());
}
void replaceRetainedTypes(DITypeArray N) { replaceOperandWith(5, N.get()); }
void replaceGlobalVariables(DIGlobalVariableExpressionArray N) {
replaceOperandWith(6, N.get());
}
void replaceImportedEntities(DIImportedEntityArray N) {
replaceOperandWith(7, N.get());
}
void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(8, N.get()); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DICompileUnitKind;
}
};
class DILocalScope : public DIScope {
protected:
DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
ArrayRef<Metadata *> Ops)
: DIScope(C, ID, Storage, Tag, Ops) {}
~DILocalScope() = default;
public:
DISubprogram *getSubprogram() const;
DILocalScope *getNonLexicalBlockFileScope() const;
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DISubprogramKind ||
MD->getMetadataID() == DILexicalBlockKind ||
MD->getMetadataID() == DILexicalBlockFileKind;
}
};
class DILocation : public MDNode {
friend class LLVMContextImpl;
friend class MDNode;
DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
unsigned Column, ArrayRef<Metadata *> MDs, bool ImplicitCode);
~DILocation() { dropAllReferences(); }
static DILocation *getImpl(LLVMContext &Context, unsigned Line,
unsigned Column, Metadata *Scope,
Metadata *InlinedAt, bool ImplicitCode,
StorageType Storage, bool ShouldCreate = true);
static DILocation *getImpl(LLVMContext &Context, unsigned Line,
unsigned Column, DILocalScope *Scope,
DILocation *InlinedAt, bool ImplicitCode,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
static_cast<Metadata *>(InlinedAt), ImplicitCode, Storage,
ShouldCreate);
}
TempDILocation cloneImpl() const {
return getTemporary(getContext(), getLine(), getColumn(), getRawScope(),
getRawInlinedAt(), isImplicitCode());
}
public:
void replaceOperandWith(unsigned I, Metadata *New) = delete;
DEFINE_MDNODE_GET(DILocation,
(unsigned Line, unsigned Column, Metadata *Scope,
Metadata *InlinedAt = nullptr, bool ImplicitCode = false),
(Line, Column, Scope, InlinedAt, ImplicitCode))
DEFINE_MDNODE_GET(DILocation,
(unsigned Line, unsigned Column, DILocalScope *Scope,
DILocation *InlinedAt = nullptr,
bool ImplicitCode = false),
(Line, Column, Scope, InlinedAt, ImplicitCode))
TempDILocation clone() const { return cloneImpl(); }
unsigned getLine() const { return SubclassData32; }
unsigned getColumn() const { return SubclassData16; }
DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
DILocation *getInlinedAt() const {
return cast_or_null<DILocation>(getRawInlinedAt());
}
bool isImplicitCode() const { return SubclassData1; }
void setImplicitCode(bool ImplicitCode) { SubclassData1 = ImplicitCode; }
DIFile *getFile() const { return getScope()->getFile(); }
StringRef getFilename() const { return getScope()->getFilename(); }
StringRef getDirectory() const { return getScope()->getDirectory(); }
Optional<StringRef> getSource() const { return getScope()->getSource(); }
DILocalScope *getInlinedAtScope() const {
if (auto *IA = getInlinedAt())
return IA->getInlinedAtScope();
return getScope();
}
inline unsigned getDiscriminator() const;
inline static bool isPseudoProbeDiscriminator(unsigned Discriminator) {
return ((Discriminator & 0x7) == 0x7) && (Discriminator & 0xFFFFFFF8);
}
inline const DILocation *cloneWithDiscriminator(unsigned Discriminator) const;
inline Optional<const DILocation *>
cloneWithBaseDiscriminator(unsigned BD) const;
inline unsigned getDuplicationFactor() const;
inline unsigned getCopyIdentifier() const;
inline unsigned getBaseDiscriminator() const;
inline Optional<const DILocation *>
cloneByMultiplyingDuplicationFactor(unsigned DF) const;
static const DILocation *getMergedLocation(const DILocation *LocA,
const DILocation *LocB);
static const DILocation *
getMergedLocations(ArrayRef<const DILocation *> Locs);
static unsigned getMaskedDiscriminator(unsigned D, unsigned B) {
return (D & getN1Bits(B));
}
static unsigned getBaseDiscriminatorBits() { return getBaseFSBitEnd(); }
static unsigned
getBaseDiscriminatorFromDiscriminator(unsigned D,
bool IsFSDiscriminator = false) {
if (IsFSDiscriminator)
return getMaskedDiscriminator(D, getBaseDiscriminatorBits());
return getUnsignedFromPrefixEncoding(D);
}
static Optional<unsigned> encodeDiscriminator(unsigned BD, unsigned DF,
unsigned CI);
static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
unsigned &CI);
static unsigned getDuplicationFactorFromDiscriminator(unsigned D) {
if (EnableFSDiscriminator)
return 1;
D = getNextComponentInDiscriminator(D);
unsigned Ret = getUnsignedFromPrefixEncoding(D);
if (Ret == 0)
return 1;
return Ret;
}
static unsigned getCopyIdentifierFromDiscriminator(unsigned D) {
return getUnsignedFromPrefixEncoding(
getNextComponentInDiscriminator(getNextComponentInDiscriminator(D)));
}
Metadata *getRawScope() const { return getOperand(0); }
Metadata *getRawInlinedAt() const {
if (getNumOperands() == 2)
return getOperand(1);
return nullptr;
}
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DILocationKind;
}
};
class DISubprogram : public DILocalScope {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Line;
unsigned ScopeLine;
unsigned VirtualIndex;
int ThisAdjustment;
public:
enum DISPFlags : uint32_t {
#define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID,
#define DISP_FLAG_LARGEST_NEEDED
#include "llvm/IR/DebugInfoFlags.def"
SPFlagNonvirtual = SPFlagZero,
SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
};
static DISPFlags getFlag(StringRef Flag);
static StringRef getFlagString(DISPFlags Flag);
static DISPFlags splitFlags(DISPFlags Flags,
SmallVectorImpl<DISPFlags> &SplitFlags);
static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
bool IsOptimized,
unsigned Virtuality = SPFlagNonvirtual,
bool IsMainSubprogram = false);
private:
DIFlags Flags;
DISPFlags SPFlags;
DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment,
DIFlags Flags, DISPFlags SPFlags, ArrayRef<Metadata *> Ops);
~DISubprogram() = default;
static DISubprogram *
getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
StringRef LinkageName, DIFile *File, unsigned Line,
DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType,
unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
DISPFlags SPFlags, DICompileUnit *Unit,
DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
DINodeArray RetainedNodes, DITypeArray ThrownTypes,
DINodeArray Annotations, StringRef TargetFuncName,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, LinkageName), File, Line, Type,
ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
RetainedNodes.get(), ThrownTypes.get(), Annotations.get(),
getCanonicalMDString(Context, TargetFuncName),
Storage, ShouldCreate);
}
static DISubprogram *
getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
Metadata *TemplateParams, Metadata *Declaration,
Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations,
MDString *TargetFuncName, StorageType Storage,
bool ShouldCreate = true);
TempDISubprogram cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
getFile(), getLine(), getType(), getScopeLine(),
getContainingType(), getVirtualIndex(),
getThisAdjustment(), getFlags(), getSPFlags(),
getUnit(), getTemplateParams(), getDeclaration(),
getRetainedNodes(), getThrownTypes(), getAnnotations(),
getTargetFuncName());
}
public:
DEFINE_MDNODE_GET(
DISubprogram,
(DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned Line, DISubroutineType *Type, unsigned ScopeLine,
DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit,
DITemplateParameterArray TemplateParams = nullptr,
DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr,
StringRef TargetFuncName = ""),
(Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName))
DEFINE_MDNODE_GET(
DISubprogram,
(Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
unsigned Line, Metadata *Type, unsigned ScopeLine,
Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment,
DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr,
Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr,
Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr),
(Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName))
TempDISubprogram clone() const { return cloneImpl(); }
TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
auto NewSP = clone();
NewSP->Flags = NewFlags;
return NewSP;
}
public:
unsigned getLine() const { return Line; }
unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
unsigned getVirtualIndex() const { return VirtualIndex; }
int getThisAdjustment() const { return ThisAdjustment; }
unsigned getScopeLine() const { return ScopeLine; }
void setScopeLine(unsigned L) {
assert(isDistinct());
ScopeLine = L;
}
DIFlags getFlags() const { return Flags; }
DISPFlags getSPFlags() const { return SPFlags; }
bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; }
bool isDefinition() const { return getSPFlags() & SPFlagDefinition; }
bool isOptimized() const { return getSPFlags() & SPFlagOptimized; }
bool isMainSubprogram() const { return getSPFlags() & SPFlagMainSubprogram; }
bool isArtificial() const { return getFlags() & FlagArtificial; }
bool isPrivate() const {
return (getFlags() & FlagAccessibility) == FlagPrivate;
}
bool isProtected() const {
return (getFlags() & FlagAccessibility) == FlagProtected;
}
bool isPublic() const {
return (getFlags() & FlagAccessibility) == FlagPublic;
}
bool isExplicit() const { return getFlags() & FlagExplicit; }
bool isPrototyped() const { return getFlags() & FlagPrototyped; }
bool areAllCallsDescribed() const {
return getFlags() & FlagAllCallsDescribed;
}
bool isPure() const { return getSPFlags() & SPFlagPure; }
bool isElemental() const { return getSPFlags() & SPFlagElemental; }
bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
bool isObjCDirect() const { return getSPFlags() & SPFlagObjCDirect; }
bool isDeleted() const { return getSPFlags() & SPFlagDeleted; }
bool isLValueReference() const { return getFlags() & FlagLValueReference; }
bool isRValueReference() const { return getFlags() & FlagRValueReference; }
bool isNoReturn() const { return getFlags() & FlagNoReturn; }
bool isThunk() const { return getFlags() & FlagThunk; }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
StringRef getLinkageName() const { return getStringOperand(3); }
void replaceLinkageName(MDString *LN) { replaceOperandWith(3, LN); }
DISubroutineType *getType() const {
return cast_or_null<DISubroutineType>(getRawType());
}
DIType *getContainingType() const {
return cast_or_null<DIType>(getRawContainingType());
}
void replaceType(DISubroutineType *Ty) {
assert(isDistinct() && "Only distinct nodes can mutate");
replaceOperandWith(4, Ty);
}
DICompileUnit *getUnit() const {
return cast_or_null<DICompileUnit>(getRawUnit());
}
void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
DITemplateParameterArray getTemplateParams() const {
return cast_or_null<MDTuple>(getRawTemplateParams());
}
DISubprogram *getDeclaration() const {
return cast_or_null<DISubprogram>(getRawDeclaration());
}
DINodeArray getRetainedNodes() const {
return cast_or_null<MDTuple>(getRawRetainedNodes());
}
DITypeArray getThrownTypes() const {
return cast_or_null<MDTuple>(getRawThrownTypes());
}
DINodeArray getAnnotations() const {
return cast_or_null<MDTuple>(getRawAnnotations());
}
StringRef getTargetFuncName() const {
return (getRawTargetFuncName()) ? getStringOperand(12) : StringRef();
}
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
Metadata *getRawType() const { return getOperand(4); }
Metadata *getRawUnit() const { return getOperand(5); }
Metadata *getRawDeclaration() const { return getOperand(6); }
Metadata *getRawRetainedNodes() const { return getOperand(7); }
Metadata *getRawContainingType() const {
return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
}
Metadata *getRawTemplateParams() const {
return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
}
Metadata *getRawThrownTypes() const {
return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
}
Metadata *getRawAnnotations() const {
return getNumOperands() > 11 ? getOperandAs<Metadata>(11) : nullptr;
}
MDString *getRawTargetFuncName() const {
return getNumOperands() > 12 ? getOperandAs<MDString>(12) : nullptr;
}
void replaceRawLinkageName(MDString *LinkageName) {
replaceOperandWith(3, LinkageName);
}
bool describes(const Function *F) const;
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DISubprogramKind;
}
};
class DILexicalBlockBase : public DILocalScope {
protected:
DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
ArrayRef<Metadata *> Ops);
~DILexicalBlockBase() = default;
public:
DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
Metadata *getRawScope() const { return getOperand(1); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DILexicalBlockKind ||
MD->getMetadataID() == DILexicalBlockFileKind;
}
};
class DILexicalBlock : public DILexicalBlockBase {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Line;
uint16_t Column;
DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
unsigned Column, ArrayRef<Metadata *> Ops)
: DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
Column(Column) {
assert(Column < (1u << 16) && "Expected 16-bit column");
}
~DILexicalBlock() = default;
static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
DIFile *File, unsigned Line, unsigned Column,
StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, static_cast<Metadata *>(Scope),
static_cast<Metadata *>(File), Line, Column, Storage,
ShouldCreate);
}
static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line, unsigned Column,
StorageType Storage, bool ShouldCreate = true);
TempDILexicalBlock cloneImpl() const {
return getTemporary(getContext(), getScope(), getFile(), getLine(),
getColumn());
}
public:
DEFINE_MDNODE_GET(DILexicalBlock,
(DILocalScope * Scope, DIFile *File, unsigned Line,
unsigned Column),
(Scope, File, Line, Column))
DEFINE_MDNODE_GET(DILexicalBlock,
(Metadata * Scope, Metadata *File, unsigned Line,
unsigned Column),
(Scope, File, Line, Column))
TempDILexicalBlock clone() const { return cloneImpl(); }
unsigned getLine() const { return Line; }
unsigned getColumn() const { return Column; }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DILexicalBlockKind;
}
};
class DILexicalBlockFile : public DILexicalBlockBase {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Discriminator;
DILexicalBlockFile(LLVMContext &C, StorageType Storage,
unsigned Discriminator, ArrayRef<Metadata *> Ops)
: DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
Discriminator(Discriminator) {}
~DILexicalBlockFile() = default;
static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
DIFile *File, unsigned Discriminator,
StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, static_cast<Metadata *>(Scope),
static_cast<Metadata *>(File), Discriminator, Storage,
ShouldCreate);
}
static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Discriminator,
StorageType Storage,
bool ShouldCreate = true);
TempDILexicalBlockFile cloneImpl() const {
return getTemporary(getContext(), getScope(), getFile(),
getDiscriminator());
}
public:
DEFINE_MDNODE_GET(DILexicalBlockFile,
(DILocalScope * Scope, DIFile *File,
unsigned Discriminator),
(Scope, File, Discriminator))
DEFINE_MDNODE_GET(DILexicalBlockFile,
(Metadata * Scope, Metadata *File, unsigned Discriminator),
(Scope, File, Discriminator))
TempDILexicalBlockFile clone() const { return cloneImpl(); }
unsigned getDiscriminator() const { return Discriminator; }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DILexicalBlockFileKind;
}
};
unsigned DILocation::getDiscriminator() const {
if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
return F->getDiscriminator();
return 0;
}
const DILocation *
DILocation::cloneWithDiscriminator(unsigned Discriminator) const {
DIScope *Scope = getScope();
for (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope);
LBF && LBF->getDiscriminator() != 0;
LBF = dyn_cast<DILexicalBlockFile>(Scope))
Scope = LBF->getScope();
DILexicalBlockFile *NewScope =
DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator);
return DILocation::get(getContext(), getLine(), getColumn(), NewScope,
getInlinedAt());
}
unsigned DILocation::getBaseDiscriminator() const {
return getBaseDiscriminatorFromDiscriminator(getDiscriminator(),
EnableFSDiscriminator);
}
unsigned DILocation::getDuplicationFactor() const {
return getDuplicationFactorFromDiscriminator(getDiscriminator());
}
unsigned DILocation::getCopyIdentifier() const {
return getCopyIdentifierFromDiscriminator(getDiscriminator());
}
Optional<const DILocation *>
DILocation::cloneWithBaseDiscriminator(unsigned D) const {
unsigned BD, DF, CI;
if (EnableFSDiscriminator) {
BD = getBaseDiscriminator();
if (D == BD)
return this;
return cloneWithDiscriminator(D);
}
decodeDiscriminator(getDiscriminator(), BD, DF, CI);
if (D == BD)
return this;
if (Optional<unsigned> Encoded = encodeDiscriminator(D, DF, CI))
return cloneWithDiscriminator(*Encoded);
return None;
}
Optional<const DILocation *>
DILocation::cloneByMultiplyingDuplicationFactor(unsigned DF) const {
assert(!EnableFSDiscriminator && "FSDiscriminator should not call this.");
DF *= getDuplicationFactor();
if (DF <= 1)
return this;
unsigned BD = getBaseDiscriminator();
unsigned CI = getCopyIdentifier();
if (Optional<unsigned> D = encodeDiscriminator(BD, DF, CI))
return cloneWithDiscriminator(*D);
return None;
}
class DINamespace : public DIScope {
friend class LLVMContextImpl;
friend class MDNode;
unsigned ExportSymbols : 1;
DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
ArrayRef<Metadata *> Ops);
~DINamespace() = default;
static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
StringRef Name, bool ExportSymbols,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
ExportSymbols, Storage, ShouldCreate);
}
static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
MDString *Name, bool ExportSymbols,
StorageType Storage, bool ShouldCreate = true);
TempDINamespace cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(),
getExportSymbols());
}
public:
DEFINE_MDNODE_GET(DINamespace,
(DIScope * Scope, StringRef Name, bool ExportSymbols),
(Scope, Name, ExportSymbols))
DEFINE_MDNODE_GET(DINamespace,
(Metadata * Scope, MDString *Name, bool ExportSymbols),
(Scope, Name, ExportSymbols))
TempDINamespace clone() const { return cloneImpl(); }
bool getExportSymbols() const { return ExportSymbols; }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DINamespaceKind;
}
};
class DIModule : public DIScope {
friend class LLVMContextImpl;
friend class MDNode;
unsigned LineNo;
bool IsDecl;
DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
bool IsDecl, ArrayRef<Metadata *> Ops);
~DIModule() = default;
static DIModule *getImpl(LLVMContext &Context, DIFile *File, DIScope *Scope,
StringRef Name, StringRef ConfigurationMacros,
StringRef IncludePath, StringRef APINotesFile,
unsigned LineNo, bool IsDecl, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, File, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, ConfigurationMacros),
getCanonicalMDString(Context, IncludePath),
getCanonicalMDString(Context, APINotesFile), LineNo, IsDecl,
Storage, ShouldCreate);
}
static DIModule *getImpl(LLVMContext &Context, Metadata *File,
Metadata *Scope, MDString *Name,
MDString *ConfigurationMacros, MDString *IncludePath,
MDString *APINotesFile, unsigned LineNo, bool IsDecl,
StorageType Storage, bool ShouldCreate = true);
TempDIModule cloneImpl() const {
return getTemporary(getContext(), getFile(), getScope(), getName(),
getConfigurationMacros(), getIncludePath(),
getAPINotesFile(), getLineNo(), getIsDecl());
}
public:
DEFINE_MDNODE_GET(DIModule,
(DIFile * File, DIScope *Scope, StringRef Name,
StringRef ConfigurationMacros, StringRef IncludePath,
StringRef APINotesFile, unsigned LineNo,
bool IsDecl = false),
(File, Scope, Name, ConfigurationMacros, IncludePath,
APINotesFile, LineNo, IsDecl))
DEFINE_MDNODE_GET(DIModule,
(Metadata * File, Metadata *Scope, MDString *Name,
MDString *ConfigurationMacros, MDString *IncludePath,
MDString *APINotesFile, unsigned LineNo,
bool IsDecl = false),
(File, Scope, Name, ConfigurationMacros, IncludePath,
APINotesFile, LineNo, IsDecl))
TempDIModule clone() const { return cloneImpl(); }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
StringRef getConfigurationMacros() const { return getStringOperand(3); }
StringRef getIncludePath() const { return getStringOperand(4); }
StringRef getAPINotesFile() const { return getStringOperand(5); }
unsigned getLineNo() const { return LineNo; }
bool getIsDecl() const { return IsDecl; }
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
MDString *getRawConfigurationMacros() const {
return getOperandAs<MDString>(3);
}
MDString *getRawIncludePath() const { return getOperandAs<MDString>(4); }
MDString *getRawAPINotesFile() const { return getOperandAs<MDString>(5); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIModuleKind;
}
};
class DITemplateParameter : public DINode {
protected:
bool IsDefault;
DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
unsigned Tag, bool IsDefault, ArrayRef<Metadata *> Ops)
: DINode(Context, ID, Storage, Tag, Ops), IsDefault(IsDefault) {}
~DITemplateParameter() = default;
public:
StringRef getName() const { return getStringOperand(0); }
DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
MDString *getRawName() const { return getOperandAs<MDString>(0); }
Metadata *getRawType() const { return getOperand(1); }
bool isDefault() const { return IsDefault; }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DITemplateTypeParameterKind ||
MD->getMetadataID() == DITemplateValueParameterKind;
}
};
class DITemplateTypeParameter : public DITemplateParameter {
friend class LLVMContextImpl;
friend class MDNode;
DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
bool IsDefault, ArrayRef<Metadata *> Ops);
~DITemplateTypeParameter() = default;
static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
DIType *Type, bool IsDefault,
StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, getCanonicalMDString(Context, Name), Type,
IsDefault, Storage, ShouldCreate);
}
static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
Metadata *Type, bool IsDefault,
StorageType Storage,
bool ShouldCreate = true);
TempDITemplateTypeParameter cloneImpl() const {
return getTemporary(getContext(), getName(), getType(), isDefault());
}
public:
DEFINE_MDNODE_GET(DITemplateTypeParameter,
(StringRef Name, DIType *Type, bool IsDefault),
(Name, Type, IsDefault))
DEFINE_MDNODE_GET(DITemplateTypeParameter,
(MDString * Name, Metadata *Type, bool IsDefault),
(Name, Type, IsDefault))
TempDITemplateTypeParameter clone() const { return cloneImpl(); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DITemplateTypeParameterKind;
}
};
class DITemplateValueParameter : public DITemplateParameter {
friend class LLVMContextImpl;
friend class MDNode;
DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
unsigned Tag, bool IsDefault,
ArrayRef<Metadata *> Ops)
: DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
IsDefault, Ops) {}
~DITemplateValueParameter() = default;
static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, DIType *Type,
bool IsDefault, Metadata *Value,
StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
IsDefault, Value, Storage, ShouldCreate);
}
static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, Metadata *Type,
bool IsDefault, Metadata *Value,
StorageType Storage,
bool ShouldCreate = true);
TempDITemplateValueParameter cloneImpl() const {
return getTemporary(getContext(), getTag(), getName(), getType(),
isDefault(), getValue());
}
public:
DEFINE_MDNODE_GET(DITemplateValueParameter,
(unsigned Tag, StringRef Name, DIType *Type, bool IsDefault,
Metadata *Value),
(Tag, Name, Type, IsDefault, Value))
DEFINE_MDNODE_GET(DITemplateValueParameter,
(unsigned Tag, MDString *Name, Metadata *Type,
bool IsDefault, Metadata *Value),
(Tag, Name, Type, IsDefault, Value))
TempDITemplateValueParameter clone() const { return cloneImpl(); }
Metadata *getValue() const { return getOperand(2); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DITemplateValueParameterKind;
}
};
class DIVariable : public DINode {
unsigned Line;
uint32_t AlignInBits;
protected:
DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line,
ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0);
~DIVariable() = default;
public:
unsigned getLine() const { return Line; }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
StringRef getName() const { return getStringOperand(1); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
uint32_t getAlignInBits() const { return AlignInBits; }
uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
Optional<uint64_t> getSizeInBits() const;
Optional<DIBasicType::Signedness> getSignedness() const {
if (auto *BT = dyn_cast<DIBasicType>(getType()))
return BT->getSignedness();
return None;
}
StringRef getFilename() const {
if (auto *F = getFile())
return F->getFilename();
return "";
}
StringRef getDirectory() const {
if (auto *F = getFile())
return F->getDirectory();
return "";
}
Optional<StringRef> getSource() const {
if (auto *F = getFile())
return F->getSource();
return None;
}
Metadata *getRawScope() const { return getOperand(0); }
MDString *getRawName() const { return getOperandAs<MDString>(1); }
Metadata *getRawFile() const { return getOperand(2); }
Metadata *getRawType() const { return getOperand(3); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DILocalVariableKind ||
MD->getMetadataID() == DIGlobalVariableKind;
}
};
class DIExpression : public MDNode {
friend class LLVMContextImpl;
friend class MDNode;
std::vector<uint64_t> Elements;
DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
: MDNode(C, DIExpressionKind, Storage, None),
Elements(Elements.begin(), Elements.end()) {}
~DIExpression() = default;
static DIExpression *getImpl(LLVMContext &Context,
ArrayRef<uint64_t> Elements, StorageType Storage,
bool ShouldCreate = true);
TempDIExpression cloneImpl() const {
return getTemporary(getContext(), getElements());
}
public:
DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
TempDIExpression clone() const { return cloneImpl(); }
ArrayRef<uint64_t> getElements() const { return Elements; }
unsigned getNumElements() const { return Elements.size(); }
uint64_t getElement(unsigned I) const {
assert(I < Elements.size() && "Index out of range");
return Elements[I];
}
enum SignedOrUnsignedConstant { SignedConstant, UnsignedConstant };
llvm::Optional<SignedOrUnsignedConstant> isConstant() const;
uint64_t getNumLocationOperands() const;
using element_iterator = ArrayRef<uint64_t>::iterator;
element_iterator elements_begin() const { return getElements().begin(); }
element_iterator elements_end() const { return getElements().end(); }
class ExprOperand {
const uint64_t *Op = nullptr;
public:
ExprOperand() = default;
explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
const uint64_t *get() const { return Op; }
uint64_t getOp() const { return *Op; }
uint64_t getArg(unsigned I) const { return Op[I + 1]; }
unsigned getNumArgs() const { return getSize() - 1; }
unsigned getSize() const;
void appendToVector(SmallVectorImpl<uint64_t> &V) const {
V.append(get(), get() + getSize());
}
};
class expr_op_iterator {
ExprOperand Op;
public:
using iterator_category = std::input_iterator_tag;
using value_type = ExprOperand;
using difference_type = std::ptrdiff_t;
using pointer = value_type *;
using reference = value_type &;
expr_op_iterator() = default;
explicit expr_op_iterator(element_iterator I) : Op(I) {}
element_iterator getBase() const { return Op.get(); }
const ExprOperand &operator*() const { return Op; }
const ExprOperand *operator->() const { return &Op; }
expr_op_iterator &operator++() {
increment();
return *this;
}
expr_op_iterator operator++(int) {
expr_op_iterator T(*this);
increment();
return T;
}
expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
bool operator==(const expr_op_iterator &X) const {
return getBase() == X.getBase();
}
bool operator!=(const expr_op_iterator &X) const {
return getBase() != X.getBase();
}
private:
void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
};
expr_op_iterator expr_op_begin() const {
return expr_op_iterator(elements_begin());
}
expr_op_iterator expr_op_end() const {
return expr_op_iterator(elements_end());
}
iterator_range<expr_op_iterator> expr_ops() const {
return {expr_op_begin(), expr_op_end()};
}
bool isValid() const;
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIExpressionKind;
}
bool startsWithDeref() const;
struct FragmentInfo {
uint64_t SizeInBits;
uint64_t OffsetInBits;
};
static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
expr_op_iterator End);
Optional<FragmentInfo> getFragmentInfo() const {
return getFragmentInfo(expr_op_begin(), expr_op_end());
}
bool isFragment() const { return getFragmentInfo().has_value(); }
bool isImplicit() const;
bool isComplex() const;
static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
bool extractIfOffset(int64_t &Offset) const;
bool hasAllLocationOps(unsigned N) const;
static const DIExpression *extractAddressClass(const DIExpression *Expr,
unsigned &AddrClass);
enum PrependOps : uint8_t {
ApplyOffset = 0,
DerefBefore = 1 << 0,
DerefAfter = 1 << 1,
StackValue = 1 << 2,
EntryValue = 1 << 3
};
static DIExpression *prepend(const DIExpression *Expr, uint8_t Flags,
int64_t Offset = 0);
static DIExpression *prependOpcodes(const DIExpression *Expr,
SmallVectorImpl<uint64_t> &Ops,
bool StackValue = false,
bool EntryValue = false);
static DIExpression *append(const DIExpression *Expr, ArrayRef<uint64_t> Ops);
static DIExpression *appendToStack(const DIExpression *Expr,
ArrayRef<uint64_t> Ops);
static DIExpression *appendOpsToArg(const DIExpression *Expr,
ArrayRef<uint64_t> Ops, unsigned ArgNo,
bool StackValue = false);
static DIExpression *replaceArg(const DIExpression *Expr, uint64_t OldArg,
uint64_t NewArg);
static Optional<DIExpression *>
createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,
unsigned SizeInBits);
static int fragmentCmp(const FragmentInfo &A, const FragmentInfo &B) {
uint64_t l1 = A.OffsetInBits;
uint64_t l2 = B.OffsetInBits;
uint64_t r1 = l1 + A.SizeInBits;
uint64_t r2 = l2 + B.SizeInBits;
if (r1 <= l2)
return -1;
else if (r2 <= l1)
return 1;
else
return 0;
}
using ExtOps = std::array<uint64_t, 6>;
static ExtOps getExtOps(unsigned FromSize, unsigned ToSize, bool Signed);
static DIExpression *appendExt(const DIExpression *Expr, unsigned FromSize,
unsigned ToSize, bool Signed);
static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B) {
return fragmentCmp(A, B) == 0;
}
int fragmentCmp(const DIExpression *Other) const {
auto Fragment1 = *getFragmentInfo();
auto Fragment2 = *Other->getFragmentInfo();
return fragmentCmp(Fragment1, Fragment2);
}
bool fragmentsOverlap(const DIExpression *Other) const {
if (!isFragment() || !Other->isFragment())
return true;
return fragmentCmp(Other) == 0;
}
bool isEntryValue() const;
std::pair<DIExpression *, const ConstantInt *>
constantFold(const ConstantInt *CI);
};
inline bool operator==(const DIExpression::FragmentInfo &A,
const DIExpression::FragmentInfo &B) {
return std::tie(A.SizeInBits, A.OffsetInBits) ==
std::tie(B.SizeInBits, B.OffsetInBits);
}
inline bool operator<(const DIExpression::FragmentInfo &A,
const DIExpression::FragmentInfo &B) {
return std::tie(A.SizeInBits, A.OffsetInBits) <
std::tie(B.SizeInBits, B.OffsetInBits);
}
template <> struct DenseMapInfo<DIExpression::FragmentInfo> {
using FragInfo = DIExpression::FragmentInfo;
static const uint64_t MaxVal = std::numeric_limits<uint64_t>::max();
static inline FragInfo getEmptyKey() { return {MaxVal, MaxVal}; }
static inline FragInfo getTombstoneKey() { return {MaxVal - 1, MaxVal - 1}; }
static unsigned getHashValue(const FragInfo &Frag) {
return (Frag.SizeInBits & 0xffff) << 16 | (Frag.OffsetInBits & 0xffff);
}
static bool isEqual(const FragInfo &A, const FragInfo &B) { return A == B; }
};
class DIGlobalVariable : public DIVariable {
friend class LLVMContextImpl;
friend class MDNode;
bool IsLocalToUnit;
bool IsDefinition;
DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
ArrayRef<Metadata *> Ops)
: DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
~DIGlobalVariable() = default;
static DIGlobalVariable *
getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type,
bool IsLocalToUnit, bool IsDefinition,
DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
uint32_t AlignInBits, DINodeArray Annotations, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, LinkageName), File, Line, Type,
IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
cast_or_null<Metadata>(TemplateParams), AlignInBits,
Annotations.get(), Storage, ShouldCreate);
}
static DIGlobalVariable *
getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
uint32_t AlignInBits, Metadata *Annotations, StorageType Storage,
bool ShouldCreate = true);
TempDIGlobalVariable cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
getFile(), getLine(), getType(), isLocalToUnit(),
isDefinition(), getStaticDataMemberDeclaration(),
getTemplateParams(), getAlignInBits(),
getAnnotations());
}
public:
DEFINE_MDNODE_GET(
DIGlobalVariable,
(DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition,
DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
uint32_t AlignInBits, DINodeArray Annotations),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations))
DEFINE_MDNODE_GET(
DIGlobalVariable,
(Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
uint32_t AlignInBits, Metadata *Annotations),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations))
TempDIGlobalVariable clone() const { return cloneImpl(); }
bool isLocalToUnit() const { return IsLocalToUnit; }
bool isDefinition() const { return IsDefinition; }
StringRef getDisplayName() const { return getStringOperand(4); }
StringRef getLinkageName() const { return getStringOperand(5); }
DIDerivedType *getStaticDataMemberDeclaration() const {
return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
}
DINodeArray getAnnotations() const {
return cast_or_null<MDTuple>(getRawAnnotations());
}
MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
Metadata *getRawTemplateParams() const { return getOperand(7); }
MDTuple *getTemplateParams() const { return getOperandAs<MDTuple>(7); }
Metadata *getRawAnnotations() const { return getOperand(8); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIGlobalVariableKind;
}
};
class DICommonBlock : public DIScope {
unsigned LineNo;
friend class LLVMContextImpl;
friend class MDNode;
DICommonBlock(LLVMContext &Context, StorageType Storage, unsigned LineNo,
ArrayRef<Metadata *> Ops);
static DICommonBlock *getImpl(LLVMContext &Context, DIScope *Scope,
DIGlobalVariable *Decl, StringRef Name,
DIFile *File, unsigned LineNo,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Scope, Decl, getCanonicalMDString(Context, Name),
File, LineNo, Storage, ShouldCreate);
}
static DICommonBlock *getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *Decl, MDString *Name, Metadata *File,
unsigned LineNo, StorageType Storage,
bool ShouldCreate = true);
TempDICommonBlock cloneImpl() const {
return getTemporary(getContext(), getScope(), getDecl(), getName(),
getFile(), getLineNo());
}
public:
DEFINE_MDNODE_GET(DICommonBlock,
(DIScope * Scope, DIGlobalVariable *Decl, StringRef Name,
DIFile *File, unsigned LineNo),
(Scope, Decl, Name, File, LineNo))
DEFINE_MDNODE_GET(DICommonBlock,
(Metadata * Scope, Metadata *Decl, MDString *Name,
Metadata *File, unsigned LineNo),
(Scope, Decl, Name, File, LineNo))
TempDICommonBlock clone() const { return cloneImpl(); }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
DIGlobalVariable *getDecl() const {
return cast_or_null<DIGlobalVariable>(getRawDecl());
}
StringRef getName() const { return getStringOperand(2); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
unsigned getLineNo() const { return LineNo; }
Metadata *getRawScope() const { return getOperand(0); }
Metadata *getRawDecl() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
Metadata *getRawFile() const { return getOperand(3); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DICommonBlockKind;
}
};
class DILocalVariable : public DIVariable {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Arg : 16;
DIFlags Flags;
DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
ArrayRef<Metadata *> Ops)
: DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
Arg(Arg), Flags(Flags) {
assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
}
~DILocalVariable() = default;
static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
StringRef Name, DIFile *File, unsigned Line,
DIType *Type, unsigned Arg, DIFlags Flags,
uint32_t AlignInBits, DINodeArray Annotations,
StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
Line, Type, Arg, Flags, AlignInBits, Annotations.get(),
Storage, ShouldCreate);
}
static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
MDString *Name, Metadata *File, unsigned Line,
Metadata *Type, unsigned Arg, DIFlags Flags,
uint32_t AlignInBits, Metadata *Annotations,
StorageType Storage,
bool ShouldCreate = true);
TempDILocalVariable cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(), getFile(),
getLine(), getType(), getArg(), getFlags(),
getAlignInBits(), getAnnotations());
}
public:
DEFINE_MDNODE_GET(DILocalVariable,
(DILocalScope * Scope, StringRef Name, DIFile *File,
unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags,
uint32_t AlignInBits, DINodeArray Annotations),
(Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
Annotations))
DEFINE_MDNODE_GET(DILocalVariable,
(Metadata * Scope, MDString *Name, Metadata *File,
unsigned Line, Metadata *Type, unsigned Arg, DIFlags Flags,
uint32_t AlignInBits, Metadata *Annotations),
(Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
Annotations))
TempDILocalVariable clone() const { return cloneImpl(); }
DILocalScope *getScope() const {
return cast<DILocalScope>(DIVariable::getScope());
}
bool isParameter() const { return Arg; }
unsigned getArg() const { return Arg; }
DIFlags getFlags() const { return Flags; }
DINodeArray getAnnotations() const {
return cast_or_null<MDTuple>(getRawAnnotations());
}
Metadata *getRawAnnotations() const { return getOperand(4); }
bool isArtificial() const { return getFlags() & FlagArtificial; }
bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
bool isValidLocationForIntrinsic(const DILocation *DL) const {
return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
}
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DILocalVariableKind;
}
};
class DILabel : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Line;
DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
ArrayRef<Metadata *> Ops);
~DILabel() = default;
static DILabel *getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
DIFile *File, unsigned Line, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
Line, Storage, ShouldCreate);
}
static DILabel *getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
Metadata *File, unsigned Line, StorageType Storage,
bool ShouldCreate = true);
TempDILabel cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(), getFile(),
getLine());
}
public:
DEFINE_MDNODE_GET(DILabel,
(DILocalScope * Scope, StringRef Name, DIFile *File,
unsigned Line),
(Scope, Name, File, Line))
DEFINE_MDNODE_GET(DILabel,
(Metadata * Scope, MDString *Name, Metadata *File,
unsigned Line),
(Scope, Name, File, Line))
TempDILabel clone() const { return cloneImpl(); }
DILocalScope *getScope() const {
return cast_or_null<DILocalScope>(getRawScope());
}
unsigned getLine() const { return Line; }
StringRef getName() const { return getStringOperand(1); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
Metadata *getRawScope() const { return getOperand(0); }
MDString *getRawName() const { return getOperandAs<MDString>(1); }
Metadata *getRawFile() const { return getOperand(2); }
bool isValidLocationForIntrinsic(const DILocation *DL) const {
return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
}
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DILabelKind;
}
};
class DIObjCProperty : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Line;
unsigned Attributes;
DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
unsigned Attributes, ArrayRef<Metadata *> Ops);
~DIObjCProperty() = default;
static DIObjCProperty *
getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
StringRef GetterName, StringRef SetterName, unsigned Attributes,
DIType *Type, StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
getCanonicalMDString(Context, GetterName),
getCanonicalMDString(Context, SetterName), Attributes, Type,
Storage, ShouldCreate);
}
static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
Metadata *File, unsigned Line,
MDString *GetterName, MDString *SetterName,
unsigned Attributes, Metadata *Type,
StorageType Storage, bool ShouldCreate = true);
TempDIObjCProperty cloneImpl() const {
return getTemporary(getContext(), getName(), getFile(), getLine(),
getGetterName(), getSetterName(), getAttributes(),
getType());
}
public:
DEFINE_MDNODE_GET(DIObjCProperty,
(StringRef Name, DIFile *File, unsigned Line,
StringRef GetterName, StringRef SetterName,
unsigned Attributes, DIType *Type),
(Name, File, Line, GetterName, SetterName, Attributes,
Type))
DEFINE_MDNODE_GET(DIObjCProperty,
(MDString * Name, Metadata *File, unsigned Line,
MDString *GetterName, MDString *SetterName,
unsigned Attributes, Metadata *Type),
(Name, File, Line, GetterName, SetterName, Attributes,
Type))
TempDIObjCProperty clone() const { return cloneImpl(); }
unsigned getLine() const { return Line; }
unsigned getAttributes() const { return Attributes; }
StringRef getName() const { return getStringOperand(0); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
StringRef getGetterName() const { return getStringOperand(2); }
StringRef getSetterName() const { return getStringOperand(3); }
DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
StringRef getFilename() const {
if (auto *F = getFile())
return F->getFilename();
return "";
}
StringRef getDirectory() const {
if (auto *F = getFile())
return F->getDirectory();
return "";
}
MDString *getRawName() const { return getOperandAs<MDString>(0); }
Metadata *getRawFile() const { return getOperand(1); }
MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
Metadata *getRawType() const { return getOperand(4); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIObjCPropertyKind;
}
};
class DIImportedEntity : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Line;
DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
unsigned Line, ArrayRef<Metadata *> Ops)
: DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
~DIImportedEntity() = default;
static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
DIScope *Scope, DINode *Entity, DIFile *File,
unsigned Line, StringRef Name,
DINodeArray Elements, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Tag, Scope, Entity, File, Line,
getCanonicalMDString(Context, Name), Elements.get(), Storage,
ShouldCreate);
}
static DIImportedEntity *
getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, Metadata *Entity,
Metadata *File, unsigned Line, MDString *Name, Metadata *Elements,
StorageType Storage, bool ShouldCreate = true);
TempDIImportedEntity cloneImpl() const {
return getTemporary(getContext(), getTag(), getScope(), getEntity(),
getFile(), getLine(), getName(), getElements());
}
public:
DEFINE_MDNODE_GET(DIImportedEntity,
(unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File,
unsigned Line, StringRef Name = "",
DINodeArray Elements = nullptr),
(Tag, Scope, Entity, File, Line, Name, Elements))
DEFINE_MDNODE_GET(DIImportedEntity,
(unsigned Tag, Metadata *Scope, Metadata *Entity,
Metadata *File, unsigned Line, MDString *Name,
Metadata *Elements = nullptr),
(Tag, Scope, Entity, File, Line, Name, Elements))
TempDIImportedEntity clone() const { return cloneImpl(); }
unsigned getLine() const { return Line; }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); }
StringRef getName() const { return getStringOperand(2); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
DINodeArray getElements() const {
return cast_or_null<MDTuple>(getRawElements());
}
Metadata *getRawScope() const { return getOperand(0); }
Metadata *getRawEntity() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
Metadata *getRawFile() const { return getOperand(3); }
Metadata *getRawElements() const { return getOperand(4); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIImportedEntityKind;
}
};
class DIGlobalVariableExpression : public MDNode {
friend class LLVMContextImpl;
friend class MDNode;
DIGlobalVariableExpression(LLVMContext &C, StorageType Storage,
ArrayRef<Metadata *> Ops)
: MDNode(C, DIGlobalVariableExpressionKind, Storage, Ops) {}
~DIGlobalVariableExpression() = default;
static DIGlobalVariableExpression *
getImpl(LLVMContext &Context, Metadata *Variable, Metadata *Expression,
StorageType Storage, bool ShouldCreate = true);
TempDIGlobalVariableExpression cloneImpl() const {
return getTemporary(getContext(), getVariable(), getExpression());
}
public:
DEFINE_MDNODE_GET(DIGlobalVariableExpression,
(Metadata * Variable, Metadata *Expression),
(Variable, Expression))
TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
Metadata *getRawVariable() const { return getOperand(0); }
DIGlobalVariable *getVariable() const {
return cast_or_null<DIGlobalVariable>(getRawVariable());
}
Metadata *getRawExpression() const { return getOperand(1); }
DIExpression *getExpression() const {
return cast<DIExpression>(getRawExpression());
}
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIGlobalVariableExpressionKind;
}
};
class DIMacroNode : public MDNode {
friend class LLVMContextImpl;
friend class MDNode;
protected:
DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType,
ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
: MDNode(C, ID, Storage, Ops1, Ops2) {
assert(MIType < 1u << 16);
SubclassData16 = MIType;
}
~DIMacroNode() = default;
template <class Ty> Ty *getOperandAs(unsigned I) const {
return cast_or_null<Ty>(getOperand(I));
}
StringRef getStringOperand(unsigned I) const {
if (auto *S = getOperandAs<MDString>(I))
return S->getString();
return StringRef();
}
static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
if (S.empty())
return nullptr;
return MDString::get(Context, S);
}
public:
unsigned getMacinfoType() const { return SubclassData16; }
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
return false;
case DIMacroKind:
case DIMacroFileKind:
return true;
}
}
};
class DIMacro : public DIMacroNode {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Line;
DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
ArrayRef<Metadata *> Ops)
: DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {}
~DIMacro() = default;
static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
StringRef Name, StringRef Value, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, Value), Storage, ShouldCreate);
}
static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
MDString *Name, MDString *Value, StorageType Storage,
bool ShouldCreate = true);
TempDIMacro cloneImpl() const {
return getTemporary(getContext(), getMacinfoType(), getLine(), getName(),
getValue());
}
public:
DEFINE_MDNODE_GET(DIMacro,
(unsigned MIType, unsigned Line, StringRef Name,
StringRef Value = ""),
(MIType, Line, Name, Value))
DEFINE_MDNODE_GET(DIMacro,
(unsigned MIType, unsigned Line, MDString *Name,
MDString *Value),
(MIType, Line, Name, Value))
TempDIMacro clone() const { return cloneImpl(); }
unsigned getLine() const { return Line; }
StringRef getName() const { return getStringOperand(0); }
StringRef getValue() const { return getStringOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(0); }
MDString *getRawValue() const { return getOperandAs<MDString>(1); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIMacroKind;
}
};
class DIMacroFile : public DIMacroNode {
friend class LLVMContextImpl;
friend class MDNode;
unsigned Line;
DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
unsigned Line, ArrayRef<Metadata *> Ops)
: DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {}
~DIMacroFile() = default;
static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
unsigned Line, DIFile *File,
DIMacroNodeArray Elements, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, MIType, Line, static_cast<Metadata *>(File),
Elements.get(), Storage, ShouldCreate);
}
static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
unsigned Line, Metadata *File, Metadata *Elements,
StorageType Storage, bool ShouldCreate = true);
TempDIMacroFile cloneImpl() const {
return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(),
getElements());
}
public:
DEFINE_MDNODE_GET(DIMacroFile,
(unsigned MIType, unsigned Line, DIFile *File,
DIMacroNodeArray Elements),
(MIType, Line, File, Elements))
DEFINE_MDNODE_GET(DIMacroFile,
(unsigned MIType, unsigned Line, Metadata *File,
Metadata *Elements),
(MIType, Line, File, Elements))
TempDIMacroFile clone() const { return cloneImpl(); }
void replaceElements(DIMacroNodeArray Elements) {
#ifndef NDEBUG
for (DIMacroNode *Op : getElements())
assert(is_contained(Elements->operands(), Op) &&
"Lost a macro node during macro node list replacement");
#endif
replaceOperandWith(1, Elements.get());
}
unsigned getLine() const { return Line; }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
DIMacroNodeArray getElements() const {
return cast_or_null<MDTuple>(getRawElements());
}
Metadata *getRawFile() const { return getOperand(0); }
Metadata *getRawElements() const { return getOperand(1); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIMacroFileKind;
}
};
class DIArgList : public MDNode {
friend class LLVMContextImpl;
friend class MDNode;
using iterator = SmallVectorImpl<ValueAsMetadata *>::iterator;
SmallVector<ValueAsMetadata *, 4> Args;
DIArgList(LLVMContext &C, StorageType Storage,
ArrayRef<ValueAsMetadata *> Args)
: MDNode(C, DIArgListKind, Storage, None),
Args(Args.begin(), Args.end()) {
track();
}
~DIArgList() { untrack(); }
static DIArgList *getImpl(LLVMContext &Context,
ArrayRef<ValueAsMetadata *> Args,
StorageType Storage, bool ShouldCreate = true);
TempDIArgList cloneImpl() const {
return getTemporary(getContext(), getArgs());
}
void track();
void untrack();
void dropAllReferences();
public:
DEFINE_MDNODE_GET(DIArgList, (ArrayRef<ValueAsMetadata *> Args), (Args))
TempDIArgList clone() const { return cloneImpl(); }
ArrayRef<ValueAsMetadata *> getArgs() const { return Args; }
iterator args_begin() { return Args.begin(); }
iterator args_end() { return Args.end(); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIArgListKind;
}
void handleChangedOperand(void *Ref, Metadata *New);
};
class DebugVariable {
using FragmentInfo = DIExpression::FragmentInfo;
const DILocalVariable *Variable;
Optional<FragmentInfo> Fragment;
const DILocation *InlinedAt;
static const FragmentInfo DefaultFragment;
public:
DebugVariable(const DILocalVariable *Var, Optional<FragmentInfo> FragmentInfo,
const DILocation *InlinedAt)
: Variable(Var), Fragment(FragmentInfo), InlinedAt(InlinedAt) {}
DebugVariable(const DILocalVariable *Var, const DIExpression *DIExpr,
const DILocation *InlinedAt)
: Variable(Var),
Fragment(DIExpr ? DIExpr->getFragmentInfo() : NoneType()),
InlinedAt(InlinedAt) {}
const DILocalVariable *getVariable() const { return Variable; }
Optional<FragmentInfo> getFragment() const { return Fragment; }
const DILocation *getInlinedAt() const { return InlinedAt; }
FragmentInfo getFragmentOrDefault() const {
return Fragment.value_or(DefaultFragment);
}
static bool isDefaultFragment(const FragmentInfo F) {
return F == DefaultFragment;
}
bool operator==(const DebugVariable &Other) const {
return std::tie(Variable, Fragment, InlinedAt) ==
std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
}
bool operator<(const DebugVariable &Other) const {
return std::tie(Variable, Fragment, InlinedAt) <
std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
}
};
template <> struct DenseMapInfo<DebugVariable> {
using FragmentInfo = DIExpression::FragmentInfo;
static inline DebugVariable getEmptyKey() {
return DebugVariable(nullptr, NoneType(), nullptr);
}
static inline DebugVariable getTombstoneKey() {
return DebugVariable(nullptr, {{0, 0}}, nullptr);
}
static unsigned getHashValue(const DebugVariable &D) {
unsigned HV = 0;
const Optional<FragmentInfo> Fragment = D.getFragment();
if (Fragment)
HV = DenseMapInfo<FragmentInfo>::getHashValue(*Fragment);
return hash_combine(D.getVariable(), HV, D.getInlinedAt());
}
static bool isEqual(const DebugVariable &A, const DebugVariable &B) {
return A == B;
}
};
}
#undef DEFINE_MDNODE_GET_UNPACK_IMPL
#undef DEFINE_MDNODE_GET_UNPACK
#undef DEFINE_MDNODE_GET
#endif