[clang-tools-extra] r345522 - [clang-query] Add non-exclusive output API

Stephen Kelly via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 29 11:59:57 PDT 2018


Author: steveire
Date: Mon Oct 29 11:59:56 2018
New Revision: 345522

URL: http://llvm.org/viewvc/llvm-project?rev=345522&view=rev
Log:
[clang-query] Add non-exclusive output API

Summary:
Add granular options for AST dumping, text printing and diagnostics.

This makes it possible to

* Have both diag and dump active at once
* Extend the output with other queryable content in the future.

Reviewers: aaron.ballman, pcc, ioeric, ilya-biryukov, klimek, sammccall

Reviewed By: aaron.ballman

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D52857

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/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=345522&r1=345521&r2=345522&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-query/Query.cpp (original)
+++ clang-tools-extra/trunk/clang-query/Query.cpp Mon Oct 29 11:59:56 2018
@@ -45,6 +45,10 @@ bool HelpQuery::run(llvm::raw_ostream &O
         "Set whether to print the current matcher,\n"
         "  set output <feature>              "
         "Set whether to output only <feature> content.\n"
+        "  enable output <feature>           "
+        "Enable <feature> content non-exclusively.\n"
+        "  disable output <feature>          "
+        "Disable <feature> content non-exclusively.\n"
         "  quit, q                           "
         "Terminates the query session.\n\n"
         "Several commands accept a <feature> parameter. The available features "

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=345522&r1=345521&r2=345522&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-query/Query.h (original)
+++ clang-tools-extra/trunk/clang-query/Query.h Mon Oct 29 11:59:56 2018
@@ -29,6 +29,8 @@ enum QueryKind {
   QK_Match,
   QK_SetBool,
   QK_SetOutputKind,
+  QK_EnableOutputKind,
+  QK_DisableOutputKind,
   QK_Quit
 };
 
@@ -151,6 +153,36 @@ struct SetExclusiveOutputQuery : Query {
   bool QuerySession::*Var;
 };
 
+// Implements the non-exclusive 'set output dump|diag|print' options.
+struct SetNonExclusiveOutputQuery : Query {
+  SetNonExclusiveOutputQuery(QueryKind Kind, bool QuerySession::*Var,
+                             bool Value)
+      : Query(Kind), Var(Var), Value(Value) {}
+  bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
+    QS.*Var = Value;
+    return true;
+  }
+
+  bool QuerySession::*Var;
+  bool Value;
+};
+
+struct EnableOutputQuery : SetNonExclusiveOutputQuery {
+  EnableOutputQuery(bool QuerySession::*Var)
+      : SetNonExclusiveOutputQuery(QK_EnableOutputKind, Var, true) {}
+
+  static bool classof(const Query *Q) { return Q->Kind == QK_EnableOutputKind; }
+};
+
+struct DisableOutputQuery : SetNonExclusiveOutputQuery {
+  DisableOutputQuery(bool QuerySession::*Var)
+      : SetNonExclusiveOutputQuery(QK_DisableOutputKind, Var, false) {}
+
+  static bool classof(const Query *Q) {
+    return Q->Kind == QK_DisableOutputKind;
+  }
+};
+
 } // namespace query
 } // namespace clang
 

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=345522&r1=345521&r2=345522&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-query/QueryParser.cpp (original)
+++ clang-tools-extra/trunk/clang-query/QueryParser.cpp Mon Oct 29 11:59:56 2018
@@ -106,7 +106,7 @@ QueryRef QueryParser::parseSetBool(bool
   return new SetQuery<bool>(Var, Value);
 }
 
-QueryRef QueryParser::parseSetOutputKind() {
+template <typename QueryType> QueryRef QueryParser::parseSetOutputKind() {
   StringRef ValStr;
   unsigned OutKind = LexOrCompleteWord<unsigned>(this, ValStr)
                          .Case("diag", OK_Diag)
@@ -122,11 +122,11 @@ QueryRef QueryParser::parseSetOutputKind
 
   switch (OutKind) {
   case OK_DetailedAST:
-    return new SetExclusiveOutputQuery(&QuerySession::DetailedASTOutput);
+    return new QueryType(&QuerySession::DetailedASTOutput);
   case OK_Diag:
-    return new SetExclusiveOutputQuery(&QuerySession::DiagOutput);
+    return new QueryType(&QuerySession::DiagOutput);
   case OK_Print:
-    return new SetExclusiveOutputQuery(&QuerySession::PrintOutput);
+    return new QueryType(&QuerySession::PrintOutput);
   }
 
   llvm_unreachable("Invalid output kind");
@@ -151,7 +151,9 @@ enum ParsedQueryKind {
   PQK_Match,
   PQK_Set,
   PQK_Unlet,
-  PQK_Quit
+  PQK_Quit,
+  PQK_Enable,
+  PQK_Disable
 };
 
 enum ParsedQueryVariable {
@@ -193,6 +195,8 @@ QueryRef QueryParser::doParse() {
                               .Case("q", PQK_Quit,  /*IsCompletion=*/false)
                               .Case("quit", PQK_Quit)
                               .Case("set", PQK_Set)
+                              .Case("enable", PQK_Enable)
+                              .Case("disable", PQK_Disable)
                               .Case("unlet", PQK_Unlet)
                               .Default(PQK_Invalid);
 
@@ -256,7 +260,7 @@ QueryRef QueryParser::doParse() {
     QueryRef Q;
     switch (Var) {
     case PQV_Output:
-      Q = parseSetOutputKind();
+      Q = parseSetOutputKind<SetExclusiveOutputQuery>();
       break;
     case PQV_BindRoot:
       Q = parseSetBool(&QuerySession::BindRoot);
@@ -270,6 +274,28 @@ QueryRef QueryParser::doParse() {
 
     return endQuery(Q);
   }
+  case PQK_Enable:
+  case PQK_Disable: {
+    StringRef VarStr;
+    ParsedQueryVariable Var =
+        LexOrCompleteWord<ParsedQueryVariable>(this, VarStr)
+            .Case("output", PQV_Output)
+            .Default(PQV_Invalid);
+    if (VarStr.empty())
+      return new InvalidQuery("expected variable name");
+    if (Var == PQV_Invalid)
+      return new InvalidQuery("unknown variable: '" + VarStr + "'");
+
+    QueryRef Q;
+
+    if (QKind == PQK_Enable)
+      Q = parseSetOutputKind<EnableOutputQuery>();
+    else if (QKind == PQK_Disable)
+      Q = parseSetOutputKind<DisableOutputQuery>();
+    else
+      llvm_unreachable("Invalid query kind");
+    return endQuery(Q);
+  }
 
   case PQK_Unlet: {
     StringRef Name = lexWord();

Modified: clang-tools-extra/trunk/clang-query/QueryParser.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/QueryParser.h?rev=345522&r1=345521&r2=345522&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-query/QueryParser.h (original)
+++ clang-tools-extra/trunk/clang-query/QueryParser.h Mon Oct 29 11:59:56 2018
@@ -44,7 +44,7 @@ private:
   template <typename T> struct LexOrCompleteWord;
 
   QueryRef parseSetBool(bool QuerySession::*Var);
-  QueryRef parseSetOutputKind();
+  template <typename QueryType> QueryRef parseSetOutputKind();
   QueryRef completeMatcherExpression();
 
   QueryRef endQuery(QueryRef Q);

Modified: clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp?rev=345522&r1=345521&r2=345522&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp Mon Oct 29 11:59:56 2018
@@ -111,6 +111,19 @@ TEST_F(QueryEngineTest, Basic) {
 
   Str.clear();
 
+  EXPECT_TRUE(EnableOutputQuery(&QuerySession::DiagOutput).run(OS, S));
+  EXPECT_TRUE(EnableOutputQuery(&QuerySession::DetailedASTOutput).run(OS, S));
+  EXPECT_TRUE(MatchQuery(FooMatcherString, FooMatcher).run(OS, S));
+
+  {
+    auto Output = OS.str();
+    EXPECT_TRUE(Output.find("FunctionDecl") != std::string::npos);
+    EXPECT_TRUE(Output.find("foo.cc:1:1: note: \"root\" binds here") !=
+                std::string::npos);
+  }
+
+  Str.clear();
+
   EXPECT_TRUE(SetQuery<bool>(&QuerySession::BindRoot, false).run(OS, S));
   EXPECT_TRUE(MatchQuery(FooMatcherString, FooMatcher).run(OS, S));
 

Modified: clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp?rev=345522&r1=345521&r2=345522&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp Mon Oct 29 11:59:56 2018
@@ -90,6 +90,18 @@ TEST_F(QueryParserTest, Set) {
   ASSERT_TRUE(isa<SetExclusiveOutputQuery>(Q));
   EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<SetExclusiveOutputQuery>(Q)->Var);
 
+  Q = parse("enable output detailed-ast");
+  ASSERT_TRUE(isa<EnableOutputQuery>(Q));
+  EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<EnableOutputQuery>(Q)->Var);
+
+  Q = parse("enable");
+  ASSERT_TRUE(isa<InvalidQuery>(Q));
+  EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr);
+
+  Q = parse("disable output detailed-ast");
+  ASSERT_TRUE(isa<DisableOutputQuery>(Q));
+  EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<DisableOutputQuery>(Q)->Var);
+
   Q = parse("set bind-root foo");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
   EXPECT_EQ("expected 'true' or 'false', got 'foo'",
@@ -163,7 +175,7 @@ TEST_F(QueryParserTest, Comment) {
 TEST_F(QueryParserTest, Complete) {
   std::vector<llvm::LineEditor::Completion> Comps =
       QueryParser::complete("", 0, QS);
-  ASSERT_EQ(6u, Comps.size());
+  ASSERT_EQ(8u, Comps.size());
   EXPECT_EQ("help ", Comps[0].TypedText);
   EXPECT_EQ("help", Comps[0].DisplayText);
   EXPECT_EQ("let ", Comps[1].TypedText);
@@ -174,14 +186,35 @@ TEST_F(QueryParserTest, Complete) {
   EXPECT_EQ("quit", Comps[3].DisplayText);
   EXPECT_EQ("set ", Comps[4].TypedText);
   EXPECT_EQ("set", Comps[4].DisplayText);
-  EXPECT_EQ("unlet ", Comps[5].TypedText);
-  EXPECT_EQ("unlet", Comps[5].DisplayText);
+  EXPECT_EQ("enable ", Comps[5].TypedText);
+  EXPECT_EQ("enable", Comps[5].DisplayText);
+  EXPECT_EQ("disable ", Comps[6].TypedText);
+  EXPECT_EQ("disable", Comps[6].DisplayText);
+  EXPECT_EQ("unlet ", Comps[7].TypedText);
+  EXPECT_EQ("unlet", Comps[7].DisplayText);
 
   Comps = QueryParser::complete("set o", 5, QS);
   ASSERT_EQ(1u, Comps.size());
   EXPECT_EQ("utput ", Comps[0].TypedText);
   EXPECT_EQ("output", Comps[0].DisplayText);
 
+  Comps = QueryParser::complete("enable ", 7, QS);
+  ASSERT_EQ(1u, Comps.size());
+  EXPECT_EQ("output ", Comps[0].TypedText);
+  EXPECT_EQ("output", Comps[0].DisplayText);
+
+  Comps = QueryParser::complete("enable output ", 14, QS);
+  ASSERT_EQ(4u, Comps.size());
+
+  EXPECT_EQ("diag ", Comps[0].TypedText);
+  EXPECT_EQ("diag", Comps[0].DisplayText);
+  EXPECT_EQ("print ", Comps[1].TypedText);
+  EXPECT_EQ("print", Comps[1].DisplayText);
+  EXPECT_EQ("detailed-ast ", Comps[2].TypedText);
+  EXPECT_EQ("detailed-ast", Comps[2].DisplayText);
+  EXPECT_EQ("dump ", Comps[3].TypedText);
+  EXPECT_EQ("dump", Comps[3].DisplayText);
+
   Comps = QueryParser::complete("match while", 11, QS);
   ASSERT_EQ(1u, Comps.size());
   EXPECT_EQ("Stmt(", Comps[0].TypedText);




More information about the cfe-commits mailing list