[clang] Add `clang_getCursorCallExprKind` to get the underlying type of CallExpr (PR #86143)

via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 21 21:46:31 PDT 2024


https://github.com/16bit-ykiko updated https://github.com/llvm/llvm-project/pull/86143

>From 32d4fc35f3d52b54e308b76c00c292497afe9621 Mon Sep 17 00:00:00 2001
From: ykiko <ykikoykikoykiko at gmail.com>
Date: Fri, 22 Mar 2024 00:00:30 +0800
Subject: [PATCH 1/4] add `clang_getCursorCallExprKind` to get the underlying
 type of CallExpr.

---
 clang/docs/ReleaseNotes.rst               |  2 +
 clang/include/clang-c/Index.h             | 46 +++++++++++++++++++++++
 clang/tools/libclang/CIndex.cpp           | 30 ++++++++++++++-
 clang/tools/libclang/libclang.map         |  5 +++
 clang/unittests/libclang/LibclangTest.cpp | 24 ++++++++++++
 5 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3a74c070ff9ffe..b25296cafc8285 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -509,6 +509,8 @@ clang-format
 libclang
 --------
 
+- Added ``CXCallExprKind`` and ``clang_getCursorCallExprKind``.
+
 Static Analyzer
 ---------------
 
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 60db3cf0966c02..1828b8ec3edaab 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6663,6 +6663,52 @@ clang_getUnaryOperatorKindSpelling(enum CXUnaryOperatorKind kind);
 CINDEX_LINKAGE enum CXUnaryOperatorKind
 clang_getCursorUnaryOperatorKind(CXCursor cursor);
 
+/**
+ * Describes the kind of CallExpr.
+ */
+enum CXCallExprKind {
+  /** Not a CallExpr. */
+  CXCallExpr_Invalid = 0,
+  /** Simple C function call. */
+  CXCallExpr_Default,
+  /** Call to overloaded operator using operator syntax. */
+  CXCallExpr_CXXOperatorCallExpr,
+  /**
+   * Call to a member function written with member call syntax or
+   * normal function-call syntax within a member function.
+   */
+  CXCallExpr_CXXMemberCallExpr,
+  /** Call to a CUDA kernel function. */
+  CXCallExpr_CUDAKernelCallExpr,
+  /** Call to a C++ constructor. */
+  CXCallExpr_CXXConstructExpr,
+  /**
+   * Call to an inherited base class constructor from an
+   * inheriting constructor. Implicitly forwards arguments.
+   */
+  CXCallExpr_CXXInheritedCtorInitExpr,
+  /**
+   * C++ functional cast expression building a temporary object.
+   */
+  CXCallExpr_CXXTemporaryObjectExpr,
+  /**
+   * Explicit type conversion using functional notation, unresolved
+   * due to type-dependency.
+   */
+  CXCallExpr_CXXUnresolvedConstructExpr,
+  /**
+   * Call to a user-defined literal.
+   */
+  CXCallExpr_UserDefinedLiteral,
+};
+
+/**
+ *  Retrieve the detailed kind of a call expression.
+ *
+ *  If this cursor is not a CallExpr then returns Invalid.
+ */
+CINDEX_LINKAGE enum CXCallExprKind clang_getCursorCallExprKind(CXCursor cursor);
+
 /**
  * @}
  */
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 418b152ba4a13f..51f78b22c43e0c 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2122,7 +2122,7 @@ class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void>,
   void VisitBlockExpr(const BlockExpr *B);
   void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
   void VisitCompoundStmt(const CompoundStmt *S);
-  void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
+  void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ 
   }
   void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
   void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
@@ -9727,3 +9727,31 @@ enum CXUnaryOperatorKind clang_getCursorUnaryOperatorKind(CXCursor cursor) {
 
   return CXUnaryOperator_Invalid;
 }
+
+enum CXCallExprKind clang_getCursorCallExprKind(CXCursor cursor) {
+  if (clang_isExpression(cursor.kind)) {
+    const Expr *expr = getCursorExpr(cursor);
+
+    switch (expr->getStmtClass()) {
+    case Stmt::CallExprClass:
+      return CXCallExpr_Default;
+    case Stmt::CXXOperatorCallExprClass:
+      return CXCallExpr_CXXOperatorCallExpr;
+    case Stmt::CXXMemberCallExprClass:
+      return CXCallExpr_CXXMemberCallExpr;
+    case Stmt::CUDAKernelCallExprClass:
+      return CXCallExpr_CUDAKernelCallExpr;
+    case Stmt::CXXConstructExprClass:
+      return CXCallExpr_CXXConstructExpr;
+    case Stmt::CXXInheritedCtorInitExprClass:
+      return CXCallExpr_CXXInheritedCtorInitExpr;
+    case Stmt::CXXTemporaryObjectExprClass:
+      return CXCallExpr_CXXTemporaryObjectExpr;
+    case Stmt::CXXUnresolvedConstructExprClass:
+      return CXCallExpr_CXXUnresolvedConstructExpr;
+    case Stmt::UserDefinedLiteralClass:
+      return CXCallExpr_UserDefinedLiteral;
+    }
+  }
+  return CXCallExpr_Invalid;
+}
\ No newline at end of file
diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map
index 5676198a286d9b..5499c38a8289f9 100644
--- a/clang/tools/libclang/libclang.map
+++ b/clang/tools/libclang/libclang.map
@@ -428,6 +428,11 @@ LLVM_17 {
     clang_getCursorUnaryOperatorKind;
 };
 
