r212735 - Provide -verify support to match "any" line for diagnostics in included files.

Andy Gibbs andyg1001 at hotmail.co.uk
Thu Jul 10 09:43:29 PDT 2014


Author: andyg
Date: Thu Jul 10 11:43:29 2014
New Revision: 212735

URL: http://llvm.org/viewvc/llvm-project?rev=212735&view=rev
Log:
Provide -verify support to match "any" line for diagnostics in included files.

Allow diagnostic checks that originate in included files to be matched without necessarily determining the line number that the diagnostic occurs on.  The new syntax replaces the line number with '*'.  This extension is limited to diagnostics in included files and may be used where the include file is not part of the test-suite itself.

Expected uses are for diagnostics originating in system headers, or for users who use -verify in testing 3rd-party library code where the location of diagnostics in header files may change from revision to revision and their precise location is not important to the success of the test-case.

Modified:
    cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h
    cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp
    cfe/trunk/test/Frontend/verify.c
    cfe/trunk/test/Frontend/verify2.c
    cfe/trunk/test/Frontend/verify2.h

Modified: cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h?rev=212735&r1=212734&r2=212735&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h (original)
+++ cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h Thu Jul 10 11:43:29 2014
@@ -71,7 +71,10 @@ class FileEntry;
 /// \endcode
 ///
 /// The path can be absolute or relative and the same search paths will be used
-/// as for #include directives.
+/// as for #include directives.  The line number in an external file may be
+/// substituted with '*' meaning that any line number will match (useful where
+/// the included file is, for example, a system header where the actual line
+/// number may change and is not critical).
 ///
 /// The simple syntax above allows each specification to match exactly one
 /// error.  You can use the extended syntax to customize this. The extended
@@ -143,7 +146,7 @@ public:
   class Directive {
   public:
     static Directive *create(bool RegexKind, SourceLocation DirectiveLoc,
-                             SourceLocation DiagnosticLoc,
+                             SourceLocation DiagnosticLoc, bool MatchAnyLine,
                              StringRef Text, unsigned Min, unsigned Max);
   public:
     /// Constant representing n or more matches.
@@ -153,6 +156,7 @@ public:
     SourceLocation DiagnosticLoc;
     const std::string Text;
     unsigned Min, Max;
+    bool MatchAnyLine;
 
     virtual ~Directive() { }
 
@@ -165,9 +169,9 @@ public:
 
   protected:
     Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-              StringRef Text, unsigned Min, unsigned Max)
+              bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
       : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
-        Text(Text), Min(Min), Max(Max) {
+        Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
     assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
     assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!");
     }

