From 8eb45116ef6ba34a579b4c55f906b7f3371dc606 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Mon, 6 Apr 2015 17:45:07 +0000 Subject: [PATCH] Metadata: Add typed array-like wrapper for MDTuple Add `MDTupleTypedArrayWrapper`, a wrapper around `MDTuple` that adapts it to look like an array and cast its operands to the given type. This is designed to be a replacement for `DITypedArray<>`, which is in the `DIDescriptor` hierarchy. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234183 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/DebugInfoMetadata.h | 18 +++++------ include/llvm/IR/Metadata.h | 50 +++++++++++++++++++++++++++++ lib/IR/Verifier.cpp | 4 +-- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 5875910b91e..a03e8764ade 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -607,7 +607,7 @@ public: return cast_or_null(getRawElements()); } Metadata *getVTableHolder() const { return getRawVTableHolder(); } - MDTuple *getTemplateParams() const { + MDTemplateParameterArray getTemplateParams() const { return cast_or_null(getRawTemplateParams()); } StringRef getIdentifier() const { return getStringOperand(7); } @@ -636,7 +636,7 @@ public: void replaceVTableHolder(Metadata *VTableHolder) { replaceOperandWith(5, VTableHolder); } - void replaceTemplateParams(MDTuple *TemplateParams) { + void replaceTemplateParams(MDTemplateParameterArray TemplateParams) { replaceOperandWith(6, TemplateParams); } /// @} @@ -844,19 +844,19 @@ public: StringRef getProducer() const { return getStringOperand(1); } StringRef getFlags() const { return getStringOperand(2); } StringRef getSplitDebugFilename() const { return getStringOperand(3); } - MDTuple *getEnumTypes() const { + MDCompositeTypeArray getEnumTypes() const { return cast_or_null(getRawEnumTypes()); } - MDTuple *getRetainedTypes() const { + MDTypeArray getRetainedTypes() const { return cast_or_null(getRawRetainedTypes()); } - MDTuple *getSubprograms() const { + MDSubprogramArray getSubprograms() const { return cast_or_null(getRawSubprograms()); } - MDTuple *getGlobalVariables() const { + MDGlobalVariableArray getGlobalVariables() const { return cast_or_null(getRawGlobalVariables()); } - MDTuple *getImportedEntities() const { + MDImportedEntityArray getImportedEntities() const { return cast_or_null(getRawImportedEntities()); } @@ -1103,13 +1103,13 @@ public: ConstantAsMetadata *getFunction() const { return cast_or_null(getRawFunction()); } - MDTuple *getTemplateParams() const { + MDTemplateParameterArray getTemplateParams() const { return cast_or_null(getRawTemplateParams()); } MDSubprogram *getDeclaration() const { return cast_or_null(getRawDeclaration()); } - MDTuple *getVariables() const { + MDLocalVariableArray getVariables() const { return cast_or_null(getRawVariables()); } diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index 825c11e2661..ae6a20b2b9c 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -1033,6 +1033,56 @@ 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 TypedMDOperandIterator + : std::iterator { + MDNode::op_iterator I; + +public: + explicit TypedMDOperandIterator(MDNode::op_iterator I) : I(I) {} + T *operator*() const { return cast_or_null(*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 MDTupleTypedArrayWrapper { + const MDTuple *N = nullptr; + +public: + MDTupleTypedArrayWrapper(const MDTuple *N) : N(N) {} + operator MDTuple *() const { return const_cast(N); } + MDTuple *operator->() const { return const_cast(N); } + MDTuple &operator*() const { return *const_cast(N); } + + unsigned size() const { return N->getNumOperands(); } + T *operator[](unsigned I) const { return cast_or_null(N->getOperand(I)); } + + typedef TypedMDOperandIterator iterator; + iterator begin() const { return iterator(N->op_begin()); } + iterator end() const { return iterator(N->op_end()); } +}; + +#define HANDLE_METADATA(CLASS) \ + typedef MDTupleTypedArrayWrapper CLASS##Array; +#include "llvm/IR/Metadata.def" + //===----------------------------------------------------------------------===// /// \brief A tuple of MDNodes. /// diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 480c2e5581e..385e3302e1d 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -3401,8 +3401,8 @@ void Verifier::verifyTypeRefs() { // Visit all the compile units again to check the type references. for (auto *CU : CUs->operands()) - if (auto *Ts = cast(CU)->getRetainedTypes()) - for (auto &Op : Ts->operands()) + if (auto Ts = cast(CU)->getRetainedTypes()) + for (MDType *Op : Ts) if (auto *T = dyn_cast(Op)) TypeRefs.erase(T->getRawIdentifier()); if (TypeRefs.empty()) -- 2.34.1