nridge updated this revision to Diff 232996.
nridge added a comment.
Add github issue number
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D71240/new/
https://reviews.llvm.org/D71240
Files:
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -465,6 +465,39 @@
template <typename T>
struct Fo^o<T*> {};
+ )cpp",
+
+ R"cpp(// Heuristic resolution of method
+ template <typename T>
+ struct S {
+ void [[bar]]() {}
+ };
+
+ template <typename T>
+ void foo(S<T> arg) {
+ arg.ba^r();
+ }
+ )cpp",
+
+ R"cpp(// Heuristic resolution of method via this->
+ template <typename T>
+ struct S {
+ void [[foo]]() {
+ this->fo^o();
+ }
+ };
+ )cpp",
+
+ R"cpp(// Heuristic resolution of static method
+ template <typename T>
+ struct S {
+ static void [[bar]]() {}
+ };
+
+ template <typename T>
+ void foo() {
+ S<T>::ba^r();
+ }
)cpp"};
for (const char *Test : Tests) {
Annotations T(Test);
@@ -525,6 +558,21 @@
Foo abcde$10^("asdf");
Foo foox2 = Foo$11^("asdf");
}
+
+ template <typename T>
+ struct S {
+ void $NonstaticOverload1[[bar]](int);
+ void $NonstaticOverload2[[bar]](float);
+
+ static void $StaticOverload1[[baz]](int);
+ static void $StaticOverload2[[baz]](int);
+ };
+
+ template <typename T, typename U>
+ void dependent_call(S<T> s, U u) {
+ s.ba$12^r(u);
+ S<T>::ba$13^z(u);
+ }
)cpp");
auto AST = TestTU::withCode(T.code()).build();
// Ordered assertions are deliberate: we expect a predictable order.
@@ -544,6 +592,15 @@
ElementsAre(Sym("Foo", T.range("ConstructorLoc"))));
EXPECT_THAT(locateSymbolAt(AST, T.point("11")),
ElementsAre(Sym("Foo", T.range("ConstructorLoc"))));
+ // These assertions are unordered because the order comes from
+ // CXXRecordDecl::lookupDependentName() which doesn't appear to provide
+ // an order guarantee.
+ EXPECT_THAT(locateSymbolAt(AST, T.point("12")),
+ UnorderedElementsAre(Sym("bar", T.range("NonstaticOverload1")),
+ Sym("bar", T.range("NonstaticOverload2"))));
+ EXPECT_THAT(locateSymbolAt(AST, T.point("13")),
+ UnorderedElementsAre(Sym("baz", T.range("StaticOverload1")),
+ Sym("baz", T.range("StaticOverload2"))));
}
TEST(LocateSymbol, TemplateTypedefs) {
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -384,8 +384,8 @@
// different kinds, deduplicate them.
std::vector<DocumentHighlight> Result;
for (const auto &Ref : References) {
- if (auto Range = getTokenRange(AST.getSourceManager(),
- AST.getLangOpts(), Ref.Loc)) {
+ if (auto Range =
+ getTokenRange(AST.getSourceManager(), AST.getLangOpts(), Ref.Loc)) {
DocumentHighlight DH;
DH.range = *Range;
if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Write))
Index: clang-tools-extra/clangd/FindTarget.cpp
===================================================================
--- clang-tools-extra/clangd/FindTarget.cpp
+++ clang-tools-extra/clangd/FindTarget.cpp
@@ -79,8 +79,6 @@
// formally size() is unresolved, but the primary template is a good guess.
// This affects:
// - DependentTemplateSpecializationType,
-// - DependentScopeMemberExpr
-// - DependentScopeDeclRefExpr
// - DependentNameType
struct TargetFinder {
using RelSet = DeclRelationSet;
@@ -212,6 +210,25 @@
break;
}
}
+ void
+ VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
+ const Type *BaseType = E->getBaseType().getTypePtrOrNull();
+ if (E->isArrow()) {
+ if (!BaseType || !BaseType->isPointerType()) {
+ return;
+ }
+ BaseType = BaseType->getAs<PointerType>()
+ ->getPointeeType()
+ .getTypePtrOrNull();
+ }
+ addMembersReferencedViaDependentName(BaseType, E->getMember(),
+ /*IsNonstaticMember=*/true);
+ }
+ void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
+ addMembersReferencedViaDependentName(E->getQualifier()->getAsType(),
+ E->getDeclName(),
+ /*IsNonstaticMember=*/false);
+ }
void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
Outer.add(OIRE->getDecl(), Flags);
}
@@ -231,6 +248,37 @@
void VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {
Outer.add(OPE->getProtocol(), Flags);
}
+
+ void addMembersReferencedViaDependentName(const Type *T,
+ const DeclarationName &Name,
+ bool IsNonstaticMember) {
+ // This code was adapted in part from indexDependentReference() in
+ // IndexBody.cpp.
+ if (!T)
+ return;
+ if (auto *ICNT = T->getAs<InjectedClassNameType>()) {
+ T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
+ }
+ auto *TST = T->getAs<TemplateSpecializationType>();
+ if (!TST)
+ return;
+ const ClassTemplateDecl *TD = dyn_cast_or_null<ClassTemplateDecl>(
+ TST->getTemplateName().getAsTemplateDecl());
+ if (!TD)
+ return;
+ CXXRecordDecl *RD = TD->getTemplatedDecl();
+ if (!RD->hasDefinition())
+ return;
+ RD = RD->getDefinition();
+ std::vector<const NamedDecl *> Decls =
+ RD->lookupDependentName(Name, [=](const NamedDecl *D) {
+ return IsNonstaticMember ? D->isCXXInstanceMember()
+ : !D->isCXXInstanceMember();
+ });
+ for (const NamedDecl *D : Decls) {
+ Outer.add(D, Flags);
+ }
+ }
};
Visitor(*this, Flags).Visit(S);
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits