diff --git a/CHANGELOG b/CHANGELOG index a1e25a2..64b378e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ 0.6, in progress: + * More properties/methods for TargetData. + * Value.uses API. * Fetch operands of instructions (Seth Warn). * Unaliased objects (with Seth Warn). * Value factory, more Constant subclasses. diff --git a/llvm/_core.c b/llvm/_core.c index 89d3566..7d18c61 100644 --- a/llvm/_core.c +++ b/llvm/_core.c @@ -860,6 +860,26 @@ _wLLVMTargetDataAsString(PyObject *self, PyObject *args) } _wrap_objobj2none(LLVMAddTargetData, LLVMTargetDataRef, LLVMPassManagerRef) +_wrap_obj2obj(LLVMByteOrder, LLVMTargetDataRef, int) +_wrap_obj2obj(LLVMPointerSize, LLVMTargetDataRef, int) +_wrap_obj2obj(LLVMIntPtrType, LLVMTargetDataRef, LLVMTypeRef) +_wrap_objobj2obj(LLVMSizeOfTypeInBits, LLVMTargetDataRef, LLVMTypeRef, + llvmwrap_ull) +_wrap_objobj2obj(LLVMStoreSizeOfType, LLVMTargetDataRef, LLVMTypeRef, + llvmwrap_ull) +_wrap_objobj2obj(LLVMABISizeOfType, LLVMTargetDataRef, LLVMTypeRef, + llvmwrap_ull) +_wrap_objobj2obj(LLVMABIAlignmentOfType, LLVMTargetDataRef, LLVMTypeRef, + int) +_wrap_objobj2obj(LLVMCallFrameAlignmentOfType, LLVMTargetDataRef, LLVMTypeRef, + int) +_wrap_objobj2obj(LLVMPreferredAlignmentOfType, LLVMTargetDataRef, LLVMTypeRef, + int) +_wrap_objobj2obj(LLVMPreferredAlignmentOfGlobal, LLVMTargetDataRef, + LLVMValueRef, int) +_wrap_objobjull2obj(LLVMElementAtOffset, LLVMTargetDataRef, LLVMTypeRef, int) +_wrap_objobjint2obj(LLVMOffsetOfElement, LLVMTargetDataRef, LLVMTypeRef, + llvmwrap_ull) /*===----------------------------------------------------------------------===*/ @@ -1466,6 +1486,18 @@ static PyMethodDef core_methods[] = { _method( LLVMDisposeTargetData ) _method( LLVMTargetDataAsString ) _method( LLVMAddTargetData ) + _method( LLVMByteOrder ) + _method( LLVMPointerSize ) + _method( LLVMIntPtrType ) + _method( LLVMSizeOfTypeInBits ) + _method( LLVMStoreSizeOfType ) + _method( LLVMABISizeOfType ) + _method( LLVMABIAlignmentOfType ) + _method( LLVMCallFrameAlignmentOfType ) + _method( LLVMPreferredAlignmentOfType ) + _method( LLVMPreferredAlignmentOfGlobal ) + _method( LLVMElementAtOffset ) + _method( LLVMOffsetOfElement ) /* Execution Engine */ _method( LLVMCreateExecutionEngine ) diff --git a/llvm/core.py b/llvm/core.py index 91ca960..2ba1a9b 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -239,12 +239,13 @@ from llvm._intrinsic_ids import * # Helpers (for internal use) #===----------------------------------------------------------------------=== -def check_is_type(obj): _util.check_gen(obj, Type) -def check_is_value(obj): _util.check_gen(obj, Value) -def check_is_constant(obj): _util.check_gen(obj, Constant) -def check_is_function(obj): _util.check_gen(obj, Function) -def check_is_basic_block(obj): _util.check_gen(obj, BasicBlock) -def check_is_module(obj): _util.check_gen(obj, Module) +def check_is_type(obj): _util.check_gen(obj, Type) +def check_is_type_struct(obj): _util.check_gen(obj, StructType) +def check_is_value(obj): _util.check_gen(obj, Value) +def check_is_constant(obj): _util.check_gen(obj, Constant) +def check_is_function(obj): _util.check_gen(obj, Function) +def check_is_basic_block(obj): _util.check_gen(obj, BasicBlock) +def check_is_module(obj): _util.check_gen(obj, Module) def check_is_module_provider(obj): _util.check_gen(obj, ModuleProvider) def unpack_types(objlst): return _util.unpack_gen(objlst, check_is_type) diff --git a/llvm/ee.py b/llvm/ee.py index 16aef80..6969653 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -38,6 +38,14 @@ import llvm._core as _core # C wrappers import llvm._util as _util # utility functions +#===----------------------------------------------------------------------=== +# Enumerations +#===----------------------------------------------------------------------=== + +BO_BIG_ENDIAN = 0 +BO_LITTLE_ENDIAN = 1 + + #===----------------------------------------------------------------------=== # Target data #===----------------------------------------------------------------------=== @@ -54,6 +62,60 @@ class TargetData(llvm.Ownable): def __str__(self): return _core.LLVMTargetDataAsString(self.ptr) + @property + def byte_order(self): + return _core.LLVMByteOrder(self.ptr) + + @property + def pointer_size(self): + return _core.LLVMPointerSize(self.ptr) + + @property + def target_integer_type(self): + ptr = _core.LLVMIntPtrType(self.ptr); + return core.IntegerType(ptr, core.TYPE_INTEGER) + + def size(self, ty): + core.check_is_type(ty) + return _core.LLVMSizeOfTypeInBits(self.ptr, ty.ptr) + + def store_size(self, ty): + core.check_is_type(ty) + return _core.LLVMStoreSizeOfType(self.ptr, ty.ptr) + + def abi_size(self, ty): + core.check_is_type(ty) + return _core.LLVMABISizeOfType(self.ptr, ty.ptr) + + def abi_alignment(self, ty): + core.check_is_type(ty) + return _core.LLVMABIAlignmentOfType(self.ptr, ty.ptr) + + def callframe_alignment(self, ty): + core.check_is_type(ty) + return _core.LLVMCallFrameAlignmentOfType(self.ptr, ty.ptr) + + def preferred_alignment(self, ty_or_gv): + if isinstance(ty_or_gv, core.Type): + return _core.LLVMPreferredAlignmentOfType(self.ptr, + ty_or_gv.ptr) + elif isinstance(ty_or_gv, core.GlobalVariable): + return _core.LLVMPreferredAlignmentOfGlobal(self.ptr, + ty_or_gv.ptr) + else: + raise core.LLVMException, \ + "argument is neither a type nor a global variable" + + def element_at_offset(self, ty, ofs): + core.check_is_type_struct(ty) + ofs = long(ofs) # ofs is unsigned long long + return _core.LLVMElementAtOffset(self.ptr, ty.ptr, ofs) + + def offset_of_element(self, ty, el): + core.check_is_type_struct(ty) + el = int(el) # el should be an int + return _core.LLVMOffsetOfElement(self.ptr, ty.ptr, el) + #===----------------------------------------------------------------------=== # Generic value diff --git a/llvm/wrap.c b/llvm/wrap.c index fe7db3a..ba2ba5e 100644 --- a/llvm/wrap.c +++ b/llvm/wrap.c @@ -66,6 +66,11 @@ PyObject *ctor_int(int i) return PyInt_FromLong(i); } +PyObject *ctor_llvmwrap_ull(llvmwrap_ull ull) +{ + return PyLong_FromUnsignedLongLong(ull); +} + /*===----------------------------------------------------------------------===*/ /* Helper functions */ diff --git a/llvm/wrap.h b/llvm/wrap.h index 4cc7c51..3b7935e 100644 --- a/llvm/wrap.h +++ b/llvm/wrap.h @@ -47,6 +47,13 @@ #include "llvm-c/Target.h" +/*===----------------------------------------------------------------------===*/ +/* Typedefs */ +/*===----------------------------------------------------------------------===*/ + +typedef unsigned long long llvmwrap_ull; + + /*===----------------------------------------------------------------------===*/ /* Type ctor/dtor */ /*===----------------------------------------------------------------------===*/ @@ -75,7 +82,8 @@ _declare_std_ctor(LLVMTargetDataRef) _declare_std_ctor(LLVMGenericValueRef) /* standard types */ -PyObject *ctor_int(int i); +_declare_std_ctor(int) +_declare_std_ctor(llvmwrap_ull) /*===----------------------------------------------------------------------===*/ @@ -471,6 +479,50 @@ _w ## func (PyObject *self, PyObject *args) \ return ctor_ ## outtype ( func (arg1, arg2, arg3)) ;\ } +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, int arg3) + */ +#define _wrap_objobjint2obj(func, intype1, intype2, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2; \ + intype1 arg1; \ + intype2 arg2; \ + int arg3; \ + \ + if (!PyArg_ParseTuple(args, "OOi", &obj1, &obj2, &arg3)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3)) ;\ +} + +/** + * Wrap LLVM functions of the type + * outtype func(intype1 arg1, intype2 arg2, unsigned long long arg3) + */ +#define _wrap_objobjull2obj(func, intype1, intype2, outtype) \ +static PyObject * \ +_w ## func (PyObject *self, PyObject *args) \ +{ \ + PyObject *obj1, *obj2; \ + intype1 arg1; \ + intype2 arg2; \ + unsigned long long arg3; \ + \ + if (!PyArg_ParseTuple(args, "OOK", &obj1, &obj2, &arg3)) \ + return NULL; \ + \ + arg1 = ( intype1 ) PyCObject_AsVoidPtr(obj1); \ + arg2 = ( intype2 ) PyCObject_AsVoidPtr(obj2); \ + \ + return ctor_ ## outtype ( func (arg1, arg2, arg3)) ;\ +} + /** * Wrap LLVM functions of the type * void func(intype1 arg1, arg2, arg3) diff --git a/test/testall.py b/test/testall.py index 8f95a7e..82a2460 100755 --- a/test/testall.py +++ b/test/testall.py @@ -510,7 +510,23 @@ def do_llvm_core(): def do_targetdata(): print " Testing class TargetData" t = TargetData.new('') - t = str(t) + v = str(t) + v = t.byte_order + v = t.pointer_size + v = t.target_integer_type + ty = Type.int() + v = t.size(ty) + v = t.store_size(ty) + v = t.abi_size(ty) + v = t.abi_alignment(ty) + v = t.callframe_alignment(ty) + v = t.preferred_alignment(ty) + sty = Type.struct([ty, ty]) + v = t.element_at_offset(sty, 0) + v = t.offset_of_element(sty, 0) + m = Module.new('a') + gv = m.add_global_variable(ty, 'gv') + v = t.preferred_alignment(gv) def do_genericvalue():