+LLVM_18 {
+  global:
+    clang_getCursorCallExprKind;
+}
+
 # Example of how to add a new symbol version entry.  If you do add a new symbol
 # version, please update the example to depend on the version you added.
 # LLVM_X {
diff --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp
index 87075a46d75187..a632cd6e3d2293 100644
--- a/clang/unittests/libclang/LibclangTest.cpp
+++ b/clang/unittests/libclang/LibclangTest.cpp
@@ -1172,6 +1172,30 @@ TEST_F(LibclangParseTest, UnaryOperator) {
   });
 }
 
+TEST_F(LibclangParseTest, CallExpr){
+  std::string Main = "main.cpp";
+  const char testSource[] = R"cpp(
+struct X{
+  int operator+(int) const;
+};
+
+int x = X() + 1;
+)cpp";
+  WriteFile(Main, testSource);
+  ClangTU = clang_parseTranslationUnit(Index, Main.c_str(), nullptr, 0, nullptr,
+                                       0, TUFlags);
+
+  Traverse([](CXCursor cursor, CXCursor parent) -> CXChildVisitResult {
+    if (cursor.kind == CXCursor_CallExpr) {
+      EXPECT_EQ(clang_getCursorCallExprKind(cursor),
+                CXCallExpr_CXXOperatorCallExpr);
+      return CXChildVisit_Break;
+    }
+
+    return CXChildVisit_Recurse;
+  });
+}
+
 TEST_F(LibclangParseTest, VisitStaticAssertDecl_noMessage) {
   const char testSource[] = R"cpp(static_assert(true))cpp";
   std::string fileName = "main.cpp";

>From c380c1febad826e64a2beaff721fc1b960542b9c Mon Sep 17 00:00:00 2001
From: ykiko <ykikoykikoykiko at gmail.com>
Date: Fri, 22 Mar 2024 00:13:04 +0800
Subject: [PATCH 2/4] delete a extra space.

---
 clang/tools/libclang/CIndex.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 20e58b656bdcb7..436ebcc580ad4d 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2126,7 +2126,7 @@ class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void>,
   void VisitBlockExpr(const BlockExpr *B);
   void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
   void VisitCompoundStmt(const CompoundStmt *S);
-  void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ 
+  void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
   }
   void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
   void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);

>From 20c1927c2c4bd8ee70f1d1b48cbb4d3017666dfc Mon Sep 17 00:00:00 2001
From: ykiko <ykikoykikoykiko at gmail.com>
Date: Fri, 22 Mar 2024 00:21:53 +0800
Subject: [PATCH 3/4] fix format error

---
 clang/unittests/libclang/LibclangTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp
index a632cd6e3d2293..06ebe6729f065c 100644
--- a/clang/unittests/libclang/LibclangTest.cpp
+++ b/clang/unittests/libclang/LibclangTest.cpp
@@ -1172,7 +1172,7 @@ TEST_F(LibclangParseTest, UnaryOperator) {
   });
 }
 
-TEST_F(LibclangParseTest, CallExpr){
+TEST_F(LibclangParseTest, clang_getCursorCallExprKind) {
   std::string Main = "main.cpp";
   const char testSource[] = R"cpp(
 struct X{

>From 4fa0569914a9b89255fb4dbe0ba7ff0b333cdd34 Mon Sep 17 00:00:00 2001
From: ykiko <ykikoykikoykiko at gmail.com>
Date: Fri, 22 Mar 2024 01:19:54 +0800
Subject: [PATCH 4/4] fix version error.

---
 clang/tools/libclang/libclang.map | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map
index 5499c38a8289f9..0c3a4fc3f8b004 100644
--- a/clang/tools/libclang/libclang.map
+++ b/clang/tools/libclang/libclang.map
@@ -428,10 +428,10 @@ LLVM_17 {
     clang_getCursorUnaryOperatorKind;
 };
 
-LLVM_18 {
+LLVM_19 {
   global:
     clang_getCursorCallExprKind;
-}
+};
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
 # version, please update the example to depend on the version you added.



More information about the cfe-commits mailing list