steveire updated this revision to Diff 170310.
steveire added a comment.

Don't deprecate existing API


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D52857

Files:
  clang-query/Query.cpp
  clang-query/Query.h
  clang-query/QueryParser.cpp
  clang-query/QuerySession.h
  unittests/clang-query/QueryEngineTest.cpp
  unittests/clang-query/QueryParserTest.cpp

Index: unittests/clang-query/QueryParserTest.cpp
===================================================================
--- unittests/clang-query/QueryParserTest.cpp
+++ unittests/clang-query/QueryParserTest.cpp
@@ -59,6 +59,35 @@
   EXPECT_EQ("unexpected extra input: ' me'", cast<InvalidQuery>(Q)->ErrStr);
 }
 
+TEST_F(QueryParserTest, Exclusive) {
+  QueryRef Q = parse("set output");
+  ASSERT_TRUE(isa<InvalidQuery>(Q));
+  EXPECT_EQ("expected 'diag', 'print' or 'dump', got ''",
+            cast<InvalidQuery>(Q)->ErrStr);
+
+  Q = parse("set output foo");
+  ASSERT_TRUE(isa<InvalidQuery>(Q));
+  EXPECT_EQ("expected 'diag', 'print' or 'dump', got 'foo'",
+            cast<InvalidQuery>(Q)->ErrStr);
+
+  Q = parse("set output dump");
+  ASSERT_TRUE(isa<SetOutputQuery>(Q));
+  EXPECT_EQ(&QuerySession::ASTOutput, cast<SetOutputQuery>(Q)->Var);
+  std::string Str;
+  llvm::raw_string_ostream OS(Str);
+  Q->run(OS, QS);
+  EXPECT_EQ(true, QS.ASTOutput);
+  EXPECT_EQ(false, QS.DiagOutput);
+  EXPECT_EQ(false, QS.PrintOutput);
+
+  std::vector<llvm::LineEditor::Completion> Comps =
+      QueryParser::complete("", 0, QS);
+  Comps = QueryParser::complete("set o", 5, QS);
+  ASSERT_EQ(1u, Comps.size());
+  EXPECT_EQ("utput ", Comps[0].TypedText);
+  EXPECT_EQ("output", Comps[0].DisplayText);
+}
+
 TEST_F(QueryParserTest, Set) {
   QueryRef Q = parse("set");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
@@ -68,24 +97,24 @@
   ASSERT_TRUE(isa<InvalidQuery>(Q));
   EXPECT_EQ("unknown variable: 'foo'", cast<InvalidQuery>(Q)->ErrStr);
 
-  Q = parse("set output");
+  Q = parse("set ast-output");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
-  EXPECT_EQ("expected 'diag', 'print' or 'dump', got ''",
+  EXPECT_EQ("expected 'true' or 'false', got ''",
             cast<InvalidQuery>(Q)->ErrStr);
 
   Q = parse("set bind-root true foo");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
   EXPECT_EQ("unexpected extra input: ' foo'", cast<InvalidQuery>(Q)->ErrStr);
 
-  Q = parse("set output foo");
+  Q = parse("set ast-output foo");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
-  EXPECT_EQ("expected 'diag', 'print' or 'dump', got 'foo'",
+  EXPECT_EQ("expected 'true' or 'false', got 'foo'",
             cast<InvalidQuery>(Q)->ErrStr);
 
-  Q = parse("set output dump");
-  ASSERT_TRUE(isa<SetQuery<OutputKind> >(Q));
-  EXPECT_EQ(&QuerySession::OutKind, cast<SetQuery<OutputKind> >(Q)->Var);
-  EXPECT_EQ(OK_Dump, cast<SetQuery<OutputKind> >(Q)->Value);
+  Q = parse("set ast-output true");
+  ASSERT_TRUE(isa<SetQuery<bool>>(Q));
+  EXPECT_EQ(&QuerySession::ASTOutput, cast<SetQuery<bool>>(Q)->Var);
+  EXPECT_EQ(true, cast<SetQuery<bool>>(Q)->Value);
 
   Q = parse("set bind-root foo");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
@@ -174,10 +203,14 @@
   EXPECT_EQ("unlet ", Comps[5].TypedText);
   EXPECT_EQ("unlet", Comps[5].DisplayText);
 
-  Comps = QueryParser::complete("set o", 5, QS);
+  Comps = QueryParser::complete("set d", 5, QS);
   ASSERT_EQ(1u, Comps.size());
-  EXPECT_EQ("utput ", Comps[0].TypedText);
-  EXPECT_EQ("output", Comps[0].DisplayText);
+  EXPECT_EQ("iag-output ", Comps[0].TypedText);
+  EXPECT_EQ("diag-output", Comps[0].DisplayText);
+  Comps = QueryParser::complete("set a", 5, QS);
+  ASSERT_EQ(1u, Comps.size());
+  EXPECT_EQ("st-output ", Comps[0].TypedText);
+  EXPECT_EQ("ast-output", Comps[0].DisplayText);
 
   Comps = QueryParser::complete("match while", 11, QS);
   ASSERT_EQ(1u, Comps.size());
Index: unittests/clang-query/QueryEngineTest.cpp
===================================================================
--- unittests/clang-query/QueryEngineTest.cpp
+++ unittests/clang-query/QueryEngineTest.cpp
@@ -48,6 +48,24 @@
   llvm::raw_string_ostream OS;
 };
 
+TEST_F(QueryEngineTest, Exclusive) {
+  DynTypedMatcher FooMatcher = functionDecl(hasName("foo1"));
+
+  EXPECT_TRUE(SetOutputQuery(&QuerySession::PrintOutput).run(OS, S));
+  EXPECT_TRUE(MatchQuery("functionDecl(hasName(\"foo1\"))", FooMatcher).run(OS, S));
+
+  EXPECT_TRUE(OS.str().find("Binding for \"root\":\nvoid foo1()") !=
+              std::string::npos);
+
+  Str.clear();
+
+  EXPECT_TRUE(SetOutputQuery(&QuerySession::ASTOutput).run(OS, S));
+  EXPECT_TRUE(MatchQuery("functionDecl(hasName(\"foo1\"))", FooMatcher).run(OS, S));
+  EXPECT_TRUE(OS.str().find("FunctionDecl") != std::string::npos);
+
+  Str.clear();
+}
+
 TEST_F(QueryEngineTest, Basic) {
   DynTypedMatcher FnMatcher = functionDecl();
   DynTypedMatcher FooMatcher = functionDecl(hasName("foo1"));
@@ -94,22 +112,36 @@
 
   Str.clear();
 
-  EXPECT_TRUE(
-      SetQuery<OutputKind>(&QuerySession::OutKind, OK_Print).run(OS, S));
+  EXPECT_TRUE(SetQuery<bool>(&QuerySession::DiagOutput, false).run(OS, S));
+  EXPECT_TRUE(SetQuery<bool>(&QuerySession::PrintOutput, true).run(OS, S));
   EXPECT_TRUE(MatchQuery(FooMatcherString, FooMatcher).run(OS, S));
 
   EXPECT_TRUE(OS.str().find("Binding for \"root\":\nvoid foo1()") !=
               std::string::npos);
 
   Str.clear();
 
-  EXPECT_TRUE(SetQuery<OutputKind>(&QuerySession::OutKind, OK_Dump).run(OS, S));
+  EXPECT_TRUE(SetQuery<bool>(&QuerySession::PrintOutput, false).run(OS, S));
+  EXPECT_TRUE(SetQuery<bool>(&QuerySession::ASTOutput, true).run(OS, S));
   EXPECT_TRUE(MatchQuery(FooMatcherString, FooMatcher).run(OS, S));
 
   EXPECT_TRUE(OS.str().find("FunctionDecl") != std::string::npos);
 
   Str.clear();
 
+  EXPECT_TRUE(SetQuery<bool>(&QuerySession::DiagOutput, true).run(OS, S));
+  EXPECT_TRUE(SetQuery<bool>(&QuerySession::ASTOutput, true).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));
 
Index: clang-query/QuerySession.h
===================================================================
--- clang-query/QuerySession.h
+++ clang-query/QuerySession.h
@@ -25,13 +25,15 @@
 class QuerySession {
 public:
   QuerySession(llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs)
-      : ASTs(ASTs), OutKind(OK_Diag), BindRoot(true), PrintMatcher(false),
-        Terminate(false) {}
+      : ASTs(ASTs), BindRoot(true), PrintMatcher(false), DiagOutput(true), ASTOutput(false),
+        PrintOutput(false), Terminate(false) {}
 
   llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs;
-  OutputKind OutKind;
   bool BindRoot;
   bool PrintMatcher;
+  bool DiagOutput;
+  bool ASTOutput;
+  bool PrintOutput;
   bool Terminate;
   llvm::StringMap<ast_matchers::dynamic::VariantValue> NamedValues;
 };
Index: clang-query/QueryParser.cpp
===================================================================
--- clang-query/QueryParser.cpp
+++ clang-query/QueryParser.cpp
@@ -117,7 +117,17 @@
     return new InvalidQuery("expected 'diag', 'print' or 'dump', got '" +
                             ValStr + "'");
   }
-  return new SetQuery<OutputKind>(&QuerySession::OutKind, OutputKind(OutKind));
+
+  switch (OutKind) {
+  case OK_Dump:
+    return new SetOutputQuery(&QuerySession::ASTOutput);
+  case OK_Diag:
+    return new SetOutputQuery(&QuerySession::DiagOutput);
+  case OK_Print:
+    return new SetOutputQuery(&QuerySession::PrintOutput);
+  }
+
+  llvm_unreachable("Invalid output kind");
 }
 
 QueryRef QueryParser::endQuery(QueryRef Q) {
@@ -146,7 +156,10 @@
   PQV_Invalid,
   PQV_Output,
   PQV_BindRoot,
-  PQV_PrintMatcher
+  PQV_PrintMatcher,
+  PQV_ASTOutput,
+  PQV_DiagOutput,
+  PQV_PrintOutput
 };
 
 QueryRef makeInvalidQueryFromDiagnostics(const Diagnostics &Diag) {
@@ -235,6 +248,9 @@
             .Case("output", PQV_Output)
             .Case("bind-root", PQV_BindRoot)
             .Case("print-matcher", PQV_PrintMatcher)
+            .Case("ast-output", PQV_ASTOutput)
+            .Case("diag-output", PQV_DiagOutput)
+            .Case("print-output", PQV_PrintOutput)
             .Default(PQV_Invalid);
     if (VarStr.empty())
       return new InvalidQuery("expected variable name");
@@ -252,6 +268,15 @@
     case PQV_PrintMatcher:
       Q = parseSetBool(&QuerySession::PrintMatcher);
       break;
+    case PQV_ASTOutput:
+      Q = parseSetBool(&QuerySession::ASTOutput);
+      break;
+    case PQV_DiagOutput:
+      Q = parseSetBool(&QuerySession::DiagOutput);
+      break;
+    case PQV_PrintOutput:
+      Q = parseSetBool(&QuerySession::PrintOutput);
+      break;
     case PQV_Invalid:
       llvm_unreachable("Invalid query kind");
     }
