[clang] 7fbc9de - [libclang] Add CXBinaryOperatorKind and CXUnaryOperatorKind

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 9 07:03:06 PDT 2023


Author: MineGame159
Date: 2023-06-09T10:01:43-04:00
New Revision: 7fbc9de4553666a189b0529ca04e1d9966c0d4f8

URL: https://github.com/llvm/llvm-project/commit/7fbc9de4553666a189b0529ca04e1d9966c0d4f8
DIFF: https://github.com/llvm/llvm-project/commit/7fbc9de4553666a189b0529ca04e1d9966c0d4f8.diff

LOG: [libclang] Add CXBinaryOperatorKind and CXUnaryOperatorKind

Adds 2 new functions to the C libclang api for retrieving operator
kinds for binary and unary operators from cursors. Also adds 2
functions for retrieving the spelling of the new enums.

Fixes https://github.com/llvm/llvm-project/issues/29138
Differential Revision: https://reviews.llvm.org/D150910

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang-c/Index.h
    clang/include/clang/AST/OperationKinds.def
    clang/tools/libclang/CIndex.cpp
    clang/tools/libclang/libclang.map
    clang/unittests/libclang/LibclangTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e3dd7910e7a9e..acd8c4d622a89 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -728,6 +728,9 @@ libclang
   has an evaluable bit width. Fixes undefined behavior when called on a
   bit-field whose width depends on a template parameter.
 
+- Added ``CXBinaryOperatorKind`` and ``CXUnaryOperatorKind``.
+  (`#29138 <https://github.com/llvm/llvm-project/issues/29138>`_)
+
 Static Analyzer
 ---------------
 - Fix incorrect alignment attribute on the this parameter of certain

diff  --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 29c53c0382abe..601b91f67d658 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6510,6 +6510,144 @@ typedef enum CXVisitorResult (*CXFieldVisitor)(CXCursor C,
 CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, CXFieldVisitor visitor,
                                                CXClientData client_data);
 
