Author: Alexandre Rames Date: 2020-05-14T15:15:49-07:00 New Revision: 05eedf1f5b449ae42f5493576164b0f9a001646c
URL: https://github.com/llvm/llvm-project/commit/05eedf1f5b449ae42f5493576164b0f9a001646c DIFF: https://github.com/llvm/llvm-project/commit/05eedf1f5b449ae42f5493576164b0f9a001646c.diff LOG: [clang][VerifyDiagnosticConsumer] Support filename wildcards Differential Revision: https://reviews.llvm.org/D72100 Added: clang/test/Frontend/verify-any-file.c clang/test/Frontend/verify-any-file.h Modified: clang/include/clang/Frontend/VerifyDiagnosticConsumer.h clang/lib/Frontend/VerifyDiagnosticConsumer.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h b/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h index 7daebe612160..a97cd138d159 100644 --- a/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h +++ b/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h @@ -190,11 +190,10 @@ class VerifyDiagnosticConsumer: public DiagnosticConsumer, /// 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 MatchAnyFileAndLine, + bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max); public: /// Constant representing n or more matches. @@ -205,6 +204,7 @@ class VerifyDiagnosticConsumer: public DiagnosticConsumer, const std::string Text; unsigned Min, Max; bool MatchAnyLine; + bool MatchAnyFileAndLine; // `MatchAnyFileAndLine` implies `MatchAnyLine`. Directive(const Directive &) = delete; Directive &operator=(const Directive &) = delete; @@ -219,9 +219,11 @@ class VerifyDiagnosticConsumer: public DiagnosticConsumer, 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 MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text, + unsigned Min, unsigned Max) + : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc), Text(Text), + Min(Min), Max(Max), MatchAnyLine(MatchAnyLine || MatchAnyFileAndLine), + MatchAnyFileAndLine(MatchAnyFileAndLine) { assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!"); assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) && "DiagnosticLoc is invalid!"); diff --git a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp index 82c2af87706e..56e05242f7c9 100644 --- a/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -89,9 +89,10 @@ namespace { 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 MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text, + unsigned Min, unsigned Max) + : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine, + MatchAnyLine, Text, Min, Max) {} bool isValid(std::string &Error) override { // all strings are considered valid; even empty ones @@ -107,9 +108,10 @@ class StandardDirective : public Directive { 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 MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text, + unsigned Min, unsigned Max, StringRef RegexStr) + : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine, + MatchAnyLine, Text, Min, Max), Regex(RegexStr) {} bool isValid(std::string &Error) override { @@ -294,11 +296,13 @@ struct UnattachedDirective { // 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 MatchAnyFileAndLine = 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); + std::unique_ptr<Directive> D = Directive::create( + UD.RegexKind, UD.DirectivePos, ExpectedLoc, MatchAnyFileAndLine, + MatchAnyLine, UD.Text, UD.Min, UD.Max); std::string Error; if (!D->isValid(Error)) { @@ -498,6 +502,7 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, // Next optional token: @ SourceLocation ExpectedLoc; StringRef Marker; + bool MatchAnyFileAndLine = false; bool MatchAnyLine = false; if (!PH.Next("@")) { ExpectedLoc = Pos; @@ -526,26 +531,39 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, 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; - } - - const FileEntry *FE = &File->getFileEntry(); - if (SM.translateFile(FE).isInvalid()) - SM.createFileID(FE, Pos, SrcMgr::C_User); - - if (PH.Next(Line) && Line > 0) - ExpectedLoc = SM.translateFileLineCol(FE, Line, 1); - else if (PH.Next("*")) { + if (Filename == "*") { + MatchAnyFileAndLine = true; + if (!PH.Next("*")) { + Diags.Report(Pos.getLocWithOffset(PH.C - PH.Begin), + diag::err_verify_missing_line) + << "'*'"; + continue; + } MatchAnyLine = true; - ExpectedLoc = SM.translateFileLineCol(FE, 1, 1); + ExpectedLoc = SourceLocation(); + } 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); + + if (PH.Next(Line) && Line > 0) + ExpectedLoc = SM.translateFileLineCol(FE, Line, 1); + else if (PH.Next("*")) { + MatchAnyLine = true; + ExpectedLoc = SM.translateFileLineCol(FE, 1, 1); + } } } else if (PH.Next("*")) { MatchAnyLine = true; @@ -631,7 +649,7 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, } if (Marker.empty()) - attachDirective(Diags, D, ExpectedLoc, MatchAnyLine); + attachDirective(Diags, D, ExpectedLoc, MatchAnyFileAndLine, MatchAnyLine); else Markers.addDirective(Marker, D); FoundDirective = true; @@ -877,7 +895,7 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags, SmallString<256> Fmt; llvm::raw_svector_ostream OS(Fmt); for (const auto *D : DL) { - if (D->DiagnosticLoc.isInvalid()) + if (D->DiagnosticLoc.isInvalid() || D->MatchAnyFileAndLine) OS << "\n File *"; else OS << "\n File " << SourceMgr.getFilename(D->DiagnosticLoc); @@ -937,7 +955,7 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, continue; } - if (!D.DiagnosticLoc.isInvalid() && + if (!D.DiagnosticLoc.isInvalid() && !D.MatchAnyFileAndLine && !IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first)) continue; @@ -1114,11 +1132,13 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() { std::unique_ptr<Directive> Directive::create(bool RegexKind, SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc, + bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max) { if (!RegexKind) return std::make_unique<StandardDirective>(DirectiveLoc, DiagnosticLoc, - MatchAnyLine, Text, Min, Max); + MatchAnyFileAndLine, + MatchAnyLine, Text, Min, Max); // Parse the directive into a regular expression. std::string RegexStr; @@ -1143,6 +1163,7 @@ std::unique_ptr<Directive> Directive::create(bool RegexKind, } } - return std::make_unique<RegexDirective>( - DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max, RegexStr); + return std::make_unique<RegexDirective>(DirectiveLoc, DiagnosticLoc, + MatchAnyFileAndLine, MatchAnyLine, + Text, Min, Max, RegexStr); } diff --git a/clang/test/Frontend/verify-any-file.c b/clang/test/Frontend/verify-any-file.c new file mode 100644 index 000000000000..d2c0d90b9db5 --- /dev/null +++ b/clang/test/Frontend/verify-any-file.c @@ -0,0 +1,14 @@ +// RUN: not %clang_cc1 -verify %s 2>&1 | FileCheck %s + +#include "verify-any-file.h" +// expected-error@*:* {{unknown type name 'unexpected'}} + +// expected-error@*:* {{missing error}} + +// expected-error@*:123 {{invalid line : "*" required}} +// +// CHECK: error: 'error' diagnostics expected but not seen: +// CHECK-NEXT: File * Line * (directive at {{.*}}verify-any-file.c:6): missing error +// CHECK-NEXT: error: 'error' diagnostics seen but not expected: +// CHECK-NEXT: File {{.*}}verify-any-file.c Line 8: missing or invalid line number following '@' in expected '*' +// CHECK-NEXT: 2 errors generated. diff --git a/clang/test/Frontend/verify-any-file.h b/clang/test/Frontend/verify-any-file.h new file mode 100644 index 000000000000..dee8fa3a7489 --- /dev/null +++ b/clang/test/Frontend/verify-any-file.h @@ -0,0 +1 @@ +unexpected var; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits