Don't generate C++ wrappers for functions using unsupported types

This is far from ideal, but better than generating uncompilable code in
this case.
This commit is contained in:
Vadim Zeitlin 2021-12-07 16:19:56 +01:00
commit a2bd9eec05

View file

@ -493,7 +493,8 @@ struct cxx_wrappers
} }
rtype_desc.set_type(type); rtype_desc.set_type(type);
do_resolve_type(n, func_type, rtype_desc.type(), NULL, &rtype_desc); if (!do_resolve_type(n, func_type, rtype_desc.type(), NULL, &rtype_desc))
return false;
if (use_cxxout) { if (use_cxxout) {
if (String* out_tm = Swig_typemap_lookup("cxxout", n, "", NULL)) if (String* out_tm = Swig_typemap_lookup("cxxout", n, "", NULL))
@ -525,7 +526,8 @@ struct cxx_wrappers
} }
ptype_desc.set_type(type); ptype_desc.set_type(type);
do_resolve_type(n, Getattr(p, "type"), ptype_desc.type(), &ptype_desc, NULL); if (!do_resolve_type(n, Getattr(p, "type"), ptype_desc.type(), &ptype_desc, NULL))
return false;
if (use_cxxin) { if (use_cxxin) {
if (String* in_tm = Getattr(p, "tmap:cxxin")) if (String* in_tm = Getattr(p, "tmap:cxxin"))
@ -552,7 +554,8 @@ struct cxx_wrappers
if (rtype_desc_) if (rtype_desc_)
rtype_desc_->set_type(type); rtype_desc_->set_type(type);
do_resolve_type(node_func_, type, tm, ptype_desc_, rtype_desc_); if (!do_resolve_type(node_func_, type, tm, ptype_desc_, rtype_desc_))
return false;
} }
return true; return true;
@ -589,7 +592,7 @@ private:
// //
// Also fills in the start/end wrapper parts of the provided type descriptions if they're not null, with the casts needed to translate from C type to C++ type // Also fills in the start/end wrapper parts of the provided type descriptions if they're not null, with the casts needed to translate from C type to C++ type
// (this is used for the parameters of C++ functions, hence the name) and from C types to C++ types (which is used for the function return values). // (this is used for the parameters of C++ functions, hence the name) and from C types to C++ types (which is used for the function return values).
static void do_resolve_type(Node* n, String* type, String* s, cxx_ptype_desc* ptype_desc, cxx_rtype_desc* rtype_desc) { static bool do_resolve_type(Node* n, String* type, String* s, cxx_ptype_desc* ptype_desc, cxx_rtype_desc* rtype_desc) {
enum TypeKind enum TypeKind
{ {
Type_Ptr, Type_Ptr,
@ -620,9 +623,11 @@ private:
"Unsupported typemap \"%s\" used for type \"%s\" of \"%s\"\n", "Unsupported typemap \"%s\" used for type \"%s\" of \"%s\"\n",
s, type, Getattr(n, "name") s, type, Getattr(n, "name")
); );
return false;
} }
return; return true;
} }
// The logic here is somewhat messy because we use the same "$resolved_type*" typemap for pointers/references to both enums and classes, but we actually // The logic here is somewhat messy because we use the same "$resolved_type*" typemap for pointers/references to both enums and classes, but we actually
@ -721,11 +726,17 @@ private:
Replaceall(typestr, basetypestr, classname); Replaceall(typestr, basetypestr, classname);
} }
} else { } else {
// This is something unknown, so just use an opaque typedef already declared in C wrappers section for it.
typestr = NewStringf("SWIGTYPE%s*", SwigType_manglestr(stripped_type));
classname = NULL; classname = NULL;
} }
if (!classname) {
Swig_warning(WARN_C_UNSUPPORTTED, input_file, line_number,
"Unsupported C++ wrapper function %s type \"%s\"\n",
ptype_desc ? "parameter" : "return", SwigType_str(type, 0)
);
return false;
}
const char* const owns = GetFlag(n, "feature:new") ? "true" : "false"; const char* const owns = GetFlag(n, "feature:new") ? "true" : "false";
switch (typeKind) { switch (typeKind) {
case Type_Ptr: case Type_Ptr:
@ -734,27 +745,20 @@ private:
} }
if (rtype_desc) { if (rtype_desc) {
if (classname) {
rtype_desc->apply_out_typemap(NewStringf( rtype_desc->apply_out_typemap(NewStringf(
"$cresult ? new %s($cresult, %s) : nullptr;", "$cresult ? new %s($cresult, %s) : nullptr;",
classname, owns classname, owns
)); ));
} }
}
break; break;
case Type_Ref: case Type_Ref:
if (rtype_desc) { if (rtype_desc) {
if (classname) {
// We can't return a reference, as this requires an existing object and we don't have any, so we have to return an object instead, and this object // We can't return a reference, as this requires an existing object and we don't have any, so we have to return an object instead, and this object
// must be constructed using the special ctor not taking the pointer ownership. // must be constructed using the special ctor not taking the pointer ownership.
typestr = Copy(classname); typestr = Copy(classname);
rtype_desc->apply_out_typemap(NewStringf("%s{$cresult, false}", classname)); rtype_desc->apply_out_typemap(NewStringf("%s{$cresult, false}", classname));
} else {
// We can't do anything at all in this case.
Swig_error(input_file, line_number, "Unknown reference return type \"%s\"\n", typestr.get());
}
} }
if (ptype_desc) { if (ptype_desc) {
@ -764,7 +768,6 @@ private:
case Type_Obj: case Type_Obj:
if (rtype_desc) { if (rtype_desc) {
if (classname) {
// The pointer returned by C function wrapping a function returning an object should never be null unless an exception happened, so we don't test // The pointer returned by C function wrapping a function returning an object should never be null unless an exception happened, so we don't test
// for it here, unlike in Type_Ptr case. // for it here, unlike in Type_Ptr case.
// //
@ -777,9 +780,6 @@ private:
typestr.get(), typestr.get(),
SwigType_isreference(Getattr(n, "type")) ? owns : "true" SwigType_isreference(Getattr(n, "type")) ? owns : "true"
)); ));
} else {
Swig_error(input_file, line_number, "Unknown object return type \"%s\"\n", typestr.get());
}
} }
if (ptype_desc) { if (ptype_desc) {
@ -799,6 +799,8 @@ private:
} }
Replaceall(s, typemaps[typeKind], typestr); Replaceall(s, typemaps[typeKind], typestr);
return true;
} }