Broken type registration during module loading when compiled with Clang after #161
When libcxxwrap-julia (after #161) or a dependent library is compiled with Clang (tested with clang-14), the core type registration in register_core_types doesn't seem to work. Loading a module gives an error "No appropriate factory for type b" or similar, depending on whichever core type (e.g. bool, double, void, etc.) is used first.
The libcxxwrap-julia tests fail when compiled with clang-14. (I haven't tested other versions of clang, but I confirmed that GCC 10-12 are working/unaffected.) I confirmed by reverting #161 locally that it is responsible for the type registration errors.
Typical stacktrace for libcxxwrap-julia@ca848c7, compiled with clang-14:
gdb julia
catch throw
run -e 'module Parametric using CxxWrap; @wrapmodule(() -> "build/lib/libparametric.so"); __init__() = @initcxx end'
#0 __cxxabiv1::__cxa_throw (obj=0xea3220, tinfo=0x7ffff7651160 <typeinfo for std::runtime_error>, dest=0x7ffff74ce1e0 <std::runtime_error::~runtime_error()>)
at /workspace/srcdir/gcc-13.2.0/libstdc++-v3/libsupc++/eh_throw.cc:80
#1 0x00007fff75763f75 in jlcxx::julia_type_factory<void, jlcxx::NoMappingTrait>::julia_type() () from build/lib/libparametric.so
#2 0x00007fff75763e2d in void jlcxx::create_julia_type<void>() () from build/lib/libparametric.so
#3 0x00007fff75763da6 in void jlcxx::create_if_not_exists<void>() () from build/lib/libparametric.so
#4 0x00007fff75763b7d in std::pair<_jl_datatype_t*, _jl_datatype_t*> jlcxx::julia_return_type<void>() () from build/lib/libparametric.so
#5 0x00007fff75763ad9 in jlcxx::FunctionWrapper<void, parametric::P1*>::FunctionWrapper(jlcxx::Module*, std::function<void (parametric::P1*)> const&) () from build/lib/libparametric.so
#6 0x00007fff75763818 in jlcxx::FunctionWrapperBase& jlcxx::Module::method_helper<void, parametric::P1*>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<void (parametric::P1*)>, jlcxx::detail::ExtraFunctionData&&) () from build/lib/libparametric.so
#7 0x00007fff757634a6 in jlcxx::FunctionWrapperBase& jlcxx::Module::method<void, parametric::P1*>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, void (*)(parametric::P1*)) () from build/lib/libparametric.so
#8 0x00007fff75759617 in void jlcxx::add_default_methods<parametric::P1>(jlcxx::Module&) () from build/lib/libparametric.so
#9 0x00007fff75758aab in jlcxx::TypeWrapper<parametric::P1> jlcxx::Module::add_type_internal<parametric::P1, jlcxx::ParameterList<>, _jl_datatype_t>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, _jl_datatype_t*) () from build/lib/libparametric.so
#10 0x00007fff7575757c in jlcxx::TypeWrapper<parametric::P1> jlcxx::Module::add_type<parametric::P1, jlcxx::ParameterList<>, _jl_datatype_t>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, _jl_datatype_t*) () from build/lib/libparametric.so
#11 0x00007fff75756684 in define_julia_module () from build/lib/libparametric.so
#12 0x00007ffff65cf379 in register_julia_module () from ~/dev/libcxxwrap-julia/build/lib/libcxxwrap_julia.so
Addendum: setting set(CMAKE_CXX_VISIBILITY_PRESET hidden) also triggers this (even when compiling with GCC).
I think you need to define JLCXX_USE_TYPE_MAP in that case. Note that both using a map with std::type_index and using static variables in templated classes are workarounds that rely on well-behaved C++ implementations. The conclusion of #161 is basically that there is no way in general to map a C++ type to something else, which is a bit troublesome for a library like this.
I don't think there's anything more at the level of libcxxwrap-julia that can be done about this.