[cfe-commits] r159978 - in /cfe/trunk: include/clang/Basic/DiagnosticFrontendKinds.td include/clang/Basic/SourceManager.h include/clang/Frontend/VerifyDiagnosticConsumer.h lib/Frontend/VerifyDiagnosticConsumer.cpp

Richard Smith richard at metafoo.co.uk
Mon Jul 9 23:33:04 PDT 2012


Tests?

On Mon, Jul 9, 2012 at 7:57 PM, Jordan Rose <jordan_rose at apple.com> wrote:

> Author: jrose
> Date: Mon Jul  9 21:57:03 2012
> New Revision: 159978
>
> URL: http://llvm.org/viewvc/llvm-project?rev=159978&view=rev
> Log:
> Allow line numbers on -verify directives.
>
> // expected-warning at 10 {{some text}}
>
> The line number may be absolute (as above), or relative to the current
> line by prefixing the number with either '+' or '-'.
>
> Patch by Andy Gibbs!
>
> Modified:
>     cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
>     cfe/trunk/include/clang/Basic/SourceManager.h
>     cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h
>     cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=159978&r1=159977&r2=159978&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td Mon Jul  9
> 21:57:03 2012
> @@ -63,6 +63,8 @@
>      "unable to open file %0 for serializing diagnostics (%1)">,
>      InGroup<DiagGroup<"serialized-diagnostics">>;
>
> +def err_verify_missing_line : Error<
> +    "missing or invalid line number following '@' in expected %0">;
>  def err_verify_missing_start : Error<
>      "cannot find start ('{{') of expected %0">;
>  def err_verify_missing_end : Error<
>
> Modified: cfe/trunk/include/clang/Basic/SourceManager.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=159978&r1=159977&r2=159978&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/SourceManager.h (original)
> +++ cfe/trunk/include/clang/Basic/SourceManager.h Mon Jul  9 21:57:03 2012
> @@ -36,6 +36,7 @@
>  #define LLVM_CLANG_SOURCEMANAGER_H
>
>  #include "clang/Basic/LLVM.h"
> +#include "clang/Basic/FileManager.h"
>  #include "clang/Basic/SourceLocation.h"
>  #include "llvm/Support/Allocator.h"
>  #include "llvm/Support/DataTypes.h"
> @@ -897,6 +898,13 @@
>      return getFileIDSlow(SLocOffset);
>    }
>
> +  /// \brief Return the filename of the file containing a SourceLocation.
> +  StringRef getFilename(SourceLocation SpellingLoc) const {
> +    if (const FileEntry *F = getFileEntryForID(getFileID(SpellingLoc)))
> +      return F->getName();
> +    return StringRef();
> +  }
> +
>    /// \brief Return the source location corresponding to the first byte of
>    /// the specified file.
>    SourceLocation getLocForStartOfFile(FileID FID) const {
>
> Modified: cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h?rev=159978&r1=159977&r2=159978&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h (original)
> +++ cfe/trunk/include/clang/Frontend/VerifyDiagnosticConsumer.h Mon Jul  9
> 21:57:03 2012
> @@ -44,6 +44,15 @@
>  /// You can place as many diagnostics on one line as you wish. To make
> the code
>  /// more readable, you can use slash-newline to separate out the
> diagnostics.
>  ///
> +/// Alternatively, it is possible to specify the line on which the
> diagnostic
> +/// should appear by appending "@<line>" to "expected-<type>", for
> example:
> +///
> +///   #warning some text
> +///   // expected-warning at 10 {{some text}}
> +///
> +/// The line number may be absolute (as above), or relative to the current
> +/// line by prefixing the number with either '+' or '-'.
> +///
>  /// The simple syntax above allows each specification to match exactly one
>  /// error.  You can use the extended syntax to customize this. The
> extended
>  /// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of
> @@ -74,13 +83,15 @@
>    ///
>    class Directive {
>    public:
> -    static Directive *create(bool RegexKind, const SourceLocation
> &Location,
> +    static Directive *create(bool RegexKind, SourceLocation DirectiveLoc,
> +                             SourceLocation DiagnosticLoc,
>                               StringRef Text, unsigned Count);
>    public:
>      /// Constant representing one or more matches aka regex "+".
>      static const unsigned OneOrMoreCount = UINT_MAX;
>
> -    SourceLocation Location;
> +    SourceLocation DirectiveLoc;
> +    SourceLocation DiagnosticLoc;
>      const std::string Text;
>      unsigned Count;
>
> @@ -94,9 +105,10 @@
>      virtual bool match(StringRef S) = 0;
>
>    protected:
> -    Directive(const SourceLocation &Location, StringRef Text,
> -              unsigned Count)
> -      : Location(Location), Text(Text), Count(Count) { }
> +    Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
> +              StringRef Text, unsigned Count)
> +      : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
> +        Text(Text), Count(Count) { }
>
>    private:
>      Directive(const Directive&); // DO NOT IMPLEMENT
>
> Modified: cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp?rev=159978&r1=159977&r2=159978&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp (original)
> +++ cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp Mon Jul  9
> 21:57:03 2012
> @@ -83,9 +83,9 @@
>  ///
>  class StandardDirective : public Directive {
>  public:
> -  StandardDirective(const SourceLocation &Location, StringRef Text,
> -                    unsigned Count)
> -    : Directive(Location, Text, Count) { }
> +  StandardDirective(SourceLocation DirectiveLoc, SourceLocation
> DiagnosticLoc,
> +                    StringRef Text, unsigned Count)
> +    : Directive(DirectiveLoc, DiagnosticLoc, Text, Count) { }
>
>    virtual bool isValid(std::string &Error) {
>      // all strings are considered valid; even empty ones
> @@ -101,9 +101,9 @@
>  ///
>  class RegexDirective : public Directive {
>  public:
> -  RegexDirective(const SourceLocation &Location, StringRef Text,
> -                 unsigned Count)
> -    : Directive(Location, Text, Count), Regex(Text) { }
> +  RegexDirective(SourceLocation DirectiveLoc, SourceLocation
> DiagnosticLoc,
> +                 StringRef Text, unsigned Count)
> +    : Directive(DirectiveLoc, DiagnosticLoc, Text, Count), Regex(Text) { }
>
>    virtual bool isValid(std::string &Error) {
>      if (Regex.isValid(Error))
> @@ -195,17 +195,17 @@
>                             SourceLocation Pos, DiagnosticsEngine &Diags) {
>    // A single comment may contain multiple directives.
>    for (ParseHelper PH(CommentStart, CommentStart+CommentLen);
> !PH.Done();) {
> -    // search for token: expected
> +    // Search for token: expected
>      if (!PH.Search("expected"))
>        break;
>      PH.Advance();
>
> -    // next token: -
> +    // Next token: -
>      if (!PH.Next("-"))
>        continue;
>      PH.Advance();
>
> -    // next token: { error | warning | note }
> +    // Next token: { error | warning | note }
>      DirectiveList* DL = NULL;
>      if (PH.Next("error"))
>        DL = &ED.Errors;
> @@ -217,21 +217,53 @@
>        continue;
>      PH.Advance();
>
> -    // default directive kind
> +    // Default directive kind.
>      bool RegexKind = false;
>      const char* KindStr = "string";
>
> -    // next optional token: -
> +    // Next optional token: -
>      if (PH.Next("-re")) {
>        PH.Advance();
>        RegexKind = true;
>        KindStr = "regex";
>      }
>
> -    // skip optional whitespace
> +    // Next optional token: @
> +    SourceLocation ExpectedLoc;
> +    if (!PH.Next("@")) {
> +      ExpectedLoc = Pos;
> +    } else {
> +      PH.Advance();
> +      unsigned Line = 0;
> +      bool FoundPlus = PH.Next("+");
> +      if (FoundPlus || PH.Next("-")) {
> +        // Relative to current line.
> +        PH.Advance();
> +        bool Invalid = false;
> +        unsigned ExpectedLine = SM.getSpellingLineNumber(Pos, &Invalid);
> +        if (!Invalid && PH.Next(Line) && (FoundPlus || Line <
> ExpectedLine)) {
> +          if (FoundPlus) ExpectedLine += Line;
> +          else ExpectedLine -= Line;
> +          ExpectedLoc = SM.translateLineCol(SM.getFileID(Pos),
> ExpectedLine, 1);
> +        }
> +      } else {
> +        // Absolute line number.
> +        if (PH.Next(Line) && Line > 0)
> +          ExpectedLoc = SM.translateLineCol(SM.getFileID(Pos), Line, 1);
> +      }
> +
> +      if (ExpectedLoc.isInvalid()) {
> +        Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
> +                     diag::err_verify_missing_line) << KindStr;
> +        continue;
> +      }
> +      PH.Advance();
> +    }
> +
> +    // Skip optional whitespace.
>      PH.SkipWhitespace();
>
> -    // next optional token: positive integer or a '+'.
> +    // Next optional token: positive integer or a '+'.
>      unsigned Count = 1;
>      if (PH.Next(Count))
>        PH.Advance();
> @@ -240,10 +272,10 @@
>        PH.Advance();
>      }
>
> -    // skip optional whitespace
> +    // Skip optional whitespace.
>      PH.SkipWhitespace();
>
> -    // next token: {{
> +    // Next token: {{
>      if (!PH.Next("{{")) {
>        Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
>                     diag::err_verify_missing_start) << KindStr;
> @@ -252,7 +284,7 @@
>      PH.Advance();
>      const char* const ContentBegin = PH.C; // mark content begin
>
> -    // search for token: }}
> +    // Search for token: }}
>      if (!PH.Search("}}")) {
>        Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
>                     diag::err_verify_missing_end) << KindStr;
> @@ -261,7 +293,7 @@
>      const char* const ContentEnd = PH.P; // mark content end
>      PH.Advance();
>
> -    // build directive text; convert \n to newlines
> +    // Build directive text; convert \n to newlines.
>      std::string Text;
>      StringRef NewlineStr = "\\n";
>      StringRef Content(ContentBegin, ContentEnd-ContentBegin);
> @@ -275,8 +307,8 @@
>      if (Text.empty())
>        Text.assign(ContentBegin, ContentEnd);
>
> -    // construct new directive
> -    Directive *D = Directive::create(RegexKind, Pos, Text, Count);
> +    // Construct new directive.
> +    Directive *D = Directive::create(RegexKind, Pos, ExpectedLoc, Text,
> Count);
>      std::string Error;
>      if (D->isValid(Error))
>        DL->push_back(D);
> @@ -318,15 +350,12 @@
>    };
>  }
>
> -/// PrintProblem - This takes a diagnostic map of the delta between
> expected and
> -/// seen diagnostics. If there's anything in it, then something unexpected
> -/// happened. Print the map out in a nice format and return "true". If
> the map
> -/// is empty and we're not going to print things, then return "false".
> -///
> -static unsigned PrintProblem(DiagnosticsEngine &Diags, SourceManager
> *SourceMgr,
> -                             const_diag_iterator diag_begin,
> -                             const_diag_iterator diag_end,
> -                             const char *Kind, bool Expected) {
> +/// \brief Takes a list of diagnostics that have been generated but not
> matched
> +/// by an expected-* directive and produces a diagnostic to the user from
> this.
> +static unsigned PrintUnexpected(DiagnosticsEngine &Diags, SourceManager
> *SourceMgr,
> +                                const_diag_iterator diag_begin,
> +                                const_diag_iterator diag_end,
> +                                const char *Kind) {
>    if (diag_begin == diag_end) return 0;
>
>    SmallString<256> Fmt;
> @@ -340,29 +369,31 @@
>    }
>
>    Diags.Report(diag::err_verify_inconsistent_diags)
> -    << Kind << !Expected << OS.str();
> +    << Kind << /*Unexpected=*/true << OS.str();
>    return std::distance(diag_begin, diag_end);
>  }
>
> -static unsigned PrintProblem(DiagnosticsEngine &Diags, SourceManager
> *SourceMgr,
> -                             DirectiveList &DL, const char *Kind,
> -                             bool Expected) {
> +/// \brief Takes a list of diagnostics that were expected to have been
> generated
> +/// but were not and produces a diagnostic to the user from this.
> +static unsigned PrintExpected(DiagnosticsEngine &Diags, SourceManager
> &SourceMgr,
> +                              DirectiveList &DL, const char *Kind) {
>    if (DL.empty())
>      return 0;
>
>    SmallString<256> Fmt;
>    llvm::raw_svector_ostream OS(Fmt);
>    for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I)
> {
> -    Directive& D = **I;
> -    if (D.Location.isInvalid() || !SourceMgr)
> -      OS << "\n  (frontend)";
> -    else
> -      OS << "\n  Line " << SourceMgr->getPresumedLineNumber(D.Location);
> +    Directive &D = **I;
> +    OS << "\n  Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
> +    if (D.DirectiveLoc != D.DiagnosticLoc)
> +      OS << " (directive at "
> +         << SourceMgr.getFilename(D.DirectiveLoc) << ":"
> +         << SourceMgr.getPresumedLineNumber(D.DirectiveLoc) << ")";
>      OS << ": " << D.Text;
>    }
>
>    Diags.Report(diag::err_verify_inconsistent_diags)
> -    << Kind << !Expected << OS.str();
> +    << Kind << /*Unexpected=*/false << OS.str();
>    return DL.size();
>  }
>
> @@ -379,7 +410,7 @@
>
>    for (DirectiveList::iterator I = Left.begin(), E = Left.end(); I != E;
> ++I) {
>      Directive& D = **I;
> -    unsigned LineNo1 = SourceMgr.getPresumedLineNumber(D.Location);
> +    unsigned LineNo1 = SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
>      bool FoundOnce = false;
>
>      for (unsigned i = 0; i < D.Count; ++i) {
> @@ -410,9 +441,8 @@
>      }
>    }
>    // Now all that's left in Right are those that were not matched.
> -  unsigned num = PrintProblem(Diags, &SourceMgr, LeftOnly, Label, true);
> -  num += PrintProblem(Diags, &SourceMgr, Right.begin(), Right.end(),
> -                      Label, false);
> +  unsigned num = PrintExpected(Diags, SourceMgr, LeftOnly, Label);
> +  num += PrintUnexpected(Diags, &SourceMgr, Right.begin(), Right.end(),
> Label);
>    return num;
>  }
>
> @@ -472,15 +502,12 @@
>      // Check that the expected diagnostics occurred.
>      NumErrors += CheckResults(Diags, SM, *Buffer, ED);
>    } else {
> -    NumErrors += (PrintProblem(Diags, 0,
> -                               Buffer->err_begin(), Buffer->err_end(),
> -                               "error", false) +
> -                  PrintProblem(Diags, 0,
> -                               Buffer->warn_begin(), Buffer->warn_end(),
> -                               "warn", false) +
> -                  PrintProblem(Diags, 0,
> -                               Buffer->note_begin(), Buffer->note_end(),
> -                               "note", false));
> +    NumErrors += (PrintUnexpected(Diags, 0, Buffer->err_begin(),
> +                                  Buffer->err_end(), "error") +
> +                  PrintUnexpected(Diags, 0, Buffer->warn_begin(),
> +                                  Buffer->warn_end(), "warn") +
> +                  PrintUnexpected(Diags, 0, Buffer->note_begin(),
> +                                  Buffer->note_end(), "note"));
>    }
>
>    Diags.takeClient();
> @@ -498,9 +525,10 @@
>    return new VerifyDiagnosticConsumer(Diags);
>  }
>
> -Directive *Directive::create(bool RegexKind, const SourceLocation
> &Location,
> -                             StringRef Text, unsigned Count) {
> +Directive *Directive::create(bool RegexKind, SourceLocation DirectiveLoc,
> +                             SourceLocation DiagnosticLoc, StringRef Text,
> +                             unsigned Count) {
>    if (RegexKind)
> -    return new RegexDirective(Location, Text, Count);
> -  return new StandardDirective(Location, Text, Count);
> +    return new RegexDirective(DirectiveLoc, DiagnosticLoc, Text, Count);
> +  return new StandardDirective(DirectiveLoc, DiagnosticLoc, Text, Count);
>  }
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120709/fdfa9f02/attachment.html>


More information about the cfe-commits mailing list