[clang-tools-extra] 10f0f98 - Add a way to set traversal mode in clang-query

Stephen Kelly via cfe-commits cfe-commits at lists.llvm.org
Sat May 23 06:57:33 PDT 2020


Author: Stephen Kelly
Date: 2020-05-23T14:57:10+01:00
New Revision: 10f0f98eac5b20796ae804a2df2a9d853d59d3bd

URL: https://github.com/llvm/llvm-project/commit/10f0f98eac5b20796ae804a2df2a9d853d59d3bd
DIFF: https://github.com/llvm/llvm-project/commit/10f0f98eac5b20796ae804a2df2a9d853d59d3bd.diff

LOG: Add a way to set traversal mode in clang-query

Reviewers: aaron.ballman

Subscribers: cfe-commits

Tags: #clang

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-query/Query.cpp b/clang-tools-extra/clang-query/Query.cpp
index 8eafc5eed750..2fc7af6a56e1 100644
--- a/clang-tools-extra/clang-query/Query.cpp
+++ b/clang-tools-extra/clang-query/Query.cpp
@@ -43,6 +43,15 @@ bool HelpQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
         "Set whether to bind the root matcher to \"root\".\n"
         "  set print-matcher (true|false)    "
         "Set whether to print the current matcher,\n"
+        "  set traversal <kind>              "
+        "Set traversal kind of clang-query session. Available kinds are:\n"
+        "    AsIs                            "
+        "Print and match the AST as clang sees it.\n"
+        "    IgnoreImplicitCastsAndParentheses  "
+        "Omit implicit casts and parens in matching and dumping.\n"
+        "    IgnoreUnlessSpelledInSource     "
+        "Omit AST nodes unless spelled in the source.  This mode is the "
+        "default.\n"
         "  set output <feature>              "
         "Set whether to output only <feature> content.\n"
         "  enable output <feature>           "
@@ -98,6 +107,8 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
       OS << "Not a valid top-level matcher.\n";
       return false;
     }
