diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index fb5aaa597..e1452bbb7 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -409,6 +409,7 @@ CPP_TEST_CASES += \ template_default_arg_overloaded \ template_default_arg_overloaded_extend \ template_default_arg_virtual_destructor \ + template_default_cache \ template_default_class_parms \ template_default_class_parms_typedef \ template_default_inherit \ diff --git a/Examples/test-suite/java/template_default_cache_runme.java b/Examples/test-suite/java/template_default_cache_runme.java new file mode 100644 index 000000000..90b584261 --- /dev/null +++ b/Examples/test-suite/java/template_default_cache_runme.java @@ -0,0 +1,18 @@ +import template_default_cache.*; + +public class template_default_cache_runme { + + static { + try { + System.loadLibrary("template_default_cache"); + } 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[]) { + AModelPtr ap = template_default_cache.get_mp_a(); + BModelPtr bp = template_default_cache.get_mp_b(); + } +} diff --git a/Examples/test-suite/python/template_default_cache_runme.py b/Examples/test-suite/python/template_default_cache_runme.py new file mode 100644 index 000000000..ffe155acf --- /dev/null +++ b/Examples/test-suite/python/template_default_cache_runme.py @@ -0,0 +1,9 @@ +import template_default_cache + +ap = template_default_cache.get_mp_a(); +bp = template_default_cache.get_mp_b(); + +if not isinstance(ap, template_default_cache.AModelPtr): + raise RuntimeError("get_mp_a fail") +if not isinstance(bp, template_default_cache.BModelPtr): + raise RuntimeError("get_mp_b fail") diff --git a/Examples/test-suite/template_default_cache.i b/Examples/test-suite/template_default_cache.i new file mode 100644 index 000000000..70bccd595 --- /dev/null +++ b/Examples/test-suite/template_default_cache.i @@ -0,0 +1,35 @@ +%module template_default_cache; + +%inline %{ + namespace d { + template< typename T > class d {}; + } +%} + +%ignore ns_a::iface1::Model; + +%inline %{ +namespace ns_a { + namespace iface1 { + class Model {}; + typedef d::d ModelPtr; + } + using iface1::ModelPtr; +} +%} + +%inline %{ +namespace ns_b { + namespace iface1 { + class Model { + public: + ns_a::ModelPtr foo() { return ns_a::ModelPtr(); }; + }; + typedef d::d ModelPtr; + ns_a::ModelPtr get_mp_a() { return ns_a::ModelPtr(); } + ModelPtr get_mp_b() { return ModelPtr(); } + } + } +%} +%template(AModelPtr) d::d; +%template(BModelPtr) d::d; diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index d72451a14..c548a0670 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -518,7 +518,6 @@ void Swig_symbol_inherit(Symtab *s) { void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) { Node *append = 0; - Node *cn; /* There are a few options for weak symbols. A "weak" symbol is any symbol that can be replaced by another symbol in the C symbol @@ -1907,19 +1906,37 @@ SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) { int len = Len(elements); int i; #ifdef SWIG_TEMPLATE_DEFTYPE_CACHE - static Hash *deftype_cache = 0; - String *scopetype = tscope ? NewStringf("%s::%s", Getattr(tscope, "name"), type) + static Hash *s_cache = 0; + Hash *scope_cache; + /* The lookup depends on the current scope and potential namespace qualification. + Looking up x in namespace y is not the same as looking up x::y in outer scope. + -> we use a 2-level hash: first scope and then symbol. */ + String *scope_name = tscope + ? Swig_symbol_qualifiedscopename(tscope) + : Swig_symbol_qualifiedscopename(current_symtab); + String *type_name = tscope + ? NewStringf("%s::%s", Getattr(tscope, "name"), type) : NewStringf("%s::%s", Swig_symbol_getscopename(), type); - if (!deftype_cache) { - deftype_cache = NewHash(); + if (!scope_name) scope_name = NewString("::"); + if (!s_cache) { + s_cache = NewHash(); } - if (scopetype) { - String *cres = Getattr(deftype_cache, scopetype); + scope_cache = Getattr(s_cache, scope_name); + if (scope_cache) { + String *cres = Getattr(scope_cache, type_name); if (cres) { Append(result, cres); - Delete(scopetype); +#ifdef SWIG_DEBUG + Printf(stderr, "cached deftype %s(%s) -> %s\n", type, scope_name, result); +#endif + Delete(type_name); + Delete(scope_name); return result; } + } else { + scope_cache = NewHash(); + Setattr(s_cache, scope_name, scope_cache); + Delete(scope_name); } #endif @@ -2019,8 +2036,8 @@ SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) { } Delete(elements); #ifdef SWIG_TEMPLATE_DEFTYPE_CACHE - Setattr(deftype_cache, scopetype, result); - Delete(scopetype); + Setattr(scope_cache, type_name, result); + Delete(type_name); #endif return result;