aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/FileCheck.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/FileCheck.cpp')
-rw-r--r--llvm/lib/Support/FileCheck.cpp84
1 files changed, 61 insertions, 23 deletions
diff --git a/llvm/lib/Support/FileCheck.cpp b/llvm/lib/Support/FileCheck.cpp
index bad8ea2..ce60b0b 100644
--- a/llvm/lib/Support/FileCheck.cpp
+++ b/llvm/lib/Support/FileCheck.cpp
@@ -412,6 +412,21 @@ void FileCheckPattern::PrintVariableUses(const SourceMgr &SM, StringRef Buffer,
}
}
+static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy,
+ const SourceMgr &SM, SMLoc Loc,
+ Check::FileCheckType CheckTy,
+ StringRef Buffer, size_t Pos, size_t Len,
+ std::vector<FileCheckDiag> *Diags) {
+ SMLoc Start = SMLoc::getFromPointer(Buffer.data() + Pos);
+ SMLoc End = SMLoc::getFromPointer(Buffer.data() + Pos + Len);
+ SMRange Range(Start, End);
+ // TODO: The second condition will disappear when we extend this to handle
+ // more match types.
+ if (Diags && MatchTy != FileCheckDiag::MatchTypeCount)
+ Diags->emplace_back(SM, CheckTy, Loc, MatchTy, Range);
+ return Range;
+}
+
void FileCheckPattern::PrintFuzzyMatch(
const SourceMgr &SM, StringRef Buffer,
const StringMap<StringRef> &VariableTable) const {
@@ -531,6 +546,22 @@ llvm::FileCheck::CanonicalizeFile(MemoryBuffer &MB,
return StringRef(OutputBuffer.data(), OutputBuffer.size() - 1);
}
+FileCheckDiag::FileCheckDiag(const SourceMgr &SM,
+ const Check::FileCheckType &CheckTy,
+ SMLoc CheckLoc, MatchType MatchTy,
+ SMRange InputRange)
+ : CheckTy(CheckTy), MatchTy(MatchTy) {
+ auto Start = SM.getLineAndColumn(InputRange.Start);
+ auto End = SM.getLineAndColumn(InputRange.End);
+ InputStartLine = Start.first;
+ InputStartCol = Start.second;
+ InputEndLine = End.first;
+ InputEndCol = End.second;
+ Start = SM.getLineAndColumn(CheckLoc);
+ CheckLine = Start.first;
+ CheckCol = Start.second;
+}
+
static bool IsPartOfWord(char c) {
return (isalnum(c) || c == '-' || c == '_');
}
@@ -897,7 +928,8 @@ static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
StringRef Prefix, SMLoc Loc,
const FileCheckPattern &Pat, int MatchedCount,
StringRef Buffer, StringMap<StringRef> &VariableTable,
- bool VerboseVerbose) {
+ bool VerboseVerbose,
+ std::vector<FileCheckDiag> *Diags) {
if (!ExpectedMatch && !VerboseVerbose)
return;
@@ -915,9 +947,11 @@ static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
// Print the "scanning from here" line. If the current position is at the
// end of a line, advance to the start of the next line.
Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
-
- SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
- "scanning from here");
+ SMRange SearchRange = ProcessMatchResult(
+ ExpectedMatch ? FileCheckDiag::MatchNoneButExpected
+ : FileCheckDiag::MatchTypeCount,
+ SM, Loc, Pat.getCheckTy(), Buffer, 0, Buffer.size(), Diags);
+ SM.PrintMessage(SearchRange.Start, SourceMgr::DK_Note, "scanning from here");
// Allow the pattern to print additional information if desired.
Pat.PrintVariableUses(SM, Buffer, VariableTable);
@@ -928,9 +962,10 @@ static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
const FileCheckString &CheckStr, int MatchedCount,
StringRef Buffer, StringMap<StringRef> &VariableTable,
- bool VerboseVerbose) {
+ bool VerboseVerbose,
+ std::vector<FileCheckDiag> *Diags) {
PrintNoMatch(ExpectedMatch, SM, CheckStr.Prefix, CheckStr.Loc, CheckStr.Pat,
- MatchedCount, Buffer, VariableTable, VerboseVerbose);
+ MatchedCount, Buffer, VariableTable, VerboseVerbose, Diags);
}
/// Count the number of newlines in the specified range.
@@ -958,9 +993,10 @@ static unsigned CountNumNewlinesBetween(StringRef Range,
/// Match check string and its "not strings" and/or "dag strings".
size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
- bool IsLabelScanMode, size_t &MatchLen,
- StringMap<StringRef> &VariableTable,
- FileCheckRequest &Req) const {
+ bool IsLabelScanMode, size_t &MatchLen,
+ StringMap<StringRef> &VariableTable,
+ FileCheckRequest &Req,
+ std::vector<FileCheckDiag> *Diags) const {
size_t LastPos = 0;
std::vector<const FileCheckPattern *> NotStrings;
@@ -970,7 +1006,7 @@ size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
// over the block again (including the last CHECK-LABEL) in normal mode.
if (!IsLabelScanMode) {
// Match "dag strings" (with mixed "not strings" if any).
- LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable, Req);
+ LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable, Req, Diags);
if (LastPos == StringRef::npos)
return StringRef::npos;
}
@@ -992,7 +1028,7 @@ size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
// report
if (MatchPos == StringRef::npos) {
PrintNoMatch(true, SM, *this, i, MatchBuffer, VariableTable,
- Req.VerboseVerbose);
+ Req.VerboseVerbose, Diags);
return StringRef::npos;
}
PrintMatch(true, SM, *this, i, MatchBuffer, VariableTable, MatchPos,
@@ -1116,7 +1152,7 @@ bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
if (Pos == StringRef::npos) {
PrintNoMatch(false, SM, Prefix, Pat->getLoc(), *Pat, 1, Buffer,
- VariableTable, Req.VerboseVerbose);
+ VariableTable, Req.VerboseVerbose, nullptr);
continue;
}
@@ -1130,10 +1166,12 @@ bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
}
/// Match "dag strings" and their mixed "not strings".
-size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
- std::vector<const FileCheckPattern *> &NotStrings,
- StringMap<StringRef> &VariableTable,
- const FileCheckRequest &Req) const {
+size_t
+FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
+ std::vector<const FileCheckPattern *> &NotStrings,
+ StringMap<StringRef> &VariableTable,
+ const FileCheckRequest &Req,
+ std::vector<FileCheckDiag> *Diags) const {
if (DagNotStrings.empty())
return 0;
@@ -1177,7 +1215,7 @@ size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
// that group of CHECK-DAGs fails immediately.
if (MatchPosBuf == StringRef::npos) {
PrintNoMatch(true, SM, Prefix, Pat.getLoc(), Pat, 1, MatchBuffer,
- VariableTable, Req.VerboseVerbose);
+ VariableTable, Req.VerboseVerbose, Diags);
return StringRef::npos;
}
// Re-calc it as the offset relative to the start of the original string.
@@ -1318,7 +1356,8 @@ static void ClearLocalVars(StringMap<StringRef> &VariableTable) {
///
/// Returns false if the input fails to satisfy the checks.
bool llvm::FileCheck::CheckInput(SourceMgr &SM, StringRef Buffer,
- ArrayRef<FileCheckString> CheckStrings) {
+ ArrayRef<FileCheckString> CheckStrings,
+ std::vector<FileCheckDiag> *Diags) {
bool ChecksFailed = false;
/// VariableTable - This holds all the current filecheck variables.
@@ -1341,9 +1380,8 @@ bool llvm::FileCheck::CheckInput(SourceMgr &SM, StringRef Buffer,
// Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
size_t MatchLabelLen = 0;
- size_t MatchLabelPos =
- CheckLabelStr.Check(SM, Buffer, true, MatchLabelLen, VariableTable,
- Req);
+ size_t MatchLabelPos = CheckLabelStr.Check(
+ SM, Buffer, true, MatchLabelLen, VariableTable, Req, Diags);
if (MatchLabelPos == StringRef::npos)
// Immediately bail of CHECK-LABEL fails, nothing else we can do.
return false;
@@ -1362,8 +1400,8 @@ bool llvm::FileCheck::CheckInput(SourceMgr &SM, StringRef Buffer,
// Check each string within the scanned region, including a second check
// of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
size_t MatchLen = 0;
- size_t MatchPos =
- CheckStr.Check(SM, CheckRegion, false, MatchLen, VariableTable, Req);
+ size_t MatchPos = CheckStr.Check(SM, CheckRegion, false, MatchLen,
+ VariableTable, Req, Diags);
if (MatchPos == StringRef::npos) {
ChecksFailed = true;