[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