llvm.org GIT mirror llvm / 4db6511
Fix a bug in FileCheck that wouldn't let define variables as follows: ; CHECK: [[VAR:[a-z]]] The problem was that to find the end of the regex var definition, it was simplistically looking for the next ]] and finding the incorrect one. A better approach is to count nesting of brackets (taking escaping into account). This way the brackets that are part of the regex can be discovered and skipped properly, and the ]] ending is detected in the right place. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169109 91177308-0d34-0410-b5e6-96231b3b80d8 Eli Bendersky 6 years ago
3 changed file(s) with 56 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
0 // RUN: FileCheck -input-file %s %s
1
2 op r1
3 op r2, [x r1]
4 ; CHECK: op [[REG:r[0-9]]]
5 ; CHECK: op [[REG2:r[0-9]]], [x [[REG]]]
6
11
22 op1 r1
33 op2 r1, r2
4 ; CHECK: op1 [[REG:r[0-9]+]]
4 ; CHECK: op1 [[REG:r[0-9]]]
55 ; CHECK-NEXT: op2 [[REG]]
66
77 op3 r16, r18, r21
99 ; CHECK: op3 {{r[0-9]+}}, [[REGa:r[0-9]+]], [[REGb:r[0-9]+]]
1010 ; CHECK-NEXT: op4 {{r[0-9]+}}, [[REGa]], [[REGb]]
1111
12
118118 /// \brief Evaluates expression and stores the result to \p Value.
119119 /// \return true on success. false when the expression has invalid syntax.
120120 bool EvaluateExpression(StringRef Expr, std::string &Value) const;
121
122 /// \brief Finds the closing sequence of a regex variable usage or
123 /// definition. Str has to point in the beginning of the definition
124 /// (right after the opening sequence).
125 /// \return offset of the closing sequence within Str, or npos if it was not
126 /// found.
127 size_t FindRegexVarEnd(StringRef Str);
121128 };
122129
123130
186193 // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
187194 // it. This is to catch some common errors.
188195 if (PatternStr.startswith("[[")) {
189 // Verify that it is terminated properly.
190 size_t End = PatternStr.find("]]");
196 // Find the closing bracket pair ending the match. End is going to be an
197 // offset relative to the beginning of the match string.
198 size_t End = FindRegexVarEnd(PatternStr.substr(2));
199
191200 if (End == StringRef::npos) {
192201 SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
193202 SourceMgr::DK_Error,
195204 return true;
196205 }
197206
198 StringRef MatchStr = PatternStr.substr(2, End-2);
199 PatternStr = PatternStr.substr(End+2);
207 StringRef MatchStr = PatternStr.substr(2, End);
208 PatternStr = PatternStr.substr(End+4);
200209
201210 // Get the regex name (e.g. "foo").
202211 size_t NameEnd = MatchStr.find(':');
518527 }
519528 }
520529
530 size_t Pattern::FindRegexVarEnd(StringRef Str) {
531 // Offset keeps track of the current offset within the input Str
532 size_t Offset = 0;
533 // [...] Nesting depth
534 size_t BracketDepth = 0;
535
536 while (!Str.empty()) {
537 if (Str.startswith("]]") && BracketDepth == 0)
538 return Offset;
539 if (Str[0] == '\\') {
540 // Backslash escapes the next char within regexes, so skip them both.
541 Str = Str.substr(2);
542 Offset += 2;
543 } else {
544 switch (Str[0]) {
545 default:
546 break;
547 case '[':
548 BracketDepth++;
549 break;
550 case ']':
551 assert(BracketDepth > 0 && "Invalid regex");
552 BracketDepth--;
553 break;
554 }
555 Str = Str.substr(1);
556 Offset++;
557 }
558 }
559
560 return StringRef::npos;
561 }
562
563
521564 //===----------------------------------------------------------------------===//
522565 // Check Strings.
523566 //===----------------------------------------------------------------------===//