Skip to content

Commit 9149ae0

Browse files
committed
Support value-typed references in iterator facade's operator->()
Add a PointerProxy similar to the existing iterator_facade_base::ReferenceProxy and return it from the arrow operator. This prevents iterator facades with a reference type that is not a true reference to take the address of a temporary. Forward the reference type of the mapped_iterator to the iterator adaptor which in turn forwards it to the iterator facade. This fixes mlir::op_iterator::operator->() to take the address of a temporary. Make some polishing changes to op_iterator and op_filter_iterator. Reviewed By: rriddle Differential Revision: https://reviews.llvm.org/D109490
1 parent 49c519a commit 9149ae0

File tree

8 files changed

+33
-32
lines changed

8 files changed

+33
-32
lines changed

llvm/include/llvm/ADT/STLExtras.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,15 @@ template <typename T> auto drop_begin(T &&RangeOrContainer, size_t N = 1) {
272272
// be applied whenever operator* is invoked on the iterator.
273273

274274
template <typename ItTy, typename FuncTy,
275-
typename FuncReturnTy =
276-
decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
275+
typename ReferenceTy =
276+
decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
277277
class mapped_iterator
278278
: public iterator_adaptor_base<
279-
mapped_iterator<ItTy, FuncTy>, ItTy,
280-
typename std::iterator_traits<ItTy>::iterator_category,
281-
typename std::remove_reference<FuncReturnTy>::type> {
279+
mapped_iterator<ItTy, FuncTy>, ItTy,
280+
typename std::iterator_traits<ItTy>::iterator_category,
281+
std::remove_reference_t<ReferenceTy>,
282+
typename std::iterator_traits<ItTy>::difference_type,
283+
std::remove_reference_t<ReferenceTy> *, ReferenceTy> {
282284
public:
283285
mapped_iterator(ItTy U, FuncTy F)
284286
: mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {}
@@ -287,7 +289,7 @@ class mapped_iterator
287289

288290
const FuncTy &getFunction() const { return F; }
289291

290-
FuncReturnTy operator*() const { return F(*this->I); }
292+
ReferenceTy operator*() const { return F(*this->I); }
291293

292294
private:
293295
FuncTy F;

llvm/include/llvm/ADT/iterator.h

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,22 @@ class iterator_facade_base {
9595
operator ReferenceT() const { return *I; }
9696
};
9797

98+
/// A proxy object for computing a pointer via indirecting a copy of a
99+
/// reference. This is used in APIs which need to produce a pointer but for
100+
/// which the reference might be a temporary. The proxy preserves the
101+
/// reference internally and exposes the pointer via a arrow operator.
102+
class PointerProxy {
103+
friend iterator_facade_base;
104+
105+
ReferenceT R;
106+
107+
template <typename RefT>
108+
PointerProxy(RefT &&R) : R(std::forward<RefT>(R)) {}
109+
110+
public:
111+
PointerT operator->() const { return &R; }
112+
};
113+
98114
public:
99115
DerivedT operator+(DifferenceTypeT n) const {
100116
static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
@@ -172,19 +188,21 @@ class iterator_facade_base {
172188
return !(static_cast<const DerivedT &>(*this) < RHS);
173189
}
174190

175-
PointerT operator->() { return &static_cast<DerivedT *>(this)->operator*(); }
176-
PointerT operator->() const {
177-
return &static_cast<const DerivedT *>(this)->operator*();
191+
PointerProxy operator->() {
192+
return static_cast<DerivedT *>(this)->operator*();
193+
}
194+
PointerProxy operator->() const {
195+
return static_cast<const DerivedT *>(this)->operator*();
178196
}
179197
ReferenceProxy operator[](DifferenceTypeT n) {
180198
static_assert(IsRandomAccess,
181199
"Subscripting is only defined for random access iterators.");
182-
return ReferenceProxy(static_cast<DerivedT *>(this)->operator+(n));
200+
return static_cast<DerivedT *>(this)->operator+(n);
183201
}
184202
ReferenceProxy operator[](DifferenceTypeT n) const {
185203
static_assert(IsRandomAccess,
186204
"Subscripting is only defined for random access iterators.");
187-
return ReferenceProxy(static_cast<const DerivedT *>(this)->operator+(n));
205+
return static_cast<const DerivedT *>(this)->operator+(n);
188206
}
189207
};
190208

mlir/include/mlir/IR/BlockSupport.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ class PredecessorIterator final
5252
static Block *unwrap(BlockOperand &value);
5353

5454
public:
55-
using reference = Block *;
5655

5756
/// Initializes the operand type iterator to the specified operand iterator.
5857
PredecessorIterator(ValueUseIterator<BlockOperand> it)
@@ -151,7 +150,7 @@ class op_filter_iterator
151150
&filter) {}
152151

153152
/// Allow implicit conversion to the underlying iterator.
154-
operator IteratorT() const { return this->wrapped(); }
153+
operator const IteratorT &() const { return this->wrapped(); }
155154
};
156155

157156
/// This class provides iteration over the held operations of a block for a
@@ -163,15 +162,14 @@ class op_iterator
163162
static OpT unwrap(Operation &op) { return cast<OpT>(op); }
164163

165164
public:
166-
using reference = OpT;
167165

168166
/// Initializes the iterator to the specified filter iterator.
169167
op_iterator(op_filter_iterator<OpT, IteratorT> it)
170168
: llvm::mapped_iterator<op_filter_iterator<OpT, IteratorT>,
171169
OpT (*)(Operation &)>(it, &unwrap) {}
172170

173171
/// Allow implicit conversion to the underlying block iterator.
174-
operator IteratorT() const { return this->wrapped(); }
172+
operator const IteratorT &() const { return this->wrapped(); }
175173
};
176174
} // end namespace detail
177175
} // end namespace mlir

mlir/include/mlir/IR/BuiltinAttributes.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,6 @@ class DenseElementsAttr : public Attribute {
299299

300300
/// Initializes the float element iterator to the specified iterator.
301301
FloatElementIterator(const llvm::fltSemantics &smt, IntElementIterator it);
302-
303-
public:
304-
using reference = APFloat;
305302
};
306303

307304
/// Iterator for walking over complex APFloat values.
@@ -314,9 +311,6 @@ class DenseElementsAttr : public Attribute {
314311
/// Initializes the float element iterator to the specified iterator.
315312
ComplexFloatElementIterator(const llvm::fltSemantics &smt,
316313
ComplexIntElementIterator it);
317-
318-
public:
319-
using reference = std::complex<APFloat>;
320314
};
321315

322316
//===--------------------------------------------------------------------===//

mlir/include/mlir/IR/TypeRange.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,6 @@ class ValueTypeIterator final
128128
static Type unwrap(Value value) { return value.getType(); }
129129

130130
public:
131-
using reference = Type;
132-
133131
/// Provide a const dereference method.
134132
Type operator*() const { return unwrap(*this->I); }
135133

mlir/include/mlir/IR/TypeUtilities.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ class OperandElementTypeIterator final
7575
: public llvm::mapped_iterator<Operation::operand_iterator,
7676
Type (*)(Value)> {
7777
public:
78-
using reference = Type;
79-
8078
/// Initializes the result element type iterator to the specified operand
8179
/// iterator.
8280
explicit OperandElementTypeIterator(Operation::operand_iterator it);
@@ -92,8 +90,6 @@ class ResultElementTypeIterator final
9290
: public llvm::mapped_iterator<Operation::result_iterator,
9391
Type (*)(Value)> {
9492
public:
95-
using reference = Type;
96-
9793
/// Initializes the result element type iterator to the specified result
9894
/// iterator.
9995
explicit ResultElementTypeIterator(Operation::result_iterator it);

mlir/include/mlir/IR/UseDefLists.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,6 @@ class ValueUserIterator final
286286
static Operation *unwrap(OperandType &value) { return value.getOwner(); }
287287

288288
public:
289-
using pointer = Operation *;
290-
using reference = Operation *;
291-
292289
/// Initializes the user iterator to the specified use iterator.
293290
ValueUserIterator(UseIteratorT it)
294291
: llvm::mapped_iterator<UseIteratorT, Operation *(*)(OperandType &)>(

mlir/include/mlir/TableGen/Operator.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ class Operator {
8484
struct VariableDecoratorIterator
8585
: public llvm::mapped_iterator<llvm::Init *const *,
8686
VariableDecorator (*)(llvm::Init *)> {
87-
using reference = VariableDecorator;
88-
8987
/// Initializes the iterator to the specified iterator.
9088
VariableDecoratorIterator(llvm::Init *const *it)
9189
: llvm::mapped_iterator<llvm::Init *const *,

0 commit comments

Comments
 (0)