[python-bindings] Added OpCode like support for all enumerations with unittests.

Also fixed some trailing whitespace issues.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201929 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Michael Gottesman 2014-02-22 05:39:35 +00:00
parent a6e734d2ed
commit 0ee9a84cac
2 changed files with 138 additions and 36 deletions

View File

@ -20,6 +20,7 @@ from ctypes import c_uint
__all__ = [ __all__ = [
"lib", "lib",
"Enums",
"OpCode", "OpCode",
"MemoryBuffer", "MemoryBuffer",
"Module", "Module",
@ -32,42 +33,116 @@ __all__ = [
] ]
lib = get_library() lib = get_library()
Enums = []
class OpCode(object): class LLVMEnumeration(object):
"""Represents an individual OpCode enumeration.""" """Represents an individual LLVM enumeration."""
_value_map = {}
def __init__(self, name, value): def __init__(self, name, value):
self.name = name self.name = name
self.value = value self.value = value
def __repr__(self): def __repr__(self):
return 'OpCode.%s' % self.name return '%s.%s' % (self.__class__.__name__,
self.name)
@staticmethod @classmethod
def from_value(value): def from_value(cls, value):
"""Obtain an OpCode instance from a numeric value.""" """Obtain an enumeration instance from a numeric value."""
result = OpCode._value_map.get(value, None) 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 @classmethod
def register(name, value): def register(cls, name, value):
"""Registers a new OpCode enumeration. """Registers a new enumeration.
This is called by this module for each enumeration defined in This is called by this module for each enumeration defined in
enumerations. You should not need to call this outside this module. enumerations. You should not need to call this outside this module.
""" """
if value in OpCode._value_map: if value in cls._value_map:
raise ValueError('OpCode value already registered: %d' % value) 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
opcode = OpCode(name, value) class Attribute(LLVMEnumeration):
OpCode._value_map[value] = opcode """Represents an individual Attribute enumeration."""
setattr(OpCode, name, opcode)
_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."""
_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): class MemoryBuffer(LLVMObject):
"""Represents an opaque memory buffer.""" """Represents an opaque memory buffer."""
@ -516,8 +591,25 @@ def register_library(library):
library.LLVMGetInstructionOpcode.restype = c_uint library.LLVMGetInstructionOpcode.restype = c_uint
def register_enumerations(): def register_enumerations():
for name, value in enumerations.OpCodes: if Enums:
OpCode.register(name, value) 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(): def initialize_llvm():
c = Context.GetGlobalContext() c = Context.GetGlobalContext()
@ -536,5 +628,5 @@ def initialize_llvm():
lib.LLVMInitializeTarget(p) lib.LLVMInitializeTarget(p)
register_library(lib) register_library(lib)
register_enumerations() Enums = register_enumerations()
initialize_llvm() initialize_llvm()

View File

@ -1,20 +1,30 @@
from .base import TestBase from .base import TestBase
from ..core import OpCode
from ..core import MemoryBuffer from ..core import MemoryBuffer
from ..core import PassRegistry from ..core import PassRegistry
from ..core import Context from ..core import Context
from ..core import Module from ..core import Module
from ..core import Enums
from ..core import OpCode
from ..bit_reader import parse_bitcode from ..bit_reader import parse_bitcode
class TestCore(TestBase): class TestCore(TestBase):
def test_opcode(self): def test_enumerations(self):
self.assertTrue(hasattr(OpCode, 'Ret')) for enum_cls, enum_spec in Enums:
self.assertTrue(isinstance(OpCode.Ret, OpCode)) for enum_name, enum_value in enum_spec:
self.assertEqual(OpCode.Ret.value, 1) # 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))
op = OpCode.from_value(1) # Then make sure that the value returned for this attribute is
self.assertTrue(isinstance(op, OpCode)) # correct in both ways.
self.assertEqual(op, OpCode.Ret) 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): def test_memory_buffer_create_from_file(self):
source = self.get_test_file() source = self.get_test_file()
@ -61,7 +71,7 @@ class TestCore(TestBase):
target = "thumbv7-apple-ios5.0.0" target = "thumbv7-apple-ios5.0.0"
m.target = target m.target = target
m.print_module_to_file("test2.ll") m.print_module_to_file("test2.ll")
def test_module_function_iteration(self): def test_module_function_iteration(self):
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc())) m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
i = 0 i = 0
@ -81,19 +91,19 @@ class TestCore(TestBase):
def test_function_basicblock_iteration(self): def test_function_basicblock_iteration(self):
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc())) m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
i = 0 i = 0
bb_list = ['b1', 'b2', 'end'] bb_list = ['b1', 'b2', 'end']
f = m.first f = m.first
while f.name != "f6": while f.name != "f6":
f = f.next f = f.next
# Forward # Forward
for bb in f: for bb in f:
self.assertEqual(bb.name, bb_list[i]) self.assertEqual(bb.name, bb_list[i])
bb.dump() bb.dump()
i += 1 i += 1
# Backwards # Backwards
for bb in reversed(f): for bb in reversed(f):
i -= 1 i -= 1
@ -103,12 +113,12 @@ class TestCore(TestBase):
def test_basicblock_instruction_iteration(self): def test_basicblock_instruction_iteration(self):
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc())) m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
i = 0 i = 0
inst_list = [('arg1', OpCode.ExtractValue), inst_list = [('arg1', OpCode.ExtractValue),
('arg2', OpCode.ExtractValue), ('arg2', OpCode.ExtractValue),
('', OpCode.Call), ('', OpCode.Call),
('', OpCode.Ret)] ('', OpCode.Ret)]
bb = m.first.first bb = m.first.first
# Forward # Forward