diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2019-02-25 19:27:23 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2019-02-25 19:27:23 +0000 |
commit | 83ea2280e2e99ecafa2e3d2e041548a2f02aa19b (patch) | |
tree | beb8299ad7375920859dd4c444f35ff919e50d9b /Source/Modules | |
parent | 613ff08150e6264a5a4a964f2badeb6bba221398 (diff) | |
download | swig-83ea2280e2e99ecafa2e3d2e041548a2f02aa19b.tar.gz |
Fix Python compile errors with overloading and varargs
Fixes wrapping overloaded functions/constructors where a vararg
function is declared after a non-vararg function.
This is a long standing bug in the Python layer exposed since fastunpack
was turned on by default.
Diffstat (limited to 'Source/Modules')
-rw-r--r-- | Source/Modules/emit.cxx | 27 | ||||
-rwxr-xr-x | Source/Modules/python.cxx | 20 | ||||
-rw-r--r-- | Source/Modules/swigmod.h | 3 |
3 files changed, 30 insertions, 20 deletions
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx index 43f87db6f..7a4c2dcfb 100644 --- a/Source/Modules/emit.cxx +++ b/Source/Modules/emit.cxx @@ -188,7 +188,9 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) { p = lp; while (p) { if (SwigType_isvarargs(Getattr(p, "type"))) { + // Mark the head of the ParmList that it has varargs Setattr(l, "emit:varargs", lp); +//Printf(stdout, "setting emit:varargs %s ... %s +++ %s\n", Getattr(l, "emit:varargs"), Getattr(l, "type"), Getattr(p, "type")); break; } p = nextSibling(p); @@ -329,7 +331,8 @@ int emit_num_required(ParmList *parms) { /* ----------------------------------------------------------------------------- * emit_isvarargs() * - * Checks if a function is a varargs function + * Checks if a ParmList is a parameter list containing varargs. + * This function requires emit_attach_parmmaps to have been called beforehand. * ----------------------------------------------------------------------------- */ int emit_isvarargs(ParmList *p) { @@ -341,6 +344,28 @@ int emit_isvarargs(ParmList *p) { } /* ----------------------------------------------------------------------------- + * emit_isvarargs_function() + * + * Checks for varargs in a function/constructor (can be overloaded) + * ----------------------------------------------------------------------------- */ + +bool emit_isvarargs_function(Node *n) { + bool has_varargs = false; + Node *over = Getattr(n, "sym:overloaded"); + if (over) { + for (Node *sibling = over; sibling; sibling = Getattr(sibling, "sym:nextSibling")) { + if (ParmList_has_varargs(Getattr(sibling, "parms"))) { + has_varargs = true; + break; + } + } + } else { + has_varargs = ParmList_has_varargs(Getattr(n, "parms")) ? true : false; + } + return has_varargs; +} + +/* ----------------------------------------------------------------------------- * void emit_mark_vararg_parms() * * Marks the vararg parameters which are to be ignored. diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 3c1767d6f..9ffc00592 100755 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -2187,7 +2187,7 @@ public: * is_real_overloaded() * * Check if the function is overloaded, but not just have some - * siblings generated due to the original function have + * siblings generated due to the original function having * default arguments. * ------------------------------------------------------------ */ bool is_real_overloaded(Node *n) { @@ -2689,7 +2689,6 @@ public: bool add_self = builtin_self && (!builtin_ctor || director_class); bool builtin_getter = (builtin && GetFlag(n, "memberget")); bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter); - bool over_varargs = false; char const *self_param = builtin ? "self" : "SWIGUNUSEDPARM(self)"; char const *wrap_return = builtin_ctor ? "int " : "PyObject *"; String *linkage = NewString("SWIGINTERN "); @@ -2765,22 +2764,7 @@ public: } } - if (overname) { - String *over_varargs_attr = Getattr(n, "python:overvarargs"); - if (!over_varargs_attr) { - for (Node *sibling = n; sibling; sibling = Getattr(sibling, "sym:nextSibling")) { - if (emit_isvarargs(Getattr(sibling, "parms"))) { - over_varargs = true; - break; - } - } - over_varargs_attr = NewString(over_varargs ? "1" : "0"); - for (Node *sibling = n; sibling; sibling = Getattr(sibling, "sym:nextSibling")) - Setattr(sibling, "python:overvarargs", over_varargs_attr); - } - if (Strcmp(over_varargs_attr, "0") != 0) - over_varargs = true; - } + bool over_varargs = emit_isvarargs_function(n); int funpack = fastunpack && !varargs && !over_varargs && !allow_kwargs; int noargs = funpack && (tuple_required == 0 && tuple_arguments == 0); diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index ef49c5684..583cb13fe 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -383,7 +383,8 @@ List *SWIG_output_files(); void SWIG_library_directory(const char *); int emit_num_arguments(ParmList *); int emit_num_required(ParmList *); -int emit_isvarargs(ParmList *); +int emit_isvarargs(ParmList *p); +bool emit_isvarargs_function(Node *n); void emit_attach_parmmaps(ParmList *, Wrapper *f); void emit_mark_varargs(ParmList *l); String *emit_action(Node *n); |