Teach FileCheck to handle trailing CHECK-NOT patterns.

A CHECK-NOT pattern without a following CHECK pattern simply checks that the
pattern doesn't match before the end of the input file.

You can even have only CHECK-NOT patterns to check that strings appear nowhere
in the input file.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116592 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2010-10-15 17:47:12 +00:00
parent 6bdc8ae291
commit 824c10ece2
2 changed files with 23 additions and 10 deletions

View File

@ -165,7 +165,7 @@ directive in a file.
=head2 The "CHECK-NOT:" directive
The CHECK-NOT: directive is used to verify that a string doesn't occur
between two matches (or the first match and the beginning of the file). For
between two matches (or before the first match, or after the last match). For
example, to verify that a load is removed by a transformation, a test like this
can be used:

View File

@ -50,6 +50,10 @@ NoCanonicalizeWhiteSpace("strict-whitespace",
class Pattern {
SMLoc PatternLoc;
/// MatchEOF - When set, this pattern only matches the end of file. This is
/// used for trailing CHECK-NOTs.
bool MatchEOF;
/// FixedStr - If non-empty, this pattern is a fixed string match with the
/// specified fixed string.
StringRef FixedStr;
@ -71,7 +75,7 @@ class Pattern {
public:
Pattern() { }
Pattern(bool matchEOF = false) : MatchEOF(matchEOF) { }
bool ParsePattern(StringRef PatternStr, SourceMgr &SM);
@ -271,6 +275,12 @@ bool Pattern::AddRegExToRegEx(StringRef RegexStr, unsigned &CurParen,
/// there is a match, the size of the matched string is returned in MatchLen.
size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
StringMap<StringRef> &VariableTable) const {
// If this is the EOF pattern, match it immediately.
if (MatchEOF) {
MatchLen = 0;
return Buffer.size();
}
// If this is a fixed string pattern, just match it now.
if (!FixedStr.empty()) {
MatchLen = FixedStr.size();
@ -565,18 +575,20 @@ static bool ReadCheckFile(SourceMgr &SM,
std::swap(NotMatches, CheckStrings.back().NotStrings);
}
// Add an EOF pattern for any trailing CHECK-NOTs.
if (!NotMatches.empty()) {
CheckStrings.push_back(CheckString(Pattern(true),
SMLoc::getFromPointer(Buffer.data()),
false));
std::swap(NotMatches, CheckStrings.back().NotStrings);
}
if (CheckStrings.empty()) {
errs() << "error: no check strings found with prefix '" << CheckPrefix
<< ":'\n";
return true;
}
if (!NotMatches.empty()) {
errs() << "error: '" << CheckPrefix
<< "-NOT:' not supported after last check line.\n";
return true;
}
return false;
}
@ -662,10 +674,11 @@ int main(int argc, char **argv) {
// Find StrNo in the file.
size_t MatchLen = 0;
Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen, VariableTable));
size_t MatchPos = CheckStr.Pat.Match(Buffer, MatchLen, VariableTable);
Buffer = Buffer.substr(MatchPos);
// If we didn't find a match, reject the input.
if (Buffer.empty()) {
if (MatchPos == StringRef::npos) {
PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
return 1;
}