Skip to content

Extend call hierarchy for enum constants #147042

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

timon-ul
Copy link
Contributor

@timon-ul timon-ul commented Jul 4, 2025

Implementation for clangd/clangd#2203

@llvmbot
Copy link
Member

llvmbot commented Jul 4, 2025

@llvm/pr-subscribers-clangd

Author: None (timon-ul)

Changes

Implementation for clangd/clangd#2203


Full diff: https://github.com/llvm/llvm-project/pull/147042.diff

2 Files Affected:

  • (modified) clang-tools-extra/clangd/XRefs.cpp (+2-1)
  • (modified) clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp (+29)
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index 089f8158c9aa5..5bbc681cf04e2 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -2287,7 +2287,8 @@ prepareCallHierarchy(ParsedAST &AST, Position Pos, PathRef TUPath) {
         Decl->getKind() != Decl::Kind::FunctionTemplate &&
         !(Decl->getKind() == Decl::Kind::Var &&
           !cast<VarDecl>(Decl)->isLocalVarDecl()) &&
-        Decl->getKind() != Decl::Kind::Field)
+        Decl->getKind() != Decl::Kind::Field &&
+        Decl->getKind() != Decl::Kind::EnumConstant)
       continue;
     if (auto CHI = declToCallHierarchyItem(*Decl, AST.tuPath()))
       Result.emplace_back(std::move(*CHI));
diff --git a/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp b/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
index eb852ef5ee00b..08cc80ff8981e 100644
--- a/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
@@ -633,6 +633,35 @@ TEST(CallHierarchy, HierarchyOnVar) {
                                 iFromRanges(Source.range("Callee")))));
 }
 
+TEST(CallHierarchy, HierarchyOnEnumConstant) {
+  // Tests that the call hierarchy works on enum constants.
+  Annotations Source(R"cpp(
+    enum class Coin { heads$Heads^ , tai$Tails^ls };
+    void caller() {
+      Coin::$CallerH[[heads]];
+      Coin::$CallerT[[tails]];
+    }
+  )cpp");
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+  auto Index = TU.index();
+
+  std::vector<CallHierarchyItem> Items =
+      prepareCallHierarchy(AST, Source.point("Heads"), testPath(TU.Filename));
+  ASSERT_THAT(Items, ElementsAre(withName("heads")));
+  auto IncomingLevel1 = incomingCalls(Items[0], Index.get());
+  ASSERT_THAT(IncomingLevel1,
+              ElementsAre(AllOf(from(withName("caller")),
+                                iFromRanges(Source.range("CallerH")))));
+  Items =
+      prepareCallHierarchy(AST, Source.point("Tails"), testPath(TU.Filename));
+  ASSERT_THAT(Items, ElementsAre(withName("tails")));
+  IncomingLevel1 = incomingCalls(Items[0], Index.get());
+  ASSERT_THAT(IncomingLevel1,
+              ElementsAre(AllOf(from(withName("caller")),
+                                iFromRanges(Source.range("CallerT")))));
+}
+
 TEST(CallHierarchy, CallInDifferentFileThanCaller) {
   Annotations Header(R"cpp(
     #define WALDO void caller() {

@llvmbot
Copy link
Member

llvmbot commented Jul 4, 2025

@llvm/pr-subscribers-clang-tools-extra

Author: None (timon-ul)

Changes

Implementation for clangd/clangd#2203


Full diff: https://github.com/llvm/llvm-project/pull/147042.diff

2 Files Affected:

  • (modified) clang-tools-extra/clangd/XRefs.cpp (+2-1)
  • (modified) clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp (+29)
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index 089f8158c9aa5..5bbc681cf04e2 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -2287,7 +2287,8 @@ prepareCallHierarchy(ParsedAST &AST, Position Pos, PathRef TUPath) {
         Decl->getKind() != Decl::Kind::FunctionTemplate &&
         !(Decl->getKind() == Decl::Kind::Var &&
           !cast<VarDecl>(Decl)->isLocalVarDecl()) &&
-        Decl->getKind() != Decl::Kind::Field)
+        Decl->getKind() != Decl::Kind::Field &&
+        Decl->getKind() != Decl::Kind::EnumConstant)
       continue;
     if (auto CHI = declToCallHierarchyItem(*Decl, AST.tuPath()))
       Result.emplace_back(std::move(*CHI));
diff --git a/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp b/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
index eb852ef5ee00b..08cc80ff8981e 100644
--- a/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
@@ -633,6 +633,35 @@ TEST(CallHierarchy, HierarchyOnVar) {
                                 iFromRanges(Source.range("Callee")))));
 }
 
+TEST(CallHierarchy, HierarchyOnEnumConstant) {
+  // Tests that the call hierarchy works on enum constants.
+  Annotations Source(R"cpp(
+    enum class Coin { heads$Heads^ , tai$Tails^ls };
+    void caller() {
+      Coin::$CallerH[[heads]];
+      Coin::$CallerT[[tails]];
+    }
+  )cpp");
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+  auto Index = TU.index();
+
+  std::vector<CallHierarchyItem> Items =
+      prepareCallHierarchy(AST, Source.point("Heads"), testPath(TU.Filename));
+  ASSERT_THAT(Items, ElementsAre(withName("heads")));
+  auto IncomingLevel1 = incomingCalls(Items[0], Index.get());
+  ASSERT_THAT(IncomingLevel1,
+              ElementsAre(AllOf(from(withName("caller")),
+                                iFromRanges(Source.range("CallerH")))));
+  Items =
+      prepareCallHierarchy(AST, Source.point("Tails"), testPath(TU.Filename));
+  ASSERT_THAT(Items, ElementsAre(withName("tails")));
+  IncomingLevel1 = incomingCalls(Items[0], Index.get());
+  ASSERT_THAT(IncomingLevel1,
+              ElementsAre(AllOf(from(withName("caller")),
+                                iFromRanges(Source.range("CallerT")))));
+}
+
 TEST(CallHierarchy, CallInDifferentFileThanCaller) {
   Annotations Header(R"cpp(
     #define WALDO void caller() {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants