diff options
Diffstat (limited to 'include/llvm/IR/Metadata.h')
-rw-r--r-- | include/llvm/IR/Metadata.h | 85 |
1 files changed, 81 insertions, 4 deletions
diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index a31bdbf..03e70fe 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -89,7 +89,7 @@ protected: 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. /// @@ -164,7 +164,7 @@ class MetadataAsValue : public Value { Metadata *MD; MetadataAsValue(Type *Ty, Metadata *MD); - ~MetadataAsValue(); + ~MetadataAsValue() override; /// \brief Drop use of metadata (during teardown). void dropUse() { MD = nullptr; } @@ -253,7 +253,7 @@ protected: : Metadata(ID, Uniqued), ReplaceableMetadataImpl(V->getContext()), V(V) { assert(V && "Expected valid value"); } - ~ValueAsMetadata() {} + ~ValueAsMetadata() = default; public: static ValueAsMetadata *get(Value *V); @@ -754,13 +754,18 @@ protected: 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, @@ -1028,6 +1033,78 @@ void TempMDNodeDeleter::operator()(MDNode *Node) const { MDNode::deleteTemporary(Node); } +/// \brief Typed iterator through MDNode operands. +/// +/// 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: + 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 Typed, array-like tuple of metadata. +/// +/// 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: + 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(); } +}; + +#define HANDLE_METADATA(CLASS) \ + typedef MDTupleTypedArrayWrapper<CLASS> CLASS##Array; +#include "llvm/IR/Metadata.def" + //===----------------------------------------------------------------------===// /// \brief A tuple of MDNodes. /// |