Author: Nathan James
Date: 2021-04-28T11:21:35+01:00
New Revision: 858a9583e1fed24aa57e5f2769f4117883264ceb

URL: 
https://github.com/llvm/llvm-project/commit/858a9583e1fed24aa57e5f2769f4117883264ceb
DIFF: 
https://github.com/llvm/llvm-project/commit/858a9583e1fed24aa57e5f2769f4117883264ceb.diff

LOG: [clang-query] Add check to prevent setting srcloc when no introspection is 
available.

Checks if introspection support is available set output kind parser.
If it isn't present the auto complete will not suggest `srcloc` and an error 
query will be reported if a user tries to access it.

Reviewed By: steveire

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

Added: 
    

Modified: 
    clang-tools-extra/clang-query/Query.h
    clang-tools-extra/clang-query/QueryParser.cpp
    clang-tools-extra/unittests/clang-query/QueryParserTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-query/Query.h 
b/clang-tools-extra/clang-query/Query.h
index 38be29101c96a..f96bf196a6420 100644
--- a/clang-tools-extra/clang-query/Query.h
+++ b/clang-tools-extra/clang-query/Query.h
@@ -149,6 +149,7 @@ struct SetExclusiveOutputQuery : Query {
     QS.DiagOutput = false;
     QS.DetailedASTOutput = false;
     QS.PrintOutput = false;
+    QS.SrcLocOutput = false;
     QS.*Var = true;
     return true;
   }

diff  --git a/clang-tools-extra/clang-query/QueryParser.cpp 
b/clang-tools-extra/clang-query/QueryParser.cpp
index b444162cfc0a8..b80ad04726bcd 100644
--- a/clang-tools-extra/clang-query/QueryParser.cpp
+++ b/clang-tools-extra/clang-query/QueryParser.cpp
@@ -11,6 +11,7 @@
 #include "QuerySession.h"
 #include "clang/ASTMatchers/Dynamic/Parser.h"
 #include "clang/Basic/CharInfo.h"
+#include "clang/Tooling/NodeIntrospection.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
 #include <set>
@@ -104,17 +105,19 @@ QueryRef QueryParser::parseSetBool(bool 
QuerySession::*Var) {
 
 template <typename QueryType> QueryRef QueryParser::parseSetOutputKind() {
   StringRef ValStr;
-  unsigned OutKind = LexOrCompleteWord<unsigned>(this, ValStr)
-                         .Case("diag", OK_Diag)
-                         .Case("print", OK_Print)
-                         .Case("detailed-ast", OK_DetailedAST)
-                         .Case("srcloc", OK_SrcLoc)
-                         .Case("dump", OK_DetailedAST)
-                         .Default(~0u);
+  bool HasIntrospection = 
tooling::NodeIntrospection::hasIntrospectionSupport();
+  unsigned OutKind =
+      LexOrCompleteWord<unsigned>(this, ValStr)
+          .Case("diag", OK_Diag)
+          .Case("print", OK_Print)
+          .Case("detailed-ast", OK_DetailedAST)
+          .Case("srcloc", OK_SrcLoc, /*IsCompletion=*/HasIntrospection)
+          .Case("dump", OK_DetailedAST)
+          .Default(~0u);
   if (OutKind == ~0u) {
-    return new InvalidQuery(
-        "expected 'diag', 'print', 'detailed-ast' or 'dump', got '" + ValStr +
-        "'");
+    return new InvalidQuery("expected 'diag', 'print', 'detailed-ast'" +
+                            StringRef(HasIntrospection ? ", 'srcloc'" : "") +
+                            " or 'dump', got '" + ValStr + "'");
   }
 
   switch (OutKind) {
@@ -125,7 +128,9 @@ template <typename QueryType> QueryRef 
QueryParser::parseSetOutputKind() {
   case OK_Print:
     return new QueryType(&QuerySession::PrintOutput);
   case OK_SrcLoc:
-    return new QueryType(&QuerySession::SrcLocOutput);
+    if (HasIntrospection)
+      return new QueryType(&QuerySession::SrcLocOutput);
+    return new InvalidQuery("'srcloc' output support is not available.");
   }
 
   llvm_unreachable("Invalid output kind");

diff  --git a/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp 
b/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
index 713a6c23848a6..06b0d7b365904 100644
--- a/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
+++ b/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
@@ -9,6 +9,7 @@
 #include "QueryParser.h"
 #include "Query.h"
 #include "QuerySession.h"
+#include "clang/Tooling/NodeIntrospection.h"
 #include "llvm/LineEditor/LineEditor.h"
 #include "gtest/gtest.h"
 
@@ -59,6 +60,8 @@ TEST_F(QueryParserTest, Quit) {
 }
 
 TEST_F(QueryParserTest, Set) {
+
+  bool HasIntrospection = 
tooling::NodeIntrospection::hasIntrospectionSupport();
   QueryRef Q = parse("set");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
   EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr);
@@ -69,8 +72,13 @@ TEST_F(QueryParserTest, Set) {
 
   Q = parse("set output");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
-  EXPECT_EQ("expected 'diag', 'print', 'detailed-ast' or 'dump', got ''",
-            cast<InvalidQuery>(Q)->ErrStr);
+  if (HasIntrospection)
+    EXPECT_EQ(
+        "expected 'diag', 'print', 'detailed-ast', 'srcloc' or 'dump', got ''",
+        cast<InvalidQuery>(Q)->ErrStr);
+  else
+    EXPECT_EQ("expected 'diag', 'print', 'detailed-ast' or 'dump', got ''",
+              cast<InvalidQuery>(Q)->ErrStr);
 
   Q = parse("set bind-root true foo");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
@@ -78,8 +86,13 @@ TEST_F(QueryParserTest, Set) {
 
   Q = parse("set output foo");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
-  EXPECT_EQ("expected 'diag', 'print', 'detailed-ast' or 'dump', got 'foo'",
-            cast<InvalidQuery>(Q)->ErrStr);
+  if (HasIntrospection)
+    EXPECT_EQ("expected 'diag', 'print', 'detailed-ast', 'srcloc' or 'dump', "
+              "got 'foo'",
+              cast<InvalidQuery>(Q)->ErrStr);
+  else
+    EXPECT_EQ("expected 'diag', 'print', 'detailed-ast' or 'dump', got 'foo'",
+              cast<InvalidQuery>(Q)->ErrStr);
 
   Q = parse("set output dump");
   ASSERT_TRUE(isa<SetExclusiveOutputQuery >(Q));
@@ -217,8 +230,10 @@ TEST_F(QueryParserTest, Complete) {
   EXPECT_EQ("output ", Comps[0].TypedText);
   EXPECT_EQ("output", Comps[0].DisplayText);
 
+  bool HasIntrospection = 
tooling::NodeIntrospection::hasIntrospectionSupport();
+
   Comps = QueryParser::complete("enable output ", 14, QS);
-  ASSERT_EQ(5u, Comps.size());
+  ASSERT_EQ(HasIntrospection ? 5u : 4u, Comps.size());
 
   EXPECT_EQ("diag ", Comps[0].TypedText);
   EXPECT_EQ("diag", Comps[0].DisplayText);
@@ -226,10 +241,12 @@ TEST_F(QueryParserTest, Complete) {
   EXPECT_EQ("print", Comps[1].DisplayText);
   EXPECT_EQ("detailed-ast ", Comps[2].TypedText);
   EXPECT_EQ("detailed-ast", Comps[2].DisplayText);
-  EXPECT_EQ("srcloc ", Comps[3].TypedText);
-  EXPECT_EQ("srcloc", Comps[3].DisplayText);
-  EXPECT_EQ("dump ", Comps[4].TypedText);
-  EXPECT_EQ("dump", Comps[4].DisplayText);
+  if (HasIntrospection) {
+    EXPECT_EQ("srcloc ", Comps[3].TypedText);
+    EXPECT_EQ("srcloc", Comps[3].DisplayText);
+  }
+  EXPECT_EQ("dump ", Comps[HasIntrospection ? 4 : 3].TypedText);
+  EXPECT_EQ("dump", Comps[HasIntrospection ? 4 : 3].DisplayText);
 
   Comps = QueryParser::complete("set traversal ", 14, QS);
   ASSERT_EQ(2u, Comps.size());


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to