Index: clang-query/Query.h =================================================================== --- clang-query/Query.h +++ clang-query/Query.h @@ -152,6 +152,30 @@ bool QuerySession::*Var; }; +// Implements the non-exclusive 'set output dump|diag|print' options +struct SetNonExclusiveOutputQuery : Query { + SetNonExclusiveOutputQuery(bool QuerySession::*Var, bool Value) : Query(QK_SetOutputKind), Var(Var), Value(Value) {} + bool run(llvm::raw_ostream &OS, QuerySession &QS) const override { + QS.*Var = Value; + return true; + } + + static bool classof(const Query *Q) { return Q->Kind == QK_SetOutputKind; } + + bool QuerySession::*Var; + bool Value; +}; + +struct EnableOutputQuery : SetNonExclusiveOutputQuery +{ + EnableOutputQuery(bool QuerySession::*Var) : SetNonExclusiveOutputQuery(Var, true) { } +}; + +struct DisableOutputQuery : SetNonExclusiveOutputQuery +{ + DisableOutputQuery(bool QuerySession::*Var) : SetNonExclusiveOutputQuery(Var, false) { } +}; + } // namespace query } // namespace clang Index: clang-query/QueryParser.h =================================================================== --- clang-query/QueryParser.h +++ clang-query/QueryParser.h @@ -44,6 +44,7 @@ template struct LexOrCompleteWord; QueryRef parseSetBool(bool QuerySession::*Var); + template QueryRef parseSetOutputKind(); QueryRef completeMatcherExpression(); Index: clang-query/QueryParser.cpp =================================================================== --- clang-query/QueryParser.cpp +++ clang-query/QueryParser.cpp @@ -106,6 +106,7 @@ return new SetQuery(Var, Value); } +template QueryRef QueryParser::parseSetOutputKind() { StringRef ValStr; unsigned OutKind = LexOrCompleteWord(this, ValStr) @@ -122,11 +123,11 @@ switch (OutKind) { case OK_DetailedAST: - return new SetExclusiveOutputQuery(&QuerySession::DetailedASTOutput); + return new QueryType(&QuerySession::DetailedASTOutput); case OK_Diag: - return new SetExclusiveOutputQuery(&QuerySession::DiagOutput); + return new QueryType(&QuerySession::DiagOutput); case OK_Print: - return new SetExclusiveOutputQuery(&QuerySession::PrintOutput); + return new QueryType(&QuerySession::PrintOutput); } llvm_unreachable("Invalid output kind"); @@ -157,6 +158,8 @@ enum ParsedQueryVariable { PQV_Invalid, PQV_Output, + PQV_EnableOutput, + PQV_DisableOutput, PQV_BindRoot, PQV_PrintMatcher }; @@ -245,6 +248,8 @@ ParsedQueryVariable Var = LexOrCompleteWord(this, VarStr) .Case("output", PQV_Output) + .Case("enable-output", PQV_EnableOutput) + .Case("disable-output", PQV_DisableOutput) .Case("bind-root", PQV_BindRoot) .Case("print-matcher", PQV_PrintMatcher) .Default(PQV_Invalid); @@ -256,7 +261,13 @@ QueryRef Q; switch (Var) { case PQV_Output: - Q = parseSetOutputKind(); + Q = parseSetOutputKind(); + break; + case PQV_EnableOutput: + Q = parseSetOutputKind(); + break; + case PQV_DisableOutput: + Q = parseSetOutputKind(); break; case PQV_BindRoot: Q = parseSetBool(&QuerySession::BindRoot); Index: unittests/clang-query/QueryEngineTest.cpp =================================================================== --- unittests/clang-query/QueryEngineTest.cpp +++ unittests/clang-query/QueryEngineTest.cpp @@ -111,6 +111,21 @@ Str.clear(); + EXPECT_TRUE( + EnableOutputQuery(&QuerySession::DiagOutput).run(OS, S)); + EXPECT_TRUE( + EnableOutputQuery(&QuerySession::DetailedASTOutput).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(&QuerySession::BindRoot, false).run(OS, S)); EXPECT_TRUE(MatchQuery(FooMatcherString, FooMatcher).run(OS, S)); Index: unittests/clang-query/QueryParserTest.cpp =================================================================== --- unittests/clang-query/QueryParserTest.cpp +++ unittests/clang-query/QueryParserTest.cpp @@ -90,6 +90,14 @@ ASSERT_TRUE(isa(Q)); EXPECT_EQ(&QuerySession::DetailedASTOutput, cast(Q)->Var); + Q = parse("set enable-output detailed-ast"); + ASSERT_TRUE(isa(Q)); + EXPECT_EQ(&QuerySession::DetailedASTOutput, cast(Q)->Var); + + Q = parse("set disable-output detailed-ast"); + ASSERT_TRUE(isa(Q)); + EXPECT_EQ(&QuerySession::DetailedASTOutput, cast(Q)->Var); + Q = parse("set bind-root foo"); ASSERT_TRUE(isa(Q)); EXPECT_EQ("expected 'true' or 'false', got 'foo'",