From b79ebf39fa38e8845c1897be8de4a5cca20d4305 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 12 Dec 2007 19:00:15 +0000 Subject: [PATCH] Fix #1819847 %template with just one default template parameter git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10189 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 6 +++ Examples/test-suite/common.mk | 1 + .../template_default_class_parms_runme.java | 43 +++++++++++++++++++ .../test-suite/template_default_class_parms.i | 33 ++++++++++++++ Source/CParse/parser.y | 11 ++++- Source/CParse/templ.c | 15 +++++-- Source/Swig/swig.h | 2 +- Source/Swig/symbol.c | 17 ++++++-- 8 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 Examples/test-suite/java/template_default_class_parms_runme.java create mode 100644 Examples/test-suite/template_default_class_parms.i diff --git a/CHANGES.current b/CHANGES.current index 39edfb4d2..93f4a17ce 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,12 @@ Version 1.3.34 (in progress) ============================ +12/12/2007: wsfulton + Fix #1819847 %template with just one default template parameter + + template class Foo {...}; + %template(FooDefault) Foo<>; + 12/12/2007: mgossage [Lua] Small correction on Lua.html diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 5bbd98a20..d1d4dfce9 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -264,6 +264,7 @@ CPP_TEST_CASES += \ template_default \ template_default2 \ template_default_arg \ + template_default_class_parms \ template_default_inherit \ template_default_qualify \ template_default_vw \ diff --git a/Examples/test-suite/java/template_default_class_parms_runme.java b/Examples/test-suite/java/template_default_class_parms_runme.java new file mode 100644 index 000000000..4c8010745 --- /dev/null +++ b/Examples/test-suite/java/template_default_class_parms_runme.java @@ -0,0 +1,43 @@ + + +import template_default_class_parms.*; + +public class template_default_class_parms_runme { + + static { + try { + System.loadLibrary("template_default_class_parms"); + } 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[]) { + { + DefaultBar bar = new DefaultBar(20.0, new SomeType(), 10); + double d = bar.getCType(); + SomeType s = bar.getDType(); + int i = bar.getEType(); + d = bar.method(d, s, i); + } + { + DefaultFoo foo = new DefaultFoo(new SomeType()); + SomeType s = foo.getTType(); + s = foo.method(s); + } + { + BarAnotherTypeBool bar = new BarAnotherTypeBool(new AnotherType(), true, 10); + AnotherType a = bar.getCType(); + boolean b = bar.getDType(); + int i = bar.getEType(); + a = bar.method(a, b, i); + } + { + FooAnotherType foo = new FooAnotherType(new AnotherType()); + AnotherType a = foo.getTType(); + a = foo.method(a); + } + } +} + diff --git a/Examples/test-suite/template_default_class_parms.i b/Examples/test-suite/template_default_class_parms.i new file mode 100644 index 000000000..cd37269d3 --- /dev/null +++ b/Examples/test-suite/template_default_class_parms.i @@ -0,0 +1,33 @@ +%module template_default_class_parms + +%inline %{ +namespace Space { + struct SomeType {}; + struct AnotherType {}; + template class Bar { + public: + C CType; + D DType; + E EType; + Bar(C c, D d, E e) {} + C method(C c, D d, E e) { return c; } + }; + template class Foo { + public: + T TType; + Foo(T t) {} + T method(T t) { return t; } + }; + template class ATemplate {}; +} +%} + +// Use defaults +%template(DefaultBar) Space::Bar; +%template(DefaultFoo) Space::Foo<>; + +// Don't use all defaults +%template(BarAnotherTypeBool) Space::Bar; +%template(FooAnotherType) Space::Foo; + +%template() Space::ATemplate<>; diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 67835f162..67cc3224b 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -2537,7 +2537,8 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va This is closer to the C++ (typedef) behavior. */ - n = Swig_cparse_template_locate($5,$7,tscope); + Parm *parms = $7; + n = Swig_cparse_template_locate($5,parms,tscope); /* Patch the argument types to respect namespaces */ p = $7; @@ -2588,7 +2589,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va continue; } else { String *tname = Copy($5); - int def_supplied = 0; + int def_supplied = 0; /* Expand the template */ Node *templ = Swig_symbol_clookup($5,0); Parm *targs = templ ? Getattr(templ,"templateparms") : 0; @@ -2600,6 +2601,12 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va /* Create typedef's and arguments */ p = $7; tp = temparms; + if (!p && ParmList_len(p) != ParmList_len(temparms)) { + /* we have no template parameters supplied in %template for a template that has default args*/ + p = tp; + def_supplied = 1; + } + while (p) { String *value = Getattr(p,"value"); if (def_supplied) { diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index edb6a9736..a1f0c8e08 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -40,7 +40,7 @@ void Swig_cparse_debug_templates(int x) { } /* ----------------------------------------------------------------------------- - * Swig_cparse_template_expand() + * cparse_template_expand() * * Expands a template node into a specialized version. This is done by * patching typenames and other aspects of the node according to a list of @@ -230,6 +230,10 @@ String *partial_arg(String *s, String *p) { return newarg; } +/* ----------------------------------------------------------------------------- + * Swig_cparse_template_expand() + * ----------------------------------------------------------------------------- */ + int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope) { List *patchlist, *cpatchlist, *typelist; String *templateargs; @@ -429,6 +433,7 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { Parm *p; Parm *parms; Parm *targs; + ParmList *expandedparms; tname = Copy(name); parms = CopyParmList(tparms); @@ -441,12 +446,14 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { Symtab *tsdecl = Getattr(templ, "sym:symtab"); targs = Getattr(templ, "templateparms"); - Swig_symbol_template_defargs(parms, targs, tscope, tsdecl); + expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, tsdecl); + } else { + expandedparms = parms; } /* reduce the typedef */ - p = parms; + p = expandedparms; while (p) { SwigType *ty = Getattr(p, "type"); if (ty) { @@ -457,7 +464,7 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { p = nextSibling(p); } - SwigType_add_template(tname, parms); + SwigType_add_template(tname, expandedparms); if (template_debug) { Printf(stdout, "\n%s:%d: template_debug: Searching for %s\n", cparse_file, cparse_line, tname); diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index d073c47bc..a0efb430d 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -222,7 +222,7 @@ extern "C" { extern String *Swig_symbol_string_qualify(String *s, Symtab *tab); extern SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab); - extern void Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl); + extern ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl); extern SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope); extern SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab); diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index 7fac16c3b..99eda204c 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -1669,10 +1669,14 @@ String *Swig_symbol_string_qualify(String *s, Symtab *st) { * Swig_symbol_template_defargs() * * Apply default arg from generic template default args + * Returns a parameter list which contains missing default arguments (if any) + * Note side effects: parms will also contain the extra parameters in its list + * (but only if non-zero). * ----------------------------------------------------------------------------- */ -void Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl) { +ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl) { + ParmList *expandedparms = parms; if (Len(parms) < Len(targs)) { Parm *lp = parms; Parm *p = lp; @@ -1713,7 +1717,10 @@ void Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symt } /* Printf(stderr,"value %s %s %s\n",value,ntr,ntq); */ cp = NewParm(ntq, 0); - set_nextSibling(lp, cp); + if (lp) + set_nextSibling(lp, cp); + else + expandedparms = CopyParm(cp); lp = cp; tp = nextSibling(tp); Delete(cp); @@ -1724,6 +1731,7 @@ void Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symt } } } + return expandedparms; } /* ----------------------------------------------------------------------------- @@ -1795,6 +1803,7 @@ SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) { #endif if (tempn) { ParmList *tnargs = Getattr(tempn, "templateparms"); + ParmList *expandedparms; Parm *p; Symtab *tsdecl = Getattr(tempn, "sym:symtab"); @@ -1802,8 +1811,8 @@ SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) { Printf(stderr, "deftype type %s %s %s\n", tprefix, targs, tsuffix); #endif Append(tprefix, "<("); - Swig_symbol_template_defargs(tparms, tnargs, tscope, tsdecl); - p = tparms; + expandedparms = Swig_symbol_template_defargs(tparms, tnargs, tscope, tsdecl); + p = expandedparms; tscope = tsdecl; while (p) { SwigType *ptype = Getattr(p, "type");