mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 06:10:12 +00:00
Widen name
stencil to support TypeLoc
nodes.
Differential Revision: https://reviews.llvm.org/D102185
This commit is contained in:
parent
2155dc51d7
commit
be5c7c5d82
@ -73,9 +73,9 @@ RangeSelector statement(std::string ID);
|
||||
/// binding in the match result.
|
||||
RangeSelector member(std::string ID);
|
||||
|
||||
/// Given a node with a "name", (like \c NamedDecl, \c DeclRefExpr or \c
|
||||
/// CxxCtorInitializer) selects the name's token. Only selects the final
|
||||
/// identifier of a qualified name, but not any qualifiers or template
|
||||
/// Given a node with a "name", (like \c NamedDecl, \c DeclRefExpr, \c
|
||||
/// CxxCtorInitializer, and \c TypeLoc) selects the name's token. Only selects
|
||||
/// the final identifier of a qualified name, but not any qualifiers or template
|
||||
/// arguments. For example, for `::foo::bar::baz` and `::foo::bar::baz<int>`,
|
||||
/// it selects only `baz`.
|
||||
///
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "clang/Tooling/Transformer/RangeSelector.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
@ -228,8 +229,16 @@ RangeSelector transformer::name(std::string ID) {
|
||||
SourceLocation L = I->getMemberLocation();
|
||||
return CharSourceRange::getTokenRange(L, L);
|
||||
}
|
||||
if (const auto *T = Node.get<TypeLoc>()) {
|
||||
TypeLoc Loc = *T;
|
||||
auto ET = Loc.getAs<ElaboratedTypeLoc>();
|
||||
if (!ET.isNull()) {
|
||||
Loc = ET.getNamedTypeLoc();
|
||||
}
|
||||
return CharSourceRange::getTokenRange(Loc.getSourceRange());
|
||||
}
|
||||
return typeError(ID, Node.getNodeKind(),
|
||||
"DeclRefExpr, NamedDecl, CXXCtorInitializer");
|
||||
"DeclRefExpr, NamedDecl, CXXCtorInitializer, TypeLoc");
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -457,6 +457,35 @@ TEST(RangeSelectorTest, NameOpCtorInitializer) {
|
||||
EXPECT_THAT_EXPECTED(select(name(Init), Match), HasValue("field"));
|
||||
}
|
||||
|
||||
TEST(RangeSelectorTest, NameOpTypeLoc) {
|
||||
StringRef Code = R"cc(
|
||||
namespace ns {
|
||||
struct Foo {
|
||||
Foo();
|
||||
Foo(int);
|
||||
Foo(int, int);
|
||||
};
|
||||
} // namespace ns
|
||||
|
||||
ns::Foo a;
|
||||
auto b = ns::Foo(3);
|
||||
auto c = ns::Foo(1, 2);
|
||||
)cc";
|
||||
const char *CtorTy = "ctor_ty";
|
||||
// Matches declaration of `a`
|
||||
TestMatch MatchA = matchCode(
|
||||
Code, varDecl(hasName("a"), hasTypeLoc(typeLoc().bind(CtorTy))));
|
||||
EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchA), HasValue("Foo"));
|
||||
// Matches call of Foo(int)
|
||||
TestMatch MatchB = matchCode(
|
||||
Code, cxxFunctionalCastExpr(hasTypeLoc(typeLoc().bind(CtorTy))));
|
||||
EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchB), HasValue("Foo"));
|
||||
// Matches call of Foo(int, int)
|
||||
TestMatch MatchC = matchCode(
|
||||
Code, cxxTemporaryObjectExpr(hasTypeLoc(typeLoc().bind(CtorTy))));
|
||||
EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchC), HasValue("Foo"));
|
||||
}
|
||||
|
||||
TEST(RangeSelectorTest, NameOpErrors) {
|
||||
EXPECT_THAT_EXPECTED(selectFromTrivial(name("unbound_id")),
|
||||
Failed<StringError>(withUnboundNodeMessage()));
|
||||
|
Loading…
Reference in New Issue
Block a user