public:
enum MetadataKind {
MDTupleKind,
- MDLocationKind,
- GenericDebugNodeKind,
- MDSubrangeKind,
- MDEnumeratorKind,
- MDBasicTypeKind,
- MDDerivedTypeKind,
- MDCompositeTypeKind,
- MDSubroutineTypeKind,
- MDFileKind,
- MDCompileUnitKind,
- MDSubprogramKind,
- MDLexicalBlockKind,
- MDLexicalBlockFileKind,
- MDNamespaceKind,
- MDTemplateTypeParameterKind,
- MDTemplateValueParameterKind,
- MDGlobalVariableKind,
- MDLocalVariableKind,
- MDExpressionKind,
- MDObjCPropertyKind,
- MDImportedEntityKind,
+ DILocationKind,
+ GenericDINodeKind,
+ DISubrangeKind,
+ DIEnumeratorKind,
+ DIBasicTypeKind,
+ DIDerivedTypeKind,
+ DICompositeTypeKind,
+ DISubroutineTypeKind,
+ DIFileKind,
+ DICompileUnitKind,
+ DISubprogramKind,
+ DILexicalBlockKind,
+ DILexicalBlockFileKind,
+ DINamespaceKind,
+ 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.
///
///
/// If \c M is provided, metadata nodes will be numbered canonically;
/// otherwise, pointer addresses are substituted.
- void dump(const Module *M = nullptr) const;
+ ///
+ /// 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 dump(const Module *M) const;
+ /// @}
/// \brief Print.
///
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);
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,
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.
///
}
};
-} // end llvm namespace
+} // namespace llvm
#endif