jdenny updated this revision to Diff 261998.
jdenny added a comment.

Fixed a missed rename in the test code in the last update.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79276/new/

https://reviews.llvm.org/D79276

Files:
  clang/test/CodeGen/default-address-space.c
  clang/test/CodeGenOpenCL/addr-space-struct-arg.cl
  clang/test/Driver/hip-device-libs.hip
  llvm/docs/CommandGuide/FileCheck.rst
  llvm/include/llvm/Support/FileCheck.h
  llvm/lib/Support/FileCheck.cpp
  llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
  llvm/test/FileCheck/comment.txt
  llvm/test/FileCheck/first-character-match.txt
  llvm/test/FileCheck/validate-check-prefix.txt
  llvm/utils/FileCheck/FileCheck.cpp

Index: llvm/utils/FileCheck/FileCheck.cpp
===================================================================
--- llvm/utils/FileCheck/FileCheck.cpp
+++ llvm/utils/FileCheck/FileCheck.cpp
@@ -44,6 +44,14 @@
     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 @@
     return "label";
   case Check::CheckEmpty:
     return "empty";
+  case Check::CheckComment:
+    return "com";
   case Check::CheckEOF:
     return "eof";
   case Check::CheckBadNot:
@@ -565,6 +575,9 @@
   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);
 
Index: llvm/test/FileCheck/validate-check-prefix.txt
===================================================================
--- llvm/test/FileCheck/validate-check-prefix.txt
+++ llvm/test/FileCheck/validate-check-prefix.txt
@@ -8,6 +8,6 @@
 
 ; 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 prefixes and comment prefixes: 'REPEAT'
 
 ; EMPTY_PREFIX: error: supplied check prefix must not be the empty string
