diff --git a/llvm/include/llvm/Support/Regex.h b/llvm/include/llvm/Support/Regex.h --- a/llvm/include/llvm/Support/Regex.h +++ b/llvm/include/llvm/Support/Regex.h @@ -95,7 +95,7 @@ /// backreferences, trailing backslashes) will be recorded as a non-empty /// string. If there is no error, it will be an empty string. std::string sub(StringRef Repl, StringRef String, - std::string *Error = nullptr) const; + std::string *Error = nullptr, bool Global = false) const; /// If this function returns true, ^Str$ is an extended regular /// expression that matches Str and only Str. diff --git a/llvm/lib/Support/Regex.cpp b/llvm/lib/Support/Regex.cpp --- a/llvm/lib/Support/Regex.cpp +++ b/llvm/lib/Support/Regex.cpp @@ -131,7 +131,7 @@ } std::string Regex::sub(StringRef Repl, StringRef String, - std::string *Error) const { + std::string *Error, bool Global) const { SmallVector Matches; // Return the input if there was no match. @@ -141,6 +141,7 @@ // Otherwise splice in the replacement string, starting with the prefix before // the match. std::string Res(String.begin(), Matches[0].begin()); + StringRef OrigRepl = Repl; // Then the replacement string, honoring possible substitutions. while (!Repl.empty()) { @@ -197,8 +198,9 @@ } } + StringRef Suffix(Matches[0].end(), String.end() - Matches[0].end()); // And finally the suffix. - Res += StringRef(Matches[0].end(), String.end() - Matches[0].end()); + Res += (Global ? sub(OrigRepl, Suffix, Error, Global) : Suffix); return Res; } diff --git a/llvm/unittests/Support/RegexTest.cpp b/llvm/unittests/Support/RegexTest.cpp --- a/llvm/unittests/Support/RegexTest.cpp +++ b/llvm/unittests/Support/RegexTest.cpp @@ -127,6 +127,9 @@ EXPECT_EQ("aber", Regex("a[0-9]+b").sub("a\\100b", "a1234ber", &Error)); EXPECT_EQ(Error, "invalid backreference string '100'"); + + // Global substitution + EXPECT_EQ("a%%b%%c%%d", Regex("%").sub("%%", "a%b%c%d", nullptr, true)); } TEST_F(RegexTest, IsLiteralERE) {