mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-26 16:05:54 +00:00
[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:
parent
a6e734d2ed
commit
0ee9a84cac
@ -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()
|
||||||
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user