mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-07 19:03:57 +00:00
[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
This commit is contained in:
parent
3ea4bc7842
commit
858a9583e1
@ -149,6 +149,7 @@ struct SetExclusiveOutputQuery : Query {
|
||||
QS.DiagOutput = false;
|
||||
QS.DetailedASTOutput = false;
|
||||
QS.PrintOutput = false;
|
||||
QS.SrcLocOutput = false;
|
||||
QS.*Var = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user