Index: llvm/test/FileCheck/first-character-match.txt
===================================================================
--- llvm/test/FileCheck/first-character-match.txt
+++ llvm/test/FileCheck/first-character-match.txt
@@ -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.
Index: llvm/test/FileCheck/comment.txt
===================================================================
--- /dev/null
+++ llvm/test/FileCheck/comment.txt
@@ -0,0 +1,176 @@
+// 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-supresses1.in
+// RUN: echo 'COM: CHECK: bar'        >  %t-supresses1.chk
+// RUN: echo 'CHECK: foo'             >> %t-supresses1.chk
+// RUN: echo 'RUN: echo "CHECK: baz"' >> %t-supresses1.chk
+// RUN: %ProtectFileCheckOutput \
+// RUN: FileCheck -vv %t-supresses1.chk < %t-supresses1.in 2>&1 \
+// RUN: | FileCheck -check-prefix=SUPPRESSES-CHECKS -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-suppresses2.in
+// RUN: echo 'CHECK: foo'                               >  %t-suppresses2.chk
+// RUN: echo 'letters then space MY-PREFIX: CHECK: bar' >> %t-suppresses2.chk
+// RUN: %ProtectFileCheckOutput \
+// RUN: FileCheck -vv %t-suppresses2.chk -comment-prefixes=MY-PREFIX \
+// RUN:           < %t-suppresses2.in 2>&1 \
+// RUN: | FileCheck -check-prefix=SUPPRESSES-CHECKS -DCHECK_LINE=1 %s
+//
+// Check the case of multiple user-specified comment prefixes.
+// RUN: echo 'foo'               >  %t-suppresses3.in
+// RUN: echo 'Bar_2: CHECK: Bar' >  %t-suppresses3.chk
+// RUN: echo 'CHECK: foo'        >> %t-suppresses3.chk
+// RUN: echo 'Foo_1: CHECK: Foo' >> %t-suppresses3.chk
+// RUN: echo 'Baz_3: CHECK: Baz' >> %t-suppresses3.chk
+// RUN: %ProtectFileCheckOutput \
+// RUN: FileCheck -vv %t-suppresses3.chk -comment-prefixes=Foo_1,Bar_2 \
+// RUN:           -comment-prefixes=Baz_3 < %t-suppresses3.in 2>&1 \
+// RUN: | FileCheck -check-prefix=SUPPRESSES-CHECKS -DCHECK_LINE=2 %s
+//
+// SUPPRESSES-CHECKS: .chk:[[CHECK_LINE]]:8: remark: CHECK: expected string found in input
+
+// 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-within.in
+// RUN: echo 'CHECK: foo COM: bar' > %t-within.chk
+// RUN: %ProtectFileCheckOutput \
+// RUN: not FileCheck %t-within.chk < %t-within.in 2>&1 \
+// RUN: | FileCheck -check-prefix=WITHIN-CHECKS %s
+//
+// WITHIN-CHECKS: .chk:1:8: error: CHECK: expected string not found in input
+
+// Comment directives with blank contents are fine.
+//
+// RUN: echo 'foo'        >  %t-blank.in
+// RUN: echo 'COM:'       >  %t-blank.chk
+// RUN: echo 'CHECK: foo' >> %t-blank.chk
+// RUN: echo ' COM: '     >> %t-blank.chk
+// RUN: %ProtectFileCheckOutput FileCheck -vv %t-blank.chk < %t-blank.in 2>&1 \
+// RUN: | FileCheck -check-prefix=BLANK-COMMENTS %s
+//
+// BLANK-COMMENTS: .chk:2:8: remark: CHECK: expected string found in input
+
+// Comment prefixes plus check directive suffixes are not comment directives
+// and are treated as plain text.
+//
+// RUN: echo foo                    >  %t-suffixes.in
+// RUN: echo bar                    >> %t-suffixes.in
+// RUN: echo 'COM-NEXT: CHECK: foo' >  %t-suffixes.chk
+// RUN: echo 'RUN-NOT: CHECK: bar'  >> %t-suffixes.chk
+//
+// RUN: %ProtectFileCheckOutput \
+// RUN: FileCheck -vv %t-suffixes.chk < %t-suffixes.in 2>&1 \
+// RUN: | FileCheck -check-prefix=SUFFIXES1 %s
+//
+// SUFFIXES1: .chk:1:18: remark: CHECK: expected string found in input
+// SUFFIXES1: .chk:2:17: remark: CHECK: expected string found in input
+//
+// But we can define them as comment prefixes.
+// RUN: %ProtectFileCheckOutput \
+// RUN: FileCheck -vv %t-suffixes.chk < %t-suffixes.in 2>&1 \
+// RUN:           -comment-prefixes=COM,RUN,RUN-NOT \
+// RUN: | FileCheck -check-prefix=SUFFIXES2 %s
+//
+// SUFFIXES2: .chk:1:18: remark: CHECK: expected string found in input
+// SUFFIXES2-NOT: .chk:2
+
+// Not using comment directives is always fine.
+//
+// RUN: echo 'foo'        > %t-unused-com.in
+// RUN: echo 'CHECK: foo' > %t-unused-com.chk
+//
+// Check the case of default comment prefixes.
+// RUN: %ProtectFileCheckOutput \
+// RUN: FileCheck -vv %t-unused-com.chk < %t-unused-com.in 2>&1 \
+// RUN: | FileCheck -check-prefix=UNUSED-COMMENT-PREFIXES %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 %t-unused-com.chk < %t-unused-com.in 2>&1 \
+// RUN:           -comment-prefixes=FOO \
+// RUN: | FileCheck -check-prefix=UNUSED-COMMENT-PREFIXES %s
+//
+// UNUSED-COMMENT-PREFIXES: .chk:1:8: remark: CHECK: expected string found in input
+
+// Comment directives do not suppress diagnostics for unused check prefixes.
+//
+// RUN: echo 'foo'       >  %t-unused-check.in
+// RUN: echo 'COM: foo'  >  %t-unused-check.chk
+// RUN: echo 'RUN: echo' >> %t-unused-check.chk
+// RUN: %ProtectFileCheckOutput \
+// RUN: not FileCheck %t-unused-check.chk < %t-unused-check.in 2>&1 \
+// RUN: | FileCheck -check-prefix=UNUSED-CHECK-PREFIXES %s
+//
+// UNUSED-CHECK-PREFIXES: error: no check strings found with prefix 'CHECK:'
+
+// Comment prefixes are not recognized at ends of words.
+//
+// RUN: echo 'foo'                 >  %t-after-words.in
+// RUN: echo 'bar'                 >> %t-after-words.in
+// RUN: echo 'foo'                 >> %t-after-words.in
+// RUN: echo 'bar'                 >> %t-after-words.in
+// RUN: echo 'FOO-COM: CHECK: foo' >  %t-after-words.chk
+// RUN: echo 'RUN_COM: CHECK: bar' >> %t-after-words.chk
+// RUN: echo 'RUN3COM: CHECK: foo' >> %t-after-words.chk
+// RUN: echo ' COMRUN: CHECK: bar' >> %t-after-words.chk
+// RUN: %ProtectFileCheckOutput \
+// RUN: FileCheck -vv %t-after-words.chk < %t-after-words.in 2>&1 \
+// RUN: | FileCheck -check-prefix=AFTER-WORDS %s
+//
+// AFTER-WORDS: .chk:1:17: remark: CHECK: expected string found in input
+// AFTER-WORDS: .chk:2:17: remark: CHECK: expected string found in input
+// AFTER-WORDS: .chk:3:17: remark: CHECK: expected string found in input
+// AFTER-WORDS: .chk:4:17: remark: CHECK: expected string found in input
+
+// 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
+// PREFIX-BAD-CHAR1: error: supplied comment prefix must start with a letter and contain only alphanumeric characters, hyphens, and underscores: '.'
+// RUN: %ProtectFileCheckOutput not FileCheck /dev/null < /dev/null 2>&1 \
+// RUN:                                       -comment-prefixes='foo ' \
+// RUN: | FileCheck -check-prefix=PREFIX-BAD-CHAR2 %s
+// 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 prefixes 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-COMMENT %s
+// CHECK-PREFIX-DUP-COMMENT: error: supplied check prefix must be unique among check prefixes and comment prefixes: 'COM'
+//
+// 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 prefixes and comment prefixes: 'CHECK'
Index: llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
===================================================================
--- llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
+++ llvm/test/Assembler/drop-debug-info-nonzero-alloca.ll
@@ -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 @@
       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