Index: clang-query/Query.h
===================================================================
--- clang-query/Query.h
+++ clang-query/Query.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
 
+#include "QuerySession.h"
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/Optional.h"
@@ -119,7 +120,7 @@
 /// Query for "set VAR VALUE".
 template <typename T> struct SetQuery : Query {
   SetQuery(T QuerySession::*Var, T Value)
-      : Query(SetQueryKind<T>::value), Var(Var), Value(Value) {}
+      : Query(QK_SetBool), Var(Var), Value(Value) {}
   bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
     QS.*Var = Value;
     return true;
@@ -133,6 +134,22 @@
   T Value;
 };
 
+// Implements the exclusive 'set output dump|diag|print' options
+struct SetOutputQuery : Query {
+  SetOutputQuery(bool QuerySession::*Var) : Query(QK_SetOutputKind), Var(Var) {}
+  bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
+    QS.DiagOutput = false;
+    QS.ASTOutput = false;
+    QS.PrintOutput = false;
+    QS.*Var = true;
+    return true;
+  }
+
+  static bool classof(const Query *Q) { return Q->Kind == QK_SetOutputKind; }
+
+  bool QuerySession::*Var;
+};
+
 } // namespace query
 } // namespace clang
 
Index: clang-query/Query.cpp
===================================================================
--- clang-query/Query.cpp
+++ clang-query/Query.cpp
@@ -41,12 +41,18 @@
         "as part of other expressions.\n"
         "  set bind-root (true|false)        "
         "Set whether to bind the root matcher to \"root\".\n"
