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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits