diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 37ed70dd2..888464b5f 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -473,6 +473,7 @@ CPP_TEST_CASES += \ template_namespace_forward_declaration \ template_using_directive_and_declaration_forward \ template_using_directive_typedef \ + template_using_member_default_arg \ template_nested \ template_nested_flat \ template_nested_typemaps \ diff --git a/Examples/test-suite/java/template_using_member_default_arg_runme.java b/Examples/test-suite/java/template_using_member_default_arg_runme.java new file mode 100644 index 000000000..5939158ad --- /dev/null +++ b/Examples/test-suite/java/template_using_member_default_arg_runme.java @@ -0,0 +1,22 @@ +import template_using_member_default_arg.*; + +public class template_using_member_default_arg_runme { + + static { + try { + System.loadLibrary("template_using_member_default_arg"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + ThingADerivedInt a = new ThingADerivedInt(); + a.describeA(); + ThingBDerivedInt b = new ThingBDerivedInt(); + b.describeB(); + } +} + + diff --git a/Examples/test-suite/python/template_using_member_default_arg_runme.py b/Examples/test-suite/python/template_using_member_default_arg_runme.py new file mode 100644 index 000000000..432306a8a --- /dev/null +++ b/Examples/test-suite/python/template_using_member_default_arg_runme.py @@ -0,0 +1,6 @@ +from template_using_member_default_arg import * + +a = ThingADerivedInt() +a.describeA() +b = ThingBDerivedInt() +b.describeB() diff --git a/Examples/test-suite/template_using_member_default_arg.i b/Examples/test-suite/template_using_member_default_arg.i new file mode 100644 index 000000000..117abd0ee --- /dev/null +++ b/Examples/test-suite/template_using_member_default_arg.i @@ -0,0 +1,33 @@ +%module template_using_member_default_arg + +%inline %{ +template +struct ThingA { + ThingA() {} +protected: + void describeA() {} +}; +template +struct ThingB { + ThingB() {} +protected: + void describeB() {} +}; +%} + +%inline %{ +template +struct ThingADerived : ThingA { + using ThingA::describeA; +}; +template +struct ThingBDerived : ThingB { + using ThingB::describeB; +}; +%} + +%template(ThingAInt) ThingA; // was okay +%template(ThingADerivedInt) ThingADerived; + +%template(ThingBInt) ThingB; // was failing - using directive in this template was not found +%template(ThingBDerivedInt) ThingBDerived; diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index 8e24c9ec7..e44585f6f 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -553,6 +553,12 @@ void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) { String *cname = NewString(name); String *dname = Swig_symbol_template_deftype(cname, 0); if (!Equal(dname, name)) { + /* Add another symbol with all template default arguments expanded, eg + * + * template struct X {}; + * %template(XInt) X; + * + * then name=X, and dname=X so add X here too. */ Swig_symbol_cadd(dname, n); } Delete(dname); @@ -1589,6 +1595,10 @@ static int symbol_no_constructor(Node *n) { return !Checkattr(n, "nodeType", "constructor"); } +static int symbol_is_template(Node *n) { + return Checkattr(n, "nodeType", "template"); +} + /* ----------------------------------------------------------------------------- * Swig_symbol_type_qualify() * @@ -1944,6 +1954,7 @@ ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, * Swig_symbol_template_deftype() * * Apply default args to generic template type + * Return input type with template args expanded to include default template args * ----------------------------------------------------------------------------- */ #define SWIG_TEMPLATE_DEFTYPE_CACHE @@ -2018,9 +2029,9 @@ SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) { String *targs = SwigType_templateargs(base); String *tsuffix = SwigType_templatesuffix(base); ParmList *tparms = SwigType_function_parms(targs, 0); - Node *tempn = Swig_symbol_clookup_local(tprefix, tscope); + Node *tempn = Swig_symbol_clookup_local_check(tprefix, tscope, symbol_is_template); if (!tempn && tsuffix && Len(tsuffix)) { - tempn = Swig_symbol_clookup(tprefix, 0); + tempn = Swig_symbol_clookup_check(tprefix, 0, symbol_is_template); } #ifdef SWIG_DEBUG Printf(stderr, "deftype type %s %s %d\n", e, tprefix, (long) tempn);