Add FileCheck -implicit-check-not option to allow stricter tests without adding too many CHECK-NOTs manually.

Summary:
Add FileCheck -implicit-check-not option which allows specifying a
pattern that should only occur in the input when explicitly matched by a
positive check. This feature allows checking tool diagnostics in a way
clang -verify does it for compiler diagnostics.

The option has been tested on a number of clang-tidy checks, I'll post a link to
the clang-tidy patch to this thread.

Once there's an agreement on the general direction, I can add tests and
documentation.

Reviewers: djasper, bkramer

Reviewed By: bkramer

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D4462

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212810 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alexander Kornienko
2014-07-11 12:39:32 +00:00
parent 52c50f5ec5
commit c58b079d23
3 changed files with 83 additions and 1 deletions

View File

@ -50,6 +50,13 @@ static cl::opt<bool>
NoCanonicalizeWhiteSpace("strict-whitespace",
cl::desc("Do not treat all horizontal whitespace as equivalent"));
static cl::list<std::string> ImplicitCheckNot(
"implicit-check-not",
cl::desc("Add an implicit negative check with this pattern to every\n"
"positive check. This can be used to ensure that no instances of\n"
"this pattern occur which are not matched by a positive pattern"),
cl::value_desc("pattern"));
typedef cl::list<std::string>::const_iterator prefix_iterator;
//===----------------------------------------------------------------------===//
@ -837,7 +844,26 @@ static bool ReadCheckFile(SourceMgr &SM,
// Find all instances of CheckPrefix followed by : in the file.
StringRef Buffer = F->getBuffer();
std::vector<Pattern> DagNotMatches;
std::vector<Pattern> ImplicitNegativeChecks;
for (const auto &PatternString : ImplicitCheckNot) {
// Create a buffer with fake command line content in order to display the
// command line option responsible for the specific implicit CHECK-NOT.
std::string Prefix = std::string("-") + ImplicitCheckNot.ArgStr + "='";
std::string Suffix = "'";
MemoryBuffer *CmdLine = MemoryBuffer::getMemBufferCopy(
Prefix + PatternString + Suffix, "command line");
StringRef PatternInBuffer =
CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
SM.AddNewSourceBuffer(CmdLine, SMLoc());
ImplicitNegativeChecks.push_back(Pattern(Check::CheckNot));
ImplicitNegativeChecks.back().ParsePattern(PatternInBuffer,
"IMPLICIT-CHECK", SM, 0);
}
std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
// LineNumber keeps track of the line on which CheckPrefix instances are
// found.
@ -910,6 +936,7 @@ static bool ReadCheckFile(SourceMgr &SM,
PatternLoc,
CheckTy));
std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
DagNotMatches = ImplicitNegativeChecks;
}
// Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first