Index: llvm/include/llvm/ADT/StringExtras.h =================================================================== --- llvm/include/llvm/ADT/StringExtras.h +++ llvm/include/llvm/ADT/StringExtras.h @@ -505,6 +505,7 @@ class SplittingIterator : public iterator_facade_base { + char SeparatorStorage; StringRef Current; StringRef Next; StringRef Separator; @@ -515,8 +516,15 @@ ++*this; } + SplittingIterator(StringRef Str, char Separator) + : SeparatorStorage(Separator), Next(Str), + Separator(&SeparatorStorage, 1) { + ++*this; + } + bool operator==(const SplittingIterator &R) const { - return Current == R.Current && Next == R.Next && Separator == R.Separator; + assert(Separator == R.Separator); + return Current.data() == R.Current.data(); } const StringRef &operator*() const { return Current; } @@ -524,9 +532,7 @@ StringRef &operator*() { return Current; } SplittingIterator &operator++() { - std::pair Res = Next.split(Separator); - Current = Res.first; - Next = Res.second; + std::tie(Current, Next) = Next.split(Separator); return *this; } }; @@ -536,26 +542,21 @@ /// over separated strings like so: /// /// \code -/// for (StringRef x : llvm::Split("foo,bar,baz", ',')) +/// for (StringRef x : llvm::split("foo,bar,baz", ",")) /// ...; /// \end /// /// Note that the passed string must remain valid throuhgout lifetime /// of the iterators. -class Split { - StringRef Str; - std::string SeparatorStr; - -public: - Split(StringRef NewStr, StringRef Separator) - : Str(NewStr), SeparatorStr(Separator) {} - Split(StringRef NewStr, char Separator) - : Str(NewStr), SeparatorStr(1, Separator) {} - - SplittingIterator begin() { return SplittingIterator(Str, SeparatorStr); } +inline iterator_range split(StringRef Str, StringRef Separator) { + return {SplittingIterator(Str, Separator), + SplittingIterator(StringRef(), Separator)}; +} - SplittingIterator end() { return SplittingIterator("", SeparatorStr); } -}; +inline iterator_range split(StringRef Str, char Separator) { + return {SplittingIterator(Str, Separator), + SplittingIterator(StringRef(), Separator)}; +} } // end namespace llvm Index: llvm/lib/IR/DataLayout.cpp =================================================================== --- llvm/lib/IR/DataLayout.cpp +++ llvm/lib/IR/DataLayout.cpp @@ -260,12 +260,12 @@ while (!Desc.empty()) { // Split at '-'. std::pair Split; - if (Error Err = split(Desc, '-', Split)) + if (Error Err = ::split(Desc, '-', Split)) return Err; Desc = Split.second; // Split at ':'. - if (Error Err = split(Split.first, ':', Split)) + if (Error Err = ::split(Split.first, ':', Split)) return Err; // Aliases used below. @@ -274,7 +274,7 @@ if (Tok == "ni") { do { - if (Error Err = split(Rest, ':', Split)) + if (Error Err = ::split(Rest, ':', Split)) return Err; Rest = Split.second; unsigned AS; @@ -315,7 +315,7 @@ if (Rest.empty()) return reportError( "Missing size specification for pointer in datalayout string"); - if (Error Err = split(Rest, ':', Split)) + if (Error Err = ::split(Rest, ':', Split)) return Err; unsigned PointerMemSize; if (Error Err = getIntInBytes(Tok, PointerMemSize)) @@ -327,7 +327,7 @@ if (Rest.empty()) return reportError( "Missing alignment specification for pointer in datalayout string"); - if (Error Err = split(Rest, ':', Split)) + if (Error Err = ::split(Rest, ':', Split)) return Err; unsigned PointerABIAlign; if (Error Err = getIntInBytes(Tok, PointerABIAlign)) @@ -342,7 +342,7 @@ // Preferred alignment. unsigned PointerPrefAlign = PointerABIAlign; if (!Rest.empty()) { - if (Error Err = split(Rest, ':', Split)) + if (Error Err = ::split(Rest, ':', Split)) return Err; if (Error Err = getIntInBytes(Tok, PointerPrefAlign)) return Err; @@ -352,7 +352,7 @@ // Now read the index. It is the second optional parameter here. if (!Rest.empty()) { - if (Error Err = split(Rest, ':', Split)) + if (Error Err = ::split(Rest, ':', Split)) return Err; if (Error Err = getIntInBytes(Tok, IndexSize)) return Err; @@ -393,7 +393,7 @@ if (Rest.empty()) return reportError( "Missing alignment specification in datalayout string"); - if (Error Err = split(Rest, ':', Split)) + if (Error Err = ::split(Rest, ':', Split)) return Err; unsigned ABIAlign; if (Error Err = getIntInBytes(Tok, ABIAlign)) @@ -410,7 +410,7 @@ // Preferred alignment. unsigned PrefAlign = ABIAlign; if (!Rest.empty()) { - if (Error Err = split(Rest, ':', Split)) + if (Error Err = ::split(Rest, ':', Split)) return Err; if (Error Err = getIntInBytes(Tok, PrefAlign)) return Err; @@ -439,7 +439,7 @@ LegalIntWidths.push_back(Width); if (Rest.empty()) break; - if (Error Err = split(Rest, ':', Split)) + if (Error Err = ::split(Rest, ':', Split)) return Err; } break; Index: llvm/unittests/ADT/StringExtrasTest.cpp =================================================================== --- llvm/unittests/ADT/StringExtrasTest.cpp +++ llvm/unittests/ADT/StringExtrasTest.cpp @@ -276,7 +276,7 @@ } TEST(StringExtrasTest, splitStringRef) { - auto Spl = Split("foo<=>bar<=><=>baz", "<=>"); + auto Spl = split("foo<=>bar<=><=>baz", "<=>"); auto It = Spl.begin(); auto End = Spl.end(); @@ -291,8 +291,8 @@ ASSERT_EQ(++It, End); } -TEST(StringExtrasTest, splItChar) { - auto Spl = Split("foo,bar,,baz", ','); +TEST(StringExtrasTest, splitChar) { + auto Spl = split("foo,bar,,baz", ','); auto It = Spl.begin(); auto End = Spl.end();