summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/DebugInfoMetadata.h18
-rw-r--r--llvm/include/llvm/IR/Metadata.h50
-rw-r--r--llvm/lib/IR/Verifier.cpp4
3 files changed, 61 insertions, 11 deletions
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 5875910b91e..a03e8764ade 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -607,7 +607,7 @@ public:
return cast_or_null<MDTuple>(getRawElements());
}
Metadata *getVTableHolder() const { return getRawVTableHolder(); }
- MDTuple *getTemplateParams() const {
+ MDTemplateParameterArray getTemplateParams() const {
return cast_or_null<MDTuple>(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<MDTuple>(getRawEnumTypes());
}
- MDTuple *getRetainedTypes() const {
+ MDTypeArray getRetainedTypes() const {
return cast_or_null<MDTuple>(getRawRetainedTypes());
}
- MDTuple *getSubprograms() const {
+ MDSubprogramArray getSubprograms() const {
return cast_or_null<MDTuple>(getRawSubprograms());
}
- MDTuple *getGlobalVariables() const {
+ MDGlobalVariableArray getGlobalVariables() const {
return cast_or_null<MDTuple>(getRawGlobalVariables());
}
- MDTuple *getImportedEntities() const {
+ MDImportedEntityArray getImportedEntities() const {
return cast_or_null<MDTuple>(getRawImportedEntities());
}
@@ -1103,13 +1103,13 @@ public:
ConstantAsMetadata *getFunction() const {
return cast_or_null<ConstantAsMetadata>(getRawFunction());
}
- MDTuple *getTemplateParams() const {
+ MDTemplateParameterArray getTemplateParams() const {
return cast_or_null<MDTuple>(getRawTemplateParams());
}
MDSubprogram *getDeclaration() const {
return cast_or_null<MDSubprogram>(getRawDeclaration());
}
- MDTuple *getVariables() const {
+ MDLocalVariableArray getVariables() const {
return cast_or_null<MDTuple>(getRawVariables());
}
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 825c11e2661..ae6a20b2b9c 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/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 T>
+class TypedMDOperandIterator
+ : std::iterator<std::input_iterator_tag, T *, std::ptrdiff_t, void, T *> {
+ MDNode::op_iterator I;
+
+public:
+ 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(const MDTuple *N) : N(N) {}
+ operator MDTuple *() const { return const_cast<MDTuple *>(N); }
+ MDTuple *operator->() const { return const_cast<MDTuple *>(N); }
+ MDTuple &operator*() const { return *const_cast<MDTuple *>(N); }
+
+ unsigned size() const { return N->getNumOperands(); }
+ T *operator[](unsigned I) const { return cast_or_null<T>(N->getOperand(I)); }
+
+ typedef TypedMDOperandIterator<T> iterator;
+ iterator begin() const { return iterator(N->op_begin()); }
+ iterator end() const { return iterator(N->op_end()); }
+};
+
+#define HANDLE_METADATA(CLASS) \
+ typedef MDTupleTypedArrayWrapper<CLASS> CLASS##Array;
+#include "llvm/IR/Metadata.def"
+
//===----------------------------------------------------------------------===//
/// \brief A tuple of MDNodes.
///
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 480c2e5581e..385e3302e1d 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/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<MDCompileUnit>(CU)->getRetainedTypes())
- for (auto &Op : Ts->operands())
+ if (auto Ts = cast<MDCompileUnit>(CU)->getRetainedTypes())
+ for (MDType *Op : Ts)
if (auto *T = dyn_cast<MDCompositeType>(Op))
TypeRefs.erase(T->getRawIdentifier());
if (TypeRefs.empty())
OpenPOWER on IntegriCloud