+/**
+ * Describes the kind of binary operators.
+ */
+enum CXBinaryOperatorKind {
+  /** This value describes cursors which are not binary operators. */
+  CXBinaryOperator_Invalid,
+  /** C++ Pointer - to - member operator. */
+  CXBinaryOperator_PtrMemD,
+  /** C++ Pointer - to - member operator. */
+  CXBinaryOperator_PtrMemI,
+  /** Multiplication operator. */
+  CXBinaryOperator_Mul,
+  /** Division operator. */
+  CXBinaryOperator_Div,
+  /** Remainder operator. */
+  CXBinaryOperator_Rem,
+  /** Addition operator. */
+  CXBinaryOperator_Add,
+  /** Subtraction operator. */
+  CXBinaryOperator_Sub,
+  /** Bitwise shift left operator. */
+  CXBinaryOperator_Shl,
+  /** Bitwise shift right operator. */
+  CXBinaryOperator_Shr,
+  /** C++ three-way comparison (spaceship) operator. */
+  CXBinaryOperator_Cmp,
+  /** Less than operator. */
+  CXBinaryOperator_LT,
+  /** Greater than operator. */
+  CXBinaryOperator_GT,
+  /** Less or equal operator. */
+  CXBinaryOperator_LE,
+  /** Greater or equal operator. */
+  CXBinaryOperator_GE,
+  /** Equal operator. */
+  CXBinaryOperator_EQ,
+  /** Not equal operator. */
+  CXBinaryOperator_NE,
+  /** Bitwise AND operator. */
+  CXBinaryOperator_And,
+  /** Bitwise XOR operator. */
+  CXBinaryOperator_Xor,
+  /** Bitwise OR operator. */
+  CXBinaryOperator_Or,
+  /** Logical AND operator. */
+  CXBinaryOperator_LAnd,
+  /** Logical OR operator. */
+  CXBinaryOperator_LOr,
+  /** Assignment operator. */
+  CXBinaryOperator_Assign,
+  /** Multiplication assignment operator. */
+  CXBinaryOperator_MulAssign,
+  /** Division assignment operator. */
+  CXBinaryOperator_DivAssign,
+  /** Remainder assignment operator. */
+  CXBinaryOperator_RemAssign,
+  /** Addition assignment operator. */
+  CXBinaryOperator_AddAssign,
+  /** Subtraction assignment operator. */
+  CXBinaryOperator_SubAssign,
+  /** Bitwise shift left assignment operator. */
+  CXBinaryOperator_ShlAssign,
+  /** Bitwise shift right assignment operator. */
+  CXBinaryOperator_ShrAssign,
+  /** Bitwise AND assignment operator. */
+  CXBinaryOperator_AndAssign,
+  /** Bitwise XOR assignment operator. */
+  CXBinaryOperator_XorAssign,
+  /** Bitwise OR assignment operator. */
+  CXBinaryOperator_OrAssign,
+  /** Comma operator. */
+  CXBinaryOperator_Comma
+};
+
+/**
+ * Retrieve the spelling of a given CXBinaryOperatorKind.
+ */
+CINDEX_LINKAGE CXString
+clang_getBinaryOperatorKindSpelling(enum CXBinaryOperatorKind kind);
+
+/**
+ * Retrieve the binary operator kind of this cursor.
+ *
+ * If this cursor is not a binary operator then returns Invalid.
+ */
+CINDEX_LINKAGE enum CXBinaryOperatorKind
+clang_getCursorBinaryOperatorKind(CXCursor cursor);
+
+/**
+ * Describes the kind of unary operators.
+ */
+enum CXUnaryOperatorKind {
+  /** This value describes cursors which are not unary operators. */
+  CXUnaryOperator_Invalid,
+  /** Postfix increment operator. */
+  CXUnaryOperator_PostInc,
+  /** Postfix decrement operator. */
+  CXUnaryOperator_PostDec,
+  /** Prefix increment operator. */
+  CXUnaryOperator_PreInc,
+  /** Prefix decrement operator. */
+  CXUnaryOperator_PreDec,
+  /** Address of operator. */
+  CXUnaryOperator_AddrOf,
+  /** Dereference operator. */
+  CXUnaryOperator_Deref,
+  /** Plus operator. */
+  CXUnaryOperator_Plus,
+  /** Minus operator. */
+  CXUnaryOperator_Minus,
+  /** Not operator. */
+  CXUnaryOperator_Not,
+  /** LNot operator. */
+  CXUnaryOperator_LNot,
+  /** "__real expr" operator. */
+  CXUnaryOperator_Real,
+  /** "__imag expr" operator. */
+  CXUnaryOperator_Imag,
+  /** __extension__ marker operator. */
+  CXUnaryOperator_Extension,
+  /** C++ co_await operator. */
+  CXUnaryOperator_Coawait
+};
+
+/**
+ * Retrieve the spelling of a given CXUnaryOperatorKind.
+ */
+CINDEX_LINKAGE CXString
+clang_getUnaryOperatorKindSpelling(enum CXUnaryOperatorKind kind);
+
+/**
+ * Retrieve the unary operator kind of this cursor.
+ *
+ * If this cursor is not a unary operator then returns Invalid.
+ */
+CINDEX_LINKAGE enum CXUnaryOperatorKind
+clang_getCursorUnaryOperatorKind(CXCursor cursor);
+
 /**
  * @}
  */

diff  --git a/clang/include/clang/AST/OperationKinds.def b/clang/include/clang/AST/OperationKinds.def
index b05b9d81569eb..96b5a4db55e0c 100644
--- a/clang/include/clang/AST/OperationKinds.def
+++ b/clang/include/clang/AST/OperationKinds.def
@@ -362,8 +362,8 @@ CAST_OPERATION(IntToOCLSampler)
 
 //===- Binary Operations  -------------------------------------------------===//
 // Operators listed in order of precedence.
-// Note that additions to this should also update the StmtVisitor class and
-// BinaryOperator::getOverloadedOperator.
+// Note that additions to this should also update the StmtVisitor class,
+// BinaryOperator::getOverloadedOperator and CXBinaryOperatorKind enum.
 
 // [C++ 5.5] Pointer-to-member operators.
 BINARY_OPERATION(PtrMemD, ".*")
@@ -415,8 +415,8 @@ BINARY_OPERATION(Comma, ",")
 
 
 //===- Unary Operations ---------------------------------------------------===//
-// Note that additions to this should also update the StmtVisitor class and
-// UnaryOperator::getOverloadedOperator.
+// Note that additions to this should also update the StmtVisitor class,
+// UnaryOperator::getOverloadedOperator and CXUnaryOperatorKind enum.
 
 // [C99 6.5.2.4] Postfix increment and decrement
 UNARY_OPERATION(PostInc, "++")

diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index f7321f0efe6ef..40c7586fe44b5 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -23,8 +23,11 @@
 #include "clang-c/FatalErrorHandler.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclObjCCommon.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/OpenMPClause.h"
