[PATCH] D114058: [clangd] Add ObjC method support to prepareCallHierarchy
sheldonneuberger-sc added a comment. Made suggested changes, ready for another review. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D114058/new/ https://reviews.llvm.org/D114058 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D114058: [clangd] Add ObjC method support to prepareCallHierarchy
sheldonneuberger-sc updated this revision to Diff 389334. sheldonneuberger-sc added a comment. - revert whitespace change Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D114058/new/ https://reviews.llvm.org/D114058 Files: clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp Index: clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp === --- clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp +++ clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp @@ -65,7 +65,7 @@ UnorderedElementsAre(M...)); } -TEST(CallHierarchy, IncomingOneFile) { +TEST(CallHierarchy, IncomingOneFileCpp) { Annotations Source(R"cpp( void call^ee(int); void caller1() { @@ -91,7 +91,51 @@ ASSERT_THAT(IncomingLevel1, ElementsAre(AllOf(From(WithName("caller1")), FromRanges(Source.range("Callee"); + auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get()); + ASSERT_THAT(IncomingLevel2, + ElementsAre(AllOf(From(WithName("caller2")), +FromRanges(Source.range("Caller1A"), + Source.range("Caller1B"))), + AllOf(From(WithName("caller3")), +FromRanges(Source.range("Caller1C"); + auto IncomingLevel3 = incomingCalls(IncomingLevel2[0].from, Index.get()); + ASSERT_THAT(IncomingLevel3, + ElementsAre(AllOf(From(WithName("caller3")), +FromRanges(Source.range("Caller2"); + + auto IncomingLevel4 = incomingCalls(IncomingLevel3[0].from, Index.get()); + EXPECT_THAT(IncomingLevel4, IsEmpty()); +} + +TEST(CallHierarchy, IncomingOneFileObjC) { + Annotations Source(R"objc( +@implementation MyClass {} + +(void)call^ee {} + +(void) caller1 { +[MyClass $Callee[[callee]]]; + } + +(void) caller2 { +[MyClass $Caller1A[[caller1]]]; +[MyClass $Caller1B[[caller1]]]; + } + +(void) caller3 { +[MyClass $Caller1C[[caller1]]]; +[MyClass $Caller2[[caller2]]]; + } +@end + )objc"); + TestTU TU = TestTU::withCode(Source.code()); + TU.Filename = "TestTU.m"; + auto AST = TU.build(); + auto Index = TU.index(); + std::vector Items = + prepareCallHierarchy(AST, Source.point(), testPath(TU.Filename)); + ASSERT_THAT(Items, ElementsAre(WithName("callee"))); + auto IncomingLevel1 = incomingCalls(Items[0], Index.get()); + ASSERT_THAT(IncomingLevel1, + ElementsAre(AllOf(From(WithName("caller1")), +FromRanges(Source.range("Callee"); auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get()); ASSERT_THAT(IncomingLevel2, ElementsAre(AllOf(From(WithName("caller2")), @@ -172,7 +216,7 @@ FromRanges(Source.range("Caller2"); } -TEST(CallHierarchy, IncomingMultiFile) { +TEST(CallHierarchy, IncomingMultiFileCpp) { // The test uses a .hh suffix for header files to get clang // to parse them in C++ mode. .h files are parsed in C mode // by default, which causes problems because e.g. symbol @@ -268,6 +312,115 @@ CheckCallHierarchy(*AST, CalleeC.point(), testPath("callee.cc")); } +TEST(CallHierarchy, IncomingMultiFileObjC) { + // The test uses a .mi suffix for header files to get clang + // to parse them in ObjC mode. .h files are parsed in C mode + // by default, which causes problems because e.g. symbol + // USRs are different in C mode (do not include function signatures). + + Annotations CalleeH(R"objc( +@interface CalleeClass + +(void)call^ee; +@end + )objc"); + Annotations CalleeC(R"objc( +#import "callee.mi" +@implementation CalleeClass {} + +(void)call^ee {} +@end + )objc"); + Annotations Caller1H(R"objc( +@interface Caller1Class + +(void)caller1; +@end + )objc"); + Annotations Caller1C(R"objc( +#import "callee.mi" +#import "caller1.mi" +@implementation Caller1Class {} + +(void)caller1 { +[CalleeClass [[calle^e]]]; + } +@end + )objc"); + Annotations Caller2H(R"objc( +@interface Caller2Class + +(void)caller2; +@end + )objc"); + Annotations Caller2C(R"objc( +#import "caller1.mi" +#import "caller2.mi" +@implementation Caller2Class {} + +(void)caller2 { +[Caller1Class $A[[caller1]]]; +[Caller1Class $B[[caller1]]]; + } +@end + )objc"); + Annotations Caller3C(R"objc( +#import "caller1.mi" +#import "caller2.mi" +@implementation Caller3Class {} + +(void)caller3 { +[Caller1Class $Caller1[[caller1]]]; +[Caller2Class $Caller2[[caller2]]]; + } +@end + )objc"); + + TestWorkspace Workspace; +
[PATCH] D114058: [clangd] Add ObjC method support to prepareCallHierarchy
sheldonneuberger-sc updated this revision to Diff 389333. sheldonneuberger-sc added a comment. - inline test helper for readability - fix indentation Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D114058/new/ https://reviews.llvm.org/D114058 Files: clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp Index: clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp === --- clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp +++ clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp @@ -65,7 +65,7 @@ UnorderedElementsAre(M...)); } -TEST(CallHierarchy, IncomingOneFile) { +TEST(CallHierarchy, IncomingOneFileCpp) { Annotations Source(R"cpp( void call^ee(int); void caller1() { @@ -91,7 +91,51 @@ ASSERT_THAT(IncomingLevel1, ElementsAre(AllOf(From(WithName("caller1")), FromRanges(Source.range("Callee"); + auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get()); + ASSERT_THAT(IncomingLevel2, + ElementsAre(AllOf(From(WithName("caller2")), +FromRanges(Source.range("Caller1A"), + Source.range("Caller1B"))), + AllOf(From(WithName("caller3")), +FromRanges(Source.range("Caller1C"); + auto IncomingLevel3 = incomingCalls(IncomingLevel2[0].from, Index.get()); + ASSERT_THAT(IncomingLevel3, + ElementsAre(AllOf(From(WithName("caller3")), +FromRanges(Source.range("Caller2"); + + auto IncomingLevel4 = incomingCalls(IncomingLevel3[0].from, Index.get()); + EXPECT_THAT(IncomingLevel4, IsEmpty()); +} + +TEST(CallHierarchy, IncomingOneFileObjC) { + Annotations Source(R"objc( +@implementation MyClass {} + +(void)call^ee {} + +(void) caller1 { +[MyClass $Callee[[callee]]]; + } + +(void) caller2 { +[MyClass $Caller1A[[caller1]]]; +[MyClass $Caller1B[[caller1]]]; + } + +(void) caller3 { +[MyClass $Caller1C[[caller1]]]; +[MyClass $Caller2[[caller2]]]; + } +@end + )objc"); + TestTU TU = TestTU::withCode(Source.code()); + TU.Filename = "TestTU.m"; + auto AST = TU.build(); + auto Index = TU.index(); + std::vector Items = + prepareCallHierarchy(AST, Source.point(), testPath(TU.Filename)); + ASSERT_THAT(Items, ElementsAre(WithName("callee"))); + auto IncomingLevel1 = incomingCalls(Items[0], Index.get()); + ASSERT_THAT(IncomingLevel1, + ElementsAre(AllOf(From(WithName("caller1")), +FromRanges(Source.range("Callee"); auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get()); ASSERT_THAT(IncomingLevel2, ElementsAre(AllOf(From(WithName("caller2")), @@ -172,7 +216,7 @@ FromRanges(Source.range("Caller2"); } -TEST(CallHierarchy, IncomingMultiFile) { +TEST(CallHierarchy, IncomingMultiFileCpp) { // The test uses a .hh suffix for header files to get clang // to parse them in C++ mode. .h files are parsed in C mode // by default, which causes problems because e.g. symbol @@ -223,7 +267,6 @@ Workspace.addMainFile("caller1.cc", Caller1C.code()); Workspace.addMainFile("caller2.cc", Caller2C.code()); Workspace.addMainFile("caller3.cc", Caller3C.code()); - auto Index = Workspace.index(); auto CheckCallHierarchy = [&](ParsedAST , Position Pos, PathRef TUPath) { @@ -268,6 +311,115 @@ CheckCallHierarchy(*AST, CalleeC.point(), testPath("callee.cc")); } +TEST(CallHierarchy, IncomingMultiFileObjC) { + // The test uses a .mi suffix for header files to get clang + // to parse them in ObjC mode. .h files are parsed in C mode + // by default, which causes problems because e.g. symbol + // USRs are different in C mode (do not include function signatures). + + Annotations CalleeH(R"objc( +@interface CalleeClass + +(void)call^ee; +@end + )objc"); + Annotations CalleeC(R"objc( +#import "callee.mi" +@implementation CalleeClass {} + +(void)call^ee {} +@end + )objc"); + Annotations Caller1H(R"objc( +@interface Caller1Class + +(void)caller1; +@end + )objc"); + Annotations Caller1C(R"objc( +#import "callee.mi" +#import "caller1.mi" +@implementation Caller1Class {} + +(void)caller1 { +[CalleeClass [[calle^e]]]; + } +@end + )objc"); + Annotations Caller2H(R"objc( +@interface Caller2Class + +(void)caller2; +@end + )objc"); + Annotations Caller2C(R"objc( +#import "caller1.mi" +#import "caller2.mi" +@implementation Caller2Class {} + +(void)caller2 { +[Caller1Class $A[[caller1]]]; +[Caller1Class $B[[caller1]]]; + } +
[PATCH] D114058: [clang] Add ObjC decls to Decl::isFunctionOrFunctionTemplate
sheldonneuberger-sc added a comment. Thanks for the detailed comments. I moved the patch into the clangd callsite. I also added a couple ObjC tests for CallHierarchy (I basically parameterized two of the existing tests). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D114058/new/ https://reviews.llvm.org/D114058 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D114058: [clang] Add ObjC decls to Decl::isFunctionOrFunctionTemplate
sheldonneuberger-sc updated this revision to Diff 388101. sheldonneuberger-sc added a comment. - fix test name Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D114058/new/ https://reviews.llvm.org/D114058 Files: clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp Index: clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp === --- clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp +++ clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp @@ -51,6 +51,13 @@ using ::testing::Matcher; using ::testing::UnorderedElementsAre; +void verifyIncomingMultiFile(std::string SourceExt, std::string HeaderExt, + Annotations , Annotations , + Annotations , Annotations , + Annotations , Annotations , + Annotations ); +void verifyIncomingOneFile(Annotations , std::string Filename); + // Helpers for matching call hierarchy data structures. MATCHER_P(WithName, N, "") { return arg.name == N; } MATCHER_P(WithSelectionRange, R, "") { return arg.selectionRange == R; } @@ -65,25 +72,11 @@ UnorderedElementsAre(M...)); } -TEST(CallHierarchy, IncomingOneFile) { - Annotations Source(R"cpp( -void call^ee(int); -void caller1() { - $Callee[[callee]](42); -} -void caller2() { - $Caller1A[[caller1]](); - $Caller1B[[caller1]](); -} -void caller3() { - $Caller1C[[caller1]](); - $Caller2[[caller2]](); -} - )cpp"); +void verifyIncomingOneFile(Annotations , std::string Filename) { TestTU TU = TestTU::withCode(Source.code()); + TU.Filename = Filename; auto AST = TU.build(); auto Index = TU.index(); - std::vector Items = prepareCallHierarchy(AST, Source.point(), testPath(TU.Filename)); ASSERT_THAT(Items, ElementsAre(WithName("callee"))); @@ -91,7 +84,6 @@ ASSERT_THAT(IncomingLevel1, ElementsAre(AllOf(From(WithName("caller1")), FromRanges(Source.range("Callee"); - auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get()); ASSERT_THAT(IncomingLevel2, ElementsAre(AllOf(From(WithName("caller2")), @@ -109,6 +101,45 @@ EXPECT_THAT(IncomingLevel4, IsEmpty()); } +TEST(CallHierarchy, IncomingOneFileCpp) { + Annotations Source(R"cpp( +void call^ee(int); +void caller1() { + $Callee[[callee]](42); +} +void caller2() { + $Caller1A[[caller1]](); + $Caller1B[[caller1]](); +} +void caller3() { + $Caller1C[[caller1]](); + $Caller2[[caller2]](); +} + )cpp"); + verifyIncomingOneFile(Source, "TestTU.cpp"); +} + +TEST(CallHierarchy, IncomingOneFileObjC) { + Annotations Source(R"objc( +@implementation MyClass {} + +(void)call^ee { +} ++(void) caller1 { + [MyClass $Callee[[callee]]]; +} ++(void) caller2 { + [MyClass $Caller1A[[caller1]]]; + [MyClass $Caller1B[[caller1]]]; +} ++(void) caller3 { + [MyClass $Caller1C[[caller1]]]; + [MyClass $Caller2[[caller2]]]; +} +@end + )objc"); + verifyIncomingOneFile(Source, "TestTU.m"); +} + TEST(CallHierarchy, MainFileOnlyRef) { // In addition to testing that we store refs to main-file only symbols, // this tests that anonymous namespaces do not interfere with the @@ -172,7 +203,7 @@ FromRanges(Source.range("Caller2"); } -TEST(CallHierarchy, IncomingMultiFile) { +TEST(CallHierarchy, IncomingMultiFileCpp) { // The test uses a .hh suffix for header files to get clang // to parse them in C++ mode. .h files are parsed in C mode // by default, which causes problems because e.g. symbol @@ -215,15 +246,84 @@ } )cpp"); - TestWorkspace Workspace; - Workspace.addSource("callee.hh", CalleeH.code()); - Workspace.addSource("caller1.hh", Caller1H.code()); - Workspace.addSource("caller2.hh", Caller2H.code()); - Workspace.addMainFile("callee.cc", CalleeC.code()); - Workspace.addMainFile("caller1.cc", Caller1C.code()); - Workspace.addMainFile("caller2.cc", Caller2C.code()); - Workspace.addMainFile("caller3.cc", Caller3C.code()); + verifyIncomingMultiFile(".cc", ".hh", CalleeH, Caller1H, Caller2H, CalleeC, + Caller1C, Caller2C, Caller3C); +} + +TEST(CallHierarchy, IncomingMultiFileObjC) { + // The test uses a .mi suffix for header files to get clang + // to parse them in ObjC mode. .h files are parsed in C mode + // by default, which causes problems because e.g. symbol + // USRs are different in C mode (do not include function signatures). + + Annotations CalleeH(R"objc( +@interface CalleeClass + +(void)call^ee; +@end + )objc"); + Annotations CalleeC(R"objc( +#import "callee.mi" +@implementation CalleeClass {} +
[PATCH] D114058: [clang] Add ObjC decls to Decl::isFunctionOrFunctionTemplate
sheldonneuberger-sc updated this revision to Diff 388100. sheldonneuberger-sc added a comment. - clang-format Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D114058/new/ https://reviews.llvm.org/D114058 Files: clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp Index: clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp === --- clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp +++ clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp @@ -51,6 +51,13 @@ using ::testing::Matcher; using ::testing::UnorderedElementsAre; +void verifyIncomingMultiFile(std::string SourceExt, std::string HeaderExt, + Annotations , Annotations , + Annotations , Annotations , + Annotations , Annotations , + Annotations ); +void verifyIncomingOneFile(Annotations , std::string Filename); + // Helpers for matching call hierarchy data structures. MATCHER_P(WithName, N, "") { return arg.name == N; } MATCHER_P(WithSelectionRange, R, "") { return arg.selectionRange == R; } @@ -65,25 +72,11 @@ UnorderedElementsAre(M...)); } -TEST(CallHierarchy, IncomingOneFile) { - Annotations Source(R"cpp( -void call^ee(int); -void caller1() { - $Callee[[callee]](42); -} -void caller2() { - $Caller1A[[caller1]](); - $Caller1B[[caller1]](); -} -void caller3() { - $Caller1C[[caller1]](); - $Caller2[[caller2]](); -} - )cpp"); +void verifyIncomingOneFile(Annotations , std::string Filename) { TestTU TU = TestTU::withCode(Source.code()); + TU.Filename = Filename; auto AST = TU.build(); auto Index = TU.index(); - std::vector Items = prepareCallHierarchy(AST, Source.point(), testPath(TU.Filename)); ASSERT_THAT(Items, ElementsAre(WithName("callee"))); @@ -91,7 +84,6 @@ ASSERT_THAT(IncomingLevel1, ElementsAre(AllOf(From(WithName("caller1")), FromRanges(Source.range("Callee"); - auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get()); ASSERT_THAT(IncomingLevel2, ElementsAre(AllOf(From(WithName("caller2")), @@ -109,6 +101,45 @@ EXPECT_THAT(IncomingLevel4, IsEmpty()); } +TEST(CallHierarchy, IncomingOneFile) { + Annotations Source(R"cpp( +void call^ee(int); +void caller1() { + $Callee[[callee]](42); +} +void caller2() { + $Caller1A[[caller1]](); + $Caller1B[[caller1]](); +} +void caller3() { + $Caller1C[[caller1]](); + $Caller2[[caller2]](); +} + )cpp"); + verifyIncomingOneFile(Source, "TestTU.cpp"); +} + +TEST(CallHierarchy, IncomingOneFileObjC) { + Annotations Source(R"objc( +@implementation MyClass {} + +(void)call^ee { +} ++(void) caller1 { + [MyClass $Callee[[callee]]]; +} ++(void) caller2 { + [MyClass $Caller1A[[caller1]]]; + [MyClass $Caller1B[[caller1]]]; +} ++(void) caller3 { + [MyClass $Caller1C[[caller1]]]; + [MyClass $Caller2[[caller2]]]; +} +@end + )objc"); + verifyIncomingOneFile(Source, "TestTU.m"); +} + TEST(CallHierarchy, MainFileOnlyRef) { // In addition to testing that we store refs to main-file only symbols, // this tests that anonymous namespaces do not interfere with the @@ -172,7 +203,7 @@ FromRanges(Source.range("Caller2"); } -TEST(CallHierarchy, IncomingMultiFile) { +TEST(CallHierarchy, IncomingMultiFileCpp) { // The test uses a .hh suffix for header files to get clang // to parse them in C++ mode. .h files are parsed in C mode // by default, which causes problems because e.g. symbol @@ -215,15 +246,84 @@ } )cpp"); - TestWorkspace Workspace; - Workspace.addSource("callee.hh", CalleeH.code()); - Workspace.addSource("caller1.hh", Caller1H.code()); - Workspace.addSource("caller2.hh", Caller2H.code()); - Workspace.addMainFile("callee.cc", CalleeC.code()); - Workspace.addMainFile("caller1.cc", Caller1C.code()); - Workspace.addMainFile("caller2.cc", Caller2C.code()); - Workspace.addMainFile("caller3.cc", Caller3C.code()); + verifyIncomingMultiFile(".cc", ".hh", CalleeH, Caller1H, Caller2H, CalleeC, + Caller1C, Caller2C, Caller3C); +} +TEST(CallHierarchy, IncomingMultiFileObjC) { + // The test uses a .mi suffix for header files to get clang + // to parse them in ObjC mode. .h files are parsed in C mode + // by default, which causes problems because e.g. symbol + // USRs are different in C mode (do not include function signatures). + + Annotations CalleeH(R"objc( +@interface CalleeClass + +(void)call^ee; +@end + )objc"); + Annotations CalleeC(R"objc( +#import "callee.mi" +@implementation CalleeClass {} +
[PATCH] D114058: [clang] Add ObjC decls to Decl::isFunctionOrFunctionTemplate
sheldonneuberger-sc updated this revision to Diff 388099. sheldonneuberger-sc added a comment. Herald added a subscriber: arphaman. Herald added a project: clang-tools-extra. - move change to clangd callsite - add tests Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D114058/new/ https://reviews.llvm.org/D114058 Files: clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp Index: clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp === --- clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp +++ clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp @@ -51,6 +51,9 @@ using ::testing::Matcher; using ::testing::UnorderedElementsAre; +void verifyIncomingMultiFile(std::string SourceExt, std::string HeaderExt, Annotations , Annotations , Annotations , Annotations , Annotations , Annotations , Annotations ); +void verifyIncomingOneFile(Annotations , std::string Filename); + // Helpers for matching call hierarchy data structures. MATCHER_P(WithName, N, "") { return arg.name == N; } MATCHER_P(WithSelectionRange, R, "") { return arg.selectionRange == R; } @@ -65,25 +68,11 @@ UnorderedElementsAre(M...)); } -TEST(CallHierarchy, IncomingOneFile) { - Annotations Source(R"cpp( -void call^ee(int); -void caller1() { - $Callee[[callee]](42); -} -void caller2() { - $Caller1A[[caller1]](); - $Caller1B[[caller1]](); -} -void caller3() { - $Caller1C[[caller1]](); - $Caller2[[caller2]](); -} - )cpp"); +void verifyIncomingOneFile(Annotations , std::string Filename) { TestTU TU = TestTU::withCode(Source.code()); + TU.Filename = Filename; auto AST = TU.build(); auto Index = TU.index(); - std::vector Items = prepareCallHierarchy(AST, Source.point(), testPath(TU.Filename)); ASSERT_THAT(Items, ElementsAre(WithName("callee"))); @@ -91,7 +80,6 @@ ASSERT_THAT(IncomingLevel1, ElementsAre(AllOf(From(WithName("caller1")), FromRanges(Source.range("Callee"); - auto IncomingLevel2 = incomingCalls(IncomingLevel1[0].from, Index.get()); ASSERT_THAT(IncomingLevel2, ElementsAre(AllOf(From(WithName("caller2")), @@ -109,6 +97,45 @@ EXPECT_THAT(IncomingLevel4, IsEmpty()); } +TEST(CallHierarchy, IncomingOneFile) { + Annotations Source(R"cpp( +void call^ee(int); +void caller1() { + $Callee[[callee]](42); +} +void caller2() { + $Caller1A[[caller1]](); + $Caller1B[[caller1]](); +} +void caller3() { + $Caller1C[[caller1]](); + $Caller2[[caller2]](); +} + )cpp"); + verifyIncomingOneFile(Source, "TestTU.cpp"); +} + +TEST(CallHierarchy, IncomingOneFileObjC) { + Annotations Source(R"objc( +@implementation MyClass {} + +(void)call^ee { +} ++(void) caller1 { + [MyClass $Callee[[callee]]]; +} ++(void) caller2 { + [MyClass $Caller1A[[caller1]]]; + [MyClass $Caller1B[[caller1]]]; +} ++(void) caller3 { + [MyClass $Caller1C[[caller1]]]; + [MyClass $Caller2[[caller2]]]; +} +@end + )objc"); + verifyIncomingOneFile(Source, "TestTU.m"); +} + TEST(CallHierarchy, MainFileOnlyRef) { // In addition to testing that we store refs to main-file only symbols, // this tests that anonymous namespaces do not interfere with the @@ -172,7 +199,7 @@ FromRanges(Source.range("Caller2"); } -TEST(CallHierarchy, IncomingMultiFile) { +TEST(CallHierarchy, IncomingMultiFileCpp) { // The test uses a .hh suffix for header files to get clang // to parse them in C++ mode. .h files are parsed in C mode // by default, which causes problems because e.g. symbol @@ -215,15 +242,78 @@ } )cpp"); - TestWorkspace Workspace; - Workspace.addSource("callee.hh", CalleeH.code()); - Workspace.addSource("caller1.hh", Caller1H.code()); - Workspace.addSource("caller2.hh", Caller2H.code()); - Workspace.addMainFile("callee.cc", CalleeC.code()); - Workspace.addMainFile("caller1.cc", Caller1C.code()); - Workspace.addMainFile("caller2.cc", Caller2C.code()); - Workspace.addMainFile("caller3.cc", Caller3C.code()); + verifyIncomingMultiFile(".cc", ".hh", CalleeH, Caller1H, Caller2H, CalleeC, Caller1C, Caller2C, Caller3C); +} +TEST(CallHierarchy, IncomingMultiFileObjC) { + // The test uses a .mi suffix for header files to get clang + // to parse them in ObjC mode. .h files are parsed in C mode + // by default, which causes problems because e.g. symbol + // USRs are different in C mode (do not include function signatures). + + Annotations CalleeH(R"objc( +@interface CalleeClass + +(void)call^ee; +@end + )objc"); + Annotations CalleeC(R"objc( +#import "callee.mi" +@implementation CalleeClass {} + +(void)call^ee {} +@end + )objc"); +
[PATCH] D114058: [clang] Add ObjC decls to Decl::isFunctionOrFunctionTemplate
sheldonneuberger-sc created this revision. sheldonneuberger-sc added a reviewer: nridge. Herald added subscribers: usaxena95, kadircet. sheldonneuberger-sc added a reviewer: erichkeane. sheldonneuberger-sc edited the summary of this revision. sheldonneuberger-sc published this revision for review. Herald added subscribers: cfe-commits, ilya-biryukov. Herald added a project: clang. This fixes "textDocument/prepareCallHierarchy" in clangd for ObjC methods. Details at https://github.com/clangd/vscode-clangd/issues/247. clangd uses Decl::isFunctionOrFunctionTemplate to check if the decl given in a prepareCallHierarchy request is eligible for prepareCallHierarchy, so we want it to return true for ObjC methods too. I added Block, Captured, and ObjCMethod because that's what was also done in DeclContext::isFunctionOrMethod. Need guidance on if the function should be renamed to isFunctionOrMethodOrFunctionTemplate. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D114058 Files: clang/include/clang/AST/DeclBase.h Index: clang/include/clang/AST/DeclBase.h === --- clang/include/clang/AST/DeclBase.h +++ clang/include/clang/AST/DeclBase.h @@ -1040,9 +1040,15 @@ /// Whether this declaration is a function or function template. bool isFunctionOrFunctionTemplate() const { -return (DeclKind >= Decl::firstFunction && -DeclKind <= Decl::lastFunction) || - DeclKind == FunctionTemplate; +switch (DeclKind) { +case Decl::Block: +case Decl::Captured: +case Decl::ObjCMethod: +case Decl::FunctionTemplate: + return true; +default: + return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction; +} } /// If this is a declaration that describes some template, this Index: clang/include/clang/AST/DeclBase.h === --- clang/include/clang/AST/DeclBase.h +++ clang/include/clang/AST/DeclBase.h @@ -1040,9 +1040,15 @@ /// Whether this declaration is a function or function template. bool isFunctionOrFunctionTemplate() const { -return (DeclKind >= Decl::firstFunction && -DeclKind <= Decl::lastFunction) || - DeclKind == FunctionTemplate; +switch (DeclKind) { +case Decl::Block: +case Decl::Captured: +case Decl::ObjCMethod: +case Decl::FunctionTemplate: + return true; +default: + return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction; +} } /// If this is a declaration that describes some template, this ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits