Index: include/llvm/ADT/ImmutableList.h =================================================================== --- include/llvm/ADT/ImmutableList.h +++ include/llvm/ADT/ImmutableList.h @@ -94,6 +94,9 @@ bool operator==(const iterator& I) const { return L == I.L; } bool operator!=(const iterator& I) const { return L != I.L; } const value_type& operator*() const { return L->getHead(); } + const typename std::remove_reference::type* operator->() const { + return &L->getHead(); + } ImmutableList getList() const { return L; } }; @@ -127,14 +130,14 @@ bool operator==(const ImmutableList& L) const { return isEqual(L); } /// getHead - Returns the head of the list. - const T& getHead() { + const T& getHead() const { assert(!isEmpty() && "Cannot get the head of an empty list."); return X->getHead(); } /// getTail - Returns the tail of the list, which is another (possibly empty) /// ImmutableList. - ImmutableList getTail() { + ImmutableList getTail() const { return X ? X->getTail() : nullptr; } Index: unittests/ADT/ImmutableListTest.cpp =================================================================== --- unittests/ADT/ImmutableListTest.cpp +++ unittests/ADT/ImmutableListTest.cpp @@ -80,6 +80,31 @@ EXPECT_FALSE(L2.contains(2)); } +struct NoCopyMoveAssignMoveAssign { + NoCopyMoveAssignMoveAssign() = default; + + NoCopyMoveAssignMoveAssign(const NoCopyMoveAssignMoveAssign &) = delete; + NoCopyMoveAssignMoveAssign(const NoCopyMoveAssignMoveAssign &&) = delete; + NoCopyMoveAssignMoveAssign *operator=(const NoCopyMoveAssignMoveAssign &) = delete; + NoCopyMoveAssignMoveAssign *operator=(const NoCopyMoveAssignMoveAssign &&) = delete; + + void doNothing() const {} + + void Profile(FoldingSetNodeID &ID) const { ID.AddPointer(this); } +}; + +// Mostly just a check whether ImmutableList::iterator can be instantiated +// with a reference type as a template argument. +TEST_F(ImmutableListTest, ReferenceStoringTest) { + ImmutableList::Factory f; + + NoCopyMoveAssignMoveAssign N; + ImmutableList L = f.create(N); + for (ImmutableList::iterator It = L.begin(), E = L.end(); It != E; ++It) { + It->doNothing(); + } +} + TEST_F(ImmutableListTest, CreatingIntListTest) { ImmutableList>::Factory f;