+#include "clang/AST/OperationKinds.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticCategories.h"
@@ -9604,3 +9607,38 @@ cxindex::Logger::~Logger() {
     OS << "--------------------------------------------------\n";
   }
 }
+
+CXString clang_getBinaryOperatorKindSpelling(enum CXBinaryOperatorKind kind) {
+  return cxstring::createRef(
+      BinaryOperator::getOpcodeStr(static_cast<BinaryOperatorKind>(kind - 1)));
+}
+
+enum CXBinaryOperatorKind clang_getCursorBinaryOperatorKind(CXCursor cursor) {
+  if (clang_isExpression(cursor.kind)) {
+    const Expr *expr = getCursorExpr(cursor);
+
+    if (const auto *op = dyn_cast<BinaryOperator>(expr))
+      return static_cast<CXBinaryOperatorKind>(op->getOpcode() + 1);
+
+    if (const auto *op = dyn_cast<CXXRewrittenBinaryOperator>(expr))
+      return static_cast<CXBinaryOperatorKind>(op->getOpcode() + 1);
+  }
+
+  return CXBinaryOperator_Invalid;
+}
+
+CXString clang_getUnaryOperatorKindSpelling(enum CXUnaryOperatorKind kind) {
+  return cxstring::createRef(
+      UnaryOperator::getOpcodeStr(static_cast<UnaryOperatorKind>(kind - 1)));
+}
+
+enum CXUnaryOperatorKind clang_getCursorUnaryOperatorKind(CXCursor cursor) {
+  if (clang_isExpression(cursor.kind)) {
+    const Expr *expr = getCursorExpr(cursor);
+
+    if (const auto *op = dyn_cast<UnaryOperator>(expr))
+      return static_cast<CXUnaryOperatorKind>(op->getOpcode() + 1);
+  }
+
+  return CXUnaryOperator_Invalid;
+}

diff  --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map
index 34b1ef1a54514..5676198a286d9 100644
--- a/clang/tools/libclang/libclang.map
+++ b/clang/tools/libclang/libclang.map
@@ -422,6 +422,10 @@ LLVM_17 {
   global:
     clang_CXXMethod_isExplicit;
     clang_createIndexWithOptions;
+    clang_getBinaryOperatorKindSpelling;
+    clang_getCursorBinaryOperatorKind;
+    clang_getUnaryOperatorKindSpelling;
+    clang_getCursorUnaryOperatorKind;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol

diff  --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp
index ca762ebb7492b..f85a72b1c2f70 100644
--- a/clang/unittests/libclang/LibclangTest.cpp
+++ b/clang/unittests/libclang/LibclangTest.cpp
@@ -1138,6 +1138,40 @@ void Class1::fun() {}
             "class ns1::Class1");
 }
 
+TEST_F(LibclangParseTest, BinaryOperator) {
+  std::string Main = "main.cpp";
+  WriteFile(Main, "int foo() { return 5 + 9; }");
+  ClangTU = clang_parseTranslationUnit(Index, Main.c_str(), nullptr, 0, nullptr,
+                                       0, TUFlags);
+
+  Traverse([](CXCursor cursor, CXCursor parent) -> CXChildVisitResult {
+    if (cursor.kind == CXCursor_BinaryOperator) {
+      EXPECT_EQ(clang_getCursorBinaryOperatorKind(cursor),
+                CXBinaryOperator_Add);
+      return CXChildVisit_Break;
+    }
+
+    return CXChildVisit_Recurse;
+  });
+}
+
+TEST_F(LibclangParseTest, UnaryOperator) {
+  std::string Main = "main.cpp";
+  WriteFile(Main, "int foo() { int a = 5; return a++; }");
+  ClangTU = clang_parseTranslationUnit(Index, Main.c_str(), nullptr, 0, nullptr,
+                                       0, TUFlags);
+
+  Traverse([](CXCursor cursor, CXCursor parent) -> CXChildVisitResult {
+    if (cursor.kind == CXCursor_UnaryOperator) {
+      EXPECT_EQ(clang_getCursorUnaryOperatorKind(cursor),
+                CXUnaryOperator_PostInc);
+      return CXChildVisit_Break;
+    }
+
+    return CXChildVisit_Recurse;
+  });
+}
+
 class LibclangRewriteTest : public LibclangParseTest {
 public:
   CXRewriter Rew = nullptr;


        


More information about the cfe-commits mailing list