diff --git a/llvm/include/llvm/Support/LineIterator.h b/llvm/include/llvm/Support/LineIterator.h --- a/llvm/include/llvm/Support/LineIterator.h +++ b/llvm/include/llvm/Support/LineIterator.h @@ -9,8 +9,10 @@ #ifndef LLVM_SUPPORT_LINEITERATOR_H #define LLVM_SUPPORT_LINEITERATOR_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/MemoryBufferRef.h" #include namespace llvm { @@ -30,7 +32,7 @@ /// Note that this iterator requires the buffer to be nul terminated. class line_iterator : public std::iterator { - const MemoryBuffer *Buffer = nullptr; + Optional Buffer; char CommentMarker = '\0'; bool SkipBlanks = true; @@ -41,6 +43,10 @@ /// Default construct an "end" iterator. line_iterator() = default; + /// Construct a new iterator around an unowned memory buffer. + explicit line_iterator(const MemoryBufferRef &Buffer, bool SkipBlanks = true, + char CommentMarker = '\0'); + /// Construct a new iterator around some memory buffer. explicit line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks = true, char CommentMarker = '\0'); diff --git a/llvm/lib/Support/LineIterator.cpp b/llvm/lib/Support/LineIterator.cpp --- a/llvm/lib/Support/LineIterator.cpp +++ b/llvm/lib/Support/LineIterator.cpp @@ -33,7 +33,11 @@ line_iterator::line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks, char CommentMarker) - : Buffer(Buffer.getBufferSize() ? &Buffer : nullptr), + : line_iterator(Buffer.getMemBufferRef(), SkipBlanks, CommentMarker) {} + +line_iterator::line_iterator(const MemoryBufferRef &Buffer, bool SkipBlanks, + char CommentMarker) + : Buffer(Buffer.getBufferSize() ? Optional(Buffer) : None), CommentMarker(CommentMarker), SkipBlanks(SkipBlanks), LineNumber(1), CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : nullptr, 0) { @@ -78,7 +82,7 @@ if (*Pos == '\0') { // We've hit the end of the buffer, reset ourselves to the end state. - Buffer = nullptr; + Buffer = None; CurrentLine = StringRef(); return; } diff --git a/llvm/unittests/Support/LineIteratorTest.cpp b/llvm/unittests/Support/LineIteratorTest.cpp --- a/llvm/unittests/Support/LineIteratorTest.cpp +++ b/llvm/unittests/Support/LineIteratorTest.cpp @@ -39,6 +39,30 @@ EXPECT_EQ(E, I); } +TEST(LineIteratorTest, Ref) { + std::unique_ptr Buffer = MemoryBuffer::getMemBuffer("line 1\n" + "line 2\n" + "line 3"); + + line_iterator I = line_iterator(Buffer->getMemBufferRef()), E; + + EXPECT_FALSE(I.is_at_eof()); + EXPECT_NE(E, I); + + EXPECT_EQ("line 1", *I); + EXPECT_EQ(1, I.line_number()); + ++I; + EXPECT_EQ("line 2", *I); + EXPECT_EQ(2, I.line_number()); + ++I; + EXPECT_EQ("line 3", *I); + EXPECT_EQ(3, I.line_number()); + ++I; + + EXPECT_TRUE(I.is_at_eof()); + EXPECT_EQ(E, I); +} + TEST(LineIteratorTest, CommentAndBlankSkipping) { std::unique_ptr Buffer( MemoryBuffer::getMemBuffer("line 1\n"