Index: llvm/lib/Support/FileCheck.cpp
===================================================================
--- llvm/lib/Support/FileCheck.cpp
+++ llvm/lib/Support/FileCheck.cpp
@@ -1110,6 +1110,8 @@
     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 @@
 }
 
 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 @@
 /// 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 @@
     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 @@
   // found.
   unsigned LineNumber = 1;
 
-  bool FoundUsedPrefix = false;
+  bool FoundUsedCheckPrefix = false;
   while (1) {
     Check::FileCheckType CheckTy;
 
@@ -1324,10 +1338,11 @@
     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 @@
     // 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 @@
       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 @@
 
   // 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 " : " ");
@@ -1880,22 +1901,23 @@
   return Validator.match(CheckPrefix);
 }
 
-static bool ValidatePrefixes(StringSet<> &PrefixSet,
+static bool ValidatePrefixes(StringRef Kind, StringSet<> &PrefixSet,
                              const std::vector<StringRef> &Prefixes) {
   for (StringRef Prefix : Prefixes) {
     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;
     }
     if (!ValidateCheckPrefix(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 (!PrefixSet.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 prefixes and comment prefixes: '" << Prefix << "'\n";
       return false;
     }
   }
@@ -1903,10 +1925,24 @@
 }
 
 static const char *DefaultCheckPrefixes[] = {"CHECK"};
+static const char *DefaultCommentPrefixes[] = {"COM", "RUN"};
 
 bool FileCheck::ValidateCheckPrefixes() {
   StringSet<> PrefixSet;
-  if (!ValidatePrefixes(PrefixSet, Req.CheckPrefixes))
+  // Add default prefixes to catch user-supplied duplicates of them below.
+  if (Req.CheckPrefixes.empty()) {
+    for (const char *Prefix : DefaultCheckPrefixes)
+      PrefixSet.insert(Prefix);
+  }
+  if (Req.CommentPrefixes.empty()) {
+    for (const char *Prefix : DefaultCommentPrefixes)
+      PrefixSet.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", PrefixSet, Req.CheckPrefixes))
+    return false;
+  if (!ValidatePrefixes("comment", PrefixSet, Req.CommentPrefixes))
     return false;
   return true;
 }
@@ -1917,15 +1953,23 @@
       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);
 }
Index: llvm/include/llvm/Support/FileCheck.h
===================================================================
--- llvm/include/llvm/Support/FileCheck.h
+++ llvm/include/llvm/Support/FileCheck.h
@@ -25,6 +25,7 @@
 /// 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 @@
   CheckDAG,
   CheckLabel,
   CheckEmpty,
+  CheckComment,
 
   /// Indicates the pattern only matches the end of file. This is used for
   /// trailing CHECK-NOTs.
Index: llvm/docs/CommandGuide/FileCheck.rst
===================================================================
--- llvm/docs/CommandGuide/FileCheck.rst
+++ llvm/docs/CommandGuide/FileCheck.rst
@@ -39,15 +39,31 @@
  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 @@
 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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Index: clang/test/Driver/hip-device-libs.hip
===================================================================
--- clang/test/Driver/hip-device-libs.hip
+++ clang/test/Driver/hip-device-libs.hip
@@ -10,7 +10,7 @@
 // RUN:   --cuda-gpu-arch=gfx803 \
 // RUN:   --hip-device-lib-path=%S/Inputs/hip_dev_lib   \
 // 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:   --hip-device-lib-path=%S/Inputs/hip_dev_lib \
 // 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:   --hip-device-lib-path=%S/Inputs/hip_dev_lib \
 // 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:   --hip-device-lib-path=%S/Inputs/hip_dev_lib \
 // 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:   --hip-device-lib-path=%S/Inputs/hip_dev_lib \
 // 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:   --hip-device-lib-path=%S/Inputs/hip_dev_lib \
 // 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:   --hip-device-lib-path=%S/Inputs/hip_dev_lib \
 // 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:   --hip-device-lib-path=%S/Inputs/hip_dev_lib   \
 // 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:   --hip-device-lib-path=%S/Inputs/hip_dev_lib   \
 // 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:   --hip-device-lib-path=%S/Inputs/hip_dev_lib \
 // 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
@@ -96,11 +96,11 @@
 // 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.amdgcn.bc"
-// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}ocml.amdgcn.bc"
-// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}ockl.amdgcn.bc"
+// ALL: {{"[^"]*clang[^"]*"}}
+// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}hip.amdgcn.bc"
+// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}ocml.amdgcn.bc"
+// ALL-SAME: "-mlink-builtin-bitcode" "{{.*}}ockl.amdgcn.bc"
 // FLUSHD-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_daz_opt_on.amdgcn.bc"
 // NOFLUSHD-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_daz_opt_off.amdgcn.bc"
Index: clang/test/CodeGenOpenCL/addr-space-struct-arg.cl
===================================================================
--- clang/test/CodeGenOpenCL/addr-space-struct-arg.cl
+++ clang/test/CodeGenOpenCL/addr-space-struct-arg.cl
@@ -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 @@
   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 @@
   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*
Index: clang/test/CodeGen/default-address-space.c
===================================================================
--- clang/test/CodeGen/default-address-space.c
+++ clang/test/CodeGen/default-address-space.c
@@ -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 *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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to