Skip to content

Commit 66e06cc

Browse files
committed
[llvm] [ADT] Update llvm::Split() per Pavel Labath's suggestions
Optimize the iterator comparison logic to compare Current.data() pointers. Use std::tie for assignments from std::pair. Replace the custom class with a function returning iterator_range. Differential Revision: https://reviews.llvm.org/D110535
1 parent d465315 commit 66e06cc

File tree

7 files changed

+74
-38
lines changed

7 files changed

+74
-38
lines changed

lldb/source/Host/common/File.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) {
772772
llvm::Expected<SerialPort::Options>
773773
SerialPort::OptionsFromURL(llvm::StringRef urlqs) {
774774
SerialPort::Options serial_options;
775-
for (llvm::StringRef x : llvm::Split(urlqs, '&')) {
775+
for (llvm::StringRef x : llvm::split(urlqs, '&')) {
776776
if (x.consume_front("baud=")) {
777777
unsigned int baud_rate;
778778
if (!llvm::to_integer(x, baud_rate, 10))

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
355355
// configuration of the transport before attaching/launching the process.
356356
m_qSupported_response = response.GetStringRef().str();
357357

358-
for (llvm::StringRef x : llvm::Split(response.GetStringRef(), ';')) {
358+
for (llvm::StringRef x : llvm::split(response.GetStringRef(), ';')) {
359359
if (x == "qXfer:auxv:read+")
360360
m_supports_qXfer_auxv_read = eLazyBoolYes;
361361
else if (x == "qXfer:libraries-svr4:read+")
@@ -1609,7 +1609,7 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
16091609
error.SetErrorString(error_string.c_str());
16101610
} else if (name.equals("dirty-pages")) {
16111611
std::vector<addr_t> dirty_page_list;
1612-
for (llvm::StringRef x : llvm::Split(value, ',')) {
1612+
for (llvm::StringRef x : llvm::split(value, ',')) {
16131613
addr_t page;
16141614
x.consume_front("0x");
16151615
if (llvm::to_integer(x, page, 16))

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3637,7 +3637,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qSaveCore(
36373637
StringRef packet_str{packet.GetStringRef()};
36383638
assert(packet_str.startswith("qSaveCore"));
36393639
if (packet_str.consume_front("qSaveCore;")) {
3640-
for (auto x : llvm::Split(packet_str, ';')) {
3640+
for (auto x : llvm::split(packet_str, ';')) {
36413641
if (x.consume_front("path-hint:"))
36423642
StringExtractor(x).GetHexByteString(path_hint);
36433643
else

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ static size_t SplitCommaSeparatedRegisterNumberString(
375375
const llvm::StringRef &comma_separated_register_numbers,
376376
std::vector<uint32_t> &regnums, int base) {
377377
regnums.clear();
378-
for (llvm::StringRef x : llvm::Split(comma_separated_register_numbers, ',')) {
378+
for (llvm::StringRef x : llvm::split(comma_separated_register_numbers, ',')) {
379379
uint32_t reg;
380380
if (llvm::to_integer(x, reg, base))
381381
regnums.push_back(reg);
@@ -1405,7 +1405,7 @@ size_t ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(
14051405
size_t ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(
14061406
llvm::StringRef value) {
14071407
m_thread_pcs.clear();
1408-
for (llvm::StringRef x : llvm::Split(value, ',')) {
1408+
for (llvm::StringRef x : llvm::split(value, ',')) {
14091409
lldb::addr_t pc;
14101410
if (llvm::to_integer(x, pc, 16))
14111411
m_thread_pcs.push_back(pc);
@@ -4973,7 +4973,7 @@ llvm::Expected<bool> ProcessGDBRemote::SaveCore(llvm::StringRef outfile) {
49734973
std::string path;
49744974

49754975
// process the response
4976-
for (auto x : llvm::Split(response.GetStringRef(), ';')) {
4976+
for (auto x : llvm::split(response.GetStringRef(), ';')) {
49774977
if (x.consume_front("core-path:"))
49784978
StringExtractor(x).GetHexByteString(path);
49794979
}

llvm/include/llvm/ADT/StringExtras.h

+39-18
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ class ListSeparator {
505505
class SplittingIterator
506506
: public iterator_facade_base<SplittingIterator, std::forward_iterator_tag,
507507
StringRef> {
508+
char SeparatorStorage;
508509
StringRef Current;
509510
StringRef Next;
510511
StringRef Separator;
@@ -515,18 +516,43 @@ class SplittingIterator
515516
++*this;
516517
}
517518

519+
SplittingIterator(StringRef Str, char Separator)
520+
: SeparatorStorage(Separator), Next(Str),
521+
Separator(&SeparatorStorage, 1) {
522+
++*this;
523+
}
524+
525+
SplittingIterator(const SplittingIterator &R)
526+
: SeparatorStorage(R.SeparatorStorage), Current(R.Current), Next(R.Next),
527+
Separator(R.Separator) {
528+
if (R.Separator.data() == &R.SeparatorStorage)
529+
Separator = StringRef(&SeparatorStorage, 1);
530+
}
531+
532+
SplittingIterator &operator=(const SplittingIterator &R) {
533+
if (this == &R)
534+
return *this;
535+
536+
SeparatorStorage = R.SeparatorStorage;
537+
Current = R.Current;
538+
Next = R.Next;
539+
Separator = R.Separator;
540+
if (R.Separator.data() == &R.SeparatorStorage)
541+
Separator = StringRef(&SeparatorStorage, 1);
542+
return *this;
543+
}
544+
518545
bool operator==(const SplittingIterator &R) const {
519-
return Current == R.Current && Next == R.Next && Separator == R.Separator;
546+
assert(Separator == R.Separator);
547+
return Current.data() == R.Current.data();
520548
}
521549

522550
const StringRef &operator*() const { return Current; }
523551

524552
StringRef &operator*() { return Current; }
525553

526554
SplittingIterator &operator++() {
527-
std::pair<StringRef, StringRef> Res = Next.split(Separator);
528-
Current = Res.first;
529-
Next = Res.second;
555+
std::tie(Current, Next) = Next.split(Separator);
530556
return *this;
531557
}
532558
};
@@ -536,26 +562,21 @@ class SplittingIterator
536562
/// over separated strings like so:
537563
///
538564
/// \code
539-
/// for (StringRef x : llvm::Split("foo,bar,baz", ','))
565+
/// for (StringRef x : llvm::split("foo,bar,baz", ","))
540566
/// ...;
541567
/// \end
542568
///
543569
/// Note that the passed string must remain valid throuhgout lifetime
544570
/// of the iterators.
545-
class Split {
546-
StringRef Str;
547-
std::string SeparatorStr;
548-
549-
public:
550-
Split(StringRef NewStr, StringRef Separator)
551-
: Str(NewStr), SeparatorStr(Separator) {}
552-
Split(StringRef NewStr, char Separator)
553-
: Str(NewStr), SeparatorStr(1, Separator) {}
554-
555-
SplittingIterator begin() { return SplittingIterator(Str, SeparatorStr); }
571+
inline iterator_range<SplittingIterator> split(StringRef Str, StringRef Separator) {
572+
return {SplittingIterator(Str, Separator),
573+
SplittingIterator(StringRef(), Separator)};
574+
}
556575

557-
SplittingIterator end() { return SplittingIterator("", SeparatorStr); }
558-
};
576+
inline iterator_range<SplittingIterator> split(StringRef Str, char Separator) {
577+
return {SplittingIterator(Str, Separator),
578+
SplittingIterator(StringRef(), Separator)};
579+
}
559580

560581
} // end namespace llvm
561582

llvm/lib/IR/DataLayout.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,12 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
260260
while (!Desc.empty()) {
261261
// Split at '-'.
262262
std::pair<StringRef, StringRef> Split;
263-
if (Error Err = split(Desc, '-', Split))
263+
if (Error Err = ::split(Desc, '-', Split))
264264
return Err;
265265
Desc = Split.second;
266266

267267
// Split at ':'.
268-
if (Error Err = split(Split.first, ':', Split))
268+
if (Error Err = ::split(Split.first, ':', Split))
269269
return Err;
270270

271271
// Aliases used below.
@@ -274,7 +274,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
274274

275275
if (Tok == "ni") {
276276
do {
277-
if (Error Err = split(Rest, ':', Split))
277+
if (Error Err = ::split(Rest, ':', Split))
278278
return Err;
279279
Rest = Split.second;
280280
unsigned AS;
@@ -315,7 +315,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
315315
if (Rest.empty())
316316
return reportError(
317317
"Missing size specification for pointer in datalayout string");
318-
if (Error Err = split(Rest, ':', Split))
318+
if (Error Err = ::split(Rest, ':', Split))
319319
return Err;
320320
unsigned PointerMemSize;
321321
if (Error Err = getIntInBytes(Tok, PointerMemSize))
@@ -327,7 +327,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
327327
if (Rest.empty())
328328
return reportError(
329329
"Missing alignment specification for pointer in datalayout string");
330-
if (Error Err = split(Rest, ':', Split))
330+
if (Error Err = ::split(Rest, ':', Split))
331331
return Err;
332332
unsigned PointerABIAlign;
333333
if (Error Err = getIntInBytes(Tok, PointerABIAlign))
@@ -342,7 +342,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
342342
// Preferred alignment.
343343
unsigned PointerPrefAlign = PointerABIAlign;
344344
if (!Rest.empty()) {
345-
if (Error Err = split(Rest, ':', Split))
345+
if (Error Err = ::split(Rest, ':', Split))
346346
return Err;
347347
if (Error Err = getIntInBytes(Tok, PointerPrefAlign))
348348
return Err;
@@ -352,7 +352,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
352352

353353
// Now read the index. It is the second optional parameter here.
354354
if (!Rest.empty()) {
355-
if (Error Err = split(Rest, ':', Split))
355+
if (Error Err = ::split(Rest, ':', Split))
356356
return Err;
357357
if (Error Err = getIntInBytes(Tok, IndexSize))
358358
return Err;
@@ -393,7 +393,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
393393
if (Rest.empty())
394394
return reportError(
395395
"Missing alignment specification in datalayout string");
396-
if (Error Err = split(Rest, ':', Split))
396+
if (Error Err = ::split(Rest, ':', Split))
397397
return Err;
398398
unsigned ABIAlign;
399399
if (Error Err = getIntInBytes(Tok, ABIAlign))
@@ -410,7 +410,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
410410
// Preferred alignment.
411411
unsigned PrefAlign = ABIAlign;
412412
if (!Rest.empty()) {
413-
if (Error Err = split(Rest, ':', Split))
413+
if (Error Err = ::split(Rest, ':', Split))
414414
return Err;
415415
if (Error Err = getIntInBytes(Tok, PrefAlign))
416416
return Err;
@@ -439,7 +439,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
439439
LegalIntWidths.push_back(Width);
440440
if (Rest.empty())
441441
break;
442-
if (Error Err = split(Rest, ':', Split))
442+
if (Error Err = ::split(Rest, ':', Split))
443443
return Err;
444444
}
445445
break;

llvm/unittests/ADT/StringExtrasTest.cpp

+18-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "llvm/ADT/StringExtras.h"
1010
#include "llvm/Support/raw_ostream.h"
11+
#include "gmock/gmock.h"
1112
#include "gtest/gtest.h"
1213

1314
using namespace llvm;
@@ -276,7 +277,7 @@ TEST(StringExtrasTest, toStringAPSInt) {
276277
}
277278

278279
TEST(StringExtrasTest, splitStringRef) {
279-
auto Spl = Split("foo<=>bar<=><=>baz", "<=>");
280+
auto Spl = split("foo<=>bar<=><=>baz", "<=>");
280281
auto It = Spl.begin();
281282
auto End = Spl.end();
282283

@@ -291,8 +292,15 @@ TEST(StringExtrasTest, splitStringRef) {
291292
ASSERT_EQ(++It, End);
292293
}
293294

294-
TEST(StringExtrasTest, splItChar) {
295-
auto Spl = Split("foo,bar,,baz", ',');
295+
TEST(StringExtrasTest, splitStringRefForLoop) {
296+
llvm::SmallVector<StringRef, 4> Result;
297+
for (StringRef x : split("foo<=>bar<=><=>baz", "<=>"))
298+
Result.push_back(x);
299+
EXPECT_THAT(Result, testing::ElementsAre("foo", "bar", "", "baz"));
300+
}
301+
302+
TEST(StringExtrasTest, splitChar) {
303+
auto Spl = split("foo,bar,,baz", ',');
296304
auto It = Spl.begin();
297305
auto End = Spl.end();
298306

@@ -306,3 +314,10 @@ TEST(StringExtrasTest, splItChar) {
306314
EXPECT_EQ(*It, StringRef("baz"));
307315
ASSERT_EQ(++It, End);
308316
}
317+
318+
TEST(StringExtrasTest, splitCharForLoop) {
319+
llvm::SmallVector<StringRef, 4> Result;
320+
for (StringRef x : split("foo,bar,,baz", ','))
321+
Result.push_back(x);
322+
EXPECT_THAT(Result, testing::ElementsAre("foo", "bar", "", "baz"));
323+
}

0 commit comments

Comments
 (0)