diff --git a/Examples/test-suite/python/template_rename_runme.py b/Examples/test-suite/python/template_rename_runme.py index 1fd45ba03..4f0e7e83e 100644 --- a/Examples/test-suite/python/template_rename_runme.py +++ b/Examples/test-suite/python/template_rename_runme.py @@ -5,7 +5,7 @@ d = template_rename.dFoo() a = i.blah_test(4) b = i.spam_test(5) -c = i.grok_test(6) +c = i.groki_test(6) x = d.blah_test(7) y = d.spam(8) diff --git a/Examples/test-suite/ruby/template_rename_runme.rb b/Examples/test-suite/ruby/template_rename_runme.rb index 04be6c94d..a45a8ff0e 100755 --- a/Examples/test-suite/ruby/template_rename_runme.rb +++ b/Examples/test-suite/ruby/template_rename_runme.rb @@ -5,7 +5,7 @@ d = Template_rename::DFoo.new a = i.blah_test(4) b = i.spam_test(5) -c = i.grok_test(6) +c = i.groki_test(6) x = d.blah_test(7) y = d.spam(8) diff --git a/Examples/test-suite/template_rename.i b/Examples/test-suite/template_rename.i index f76f103af..13a9ede18 100644 --- a/Examples/test-suite/template_rename.i +++ b/Examples/test-suite/template_rename.i @@ -22,3 +22,28 @@ public: %template(iFoo) Foo; %template(dFoo) Foo; + +// Testing ignore + +%ignore std::vector::vector(size_type); + +%inline %{ + +namespace std { + + template class vector { + public: + typedef size_t size_type; + vector() {} + vector(size_type n) { T t = T(); } + }; +} + +class Flow { + Flow() {} +public: + Flow(double d) {} +}; +%} + +%template(VectFlow) std::vector; diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 8920c015c..1a0f6ba47 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -237,7 +237,8 @@ static String *make_name(Node *n, String *name,SwigType *decl) { int destructor = name && (*(Char(name)) == '~'); if (yyrename) { - String *s = (yyrename); + String *s = NewString(yyrename); + Delete(yyrename); yyrename = 0; if (destructor && (*(Char(s)) != '~')) { Insert(s,0,"~"); @@ -539,11 +540,14 @@ static void add_symbols_copy(Node *n) { if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) { if (add_oldname) { DohIncref(add_oldname); - /* If already renamed, we used that name */ + /* Disable this, it prevents %rename to work with templates */ + /* If already renamed, we used that name */ + /* if (Strcmp(add_oldname, Getattr(n,k_name)) != 0) { Delete(yyrename); yyrename = Copy(add_oldname); } + */ } Delattr(n,"sym:needs_symtab"); Delattr(n,k_symname); @@ -587,12 +591,12 @@ static void add_symbols_copy(Node *n) { } if (add_oldname) { Delete(add_oldname); + add_oldname = 0; } if (strcmp(cnodeType,"class") == 0) { inclass = 0; current_class = 0; } - add_oldname = 0; } else { if (strcmp(cnodeType,"extend") == 0) { emode = cplus_mode; diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index c0c319565..047bbc948 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -418,6 +418,7 @@ Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) } } + /* ----------------------------------------------------------------------------- * Swig_name_object_get() * @@ -468,6 +469,7 @@ Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *dec Printf(stderr,"Swig_name_object_get: '%s', '%s'\n", name, decl); #endif + /* Perform a class-based lookup (if class prefix supplied) */ if (prefix) { if (Len(prefix)) { @@ -491,7 +493,7 @@ Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *dec Delete(t_name); } /* A template-based class lookup */ - if (!rn && SwigType_istemplate(prefix)) { + if (0 && !rn && SwigType_istemplate(prefix)) { String *t_prefix = SwigType_templateprefix(prefix); if (Strcmp(t_prefix,prefix) != 0) { String *t_name = SwigType_templateprefix(name); @@ -614,7 +616,7 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) { char *ncdecl = 0; String *rdecl = 0; - SwigType *rname = 0; + String *rname = 0; if (!features) return; /* MM: This removed to more tightly control feature/name matching */ @@ -626,29 +628,31 @@ Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, */ /* very specific hack for template constructors/destructors */ - if (name && SwigType_istemplate(name) && - (HashCheckAttr(node,k_nodetype,k_constructor) - || HashCheckAttr(node, k_nodetype,k_destructor))) { - String *nprefix = NewStringEmpty(); - String *nlast = NewStringEmpty(); - String *tprefix; - Swig_scopename_split(name, &nprefix, &nlast); - tprefix = SwigType_templateprefix(nlast); - Delete(nlast); - if (Len(nprefix)) { - Append(nprefix,"::"); - Append(nprefix,tprefix); - Delete(tprefix); - rname = nprefix; - } else { - rname = tprefix; - Delete(nprefix); + if (name && SwigType_istemplate(name)) { + String *nodetype = Getattr(node, k_nodetype); + if (nodetype && (Equal(nodetype,k_constructor) || Equal(nodetype,k_destructor))) { + String *nprefix = NewStringEmpty(); + String *nlast = NewStringEmpty(); + String *tprefix; + Swig_scopename_split(name, &nprefix, &nlast); + tprefix = SwigType_templateprefix(nlast); + Delete(nlast); + if (Len(nprefix)) { + Append(nprefix,"::"); + Append(nprefix,tprefix); + Delete(tprefix); + rname = nprefix; + } else { + rname = tprefix; + Delete(nprefix); + } + rdecl = Copy(decl); + Replaceall(rdecl,name,rname); + decl = rdecl; + name = rname; } - rdecl = Copy(decl); - Replaceall(rdecl,name,rname); - decl = rdecl; - name = rname; } + #ifdef SWIG_DEBUG Printf(stderr,"Swig_features_get: %s %s %s\n", prefix, name, decl); @@ -658,6 +662,12 @@ Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, features_get(features, empty_string, 0, 0, node); if (name) { String *tname = NewStringEmpty(); + /* add features for 'root' template */ + if (SwigType_istemplate(name)) { + String *dname = SwigType_templateprefix(name); + features_get(features, dname, decl, ncdecl, node); + Delete(dname); + } /* Catch-all */ features_get(features, name, decl, ncdecl, node); /* Perform a class-based lookup (if class prefix supplied) */ @@ -694,15 +704,16 @@ Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Delete(tname); } if (name && SwigType_istemplate(name)) { + /* add features for complete template type */ String *dname = Swig_symbol_template_deftype(name,0); - if (Strcmp(dname,name)) { + if (!Equal(dname,name)) { Swig_features_get(features, prefix, dname, decl, node); } Delete(dname); } - Delete(rname); - Delete(rdecl); + if (rname) Delete(rname); + if (rdecl) Delete(rdecl); } @@ -1421,6 +1432,44 @@ Swig_name_make(Node *n, String *prefix, String_or_char *cname, SwigType *decl, S String *result = 0; String *name = NewString(cname); Hash *wrn = 0; + String *rdecl = 0; + String *rname = 0; + + /* very specific hack for template constructors/destructors */ +#ifdef SWIG_DEBUG + Printf(stderr,"SWIG_name_make: looking for %s %s %s %s\n", prefix, name, decl, oldname); +#endif + + if (name && n && SwigType_istemplate(name)) { + String *nodetype = Getattr(n, k_nodetype); + if (nodetype && (Equal(nodetype,k_constructor) || Equal(nodetype,k_destructor))) { + String *nprefix = NewStringEmpty(); + String *nlast = NewStringEmpty(); + String *tprefix; + Swig_scopename_split(name, &nprefix, &nlast); + tprefix = SwigType_templateprefix(nlast); + Delete(nlast); + if (Len(nprefix)) { + Append(nprefix,"::"); + Append(nprefix,tprefix); + Delete(tprefix); + rname = nprefix; + } else { + rname = tprefix; + Delete(nprefix); + } + rdecl = Copy(decl); + Replaceall(rdecl,name,rname); +#ifdef SWIG_DEBUG + Printf(stderr,"SWIG_name_make: use new name %s %s : %s %s\n",name, decl, rname, rdecl); +#endif + decl = rdecl; + Delete(name); + name = rname; + } + } + + if (rename_hash || rename_list) { Hash *rn = Swig_name_object_get(Swig_name_rename_hash(), prefix, name, decl); if (!rn || !Swig_name_match_nameobj(rn,n)) { @@ -1487,17 +1536,16 @@ Swig_name_make(Node *n, String *prefix, String_or_char *cname, SwigType *decl, S if (result) Delete(result); if (oldname) { result = NewString(oldname); - Delete(name); } else { - result = name; + result = NewString(cname); } - } else { - Delete(name); } + Delete(name); #ifdef SWIG_DEBUG - Printf(stderr,"Swig_name_make: '%s' '%s'\n", cname, result); + Printf(stderr,"Swig_name_make: result '%s' '%s'\n", cname, result); #endif + return result; } diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 495fdf732..48ac2f750 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -63,7 +63,19 @@ static Hash* get_typemap(int tm_scope, SwigType* type) Delete(ty); } tm = Getattr(typemaps[tm_scope],type); - Delete(dtype); + + + if (dtype) { + if (!tm) { + String *t_name = SwigType_templateprefix(type); + if (!Equal(t_name,type)) { + tm = Getattr(typemaps[tm_scope],t_name); + } + Delete(t_name); + } + Delete(dtype); + } + return tm; } @@ -1215,10 +1227,6 @@ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const Stri String *cname = 0; String *clname = 0; char *cop = Char(op); -#if 0 - String *qsn; - Symtab *st; -#endif /* special case, we need to check for 'ref' call and set the default code 'sdef' */ if (Cmp(op,"newfree") == 0) { @@ -1230,40 +1238,27 @@ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const Stri pname = Getattr(node,k_name); -#if 0 - /* removed for now as it breaks old code and introduces - inconsistencies and adds about 25% to the execution time of the - test-suite - WSF This is my plan to fix this longer term: The - following debug shows that some typemap lookups use fully qualified - names and some do not. - -Printf(stdout, "Swig_typemap_lookup %s [%s %s]\n", op, type, pname ? pname : "NONAME"); - - So even the current typemap lookups are inconsistent. The "name" - attribute is often changed, particularly in lang.cxx. I hope to - either remove this name changing to fix this or introduce a new - attribute to use for the name. Possibly introduce a new attribute - called fqname - fully qualified name, that holds the name to use for - the Swig_typemap_search. If this typemap search fails then use the - unqualified name. Need to check non-simple return types, eg - pointers/references. - */ - st = Getattr(node,k_symsymtab); - qsn = st ? Swig_symbol_qualifiedscopename(st) : 0; - if (qsn && StringLen(qsn)) { - /* look qualified names first, such as +#if 1 + if (pname && node && checkAttribute(node,k_kind,"function")) { + /* + For functions, look qualified names first, such as - int *Foo::foo(int bar) -> Foo::foo + struct Foo { + int *foo(int bar) -> Foo::foo + }; */ - String *qname = NewStringf("%s::%s",qsn,pname); - tm = Swig_typemap_search(op,type,qname,&mtype); - Delete(qname); + Symtab *st = Getattr(node,k_symsymtab); + String *qsn = st ? Swig_symbol_string_qualify(pname, st) : 0; + if (qsn) { + if (StringLen(qsn) && !Equal(qsn,pname)) { + tm = Swig_typemap_search(op,type,qsn,&mtype); + if (tm && strstr(Char(Getattr(tm,k_type)),"SWIGTYPE")) { + tm = 0; + } + } + Delete(qsn); + } } - Delete(qsn); - - /* look now for simple name, such as - int *Foo::foo(int bar) -> foo - */ if (!tm) #endif tm = Swig_typemap_search(op,type,pname,&mtype);