My project has a C ++ library that I want to allow the user to use with some programming language so that JIT'd call functions in the specified library. For simplicity, suppose the library has classes such as:
class item { public: item(); item( int ); ~item(); // ... }; class item_iterator { public: virtual ~item_iterator(); virtual bool next( item *result ) = 0; }; class singleton_iterator : public item_iterator { public: singleton_iterator( item const &i ); // ... };
I know that LLVM knows nothing about C ++ and that one way to call C ++ functions is to wrap them in C thunks:
extern "C" { void thunk_item_M_new( item *addr ) { new( addr ) item; } void thunk_singleton_iterator_M_new( singleton_iterator *addr, item *i ) { new( addr ) singleton_iterator( *i ); } bool thunk_iterator_M_next( item_iterator *that, item *result ) { return that->next( result ); } }
The first problem is how to extract item from LLVM. I know how to create StructType and add fields to them, but I donβt want the parallel layout of the C ++ class to be tedious and error-prone.
The idea I got is to simply add char[sizeof(T)] as the only field for StructType for a C ++ class type:
StructType *const llvm_item_type = StructType::create( llvm_ctx, "item" ); vector<Type*> llvm_struct_types; llvm_struct_types.push_back( ArrayType::get( IntegerType::get( llvm_ctx, 8 ), sizeof( item ) ) ); llvm_item_type->setBody( llvm_struct_types, false ); PointerType *const llvm_item_ptr_type = PointerType::getUnqual( llvm_item_type );
I would think that since this is a StructType , alignment would be correct, and sizeof(item) would get the correct size. Will this work? Is there a better way?
The second problem is that, unlike the C ++ class hierarchy, there is no inheritance relationship between StructType s. If I create a Function that accepts llvm_iterator_type but tries to build a Function object using llvm_singleton_iterator_type , the LLVM verifyModule() function complains about me:
The call parameter type does not match the function signature!
So, I thought I was just using void* everywhere:
Type *const llvm_void_type = Type::getVoidTy( llvm_ctx ); PointerType *const llvm_void_ptr_type = PointerType::getUnqual( llvm_void_type );
but verifyModule() is still complaining about me because there seems to be no automatic casting to void* types in LLVM. How can I solve this problem?