From 36b56886974eae4f9c5ebc96befd3e7bfe5de338 Mon Sep 17 00:00:00 2001 From: Stephen Hines Date: Wed, 23 Apr 2014 16:57:46 -0700 Subject: Update to LLVM 3.5a. Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617 --- bindings/ocaml/Makefile.ocaml | 2 +- .../ocaml/transforms/scalar/llvm_scalar_opts.mli | 2 +- bindings/python/llvm/core.py | 136 +++++++++++++++++---- bindings/python/llvm/tests/test_core.py | 42 ++++--- bindings/python/llvm/tests/test_disassembler.py | 4 +- 5 files changed, 143 insertions(+), 43 deletions(-) (limited to 'bindings') diff --git a/bindings/ocaml/Makefile.ocaml b/bindings/ocaml/Makefile.ocaml index f8ed841..1b964ee 100644 --- a/bindings/ocaml/Makefile.ocaml +++ b/bindings/ocaml/Makefile.ocaml @@ -37,7 +37,7 @@ OcamlDir := $(LibDir)/ocaml # Info from llvm-config and similar ifndef IS_CLEANING_TARGET ifdef UsedComponents -UsedLibs = $(shell $(LLVM_CONFIG) --libs $(UsedComponents)) +UsedLibs = $(shell $(LLVM_CONFIG) --libs --system-libs $(UsedComponents)) UsedLibNames = $(shell $(LLVM_CONFIG) --libnames $(UsedComponents)) endif endif diff --git a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli index d69abe2..ab6fa4a 100644 --- a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli +++ b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli @@ -12,7 +12,7 @@ This interface provides an OCaml API for LLVM scalar transforms, the classes in the [LLVMScalarOpts] library. *) -(** See the [llvm::createConstantPropogationPass] function. *) +(** See the [llvm::createConstantPropagationPass] function. *) external add_constant_propagation : [ unit = "llvm_add_constant_propagation" diff --git a/bindings/python/llvm/core.py b/bindings/python/llvm/core.py index ebf57d4..c95952d 100644 --- a/bindings/python/llvm/core.py +++ b/bindings/python/llvm/core.py @@ -20,6 +20,7 @@ from ctypes import c_uint __all__ = [ "lib", + "Enums", "OpCode", "MemoryBuffer", "Module", @@ -32,42 +33,115 @@ __all__ = [ ] 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): - 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: - raise ValueError('Unknown OpCode: %d' % value) + raise ValueError('Unknown %s: %d' % (cls.__name__, + value)) 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. """ - 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) + +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.""" @@ -125,7 +199,7 @@ class Module(LLVMObject): @classmethod def CreateWithName(cls, module_id): m = Module(lib.LLVMModuleCreateWithName(module_id)) - c = Context.GetGlobalContext().take_ownership(m) + Context.GetGlobalContext().take_ownership(m) return m @property @@ -516,11 +590,27 @@ def register_library(library): 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), + ] + 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() + Context.GetGlobalContext() p = PassRegistry() lib.LLVMInitializeCore(p) lib.LLVMInitializeTransformUtils(p) @@ -536,5 +626,5 @@ def initialize_llvm(): lib.LLVMInitializeTarget(p) register_library(lib) -register_enumerations() +Enums = register_enumerations() initialize_llvm() diff --git a/bindings/python/llvm/tests/test_core.py b/bindings/python/llvm/tests/test_core.py index 63f84c8..da7b635 100644 --- a/bindings/python/llvm/tests/test_core.py +++ b/bindings/python/llvm/tests/test_core.py @@ -1,20 +1,30 @@ 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 Enums +from ..core import OpCode 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() @@ -61,7 +71,7 @@ class TestCore(TestBase): 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 @@ -81,19 +91,19 @@ class TestCore(TestBase): def test_function_basicblock_iteration(self): m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc())) i = 0 - + bb_list = ['b1', 'b2', 'end'] - + 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 - + # 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 - + inst_list = [('arg1', OpCode.ExtractValue), ('arg2', OpCode.ExtractValue), ('', OpCode.Call), ('', OpCode.Ret)] - + bb = m.first.first # Forward diff --git a/bindings/python/llvm/tests/test_disassembler.py b/bindings/python/llvm/tests/test_disassembler.py index e960dc0..37a04e4 100644 --- a/bindings/python/llvm/tests/test_disassembler.py +++ b/bindings/python/llvm/tests/test_disassembler.py @@ -16,9 +16,9 @@ class TestDisassembler(TestBase): self.assertEqual(count, 3) self.assertEqual(s, '\tjcxz\t-127') - def test_nonexistant_triple(self): + def test_nonexistent_triple(self): with self.assertRaisesRegexp(Exception, "Could not obtain disassembler for triple"): - Disassembler("nonexistant-triple-raises") + Disassembler("nonexistent-triple-raises") def test_get_instructions(self): sequence = '\x67\xe3\x81\x01\xc7' # jcxz -127; addl %eax, %edi -- cgit v1.1