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