diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -780,6 +780,13 @@ explicitReferenceTargets(DynTypedNode::create(*E), {}, Resolver)}); } + void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) { + Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), + OIRE->getLocation(), + /*IsDecl=*/false, + {OIRE->getDecl()}}); + } + void VisitObjCMessageExpr(const ObjCMessageExpr *E) { // The name may have several tokens, we can only report the first. Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(), diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -687,6 +687,19 @@ @implementation $Class[[Foo]]($Namespace_decl[[Bar]]) @end )cpp", + R"cpp( + // ObjC: Properties and Ivars. + @interface $Class_decl[[Foo]] + @property(nonatomic, assign) int $Field_decl[[someProperty]]; + @end + @implementation $Class_decl[[Foo]] + @synthesize someProperty = $Field_decl[[_someProperty]]; + - (int)$Method_decl[[doSomething]] { + self.$Field[[someProperty]] = self.$Field[[someProperty]] + 1; + self->$Field[[_someProperty]] = $Field[[_someProperty]] + 1; + } + @end + )cpp", // Member imported from dependent base R"cpp( template struct $Class_decl[[Base]] {