Use wrapper functions for global variables of non-C types

Don't try to export the variables whose type can't be represented in C
directly, this can't work.

Instead, just let use the default implementation to generate wrapper functions
for them.

Update "cpp_basic_global_var_class" unit test accordingly and remove it from
the list of the failing tests.
This commit is contained in:
Vadim Zeitlin 2016-04-19 00:31:12 +02:00
commit c8e4abd16e
3 changed files with 29 additions and 10 deletions

View file

@ -67,7 +67,6 @@ FAILING_CPP_TESTS := \
cpp_basic \ cpp_basic \
cpp_basic_class_var_pub_member_built_in \ cpp_basic_class_var_pub_member_built_in \
cpp_basic_global_var_built_in \ cpp_basic_global_var_built_in \
cpp_basic_global_var_class \
cpp_basic_template_class \ cpp_basic_template_class \
cpp_basic_template_function \ cpp_basic_template_function \
cpp_namespace \ cpp_namespace \

View file

@ -3,7 +3,7 @@
int main(int argc, const char *argv[]) int main(int argc, const char *argv[])
{ {
assert(myGlobalClassInstance); assert(myGlobalClassInstance_get());
return 0; return 0;
} }

View file

@ -447,10 +447,15 @@ public:
* ------------------------------------------------------------------------ */ * ------------------------------------------------------------------------ */
virtual int globalvariableHandler(Node *n) { virtual int globalvariableHandler(Node *n) {
String* const var_decl = make_var_decl(n); // If we can export the variable directly, do it, this will be more convenient to use from C code than accessor functions.
Printv(f_wrappers_decl, "SWIGIMPORT ", var_decl, ";\n\n", NIL); if (String* const var_decl = make_c_var_decl(n)) {
Delete(var_decl); Printv(f_wrappers_decl, "SWIGIMPORT ", var_decl, ";\n\n", NIL);
return SWIG_OK; Delete(var_decl);
return SWIG_OK;
}
// Otherwise, e.g. if it's of a C++-only type, or a reference, generate accessor functions for it.
return Language::globalvariableHandler(n);
} }
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
@ -1264,14 +1269,17 @@ ready:
} }
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
* make_var_decl() * make_c_var_decl()
*
* Return the C declaration for the given node of "variable" kind.
*
* If the variable has a type not representable in C, returns NULL, the caller must check for this!
* *
* Return the declaration for the given node of "variable" kind.
* This function accounts for two special cases: * This function accounts for two special cases:
* 1. If the type is an anonymous enum, "int" is used instead. * 1. If the type is an anonymous enum, "int" is used instead.
* 2. If the type is an array, its bounds are stripped. * 2. If the type is an array, its bounds are stripped.
* --------------------------------------------------------------------- */ * --------------------------------------------------------------------- */
String *make_var_decl(Node *n) { String *make_c_var_decl(Node *n) {
String *name = Getattr(n, "name"); String *name = Getattr(n, "name");
SwigType *type = Getattr(n, "type"); SwigType *type = Getattr(n, "type");
String *type_str = SwigType_str(type, 0); String *type_str = SwigType_str(type, 0);
@ -1294,6 +1302,18 @@ ready:
String* const int_type_str = NewStringf("int%s", unnamed_end + 1); String* const int_type_str = NewStringf("int%s", unnamed_end + 1);
Delete(type_str); Delete(type_str);
type_str = int_type_str; type_str = int_type_str;
} else {
// Don't bother with checking if type is representable in C if we're wrapping C and not C++ anyhow: of course it is.
if (CPlusPlus) {
if (SwigType_isreference(type))
return NIL;
SwigType *btype = SwigType_base(type);
const bool can_be_repr_in_c = SwigType_isbuiltin(btype) || SwigType_isenum(btype);
Delete(btype);
if (!can_be_repr_in_c)
return NIL;
}
} }
String* const var_decl = NewStringEmpty(); String* const var_decl = NewStringEmpty();
@ -1319,7 +1339,7 @@ ready:
for ( ; node; node = nextSibling(node)) { for ( ; node; node = nextSibling(node)) {
String* const ntype = nodeType(node); String* const ntype = nodeType(node);
if (Cmp(ntype, "cdecl") == 0) { if (Cmp(ntype, "cdecl") == 0) {
String* const var_decl = make_var_decl(node); String* const var_decl = make_c_var_decl(node);
Printv(f_wrappers_types, cindent, var_decl, ";\n", NIL); Printv(f_wrappers_types, cindent, var_decl, ";\n", NIL);
Delete(var_decl); Delete(var_decl);
} else if (Cmp(ntype, "enum") == 0) { } else if (Cmp(ntype, "enum") == 0) {