Index: test/FileCheck/repeat-in-regex.txt =================================================================== --- /dev/null +++ test/FileCheck/repeat-in-regex.txt @@ -0,0 +1,13 @@ +// RUN: FileCheck -input-file %s %s + +text to be matchedmatchedmatchedmatchedmatched +// CHECK: {{(matched){5}}} + +r1, is register is register is register is register is register +// CHECK: [[REG:r[0-9]{1,2}]] +// CHECK-SAME: {{(is register ){1,}}} + +r2r13r1 +dag +// CHECK-DAG: {{dag{1}}} +// CHECK-DAG: {{[[REG]]{,2}}} Index: utils/FileCheck/FileCheck.cpp =================================================================== --- utils/FileCheck/FileCheck.cpp +++ utils/FileCheck/FileCheck.cpp @@ -237,14 +237,31 @@ return true; } + size_t NextChar = End + 2; + while (NextChar < PatternStr.size() && PatternStr[NextChar] == '}') { + NextChar++; + } + + End = NextChar - 2; + // Enclose {{}} patterns in parens just like [[]] even though we're not // capturing the result for any purpose. This is required in case the // expression contains an alternation like: CHECK: abc{{x|z}}def. We // want this to turn into: "abc(x|z)def" not "abcx|zdef". RegExStr += '('; ++CurParen; + + StringRef RegexPart = PatternStr.substr(2, End-2); + // Find quantifier for replacing. + size_t NullQuantifier = RegexPart.find("{,"); + if (NullQuantifier != StringRef::npos && (NullQuantifier == 0 || RegexPart[NullQuantifier - 1] != '\\')) { + // Need replacing. + StringRef FirstPart = RegexPart.drop_back(RegexPart.size() - NullQuantifier - 1); + StringRef SecondPart = RegexPart.drop_front(NullQuantifier + 1); + RegexPart = StringRef(FirstPart.str() + "0" + SecondPart.str()); + } - if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM)) + if (AddRegExToRegEx(RegexPart, CurParen, SM)) return true; RegExStr += ')';