[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