[clang-tools-extra] r206984 - Add new 'let' command to bind arbitrary values into constants.

Aaron Ballman aaron at aaronballman.com
Wed Apr 23 08:45:20 PDT 2014


On Wed, Apr 23, 2014 at 10:04 AM, Samuel Benzaquen <sbenza at google.com> wrote:
> Author: sbenza
> Date: Wed Apr 23 09:04:52 2014
> New Revision: 206984
>
> URL: http://llvm.org/viewvc/llvm-project?rev=206984&view=rev
> Log:
> Add new 'let' command to bind arbitrary values into constants.
>
> Summary:
> Add new 'let' command to bind arbitrary values into constants.
> These constants can then be used in the matcher expressions.
>
> Reviewers: pcc
>
> CC: cfe-commits
>
> Differential Revision: http://reviews.llvm.org/D3383
>
> Modified:
>     clang-tools-extra/trunk/clang-query/Query.cpp
>     clang-tools-extra/trunk/clang-query/Query.h
>     clang-tools-extra/trunk/clang-query/QueryParser.cpp
>     clang-tools-extra/trunk/clang-query/QueryParser.h
>     clang-tools-extra/trunk/clang-query/QuerySession.h
>     clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp
>     clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp
>     clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp
>
> Modified: clang-tools-extra/trunk/clang-query/Query.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/Query.cpp?rev=206984&r1=206983&r2=206984&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/clang-query/Query.cpp (original)
> +++ clang-tools-extra/trunk/clang-query/Query.cpp Wed Apr 23 09:04:52 2014
> @@ -54,7 +54,7 @@ struct CollectBoundNodes : MatchFinder::
>    }
>  };
>
> -}
> +}  // namespace
>
>  bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
>    unsigned MatchCount = 0;
> @@ -124,6 +124,15 @@ bool MatchQuery::run(llvm::raw_ostream &
>    return true;
>  }
>
> +bool LetQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
> +  if (Value) {
> +    QS.NamedValues[Name] = Value;
> +  } else {
> +    QS.NamedValues.erase(Name);
> +  }
> +  return true;
> +}
> +
>  #ifndef _MSC_VER
>  const QueryKind SetQueryKind<bool>::value;
>  const QueryKind SetQueryKind<OutputKind>::value;
>
> Modified: clang-tools-extra/trunk/clang-query/Query.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/Query.h?rev=206984&r1=206983&r2=206984&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/clang-query/Query.h (original)
> +++ clang-tools-extra/trunk/clang-query/Query.h Wed Apr 23 09:04:52 2014
> @@ -28,9 +28,10 @@ enum QueryKind {
>    QK_Invalid,
>    QK_NoOp,
>    QK_Help,
> +  QK_Let,
>    QK_Match,
>    QK_SetBool,
> -  QK_SetOutputKind
> +  QK_SetOutputKind,
>  };
>
>  class QuerySession;
> @@ -86,6 +87,17 @@ struct MatchQuery : Query {
>    static bool classof(const Query *Q) { return Q->Kind == QK_Match; }
>  };
>
> +struct LetQuery : Query {
> +  LetQuery(StringRef Name, const ast_matchers::dynamic::VariantValue &Value)
> +      : Query(QK_Let), Name(Name), Value(Value) {}
> +  bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
> +
> +  std::string Name;
> +  ast_matchers::dynamic::VariantValue Value;
> +
> +  static bool classof(const Query *Q) { return Q->Kind == QK_Let; }
> +};
> +
>  template <typename T> struct SetQueryKind {};
>
>  template <> struct SetQueryKind<bool> {
>
> Modified: clang-tools-extra/trunk/clang-query/QueryParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/QueryParser.cpp?rev=206984&r1=206983&r2=206984&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/clang-query/QueryParser.cpp (original)
> +++ clang-tools-extra/trunk/clang-query/QueryParser.cpp Wed Apr 23 09:04:52 2014
> @@ -132,12 +132,16 @@ QueryRef QueryParser::endQuery(QueryRef
>    return Q;
>  }
>
> +namespace {
> +
>  enum ParsedQueryKind {
>    PQK_Invalid,
>    PQK_NoOp,
>    PQK_Help,
> +  PQK_Let,
>    PQK_Match,
> -  PQK_Set
> +  PQK_Set,
> +  PQK_Unlet,
>  };
>
>  enum ParsedQueryVariable {
> @@ -146,16 +150,52 @@ enum ParsedQueryVariable {
>    PQV_BindRoot
>  };
>
> +QueryRef makeInvalidQueryFromDiagnostics(const Diagnostics &Diag) {
> +  std::string ErrStr;
> +  llvm::raw_string_ostream OS(ErrStr);
> +  Diag.printToStreamFull(OS);
> +  return new InvalidQuery(OS.str());
> +}
> +
> +class QuerySessionSema : public Parser::RegistrySema {
> +public:
> +  QuerySessionSema(const QuerySession &QS) : QS(QS) {}
> +
> +  ast_matchers::dynamic::VariantValue getNamedValue(StringRef Name) override {
> +    return QS.NamedValues.lookup(Name);
> +  }
> +
> +private:
> +  const QuerySession &QS;
> +};
> +
> +}  // namespace
> +
> +QueryRef QueryParser::completeMatcherExpression() {
> +  std::vector<MatcherCompletion> Comps = Parser::completeExpression(
> +      StringRef(Begin, End - Begin), CompletionPos - Begin);
> +  for (std::vector<MatcherCompletion>::iterator I = Comps.begin(),
> +                                                E = Comps.end();
> +       I != E; ++I) {
> +    Completions.push_back(LineEditor::Completion(I->TypedText, I->MatcherDecl));
> +  }
> +  return QueryRef();
> +}
> +
>  QueryRef QueryParser::doParse() {
>    StringRef CommandStr;
>    ParsedQueryKind QKind = lexOrCompleteWord<ParsedQueryKind>(CommandStr)
>                                .Case("", PQK_NoOp)
>                                .Case("help", PQK_Help)
>                                .Case("m", PQK_Match, /*IsCompletion=*/false)
> +                              .Case("let", PQK_Let)
>                                .Case("match", PQK_Match)
>                                .Case("set", PQK_Set)
> +                              .Case("unlet", PQK_Unlet)
>                                .Default(PQK_Invalid);
>
> +  QuerySessionSema S(QS);
> +
>    switch (QKind) {
>    case PQK_NoOp:
>      return new NoOpQuery;
> @@ -163,29 +203,36 @@ QueryRef QueryParser::doParse() {
>    case PQK_Help:
>      return endQuery(new HelpQuery);
>
> +  case PQK_Let: {
> +    StringRef Name = lexWord();
> +
> +    if (Name.empty())
> +      return new InvalidQuery("expected variable name");
> +
> +    if (CompletionPos)
> +      return completeMatcherExpression();
> +
> +    Diagnostics Diag;
> +    ast_matchers::dynamic::VariantValue Value;
> +    if (!Parser::parseExpression(StringRef(Begin, End - Begin), &S, &Value,
> +                                 &Diag)) {
> +      return makeInvalidQueryFromDiagnostics(Diag);
> +    }
> +
> +    return new LetQuery(Name, Value);
> +  }
> +
>    case PQK_Match: {
> -    if (CompletionPos) {
> -      std::vector<MatcherCompletion> Comps = Parser::completeExpression(
> -          StringRef(Begin, End - Begin), CompletionPos - Begin);
> -      for (std::vector<MatcherCompletion>::iterator I = Comps.begin(),
> -                                                    E = Comps.end();
> -           I != E; ++I) {
> -        Completions.push_back(
> -            LineEditor::Completion(I->TypedText, I->MatcherDecl));
> -      }
> -      return QueryRef();
> -    } else {
> -      Diagnostics Diag;
> -      Optional<DynTypedMatcher> Matcher =
> -          Parser::parseMatcherExpression(StringRef(Begin, End - Begin), &Diag);
> -      if (!Matcher) {
> -        std::string ErrStr;
> -        llvm::raw_string_ostream OS(ErrStr);
> -        Diag.printToStreamFull(OS);
> -        return new InvalidQuery(OS.str());
> -      }
> -      return new MatchQuery(*Matcher);
> +    if (CompletionPos)
> +      return completeMatcherExpression();
> +
> +    Diagnostics Diag;
> +    Optional<DynTypedMatcher> Matcher = Parser::parseMatcherExpression(
> +        StringRef(Begin, End - Begin), &S, &Diag);
> +    if (!Matcher) {
> +      return makeInvalidQueryFromDiagnostics(Diag);
>      }
> +    return new MatchQuery(*Matcher);
>    }
>
>    case PQK_Set: {
> @@ -214,6 +261,15 @@ QueryRef QueryParser::doParse() {
>      return endQuery(Q);
>    }
>
> +  case PQK_Unlet: {
> +    StringRef Name = lexWord();
> +
> +    if (Name.empty())
> +      return new InvalidQuery("expected variable name");
> +
> +    return endQuery(new LetQuery(Name, {}));

This commit broke the MSVC build bots (because of the {}):
http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/8179

~Aaron



More information about the cfe-commits mailing list