Modified: cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp?rev=212735&r1=212734&r2=212735&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp (original)
+++ cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp Thu Jul 10 11:43:29 2014
@@ -164,8 +164,9 @@ namespace {
 class StandardDirective : public Directive {
 public:
   StandardDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-                    StringRef Text, unsigned Min, unsigned Max)
-    : Directive(DirectiveLoc, DiagnosticLoc, Text, Min, Max) { }
+                    bool MatchAnyLine, StringRef Text, unsigned Min,
+                    unsigned Max)
+    : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max) { }
 
   bool isValid(std::string &Error) override {
     // all strings are considered valid; even empty ones
@@ -182,8 +183,10 @@ public:
 class RegexDirective : public Directive {
 public:
   RegexDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-                 StringRef Text, unsigned Min, unsigned Max, StringRef RegexStr)
-    : Directive(DirectiveLoc, DiagnosticLoc, Text, Min, Max), Regex(RegexStr) { }
+                 bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max,
+                 StringRef RegexStr)
+    : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max),
+      Regex(RegexStr) { }
 
   bool isValid(std::string &Error) override {
     if (Regex.isValid(Error))
@@ -371,6 +374,7 @@ static bool ParseDirective(StringRef S,
 
     // Next optional token: @
     SourceLocation ExpectedLoc;
+    bool MatchAnyLine = false;
     if (!PH.Next("@")) {
       ExpectedLoc = Pos;
     } else {
@@ -411,6 +415,10 @@ static bool ParseDirective(StringRef S,
 
         if (PH.Next(Line) && Line > 0)
           ExpectedLoc = SM.translateFileLineCol(FE, Line, 1);
+        else if (PH.Next("*")) {
+          MatchAnyLine = true;
+          ExpectedLoc = SM.translateFileLineCol(FE, 1, 1);
+        }
       }
 
       if (ExpectedLoc.isInvalid()) {
@@ -495,7 +503,8 @@ static bool ParseDirective(StringRef S,
 
     // Construct new directive.
     std::unique_ptr<Directive> D(
-        Directive::create(RegexKind, Pos, ExpectedLoc, Text, Min, Max));
+        Directive::create(RegexKind, Pos, ExpectedLoc, MatchAnyLine, Text,
+                          Min, Max));
 
     std::string Error;
     if (D->isValid(Error)) {
@@ -644,8 +653,11 @@ static unsigned PrintExpected(Diagnostic
   llvm::raw_svector_ostream OS(Fmt);
   for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I) {
     Directive &D = **I;
-    OS << "\n  File " << SourceMgr.getFilename(D.DiagnosticLoc)
-          << " Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
+    OS << "\n  File " << SourceMgr.getFilename(D.DiagnosticLoc);
+    if (D.MatchAnyLine)
+      OS << " Line *";
+    else
+      OS << " Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
     if (D.DirectiveLoc != D.DiagnosticLoc)
       OS << " (directive at "
          << SourceMgr.getFilename(D.DirectiveLoc) << ':'
@@ -692,9 +704,11 @@ static unsigned CheckLists(DiagnosticsEn
     for (unsigned i = 0; i < D.Max; ++i) {
       DiagList::iterator II, IE;
       for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
-        unsigned LineNo2 = SourceMgr.getPresumedLineNumber(II->first);
-        if (LineNo1 != LineNo2)
-          continue;
+        if (!D.MatchAnyLine) {
+          unsigned LineNo2 = SourceMgr.getPresumedLineNumber(II->first);
+          if (LineNo1 != LineNo2)
+            continue;
+        }
 
         if (!IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first))
           continue;
@@ -859,10 +873,11 @@ void VerifyDiagnosticConsumer::CheckDiag
 }
 
 Directive *Directive::create(bool RegexKind, SourceLocation DirectiveLoc,
-                             SourceLocation DiagnosticLoc, StringRef Text,
-                             unsigned Min, unsigned Max) {
+                             SourceLocation DiagnosticLoc, bool MatchAnyLine,
+                             StringRef Text, unsigned Min, unsigned Max) {
   if (!RegexKind)
-    return new StandardDirective(DirectiveLoc, DiagnosticLoc, Text, Min, Max);
+    return new StandardDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine,
+                                 Text, Min, Max);
 
   // Parse the directive into a regular expression.
   std::string RegexStr;
@@ -887,6 +902,6 @@ Directive *Directive::create(bool RegexK
     }
   }
 
-  return new RegexDirective(DirectiveLoc, DiagnosticLoc, Text, Min, Max,
-                            RegexStr);
+  return new RegexDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text,
+                            Min, Max, RegexStr);
 }

Modified: cfe/trunk/test/Frontend/verify.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/verify.c?rev=212735&r1=212734&r2=212735&view=diff
==============================================================================
--- cfe/trunk/test/Frontend/verify.c (original)
+++ cfe/trunk/test/Frontend/verify.c Thu Jul 10 11:43:29 2014
@@ -134,9 +134,18 @@ unexpected b; // expected-error at 33 1-1 {
 // expected-warning at verify-directive.h: {{ }}
 // expected-error at -1 {{missing or invalid line number}}
 
+// expected-warning at verify-directive.h:0 {{ }}
+// expected-error at -1 {{missing or invalid line number}}
+
+// expected-warning at verify-directive.h:0*{{ }}
+// expected-error at -1 {{missing or invalid line number}}
+
+// expected-warning at verify-directive.h:*0{{ }}
+// syntactically ok -- means match in any line for 0 occurrences.
+
 // expected-warning at verify-directive.h:1 {{diagnostic}}
 
 //      CHECK8: error: 'warning' diagnostics expected but not seen:
-// CHECK8-NEXT:   File {{.*}}verify-directive.h Line 1 (directive at {{.*}}verify.c:137): diagnostic
+// CHECK8-NEXT:   File {{.*}}verify-directive.h Line 1 (directive at {{.*}}verify.c:146): diagnostic
 // CHECK8-NEXT: 1 error generated.
 #endif

Modified: cfe/trunk/test/Frontend/verify2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/verify2.c?rev=212735&r1=212734&r2=212735&view=diff
==============================================================================
--- cfe/trunk/test/Frontend/verify2.c (original)
+++ cfe/trunk/test/Frontend/verify2.c Thu Jul 10 11:43:29 2014
@@ -14,7 +14,26 @@
 
 //      CHECK: error: no expected directives found: consider use of 'expected-no-diagnostics'
 // CHECK-NEXT: error: 'error' diagnostics seen but not expected:
-// CHECK-NEXT:   Line 1: header
+// CHECK-NEXT:   Line 5: header
 // CHECK-NEXT:   Line 10: source
 // CHECK-NEXT: 3 errors generated.
 #endif
+
+#ifdef CHECK2
+// RUN: not %clang_cc1 -DCHECK2 -verify %s 2>&1 | FileCheck -check-prefix=CHECK2 %s
+
+// The following checks that -verify can match "any line" in an included file.
+// The location of the diagnostic need therefore only match in the file, not to
+// a specific line number.  This is useful where -verify is used as a testing
+// tool for 3rd-party libraries where headers may change and the specific line
+// number of a diagnostic in a header is not important.
+
+// expected-error at verify2.h:* {{header}}
+// expected-error at verify2.h:* {{unknown}}
+
+//      CHECK2: error: 'error' diagnostics expected but not seen:
+// CHECK2-NEXT:   File {{.*}}verify2.h Line * (directive at {{.*}}verify2.c:32): unknown
+// CHECK2-NEXT: error: 'error' diagnostics seen but not expected:
+// CHECK2-NEXT:   File {{.*}}verify2.c Line 10: source
+// CHECK2-NEXT: 2 errors generated.
+#endif

Modified: cfe/trunk/test/Frontend/verify2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/verify2.h?rev=212735&r1=212734&r2=212735&view=diff
==============================================================================
--- cfe/trunk/test/Frontend/verify2.h (original)
+++ cfe/trunk/test/Frontend/verify2.h Thu Jul 10 11:43:29 2014
@@ -1,5 +1,5 @@
-#error header
-
 #if 0
 // expected-error {{should be ignored}}
 #endif
+
+#error header





More information about the cfe-commits mailing list