forked from OSchip/llvm-project
[python-bindings] Added OpCode like support for all enumerations with unittests.
Also fixed some trailing whitespace issues. llvm-svn: 201929
This commit is contained in:
parent
9cd270e26e
commit
29ef6b0aca
llvm/bindings/python/llvm
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue