diff --git a/CHANGES.current b/CHANGES.current index fe625d798ae..edd39af316e 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) ============================ +2013-10-04: wsfulton + Fix %naturalvar not having any affect on templated classes instantiated with an + enum as the template parameter type. Problem reported by Vadim Zeitlin. + 2013-09-20: wsfulton [Java] Fix a memory leak for the java char **STRING_ARRAY typemaps. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 997f8e715e8..381a49f7bc5 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -274,6 +274,7 @@ CPP_TEST_CASES += \ nspace \ nspace_extend \ naturalvar \ + naturalvar_more \ nested_class \ nested_comment \ nested_workaround \ diff --git a/Examples/test-suite/naturalvar_more.i b/Examples/test-suite/naturalvar_more.i new file mode 100644 index 00000000000..2cbfb069cf9 --- /dev/null +++ b/Examples/test-suite/naturalvar_more.i @@ -0,0 +1,46 @@ +%module naturalvar_more + +// The instantiation of a template using an enum in the template parameter was not picking up %naturalvar. + +// These typemaps will be used if %naturalvar is not working +%typemap(out) T *te, T *const_te "_should_not_use_this_out_typemap_" +%typemap(varout) T *te, T *const_te "_should_not_use_this_varout_typemap_" +%typemap(out) Hidden *hidden "_should_not_use_this_out_typemap_" +%typemap(varout) Hidden *hidden "_should_not_use_this_varout_typemap_" + +%naturalvar T; +%naturalvar Hidden; + +%inline %{ +template struct T {}; +struct K {}; +struct Hidden; +%} +%{ +struct Hidden {}; +%} + +%inline %{ +namespace Space { + enum E { E1, E2, E3 }; +} +%} + +%template(TE) T; + +%include +%include +%template(VectorString) std::vector; + +%inline { +using namespace Space; +struct S { + T te; + const T const_te; + const std::vector::value_type const_string_member; // check this resolves to std::string which has a naturalvar + std::vector::value_type string_member; // check this resolves to std::string which has a naturalvar + Hidden hidden; + S() : const_te(), const_string_member("initial string value") {} +}; +} + diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 6cc6e9fc36a..1e63d4d9c17 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -467,9 +467,9 @@ void swig_pragma(char *lang, char *name, char *value) { } /* -------------------------------------------------------------------------- - * use_naturalvar_mode() + * Language::use_naturalvar_mode() * -------------------------------------------------------------------------- */ -int use_naturalvar_mode(Node *n) { +int Language::use_naturalvar_mode(Node *n) const { if (Getattr(n, "unnamed")) return 0; int nvar = naturalvar_mode || GetFlag(n, "feature:naturalvar"); @@ -478,12 +478,17 @@ int use_naturalvar_mode(Node *n) { SwigType *ty = Getattr(n, "type"); SwigType *fullty = SwigType_typedef_resolve_all(ty); if (SwigType_isclass(fullty)) { - Node *m = Copy(n); SwigType *tys = SwigType_strip_qualifiers(fullty); - Swig_features_get(Swig_cparse_features(), 0, tys, 0, m); - nvar = GetFlag(m, "feature:naturalvar"); + if (!CPlusPlus) { + Replaceall(tys, "struct ", ""); + Replaceall(tys, "union ", ""); + Replaceall(tys, "class ", ""); + } + Node *typenode = Swig_symbol_clookup(tys, 0); + assert(typenode); + if (typenode) + nvar = GetFlag(typenode, "feature:naturalvar"); Delete(tys); - Delete(m); } Delete(fullty); } @@ -1441,6 +1446,7 @@ int Language::membervariableHandler(Node *n) { tm = Swig_typemap_lookup("memberin", nin, target, 0); Delete(nin); } + int flags = Extend | SmartPointer | use_naturalvar_mode(n); if (isNonVirtualProtectedAccess(n)) flags = flags | CWRAP_ALL_PROTECTED_ACCESS; @@ -3091,7 +3097,7 @@ Node *Language::symbolLookup(String *s, const_String_or_char_ptr scope) { * Tries to locate a class from a type definition * ----------------------------------------------------------------------------- */ -Node *Language::classLookup(const SwigType *s) { +Node *Language::classLookup(const SwigType *s) const { Node *n = 0; /* Look in hash of cached values */ diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index b3722af407a..4fcf013eb00 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -215,7 +215,7 @@ class Language:public Dispatcher { virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */ virtual void dumpSymbols(); virtual Node *symbolLookup(String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */ - virtual Node *classLookup(const SwigType *s); /* Class lookup */ + virtual Node *classLookup(const SwigType *s) const; /* Class lookup */ virtual Node *enumLookup(SwigType *s); /* Enum lookup */ virtual int abstractClassTest(Node *n); /* Is class really abstract? */ virtual int is_assignable(Node *n); /* Is variable assignable? */ @@ -300,6 +300,9 @@ class Language:public Dispatcher { This does not include protected virtual methods as they are turned on with the dirprot option. */ bool isNonVirtualProtectedAccess(Node *n) const; + /* Identify if a wrapped global or member variable n should use the naturalvar feature */ + int use_naturalvar_mode(Node *n) const; + /* Director subclass comparison test */ String *none_comparison; @@ -380,7 +383,6 @@ int is_protected(Node *n); int is_member_director(Node *parentnode, Node *member); int is_member_director(Node *member); int is_non_virtual_protected_access(Node *n); /* Check if the non-virtual protected members are required (for directors) */ -int use_naturalvar_mode(Node *n); void Wrapper_virtual_elimination_mode_set(int); void Wrapper_fast_dispatch_mode_set(int);