From 0801df41dc079608df5c66fc02ad29ce926ab178 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Mon, 26 Aug 2013 12:18:04 -0500 Subject: [PATCH] fix upcasting problem (#77 thanks to cantora) --- llvmpy/gen/binding.py | 2 +- llvmpy/gen/codegen.py | 3 ++- llvmpy/include/llvm_binding/conversion.h | 30 ++++++++++++++++++++---- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/llvmpy/gen/binding.py b/llvmpy/gen/binding.py index db4fdbf..30e1614 100644 --- a/llvmpy/gen/binding.py +++ b/llvmpy/gen/binding.py @@ -333,7 +333,7 @@ class Class(SubModule, _Type): writer.die_if_false(raw, verbose=name) ptrty = ptr(self).fullname ty = self.fullname - fmt = 'typecast< %(ty)s >::from(%(raw)s)' + fmt = 'unwrap_as<%(ty)s, %(name)s >::from(%(raw)s)' casted = writer.declare(ptrty, fmt % locals()) writer.die_if_false(casted) return casted diff --git a/llvmpy/gen/codegen.py b/llvmpy/gen/codegen.py index f9585fd..6e36683 100644 --- a/llvmpy/gen/codegen.py +++ b/llvmpy/gen/codegen.py @@ -202,7 +202,8 @@ class CppCodeWriter(CodeWriterBase): def pycapsule_new(self, ptr, name, clsname): name_soften = mangle(name) - ret = self.call('pycapsule_new', 'PyObject*', ptr, quote(name), + cast_to_base = 'cast_to_base<%s >::from(%s)' % (name, ptr) + ret = self.call('pycapsule_new', 'PyObject*', cast_to_base, quote(name), quote(clsname)) with self.block('if (!%(ret)s)' % locals()): self.return_null() diff --git a/llvmpy/include/llvm_binding/conversion.h b/llvmpy/include/llvm_binding/conversion.h index a9f073c..10f6286 100644 --- a/llvmpy/include/llvm_binding/conversion.h +++ b/llvmpy/include/llvm_binding/conversion.h @@ -254,10 +254,11 @@ PyObject* py_float_from(const double& val) { // casting template struct typecast { - template static - Td* from(Ts* src) { - return llvm::dyn_cast(src); - } +// Unused +// template static +// Td* from(Ts* src) { +// return llvm::dyn_cast(src); +// } static Td* from(void* src) { @@ -265,3 +266,24 @@ struct typecast { } }; +template +struct unwrap_as { + static + Td* from(void* src) { + Tbase* base = static_cast(src); + return static_cast(base); + } +}; + +template +struct cast_to_base { + template static + Td* from(Ts* src){ + return static_cast(src); + } + + template static + const Td* from(const Ts* src){ + return static_cast(src); + } +};