forked from OSchip/llvm-project
[FileCheck] Support comment directives
Sometimes you want to disable a FileCheck directive without removing it entirely, or you want to write comments that mention a directive by name. The `COM:` directive makes it easy to do this. For example, you might have: ``` ; X32: pinsrd_1: ; X32: pinsrd $1, 4(%esp), %xmm0 ; COM: FIXME: X64 isn't working correctly yet for this part of codegen, but ; COM: X64 will have something similar to X32: ; COM: ; COM: X64: pinsrd_1: ; COM: X64: pinsrd $1, %edi, %xmm0 ``` Without this patch, you need to use some combination of rewording and directive syntax mangling to prevent FileCheck from recognizing the commented occurrences of `X32:` and `X64:` above as directives. Moreover, FileCheck diagnostics have been proposed that might complain about the occurrences of `X64` that don't have the trailing `:` because they look like directive typos: <http://lists.llvm.org/pipermail/llvm-dev/2020-April/140610.html> I think dodging all these problems can prove tedious for test authors, and directive syntax mangling already makes the purpose of existing test code unclear. `COM:` can avoid all these problems. This patch also updates the small set of existing tests that define `COM` as a check prefix: - clang/test/CodeGen/default-address-space.c - clang/test/CodeGenOpenCL/addr-space-struct-arg.cl - clang/test/Driver/hip-device-libs.hip - llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll I think lit should support `COM:` as well. Perhaps `clang -verify` should too. Reviewed By: jhenderson, thopre Differential Revision: https://reviews.llvm.org/D79276
This commit is contained in:
parent
1370757dd0
commit
a1fd188223
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -triple amdgcn---amdgiz -emit-llvm < %s | FileCheck -check-prefixes=CHECK,COM %s
|
||||
// RUN: %clang_cc1 -triple amdgcn---amdgiz -emit-llvm < %s | FileCheck -check-prefixes=CHECK %s
|
||||
|
||||
// CHECK-DAG: @foo = addrspace(1) global i32 0
|
||||
int foo;
|
||||
|
@ -11,17 +11,17 @@ int ban[10];
|
|||
int *A;
|
||||
int *B;
|
||||
|
||||
// COM-LABEL: define i32 @test1()
|
||||
// CHECK-LABEL: define i32 @test1()
|
||||
// CHECK: load i32, i32* addrspacecast{{[^@]+}} @foo
|
||||
int test1() { return foo; }
|
||||
|
||||
// COM-LABEL: define i32 @test2(i32 %i)
|
||||
// COM: %[[addr:.*]] = getelementptr
|
||||
// CHECK-LABEL: define i32 @test2(i32 %i)
|
||||
// CHECK: %[[addr:.*]] = getelementptr
|
||||
// CHECK: load i32, i32* %[[addr]]
|
||||
// CHECK-NEXT: ret i32
|
||||
int test2(int i) { return ban[i]; }
|
||||
|
||||
// COM-LABEL: define void @test3()
|
||||
// CHECK-LABEL: define void @test3()
|
||||
// CHECK: load i32*, i32** addrspacecast{{.*}} @B
|
||||
// CHECK: load i32, i32*
|
||||
// CHECK: load i32*, i32** addrspacecast{{.*}} @A
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -ffake-address-space-map -triple i686-pc-darwin | FileCheck -enable-var-scope -check-prefixes=COM,X86 %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL2.0 -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=COM,AMDGCN,AMDGCN20 %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -ffake-address-space-map -triple i686-pc-darwin | FileCheck -enable-var-scope -check-prefixes=ALL,X86 %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL2.0 -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN,AMDGCN20 %s
|
||||
// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL1.2 -O0 -triple spir-unknown-unknown-unknown | FileCheck -enable-var-scope -check-prefixes=SPIR %s
|
||||
|
||||
typedef int int2 __attribute__((ext_vector_type(2)));
|
||||
|
@ -50,7 +50,7 @@ Mat4X4 __attribute__((noinline)) foo(Mat3X3 in) {
|
|||
return out;
|
||||
}
|
||||
|
||||
// COM-LABEL: define {{.*}} void @ker
|
||||
// ALL-LABEL: define {{.*}} void @ker
|
||||
// Expect two mem copies: one for the argument "in", and one for
|
||||
// the return value.
|
||||
// X86: call void @llvm.memcpy.p0i8.p1i8.i32(i8*
|
||||
|
@ -70,7 +70,7 @@ Mat64X64 __attribute__((noinline)) foo_large(Mat32X32 in) {
|
|||
return out;
|
||||
}
|
||||
|
||||
// COM-LABEL: define {{.*}} void @ker_large
|
||||
// ALL-LABEL: define {{.*}} void @ker_large
|
||||
// Expect two mem copies: one for the argument "in", and one for
|
||||
// the return value.
|
||||
// X86: call void @llvm.memcpy.p0i8.p1i8.i32(i8*
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// RUN: --cuda-gpu-arch=gfx803 \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,FLUSHD
|
||||
|
||||
|
||||
// Test subtarget with flushing off by ddefault.
|
||||
|
@ -18,7 +18,7 @@
|
|||
// RUN: --cuda-gpu-arch=gfx900 \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,NOFLUSHD
|
||||
|
||||
|
||||
// Test explicit flag, opposite of target default.
|
||||
|
@ -27,7 +27,7 @@
|
|||
// RUN: -fcuda-flush-denormals-to-zero \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,FLUSHD
|
||||
|
||||
|
||||
// Test explicit flag, opposite of target default.
|
||||
|
@ -36,7 +36,7 @@
|
|||
// RUN: -fno-cuda-flush-denormals-to-zero \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,NOFLUSHD
|
||||
|
||||
|
||||
// Test explicit flag, same as target default.
|
||||
|
@ -45,7 +45,7 @@
|
|||
// RUN: -fno-cuda-flush-denormals-to-zero \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,NOFLUSHD
|
||||
|
||||
|
||||
// Test explicit flag, same as target default.
|
||||
|
@ -54,7 +54,7 @@
|
|||
// RUN: -fcuda-flush-denormals-to-zero \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,FLUSHD
|
||||
|
||||
|
||||
// Test last flag wins, not flushing
|
||||
|
@ -63,7 +63,7 @@
|
|||
// RUN: -fcuda-flush-denormals-to-zero -fno-cuda-flush-denormals-to-zero \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,NOFLUSHD
|
||||
|
||||
|
||||
// RUN: %clang -### -target x86_64-linux-gnu \
|
||||
|
@ -71,7 +71,7 @@
|
|||
// RUN: -fcuda-flush-denormals-to-zero -fno-cuda-flush-denormals-to-zero \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,NOFLUSHD
|
||||
|
||||
|
||||
// RUN: %clang -### -target x86_64-linux-gnu \
|
||||
|
@ -79,7 +79,7 @@
|
|||
// RUN: -fno-cuda-flush-denormals-to-zero -fcuda-flush-denormals-to-zero \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,FLUSHD
|
||||
|
||||
|
||||
// RUN: %clang -### -target x86_64-linux-gnu \
|
||||
|
@ -87,7 +87,7 @@
|
|||
// RUN: -fno-cuda-flush-denormals-to-zero -fcuda-flush-denormals-to-zero \
|
||||
// RUN: --rocm-path=%S/Inputs/rocm-device-libs \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,FLUSHD
|
||||
|
||||
|
||||
// Test --hip-device-lib-path flag
|
||||
|
@ -95,7 +95,7 @@
|
|||
// RUN: --cuda-gpu-arch=gfx803 \
|
||||
// RUN: --hip-device-lib-path=%S/Inputs/rocm-device-libs/amdgcn/bitcode \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL,FLUSHD
|
||||
|
||||
|
||||
// Test environment variable HIP_DEVICE_LIB_PATH
|
||||
|
@ -103,18 +103,18 @@
|
|||
// RUN: %clang -### -target x86_64-linux-gnu \
|
||||
// RUN: --cuda-gpu-arch=gfx900 \
|
||||
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM
|
||||
// RUN: 2>&1 | FileCheck %s --check-prefixes=ALL
|
||||
|
||||
// COM: {{"[^"]*clang[^"]*"}}
|
||||
// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}hip.bc"
|
||||
// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}ocml.bc"
|
||||
// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}ockl.bc"
|
||||
// ALL: {{"[^"]*clang[^"]*"}}
|
||||
// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}hip.bc"
|
||||
// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}ocml.bc"
|
||||
// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}ockl.bc"
|
||||
|
||||
// FLUSHD-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_daz_opt_on.bc"
|
||||
// NOFLUSHD-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_daz_opt_off.bc"
|
||||
|
||||
// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_unsafe_math_off.bc"
|
||||
// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_finite_only_off.bc"
|
||||
// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_correctly_rounded_sqrt_on.bc"
|
||||
// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_wavefrontsize64_on.bc"
|
||||
// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_isa_version_{{[0-9]+}}.bc"
|
||||
// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_unsafe_math_off.bc"
|
||||
// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_finite_only_off.bc"
|
||||
// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_correctly_rounded_sqrt_on.bc"
|
||||
// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_wavefrontsize64_on.bc"
|
||||
// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_isa_version_{{[0-9]+}}.bc"
|
||||
|
|
|
@ -39,15 +39,31 @@ and from the command line.
|
|||
match. By default, these patterns are prefixed with "``CHECK:``".
|
||||
If you'd like to use a different prefix (e.g. because the same input
|
||||
file is checking multiple different tool or options), the
|
||||
:option:`--check-prefix` argument allows you to specify one or more
|
||||
prefixes to match. Multiple prefixes are useful for tests which might
|
||||
change for different run options, but most lines remain the same.
|
||||
:option:`--check-prefix` argument allows you to specify (without the trailing
|
||||
"``:``") one or more prefixes to match. Multiple prefixes are useful for tests
|
||||
which might change for different run options, but most lines remain the same.
|
||||
|
||||
FileCheck does not permit duplicate prefixes, even if one is a check prefix
|
||||
and one is a comment prefix (see :option:`--comment-prefixes` below).
|
||||
|
||||
.. option:: --check-prefixes prefix1,prefix2,...
|
||||
|
||||
An alias of :option:`--check-prefix` that allows multiple prefixes to be
|
||||
specified as a comma separated list.
|
||||
|
||||
.. option:: --comment-prefixes prefix1,prefix2,...
|
||||
|
||||
By default, FileCheck ignores any occurrence in ``match-filename`` of any check
|
||||
prefix if it is preceded on the same line by "``COM:``" or "``RUN:``". See the
|
||||
section `The "COM:" directive`_ for usage details.
|
||||
|
||||
These default comment prefixes can be overridden by
|
||||
:option:`--comment-prefixes` if they are not appropriate for your testing
|
||||
environment. However, doing so is not recommended in LLVM's LIT-based test
|
||||
suites, which should be easier to maintain if they all follow a consistent
|
||||
comment style. In that case, consider proposing a change to the default
|
||||
comment prefixes instead.
|
||||
|
||||
.. option:: --input-file filename
|
||||
|
||||
File to check (defaults to stdin).
|
||||
|
@ -236,6 +252,57 @@ circumstances, for example, testing different architectural variants with
|
|||
In this case, we're testing that we get the expected code generation with
|
||||
both 32-bit and 64-bit code generation.
|
||||
|
||||
The "COM:" directive
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes you want to disable a FileCheck directive without removing it
|
||||
entirely, or you want to write comments that mention a directive by name. The
|
||||
"``COM:``" directive makes it easy to do this. For example, you might have:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
; X32: pinsrd_1:
|
||||
; X32: pinsrd $1, 4(%esp), %xmm0
|
||||
|
||||
; COM: FIXME: X64 isn't working correctly yet for this part of codegen, but
|
||||
; COM: X64 will have something similar to X32:
|
||||
; COM:
|
||||
; COM: X64: pinsrd_1:
|
||||
; COM: X64: pinsrd $1, %edi, %xmm0
|
||||
|
||||
Without "``COM:``", you would need to use some combination of rewording and
|
||||
directive syntax mangling to prevent FileCheck from recognizing the commented
|
||||
occurrences of "``X32:``" and "``X64:``" above as directives. Moreover,
|
||||
FileCheck diagnostics have been proposed that might complain about the above
|
||||
occurrences of "``X64``" that don't have the trailing "``:``" because they look
|
||||
like directive typos. Dodging all these problems can be tedious for a test
|
||||
author, and directive syntax mangling can make the purpose of test code unclear.
|
||||
"``COM:``" avoids all these problems.
|
||||
|
||||
A few important usage notes:
|
||||
|
||||
* "``COM:``" within another directive's pattern does *not* comment out the
|
||||
remainder of the pattern. For example:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
; X32: pinsrd $1, 4(%esp), %xmm0 COM: This is part of the X32 pattern!
|
||||
|
||||
If you need to temporarily comment out part of a directive's pattern, move it
|
||||
to another line. The reason is that FileCheck parses "``COM:``" in the same
|
||||
manner as any other directive: only the first directive on the line is
|
||||
recognized as a directive.
|
||||
|
||||
* For the sake of LIT, FileCheck treats "``RUN:``" just like "``COM:``". If this
|
||||
is not suitable for your test environment, see :option:`--comment-prefixes`.
|
||||
|
||||
* FileCheck does not recognize "``COM``", "``RUN``", or any user-defined comment
|
||||
prefix as a comment directive if it's combined with one of the usual check
|
||||
directive suffixes, such as "``-NEXT:``" or "``-NOT:``", discussed below.
|
||||
FileCheck treats such a combination as plain text instead. If it needs to act
|
||||
as a comment directive for your test environment, define it as such with
|
||||
:option:`--comment-prefixes`.
|
||||
|
||||
The "CHECK-NEXT:" directive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace llvm {
|
|||
/// Contains info about various FileCheck options.
|
||||
struct FileCheckRequest {
|
||||
std::vector<StringRef> CheckPrefixes;
|
||||
std::vector<StringRef> CommentPrefixes;
|
||||
bool NoCanonicalizeWhiteSpace = false;
|
||||
std::vector<StringRef> ImplicitCheckNot;
|
||||
std::vector<StringRef> GlobalDefines;
|
||||
|
@ -53,6 +54,7 @@ enum FileCheckKind {
|
|||
CheckDAG,
|
||||
CheckLabel,
|
||||
CheckEmpty,
|
||||
CheckComment,
|
||||
|
||||
/// Indicates the pattern only matches the end of file. This is used for
|
||||
/// trailing CHECK-NOTs.
|
||||
|
|
|
@ -1110,6 +1110,8 @@ std::string Check::FileCheckType::getDescription(StringRef Prefix) const {
|
|||
return Prefix.str() + "-LABEL";
|
||||
case Check::CheckEmpty:
|
||||
return Prefix.str() + "-EMPTY";
|
||||
case Check::CheckComment:
|
||||
return std::string(Prefix);
|
||||
case Check::CheckEOF:
|
||||
return "implicit EOF";
|
||||
case Check::CheckBadNot:
|
||||
|
@ -1121,13 +1123,24 @@ std::string Check::FileCheckType::getDescription(StringRef Prefix) const {
|
|||
}
|
||||
|
||||
static std::pair<Check::FileCheckType, StringRef>
|
||||
FindCheckType(StringRef Buffer, StringRef Prefix) {
|
||||
FindCheckType(const FileCheckRequest &Req, StringRef Buffer, StringRef Prefix) {
|
||||
if (Buffer.size() <= Prefix.size())
|
||||
return {Check::CheckNone, StringRef()};
|
||||
|
||||
char NextChar = Buffer[Prefix.size()];
|
||||
|
||||
StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
|
||||
|
||||
// Check for comment.
|
||||
if (Req.CommentPrefixes.end() != std::find(Req.CommentPrefixes.begin(),
|
||||
Req.CommentPrefixes.end(),
|
||||
Prefix)) {
|
||||
if (NextChar == ':')
|
||||
return {Check::CheckComment, Rest};
|
||||
// Ignore a comment prefix if it has a suffix like "-NOT".
|
||||
return {Check::CheckNone, StringRef()};
|
||||
}
|
||||
|
||||
// Verify that the : is present after the prefix.
|
||||
if (NextChar == ':')
|
||||
return {Check::CheckPlain, Rest};
|
||||
|
@ -1206,8 +1219,9 @@ static size_t SkipWord(StringRef Str, size_t Loc) {
|
|||
/// If no valid prefix is found, the state of Buffer, LineNumber, and CheckTy
|
||||
/// is unspecified.
|
||||
static std::pair<StringRef, StringRef>
|
||||
FindFirstMatchingPrefix(Regex &PrefixRE, StringRef &Buffer,
|
||||
unsigned &LineNumber, Check::FileCheckType &CheckTy) {
|
||||
FindFirstMatchingPrefix(const FileCheckRequest &Req, Regex &PrefixRE,
|
||||
StringRef &Buffer, unsigned &LineNumber,
|
||||
Check::FileCheckType &CheckTy) {
|
||||
SmallVector<StringRef, 2> Matches;
|
||||
|
||||
while (!Buffer.empty()) {
|
||||
|
@ -1235,7 +1249,7 @@ FindFirstMatchingPrefix(Regex &PrefixRE, StringRef &Buffer,
|
|||
if (Skipped.empty() || !IsPartOfWord(Skipped.back())) {
|
||||
// Now extract the type.
|
||||
StringRef AfterSuffix;
|
||||
std::tie(CheckTy, AfterSuffix) = FindCheckType(Buffer, Prefix);
|
||||
std::tie(CheckTy, AfterSuffix) = FindCheckType(Req, Buffer, Prefix);
|
||||
|
||||
// If we've found a valid check type for this prefix, we're done.
|
||||
if (CheckTy != Check::CheckNone)
|
||||
|
@ -1316,7 +1330,7 @@ bool FileCheck::readCheckFile(
|
|||
// found.
|
||||
unsigned LineNumber = 1;
|
||||
|
||||
bool FoundUsedPrefix = false;
|
||||
bool FoundUsedCheckPrefix = false;
|
||||
while (1) {
|
||||
Check::FileCheckType CheckTy;
|
||||
|
||||
|
@ -1324,10 +1338,11 @@ bool FileCheck::readCheckFile(
|
|||
StringRef UsedPrefix;
|
||||
StringRef AfterSuffix;
|
||||
std::tie(UsedPrefix, AfterSuffix) =
|
||||
FindFirstMatchingPrefix(PrefixRE, Buffer, LineNumber, CheckTy);
|
||||
FindFirstMatchingPrefix(Req, PrefixRE, Buffer, LineNumber, CheckTy);
|
||||
if (UsedPrefix.empty())
|
||||
break;
|
||||
FoundUsedPrefix = true;
|
||||
if (CheckTy != Check::CheckComment)
|
||||
FoundUsedCheckPrefix = true;
|
||||
|
||||
assert(UsedPrefix.data() == Buffer.data() &&
|
||||
"Failed to move Buffer's start forward, or pointed prefix outside "
|
||||
|
@ -1370,9 +1385,17 @@ bool FileCheck::readCheckFile(
|
|||
// Remember the location of the start of the pattern, for diagnostics.
|
||||
SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
|
||||
|
||||
// Extract the pattern from the buffer.
|
||||
StringRef PatternBuffer = Buffer.substr(0, EOL);
|
||||
Buffer = Buffer.substr(EOL);
|
||||
|
||||
// If this is a comment, we're done.
|
||||
if (CheckTy == Check::CheckComment)
|
||||
continue;
|
||||
|
||||
// Parse the pattern.
|
||||
Pattern P(CheckTy, PatternContext.get(), LineNumber);
|
||||
if (P.parsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, Req))
|
||||
if (P.parsePattern(PatternBuffer, UsedPrefix, SM, Req))
|
||||
return true;
|
||||
|
||||
// Verify that CHECK-LABEL lines do not define or use variables
|
||||
|
@ -1384,8 +1407,6 @@ bool FileCheck::readCheckFile(
|
|||
return true;
|
||||
}
|
||||
|
||||
Buffer = Buffer.substr(EOL);
|
||||
|
||||
// Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them.
|
||||
if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame ||
|
||||
CheckTy == Check::CheckEmpty) &&
|
||||
|
@ -1414,7 +1435,7 @@ bool FileCheck::readCheckFile(
|
|||
|
||||
// When there are no used prefixes we report an error except in the case that
|
||||
// no prefix is specified explicitly but -implicit-check-not is specified.
|
||||
if (!FoundUsedPrefix &&
|
||||
if (!FoundUsedCheckPrefix &&
|
||||
(ImplicitNegativeChecks.empty() || !Req.IsDefaultCheckPrefix)) {
|
||||
errs() << "error: no check strings found with prefix"
|
||||
<< (Req.CheckPrefixes.size() > 1 ? "es " : " ");
|
||||
|
@ -1874,50 +1895,76 @@ size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
|
|||
return StartPos;
|
||||
}
|
||||
|
||||
static bool ValidatePrefixes(StringSet<> &UniquePrefixes,
|
||||
static bool ValidatePrefixes(StringRef Kind, StringSet<> &UniquePrefixes,
|
||||
ArrayRef<StringRef> SuppliedPrefixes) {
|
||||
for (StringRef Prefix : SuppliedPrefixes) {
|
||||
if (Prefix.empty()) {
|
||||
errs() << "error: supplied check prefix must not be the empty string\n";
|
||||
errs() << "error: supplied " << Kind << " prefix must not be the empty "
|
||||
<< "string\n";
|
||||
return false;
|
||||
}
|
||||
static const Regex Validator("^[a-zA-Z0-9_-]*$");
|
||||
if (!Validator.match(Prefix)) {
|
||||
errs() << "error: supplied check prefix must start with a letter and "
|
||||
<< "contain only alphanumeric characters, hyphens, and "
|
||||
errs() << "error: supplied " << Kind << " prefix must start with a "
|
||||
<< "letter and contain only alphanumeric characters, hyphens, and "
|
||||
<< "underscores: '" << Prefix << "'\n";
|
||||
return false;
|
||||
}
|
||||
if (!UniquePrefixes.insert(Prefix).second) {
|
||||
errs() << "error: supplied check prefix must be unique among check "
|
||||
<< "prefixes: '" << Prefix << "'\n";
|
||||
errs() << "error: supplied " << Kind << " prefix must be unique among "
|
||||
<< "check and comment prefixes: '" << Prefix << "'\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *DefaultCheckPrefixes[] = {"CHECK"};
|
||||
static const char *DefaultCommentPrefixes[] = {"COM", "RUN"};
|
||||
|
||||
bool FileCheck::ValidateCheckPrefixes() {
|
||||
StringSet<> UniquePrefixes;
|
||||
if (!ValidatePrefixes(UniquePrefixes, Req.CheckPrefixes))
|
||||
// Add default prefixes to catch user-supplied duplicates of them below.
|
||||
if (Req.CheckPrefixes.empty()) {
|
||||
for (const char *Prefix : DefaultCheckPrefixes)
|
||||
UniquePrefixes.insert(Prefix);
|
||||
}
|
||||
if (Req.CommentPrefixes.empty()) {
|
||||
for (const char *Prefix : DefaultCommentPrefixes)
|
||||
UniquePrefixes.insert(Prefix);
|
||||
}
|
||||
// Do not validate the default prefixes, or diagnostics about duplicates might
|
||||
// incorrectly indicate that they were supplied by the user.
|
||||
if (!ValidatePrefixes("check", UniquePrefixes, Req.CheckPrefixes))
|
||||
return false;
|
||||
if (!ValidatePrefixes("comment", UniquePrefixes, Req.CommentPrefixes))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Regex FileCheck::buildCheckPrefixRegex() {
|
||||
if (Req.CheckPrefixes.empty()) {
|
||||
Req.CheckPrefixes.push_back("CHECK");
|
||||
for (const char *Prefix : DefaultCheckPrefixes)
|
||||
Req.CheckPrefixes.push_back(Prefix);
|
||||
Req.IsDefaultCheckPrefix = true;
|
||||
}
|
||||
if (Req.CommentPrefixes.empty()) {
|
||||
for (const char *Prefix : DefaultCommentPrefixes)
|
||||
Req.CommentPrefixes.push_back(Prefix);
|
||||
}
|
||||
|
||||
// We already validated the contents of CheckPrefixes so just concatenate
|
||||
// them as alternatives.
|
||||
// We already validated the contents of CheckPrefixes and CommentPrefixes so
|
||||
// just concatenate them as alternatives.
|
||||
SmallString<32> PrefixRegexStr;
|
||||
for (size_t I = 0, E = Req.CheckPrefixes.size(); I != E; ++I) {
|
||||
if (I != 0)
|
||||
PrefixRegexStr.push_back('|');
|
||||
PrefixRegexStr.append(Req.CheckPrefixes[I]);
|
||||
}
|
||||
for (StringRef Prefix : Req.CommentPrefixes) {
|
||||
PrefixRegexStr.push_back('|');
|
||||
PrefixRegexStr.append(Prefix);
|
||||
}
|
||||
|
||||
return Regex(PrefixRegexStr);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
; RUN: llvm-as < %s -o %t.bc -data-layout=A5 2>&1 | FileCheck -check-prefixes=COM,AS %s
|
||||
; RUN: llvm-dis < %t.bc | FileCheck -check-prefixes=COM,DIS %s
|
||||
; RUN: opt < %s -S -data-layout=A5 2>&1 | FileCheck -check-prefixes=COM,AS %s
|
||||
; RUN: opt < %t.bc -S | FileCheck -check-prefixes=COM,DIS %s
|
||||
; RUN: llvm-as < %s -o %t.bc -data-layout=A5 2>&1 | FileCheck -check-prefixes=ALL,AS %s
|
||||
; RUN: llvm-dis < %t.bc | FileCheck -check-prefixes=ALL,DIS %s
|
||||
; RUN: opt < %s -S -data-layout=A5 2>&1 | FileCheck -check-prefixes=ALL,AS %s
|
||||
; RUN: opt < %t.bc -S | FileCheck -check-prefixes=ALL,DIS %s
|
||||
|
||||
define void @foo() {
|
||||
entry:
|
||||
|
@ -12,7 +12,7 @@ entry:
|
|||
metadata i8* undef,
|
||||
metadata !DILocalVariable(scope: !1),
|
||||
metadata !DIExpression())
|
||||
; COM-NOT: Allocation instruction pointer not in the stack address space!
|
||||
; ALL-NOT: Allocation instruction pointer not in the stack address space!
|
||||
; AS: llvm.dbg.value intrinsic requires a !dbg attachment
|
||||
; AS: warning: ignoring invalid debug info in <stdin>
|
||||
ret void
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# Comment prefixes are not recognized at ends of words.
|
||||
|
||||
RUN: echo 'foo' > %t.in
|
||||
RUN: echo 'bar' >> %t.in
|
||||
RUN: echo 'foo' >> %t.in
|
||||
RUN: echo 'bar' >> %t.in
|
||||
RUN: echo 'FOO-COM: CHECK: foo' > %t.chk
|
||||
RUN: echo 'RUN_COM: CHECK: bar' >> %t.chk
|
||||
RUN: echo 'RUN3COM: CHECK: foo' >> %t.chk
|
||||
RUN: echo ' COMRUN: CHECK: bar' >> %t.chk
|
||||
RUN: %ProtectFileCheckOutput FileCheck -vv %t.chk < %t.in 2>&1 | FileCheck %s
|
||||
|
||||
CHECK: .chk:1:17: remark: CHECK: expected string found in input
|
||||
CHECK: .chk:2:17: remark: CHECK: expected string found in input
|
||||
CHECK: .chk:3:17: remark: CHECK: expected string found in input
|
||||
CHECK: .chk:4:17: remark: CHECK: expected string found in input
|
|
@ -0,0 +1,48 @@
|
|||
# Bad comment prefixes are diagnosed.
|
||||
|
||||
# Check empty comment prefix.
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -comment-prefixes= | \
|
||||
RUN: FileCheck -check-prefix=PREFIX-EMPTY %s
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -comment-prefixes=,FOO | \
|
||||
RUN: FileCheck -check-prefix=PREFIX-EMPTY %s
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -comment-prefixes=FOO, | \
|
||||
RUN: FileCheck -check-prefix=PREFIX-EMPTY %s
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -comment-prefixes=FOO,,BAR | \
|
||||
RUN: FileCheck -check-prefix=PREFIX-EMPTY %s
|
||||
PREFIX-EMPTY: error: supplied comment prefix must not be the empty string
|
||||
|
||||
# Check invalid characters in comment prefix.
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -comment-prefixes=. | \
|
||||
RUN: FileCheck -check-prefix=PREFIX-BAD-CHAR1 %s
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -comment-prefixes='foo ' | \
|
||||
RUN: FileCheck -check-prefix=PREFIX-BAD-CHAR2 %s
|
||||
PREFIX-BAD-CHAR1: error: supplied comment prefix must start with a letter and contain only alphanumeric characters, hyphens, and underscores: '.'
|
||||
PREFIX-BAD-CHAR2: error: supplied comment prefix must start with a letter and contain only alphanumeric characters, hyphens, and underscores: 'foo '
|
||||
|
||||
# Check duplicate comment prefixes.
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -comment-prefixes=FOO,BAR,BAZ,BAR | \
|
||||
RUN: FileCheck -check-prefix=COMMENT-PREFIX-DUP %s
|
||||
COMMENT-PREFIX-DUP: error: supplied comment prefix must be unique among check and comment prefixes: 'BAR'
|
||||
|
||||
# Check user-supplied check prefix that duplicates a default comment prefix.
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -check-prefixes=FOO,COM | \
|
||||
RUN: FileCheck -check-prefix=CHECK-PREFIX-DUP-COM %s
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -check-prefixes=RUN,FOO | \
|
||||
RUN: FileCheck -check-prefix=CHECK-PREFIX-DUP-RUN_ %s
|
||||
CHECK-PREFIX-DUP-COM: error: supplied check prefix must be unique among check and comment prefixes: 'COM'
|
||||
CHECK-PREFIX-DUP-RUN_: error: supplied check prefix must be unique among check and comment prefixes: 'RUN'
|
||||
|
||||
# Check user-supplied comment prefix that duplicates default check prefixes.
|
||||
RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
|
||||
RUN: -comment-prefixes=CHECK | \
|
||||
RUN: FileCheck -check-prefix=COMMENT-PREFIX-DUP-CHECK %s
|
||||
COMMENT-PREFIX-DUP-CHECK: error: supplied comment prefix must be unique among check and comment prefixes: 'CHECK'
|
|
@ -0,0 +1,9 @@
|
|||
# Comment directives with blank contents are fine.
|
||||
|
||||
RUN: echo 'foo' > %t.in
|
||||
RUN: echo 'COM:' > %t.chk
|
||||
RUN: echo 'CHECK: foo' >> %t.chk
|
||||
RUN: echo ' COM: ' >> %t.chk
|
||||
RUN: %ProtectFileCheckOutput FileCheck -vv %t.chk < %t.in 2>&1 | FileCheck %s
|
||||
|
||||
CHECK: .chk:2:8: remark: CHECK: expected string found in input
|
|
@ -0,0 +1,22 @@
|
|||
# Comment prefixes plus check directive suffixes are not comment directives
|
||||
# and are treated as plain text.
|
||||
|
||||
RUN: echo foo > %t.in
|
||||
RUN: echo bar >> %t.in
|
||||
RUN: echo 'COM-NEXT: CHECK: foo' > %t.chk
|
||||
RUN: echo 'RUN-NOT: CHECK: bar' >> %t.chk
|
||||
|
||||
RUN: %ProtectFileCheckOutput FileCheck -vv %t.chk < %t.in 2>&1 | \
|
||||
RUN: FileCheck -check-prefix=CHECK1 %s
|
||||
|
||||
CHECK1: .chk:1:18: remark: CHECK: expected string found in input
|
||||
CHECK1: .chk:2:17: remark: CHECK: expected string found in input
|
||||
|
||||
# But we can define them as comment prefixes.
|
||||
|
||||
RUN: %ProtectFileCheckOutput \
|
||||
RUN: FileCheck -vv -comment-prefixes=COM,RUN,RUN-NOT %t.chk < %t.in 2>&1 | \
|
||||
RUN: FileCheck -check-prefix=CHECK2 %s
|
||||
|
||||
CHECK2: .chk:1:18: remark: CHECK: expected string found in input
|
||||
CHECK2-NOT: .chk:2
|
|
@ -0,0 +1,33 @@
|
|||
# Comment directives successfully comment out check directives.
|
||||
|
||||
# Check all default comment prefixes.
|
||||
# Check that a comment directive at the beginning/end of the file is handled.
|
||||
# Check that the preceding/following line's check directive is not affected.
|
||||
RUN: echo 'foo' > %t-1.in
|
||||
RUN: echo 'COM: CHECK: bar' > %t-1.chk
|
||||
RUN: echo 'CHECK: foo' >> %t-1.chk
|
||||
RUN: echo 'RUN: echo "CHECK: baz"' >> %t-1.chk
|
||||
RUN: %ProtectFileCheckOutput FileCheck -vv %t-1.chk < %t-1.in 2>&1 | \
|
||||
RUN: FileCheck -DCHECK_LINE=2 %s
|
||||
|
||||
# Check the case of one user-specified comment prefix.
|
||||
# Check that a comment directive not at the beginning of a line is handled.
|
||||
RUN: echo 'foo' > %t-2.in
|
||||
RUN: echo 'CHECK: foo' > %t-2.chk
|
||||
RUN: echo 'letters then space MY-PREFIX: CHECK: bar' >> %t-2.chk
|
||||
RUN: %ProtectFileCheckOutput \
|
||||
RUN: FileCheck -vv %t-2.chk -comment-prefixes=MY-PREFIX < %t-2.in 2>&1 | \
|
||||
RUN: FileCheck -DCHECK_LINE=1 %s
|
||||
|
||||
# Check the case of multiple user-specified comment prefixes.
|
||||
RUN: echo 'foo' > %t-3.in
|
||||
RUN: echo 'Bar_2: CHECK: Bar' > %t-3.chk
|
||||
RUN: echo 'CHECK: foo' >> %t-3.chk
|
||||
RUN: echo 'Foo_1: CHECK: Foo' >> %t-3.chk
|
||||
RUN: echo 'Baz_3: CHECK: Baz' >> %t-3.chk
|
||||
RUN: %ProtectFileCheckOutput \
|
||||
RUN: FileCheck -vv %t-3.chk -comment-prefixes=Foo_1,Bar_2 \
|
||||
RUN: -comment-prefixes=Baz_3 < %t-3.in 2>&1 | \
|
||||
RUN: FileCheck -DCHECK_LINE=2 %s
|
||||
|
||||
CHECK: .chk:[[CHECK_LINE]]:8: remark: CHECK: expected string found in input
|
|
@ -0,0 +1,8 @@
|
|||
# Comment directives do not suppress diagnostics for unused check prefixes.
|
||||
|
||||
RUN: echo 'foo' > %t.in
|
||||
RUN: echo 'COM: foo' > %t.chk
|
||||
RUN: echo 'RUN: echo' >> %t.chk
|
||||
RUN: %ProtectFileCheckOutput not FileCheck %t.chk < %t.in 2>&1 | FileCheck %s
|
||||
|
||||
CHECK: error: no check strings found with prefix 'CHECK:'
|
|
@ -0,0 +1,16 @@
|
|||
# Not using comment directives is always fine.
|
||||
|
||||
RUN: echo 'foo' > %t.in
|
||||
RUN: echo 'CHECK: foo' > %t.chk
|
||||
|
||||
# Check the case of default comment prefixes.
|
||||
RUN: %ProtectFileCheckOutput \
|
||||
RUN: FileCheck -vv %t.chk < %t.in 2>&1 | FileCheck %s
|
||||
|
||||
# Specifying non-default comment prefixes doesn't mean you have to use them.
|
||||
# For example, they might be applied to an entire test suite via
|
||||
# FILECHECK_OPTS or via a wrapper command or substitution.
|
||||
RUN: %ProtectFileCheckOutput \
|
||||
RUN: FileCheck -vv -comment-prefixes=FOO %t.chk < %t.in 2>&1 | FileCheck %s
|
||||
|
||||
CHECK: .chk:1:8: remark: CHECK: expected string found in input
|
|
@ -0,0 +1,8 @@
|
|||
# A comment directive is not recognized within a check directive's pattern and
|
||||
# thus does not comment out the remainder of the pattern.
|
||||
|
||||
RUN: echo 'foo' > %t.in
|
||||
RUN: echo 'CHECK: foo COM: bar' > %t.chk
|
||||
RUN: %ProtectFileCheckOutput not FileCheck %t.chk < %t.in 2>&1 | FileCheck %s
|
||||
|
||||
CHECK: .chk:1:8: error: CHECK: expected string not found in input
|
|
@ -1,2 +1,2 @@
|
|||
RUN: FileCheck -check-prefix=RUN -input-file %s %s
|
||||
RUN: FileCheck -check-prefix=RUN --comment-prefixes=COM -input-file %s %s
|
||||
// Prefix is at the first character in the file. The run line then matches itself.
|
||||
|
|
|
@ -8,6 +8,6 @@ foobar
|
|||
|
||||
; BAD_PREFIX: supplied check prefix must start with a letter and contain only alphanumeric characters, hyphens, and underscores: 'A!'
|
||||
|
||||
; DUPLICATE_PREFIX: error: supplied check prefix must be unique among check prefixes: 'REPEAT'
|
||||
; DUPLICATE_PREFIX: error: supplied check prefix must be unique among check and comment prefixes: 'REPEAT'
|
||||
|
||||
; EMPTY_PREFIX: error: supplied check prefix must not be the empty string
|
||||
|
|
|
@ -44,6 +44,14 @@ static cl::alias CheckPrefixesAlias(
|
|||
cl::desc(
|
||||
"Alias for -check-prefix permitting multiple comma separated values"));
|
||||
|
||||
static cl::list<std::string> CommentPrefixes(
|
||||
"comment-prefixes", cl::CommaSeparated, cl::Hidden,
|
||||
cl::desc("Comma-separated list of comment prefixes to use from check file\n"
|
||||
"(defaults to 'COM,RUN'). Please avoid using this feature in\n"
|
||||
"LLVM's LIT-based test suites, which should be easier to\n"
|
||||
"maintain if they all follow a consistent comment style. This\n"
|
||||
"feature is meant for non-LIT test suites using FileCheck."));
|
||||
|
||||
static cl::opt<bool> NoCanonicalizeWhiteSpace(
|
||||
"strict-whitespace",
|
||||
cl::desc("Do not treat all horizontal whitespace as equivalent"));
|
||||
|
@ -279,6 +287,8 @@ std::string GetCheckTypeAbbreviation(Check::FileCheckType Ty) {
|
|||
return "label";
|
||||
case Check::CheckEmpty:
|
||||
return "empty";
|
||||
case Check::CheckComment:
|
||||
return "com";
|
||||
case Check::CheckEOF:
|
||||
return "eof";
|
||||
case Check::CheckBadNot:
|
||||
|
@ -565,6 +575,9 @@ int main(int argc, char **argv) {
|
|||
for (StringRef Prefix : CheckPrefixes)
|
||||
Req.CheckPrefixes.push_back(Prefix);
|
||||
|
||||
for (StringRef Prefix : CommentPrefixes)
|
||||
Req.CommentPrefixes.push_back(Prefix);
|
||||
|
||||
for (StringRef CheckNot : ImplicitCheckNot)
|
||||
Req.ImplicitCheckNot.push_back(CheckNot);
|
||||
|
||||
|
|
Loading…
Reference in New Issue