-        "  set print-matcher (true|false)    "
-        "Set whether to print the current matcher,\n"
         "  set output (diag|print|dump)      "
         "Set whether to print bindings as diagnostics,\n"
         "                                    "
         "AST pretty prints or AST dumps.\n"
+        "  set print-matcher (true|false)    "
+        "Set whether to print the current matcher,\n"
+        "  set diag-output (true|false)      "
+        "Set whether to print binding diagnostic locations.\n"
+        "  set ast-output (true|false)       "
+        "Set whether to dump binding ASTs.\n"
+        "  set print-output (true|false)     "
+        "Set whether to print matched text.\n"
         "  quit, q                           "
         "Terminates the query session.\n\n";
   return true;
@@ -99,8 +105,7 @@
 
       for (auto BI = MI->getMap().begin(), BE = MI->getMap().end(); BI != BE;
            ++BI) {
-        switch (QS.OutKind) {
-        case OK_Diag: {
+        if (QS.DiagOutput) {
           clang::SourceRange R = BI->second.getSourceRange();
           if (R.isValid()) {
             TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(),
@@ -110,20 +115,16 @@
                 DiagnosticsEngine::Note, "\"" + BI->first + "\" binds here",
                 CharSourceRange::getTokenRange(R), None);
           }
-          break;
         }
-        case OK_Print: {
+        if (QS.PrintOutput) {
           OS << "Binding for \"" << BI->first << "\":\n";
           BI->second.print(OS, AST->getASTContext().getPrintingPolicy());
           OS << "\n";
-          break;
         }
-        case OK_Dump: {
+        if (QS.ASTOutput) {
           OS << "Binding for \"" << BI->first << "\":\n";
           BI->second.dump(OS, AST->getSourceManager());
           OS << "\n";
-          break;
-        }
         }
       }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to