diff --git a/Examples/test-suite/java/template_nested_runme.java b/Examples/test-suite/java/template_nested_runme.java index 422e7ea9e..4cca9f34a 100644 --- a/Examples/test-suite/java/template_nested_runme.java +++ b/Examples/test-suite/java/template_nested_runme.java @@ -29,6 +29,7 @@ public class template_nested_runme { OuterClass.T_OuterClassInner2NormalClass inner2 = new OuterClass.T_OuterClassInner2NormalClass(); inner2.setEmbeddedVar(2); OuterClass.T_OuterClassInner2NormalClass inner22 = new OuterClass().useInner2Again(inner2); + OuterClass.T_OuterClassInner1Double inner3 = new OuterClass.T_OuterClassInner1Double(); } } diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i index 0d418192d..282875531 100644 --- a/Examples/test-suite/nested_class.i +++ b/Examples/test-suite/nested_class.i @@ -167,10 +167,16 @@ struct Outer { /////////////////////////////////////////// typedef struct InnerSameName { Integer x; + struct InnerSameName2 {}; } InnerSameName; InnerSameName* makeInnerSameName() { return 0; } }; +#if defined(SWIGCSHARP) || defined (SWIGJAVA) +// place a class with the same name as in Outer in global scope, to test language symbol table +class InnerSameName {}; +class InnerSameName2 {}; +#endif %} // Ignore nested struct instance diff --git a/Examples/test-suite/template_nested.i b/Examples/test-suite/template_nested.i index bbca9502c..c33018e0f 100644 --- a/Examples/test-suite/template_nested.i +++ b/Examples/test-suite/template_nested.i @@ -30,6 +30,7 @@ namespace ns { %} %template(T_NormalTemplateNormalClass) ns::NormalTemplate; %template(T_NormalTemplateInt) ns::NormalTemplate; +%template(T_NormalTemplateDouble) ns::NormalTemplate; %inline %{ namespace ns { @@ -70,6 +71,9 @@ namespace ns { }; Inner2 useInner2(const Inner2& inner) { return inner; } Inner2 useInner2Again(const Inner2& inner) { return inner; } +#ifdef SWIG + %template(T_OuterClassInner1Double) Inner1; +#endif int iii; }; struct ABC { @@ -105,8 +109,10 @@ namespace ns { NestedStruct useNestedStruct(const NestedStruct& inner) { return inner; } }; } - %} +%extend ns::OuterClass { + %template(T_OuterClassInner2Double) Inner2; +} %template(T_OuterTMethodNormalClass) ns::OuterClass::InnerTMethod; %template(T_TemplateFuncs1Int) ns::TemplateFuncs::templateMethod1; diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index ef5aa6ef4..40d853387 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1311,16 +1311,18 @@ static void default_arguments(Node *n) { } /* ----------------------------------------------------------------------------- - * tag_nodes() + * mark_nodes_as_extend() * - * Used by the parser to mark subtypes with extra information. + * Used by the %extend to mark subtypes with "feature:extend". + * template instances declared within %extend are skipped * ----------------------------------------------------------------------------- */ -static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) { - while (n) { - Setattr(n, attrname, value); - tag_nodes(firstChild(n), attrname, value); - n = nextSibling(n); +static void mark_nodes_as_extend(Node *n) { + for (; n; n = nextSibling(n)) { + if (Getattr(n, "template") && Strcmp(nodeType(n), "class") == 0) + continue; + Setattr(n, "feature:extend", "1"); + mark_nodes_as_extend(firstChild(n)); } } @@ -1648,9 +1650,7 @@ extend_directive : EXTEND options idcolon LBRACE { clsname = make_class_name($3); Setattr($$,"name",clsname); - /* Mark members as extend */ - - tag_nodes($6,"feature:extend",(char*) "1"); + mark_nodes_as_extend($6); if (current_class) { /* We add the extension to the previously defined class */ appendChild($$,$6); @@ -4267,7 +4267,7 @@ cpp_members : cpp_member cpp_members { } } cpp_members RBRACE cpp_members { $$ = new_node("extend"); - tag_nodes($4,"feature:extend",(char*) "1"); + mark_nodes_as_extend($4); appendChild($$,$4); set_nextSibling($$,$6); } diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 7f1d13678..d3384e1ba 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -559,9 +559,11 @@ Allocate(): virtual int classDeclaration(Node *n) { Symtab *symtab = Swig_symbol_current(); Swig_symbol_setscope(Getattr(n, "symtab")); - Node *oldInclass = inclass; - AccessMode oldAcessMode = cplus_mode; - + save_value oldInclass(inclass); + save_value oldAcessMode(cplus_mode); + save_value oldExtendMode(extendmode); + if (Getattr(n, "template")) + extendmode = 0; if (!CPlusPlus) { /* Always have default constructors/destructors in C */ Setattr(n, "allocate:default_constructor", "1"); @@ -729,8 +731,6 @@ Allocate(): /* Only care about default behavior. Remove temporary values */ Setattr(n, "allocate:visit", "1"); - inclass = oldInclass; - cplus_mode = oldAcessMode; Swig_symbol_setscope(symtab); return SWIG_OK; } diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 9197b4b17..3c765835e 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -1888,10 +1888,10 @@ public: if (Node *outer = Getattr(n, "nested:outer")) { String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { - Push(outerClassesPrefix, "::"); + Push(outerClassesPrefix, "."); Push(outerClassesPrefix, Getattr(outer, "sym:name")); } - String *fnspace = nspace ? NewStringf("%s::%s", nspace, outerClassesPrefix) : outerClassesPrefix; + String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix; if (!addSymbol(proxy_class_name, n, fnspace)) return SWIG_ERROR; if (nspace) diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index fdc678dbf..d378a02f3 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -1969,8 +1969,7 @@ public: } if (outerClassesPrefix) { - Replaceall(outerClassesPrefix, ".", "::"); - String *fnspace = nspace ? NewStringf("%s::%s", nspace, outerClassesPrefix) : outerClassesPrefix; + String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix; if (!addSymbol(proxy_class_name, n, fnspace)) return SWIG_ERROR; if (nspace) diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index be83b5069..795b9edb8 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -525,15 +525,9 @@ int Language::top(Node *n) { * ---------------------------------------------------------------------- */ int Language::extendDirective(Node *n) { - int oldam = Extend; - AccessMode oldmode = cplus_mode; - Extend = CWRAP_EXTEND; - cplus_mode = PUBLIC; - + save_value oldam(Extend, CWRAP_EXTEND); + save_value oldmode(cplus_mode, PUBLIC); emit_children(n); - - Extend = oldam; - cplus_mode = oldmode; return SWIG_OK; } @@ -2486,7 +2480,9 @@ int Language::classDeclaration(Node *n) { * ---------------------------------------------------------------------- */ int Language::classHandler(Node *n) { - + save_value oldExtend(Extend); + if (Getattr(n, "template")) + Extend = 0; bool hasDirector = Swig_directorclass(n) ? true : false; /* Emit all of the class members */ @@ -2519,7 +2515,7 @@ int Language::classHandler(Node *n) { if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) { Node *vtable = Getattr(n, "vtable"); String *symname = Getattr(n, "sym:name"); - AccessMode old_mode = cplus_mode; + save_value old_mode(cplus_mode); cplus_mode = PROTECTED; int len = Len(vtable); for (int i = 0; i < len; i++) { @@ -2548,7 +2544,6 @@ int Language::classHandler(Node *n) { } Delete(wrapname); } - cplus_mode = old_mode; } } diff --git a/Source/Modules/nested.cxx b/Source/Modules/nested.cxx index a62a9e9da..37248608c 100644 --- a/Source/Modules/nested.cxx +++ b/Source/Modules/nested.cxx @@ -432,6 +432,8 @@ void Swig_nested_process_classes(Node *n) { removeNode(c); if (!checkAttribute(c, "access", "public")) SetFlag(c, "feature:ignore"); + else if (Strcmp(nodeType(n),"extend") == 0 && Strcmp(nodeType(parentNode(n)),"class") == 0) + insertNodeAfter(parentNode(n), c); else insertNodeAfter(n, c); } diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index 9e76b4d10..6d3cd35de 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -423,4 +423,13 @@ void Swig_process_types(Node *n); void Swig_nested_process_classes(Node *n); void Swig_nested_name_unnamed_c_structs(Node *n); +template class save_value { + T _value; + T& _value_ptr; +public: + save_value(T& value) : _value(value), _value_ptr(value){} + save_value(T& value, T new_val) : _value(value), _value_ptr(value){ value = new_val; } + ~save_value(){ _value_ptr = _value; } +}; + #endif diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 3f8e33dae..e918c0770 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -417,7 +417,7 @@ class TypePass:private Dispatcher { String *unnamed = Getattr(n, "unnamed"); String *storage = Getattr(n, "storage"); String *kind = Getattr(n, "kind"); - Node *oldinclass = inclass; + save_value oldinclass(inclass); List *olist = normalize; Symtab *symtab; String *nname = 0; @@ -537,8 +537,6 @@ class TypePass:private Dispatcher { normalize = olist; - inclass = oldinclass; - /* If in a namespace, patch the class name */ if (nname) { Setattr(n, "name", nname); diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index 7d8180d1c..161c71e43 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -1154,13 +1154,13 @@ String *Swig_string_strip(String *s) { * ----------------------------------------------------------------------------- */ void Swig_offset_string(String *s, int number) { - char *res; - char *p; - char *end; + char *res, *p, *end, *start; /* count a number of lines in s */ int lines = 1; int len = Len(s); - char *start = strchr(Char(s), '\n'); + if (len == 0) + return; + start = strchr(Char(s), '\n'); while (start) { ++lines; start = strchr(start + 1, '\n');