Index: include/llvm/Support/FileCheck.h =================================================================== --- include/llvm/Support/FileCheck.h +++ include/llvm/Support/FileCheck.h @@ -35,6 +35,7 @@ bool AllowDeprecatedDagOverlap = false; bool Verbose = false; bool VerboseVerbose = false; + bool Warn = false; }; @@ -218,6 +219,8 @@ /// Returns false if the input fails to satisfy the checks. bool CheckInput(SourceMgr &SM, StringRef Buffer, ArrayRef CheckStrings); + + void PrintWarning(SourceMgr &SM, SMLoc Loc, const Twine &Msg); }; } // namespace llvm #endif Index: lib/Support/FileCheck.cpp =================================================================== --- lib/Support/FileCheck.cpp +++ lib/Support/FileCheck.cpp @@ -22,9 +22,17 @@ #include #include #include +#include using namespace llvm; +void FileCheck::PrintWarning(SourceMgr &SM, SMLoc Loc, const Twine &Msg) { + if (!Req.Warn) + return; + + SM.PrintMessage(Loc, SourceMgr::DK_Warning, Msg); +} + /// Parses the given string into the Pattern. /// /// \p Prefix provides which prefix is being matched, \p SM provides the @@ -736,6 +744,7 @@ // LineNumber keeps track of the line on which CheckPrefix instances are // found. unsigned LineNumber = 1; + std::set FoundPrefixes; while (1) { Check::FileCheckType CheckTy; @@ -777,8 +786,10 @@ return true; } - // Okay, we found the prefix, yay. Remember the rest of the line, but ignore - // leading whitespace. + // Okay, we found the prefix, yay. + FoundPrefixes.insert(UsedPrefix.str()); + + // Remember the rest of the line, but ignore leading whitespace. if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines)) Buffer = Buffer.substr(Buffer.find_first_not_of(" \t")); @@ -854,6 +865,11 @@ return true; } + for (auto P : Req.CheckPrefixes) + if (FoundPrefixes.find(P) == FoundPrefixes.end()) + PrintWarning(SM, SMLoc(), "Didn't find prefix " + P + ", it isn't " + "checked!"); + return false; } Index: test/FileCheck/check-warnings.txt =================================================================== --- /dev/null +++ test/FileCheck/check-warnings.txt @@ -0,0 +1,37 @@ + +foo +; FOO: foo + +// Option -warn enabled in these tests, and we want only 1 warning, not 2: + +// RUN: FileCheck -warn -check-prefixes=FOO,ZOO -input-file %s %s 2>&1 | \ +// RUN: FileCheck -check-prefix=WARNING-1 %s +// RUN: FileCheck -warn=true -check-prefixes=FOO,ZOO -input-file %s %s 2>&1 | \ +// RUN: FileCheck -check-prefix=WARNING-1 %s +// WARNING-1: warning: Didn't find prefix ZOO, it isn't checked! +// WARNING-1-NOT: warning: Didn't find prefix + + +// Option -warn enabled in these tests, and we want 2 warnings, not 3: + +// RUN: FileCheck -warn -check-prefixes=FOO,ZOO,BOO -input-file %s %s 2>&1 | \ +// RUN: FileCheck -check-prefix=WARNING-2 %s +// WARNING-2: warning: Didn't find prefix ZOO, it isn't checked! +// WARNING-2: warning: Didn't find prefix BOO, it isn't checked! +// WARNING-2-NOT: warning: Didn't find prefix + + +// Option -warn disabled in these tests: + +// RUN: FileCheck -check-prefixes=FOO,ZOO -input-file %s %s 2>&1 | \ +// RUN FileCheck -allow-empty -check-prefix=QUIET-PLEASE %s +// RUN: FileCheck -warn=false -check-prefixes=FOO,ZOO -input-file %s %s 2>&1 | \ +// RUN: FileCheck -allow-empty -check-prefix=QUIET-PLEASE %s + + +// Option -warn is enabled and prefix FOO is used, so this shouldn't warn: + +// RUN: FileCheck -warn -check-prefix=FOO -input-file %s %s 2>&1 | \ +// RUN: FileCheck -allow-empty -check-prefix=QUIET-PLEASE %s + +// QUIET-PLEASE-NOT: warning: Didn't find prefix Index: utils/FileCheck/FileCheck.cpp =================================================================== --- utils/FileCheck/FileCheck.cpp +++ utils/FileCheck/FileCheck.cpp @@ -85,6 +85,10 @@ "vv", cl::init(false), cl::desc("Print information helpful in diagnosing internal FileCheck\n" "issues. Implies -v.\n")); + +static cl::opt Warn("warn", cl::init(false), + cl::desc("Print warning messages.\n")); + static const char * DumpInputEnv = "FILECHECK_DUMP_INPUT_ON_FAILURE"; static cl::opt DumpInputOnFailure( @@ -130,6 +134,7 @@ Req.AllowEmptyInput = AllowEmptyInput; Req.EnableVarScope = EnableVarScope; Req.AllowDeprecatedDagOverlap = AllowDeprecatedDagOverlap; + Req.Warn = Warn; Req.Verbose = Verbose; Req.VerboseVerbose = VerboseVerbose; Req.NoCanonicalizeWhiteSpace = NoCanonicalizeWhiteSpace; @@ -157,7 +162,6 @@ return 2; } - SourceMgr SM; // Read the expected strings from the check file.