Retrieve BinaryOperator::getOpcode and BinaryOperator::getOpcodeStr via
libclang and its python interface.
http://reviews.llvm.org/D10833
Files:
bindings/python/clang/cindex.py
include/clang-c/Index.h
include/clang/AST/OperationKinds.h
tools/libclang/CIndex.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: bindings/python/clang/cindex.py
===================================================================
--- bindings/python/clang/cindex.py
+++ bindings/python/clang/cindex.py
@@ -1258,6 +1258,18 @@
return StorageClass.from_id(self._storage_class)
@property
+ def binary_operator(self):
+ """
+ Retrieves the opcode if this cursor points to a binary operator
+ :return:
+ """
+
+ if not hasattr(self, '_binopcode'):
+ self._binopcode = conf.lib.clang_Cursor_getBinaryOpCode(self)
+
+ return BinaryOperator.from_id(self._binopcode)
+
+ @property
def access_specifier(self):
"""
Retrieves the access specifier (if any) of the entity pointed at by the
@@ -1533,6 +1545,84 @@
res._tu = args[0]._tu
return res
+class BinaryOperator(object):
+ """
+ Describes the BinaryOperator of a declaration
+ """
+
+ # The unique kind objects, index by id.
+ _kinds = []
+ _name_map = None
+
+ def __init__(self, value):
+ if value >= len(BinaryOperator._kinds):
+ BinaryOperator._kinds += [None] * (value - len(BinaryOperator._kinds) + 1)
+ if BinaryOperator._kinds[value] is not None:
+ raise ValueError, 'BinaryOperator already loaded'
+ self.value = value
+ BinaryOperator._kinds[value] = self
+ BinaryOperator._name_map = None
+
+ def from_param(self):
+ return self.value
+
+ @property
+ def name(self):
+ """Get the enumeration name of this storage class."""
+ if self._name_map is None:
+ self._name_map = {}
+ for key, value in BinaryOperator.__dict__.items():
+ if isinstance(value, BinaryOperator):
+ self._name_map[value] = key
+ return self._name_map[self]
+
+ @property
+ def is_assignment(self):
+ return BinaryOperator.Assign.value <= self.value < BinaryOperator.Comma.value
+
+ @staticmethod
+ def from_id(id):
+ if id >= len(BinaryOperator._kinds) or not BinaryOperator._kinds[id]:
+ raise ValueError,'Unknown storage class %d' % id
+ return BinaryOperator._kinds[id]
+
+ def __repr__(self):
+ return 'BinaryOperator.%s' % (self.name,)
+
+BinaryOperator.Invalid = BinaryOperator(0)
+BinaryOperator.PtrMemD = BinaryOperator(1)
+BinaryOperator.PtrMemI = BinaryOperator(2)
+BinaryOperator.Mul = BinaryOperator(3)
+BinaryOperator.Div = BinaryOperator(4)
+BinaryOperator.Rem = BinaryOperator(5)
+BinaryOperator.Add = BinaryOperator(6)
+BinaryOperator.Sub = BinaryOperator(7)
+BinaryOperator.Shl = BinaryOperator(8)
+BinaryOperator.Shr = BinaryOperator(9)
+BinaryOperator.LT = BinaryOperator(10)
+BinaryOperator.GT = BinaryOperator(11)
+BinaryOperator.LE = BinaryOperator(12)
+BinaryOperator.GE = BinaryOperator(13)
+BinaryOperator.EQ = BinaryOperator(14)
+BinaryOperator.NE = BinaryOperator(15)
+BinaryOperator.And = BinaryOperator(16)
+BinaryOperator.Xor = BinaryOperator(17)
+BinaryOperator.Or = BinaryOperator(18)
+BinaryOperator.LAnd = BinaryOperator(19)
+BinaryOperator.LOr = BinaryOperator(20)
+BinaryOperator.Assign = BinaryOperator(21)
+BinaryOperator.MulAssign = BinaryOperator(22)
+BinaryOperator.DivAssign = BinaryOperator(23)
+BinaryOperator.RemAssign = BinaryOperator(24)
+BinaryOperator.AddAssign = BinaryOperator(25)
+BinaryOperator.SubAssign = BinaryOperator(26)
+BinaryOperator.ShlAssign = BinaryOperator(27)
+BinaryOperator.ShrAssign = BinaryOperator(28)
+BinaryOperator.AndAssign = BinaryOperator(29)
+BinaryOperator.XorAssign = BinaryOperator(30)
+BinaryOperator.OrAssign = BinaryOperator(31)
+BinaryOperator.Comma = BinaryOperator(32)
+
class StorageClass(object):
"""
Describes the storage class of a declaration
Index: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -3812,6 +3812,51 @@
*/
CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C);
+enum CX_BinaryOperatorKind {
+ CX_BO_Invalid,
+ CX_BO_PtrMemD,
+ CX_BO_PtrMemI,
+ CX_BO_Mul,
+ CX_BO_Div,
+ CX_BO_Rem,
+ CX_BO_Add,
+ CX_BO_Sub,
+ CX_BO_Shl,
+ CX_BO_Shr,
+ CX_BO_LT,
+ CX_BO_GT,
+ CX_BO_LE,
+ CX_BO_GE,
+ CX_BO_EQ,
+ CX_BO_NE,
+ CX_BO_And,
+ CX_BO_Xor,
+ CX_BO_Or,
+ CX_BO_LAnd,
+ CX_BO_LOr,
+ CX_BO_Assign,
+ CX_BO_MulAssign,
+ CX_BO_DivAssign,
+ CX_BO_RemAssign,
+ CX_BO_AddAssign,
+ CX_BO_SubAssign,
+ CX_BO_ShlAssign,
+ CX_BO_ShrAssign,
+ CX_BO_AndAssign,
+ CX_BO_XorAssign,
+ CX_BO_OrAssign,
+ CX_BO_Comma
+};
+
+/**
+ * \brief Returns the operator code for the binary operator.
+ */
+CINDEX_LINKAGE enum CX_BinaryOperatorKind clang_Cursor_getBinaryOpCode(CXCursor C);
+
+/**
+ * \brief Returns a string containing the spelling of the binary operator.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getBinaryOpCodeStr(CXCursor C);
/**
* \brief Given a cursor that represents a declaration, return the associated
* comment's source range. The range may include multiple consecutive comments
Index: include/clang/AST/OperationKinds.h
===================================================================
--- include/clang/AST/OperationKinds.h
+++ include/clang/AST/OperationKinds.h
@@ -305,7 +305,8 @@
enum BinaryOperatorKind {
// Operators listed in order of precedence.
- // Note that additions to this should also update the StmtVisitor class.
+ // Note that additions to this should also update the StmtVisitor class
+ // and the C bindings in libclang.
BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators.
BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators.
BO_Add, BO_Sub, // [C99 6.5.6] Additive operators.
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -3670,6 +3670,11 @@
return cxstring::createDup(OS.str());
}
+ if (C.kind == CXCursor_BinaryOperator ||
+ C.kind == CXCursor_CompoundAssignOperator) {
+ return clang_Cursor_getBinaryOpCodeStr(C);
+ }
+
const Decl *D = getDeclFromExpr(getCursorExpr(C));
if (D)
return getDeclSpelling(D);
@@ -3683,18 +3688,18 @@
return cxstring::createEmpty();
}
-
+
if (C.kind == CXCursor_MacroExpansion)
return cxstring::createRef(getCursorMacroExpansion(C).getName()
- ->getNameStart());
+ ->getNameStart());
if (C.kind == CXCursor_MacroDefinition)
return cxstring::createRef(getCursorMacroDefinition(C)->getName()
- ->getNameStart());
+ ->getNameStart());
if (C.kind == CXCursor_InclusionDirective)
return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
-
+
if (clang_isDeclaration(C.kind))
return getDeclSpelling(getCursorDecl(C));
@@ -6667,6 +6672,34 @@
return 0;
}
+enum CX_BinaryOperatorKind clang_Cursor_getBinaryOpCode(CXCursor C) {
+ if (C.kind != CXCursor_BinaryOperator &&
+ C.kind != CXCursor_CompoundAssignOperator) {
+ return CX_BO_Invalid;
+ }
+
+ const Expr *D = getCursorExpr(C);
+ if (const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(D)) {
+ return static_cast<CX_BinaryOperatorKind>(BinOp->getOpcode() + 1);
+ }
+
+ return CX_BO_Invalid;
+}
+
+CXString clang_Cursor_getBinaryOpCodeStr(CXCursor C) {
+ if (C.kind != CXCursor_BinaryOperator &&
+ C.kind != CXCursor_CompoundAssignOperator) {
+ return cxstring::createEmpty();
+ }
+
+ const Expr *D = getCursorExpr(C);
+ if (const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(D)) {
+ return cxstring::createDup(BinOp->getOpcodeStr());
+ }
+
+ return cxstring::createEmpty();
+}
+
CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullRange();
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits