RedX2501 updated this revision to Diff 39176.
RedX2501 added a comment.

Changed points raised during review.


http://reviews.llvm.org/D10833

Files:
  bindings/python/clang/cindex.py
  bindings/python/tests/cindex/test_cursor.py
  include/clang-c/Index.h
  include/clang/AST/OperationKinds.h
  test/Index/binop.cpp
  tools/c-index-test/c-index-test.c
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -3725,6 +3725,11 @@
       return cxstring::createDup(OS.str());
     }
 
+    if (C.kind == CXCursor_BinaryOperator ||
+        C.kind == CXCursor_CompoundAssignOperator) {
+      return clang_Cursor_getBinaryOpcodeStr(clang_Cursor_getBinaryOpcode(C));
+    }
+
     const Decl *D = getDeclFromExpr(getCursorExpr(C));
     if (D)
       return getDeclSpelling(D);
@@ -6741,6 +6746,29 @@
   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(enum CX_BinaryOperatorKind Op) {
+	if (Op > CX_BO_LAST) {
+		return cxstring::createEmpty();
+	}
+
+	return cxstring::createDup(
+			BinaryOperator::getOpcodeStr(static_cast<BinaryOperatorKind>(Op - 1)));
+}
+
 CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
   if (!clang_isDeclaration(C.kind))
     return clang_getNullRange();
Index: tools/c-index-test/c-index-test.c
===================================================================
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1425,6 +1425,21 @@
   return CXChildVisit_Recurse;
 }
 
+static enum CXChildVisitResult PrintBinOps(CXCursor C, CXCursor p,
+                                           CXClientData d){
+  enum CXCursorKind ck = clang_getCursorKind(C);
+  if (ck != CXCursor_BinaryOperator && ck != CXCursor_CompoundAssignOperator)
+    return CXChildVisit_Recurse;
+
+  PrintCursor(C, NULL);
+  enum CX_BinaryOperatorKind bok = clang_Cursor_getBinaryOpcode(C);
+  CXString opstr = clang_Cursor_getBinaryOpcodeStr(bok);
+  printf(" BinOp=%s %d\n", clang_getCString(opstr), bok);
+
+  return CXChildVisit_Recurse;
+}
+
+
 /******************************************************************************/
 /* Mangling testing.                                                          */
 /******************************************************************************/
@@ -4068,6 +4083,7 @@
     "       c-index-test -test-print-type {<args>}*\n"
     "       c-index-test -test-print-type-size {<args>}*\n"
     "       c-index-test -test-print-bitwidth {<args>}*\n"
+    "       c-index-test -test-print-binops {<args>}*\n"
     "       c-index-test -print-usr [<CursorKind> {<args>}]*\n"
     "       c-index-test -print-usr-file <file>\n"
     "       c-index-test -write-pch <file> <compiler arguments>\n");
@@ -4161,6 +4177,9 @@
   else if (argc > 2 && strcmp(argv[1], "-test-print-bitwidth") == 0)
     return perform_test_load_source(argc - 2, argv + 2, "all",
                                     PrintBitWidth, 0);
+  else if (argc > 2 && strcmp(argv[1], "-test-print-binops") == 0)
+    return perform_test_load_source(argc - 2, argv + 2, "all",
+                                    PrintBinOps, 0);
   else if (argc > 2 && strcmp(argv[1], "-test-print-mangle") == 0)
     return perform_test_load_tu(argv[2], "all", NULL, PrintMangledName, NULL);
   else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) {
Index: test/Index/binop.cpp
===================================================================
--- /dev/null
+++ test/Index/binop.cpp
@@ -0,0 +1,90 @@
+// RUN: c-index-test -test-print-binops %s | FileCheck %s
+
+struct C {
+  int m;
+};
+
+void func(void){
+	int a, b;
+  int C::* p = &C::m;
+
+	C c;
+	c.*p;
+
+	C* pc;
+	pc->*p;
+
+	a * b;
+	a / b;
+	a % b;
+	a + b;
+	a - b;
+
+	a << b;
+	a >> b;
+
+	a < b;
+	a > b;
+
+	a <= b;
+	a >= b;
+	a == b;
+	a != b;
+	
+	a & b;
+	a ^ b;
+	a | b;
+
+	a && b;
+	a || b;
+
+	a = b;
+
+	a *= b;
+	a /= b;
+	a %= b;
+	a += b;
+	a -= b;
+	
+	a <<= b;
+	a >>= b;
+
+	a &= b;
+	a ^= b;
+	a |= b;
+	a , b;
+
+}
+
+// CHECK: BinaryOperator=.* BinOp=.* 1
+// CHECK: BinaryOperator=->* BinOp=->* 2
+// CHECK: BinaryOperator=* BinOp=* 3
+// CHECK: BinaryOperator=/ BinOp=/ 4
+// CHECK: BinaryOperator=% BinOp=% 5
+// CHECK: BinaryOperator=+ BinOp=+ 6
+// CHECK: BinaryOperator=- BinOp=- 7
+// CHECK: BinaryOperator=<< BinOp=<< 8
+// CHECK: BinaryOperator=>> BinOp=>> 9
+// CHECK: BinaryOperator=< BinOp=< 10
+// CHECK: BinaryOperator=> BinOp=> 11
+// CHECK: BinaryOperator=<= BinOp=<= 12
+// CHECK: BinaryOperator=>= BinOp=>= 13
+// CHECK: BinaryOperator=== BinOp=== 14
+// CHECK: BinaryOperator=!= BinOp=!= 15
+// CHECK: BinaryOperator=& BinOp=& 16
+// CHECK: BinaryOperator=^ BinOp=^ 17
+// CHECK: BinaryOperator=| BinOp=| 18
+// CHECK: BinaryOperator=&& BinOp=&& 19
+// CHECK: BinaryOperator=|| BinOp=|| 20
+// CHECK: BinaryOperator== BinOp== 21
+// CHECK: CompoundAssignOperator=*= BinOp=*= 22
+// CHECK: CompoundAssignOperator=/= BinOp=/= 23
+// CHECK: CompoundAssignOperator=%= BinOp=%= 24
+// CHECK: CompoundAssignOperator=+= BinOp=+= 25
+// CHECK: CompoundAssignOperator=-= BinOp=-= 26
+// CHECK: CompoundAssignOperator=<<= BinOp=<<= 27
+// CHECK: CompoundAssignOperator=>>= BinOp=>>= 28
+// CHECK: CompoundAssignOperator=&= BinOp=&= 29
+// CHECK: CompoundAssignOperator=^= BinOp=^= 30
+// CHECK: CompoundAssignOperator=|= BinOp=|= 31
+// CHECK: BinaryOperator=, BinOp=, 32
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: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -3828,6 +3828,52 @@
  */
 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,
+  CX_BO_LAST = 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(enum CX_BinaryOperatorKind Op);
 /**
  * \brief Given a cursor that represents a declaration, return the associated
  * comment's source range.  The range may include multiple consecutive comments
Index: bindings/python/tests/cindex/test_cursor.py
===================================================================
--- bindings/python/tests/cindex/test_cursor.py
+++ bindings/python/tests/cindex/test_cursor.py
@@ -5,6 +5,7 @@
 from clang.cindex import TemplateArgumentKind
 from clang.cindex import TranslationUnit
 from clang.cindex import TypeKind
+from clang.cindex import BinaryOperator
 from .util import get_cursor
 from .util import get_cursors
 from .util import get_tu
@@ -266,6 +267,109 @@
     assert ham.kind == CursorKind.ENUM_CONSTANT_DECL
     assert ham.enum_value == 0x10000000000
 
+binops = """
+struct C {
+   int m;
+ };
+
+ void func(void){
+   int a, b;
+   int C::* p = &C::
+
+   C c;
+   c.*p;
+
+   C* pc;
+   pc->*p;
+
+   a * b;
+   a / b;
+   a % b;
+   a + b;
+   a - b;
+
+   a << b;
+   a >> b;
+
+   a < b;
+   a > b;
+
+   a <= b;
+   a >= b;
+   a == b;
+   a != b;
+
+   a & b;
+   a ^ b;
+   a | b;
+
+   a && b;
+   a || b;
+
+   a = b;
+
+   a *= b;
+   a /= b;
+   a %= b;
+   a += b;
+   a -= b;
+
+   a <<= b;
+   a >>= b;
+
+   a &= b;
+   a ^= b;
+   a |= b;
+   a , b;
+
+ }
+ """
+
+def test_binop():
+    tu = get_tu(binops, lang="cpp")
+
+    operators = {
+        # not exposed yet
+        # ".*" : BinaryOperator.PtrMemD,
+        "->*" : BinaryOperator.PtrMemI,
+        "*" : BinaryOperator.Mul,
+        "/" : BinaryOperator.Div,
+        "%" : BinaryOperator.Rem,
+        "+" : BinaryOperator.Add,
+        "-" : BinaryOperator.Sub,
+        "<<" : BinaryOperator.Shl,
+        ">>" : BinaryOperator.Shr,
+        "<" : BinaryOperator.LT,
+        ">" : BinaryOperator.GT,
+        "<=" : BinaryOperator.LE,
+        ">=" : BinaryOperator.GE,
+        "==" : BinaryOperator.EQ,
+        "!=" : BinaryOperator.NE,
+        "&" : BinaryOperator.And,
+        "^" : BinaryOperator.Xor,
+        "|" : BinaryOperator.Or,
+        "&&" : BinaryOperator.LAnd,
+        "||" : BinaryOperator.LOr,
+        "=" : BinaryOperator.Assign,
+        "*=" : BinaryOperator.MulAssign,
+        "/=" : BinaryOperator.DivAssign,
+        "%=" : BinaryOperator.RemAssign,
+        "+=" : BinaryOperator.AddAssign,
+        "-=" : BinaryOperator.SubAssign,
+        "<<=" : BinaryOperator.ShlAssign,
+        ">>=" : BinaryOperator.ShrAssign,
+        "&=" : BinaryOperator.AndAssign,
+        "^=" : BinaryOperator.XorAssign,
+        "|=" : BinaryOperator.OrAssign,
+        "," : BinaryOperator.Comma,
+    }
+
+
+    for op, typ in operators.items():
+        c = get_cursor(tu, op)
+        assert c.binary_operator == typ
+
+
 def test_annotation_attribute():
     tu = get_tu('int foo (void) __attribute__ ((annotate("here be annotation attribute")));')
 
Index: bindings/python/clang/cindex.py
===================================================================
--- bindings/python/clang/cindex.py
+++ bindings/python/clang/cindex.py
@@ -1284,6 +1284,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
@@ -1559,6 +1571,60 @@
         res._tu = args[0]._tu
         return res
 
+class BinaryOperator(BaseEnumeration):
+    """
+    Describes the BinaryOperator of a declaration
+    """
+
+    # The unique kind objects, index by id.
+    _kinds = []
+    _name_map = None
+
+    def __nonzero__(self):
+        """ Allows checks of the kind ```if cursor.binary_operator:```"""
+        return self.value != 0
+
+    @property
+    def is_assignment(self):
+        return BinaryOperator.Assign.value <= self.value < BinaryOperator.Comma.value
+
+    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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to