Index: llvm/docs/CommandGuide/FileCheck.rst =================================================================== --- llvm/docs/CommandGuide/FileCheck.rst +++ llvm/docs/CommandGuide/FileCheck.rst @@ -111,13 +111,16 @@ .. option:: -v - Print directive pattern matches. + Print good directive pattern matches. However, if ``-input-dump=fail`` or + ``-input-dump=always``, add those matches as input annotations instead. .. option:: -vv Print information helpful in diagnosing internal FileCheck issues, such as discarded overlapping ``CHECK-DAG:`` matches, implicit EOF pattern matches, and ``CHECK-NOT:`` patterns that do not have matches. Implies ``-v``. + However, if ``-input-dump=fail`` or ``-input-dump=always``, just add that + information as input annotations instead. .. option:: --allow-deprecated-dag-overlap Index: llvm/lib/Support/FileCheck.cpp =================================================================== --- llvm/lib/Support/FileCheck.cpp +++ llvm/lib/Support/FileCheck.cpp @@ -901,16 +901,24 @@ StringMap &VariableTable, size_t MatchPos, size_t MatchLen, const FileCheckRequest &Req, std::vector *Diags) { + bool PrintDiag = true; if (ExpectedMatch) { if (!Req.Verbose) return; if (!Req.VerboseVerbose && Pat.getCheckTy() == Check::CheckEOF) return; + // Due to their verbosity, we don't print verbose diagnostics here if we're + // gathering them for a different rendering, but we always print other + // diagnostics. + PrintDiag = !Diags; } SMRange MatchRange = ProcessMatchResult( ExpectedMatch ? FileCheckDiag::MatchFoundAndExpected : FileCheckDiag::MatchFoundButExcluded, SM, Loc, Pat.getCheckTy(), Buffer, MatchPos, MatchLen, Diags); + if (!PrintDiag) + return; + std::string Message = formatv("{0}: {1} string found in input", Pat.getCheckTy().getDescription(Prefix), (ExpectedMatch ? "expected" : "excluded")) @@ -941,27 +949,37 @@ StringRef Buffer, StringMap &VariableTable, bool VerboseVerbose, std::vector *Diags) { - if (!ExpectedMatch && !VerboseVerbose) + bool PrintDiag = true; + if (!ExpectedMatch) { + if (!VerboseVerbose) + return; + // Due to their verbosity, we don't print verbose diagnostics here if we're + // gathering them for a different rendering, but we always print other + // diagnostics. + PrintDiag = !Diags; + } + + // 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")); + SMRange SearchRange = ProcessMatchResult( + ExpectedMatch ? FileCheckDiag::MatchNoneButExpected + : FileCheckDiag::MatchNoneAndExcluded, + SM, Loc, Pat.getCheckTy(), Buffer, 0, Buffer.size(), Diags); + if (!PrintDiag) return; - // Otherwise, we have an error, emit an error message. + // Print "not found" diagnostic. std::string Message = formatv("{0}: {1} string not found in input", Pat.getCheckTy().getDescription(Prefix), (ExpectedMatch ? "expected" : "excluded")) .str(); if (Pat.getCount() > 1) Message += formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str(); - SM.PrintMessage( Loc, ExpectedMatch ? SourceMgr::DK_Error : SourceMgr::DK_Remark, Message); - // 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")); - SMRange SearchRange = ProcessMatchResult( - ExpectedMatch ? FileCheckDiag::MatchNoneButExpected - : FileCheckDiag::MatchNoneAndExcluded, - SM, Loc, Pat.getCheckTy(), Buffer, 0, Buffer.size(), Diags); + // Print the "scanning from here" line. SM.PrintMessage(SearchRange.Start, SourceMgr::DK_Note, "scanning from here"); // Allow the pattern to print additional information if desired. @@ -1276,13 +1294,17 @@ break; } if (Req.VerboseVerbose) { - SMLoc OldStart = SMLoc::getFromPointer(Buffer.data() + MI->Pos); - SMLoc OldEnd = SMLoc::getFromPointer(Buffer.data() + MI->End); - SMRange OldRange(OldStart, OldEnd); - SM.PrintMessage(OldStart, SourceMgr::DK_Note, - "match discarded, overlaps earlier DAG match here", - {OldRange}); - if (Diags) + // Due to their verbosity, we don't print verbose diagnostics here if + // we're gathering them for a different rendering, but we always print + // other diagnostics. + if (!Diags) { + SMLoc OldStart = SMLoc::getFromPointer(Buffer.data() + MI->Pos); + SMLoc OldEnd = SMLoc::getFromPointer(Buffer.data() + MI->End); + SMRange OldRange(OldStart, OldEnd); + SM.PrintMessage(OldStart, SourceMgr::DK_Note, + "match discarded, overlaps earlier DAG match here", + {OldRange}); + } else Diags->rbegin()->MatchTy = FileCheckDiag::MatchFoundButDiscarded; } MatchPos = MI->End; Index: llvm/test/FileCheck/dump-input-annotations.txt =================================================================== --- llvm/test/FileCheck/dump-input-annotations.txt +++ llvm/test/FileCheck/dump-input-annotations.txt @@ -18,6 +18,11 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -v 2>&1 \ ; RUN: | FileCheck -strict-whitespace -match-full-lines -check-prefix=ALIGN %s +; Verbose diagnostics are suppressed but not errors. +; ALIGN-NOT:{{.*}}remark:{{.*}} +; ALIGN:{{.*}}error:{{.*}} +; ALIGN:{{.*}}possible intended match here{{.*}} + ; ALIGN:Full input was: ; ALIGN-NEXT:<<<<<< ; ALIGN-NEXT: 1: hello world @@ -53,6 +58,11 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=CHK,CHK-V +; Verbose diagnostics are suppressed but not errors. +; CHK-NOT: {{.*}}remark:{{.*}} +; CHK: {{.*}}error:{{.*}} +; CHK: {{.*}}possible intended match here{{.*}} + ; CHK: <<<<<< ; CHK-NEXT: 1: hello ; CHK-V-NEXT: check:1 ^~~~~ @@ -83,6 +93,10 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=CNT,CNT-V +; Verbose diagnostics are suppressed but not errors. +; CNT-NOT: {{.*}}remark:{{.*}} +; CNT: {{.*}}error:{{.*}} + ; CNT: <<<<<< ; CNT-NEXT: 1: pete ; CNT-V-NEXT: count:1'0 ^~~~ @@ -114,6 +128,10 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=NXT,NXT-V,NXT-VV +; Verbose diagnostics are suppressed but not errors. +; NXT-NOT: {{.*}}remark:{{.*}} +; NXT: {{.*}}error:{{.*}} + ; NXT: <<<<<< ; NXT-NEXT: 1: hello ; NXT-V-NEXT: check:1 ^~~~~ @@ -161,6 +179,10 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=SAM,SAM-V,SAM-VV +; Verbose diagnostics are suppressed but not errors. +; SAM-NOT: {{.*}}remark:{{.*}} +; SAM: {{.*}}error:{{.*}} + ; SAM: <<<<<< ; SAM-NEXT: 1: hello world! ; SAM-V-NEXT: check:1 ^~~~~ @@ -176,6 +198,10 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -v 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=SAM2 +; Verbose diagnostics are suppressed but not errors. +; SAM2-NOT: {{.*}}remark:{{.*}} +; SAM2: {{.*}}error:{{.*}} + ; SAM2: <<<<<< ; SAM2-NEXT: 1: hello world! ; SAM2-NEXT: check:1 ^~~~~ @@ -214,6 +240,10 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=EMP,EMP-V,EMP-VV +; Verbose diagnostics are suppressed but not errors. +; EMP-NOT: {{.*}}remark:{{.*}} +; EMP: {{.*}}error:{{.*}} + ; EMP: <<<<<< ; EMP-NEXT: 1: hello ; EMP-V-NEXT: check:1 ^~~~~ @@ -242,6 +272,10 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=EMP2,EMP2-V,EMP2-VV +; Verbose diagnostics are suppressed but not errors. +; EMP2-NOT: {{.*}}remark:{{.*}} +; EMP2: {{.*}}error:{{.*}} + ; EMP2: <<<<<< ; EMP2-NEXT: 1: hello ; EMP2-V-NEXT: check:1 ^~~~~ @@ -271,6 +305,10 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=NOT,NOT-V,NOT-VV +; Verbose diagnostics are suppressed but not errors. +; NOT-NOT: {{.*}}remark:{{.*}} +; NOT: {{.*}}error:{{.*}} + ; NOT: <<<<<< ; NOT-NEXT: 1: hello ; NOT-VV-NEXT: not:1 X~~~~ @@ -295,6 +333,10 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=NOT2,NOT2-V,NOT2-VV +; Verbose diagnostics are suppressed but not errors. +; NOT2-NOT: {{.*}}remark:{{.*}} +; NOT2: {{.*}}error:{{.*}} + ; NOT2: <<<<<< ; NOT2-NEXT: 1: hello ; NOT2-VV-NEXT: not:1 X~~~~ @@ -336,6 +378,10 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=DAG,DAG-V,DAG-VV +; Verbose diagnostics are suppressed but not errors. +; DAG-NOT: {{.*}}remark:{{.*}} +; DAG: {{.*}}error:{{.*}} + ; DAG: <<<<<< ; DAG-NEXT: 1: abc ; DAG-V-NEXT: dag:2 ^~~ @@ -377,6 +423,11 @@ ; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \ ; RUN: | FileCheck -match-full-lines %s -check-prefixes=LAB,LAB-V,LAB-VV +; Verbose diagnostics are suppressed but not errors. +; LAB-NOT: {{.*}}remark:{{.*}} +; LAB: {{.*}}error:{{.*}} +; LAB: {{.*}}possible intended match{{.*}} + ; LAB: <<<<<< ; LAB-NEXT: 1: lab0 ; LAB-V-NEXT: label:1'0 ^~~~ @@ -390,5 +441,3 @@ ; LAB-NEXT: label:3'0 ~~~ error: no match found ; LAB-NEXT: >>>>>> ; LAB-NOT: {{.}} - - Index: llvm/test/FileCheck/dump-input-enable.txt =================================================================== --- llvm/test/FileCheck/dump-input-enable.txt +++ llvm/test/FileCheck/dump-input-enable.txt @@ -1,10 +1,10 @@ -; RUN: echo ciao > %t.good +; RUN: echo hello > %t.good ; RUN: echo world >> %t.good ; RUN: echo hello > %t.err -; RUN: echo world >> %t.err +; RUN: echo whirled >> %t.err -; RUN: echo 'CHECK: ciao' > %t.check +; RUN: echo 'CHECK: hello' > %t.check ; RUN: echo 'CHECK-NEXT: world' >> %t.check ;-------------------------------------------------- @@ -42,58 +42,61 @@ ;-------------------------------------------------- ; RUN: FileCheck -input-file %t.good %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines -dump-input=never 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-NODUMP -allow-empty +; RUN: -match-full-lines -dump-input=never -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=TRACE,NODUMP ; RUN: not FileCheck -input-file %t.err %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines -dump-input=never 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-NODUMP +; RUN: -match-full-lines -dump-input=never -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=TRACE,ERR,NODUMP ;-------------------------------------------------- ; default: never ;-------------------------------------------------- ; RUN: FileCheck -input-file %t.good %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-NODUMP -allow-empty +; RUN: -match-full-lines -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=TRACE,NODUMP ; RUN: not FileCheck -input-file %t.err %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-NODUMP +; RUN: -match-full-lines -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=TRACE,ERR,NODUMP ;-------------------------------------------------- ; fail ;-------------------------------------------------- ; RUN: FileCheck -input-file %t.good %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines -dump-input=fail 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-NODUMP -allow-empty +; RUN: -match-full-lines -dump-input=fail -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -allow-empty \ +; RUN: -check-prefixes=NOTRACE,NODUMP ; RUN: not FileCheck -input-file %t.err %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines -dump-input=fail 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-ERR +; RUN: -match-full-lines -dump-input=fail -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=NOTRACE,ERR,DUMP-ERR ;-------------------------------------------------- ; -dump-input-on-failure ;-------------------------------------------------- ; RUN: FileCheck -input-file %t.good %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines -dump-input-on-failure 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-NODUMP -allow-empty +; RUN: -match-full-lines -dump-input-on-failure -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -allow-empty \ +; RUN: -check-prefixes=NOTRACE,NODUMP ; RUN: not FileCheck -input-file %t.err %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines -dump-input-on-failure 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-ERR +; RUN: -match-full-lines -dump-input-on-failure -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=NOTRACE,ERR,DUMP-ERR ; RUN: env FILECHECK_DUMP_INPUT_ON_FAILURE=1 \ ; RUN: FileCheck -input-file %t.good %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-NODUMP -allow-empty +; RUN: -match-full-lines -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -allow-empty \ +; RUN: -check-prefixes=NOTRACE,NODUMP ; RUN: env FILECHECK_DUMP_INPUT_ON_FAILURE=1 \ ; RUN: not FileCheck -input-file %t.err %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-ERR +; RUN: -match-full-lines -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=NOTRACE,ERR,DUMP-ERR ;-------------------------------------------------- ; always @@ -101,28 +104,35 @@ ; RUN: FileCheck -input-file %t.good %t.check -check-prefix=CHECK \ ; RUN: -match-full-lines -dump-input=always -v 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-GOOD +; RUN: | FileCheck %s -match-full-lines -check-prefixes=NOTRACE,DUMP-OK ; RUN: not FileCheck -input-file %t.err %t.check -check-prefix=CHECK \ -; RUN: -match-full-lines -dump-input=always 2>&1 \ -; RUN: | FileCheck %s -match-full-lines -check-prefix=CHECK-ERR +; RUN: -match-full-lines -dump-input=always -v 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=NOTRACE,ERR,DUMP-ERR ; END. -; CHECK-GOOD: Full input was: -; CHECK-GOOD-NEXT: <<<<<< -; CHECK-GOOD-NEXT: 1: ciao -; CHECK-GOOD-NEXT: check:1 ^~~~ -; CHECK-GOOD-NEXT: 2: world -; CHECK-GOOD-NEXT: next:2 ^~~~~ -; CHECK-GOOD-NEXT: >>>>>> - -; CHECK-ERR: Full input was: -; CHECK-ERR-NEXT: <<<<<< -; CHECK-ERR-NEXT: 1: hello -; CHECK-ERR-NEXT: check:1 X~~~~ -; CHECK-ERR-NEXT: 2: world -; CHECK-ERR-NEXT: check:1 ~~~~~ error: no match found -; CHECK-ERR-NEXT: >>>>>> - -; CHECK-NODUMP-NOT: <<<<<< +; Trace is sometimes suppressed. +; TRACE: {{.*}}remark:{{.*}} +; NOTRACE-NOT: {{.*}}remark:{{.*}} + +; Error diagnostics are never suppressed. +; ERR: {{.*}}error:{{.*}} + +; NODUMP-NOT: <<<<<< + +; DUMP-OK: Full input was: +; DUMP-OK-NEXT: <<<<<< +; DUMP-OK-NEXT: 1: hello +; DUMP-OK-NEXT: check:1 ^~~~~ +; DUMP-OK-NEXT: 2: world +; DUMP-OK-NEXT: next:2 ^~~~~ +; DUMP-OK-NEXT: >>>>>> + +; DUMP-ERR: Full input was: +; DUMP-ERR-NEXT: <<<<<< +; DUMP-ERR-NEXT: 1: hello +; DUMP-ERR-NEXT: check:1 ^~~~~ +; DUMP-ERR-NEXT: 2: whirled +; DUMP-ERR-NEXT: next:2 X~~~~~~ error: no match found +; DUMP-ERR-NEXT: >>>>>> Index: llvm/utils/FileCheck/FileCheck.cpp =================================================================== --- llvm/utils/FileCheck/FileCheck.cpp +++ llvm/utils/FileCheck/FileCheck.cpp @@ -79,13 +79,16 @@ "provided for convenience as old tests are migrated to the new\n" "non-overlapping CHECK-DAG implementation.\n")); -static cl::opt Verbose("v", cl::init(false), - cl::desc("Print directive pattern matches.\n")); +static cl::opt Verbose( + "v", cl::init(false), + cl::desc("Print directive pattern matches, or add them to the input dump\n" + "if enabled.\n")); static cl::opt VerboseVerbose( "vv", cl::init(false), cl::desc("Print information helpful in diagnosing internal FileCheck\n" - "issues. Implies -v.\n")); + "issues, or add it to the input dump if enabled. Implies\n" + "-v.\n")); static const char * DumpInputEnv = "FILECHECK_DUMP_INPUT_ON_FAILURE"; static cl::opt DumpInputOnFailure(