diff --git a/CHANGES.current b/CHANGES.current index c711536ce..5aa45704f 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.0 (in progress) ============================ +2014-01-14: diorcety + Patch #112 - Fix symbol resolution involving scopes that have multiple levels + of typedefs - fixes some template resolutions as well as some typemap searches. + 2014-01-13: kwwette [Octave] update support to Octave version 3.8.0 diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index bf88b0035..6d1d2a25b 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -424,6 +424,7 @@ CPP_TEST_CASES += \ template_typedef_ns \ template_typedef_ptr \ template_typedef_rec \ + template_typedef_typedef \ template_typemaps \ template_typemaps_typedef \ template_typemaps_typedef2 \ @@ -442,6 +443,7 @@ CPP_TEST_CASES += \ typedef_scope \ typedef_sizet \ typedef_struct \ + typedef_typedef \ typemap_arrays \ typemap_array_qualifiers \ typemap_delete \ diff --git a/Examples/test-suite/java/template_typedef_typedef_runme.java b/Examples/test-suite/java/template_typedef_typedef_runme.java new file mode 100644 index 000000000..f5f368561 --- /dev/null +++ b/Examples/test-suite/java/template_typedef_typedef_runme.java @@ -0,0 +1,26 @@ +import template_typedef_typedef.*; + +public class template_typedef_typedef_runme { + + static { + try { + System.loadLibrary("template_typedef_typedef"); + } 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[]) { + ObjectBase ob1 = new ObjectBase(); + ob1.getBlabla1(new ObjectBase()); + Object2Base ob2 = new Object2Base(); + ob2.getBlabla2(new Object2Base()); + + Factory factory = new Factory(); + factory.getBlabla3(new ObjectBase()); + factory.getBlabla4(new Object2Base()); + } +} + + diff --git a/Examples/test-suite/python/typedef_typedef_runme.py b/Examples/test-suite/python/typedef_typedef_runme.py new file mode 100644 index 000000000..51a823def --- /dev/null +++ b/Examples/test-suite/python/typedef_typedef_runme.py @@ -0,0 +1,5 @@ +import typedef_typedef + +b = typedef_typedef.B() +if b.getValue(123) == 1234: + print "Failed !!!" diff --git a/Examples/test-suite/template_typedef_typedef.i b/Examples/test-suite/template_typedef_typedef.i new file mode 100644 index 000000000..30077c484 --- /dev/null +++ b/Examples/test-suite/template_typedef_typedef.i @@ -0,0 +1,43 @@ +%module template_typedef_typedef + +// Github issue #50 +// The Object2::getBlabla2 and Object::getBlabla1 functions were not resolving to the correct template types + +%inline%{ + +class Factory; +class Base { +public: + typedef Factory ABCD; + +}; + +namespace TT{ + template + class Object2:public T { + public: + void getBlabla2(typename T::ABCD::CC2 c) { + }; + }; + template + class Object:public T { + public: + void getBlabla1(typename T::ABCD::CC1 c) { + }; + }; +} + +class Factory { + public: + typedef TT::Object CC1; + typedef TT::Object2 CC2; + void getBlabla4(CC2 c) { + }; + void getBlabla3(CC1 c) { + }; +}; +%} + +%template(ObjectBase) TT::Object; +%template(Object2Base) TT::Object2; + diff --git a/Examples/test-suite/typedef_typedef.i b/Examples/test-suite/typedef_typedef.i new file mode 100644 index 000000000..9bfa14a23 --- /dev/null +++ b/Examples/test-suite/typedef_typedef.i @@ -0,0 +1,37 @@ +%module typedef_typedef + +// Check C::Bar::Foo resolves to A::Foo in typemap search + +%typemap(in) SWIGTYPE, int "__wrong_in_typemap__will_not_compile__" + +%typemap(in) A::Foo { + $1 = 1234; /* A::Foo in typemap */ +} + +%inline %{ + struct A + { + typedef int Foo; + }; + + struct C + { + typedef A Bar; + }; + + struct B + { + C::Bar::Foo getValue(C::Bar::Foo intvalue) { + return intvalue; + } + }; +%} + +/* + + An issue can be the steps resolution. + 1) C::Bar is A. So C::Bar::Foo should be first resolved as A::Foo. + 2) Then A::Foo should be resolved int. + If the first step is skipped the typemap is not applied. + +*/ diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index bcfd2feb5..e11fc781a 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -602,7 +602,7 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) { Typetab *s; Hash *ttab; String *namebase = 0; - String *nameprefix = 0; + String *nameprefix = 0, *rnameprefix = 0; int newtype = 0; resolved_scope = 0; @@ -647,51 +647,66 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) { Printf(stdout, "nameprefix = '%s'\n", nameprefix); #endif if (nameprefix) { - /* Name had a prefix on it. See if we can locate the proper scope for it */ - String *rnameprefix = template_parameters_resolve(nameprefix); - nameprefix = rnameprefix ? Copy(rnameprefix) : nameprefix; - Delete(rnameprefix); - s = SwigType_find_scope(s, nameprefix); - - /* Couldn't locate a scope for the type. */ - if (!s) { - Delete(base); - Delete(namebase); - Delete(nameprefix); - r = 0; - goto return_result; - } - /* Try to locate the name starting in the scope */ + rnameprefix = SwigType_typedef_resolve(nameprefix); + if(rnameprefix != NULL) { #ifdef SWIG_DEBUG - Printf(stdout, "namebase = '%s'\n", namebase); + Printf(stdout, "nameprefix '%s' is a typedef to '%s'\n", nameprefix, rnameprefix); #endif - type = typedef_resolve(s, namebase); - if (type && resolved_scope) { - /* we need to look for the resolved type, this will also - fix the resolved_scope if 'type' and 'namebase' are - declared in different scopes */ - String *rtype = 0; - rtype = typedef_resolve(resolved_scope, type); - if (rtype) - type = rtype; - } -#ifdef SWIG_DEBUG - Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type); -#endif - if (type && (!Swig_scopename_check(type)) && resolved_scope) { - Typetab *rtab = resolved_scope; - String *qname = Getattr(resolved_scope, "qname"); - /* If qualified *and* the typename is defined from the resolved scope, we qualify */ - if ((qname) && typedef_resolve(resolved_scope, type)) { - type = Copy(type); - Insert(type, 0, "::"); - Insert(type, 0, qname); -#ifdef SWIG_DEBUG - Printf(stdout, "qual %s \n", type); -#endif - newtype = 1; + type = Copy(namebase); + Insert(type, 0, "::"); + Insert(type, 0, rnameprefix); + if (strncmp(Char(type), "::", 2) == 0) { + Delitem(type, 0); + Delitem(type, 0); + } + newtype = 1; + } else { + /* Name had a prefix on it. See if we can locate the proper scope for it */ + String *rnameprefix = template_parameters_resolve(nameprefix); + nameprefix = rnameprefix ? Copy(rnameprefix) : nameprefix; + Delete(rnameprefix); + s = SwigType_find_scope(s, nameprefix); + + /* Couldn't locate a scope for the type. */ + if (!s) { + Delete(base); + Delete(namebase); + Delete(nameprefix); + r = 0; + goto return_result; + } + /* Try to locate the name starting in the scope */ +#ifdef SWIG_DEBUG + Printf(stdout, "namebase = '%s'\n", namebase); +#endif + type = typedef_resolve(s, namebase); + if (type && resolved_scope) { + /* we need to look for the resolved type, this will also + fix the resolved_scope if 'type' and 'namebase' are + declared in different scopes */ + String *rtype = 0; + rtype = typedef_resolve(resolved_scope, type); + if (rtype) + type = rtype; + } +#ifdef SWIG_DEBUG + Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type); +#endif + if ((type) && (!Swig_scopename_check(type)) && resolved_scope) { + Typetab *rtab = resolved_scope; + String *qname = Getattr(resolved_scope, "qname"); + /* If qualified *and* the typename is defined from the resolved scope, we qualify */ + if ((qname) && typedef_resolve(resolved_scope, type)) { + type = Copy(type); + Insert(type, 0, "::"); + Insert(type, 0, qname); +#ifdef SWIG_DEBUG + Printf(stdout, "qual %s \n", type); +#endif + newtype = 1; + } + resolved_scope = rtab; } - resolved_scope = rtab; } } else { /* Name is unqualified. */