[python-bindings] Added OpCode like support for all enumerations with unittests.
authorMichael Gottesman <mgottesman@apple.com>
Sat, 22 Feb 2014 05:39:35 +0000 (05:39 +0000)
committerMichael Gottesman <mgottesman@apple.com>
Sat, 22 Feb 2014 05:39:35 +0000 (05:39 +0000)
Also fixed some trailing whitespace issues.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201929 91177308-0d34-0410-b5e6-96231b3b80d8

bindings/python/llvm/core.py
bindings/python/llvm/tests/test_core.py

index ebf57d44438bf14f4657117b681fba0b0cb53c7a..e8bfab8445f7e0fc7aa2709b1f1b1020f854acb9 100644 (file)
@@ -20,6 +20,7 @@ from ctypes import c_uint
 
 __all__ = [
     "lib",
 
 __all__ = [
     "lib",
+    "Enums",
     "OpCode",
     "MemoryBuffer",
     "Module",
     "OpCode",
     "MemoryBuffer",
     "Module",
@@ -32,42 +33,116 @@ __all__ = [
 ]
 
 lib = get_library()
 ]
 
 lib = get_library()
+Enums = []
 
 
-class OpCode(object):
-    """Represents an individual OpCode enumeration."""
-
-    _value_map = {}
+class LLVMEnumeration(object):
+    """Represents an individual LLVM enumeration."""
 
     def __init__(self, name, value):
         self.name = name
         self.value = value
 
     def __repr__(self):
 
     def __init__(self, name, value):
         self.name = name
         self.value = value
 
     def __repr__(self):
-        return 'OpCode.%s' % self.name
+        return '%s.%s' % (self.__class__.__name__,
+                          self.name)
 
 
-    @staticmethod
-    def from_value(value):
-        """Obtain an OpCode instance from a numeric value."""
-        result = OpCode._value_map.get(value, None)
+    @classmethod
+    def from_value(cls, value):
+        """Obtain an enumeration instance from a numeric value."""
+        result = cls._value_map.get(value, None)
 
         if result is None:
 
         if result is None:
-            raise ValueError('Unknown OpCode: %d' % value)
+            raise ValueError('Unknown %s: %d' % (cls.__name__,
+                                                 value))
 
         return result
 
 
         return result
 
-    @staticmethod
-    def register(name, value):
-        """Registers a new OpCode enumeration.
+    @classmethod
+    def register(cls, name, value):
+        """Registers a new enumeration.
 
         This is called by this module for each enumeration defined in
         enumerations. You should not need to call this outside this module.
         """
 
         This is called by this module for each enumeration defined in
         enumerations. You should not need to call this outside this module.
         """
-        if value in OpCode._value_map:
-            raise ValueError('OpCode value already registered: %d' % value)
+        if value in cls._value_map:
+            raise ValueError('%s value already registered: %d' % (cls.__name__,
+                                                                  value))
+        enum = cls(name, value)
+        cls._value_map[value] = enum
+        setattr(cls, name, enum)
+        #print cls, name, value
+
+class Attribute(LLVMEnumeration):
+    """Represents an individual Attribute enumeration."""
+
+    _value_map = {}
+
+    def __init__(self, name, value):
+        super(Attribute, self).__init__(name, value)
+
+class OpCode(LLVMEnumeration):
+    """Represents an individual OpCode enumeration."""
+
+    _value_map = {}
+
+    def __init__(self, name, value):
+        super(OpCode, self).__init__(name, value)
+
+class TypeKind(LLVMEnumeration):
+    """Represents an individual TypeKind enumeration."""
+
+    _value_map = {}
+
+    def __init__(self, name, value):
+        super(TypeKind, self).__init__(name, value)
+
+class Linkage(LLVMEnumeration):
+    """Represents an individual Linkage enumeration."""
+
+    _value_map = {}
+
+    def __init__(self, name, value):
+        super(Linkage, self).__init__(name, value)
+
+class Visibility(LLVMEnumeration):
+    """Represents an individual visibility enumeration."""
+
+    _value_map = {}
+
+    def __init__(self, name, value):
+        super(Visibility, self).__init__(name, value)
+
+class CallConv(LLVMEnumeration):
+    """Represents an individual calling convention enumeration."""
 
 
-        opcode = OpCode(name, value)
-        OpCode._value_map[value] = opcode
-        setattr(OpCode, name, opcode)
+    _value_map = {}
+
+    def __init__(self, name, value):
+        super(CallConv, self).__init__(name, value)
+
+class IntPredicate(LLVMEnumeration):
+    """Represents an individual IntPredicate enumeration."""
+
+    _value_map = {}
+
+    def __init__(self, name, value):
+        super(IntPredicate, self).__init__(name, value)
+
+class RealPredicate(LLVMEnumeration):
+    """Represents an individual RealPredicate enumeration."""
+
+    _value_map = {}
+
+    def __init__(self, name, value):
+        super(RealPredicate, self).__init__(name, value)
+
+class LandingPadClauseTy(LLVMEnumeration):
+    """Represents an individual LandingPadClauseTy enumeration."""
+
+    _value_map = {}
+
+    def __init__(self, name, value):
+        super(LandingPadClauseTy, self).__init__(name, value)
 
 class MemoryBuffer(LLVMObject):
     """Represents an opaque memory buffer."""
 
 class MemoryBuffer(LLVMObject):
     """Represents an opaque memory buffer."""
@@ -516,8 +591,25 @@ def register_library(library):
     library.LLVMGetInstructionOpcode.restype = c_uint
 
 def register_enumerations():
     library.LLVMGetInstructionOpcode.restype = c_uint
 
 def register_enumerations():
-    for name, value in enumerations.OpCodes:
-        OpCode.register(name, value)
+    if Enums:
+        return None
+    enums = [
+        (Attribute, enumerations.Attributes),
+        (OpCode, enumerations.OpCodes),
+        (TypeKind, enumerations.TypeKinds),
+        (Linkage, enumerations.Linkages),
+        (Visibility, enumerations.Visibility),
+        (CallConv, enumerations.CallConv),
+        (IntPredicate, enumerations.IntPredicate),
+        (RealPredicate, enumerations.RealPredicate),
+        (LandingPadClauseTy, enumerations.LandingPadClauseTy),
+    ]
+    s = set([])
+    for enum_class, enum_spec in enums:
+        for name, value in enum_spec:
+            print name, value
+            enum_class.register(name, value)
+    return enums
 
 def initialize_llvm():
     c = Context.GetGlobalContext()
 
 def initialize_llvm():
     c = Context.GetGlobalContext()
@@ -536,5 +628,5 @@ def initialize_llvm():
     lib.LLVMInitializeTarget(p)
 
 register_library(lib)
     lib.LLVMInitializeTarget(p)
 
 register_library(lib)
-register_enumerations()
+Enums = register_enumerations()
 initialize_llvm()
 initialize_llvm()
index 63f84c828bc8ac8eefbee45efa41799b3854ccf9..da7b635ec999b70020606db73e89c27b5742e748 100644 (file)
@@ -1,20 +1,30 @@
 from .base import TestBase
 from .base import TestBase
-from ..core import OpCode
 from ..core import MemoryBuffer
 from ..core import PassRegistry
 from ..core import Context
 from ..core import Module
 from ..core import MemoryBuffer
 from ..core import PassRegistry
 from ..core import Context
 from ..core import Module
+from ..core import Enums
+from ..core import OpCode
 from ..bit_reader import parse_bitcode
 
 class TestCore(TestBase):
 from ..bit_reader import parse_bitcode
 
 class TestCore(TestBase):
-    def test_opcode(self):
-        self.assertTrue(hasattr(OpCode, 'Ret'))
-        self.assertTrue(isinstance(OpCode.Ret, OpCode))
-        self.assertEqual(OpCode.Ret.value, 1)
-
-        op = OpCode.from_value(1)
-        self.assertTrue(isinstance(op, OpCode))
-        self.assertEqual(op, OpCode.Ret)
+    def test_enumerations(self):
+        for enum_cls, enum_spec in Enums:
+            for enum_name, enum_value in enum_spec:
+                # First make sure that enum_cls has the name of the enum as an
+                # attribute. People will access these values as
+                # EnumCls.EnumName.
+                self.assertTrue(hasattr(enum_cls, enum_name))
+                v_attr = getattr(enum_cls, enum_name)
+                self.assertTrue(isinstance(v_attr, enum_cls))
+
+                # Then make sure that the value returned for this attribute is
+                # correct in both ways.
+                self.assertEqual(v_attr.value, enum_value)
+
+                e = enum_cls.from_value(enum_value)
+                self.assertTrue(isinstance(e, enum_cls))
+                self.assertEqual(e, v_attr)
 
     def test_memory_buffer_create_from_file(self):
         source = self.get_test_file()
 
     def test_memory_buffer_create_from_file(self):
         source = self.get_test_file()
@@ -61,7 +71,7 @@ class TestCore(TestBase):
         target = "thumbv7-apple-ios5.0.0"
         m.target = target
         m.print_module_to_file("test2.ll")
         target = "thumbv7-apple-ios5.0.0"
         m.target = target
         m.print_module_to_file("test2.ll")
-    
+
     def test_module_function_iteration(self):
         m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
         i = 0
     def test_module_function_iteration(self):
         m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
         i = 0
@@ -81,19 +91,19 @@ class TestCore(TestBase):
     def test_function_basicblock_iteration(self):
         m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
         i = 0
     def test_function_basicblock_iteration(self):
         m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
         i = 0
-        
+
         bb_list = ['b1', 'b2', 'end']
         bb_list = ['b1', 'b2', 'end']
-        
+
         f = m.first
         while f.name != "f6":
             f = f.next
         f = m.first
         while f.name != "f6":
             f = f.next
-        
+
         # Forward
         for bb in f:
             self.assertEqual(bb.name, bb_list[i])
             bb.dump()
             i += 1
         # Forward
         for bb in f:
             self.assertEqual(bb.name, bb_list[i])
             bb.dump()
             i += 1
-        
+
         # Backwards
         for bb in reversed(f):
             i -= 1
         # Backwards
         for bb in reversed(f):
             i -= 1
@@ -103,12 +113,12 @@ class TestCore(TestBase):
     def test_basicblock_instruction_iteration(self):
         m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
         i = 0
     def test_basicblock_instruction_iteration(self):
         m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
         i = 0
-        
+
         inst_list = [('arg1', OpCode.ExtractValue),
                      ('arg2', OpCode.ExtractValue),
                      ('', OpCode.Call),
                      ('', OpCode.Ret)]
         inst_list = [('arg1', OpCode.ExtractValue),
                      ('arg2', OpCode.ExtractValue),
                      ('', OpCode.Call),
                      ('', OpCode.Ret)]
-        
+
         bb = m.first.first
 
         # Forward
         bb = m.first.first
 
         # Forward