-//===-- llvm/Metadata.h - Metadata definitions ------------------*- C++ -*-===//
+//===- llvm/IR/Metadata.h - Metadata definitions ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#include <type_traits>
namespace llvm {
+
class LLVMContext;
class Module;
+class ModuleSlotTracker;
+
template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
-
enum LLVMConstants : uint32_t {
- DEBUG_METADATA_VERSION = 2 // Current debug info version number.
+ DEBUG_METADATA_VERSION = 3 // Current debug info version number.
};
/// \brief Root of the metadata hierarchy.
public:
enum MetadataKind {
MDTupleKind,
- MDLocationKind,
- GenericDwarfNodeKind,
+ DILocationKind,
+ GenericDINodeKind,
+ DISubrangeKind,
+ DIEnumeratorKind,
+ DIBasicTypeKind,
+ DIDerivedTypeKind,
+ DICompositeTypeKind,
+ DISubroutineTypeKind,
+ DIFileKind,
+ DICompileUnitKind,
+ DISubprogramKind,
+ DILexicalBlockKind,
+ DILexicalBlockFileKind,
+ DINamespaceKind,
+ DIModuleKind,
+ DITemplateTypeParameterKind,
+ DITemplateValueParameterKind,
+ DIGlobalVariableKind,
+ DILocalVariableKind,
+ DIExpressionKind,
+ DIObjCPropertyKind,
+ DIImportedEntityKind,
ConstantAsMetadataKind,
LocalAsMetadataKind,
MDStringKind
Metadata(unsigned ID, StorageType Storage)
: SubclassID(ID), Storage(Storage), SubclassData16(0), SubclassData32(0) {
}
- ~Metadata() {}
+ ~Metadata() = default;
/// \brief Default handling of a changed operand, which asserts.
///
unsigned getMetadataID() const { return SubclassID; }
/// \brief User-friendly dump.
+ ///
+ /// If \c M is provided, metadata nodes will be numbered canonically;
+ /// otherwise, pointer addresses are substituted.
+ ///
+ /// Note: this uses an explicit overload instead of default arguments so that
+ /// the nullptr version is easy to call from a debugger.
+ ///
+ /// @{
void dump() const;
- void print(raw_ostream &OS) const;
- void printAsOperand(raw_ostream &OS, bool PrintType = true,
+ void dump(const Module *M) const;
+ /// @}
+
+ /// \brief Print.
+ ///
+ /// Prints definition of \c this.
+ ///
+ /// If \c M is provided, metadata nodes will be numbered canonically;
+ /// otherwise, pointer addresses are substituted.
+ /// @{
+ void print(raw_ostream &OS, const Module *M = nullptr,
+ bool IsForDebug = false) const;
+ void print(raw_ostream &OS, ModuleSlotTracker &MST, const Module *M = nullptr,
+ bool IsForDebug = false) const;
+ /// @}
+
+ /// \brief Print as operand.
+ ///
+ /// Prints reference of \c this.
+ ///
+ /// If \c M is provided, metadata nodes will be numbered canonically;
+ /// otherwise, pointer addresses are substituted.
+ /// @{
+ void printAsOperand(raw_ostream &OS, const Module *M = nullptr) const;
+ void printAsOperand(raw_ostream &OS, ModuleSlotTracker &MST,
const Module *M = nullptr) const;
+ /// @}
};
#define HANDLE_METADATA(CLASS) class CLASS;
#include "llvm/IR/Metadata.def"
+// Provide specializations of isa so that we don't need definitions of
+// subclasses to see if the metadata is a subclass.
+#define HANDLE_METADATA_LEAF(CLASS) \
+ template <> struct isa_impl<CLASS, Metadata> { \
+ static inline bool doit(const Metadata &MD) { \
+ return MD.getMetadataID() == Metadata::CLASS##Kind; \
+ } \
+ };
+#include "llvm/IR/Metadata.def"
+
inline raw_ostream &operator<<(raw_ostream &OS, const Metadata &MD) {
MD.print(OS);
return OS;
Metadata *MD;
MetadataAsValue(Type *Ty, Metadata *MD);
- ~MetadataAsValue();
+ ~MetadataAsValue() override;
/// \brief Drop use of metadata (during teardown).
void dropUse() { MD = nullptr; }
: Metadata(ID, Uniqued), ReplaceableMetadataImpl(V->getContext()), V(V) {
assert(V && "Expected valid value");
}
- ~ValueAsMetadata() {}
+ ~ValueAsMetadata() = default;
public:
static ValueAsMetadata *get(Value *V);
class MDString : public Metadata {
friend class StringMapEntry<MDString>;
- MDString(const MDString &) LLVM_DELETED_FUNCTION;
- MDString &operator=(MDString &&) LLVM_DELETED_FUNCTION;
- MDString &operator=(const MDString &) LLVM_DELETED_FUNCTION;
+ MDString(const MDString &) = delete;
+ MDString &operator=(MDString &&) = delete;
+ MDString &operator=(const MDString &) = delete;
StringMapEntry<MDString> *Entry;
MDString() : Metadata(MDStringKind, Uniqued), Entry(nullptr) {}
bool operator!=(const AAMDNodes &A) const { return !(*this == A); }
- LLVM_EXPLICIT operator bool() const { return TBAA || Scope || NoAlias; }
+ explicit operator bool() const { return TBAA || Scope || NoAlias; }
/// \brief The tag for type-based alias analysis.
MDNode *TBAA;
template<>
struct DenseMapInfo<AAMDNodes> {
static inline AAMDNodes getEmptyKey() {
- return AAMDNodes(DenseMapInfo<MDNode *>::getEmptyKey(), 0, 0);
+ return AAMDNodes(DenseMapInfo<MDNode *>::getEmptyKey(),
+ nullptr, nullptr);
}
static inline AAMDNodes getTombstoneKey() {
- return AAMDNodes(DenseMapInfo<MDNode *>::getTombstoneKey(), 0, 0);
+ return AAMDNodes(DenseMapInfo<MDNode *>::getTombstoneKey(),
+ nullptr, nullptr);
}
static unsigned getHashValue(const AAMDNodes &Val) {
return DenseMapInfo<MDNode *>::getHashValue(Val.TBAA) ^
///
/// In particular, this is used by \a MDNode.
class MDOperand {
- MDOperand(MDOperand &&) LLVM_DELETED_FUNCTION;
- MDOperand(const MDOperand &) LLVM_DELETED_FUNCTION;
- MDOperand &operator=(MDOperand &&) LLVM_DELETED_FUNCTION;
- MDOperand &operator=(const MDOperand &) LLVM_DELETED_FUNCTION;
+ MDOperand(MDOperand &&) = delete;
+ MDOperand(const MDOperand &) = delete;
+ MDOperand &operator=(MDOperand &&) = delete;
+ MDOperand &operator=(const MDOperand &) = delete;
Metadata *MD;
class ContextAndReplaceableUses {
PointerUnion<LLVMContext *, ReplaceableMetadataImpl *> Ptr;
- ContextAndReplaceableUses() LLVM_DELETED_FUNCTION;
- ContextAndReplaceableUses(ContextAndReplaceableUses &&)
- LLVM_DELETED_FUNCTION;
- ContextAndReplaceableUses(const ContextAndReplaceableUses &)
- LLVM_DELETED_FUNCTION;
+ ContextAndReplaceableUses() = delete;
+ ContextAndReplaceableUses(ContextAndReplaceableUses &&) = delete;
+ ContextAndReplaceableUses(const ContextAndReplaceableUses &) = delete;
+ ContextAndReplaceableUses &operator=(ContextAndReplaceableUses &&) = delete;
ContextAndReplaceableUses &
- operator=(ContextAndReplaceableUses &&) LLVM_DELETED_FUNCTION;
- ContextAndReplaceableUses &
- operator=(const ContextAndReplaceableUses &) LLVM_DELETED_FUNCTION;
+ operator=(const ContextAndReplaceableUses &) = delete;
public:
ContextAndReplaceableUses(LLVMContext &Context) : Ptr(&Context) {}
friend class ReplaceableMetadataImpl;
friend class LLVMContextImpl;
- MDNode(const MDNode &) LLVM_DELETED_FUNCTION;
- void operator=(const MDNode &) LLVM_DELETED_FUNCTION;
- void *operator new(size_t) LLVM_DELETED_FUNCTION;
+ MDNode(const MDNode &) = delete;
+ void operator=(const MDNode &) = delete;
+ void *operator new(size_t) = delete;
unsigned NumOperands;
unsigned NumUnresolved;
MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None);
- ~MDNode() {}
+ ~MDNode() = default;
void dropAllReferences();
MDOperand *mutable_begin() { return mutable_end() - NumOperands; }
MDOperand *mutable_end() { return reinterpret_cast<MDOperand *>(this); }
+ typedef iterator_range<MDOperand *> mutable_op_range;
+ mutable_op_range mutable_operands() {
+ return mutable_op_range(mutable_begin(), mutable_end());
+ }
+
public:
static inline MDTuple *get(LLVMContext &Context, ArrayRef<Metadata *> MDs);
static inline MDTuple *getIfExists(LLVMContext &Context,
/// \brief Deallocate a node created by getTemporary.
///
- /// The node must not have any users.
+ /// Calls \c replaceAllUsesWith(nullptr) before deleting, so any remaining
+ /// references will be reset.
static void deleteTemporary(MDNode *N);
LLVMContext &getContext() const { return Context.getContext(); }
/// \pre No operands (or operands' operands, etc.) have \a isTemporary().
void resolveCycles();
+ /// \brief Replace a temporary node with a permanent one.
+ ///
+ /// Try to create a uniqued version of \c N -- in place, if possible -- and
+ /// return it. If \c N cannot be uniqued, return a distinct node instead.
+ template <class T>
+ static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
+ replaceWithPermanent(std::unique_ptr<T, TempMDNodeDeleter> N) {
+ return cast<T>(N.release()->replaceWithPermanentImpl());
+ }
+
/// \brief Replace a temporary node with a uniqued one.
///
/// Create a uniqued version of \c N -- in place, if possible -- and return
/// it. Takes ownership of the temporary node.
+ ///
+ /// \pre N does not self-reference.
template <class T>
static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
replaceWithUniqued(std::unique_ptr<T, TempMDNodeDeleter> N) {
}
private:
+ MDNode *replaceWithPermanentImpl();
MDNode *replaceWithUniquedImpl();
MDNode *replaceWithDistinctImpl();
void storeDistinctInContext();
template <class T, class StoreT>
static T *storeImpl(T *N, StorageType Storage, StoreT &Store);
+ template <class T> static T *storeImpl(T *N, StorageType Storage);
private:
void handleChangedOperand(void *Ref, Metadata *New);
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDTupleKind ||
- MD->getMetadataID() == MDLocationKind ||
- MD->getMetadataID() == GenericDwarfNodeKind;
+ switch (MD->getMetadataID()) {
+ default:
+ return false;
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case CLASS##Kind: \
+ return true;
+#include "llvm/IR/Metadata.def"
+ }
}
/// \brief Check whether MDNode is a vtable access.
static MDNode *getMostGenericTBAA(MDNode *A, MDNode *B);
static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
+ static MDNode *getMostGenericAliasScope(MDNode *A, MDNode *B);
};
/// \brief Tuple of metadata.
MDNode::deleteTemporary(Node);
}
-/// \brief Debug location.
+/// \brief Typed iterator through MDNode operands.
///
-/// A debug location in source code, used for debug info and otherwise.
-class MDLocation : public MDNode {
- friend class LLVMContextImpl;
- friend class MDNode;
-
- MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
- unsigned Column, ArrayRef<Metadata *> MDs);
- ~MDLocation() { dropAllReferences(); }
-
- static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt, StorageType Storage,
- bool ShouldCreate = true);
-
- TempMDLocation cloneImpl() const {
- return getTemporary(getContext(), getLine(), getColumn(), getScope(),
- getInlinedAt());
- }
-
- // Disallow replacing operands.
- void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION;
+/// An iterator that transforms an \a MDNode::iterator into an iterator over a
+/// particular Metadata subclass.
+template <class T>
+class TypedMDOperandIterator
+ : std::iterator<std::input_iterator_tag, T *, std::ptrdiff_t, void, T *> {
+ MDNode::op_iterator I = nullptr;
public:
- static MDLocation *get(LLVMContext &Context, unsigned Line, unsigned Column,
- Metadata *Scope, Metadata *InlinedAt = nullptr) {
- return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued);
- }
- static MDLocation *getIfExists(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt = nullptr) {
- return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued,
- /* ShouldCreate */ false);
- }
- static MDLocation *getDistinct(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt = nullptr) {
- return getImpl(Context, Line, Column, Scope, InlinedAt, Distinct);
- }
- static TempMDLocation getTemporary(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt = nullptr) {
- return TempMDLocation(
- getImpl(Context, Line, Column, Scope, InlinedAt, Temporary));
- }
-
- /// \brief Return a (temporary) clone of this.
- TempMDLocation clone() const { return cloneImpl(); }
-
- unsigned getLine() const { return SubclassData32; }
- unsigned getColumn() const { return SubclassData16; }
- Metadata *getScope() const { return getOperand(0); }
- Metadata *getInlinedAt() const {
- if (getNumOperands() == 2)
- return getOperand(1);
- return nullptr;
- }
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDLocationKind;
- }
+ TypedMDOperandIterator() = default;
+ explicit TypedMDOperandIterator(MDNode::op_iterator I) : I(I) {}
+ T *operator*() const { return cast_or_null<T>(*I); }
+ TypedMDOperandIterator &operator++() {
+ ++I;
+ return *this;
+ }
+ TypedMDOperandIterator operator++(int) {
+ TypedMDOperandIterator Temp(*this);
+ ++I;
+ return Temp;
+ }
+ bool operator==(const TypedMDOperandIterator &X) const { return I == X.I; }
+ bool operator!=(const TypedMDOperandIterator &X) const { return I != X.I; }
};
-/// \brief Tagged dwarf node.
+/// \brief Typed, array-like tuple of metadata.
///
-/// A metadata node with a DWARF tag.
-class DwarfNode : public MDNode {
- friend class LLVMContextImpl;
- friend class MDNode;
-
-protected:
- DwarfNode(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;
- }
- ~DwarfNode() {}
+/// This is a wrapper for \a MDTuple that makes it act like an array holding a
+/// particular type of metadata.
+template <class T> class MDTupleTypedArrayWrapper {
+ const MDTuple *N = nullptr;
public:
- unsigned getTag() const { return SubclassData16; }
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == GenericDwarfNodeKind;
- }
+ MDTupleTypedArrayWrapper() = default;
+ MDTupleTypedArrayWrapper(const MDTuple *N) : N(N) {}
+
+ template <class U>
+ MDTupleTypedArrayWrapper(
+ const MDTupleTypedArrayWrapper<U> &Other,
+ typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
+ nullptr)
+ : N(Other.get()) {}
+
+ template <class U>
+ explicit MDTupleTypedArrayWrapper(
+ const MDTupleTypedArrayWrapper<U> &Other,
+ typename std::enable_if<!std::is_convertible<U *, T *>::value>::type * =
+ nullptr)
+ : N(Other.get()) {}
+
+ 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(); }
+
+ // FIXME: Fix callers and remove condition on N.
+ unsigned size() const { return N ? N->getNumOperands() : 0u; }
+ T *operator[](unsigned I) const { return cast_or_null<T>(N->getOperand(I)); }
+
+ // FIXME: Fix callers and remove condition on N.
+ typedef TypedMDOperandIterator<T> iterator;
+ iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
+ iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
};
-/// \brief Generic tagged dwarf node.
-///
-/// A generic metadata node with a DWARF tag that doesn't have special
-/// handling.
-class GenericDwarfNode : public DwarfNode {
- friend class LLVMContextImpl;
- friend class MDNode;
-
- GenericDwarfNode(LLVMContext &C, StorageType Storage, unsigned Hash,
- unsigned Tag, ArrayRef<Metadata *> Ops1,
- ArrayRef<Metadata *> Ops2)
- : DwarfNode(C, GenericDwarfNodeKind, Storage, Tag, Ops1, Ops2) {
- setHash(Hash);
- }
- ~GenericDwarfNode() { dropAllReferences(); }
-
- void setHash(unsigned Hash) { SubclassData32 = Hash; }
- void recalculateHash();
-
- static GenericDwarfNode *getImpl(LLVMContext &Context, unsigned Tag,
- MDString *Header,
- ArrayRef<Metadata *> DwarfOps,
- StorageType Storage,
- bool ShouldCreate = true);
-
- TempGenericDwarfNode cloneImpl() const {
- return getTemporary(
- getContext(), getTag(), getHeader(),
- SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
- }
-
-public:
- unsigned getHash() const { return SubclassData32; }
-
- static GenericDwarfNode *get(LLVMContext &Context,
- unsigned Tag,
- MDString *Header,
- ArrayRef<Metadata *> DwarfOps) {
- return getImpl(Context, Tag, Header, DwarfOps, Uniqued);
- }
- static GenericDwarfNode *getIfExists(LLVMContext &Context, unsigned Tag,
- MDString *Header,
- ArrayRef<Metadata *> DwarfOps) {
- return getImpl(Context, Tag, Header, DwarfOps, Uniqued,
- /* ShouldCreate */ false);
- }
- static GenericDwarfNode *getDistinct(LLVMContext &Context, unsigned Tag,
- MDString *Header,
- ArrayRef<Metadata *> DwarfOps) {
- return getImpl(Context, Tag, Header, DwarfOps, Distinct);
- }
- static TempGenericDwarfNode getTemporary(LLVMContext &Context, unsigned Tag,
- MDString *Header,
- ArrayRef<Metadata *> DwarfOps) {
- return TempGenericDwarfNode(
- getImpl(Context, Tag, Header, DwarfOps, Temporary));
- }
-
- /// \brief Return a (temporary) clone of this.
- TempGenericDwarfNode clone() const { return cloneImpl(); }
-
- unsigned getTag() const { return SubclassData16; }
- MDString *getHeader() const { return cast_or_null<MDString>(getOperand(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() == GenericDwarfNodeKind;
- }
-};
+#define HANDLE_METADATA(CLASS) \
+ typedef MDTupleTypedArrayWrapper<CLASS> CLASS##Array;
+#include "llvm/IR/Metadata.def"
//===----------------------------------------------------------------------===//
/// \brief A tuple of MDNodes.
friend struct ilist_traits<NamedMDNode>;
friend class LLVMContextImpl;
friend class Module;
- NamedMDNode(const NamedMDNode &) LLVM_DELETED_FUNCTION;
+ NamedMDNode(const NamedMDNode &) = delete;
std::string Name;
Module *Parent;
void addOperand(MDNode *M);
void setOperand(unsigned I, MDNode *New);
StringRef getName() const;
- void print(raw_ostream &ROS) const;
+ void print(raw_ostream &ROS, bool IsForDebug = false) const;
void dump() const;
// ---------------------------------------------------------------------------
} // end llvm namespace
-#endif
+#endif // LLVM_IR_METADATA_H