@@ -315,6 +315,15 @@ std::ostream&
315315CodeTree::generate_cxx_for_type (std::ostream& o,
316316 const TypeRcd& t){
317317
318+ // wrapper implemeted by the user
319+ if (is_custom_type_wrapper (t.type_name )){
320+ if (verbose > 1 ){
321+ std::cerr << " Info. Wrapper for type " << t.type_name
322+ << " is configured as custom. Wrapper code generation skipped.\n " ;
323+ }
324+ return o;
325+ }
326+
318327 // if true, fake type used to hold global functions
319328 bool notype = t.type_name .size () == 0 ;
320329
@@ -595,6 +604,8 @@ CodeTree::generate_cxx(){
595604 o << " #include \" dbg_msg.h\"\n " ;
596605 o << " #include \" Wrapper.h\"\n " ;
597606
607+ o << " \n void end_hook(jlcxx::Module& jlModule) __attribute__((weak));\n " ;
608+
598609 std::vector<std::string> wrappers;
599610
600611 // File stream to write type wrapper,
@@ -700,6 +711,8 @@ CodeTree::generate_cxx(){
700711
701712 indent (o, 1 ) << " for(const auto& w: wrappers) w->add_methods();\n " ;
702713
714+ indent (o, 1 ) << " \n if(end_hook) end_hook(jlModule);\n " ;
715+
703716 o << " \n }\n " ;
704717 o.close ();
705718 otimerstore.settimestamp ();
@@ -2844,30 +2857,6 @@ void CodeTree::preprocess(){
28442857 }// next paramType
28452858 }// next iCombi
28462859
2847-
2848- // Add user defined dependencies
2849- for (const auto & dep: class_order_constraints_){
2850- auto it1 = std::find_if (types_.begin (), types_.end (),
2851- [dep](const auto & x){ return x.type_name == dep.first ;});
2852- auto it2 = std::find_if (types_.begin (), types_.end (),
2853- [dep](const auto & x){ return x.type_name == dep.second ;});
2854-
2855- if (it1 != types_.end () && it2 != types_.end ()){
2856- type_dependencies_.preceeds (it1 - types_.begin (), it2 - types_.begin ());
2857- if (verbose > 1 ) std::cerr << " Dependency \" " << dep.second << " requires " << dep.first
2858- << " \" added.\n " ;
2859- } else {
2860- if (verbose>0 ){
2861- std::cerr << " Warning: class dependency "
2862- << dep.first << " < " << dep.second
2863- << " not used." ;
2864- if (it1 == types_.end ()) std::cerr << " No " << dep.first << " class." ;
2865- if (it2 == types_.end ()) std::cerr << " No " << dep.second << " class." ;
2866- std::cerr << " \n " ;
2867- }
2868- }
2869- }
2870-
28712860#ifdef DEFINE_TEMPLATE_METHODS_IN_CTOR
28722861 // Add dependencies of templated classes to the type of their methods
28732862 // argument and return value.
@@ -2904,6 +2893,32 @@ void CodeTree::preprocess(){
29042893 } // next iChild
29052894#endif
29062895
2896+ // Add user defined dependencies
2897+ for (const auto & dep: class_order_constraints_){
2898+ auto it1 = std::find_if (types_.begin (), types_.end (),
2899+ [dep](const auto & x){ return x.type_name == dep.first ;});
2900+ auto it2 = std::find_if (types_.begin (), types_.end (),
2901+ [dep](const auto & x){ return x.type_name == dep.second ;});
2902+
2903+ if (it1 != types_.end () && it2 != types_.end ()){
2904+ type_dependencies_.preceeds (it1 - types_.begin (), it2 - types_.begin ());
2905+ if (verbose > 1 ) std::cerr << " Dependency \" " << dep.second
2906+ << " ( node " << (it2 - types_.begin ()) << " )"
2907+ << " requires " << dep.first
2908+ << " ( node " << (it1 - types_.begin ()) << " )"
2909+ << " \" added.\n " ;
2910+ } else {
2911+ if (verbose>0 ){
2912+ std::cerr << " Warning: class dependency "
2913+ << dep.first << " < " << dep.second
2914+ << " not used." ;
2915+ if (it1 == types_.end ()) std::cerr << " No " << dep.first << " class." ;
2916+ if (it2 == types_.end ()) std::cerr << " No " << dep.second << " class." ;
2917+ std::cerr << " \n " ;
2918+ }
2919+ }
2920+ }
2921+
29072922 if (verbose > 2 ){
29082923 std::cerr << " \n Type list at end of preprocess:\n " ;
29092924 for (const auto & t: types_){
@@ -2918,8 +2933,10 @@ void CodeTree::preprocess(){
29182933
29192934 if (verbose > 2 ){
29202935 std::cerr << " \n Type list at end of preprocess after reordering:\n " ;
2936+ size_t j = 0 ;
29212937 for (const auto i: types_sorted_indices_){
2922- std::cerr << types_[i].type_name << " \n " ;
2938+ std::cerr << std::setw (4 ) << ++j << " . " << types_[i].type_name
2939+ << " (" << i << " )\n " ;
29232940 }
29242941 std::cerr << " \n " ;
29252942 }
@@ -3160,21 +3177,61 @@ CodeTree::check_veto_list_for_var_or_field(const CXCursor& cursor, bool global_v
31603177 }
31613178}
31623179
3180+
3181+ // FIXME: duplicate for template class
3182+ // strategy to adopt. add an extra_cursors vector to TypeRcd to keep tracks
3183+ // of duplicate and select the cursor with the largest number of visited elements.
3184+ // as main cursor.
31633185int
31643186CodeTree::add_type (const CXCursor& cursor, bool check){
31653187 const int not_found = -1 ;
31663188 int index = not_found;
3189+ bool spelling_duplicate = false ;
3190+ CXCursor dup_cursor;
31673191 if (check){
31683192 int i = 0 ;
31693193 for (const auto & t: types_){
31703194 if (clang_equalCursors (t.cursor , cursor)){
31713195 index = i;
31723196 break ;
31733197 }
3198+ if (str (clang_getCursorSpelling (t.cursor )) == str (clang_getCursorSpelling (cursor))){
3199+ spelling_duplicate = true ;
3200+ dup_cursor = t.cursor ;
3201+ }
31743202 ++i;
31753203 }
31763204 }
31773205 if (index == not_found){
3206+ if (verbose > 0 && spelling_duplicate){
3207+ std::cerr << " Error. Duplicate definition of "
3208+ << clang_getCursorSpelling (cursor)
3209+ << " in the type list. This can lead to "
3210+ << " improper wrapper definition order\n "
3211+ << " first location: " << clang_getCursorLocation (dup_cursor)
3212+ << " \n\t cursor kind: " << clang_getCursorKind (dup_cursor) << " \n "
3213+ << " \n\t declaraion: " << (clang_isDeclaration (dup_cursor.kind ) ? " yes" : " no" ) << " \n "
3214+ << " \n\t FQN: " << fully_qualified_name (dup_cursor) << " \n "
3215+ << " secon location: " << clang_getCursorLocation (cursor)
3216+ << " \n\t cursor kind: " << clang_getCursorKind (cursor) << " \n "
3217+ << " \n\t declaraion: " << (clang_isDeclaration (cursor.kind ) ? " yes" : " no" ) << " \n "
3218+ << " \n\t FQN: " << fully_qualified_name (cursor) << " \n "
3219+ << " \n " ;
3220+
3221+ std::cerr << " First cursor contents:\n " ;
3222+ clang_visitChildren (dup_cursor, [](CXCursor cursor, CXCursor, CXClientData data){
3223+ std::cerr << cursor << " (" << clang_getCursorKind (cursor) << " )\n " ;
3224+ return CXChildVisit_Recurse;
3225+ }, nullptr );
3226+
3227+ std::cerr << " Second cursor contents:\n " ;
3228+ clang_visitChildren (cursor, [](CXCursor cursor, CXCursor, CXClientData data){
3229+ std::cerr << cursor << " (" << clang_getCursorKind (cursor) << " )\n " ;
3230+ return CXChildVisit_Recurse;
3231+ }, nullptr );
3232+
3233+
3234+ }
31783235 index = types_.size ();
31793236 types_.emplace_back (cursor);
31803237 set_type_rcd_ctor_info (types_.back ());
@@ -3715,7 +3772,7 @@ CodeTree::get_methods_to_wrap(const TypeRcd& type_rcd, bool quiet) const{
37153772 << " not wrapped for type " << type_rcd.type_name
37163773 << " , because of an overriding ambiguity in C++. Function "
37173774 " provided by the ancestor classes" ;
3718- for (const auto & cl: m.second ) std::cerr << " , " << cl.first .type_name << " \n " ;
3775+ for (const auto & cl: m.second ) std::cerr << " , " << cl.first .type_name ;
37193776 std::cerr << " .\n " ;
37203777 }
37213778 }
0 commit comments