@@ -411,6 +411,85 @@ TEST(LocateSymbol, FindOverrides) {
411411 sym (" foo" , Code.range (" 2" ), std::nullopt )));
412412}
413413
414+ TEST (LocateSymbol, FindOverridesFromDefObjC) {
415+ auto Code = Annotations (R"objc(
416+ @protocol Fooey
417+ - (void)foo;
418+ @end
419+ @interface Base
420+ - (void)foo;
421+ @end
422+ @interface Foo : Base<Fooey>
423+ - (void)$1[[foo]];
424+ @end
425+
426+ @interface Bar : Foo
427+ - (void)$2[[foo]];
428+ @end
429+ @implementation Bar
430+ - (void)$3[[fo^o]] {}
431+ @end
432+ )objc" );
433+ TestTU TU = TestTU::withCode (Code.code ());
434+ TU.ExtraArgs .push_back (" -xobjective-c++" );
435+ auto AST = TU.build ();
436+ EXPECT_THAT (
437+ locateSymbolAt (AST, Code.point (), TU.index ().get ()),
438+ UnorderedElementsAre (sym (" foo" , Code.range (" 1" ), std::nullopt ),
439+ sym (" foo" , Code.range (" 2" ), Code.range (" 3" ))));
440+ }
441+
442+ TEST (LocateSymbol, NoOverridesFromDeclObjC) {
443+ auto Code = Annotations (R"objc(
444+ @protocol Fooey
445+ - (void)foo;
446+ @end
447+ @interface Base
448+ - (void)foo;
449+ @end
450+ @interface Foo : Base<Fooey>
451+ - (void)foo;
452+ @end
453+
454+ @interface Bar : Foo
455+ - (void)$2[[fo^o]];
456+ @end
457+ @implementation Bar
458+ - (void)$3[[foo]] {}
459+ @end
460+ )objc" );
461+ TestTU TU = TestTU::withCode (Code.code ());
462+ TU.ExtraArgs .push_back (" -xobjective-c++" );
463+ auto AST = TU.build ();
464+ EXPECT_THAT (
465+ locateSymbolAt (AST, Code.point (), TU.index ().get ()),
466+ UnorderedElementsAre (sym (" foo" , Code.range (" 2" ), Code.range (" 3" ))));
467+ }
468+
469+ TEST (LocateSymbol, ObjCNoOverridesOnUsage) {
470+ auto Code = Annotations (R"objc(
471+ @interface Foo
472+ - (void)foo;
473+ @end
474+
475+ @interface Bar : Foo
476+ - (void)$1[[foo]];
477+ @end
478+ @implementation Bar
479+ - (void)$2[[foo]] {}
480+ @end
481+ void doSomething(Bar *bar) {
482+ [bar fo^o];
483+ }
484+ )objc" );
485+ TestTU TU = TestTU::withCode (Code.code ());
486+ TU.ExtraArgs .push_back (" -xobjective-c++" );
487+ auto AST = TU.build ();
488+ EXPECT_THAT (
489+ locateSymbolAt (AST, Code.point (), TU.index ().get ()),
490+ UnorderedElementsAre (sym (" foo" , Code.range (" 1" ), Code.range (" 2" ))));
491+ }
492+
414493TEST (LocateSymbol, WithIndexPreferredLocation) {
415494 Annotations SymbolHeader (R"cpp(
416495 class $p[[Proto]] {};
@@ -1834,6 +1913,41 @@ TEST(FindImplementations, Inheritance) {
18341913 }
18351914}
18361915
1916+ TEST (FindImplementations, InheritanceObjC) {
1917+ llvm::StringRef Test = R"objc(
1918+ @interface $base^Base
1919+ - (void)fo$foo^o;
1920+ @end
1921+ @protocol Protocol
1922+ - (void)$protocol^protocol;
1923+ @end
1924+ @interface $ChildDecl[[Child]] : Base <Protocol>
1925+ - (void)concrete;
1926+ - (void)$fooDecl[[foo]];
1927+ @end
1928+ @implementation $ChildDef[[Child]]
1929+ - (void)concrete {}
1930+ - (void)$fooDef[[foo]] {}
1931+ - (void)$protocolDef[[protocol]] {}
1932+ @end
1933+ )objc" ;
1934+
1935+ Annotations Code (Test);
1936+ auto TU = TestTU::withCode (Code.code ());
1937+ TU.ExtraArgs .push_back (" -xobjective-c++" );
1938+ auto AST = TU.build ();
1939+ auto Index = TU.index ();
1940+ EXPECT_THAT (findImplementations (AST, Code.point (" base" ), Index.get ()),
1941+ UnorderedElementsAre (sym (" Child" , Code.range (" ChildDecl" ),
1942+ Code.range (" ChildDef" ))));
1943+ EXPECT_THAT (findImplementations (AST, Code.point (" foo" ), Index.get ()),
1944+ UnorderedElementsAre (
1945+ sym (" foo" , Code.range (" fooDecl" ), Code.range (" fooDef" ))));
1946+ EXPECT_THAT (findImplementations (AST, Code.point (" protocol" ), Index.get ()),
1947+ UnorderedElementsAre (sym (" protocol" , Code.range (" protocolDef" ),
1948+ Code.range (" protocolDef" ))));
1949+ }
1950+
18371951TEST (FindImplementations, CaptureDefinition) {
18381952 llvm::StringRef Test = R"cpp(
18391953 struct Base {
@@ -1963,6 +2077,7 @@ void checkFindRefs(llvm::StringRef Test, bool UseIndex = false) {
19632077 Annotations T (Test);
19642078 auto TU = TestTU::withCode (T.code ());
19652079 TU.ExtraArgs .push_back (" -std=c++20" );
2080+ TU.ExtraArgs .push_back (" -xobjective-c++" );
19662081
19672082 auto AST = TU.build ();
19682083 std::vector<Matcher<ReferencesResult::Reference>> ExpectedLocations;
@@ -2260,6 +2375,25 @@ TEST(FindReferences, IncludeOverrides) {
22602375 checkFindRefs (Test, /* UseIndex=*/ true );
22612376}
22622377
2378+ TEST (FindReferences, IncludeOverridesObjC) {
2379+ llvm::StringRef Test =
2380+ R"objc(
2381+ @interface Base
2382+ - (void)$decl(Base)[[f^unc]];
2383+ @end
2384+ @interface Derived : Base
2385+ - (void)$overridedecl(Derived::func)[[func]];
2386+ @end
2387+ @implementation Derived
2388+ - (void)$overridedef[[func]] {}
2389+ @end
2390+ void test(Derived *derived, Base *base) {
2391+ [derived func]; // No references to the overrides.
2392+ [base $(test)[[func]]];
2393+ })objc" ;
2394+ checkFindRefs (Test, /* UseIndex=*/ true );
2395+ }
2396+
22632397TEST (FindReferences, RefsToBaseMethod) {
22642398 llvm::StringRef Test =
22652399 R"cpp(
@@ -2284,6 +2418,27 @@ TEST(FindReferences, RefsToBaseMethod) {
22842418 checkFindRefs (Test, /* UseIndex=*/ true );
22852419}
22862420
2421+ TEST (FindReferences, RefsToBaseMethodObjC) {
2422+ llvm::StringRef Test =
2423+ R"objc(
2424+ @interface BaseBase
2425+ - (void)$(BaseBase)[[func]];
2426+ @end
2427+ @interface Base : BaseBase
2428+ - (void)$(Base)[[func]];
2429+ @end
2430+ @interface Derived : Base
2431+ - (void)$decl(Derived)[[fu^nc]];
2432+ @end
2433+ void test(BaseBase *bb, Base *b, Derived *d) {
2434+ // refs to overridden methods in complete type hierarchy are reported.
2435+ [bb $(test)[[func]]];
2436+ [b $(test)[[func]]];
2437+ [d $(test)[[fu^nc]]];
2438+ })objc" ;
2439+ checkFindRefs (Test, /* UseIndex=*/ true );
2440+ }
2441+
22872442TEST (FindReferences, MainFileReferencesOnly) {
22882443 llvm::StringRef Test =
22892444 R"cpp(
0 commit comments