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
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to