+
+    AST->getASTContext().getParentMapContext().setTraversalKind(QS.TK);
     Finder.matchAST(AST->getASTContext());
 
     if (QS.PrintMatcher) {
@@ -148,6 +159,7 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
           const SourceManager &SM = Ctx.getSourceManager();
           ASTDumper Dumper(OS, &Ctx.getCommentCommandTraits(), &SM,
                 SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
+          Dumper.SetTraversalKind(QS.TK);
           Dumper.Visit(BI->second);
           OS << "\n";
         }

diff  --git a/clang-tools-extra/clang-query/Query.h b/clang-tools-extra/clang-query/Query.h
index 78bcbc79cdf8..223644fe2e51 100644
--- a/clang-tools-extra/clang-query/Query.h
+++ b/clang-tools-extra/clang-query/Query.h
@@ -28,6 +28,7 @@ enum QueryKind {
   QK_Match,
   QK_SetBool,
   QK_SetOutputKind,
+  QK_SetTraversalKind,
   QK_EnableOutputKind,
   QK_DisableOutputKind,
   QK_Quit
@@ -119,6 +120,10 @@ template <> struct SetQueryKind<OutputKind> {
   static const QueryKind value = QK_SetOutputKind;
 };
 
+template <> struct SetQueryKind<ast_type_traits::TraversalKind> {
+  static const QueryKind value = QK_SetTraversalKind;
+};
+
 /// Query for "set VAR VALUE".
 template <typename T> struct SetQuery : Query {
   SetQuery(T QuerySession::*Var, T Value)

diff  --git a/clang-tools-extra/clang-query/QueryParser.cpp b/clang-tools-extra/clang-query/QueryParser.cpp
index ecc189a7db2f..2f1965e77ab4 100644
--- a/clang-tools-extra/clang-query/QueryParser.cpp
+++ b/clang-tools-extra/clang-query/QueryParser.cpp
@@ -128,6 +128,24 @@ template <typename QueryType> QueryRef QueryParser::parseSetOutputKind() {
   llvm_unreachable("Invalid output kind");
 }
 
+QueryRef QueryParser::parseSetTraversalKind(
+    ast_type_traits::TraversalKind QuerySession::*Var) {
+  StringRef ValStr;
+  unsigned Value =
+      LexOrCompleteWord<unsigned>(this, ValStr)
+          .Case("AsIs", ast_type_traits::TK_AsIs)
+          .Case("IgnoreImplicitCastsAndParentheses",
+                ast_type_traits::TK_IgnoreImplicitCastsAndParentheses)
+          .Case("IgnoreUnlessSpelledInSource",
+                ast_type_traits::TK_IgnoreUnlessSpelledInSource)
+          .Default(~0u);
+  if (Value == ~0u) {
+    return new InvalidQuery("expected traversal kind, got '" + ValStr + "'");
+  }
+  return new SetQuery<ast_type_traits::TraversalKind>(
+      Var, static_cast<ast_type_traits::TraversalKind>(Value));
+}
+
 QueryRef QueryParser::endQuery(QueryRef Q) {
   StringRef Extra = Line;
   StringRef ExtraTrimmed = Extra.drop_while(
@@ -171,7 +189,8 @@ enum ParsedQueryVariable {
   PQV_Invalid,
   PQV_Output,
   PQV_BindRoot,
-  PQV_PrintMatcher
+  PQV_PrintMatcher,
+  PQV_Traversal
 };
 
 QueryRef makeInvalidQueryFromDiagnostics(const Diagnostics &Diag) {
@@ -272,6 +291,7 @@ QueryRef QueryParser::doParse() {
             .Case("output", PQV_Output)
             .Case("bind-root", PQV_BindRoot)
             .Case("print-matcher", PQV_PrintMatcher)
+            .Case("traversal", PQV_Traversal)
             .Default(PQV_Invalid);
     if (VarStr.empty())
       return new InvalidQuery("expected variable name");
@@ -289,6 +309,9 @@ QueryRef QueryParser::doParse() {
     case PQV_PrintMatcher:
       Q = parseSetBool(&QuerySession::PrintMatcher);
       break;
+    case PQV_Traversal:
+      Q = parseSetTraversalKind(&QuerySession::TK);
+      break;
     case PQV_Invalid:
       llvm_unreachable("Invalid query kind");
     }

diff  --git a/clang-tools-extra/clang-query/QueryParser.h b/clang-tools-extra/clang-query/QueryParser.h
index 12664777ee44..68f420dc0994 100644
--- a/clang-tools-extra/clang-query/QueryParser.h
+++ b/clang-tools-extra/clang-query/QueryParser.h
@@ -43,6 +43,8 @@ class QueryParser {
   template <typename T> struct LexOrCompleteWord;
 
   QueryRef parseSetBool(bool QuerySession::*Var);
+  QueryRef
+  parseSetTraversalKind(ast_type_traits::TraversalKind QuerySession::*Var);
   template <typename QueryType> QueryRef parseSetOutputKind();
   QueryRef completeMatcherExpression();
 

diff  --git a/clang-tools-extra/clang-query/QuerySession.h b/clang-tools-extra/clang-query/QuerySession.h
index 0f3bc1aa6464..1660e4039f61 100644
--- a/clang-tools-extra/clang-query/QuerySession.h
+++ b/clang-tools-extra/clang-query/QuerySession.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_SESSION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_SESSION_H
 
+#include "clang/AST/ASTTypeTraits.h"
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringMap.h"
@@ -25,7 +26,7 @@ class QuerySession {
   QuerySession(llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs)
       : ASTs(ASTs), PrintOutput(false), DiagOutput(true),
         DetailedASTOutput(false), BindRoot(true), PrintMatcher(false),
-        Terminate(false) {}
+        Terminate(false), TK(ast_type_traits::TK_IgnoreUnlessSpelledInSource) {}
 
   llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs;
 
@@ -36,6 +37,8 @@ class QuerySession {
   bool BindRoot;
   bool PrintMatcher;
   bool Terminate;
+
+  ast_type_traits::TraversalKind TK;
   llvm::StringMap<ast_matchers::dynamic::VariantValue> NamedValues;
 };
 

diff  --git a/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp b/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
index 4ebe1237b21c..4a0a80146af4 100644
--- a/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
+++ b/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
@@ -110,6 +110,18 @@ TEST_F(QueryParserTest, Set) {
   ASSERT_TRUE(isa<SetQuery<bool> >(Q));
   EXPECT_EQ(&QuerySession::BindRoot, cast<SetQuery<bool> >(Q)->Var);
   EXPECT_EQ(true, cast<SetQuery<bool> >(Q)->Value);
+
+  Q = parse("set traversal AsIs");
+  ASSERT_TRUE(isa<SetQuery<ast_type_traits::TraversalKind>>(Q));
+  EXPECT_EQ(&QuerySession::TK,
+            cast<SetQuery<ast_type_traits::TraversalKind>>(Q)->Var);
+  EXPECT_EQ(ast_type_traits::TK_AsIs,
+            cast<SetQuery<ast_type_traits::TraversalKind>>(Q)->Value);
+
+  Q = parse("set traversal NotATraversal");
+  ASSERT_TRUE(isa<InvalidQuery>(Q));
+  EXPECT_EQ("expected traversal kind, got 'NotATraversal'",
+            cast<InvalidQuery>(Q)->ErrStr);
 }
 
 TEST_F(QueryParserTest, Match) {
@@ -197,6 +209,11 @@ TEST_F(QueryParserTest, Complete) {
   EXPECT_EQ("utput ", Comps[0].TypedText);
   EXPECT_EQ("output", Comps[0].DisplayText);
 
+  Comps = QueryParser::complete("set t", 5, QS);
+  ASSERT_EQ(1u, Comps.size());
+  EXPECT_EQ("raversal ", Comps[0].TypedText);
+  EXPECT_EQ("traversal", Comps[0].DisplayText);
+
   Comps = QueryParser::complete("enable ", 7, QS);
   ASSERT_EQ(1u, Comps.size());
   EXPECT_EQ("output ", Comps[0].TypedText);
@@ -214,6 +231,16 @@ TEST_F(QueryParserTest, Complete) {
   EXPECT_EQ("dump ", Comps[3].TypedText);
   EXPECT_EQ("dump", Comps[3].DisplayText);
 
+  Comps = QueryParser::complete("set traversal ", 14, QS);
+  ASSERT_EQ(3u, Comps.size());
+
+  EXPECT_EQ("AsIs ", Comps[0].TypedText);
+  EXPECT_EQ("AsIs", Comps[0].DisplayText);
+  EXPECT_EQ("IgnoreImplicitCastsAndParentheses ", Comps[1].TypedText);
+  EXPECT_EQ("IgnoreImplicitCastsAndParentheses", Comps[1].DisplayText);
+  EXPECT_EQ("IgnoreUnlessSpelledInSource ", Comps[2].TypedText);
+  EXPECT_EQ("IgnoreUnlessSpelledInSource", Comps[2].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