Index: llvm/test/FileCheck/dump-input-annotations.txt =================================================================== --- llvm/test/FileCheck/dump-input-annotations.txt +++ llvm/test/FileCheck/dump-input-annotations.txt @@ -24,7 +24,7 @@ ; ALIGN:{{.*}}error:{{.*}} ; ALIGN:{{.*}}possible intended match here{{.*}} -; ALIGN:Full input was: +; ALIGN:Input was: ; ALIGN-NEXT:<<<<<< ; ALIGN-NEXT: 1: hello world ; ALIGN-NEXT:check:1 ^~~~~ Index: llvm/test/FileCheck/dump-input-context.txt =================================================================== --- /dev/null +++ llvm/test/FileCheck/dump-input-context.txt @@ -0,0 +1,288 @@ +;-------------------------------------------------- +; Input file, check file, and directives for checking the size of the context. +; +; These are designed to be used with -dump-input=always +; -dump-input-filter=annotation -vv. +; +; In the resulting input dump, there are three potential ellipses: +; +; - S: At the start of the input. +; - M: Between two input lines included by the filter. +; - E: At the end of the input. +; +; They are all present at -dump-input-context=4. One becomes useless each time +; -dump-input-context is incremented beyond that because then that ellipsis +; becomes equal to or larger than the input lines it elides. +;-------------------------------------------------- + +; RUN: echo foo8 > %t.in +; RUN: echo foo7 >> %t.in +; RUN: echo foo6 >> %t.in +; RUN: echo foo5 >> %t.in +; RUN: echo foo4 >> %t.in +; RUN: echo foo3 >> %t.in +; RUN: echo foo2 >> %t.in +; RUN: echo foo1 >> %t.in +; RUN: echo hello >> %t.in +; RUN: echo foo1 >> %t.in +; RUN: echo foo2 >> %t.in +; RUN: echo foo3 >> %t.in +; RUN: echo foo4 >> %t.in +; RUN: echo foo5 >> %t.in +; RUN: echo foo6 >> %t.in +; RUN: echo foo7 >> %t.in +; RUN: echo foo7 >> %t.in +; RUN: echo foo6 >> %t.in +; RUN: echo foo5 >> %t.in +; RUN: echo foo4 >> %t.in +; RUN: echo foo3 >> %t.in +; RUN: echo foo2 >> %t.in +; RUN: echo foo1 >> %t.in +; RUN: echo world >> %t.in +; RUN: echo foo1 >> %t.in +; RUN: echo foo2 >> %t.in +; RUN: echo foo3 >> %t.in +; RUN: echo foo4 >> %t.in +; RUN: echo foo5 >> %t.in +; RUN: echo foo6 >> %t.in +; RUN: echo foo7 >> %t.in +; RUN: echo foo8 >> %t.in +; RUN: echo foo9 >> %t.in +; RUN: echo foo0 >> %t.in + +; RUN: echo 'CHECK: hello' > %t.chk +; RUN: echo 'CHECK: world' >> %t.chk + +; C0: <<<<<< +; CS-NEXT: . +; CS-NEXT: . +; CS-NEXT: . +; C5-NEXT: 1: foo8 +; C5-NEXT: 2: foo7 +; C5-NEXT: 3: foo6 +; C5-NEXT: 4: foo5 +; C4-NEXT: 5: foo4 +; C3-NEXT: 6: foo3 +; C2-NEXT: 7: foo2 +; C1-NEXT: 8: foo1 +; C0-NEXT: 9: hello +; C0-NEXT: check:1 ^~~~~ +; C1-NEXT: 10: foo1 +; C2-NEXT: 11: foo2 +; C3-NEXT: 12: foo3 +; C4-NEXT: 13: foo4 +; C5-NEXT: 14: foo5 +; C6-NEXT: 15: foo6 +; C6-NEXT: 16: foo7 +; CM-NEXT: . +; CM-NEXT: . +; CM-NEXT: . +; C6-NEXT: 17: foo7 +; C6-NEXT: 18: foo6 +; C5-NEXT: 19: foo5 +; C4-NEXT: 20: foo4 +; C3-NEXT: 21: foo3 +; C2-NEXT: 22: foo2 +; C1-NEXT: 23: foo1 +; C0-NEXT: 24: world +; C0-NEXT: check:2 ^~~~~ +; C1-NEXT: 25: foo1 +; C2-NEXT: 26: foo2 +; C3-NEXT: 27: foo3 +; C4-NEXT: 28: foo4 +; C5-NEXT: 29: foo5 +; C6-NEXT: 30: foo6 +; C7-NEXT: 31: foo7 +; C7-NEXT: 32: foo8 +; C7-NEXT: 33: foo9 +; C7-NEXT: 34: foo0 +; CE-NEXT: . +; CE-NEXT: . +; CE-NEXT: . +; C0-NEXT: >>>>>> + +; Now build an alternate set of checks where input lines that might be elided by +; ellipses have annotations. + +; RUN: cp %t.in %t.wide.in +; RUN: echo 'CHECK: hello' > %t.wide.chk +; RUN: echo 'CHECK-NOT: bar' >> %t.wide.chk +; RUN: echo 'CHECK: world' >> %t.wide.chk + +; W5: <<<<<< +; W5: 9: hello +; W5-NEXT: check:1 ^~~~~ +; W5-NEXT: 10: foo1 +; W5-NEXT: not:2 X~~~ +; W5-NEXT: 11: foo2 +; W5-NEXT: not:2 ~~~~ +; W5-NEXT: 12: foo3 +; W5-NEXT: not:2 ~~~~ +; W5-NEXT: 13: foo4 +; W5-NEXT: not:2 ~~~~ +; W5-NEXT: 14: foo5 +; W5-NEXT: not:2 ~~~~ +; W5-NEXT: 15: foo6 +; W5-NEXT: not:2 ~~~~ +; W6-NEXT: 16: foo7 +; W6-NEXT: not:2 ~~~~ +; WM-NEXT: . +; WM-NEXT: . +; WM-NEXT: . +; W6-NEXT: 17: foo7 +; W6-NEXT: not:2 ~~~~ +; W6-NEXT: 18: foo6 +; W6-NEXT: not:2 ~~~~ +; W5-NEXT: 19: foo5 +; W5-NEXT: not:2 ~~~~ +; W5-NEXT: 20: foo4 +; W5-NEXT: not:2 ~~~~ +; W5-NEXT: 21: foo3 +; W5-NEXT: not:2 ~~~~ +; W5-NEXT: 22: foo2 +; W5-NEXT: not:2 ~~~~ +; W5-NEXT: 23: foo1 +; W5-NEXT: not:2 ~~~~ +; W5-NEXT: 24: world +; W5-NEXT: check:3 ^~~~~ + +;-------------------------------------------------- +; Check -dump-input-context=. +;-------------------------------------------------- + +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=-1 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefix=BADVAL -DVAL=-1 + +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=foobar %t.chk < %t.in \ +; RUN: 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefix=BADVAL -DVAL=foobar + +BADVAL: {{F|f}}ile{{C|c}}heck{{.*}}: for the --dump-input-context option: '[[VAL]]' value invalid for uint argument! + +;-------------------------------------------------- +; Check -dump-input-context explicit values. +;-------------------------------------------------- + +; 0 is an important boundary case. +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=0 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,CS,CM,CE + +; 1 is an important boundary case. +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=1 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,CS,CM,CE + +; 4 is the boundary case at which all ellipses are present in our test. +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=4 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,CS,CM,CE + +; 5 is the boundary case at which the start ellipsis is useless. +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=5 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,CM,CE + +; 6 is the boundary case at which the middle ellipsis is useless. +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=6 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,C6,CE + +; 7 is the boundary case at which the end ellipsis is useless. +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=7 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,C6,C7 + +; Make sure all is fine when -dump-input-context is far larger than the input. +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=200 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,C6,C7 + +;-------------------------------------------------- +; Check that -dump-input-context default is 5. +;-------------------------------------------------- + +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,CM,CE + +;-------------------------------------------------- +; Check multiple -dump-input-context options. +; +; This might occur when a test author specifies -dump-input-context on a +; specific FileCheck call while a test runner specifies -dump-input-context in +; FILECHECK_OPTS, but check the behavior generally. +; +; The largest value wins because it provides the most information. +;-------------------------------------------------- + +;- - - - - - - - - - - - - - - - - - - - - - - - - +; Check duplicate. +;- - - - - - - - - - - - - - - - - - - - - - - - - + +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=1 -dump-input-context=1 \ +; RUN: %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,CS,CM,CE + +;- - - - - - - - - - - - - - - - - - - - - - - - - +; Check precedence. +;- - - - - - - - - - - - - - - - - - - - - - - - - + +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=0 -dump-input-context=1 \ +; RUN: %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,CS,CM,CE + +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=1 -dump-input-context=0 \ +; RUN: %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,CS,CM,CE + +;- - - - - - - - - - - - - - - - - - - - - - - - - +; Check that FILECHECK_OPTS isn't handled differently. +;- - - - - - - - - - - - - - - - - - - - - - - - - + +; RUN: %ProtectFileCheckOutput FILECHECK_OPTS=-dump-input-context=0 \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=1 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,CS,CM,CE + +; RUN: %ProtectFileCheckOutput FILECHECK_OPTS=-dump-input-context=1 \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=0 %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,CS,CM,CE + +;-------------------------------------------------- +; Check how annotations on input lines that might be elided by ellipses affect +; whether they are actually elided. +;-------------------------------------------------- + +; At -dump-input-context=5, the ellipsis is useful but only when annotations on +; elided input lines are considered. +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=5 %t.wide.chk < %t.wide.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=W5,WM + +; At -dump-input-context=6, the ellipsis is not useful even when annotations on +; elided input lines are considered. +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=annotation -vv \ +; RUN: -dump-input-context=6 %t.wide.chk < %t.wide.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=W5,W6 Index: llvm/test/FileCheck/dump-input-enable.txt =================================================================== --- llvm/test/FileCheck/dump-input-enable.txt +++ llvm/test/FileCheck/dump-input-enable.txt @@ -236,7 +236,7 @@ ; NODUMP-NOT: <<<<<< -; DUMP-OK: Full input was: +; DUMP-OK: Input was: ; DUMP-OK-NEXT: <<<<<< ; DUMP-OK-NEXT: 1: hello ; DUMP-OK-NEXT: check:1 ^~~~~ @@ -244,7 +244,7 @@ ; DUMP-OK-NEXT: next:2 ^~~~~ ; DUMP-OK-NEXT: >>>>>> -; DUMP-ERR: Full input was: +; DUMP-ERR: Input was: ; DUMP-ERR-NEXT: <<<<<< ; DUMP-ERR-NEXT: 1: hello ; DUMP-ERR-V-NEXT: check:1 ^~~~~ Index: llvm/test/FileCheck/dump-input-filter.txt =================================================================== --- /dev/null +++ llvm/test/FileCheck/dump-input-filter.txt @@ -0,0 +1,425 @@ +; To keep this test maintainable, avoid depending on -dump-input-context's +; default value, which is checked in dump-input-context.txt instead. + +;-------------------------------------------------- +; Create the input file and the check file. +;-------------------------------------------------- + +; line 1 +; RUN: echo start > %t.in +; RUN: echo foo0 >> %t.in +; RUN: echo foo1 >> %t.in +; RUN: echo foo2 >> %t.in +; RUN: echo foo3 >> %t.in +; RUN: echo foo4 >> %t.in +; RUN: echo foo5 >> %t.in +; RUN: echo foo6 >> %t.in +; RUN: echo foo7 >> %t.in +; RUN: echo foo8 >> %t.in +; RUN: echo foo9 >> %t.in +; line 12 +; RUN: echo hello >> %t.in +; RUN: echo foo0 >> %t.in +; RUN: echo foo1 >> %t.in +; RUN: echo foo2 >> %t.in +; RUN: echo foo3 >> %t.in +; RUN: echo foo4 >> %t.in +; RUN: echo foo5 >> %t.in +; RUN: echo foo6 >> %t.in +; RUN: echo foo7 >> %t.in +; RUN: echo foo8 >> %t.in +; RUN: echo foo9 >> %t.in +; line 23 +; RUN: echo word >> %t.in +; RUN: echo foo0 >> %t.in +; RUN: echo foo1 >> %t.in +; RUN: echo foo2 >> %t.in +; RUN: echo foo3 >> %t.in +; RUN: echo foo4 >> %t.in +; RUN: echo foo5 >> %t.in +; RUN: echo foo6 >> %t.in +; RUN: echo foo7 >> %t.in +; RUN: echo foo8 >> %t.in +; RUN: echo foo9 >> %t.in +; line 34 +; RUN: echo end >> %t.in + +; RUN: echo 'CHECK: start' > %t.chk +; RUN: echo 'CHECK: hello' >> %t.chk +; RUN: echo 'CHECK: world' >> %t.chk +; RUN: echo 'CHECK: end' >> %t.chk + +;-------------------------------------------------- +; Directives for checking the dump. +;-------------------------------------------------- + +; ALL: <<<<<< +; ALL-NEXT: 1: start +; ALL-NEXT: check:1 ^~~~~ +; ALL-NEXT: 2: foo0 +; ALL-NEXT: 3: foo1 +; ALL-NEXT: 4: foo2 +; ALL-NEXT: 5: foo3 +; ALL-NEXT: 6: foo4 +; ALL-NEXT: 7: foo5 +; ALL-NEXT: 8: foo6 +; ALL-NEXT: 9: foo7 +; ALL-NEXT: 10: foo8 +; ALL-NEXT: 11: foo9 +; ALL-NEXT: 12: hello +; ALL-NEXT: check:2 ^~~~~ +; ALL-NEXT: 13: foo0 +; ALL-NEXT: check:3'0 X~~~ error: no match found +; ALL-NEXT: 14: foo1 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 15: foo2 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 16: foo3 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 17: foo4 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 18: foo5 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 19: foo6 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 20: foo7 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 21: foo8 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 22: foo9 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 23: word +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: check:3'1 ? possible intended match +; ALL-NEXT: 24: foo0 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 25: foo1 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 26: foo2 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 27: foo3 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 28: foo4 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 29: foo5 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 30: foo6 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 31: foo7 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 32: foo8 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 33: foo9 +; ALL-NEXT: check:3'0 ~~~~ +; ALL-NEXT: 34: end +; ALL-NEXT: check:3'0 ~~~ +; ALL-NEXT: >>>>>> + +; ANNOTATION-FULL: <<<<<< +; ANNOTATION-FULL-NEXT: 1: start +; ANNOTATION-FULL-NEXT: check:1 ^~~~~ +; ANNOTATION-FULL-NEXT: 2: foo0 +; ANNOTATION-FULL-NEXT: 3: foo1 +; ANNOTATION-FULL-NEXT: . +; ANNOTATION-FULL-NEXT: . +; ANNOTATION-FULL-NEXT: . +; ANNOTATION-FULL-NEXT: 10: foo8 +; ANNOTATION-FULL-NEXT: 11: foo9 +; ANNOTATION-FULL-NEXT: 12: hello +; ANNOTATION-FULL-NEXT: check:2 ^~~~~ +; ANNOTATION-FULL-NEXT: 13: foo0 +; ANNOTATION-FULL-NEXT: check:3'0 X~~~ error: no match found +; ANNOTATION-FULL-NEXT: 14: foo1 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 15: foo2 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 16: foo3 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 17: foo4 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 18: foo5 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 19: foo6 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 20: foo7 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 21: foo8 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 22: foo9 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 23: word +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: check:3'1 ? possible intended match +; ANNOTATION-FULL-NEXT: 24: foo0 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 25: foo1 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 26: foo2 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 27: foo3 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 28: foo4 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 29: foo5 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 30: foo6 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 31: foo7 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 32: foo8 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 33: foo9 +; ANNOTATION-FULL-NEXT: check:3'0 ~~~~ +; ANNOTATION-FULL-NEXT: 34: end +; ANNOTATION-FULL-NEXT: check:3'0 ~~~ +; ANNOTATION-FULL-NEXT: >>>>>> + +; ANNOTATION: <<<<<< +; ANNOTATION-NEXT: 1: start +; ANNOTATION-NEXT: check:1 ^~~~~ +; ANNOTATION-NEXT: 2: foo0 +; ANNOTATION-NEXT: 3: foo1 +; ANNOTATION-NEXT: . +; ANNOTATION-NEXT: . +; ANNOTATION-NEXT: . +; ANNOTATION-NEXT: 10: foo8 +; ANNOTATION-NEXT: 11: foo9 +; ANNOTATION-NEXT: 12: hello +; ANNOTATION-NEXT: check:2 ^~~~~ +; ANNOTATION-NEXT: 13: foo0 +; ANNOTATION-NEXT: check:3'0 X~~~ error: no match found +; ANNOTATION-NEXT: 14: foo1 +; ANNOTATION-NEXT: check:3'0 ~~~~ +; ANNOTATION-NEXT: 15: foo2 +; ANNOTATION-NEXT: check:3'0 ~~~~ +; ANNOTATION-NEXT: . +; ANNOTATION-NEXT: . +; ANNOTATION-NEXT: . +; ANNOTATION-NEXT: 21: foo8 +; ANNOTATION-NEXT: check:3'0 ~~~~ +; ANNOTATION-NEXT: 22: foo9 +; ANNOTATION-NEXT: check:3'0 ~~~~ +; ANNOTATION-NEXT: 23: word +; ANNOTATION-NEXT: check:3'0 ~~~~ +; ANNOTATION-NEXT: check:3'1 ? possible intended match +; ANNOTATION-NEXT: 24: foo0 +; ANNOTATION-NEXT: check:3'0 ~~~~ +; ANNOTATION-NEXT: 25: foo1 +; ANNOTATION-NEXT: check:3'0 ~~~~ +; ANNOTATION-NEXT: . +; ANNOTATION-NEXT: . +; ANNOTATION-NEXT: . +; ANNOTATION-NEXT: >>>>>> + +; ERROR: <<<<<< +; ERROR-NEXT: . +; ERROR-NEXT: . +; ERROR-NEXT: . +; ERROR-NEXT: 11: foo9 +; ERROR-NEXT: 12: hello +; ERROR-NEXT: check:2 ^~~~~ +; ERROR-NEXT: 13: foo0 +; ERROR-NEXT: check:3'0 X~~~ error: no match found +; ERROR-NEXT: 14: foo1 +; ERROR-NEXT: check:3'0 ~~~~ +; ERROR-NEXT: 15: foo2 +; ERROR-NEXT: check:3'0 ~~~~ +; ERROR-NEXT: . +; ERROR-NEXT: . +; ERROR-NEXT: . +; ERROR-NEXT: 21: foo8 +; ERROR-NEXT: check:3'0 ~~~~ +; ERROR-NEXT: 22: foo9 +; ERROR-NEXT: check:3'0 ~~~~ +; ERROR-NEXT: 23: word +; ERROR-NEXT: check:3'0 ~~~~ +; ERROR-NEXT: check:3'1 ? possible intended match +; ERROR-NEXT: 24: foo0 +; ERROR-NEXT: check:3'0 ~~~~ +; ERROR-NEXT: 25: foo1 +; ERROR-NEXT: check:3'0 ~~~~ +; ERROR-NEXT: . +; ERROR-NEXT: . +; ERROR-NEXT: . +; ERROR-NEXT: >>>>>> + +;-------------------------------------------------- +; Check -dump-input-filter=. +;-------------------------------------------------- + +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=foobar \ +; RUN: | FileCheck %s -match-full-lines -check-prefix=BADVAL + +BADVAL: {{F|f}}ile{{C|c}}heck{{.*}}: for the --dump-input-filter option: Cannot find option named 'foobar'! + +;-------------------------------------------------- +; Check -dump-input-filter explicit values. +;-------------------------------------------------- + +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=all \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ALL + +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=annotation-full \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION-FULL + +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=annotation \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION + +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=error \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ERROR + +;-------------------------------------------------- +; Check -dump-input-filter defaults. +;-------------------------------------------------- + +; no -dump-input => -dump-input-filter=error +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ERROR + +; -dump-input=fail => -dump-input-filter=error +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input=fail \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ERROR + +; -dump-input=always => -dump-input-filter=all +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input=always \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ALL + +;-------------------------------------------------- +; Check multiple -dump-input-filter options. +; +; This might occur when a test author specifies -dump-input-filter on a specific +; FileCheck call while a test runner specifies -dump-input-filter in +; FILECHECK_OPTS, but check the behavior generally. +; +; The value providing the most information wins. +;-------------------------------------------------- + +;- - - - - - - - - - - - - - - - - - - - - - - - - +; Check duplicate. +;- - - - - - - - - - - - - - - - - - - - - - - - - + +; all, all => all +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=all -dump-input-filter=all \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ALL + +;- - - - - - - - - - - - - - - - - - - - - - - - - +; Check precedence. +;- - - - - - - - - - - - - - - - - - - - - - - - - + +; all, annotation-full => all +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=all -dump-input-filter=annotation-full \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ALL + +; annotation-full, annotation => annotation-full +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=annotation-full \ +; RUN: -dump-input-filter=annotation \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION-FULL + +; annotation, error => annotation +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=annotation -dump-input-filter=error \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION + +;- - - - - - - - - - - - - - - - - - - - - - - - - +; Check that order doesn't matter. +;- - - - - - - - - - - - - - - - - - - - - - - - - + +; error, annotation => annotation +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=error -dump-input-filter=annotation \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION + +;- - - - - - - - - - - - - - - - - - - - - - - - - +; Check that FILECHECK_OPTS isn't handled differently. +;- - - - - - - - - - - - - - - - - - - - - - - - - + +; annotation, error => annotation +; RUN: %ProtectFileCheckOutput FILECHECK_OPTS=-dump-input-filter=annotation \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=error \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION + +; error, annotation => annotation +; RUN: %ProtectFileCheckOutput FILECHECK_OPTS=-dump-input-filter=error \ +; RUN: not FileCheck -dump-input-context=2 -vv %t.chk < %t.in 2>&1 \ +; RUN: -dump-input-filter=annotation \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=ANNOTATION + +;-------------------------------------------------- +; Check the case where all input lines are filtered out. +;-------------------------------------------------- + +; RUN: echo 'CHECK: hello' > %t.good.chk + +; RUN: %ProtectFileCheckOutput \ +; RUN: FileCheck -dump-input=always -dump-input-filter=error -vv %t.good.chk \ +; RUN: < %t.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=EMPTY + +; EMPTY: <<<<<< +; EMPTY-NEXT: . +; EMPTY-NEXT: . +; EMPTY-NEXT: . +; EMPTY-NEXT: >>>>>> + +;-------------------------------------------------- +; Check that other kinds of errors are included by -dump-input-filter=error. +; +; "error: no match found" and "possible intended match" are checked above. +;-------------------------------------------------- + +;- - - - - - - - - - - - - - - - - - - - - - - - - +; error: no match expected. +;- - - - - - - - - - - - - - - - - - - - - - - - - + +; RUN: echo 'foo' > %t.not-err.in +; RUN: echo 'CHECK-NOT: foo' > %t.not-err.chk + +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=0 -dump-input-filter=error \ +; RUN: %t.not-err.chk < %t.not-err.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=NOT-ERR + +; NOT-ERR: 1: foo +; NOT-ERR-NEXT: not:1 !~~ error: no match expected + +;- - - - - - - - - - - - - - - - - - - - - - - - - +; error: match on wrong line. +;- - - - - - - - - - - - - - - - - - - - - - - - - + +; RUN: echo 'foo' > %t.next-err.in +; RUN: echo 'foo' >> %t.next-err.in +; RUN: echo 'bar' >> %t.next-err.in +; RUN: echo 'CHECK: foo' > %t.next-err.chk +; RUN: echo 'CHECK-NEXT: bar' >> %t.next-err.chk + +; RUN: %ProtectFileCheckOutput \ +; RUN: not FileCheck -dump-input-context=0 -dump-input-filter=error \ +; RUN: %t.next-err.chk < %t.next-err.in 2>&1 \ +; RUN: | FileCheck %s -match-full-lines -check-prefixes=NEXT-ERR + +; NEXT-ERR: 3: bar +; NEXT-ERR-NEXT: next:2 !~~ error: match on wrong line \ No newline at end of file Index: llvm/utils/FileCheck/FileCheck.cpp =================================================================== --- llvm/utils/FileCheck/FileCheck.cpp +++ llvm/utils/FileCheck/FileCheck.cpp @@ -121,14 +121,48 @@ cl::desc("Dump input to stderr, adding annotations representing\n" "currently enabled diagnostics. When there are multiple\n" "occurrences of this option, the that appears earliest\n" - "in the list below has precedence.\n"), + "in the list below has precedence. The default is 'fail'.\n"), cl::value_desc("mode"), - cl::values(clEnumValN(DumpInputHelp, "help", - "Explain dump format and quit"), + cl::values(clEnumValN(DumpInputHelp, "help", "Explain input dump and quit"), clEnumValN(DumpInputAlways, "always", "Always dump input"), clEnumValN(DumpInputFail, "fail", "Dump input on failure"), clEnumValN(DumpInputNever, "never", "Never dump input"))); +// The order of DumpInputFilterValue members affects their precedence, as +// documented for -dump-input-filter below. +enum DumpInputFilterValue { + DumpInputFilterError, + DumpInputFilterAnnotation, + DumpInputFilterAnnotationFull, + DumpInputFilterAll +}; + +static cl::list DumpInputFilters( + "dump-input-filter", + cl::desc("In the dump requested by -dump-input, print only input lines of\n" + "kind plus any context specified by -dump-input-context.\n" + "When there are multiple occurrences of this option, the \n" + "that appears earliest in the list below has precedence. The\n" + "default is 'error' when -dump-input=fail, and it's 'all' when\n" + "-dump-input=always.\n"), + cl::value_desc("kind"), + cl::values(clEnumValN(DumpInputFilterAll, "all", "All input lines"), + clEnumValN(DumpInputFilterAnnotationFull, "annotation-full", + "Input lines with annotations"), + clEnumValN(DumpInputFilterAnnotation, "annotation", + "Input lines with starting points of annotations"), + clEnumValN(DumpInputFilterError, "error", + "Input lines with starting points of error " + "annotations"))); + +static cl::list DumpInputContexts( + "dump-input-context", cl::value_desc("N"), + cl::desc("In the dump requested by -dump-input, print input lines\n" + "before and input lines after any lines specified by\n" + "-dump-input-filter. When there are multiple occurrences of\n" + "this option, the largest specified has precedence. The\n" + "default is 5.\n")); + typedef cl::list::const_iterator prefix_iterator; @@ -151,10 +185,15 @@ raw_ostream::Colors Color; /// A note to follow the marker, or empty string if none. std::string Note; + /// Does this marker indicate inclusion by -dump-input-filter=error? + bool FiltersAsError; MarkerStyle() {} MarkerStyle(char Lead, raw_ostream::Colors Color, - const std::string &Note = "") - : Lead(Lead), Color(Color), Note(Note) {} + const std::string &Note = "", bool FiltersAsError = false) + : Lead(Lead), Color(Color), Note(Note), FiltersAsError(FiltersAsError) { + assert((!FiltersAsError || !Note.empty()) && + "expected error diagnostic to have note"); + } }; static MarkerStyle GetMarker(FileCheckDiag::MatchType MatchTy) { @@ -162,26 +201,39 @@ case FileCheckDiag::MatchFoundAndExpected: return MarkerStyle('^', raw_ostream::GREEN); case FileCheckDiag::MatchFoundButExcluded: - return MarkerStyle('!', raw_ostream::RED, "error: no match expected"); + return MarkerStyle('!', raw_ostream::RED, "error: no match expected", + /*FiltersAsError=*/true); case FileCheckDiag::MatchFoundButWrongLine: - return MarkerStyle('!', raw_ostream::RED, "error: match on wrong line"); + return MarkerStyle('!', raw_ostream::RED, "error: match on wrong line", + /*FiltersAsError=*/true); case FileCheckDiag::MatchFoundButDiscarded: return MarkerStyle('!', raw_ostream::CYAN, "discard: overlaps earlier match"); case FileCheckDiag::MatchNoneAndExcluded: return MarkerStyle('X', raw_ostream::GREEN); case FileCheckDiag::MatchNoneButExpected: - return MarkerStyle('X', raw_ostream::RED, "error: no match found"); + return MarkerStyle('X', raw_ostream::RED, "error: no match found", + /*FiltersAsError=*/true); case FileCheckDiag::MatchFuzzy: - return MarkerStyle('?', raw_ostream::MAGENTA, "possible intended match"); + return MarkerStyle('?', raw_ostream::MAGENTA, "possible intended match", + /*FiltersAsError=*/true); } llvm_unreachable_internal("unexpected match type"); } static void DumpInputAnnotationHelp(raw_ostream &OS) { OS << "The following description was requested by -dump-input=help to\n" - << "explain the input annotations printed by -dump-input=always and\n" - << "-dump-input=fail:\n\n"; + << "explain the input dump printed by FileCheck.\n" + << "\n" + << "Related command-line options:\n" + << " - -dump-input= enables or disables the input dump\n" + << " - -dump-input-filter= filters the input lines\n" + << " - -dump-input-context= adjusts the context of filtered lines\n" + << " - -v and -vv add more annotations\n" + << " - -color forces colors to be enabled both in the dump and below\n" + << " - -help documents the above options in more detail\n" + << "\n" + << "Input dump annotation format:\n"; // Labels for input lines. OS << " - "; @@ -222,6 +274,12 @@ WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "?"; OS << " marks fuzzy match when no match is found\n"; + // Elided lines. + OS << " - "; + WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "..."; + OS << " indicates elided input lines and annotations, as specified by\n" + << " -dump-input-filter and -dump-input-context\n"; + // Colors. OS << " - colors "; WithColor(OS, raw_ostream::GREEN, true) << "success"; @@ -233,8 +291,7 @@ WithColor(OS, raw_ostream::CYAN, true, false) << "discarded match"; OS << ", "; WithColor(OS, raw_ostream::CYAN, true, true) << "unmatched input"; - OS << "\n\n" - << "If you are not seeing color above or in input dumps, try: -color\n"; + OS << "\n"; } /// An annotation for a single input line. @@ -243,10 +300,12 @@ unsigned DiagIndex; /// The label for this annotation. std::string Label; + /// Is this the initial fragment of a diagnostic that has been broken across + /// multiple lines? + bool IsFirstLine; /// What input line (one-origin indexing) this annotation marks. This might - /// be different from the starting line of the original diagnostic if this is - /// a non-initial fragment of a diagnostic that has been broken across - /// multiple lines. + /// be different from the starting line of the original diagnostic if + /// !IsFirstLine. unsigned InputLine; /// The column range (one-origin indexing, open end) in which to mark the /// input line. If InputEndCol is UINT_MAX, treat it as the last column @@ -342,6 +401,7 @@ // Compute the mark location, and break annotation into multiple // annotations if it spans multiple lines. + A.IsFirstLine = true; A.InputLine = DiagItr->InputStartLine; A.InputStartCol = DiagItr->InputStartCol; if (DiagItr->InputStartLine == DiagItr->InputEndLine) { @@ -365,6 +425,7 @@ InputAnnotation B; B.DiagIndex = A.DiagIndex; B.Label = A.Label; + B.IsFirstLine = false; B.InputLine = L; B.Marker = A.Marker; B.Marker.Lead = '~'; @@ -381,11 +442,56 @@ } } +static unsigned FindInputLineInFilter( + DumpInputFilterValue DumpInputFilter, unsigned CurInputLine, + const std::vector::iterator &AnnotationBeg, + const std::vector::iterator &AnnotationEnd) { + if (DumpInputFilter == DumpInputFilterAll) + return CurInputLine; + for (auto AnnotationItr = AnnotationBeg; AnnotationItr != AnnotationEnd; + ++AnnotationItr) { + switch (DumpInputFilter) { + case DumpInputFilterAll: + llvm_unreachable("unexpected DumpInputFilterAll"); + break; + case DumpInputFilterAnnotationFull: + return AnnotationItr->InputLine; + case DumpInputFilterAnnotation: + if (AnnotationItr->IsFirstLine) + return AnnotationItr->InputLine; + break; + case DumpInputFilterError: + if (AnnotationItr->IsFirstLine && AnnotationItr->Marker.FiltersAsError) + return AnnotationItr->InputLine; + break; + } + } + return UINT_MAX; +} + +static void DumpEllipsisOrElidedLines(raw_ostream &OS, std::string &ElidedLines, + unsigned LabelWidth) { + if (ElidedLines.empty()) + return; + unsigned EllipsisLines = 3; + if (EllipsisLines < StringRef(ElidedLines).count('\n')) { + for (unsigned i = 0; i < EllipsisLines; ++i) { + WithColor(OS, raw_ostream::BLACK, /*Bold=*/true) + << right_justify(".", LabelWidth); + OS << '\n'; + } + } else + OS << ElidedLines; + ElidedLines.clear(); +} + static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req, + DumpInputFilterValue DumpInputFilter, + unsigned DumpInputContext, StringRef InputFileText, std::vector &Annotations, unsigned LabelWidth) { - OS << "Full input was:\n<<<<<<\n"; + OS << "Input was:\n<<<<<<\n"; // Sort annotations. std::sort(Annotations.begin(), Annotations.end(), @@ -455,21 +561,53 @@ LabelWidth = std::max(LabelWidth, LineNoWidth) + 3; // Print annotated input lines. + unsigned PrevLineInFilter = 0; // 0 means none so far + unsigned NextLineInFilter = 0; // 0 means uncomputed, UINT_MAX means none + std::string ElidedLines; + raw_string_ostream ElidedLinesOS(ElidedLines); + ColorMode TheColorMode = + WithColor(OS).colorsEnabled() ? ColorMode::Enable : ColorMode::Disable; + if (TheColorMode == ColorMode::Enable) + ElidedLinesOS.enable_colors(true); auto AnnotationItr = Annotations.begin(), AnnotationEnd = Annotations.end(); for (unsigned Line = 1; InputFilePtr != InputFileEnd || AnnotationItr != AnnotationEnd; ++Line) { const unsigned char *InputFileLine = InputFilePtr; + // Compute the previous and next line included by the filter. + if (NextLineInFilter < Line) + NextLineInFilter = FindInputLineInFilter(DumpInputFilter, Line, + AnnotationItr, AnnotationEnd); + assert(NextLineInFilter && "expected NextLineInFilter to be computed"); + if (NextLineInFilter == Line) + PrevLineInFilter = Line; + + // Elide this input line and its annotations if it's not within the + // context specified by -dump-input-context of an input line included by + // -dump-input-filter. However, in case the resulting ellipsis would occupy + // more lines than the input lines and annotations it elides, buffer the + // elided lines and annotations so we can print them instead. + raw_ostream *LineOS = &OS; + if ((!PrevLineInFilter || PrevLineInFilter + DumpInputContext < Line) && + (NextLineInFilter == UINT_MAX || + Line + DumpInputContext < NextLineInFilter)) + LineOS = &ElidedLinesOS; + else { + LineOS = &OS; + DumpEllipsisOrElidedLines(OS, ElidedLinesOS.str(), LabelWidth); + } + // Print right-aligned line number. - WithColor(OS, raw_ostream::BLACK, true) + WithColor(*LineOS, raw_ostream::BLACK, /*Bold=*/true, /*BF=*/false, + TheColorMode) << format_decimal(Line, LabelWidth) << ": "; // For the case where -v and colors are enabled, find the annotations for // good matches for expected patterns in order to highlight everything // else in the line. There are no such annotations if -v is disabled. std::vector FoundAndExpectedMatches; - if (Req.Verbose && WithColor(OS).colorsEnabled()) { + if (Req.Verbose && TheColorMode == ColorMode::Enable) { for (auto I = AnnotationItr; I != AnnotationEnd && I->InputLine == Line; ++I) { if (I->FoundAndExpectedMatch) @@ -481,7 +619,8 @@ // expected patterns. bool Newline = false; { - WithColor COS(OS); + WithColor COS(*LineOS, raw_ostream::SAVEDCOLOR, /*Bold=*/false, + /*BG=*/false, TheColorMode); bool InMatch = false; if (Req.Verbose) COS.changeColor(raw_ostream::CYAN, true, true); @@ -505,13 +644,14 @@ ++InputFilePtr; } } - OS << '\n'; + *LineOS << '\n'; unsigned InputLineWidth = InputFilePtr - InputFileLine - Newline; // Print any annotations. while (AnnotationItr != AnnotationEnd && AnnotationItr->InputLine == Line) { - WithColor COS(OS, AnnotationItr->Marker.Color, true); + WithColor COS(*LineOS, AnnotationItr->Marker.Color, /*Bold=*/true, + /*BG=*/false, TheColorMode); // The two spaces below are where the ": " appears on input lines. COS << left_justify(AnnotationItr->Label, LabelWidth) << " "; unsigned Col; @@ -536,6 +676,7 @@ ++AnnotationItr; } } + DumpEllipsisOrElidedLines(OS, ElidedLinesOS.str(), LabelWidth); OS << ">>>>>>\n"; } @@ -548,10 +689,27 @@ InitLLVM X(argc, argv); cl::ParseCommandLineOptions(argc, argv, /*Overview*/ "", /*Errs*/ nullptr, "FILECHECK_OPTS"); + + // Select -dump-input* values. The -help documentation specifies the default + // value and which value to choose if an option is specified multiple times. + // In the latter case, the general rule of thumb is to choose the value that + // provides the most information. DumpInputValue DumpInput = DumpInputs.empty() ? DumpInputFail : *std::max_element(DumpInputs.begin(), DumpInputs.end()); + DumpInputFilterValue DumpInputFilter; + if (DumpInputFilters.empty()) + DumpInputFilter = DumpInput == DumpInputAlways ? DumpInputFilterAll + : DumpInputFilterError; + else + DumpInputFilter = + *std::max_element(DumpInputFilters.begin(), DumpInputFilters.end()); + unsigned DumpInputContext = DumpInputContexts.empty() + ? 5 + : *std::max_element(DumpInputContexts.begin(), + DumpInputContexts.end()); + if (DumpInput == DumpInputHelp) { DumpInputAnnotationHelp(outs()); return 0; @@ -675,18 +833,17 @@ if (DumpInput == DumpInputAlways || (ExitCode == 1 && DumpInput == DumpInputFail)) { errs() << "\n" - << "Input file: " - << InputFilename - << "\n" + << "Input file: " << InputFilename << "\n" << "Check file: " << CheckFilename << "\n" << "\n" - << "-dump-input=help describes the format of the following dump.\n" + << "-dump-input=help explains the following input dump.\n" << "\n"; std::vector Annotations; unsigned LabelWidth; BuildInputAnnotations(SM, CheckFileBufferID, ImpPatBufferIDRange, Diags, Annotations, LabelWidth); - DumpAnnotatedInput(errs(), Req, InputFileText, Annotations, LabelWidth); + DumpAnnotatedInput(errs(), Req, DumpInputFilter, DumpInputContext, + InputFileText, Annotations, LabelWidth); } return ExitCode;