Skip to content

Commit ff729f8

Browse files
committed
Propagate argument names to julia and more.
- argument names: if code is generated for CxxWrap release 0.15.0 or above, then the method argument names are passed to their julia wrapper with the `jlcxx::argname` featured added with this release. - Add suppport to enable verbose import at runtime by defining the WRAPIT_VERBOSE_INPUT environment variable, which as the same effect as the VERBOSE_INPUT compilation option. - New class_order_contraints configuration parameter to allow tuning of type wrapper declaration order
1 parent da13302 commit ff729f8

File tree

10 files changed

+230
-49
lines changed

10 files changed

+230
-49
lines changed

doc/FAQ.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,17 @@ Clang options:
7979

8080
## Issue when using code generated by wrapit.
8181

82-
### C++ exception while wrapping module <module_name>: No appropriate factory for type <mangled_name>.
82+
### Exception "No appropriate factory for type <mangled_name>".
8383

84-
First, used `c++filt -t <mangled_name>` to get the name of the problematic type. Beware of not being misled by mangled_name that looks like a plain name, always demangle it.
84+
First, use `c++filt -t <mangled_name>` to get the name of the problematic type `T`. Beware of not being misled by mangled_name that looks like a plain name, always demangle it. If the exception occurs when importing the Julia module, see the question "I get an exception when loading the Julia module. How can I find the guilty code?" to find the wrapper declaration that is causing the exception.
85+
86+
The exception indicates that the wrapper for `T` must be declared (with the `add_type()` function) before the declaration triggering the exception. There two options, the wrapper is not declared or is declared too late. You can check order of type declaration in the generation file name jl<module_name>.cxx: the wrapport of type `<type_name>` is declared with a call `newJl<type_name>(jlModule)`.
87+
88+
The order of wrapper declaration lines can be tuned using the `class_order_constraints` configuration parameter. If the wrapper is not declared at all, check the `wrapit` logs to find the reason. If the file, where the type is declared is not included in the configuration, you can try to add it in the `input` or `extra_headers` list.
8589

8690
### I get an exception when loading the Julia module. How can I find the guilty code?
8791

88-
For wrapit release 1.1.x or less, compile the code with the VERBOSE_IMPORT macro defined (`-DVERBOSE_IMPORT` compiler flag). For newer release, it is sufficient to define the `VERBOSE_IMPORT` environment variable.
92+
For wrapit release 1.1.x or less, compile the code with the VERBOSE_IMPORT macro defined (`-DVERBOSE_IMPORT` compiler flag). For newer release, it is sufficient to define the `WRAPIT_VERBOSE_IMPORT` environment variable.
8993

9094
### What the `Warning: specialization found at `X` for class/struct `Y` before its definition.` message mean?
9195

doc/config.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ The configuration file uses the [toml](https://toml.io) syntax.
44

55
The list of parameters with their defaut value is provided below.
66

7-
87
### Main parameters
98

109
```
@@ -113,6 +112,15 @@ fields_and_variables = true
113112
#
114113
inheritances = [ "" ]
115114
115+
# Explicit constraints on the class wrapper declaration order.
116+
# A constraint is a string with format class_name_1 < class_name_2. It results
117+
# in having the wrappert of class_name_1 declared before the one of class_name_2.
118+
#
119+
# This parameter can be used to fix a bad wrapper declaration order resulting
120+
# from a Wrapit limitation. See the FAQ ""
121+
#
122+
class_order_constraints = [ "" ]
123+
116124
# List of customized C++-to-Julia name mapping. Each element of the list must
117125
# be a string with format <C++ fully qualified name> -> <julia name>.
118126
#

examples/ex002-ROOT/ROOT.wit

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ veto_list = "jlROOT-veto.h"
1616

1717
fields_and_variables = false
1818

19-
# Currently not working with CxxWrap 0.15.0, use 0.14.x
20-
cxxwrap_version = "0.14"
19+
# Currently not working with CxxWrap 0.15.0, use 0.14.x or 0.16+
20+
cxxwrap_version = "0.17"
2121

2222
#auto_veto = false
2323

src/CodeTree.cpp

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ CodeTree::generate_template_add_type_cxx(std::ostream& o,
308308
#ifdef DEFINE_TEMPLATE_METHODS_IN_CTOR
309309
if(type_rcd.default_ctor){
310310
FunctionWrapper::gen_ctor(o, 2, "t", type_rcd.template_parameters.empty(),
311-
type_rcd.finalize, std::string(),
311+
type_rcd.finalize, std::string(), std::string(),
312312
cxxwrap_version_);
313313
}
314314
#endif
@@ -449,7 +449,7 @@ CodeTree::generate_cxx_for_type(std::ostream& o,
449449
//Generate a wrapper for the implicit default ctor if needed
450450
if(t.default_ctor){
451451
FunctionWrapper::gen_ctor(o, 2, "t", t.template_parameters.empty(),
452-
t.finalize, std::string(),
452+
t.finalize, std::string(), std::string(),
453453
cxxwrap_version_);
454454
}
455455
}
@@ -722,7 +722,7 @@ CodeTree::generate_cxx(){
722722
o2 << "#ifdef VERBOSE_IMPORT\n"
723723
"# define DEBUG_MSG(a) std::cerr << a << \"\\n\"\n"
724724
"#else\n"
725-
"# define DEBUG_MSG(a)\n"
725+
"# define DEBUG_MSG(a) if(getenv(\"WRAPIT_VERBOSE_IMPORT\")) std::cerr << a << \"\\n\"\n"
726726
"#endif\n"
727727
"#define __HERE__ __FILE__ \":\" QUOTE2(__LINE__)\n"
728728
"#define QUOTE(arg) #arg\n"
@@ -1100,7 +1100,8 @@ CodeTree::generate_methods_of_templated_type_cxx(std::ostream& o,
11001100
// wrapped.constructor<>();
11011101
if(t.default_ctor){
11021102
FunctionWrapper::gen_ctor(o, 3, "wrapped", /*templated=*/true,
1103-
t.finalize, std::string(), cxxwrap_version_);
1103+
t.finalize, std::string(), std::string(),
1104+
cxxwrap_version_);
11041105
}
11051106

11061107
// wrapped.method("get_first", [](const T& a) -> T1 { return a.get_first(); });
@@ -2674,6 +2675,30 @@ void CodeTree::preprocess(){
26742675
}//next paramType
26752676
}//next iCombi
26762677

2678+
2679+
//Add user defined dependencies
2680+
for(const auto& dep: class_order_constraints_){
2681+
auto it1 = std::find_if(types_.begin(), types_.end(),
2682+
[dep](const auto& x){ return x.type_name == dep.first;});
2683+
auto it2 = std::find_if(types_.begin(), types_.end(),
2684+
[dep](const auto& x){ return x.type_name == dep.second;});
2685+
2686+
if(it1 != types_.end() && it2 != types_.end()){
2687+
type_dependencies_.preceeds(it1 - types_.begin(), it2 - types_.begin());
2688+
if(verbose > 1) std::cerr << "Dependency \"" << dep.second << " requires " << dep.first
2689+
<< "\" added.\n";
2690+
} else{
2691+
if(verbose>0){
2692+
std::cerr << "Warning: class dependency "
2693+
<< dep.first << " < " << dep.second
2694+
<< " not used.";
2695+
if(it1 == types_.end()) std::cerr << " No " << dep.first << " class.";
2696+
if(it2 == types_.end()) std::cerr << " No " << dep.second << " class.";
2697+
std::cerr << "\n";
2698+
}
2699+
}
2700+
}
2701+
26772702
#ifdef DEFINE_TEMPLATE_METHODS_IN_CTOR
26782703
//Add dependencies of templated classes to the type of their methods
26792704
//argument and return value.
@@ -3160,24 +3185,54 @@ void CodeTree::generate_project_file(std::ostream& o,
31603185

31613186
void CodeTree::set_julia_names(const std::vector<std::string>& name_map){
31623187
cxx_to_julia_.clear();
3163-
std::regex re("\\s*->\\s");
3188+
std::regex re("\\s*->\\s*");
3189+
int i = 0;
31643190
for(const std::string& m: name_map){
3191+
++i;
31653192
std::sregex_token_iterator it{m.begin(), m.end(), re, -1};
31663193
std::vector<std::string> tokens{it, {}};
31673194
if(tokens.size() > 1){
31683195
cxx_to_julia_[tokens[0]] = tokens[1];
3196+
} else{
3197+
std::cerr << "ERROR. Syntax error for the " << nth(i) << " element "
3198+
<< m
3199+
<< " of julia_names parameter.\n";
3200+
}
3201+
}
3202+
}
3203+
3204+
void CodeTree::set_class_order_constraints(const std::vector<std::string>& class_order_constraints){
3205+
class_order_constraints_.clear();
3206+
std::regex re("\\s*<\\s*");
3207+
int i = 0;
3208+
for(const std::string& m: class_order_constraints){
3209+
++i;
3210+
std::sregex_token_iterator it{m.begin(), m.end(), re, -1};
3211+
std::vector<std::string> tokens{it, {}};
3212+
if(tokens.size() > 1){
3213+
class_order_constraints_.push_back(std::make_pair(tokens[0], tokens[1]));
3214+
} else{
3215+
std::cerr << "ERROR. Syntax error for the " << nth(i) << " element "
3216+
<< m
3217+
<< " of class_dependencies configuration parameter.\n";
31693218
}
31703219
}
31713220
}
31723221

31733222
void CodeTree::set_mapped_types(const std::vector<std::string>& name_map){
31743223
type_straight_mapping_.clear();
3175-
std::regex re("\\s*->\\s");
3224+
std::regex re("\\s*->\\s*");
3225+
int i = 0;
31763226
for(const std::string& m: name_map){
3227+
++i;
31773228
std::sregex_token_iterator it{m.begin(), m.end(), re, -1};
31783229
std::vector<std::string> tokens{it, {}};
31793230
if(tokens.size() > 1){
31803231
type_straight_mapping_[tokens[0]] = tokens[1];
3232+
} else{
3233+
std::cerr << "ERROR. Syntax error for the " << nth(i) << " element "
3234+
<< m
3235+
<< " of mapped_types configuration parameter.\n";
31813236
}
31823237
}
31833238
}

src/CodeTree.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ namespace codetree{
284284
void set_force_mode(bool forced){ out_open_mode_ = forced ? std::ios_base::out : std::ios_base::app; }
285285

286286
void set_julia_names(const std::vector<std::string>& name_map);
287+
288+
void set_class_order_constraints(const std::vector<std::string>& class_order_constraints);
287289

288290
void set_mapped_types(const std::vector<std::string>& name_map);
289291

@@ -320,7 +322,6 @@ namespace codetree{
320322

321323
bool add_type_specialization(TypeRcd* pTypeRcd, const CXType& type);
322324

323-
324325
bool check_resource_dir(bool verbose) const;
325326

326327
//Finds the definition of a type or the underlying type in case
@@ -546,6 +547,8 @@ namespace codetree{
546547

547548
Graph type_dependencies_;
548549

550+
std::vector<std::pair<std::string, std::string>> class_order_constraints_;
551+
549552
std::vector<std::string> towrap_type_filenames_;
550553
std::set<std::string> towrap_type_filenames_set_;
551554

0 commit comments

Comments
 (0)