Index: llvm/trunk/include/llvm/ADT/ImmutableList.h =================================================================== --- llvm/trunk/include/llvm/ADT/ImmutableList.h +++ llvm/trunk/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: llvm/trunk/unittests/ADT/ImmutableListTest.cpp =================================================================== --- llvm/trunk/unittests/ADT/ImmutableListTest.cpp +++ llvm/trunk/unittests/ADT/ImmutableListTest.cpp @@ -80,6 +80,36 @@ EXPECT_FALSE(L2.contains(2)); } +// We'll store references to objects of this type. +struct Unmodifiable { + Unmodifiable() = default; + + // We'll delete all of these special member functions to make sure no copy or + // move happens during insertation. + Unmodifiable(const Unmodifiable &) = delete; + Unmodifiable(const Unmodifiable &&) = delete; + Unmodifiable &operator=(const Unmodifiable &) = delete; + Unmodifiable &operator=(const Unmodifiable &&) = 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; + + Unmodifiable 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;