arames created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
arames added a reviewer: rsmith.

This allows specifying `*` for the filename to match any file. For example:

  // expected-note@*:* {{Match this note in any file at any line.}}
  // expected-note@*:123 {{Match this note in any file at line 123.}}


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72100

Files:
  clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
  clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
  clang/test/Frontend/verify-any-file.c
  clang/test/Frontend/verify-any-file.h

Index: clang/test/Frontend/verify-any-file.h
===================================================================
--- /dev/null
+++ clang/test/Frontend/verify-any-file.h
@@ -0,0 +1 @@
+unexpected var;
Index: clang/test/Frontend/verify-any-file.c
===================================================================
--- /dev/null
+++ clang/test/Frontend/verify-any-file.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -verify %s 2>&1
+
+#include "verify-any-file.h"
+// expected-error@*:1 {{unknown type name 'unexpected'}}
+#include "verify-any-file.h"
+// expected-error@*:* {{unknown type name 'unexpected'}}
Index: clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
===================================================================
--- clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -89,9 +89,10 @@
 class StandardDirective : public Directive {
 public:
   StandardDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-                    bool MatchAnyLine, StringRef Text, unsigned Min,
-                    unsigned Max)
-      : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max) {}
+                    bool MatchAnyFile, bool MatchAnyLine, StringRef Text,
+                    unsigned Min, unsigned Max)
+      : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFile, MatchAnyLine, Text,
+                  Min, Max) {}
 
   bool isValid(std::string &Error) override {
     // all strings are considered valid; even empty ones
@@ -107,9 +108,10 @@
 class RegexDirective : public Directive {
 public:
   RegexDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-                 bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max,
-                 StringRef RegexStr)
-      : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max),
+                 bool MatchAnyFile, bool MatchAnyLine, StringRef Text,
+                 unsigned Min, unsigned Max, StringRef RegexStr)
+      : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFile, MatchAnyLine, Text,
+                  Min, Max),
         Regex(RegexStr) {}
 
   bool isValid(std::string &Error) override {
@@ -294,11 +296,12 @@
 // Attach the specified directive to the line of code indicated by
 // \p ExpectedLoc.
 void attachDirective(DiagnosticsEngine &Diags, const UnattachedDirective &UD,
-                     SourceLocation ExpectedLoc, bool MatchAnyLine = false) {
+                     SourceLocation ExpectedLoc, bool MatchAnyFile = false,
+                     bool MatchAnyLine = false) {
   // Construct new directive.
   std::unique_ptr<Directive> D =
       Directive::create(UD.RegexKind, UD.DirectivePos, ExpectedLoc,
-                        MatchAnyLine, UD.Text, UD.Min, UD.Max);
+                        MatchAnyFile, MatchAnyLine, UD.Text, UD.Min, UD.Max);
 
   std::string Error;
   if (!D->isValid(Error)) {
@@ -498,6 +501,7 @@
     // Next optional token: @
     SourceLocation ExpectedLoc;
     StringRef Marker;
+    bool MatchAnyFile = false;
     bool MatchAnyLine = false;
     if (!PH.Next("@")) {
       ExpectedLoc = Pos;
@@ -526,26 +530,36 @@
         StringRef Filename(PH.C, PH.P-PH.C);
         PH.Advance();
 
-        // Lookup file via Preprocessor, like a #include.
-        const DirectoryLookup *CurDir;
-        Optional<FileEntryRef> File =
-            PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir,
-                           nullptr, nullptr, nullptr, nullptr, nullptr);
-        if (!File) {
-          Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
-                       diag::err_verify_missing_file) << Filename << KindStr;
-          continue;
-        }
+        FileID FID;
+
+        if (Filename == "*") {
+          MatchAnyFile = true;
+          FID = SM.getFileID(Pos);
+        } else {
+          // Lookup file via Preprocessor, like a #include.
+          const DirectoryLookup *CurDir;
+          Optional<FileEntryRef> File =
+              PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir,
+                             nullptr, nullptr, nullptr, nullptr, nullptr);
+          if (!File) {
+            Diags.Report(Pos.getLocWithOffset(PH.C - PH.Begin),
+                         diag::err_verify_missing_file)
+                << Filename << KindStr;
+            continue;
+          }
+
+          const FileEntry *FE = &File->getFileEntry();
+          if (SM.translateFile(FE).isInvalid())
+            SM.createFileID(FE, Pos, SrcMgr::C_User);
 
-        const FileEntry *FE = &File->getFileEntry();
-        if (SM.translateFile(FE).isInvalid())
-          SM.createFileID(FE, Pos, SrcMgr::C_User);
+          FID = SM.translateFile(FE);
+        }
 
         if (PH.Next(Line) && Line > 0)
-          ExpectedLoc = SM.translateFileLineCol(FE, Line, 1);
+          ExpectedLoc = SM.translateLineCol(FID, Line, 1);
         else if (PH.Next("*")) {
           MatchAnyLine = true;
-          ExpectedLoc = SM.translateFileLineCol(FE, 1, 1);
+          ExpectedLoc = SM.translateLineCol(FID, 1, 1);
         }
       } else if (PH.Next("*")) {
         MatchAnyLine = true;
@@ -631,7 +645,7 @@
     }
 
     if (Marker.empty())
-      attachDirective(Diags, D, ExpectedLoc, MatchAnyLine);
+      attachDirective(Diags, D, ExpectedLoc, MatchAnyFile, MatchAnyLine);
     else
       Markers.addDirective(Marker, D);
     FoundDirective = true;
@@ -877,7 +891,7 @@
   SmallString<256> Fmt;
   llvm::raw_svector_ostream OS(Fmt);
   for (const auto *D : DL) {
-    if (D->DiagnosticLoc.isInvalid())
+    if (D->DiagnosticLoc.isInvalid() || D->MatchAnyFile)
       OS << "\n  File *";
     else
       OS << "\n  File " << SourceMgr.getFilename(D->DiagnosticLoc);
@@ -937,7 +951,7 @@
             continue;
         }
 
-        if (!D.DiagnosticLoc.isInvalid() &&
+        if (!D.DiagnosticLoc.isInvalid() && !D.MatchAnyFile &&
             !IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first))
           continue;
 
@@ -1114,11 +1128,13 @@
 std::unique_ptr<Directive> Directive::create(bool RegexKind,
                                              SourceLocation DirectiveLoc,
                                              SourceLocation DiagnosticLoc,
+                                             bool MatchAnyFile,
                                              bool MatchAnyLine, StringRef Text,
                                              unsigned Min, unsigned Max) {
   if (!RegexKind)
     return std::make_unique<StandardDirective>(DirectiveLoc, DiagnosticLoc,
-                                                MatchAnyLine, Text, Min, Max);
+                                               MatchAnyFile, MatchAnyLine, Text,
+                                               Min, Max);
 
   // Parse the directive into a regular expression.
   std::string RegexStr;
@@ -1143,6 +1159,7 @@
     }
   }
 
-  return std::make_unique<RegexDirective>(
-      DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max, RegexStr);
+  return std::make_unique<RegexDirective>(DirectiveLoc, DiagnosticLoc,
+                                          MatchAnyFile, MatchAnyLine, Text, Min,
+                                          Max, RegexStr);
 }
Index: clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
===================================================================
--- clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -189,11 +189,10 @@
   ///
   class Directive {
   public:
-    static std::unique_ptr<Directive> create(bool RegexKind,
-                                             SourceLocation DirectiveLoc,
-                                             SourceLocation DiagnosticLoc,
-                                             bool MatchAnyLine, StringRef Text,
-                                             unsigned Min, unsigned Max);
+    static std::unique_ptr<Directive>
+    create(bool RegexKind, SourceLocation DirectiveLoc,
+           SourceLocation DiagnosticLoc, bool MatchAnyFile, bool MatchAnyLine,
+           StringRef Text, unsigned Min, unsigned Max);
 
   public:
     /// Constant representing n or more matches.
@@ -204,6 +203,7 @@
     const std::string Text;
     unsigned Min, Max;
     bool MatchAnyLine;
+    bool MatchAnyFile;
 
     Directive(const Directive &) = delete;
     Directive &operator=(const Directive &) = delete;
@@ -218,11 +218,13 @@
 
   protected:
     Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-              bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
-        : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
-          Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
+              bool MatchAnyFile, bool MatchAnyLine, StringRef Text,
+              unsigned Min, unsigned Max)
+        : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc), Text(Text),
+          Min(Min), Max(Max), MatchAnyLine(MatchAnyLine),
+          MatchAnyFile(MatchAnyFile) {
       assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
-      assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) &&
+      assert((!DiagnosticLoc.isInvalid() || MatchAnyFile || MatchAnyLine) &&
              "DiagnosticLoc is invalid!");
     }
   };
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to