Skip to content

Commit

Permalink
[clang][tooling] Fix name range-selector to handle TypeLocs correctly.
Browse files Browse the repository at this point in the history
Previously, where `name` was applied to a template-specialization TypeLoc, it
returned the entire specialization (name, brackets, args) rather than just the
name identifier. With this change, exactly the name token is selected.

Differential Revision: https://reviews.llvm.org/D158771
  • Loading branch information
ymand committed Aug 25, 2023
1 parent 50b1276 commit c783258
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
6 changes: 4 additions & 2 deletions clang/lib/Tooling/Transformer/RangeSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,11 @@ RangeSelector transformer::name(std::string ID) {
if (const auto *T = Node.get<TypeLoc>()) {
TypeLoc Loc = *T;
auto ET = Loc.getAs<ElaboratedTypeLoc>();
if (!ET.isNull()) {
if (!ET.isNull())
Loc = ET.getNamedTypeLoc();
}
if (auto SpecLoc = Loc.getAs<TemplateSpecializationTypeLoc>();
!SpecLoc.isNull())
return CharSourceRange::getTokenRange(SpecLoc.getTemplateNameLoc());
return CharSourceRange::getTokenRange(Loc.getSourceRange());
}
return typeError(ID, Node.getNodeKind(),
Expand Down
16 changes: 16 additions & 0 deletions clang/unittests/Tooling/RangeSelectorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,22 @@ TEST(RangeSelectorTest, NameOpTypeLoc) {
EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchC), HasValue("Foo"));
}

TEST(RangeSelectorTest, NameOpTemplateSpecializationTypeLoc) {
StringRef Code = R"cc(
namespace ns {
template <typename T>
struct Foo {};
} // namespace ns
ns::Foo<int> a;
)cc";
const char *Loc = "tyloc";
// Matches declaration of `a`.
TestMatch MatchA =
matchCode(Code, varDecl(hasName("a"), hasTypeLoc(typeLoc().bind(Loc))));
EXPECT_THAT_EXPECTED(select(name(Loc), MatchA), HasValue("Foo"));
}

TEST(RangeSelectorTest, NameOpErrors) {
EXPECT_THAT_EXPECTED(selectFromTrivial(name("unbound_id")),
Failed<StringError>(withUnboundNodeMessage()));
Expand Down

0 comments on commit c783258

Please sign in to comment.