diff --git a/SWIG/Examples/test-suite/features.i b/SWIG/Examples/test-suite/features.i index ff21fadd2..578fc5fe7 100644 --- a/SWIG/Examples/test-suite/features.i +++ b/SWIG/Examples/test-suite/features.i @@ -7,6 +7,7 @@ %exception "this_will_not_compile"; // Test 1: Test for no user supplied constructors and destructor +%exception Simple::Simple(const Simple&) "$action /*Simple::Simple*/"; %exception Simple::Simple() "$action /*Simple::Simple*/"; %exception Simple::~Simple() "$action /*Simple::~Simple*/"; @@ -15,6 +16,7 @@ class Simple {}; %} +%exception NS::SimpleNS::SimpleNS(const NS::SimpleNS&) "$action /*NS::SimpleNS::SimpleNS*/"; %exception NS::SimpleNS::SimpleNS() "$action /*NS::SimpleNS::SimpleNS*/"; %exception NS::SimpleNS::~SimpleNS() "$action /*NS::SimpleNS::~SimpleNS*/"; // method tests @@ -46,6 +48,7 @@ template void foobar(T t) {} %template(FooBarInt) foobar; // Test 3: Test templates with no user supplied constructors and destructor +%exception SimpleTemplate::SimpleTemplate(const SimpleTemplate&) "$action /*SimpleTemplate::SimpleTemplate*/"; %exception SimpleTemplate::SimpleTemplate() "$action /*SimpleTemplate::SimpleTemplate*/"; %exception SimpleTemplate::~SimpleTemplate() "$action /*SimpleTemplate::~SimpleTemplate*/"; @@ -92,6 +95,7 @@ public: %template(TemplateInt) Template; // Test 5: wildcards +%exception Space::WildCards::WildCards(const Space::WildCards&) "$action /* Space::WildCards::WildCards() */"; %exception Space::WildCards::WildCards() "$action /* Space::WildCards::WildCards() */"; %exception Space::WildCards::~WildCards() "$action /* Space::WildCards::WildCards() */"; %exception *::incy "_failure_ /* *::incy */"; @@ -113,6 +117,7 @@ namespace Space { %} // Test 6: default arguments +%exception Space::Animals::Animals(const Space::Animals&) "$action /* Space::Animals::Animals(int a = 0, double d = 0.0) */"; %exception Space::Animals::Animals(int a = 0, double d = 0.0) "$action /* Space::Animals::Animals(int a = 0, double d = 0.0) */"; %exception Space::Animals::~Animals() "$action /* Space::Animals::~Animals() */"; %exception Space::Animals::lions(int a = 0, double d = 0.0) const "$action /* Space::Animals::lions(int a = 0, double d = 0.0) const */"; @@ -132,8 +137,10 @@ namespace Space { %} // Test 7: inheritance +%exception Space::Base::Base(const Space::Base&) "$action /* Space::Base::Base() */"; %exception Space::Base::Base() "$action /* Space::Base::Base() */"; %exception Space::Base::~Base() "$action /* Space::Base::~Base() */"; +%exception Space::Derived::Derived(const Space::Derived&) "$action /* Space::Derived::Derived() */"; %exception Space::Derived::Derived() "$action /* Space::Derived::Derived() */"; %exception Space::Derived::~Derived() "$action /* Space::Derived::~Derived() */"; // The following should apply to both Base and Derived diff --git a/SWIG/Lib/std/std_streambuf.i b/SWIG/Lib/std/std_streambuf.i index 3583cf28f..7efb19c6c 100644 --- a/SWIG/Lib/std/std_streambuf.i +++ b/SWIG/Lib/std/std_streambuf.i @@ -80,6 +80,9 @@ namespace std { protected: basic_streambuf(); + private: + basic_streambuf(const basic_streambuf&); + }; } diff --git a/SWIG/Lib/swig.swg b/SWIG/Lib/swig.swg index 8d3c9a237..3beebff43 100644 --- a/SWIG/Lib/swig.swg +++ b/SWIG/Lib/swig.swg @@ -63,10 +63,10 @@ #define %defaultdtor %feature("nodefaultdtor","0") #define %clearnodefaultdtor %feature("nodefaultdtor","") -/* Disable the generation of copy constructor */ -#define %nocopyctor %feature("nocopyctor","1") -#define %copyctor %feature("nocopyctor","0") -#define %clearnocopyctor %feature("nocopyctor","") +/* Enable the generation of copy constructor */ +#define %copyctor %feature("copyctor","1") +#define %nocopyctor %feature("copyctor","0") +#define %clearcopyctor %feature("copyctor","") /* Force the old nodefault behavior, ie disable both constructor and destructor */ #define %oldnodefault %feature("oldnodefault","1") diff --git a/SWIG/Lib/typemaps/swigtype.swg b/SWIG/Lib/typemaps/swigtype.swg index 3f1a99464..2d724537a 100644 --- a/SWIG/Lib/typemaps/swigtype.swg +++ b/SWIG/Lib/typemaps/swigtype.swg @@ -155,6 +155,7 @@ } } + /* memberin/globalin/varin, for fix double arrays. */ %typemap(memberin) SWIGTYPE [ANY][ANY] { diff --git a/SWIG/Source/CParse/cparse.h b/SWIG/Source/CParse/cparse.h index 9192f842a..47ef1f198 100644 --- a/SWIG/Source/CParse/cparse.h +++ b/SWIG/Source/CParse/cparse.h @@ -45,6 +45,7 @@ extern SwigType *Swig_cparse_type(String *); extern Node *Swig_cparse(File *); extern Hash *Swig_cparse_namewarn(); extern Hash *Swig_cparse_features(); +extern Hash *Swig_cparse_rename(); extern void SWIG_cparse_set_compact_default_args(int defargs); extern int SWIG_cparse_template_reduce(int treduce); diff --git a/SWIG/Source/CParse/parser.y b/SWIG/Source/CParse/parser.y index 75e63637d..6ecd54c2a 100644 --- a/SWIG/Source/CParse/parser.y +++ b/SWIG/Source/CParse/parser.y @@ -217,6 +217,11 @@ Hash *Swig_cparse_features() { return features_hash; } +Hash *Swig_cparse_rename() { + if (!rename_hash) rename_hash = NewHash(); + return rename_hash; +} + static String *feature_identifier_fix(String *s) { if (SwigType_istemplate(s)) { String *tp, *ts, *ta, *tq; @@ -238,13 +243,12 @@ static String *feature_identifier_fix(String *s) { static void single_rename_add(const char *name, SwigType *decl, const char *cnewname) { String *nname; String *newname = NewString(cnewname); - if (!rename_hash) rename_hash = NewHash(); if (Namespaceprefix) { nname = NewStringf("%s::%s",Namespaceprefix, name); } else { nname = NewString(name); } - Swig_name_object_set(rename_hash,nname,decl,newname); + Swig_name_object_set(Swig_cparse_rename(),nname,decl,newname); Delete(newname); Delete(nname); } @@ -298,7 +302,7 @@ static void namewarn_add(const char *name, SwigType *decl, const char *warning) static void rename_inherit(String *base, String *derived) { /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */ - Swig_name_object_inherit(rename_hash,base,derived); + Swig_name_object_inherit(Swig_cparse_rename(),base,derived); Swig_name_object_inherit(Swig_cparse_namewarn(),base,derived); Swig_name_object_inherit(features_hash,base,derived); } @@ -330,7 +334,7 @@ static String *make_name(String *name,SwigType *decl) { if (add_oldname) return Copy(add_oldname); return Copy(origname); } - rn = Swig_name_object_get(rename_hash, Namespaceprefix, name, decl); + rn = Swig_name_object_get(Swig_cparse_rename(), Namespaceprefix, name, decl); if (!rn) { if (add_oldname) return Copy(add_oldname); return Copy(name); diff --git a/SWIG/Source/Modules/allocate.cxx b/SWIG/Source/Modules/allocate.cxx index 450654823..48a5ba322 100644 --- a/SWIG/Source/Modules/allocate.cxx +++ b/SWIG/Source/Modules/allocate.cxx @@ -820,8 +820,19 @@ public: if (parms && (ParmList_numrequired(parms) == 1)) { /* Look for a few cases. X(const X &), X(X &), X(X *) */ int copy_constructor = 0; - String *cc = NewStringf("r.q(const).%s", Getattr(inclass,"name")); - if (Strcmp(cc,Getattr(parms,"type")) == 0) { + SwigType *type = Getattr(inclass,"name"); + String *tn = NewStringf("r.q(const).%s", type); + String *cc = SwigType_typedef_resolve_all(tn); + SwigType *rt = SwigType_typedef_resolve_all(Getattr(parms,"type")); + if (SwigType_istemplate(type)) { + String *tmp = Swig_symbol_template_deftype(cc, 0); + Delete(cc); + cc = tmp; + tmp = Swig_symbol_template_deftype(rt, 0); + Delete(rt); + rt = tmp; + } + if (Strcmp(cc,rt) == 0) { copy_constructor = 1; } else { Delete(cc); @@ -835,10 +846,12 @@ public: if (Strcmp(cc,ty) == 0) { copy_constructor = 1; } - Delete(cc); Delete(ty); } } + Delete(cc); + Delete(rt); + Delete(tn); if (copy_constructor) { Setattr(n,"copy_constructor","1"); diff --git a/SWIG/Source/Modules/lang.cxx b/SWIG/Source/Modules/lang.cxx index 445b0cdf4..89ad9731c 100644 --- a/SWIG/Source/Modules/lang.cxx +++ b/SWIG/Source/Modules/lang.cxx @@ -182,7 +182,7 @@ int Dispatcher::emit_one(Node *n) { /* ---------------------------------------------------------------------- * Dispatcher::emit_children() * - * Emit all children. + * Emit all children that matches the given type. type = 0 means all types. * ---------------------------------------------------------------------- */ int Dispatcher::emit_children(Node *n) { @@ -191,7 +191,7 @@ int Dispatcher::emit_children(Node *n) { for (c = firstChild(n); c; c = nextSibling(c)) { if (eo) { const char *tag = Char(nodeType(c)); - if (Strcmp(tag,"cdecl") == 0) { + if (strcmp(tag,"cdecl") == 0) { if (checkAttribute(c, "storage", "typedef")) tag = "typedef"; } @@ -204,6 +204,7 @@ int Dispatcher::emit_children(Node *n) { return SWIG_OK; } + /* Stubs for dispatcher class. We don't do anything by default---up to derived class to fill in traversal code */ @@ -1967,6 +1968,137 @@ int Language::classDirector(Node *n) { /* ---------------------------------------------------------------------- * Language::classDeclaration() * ---------------------------------------------------------------------- */ +static void addCopyConstructor(Node *n) +{ + String *cname = Getattr(n,"name"); + SwigType *type = Copy(cname); + String *last = Swig_scopename_last(cname); + String *name = NewStringf("%s::%s",cname,last); + String *cc = NewStringf("r.q(const).%s", type); + String *decl = NewStringf("f(%s).",cc); + String *csymname = Getattr(n,"sym:name"); + String *symname = Swig_name_object_get(Swig_cparse_rename(), cname, last, decl); + if (!symname) { + symname = Copy(csymname); + } + Parm *p = NewParm(cc,"_swig_self"); + + Node *cn = NewHash(); + set_nodeType(cn,"constructor"); + Setattr(cn,"name",name); + Setattr(cn,"sym:name",symname); + SetFlag(cn,"feature:new"); + Setattr(cn,"decl",decl); + Setattr(cn,"parentNode",n); + Setattr(cn,"parms",p); + Setattr(cn,"copy_constructor","1"); + + Symtab *oldscope = Swig_symbol_setscope(Getattr(n,"symtab")); + Node *on = Swig_symbol_add(symname, cn); + Swig_symbol_setscope(oldscope); + Swig_features_get(Swig_cparse_features(), 0, name, decl, cn); + + if (on == cn) { + Node *access = NewHash(); + set_nodeType(access,"access"); + Setattr(access,"kind","public"); + appendChild(n,access); + appendChild(n,cn); + Setattr(n,"has_copy_constructor","1"); + Setattr(n,"copy_constructor_decl",decl); + Setattr(n,"allocate:copy_constructor","1"); + Delete(access); + } + Delete(cn); + Delete(last); + Delete(name); + Delete(decl); + Delete(symname); +} + +static void addDefaultConstructor(Node *n) +{ + String *cname = Getattr(n,"name"); + String *last = Swig_scopename_last(cname); + String *name = NewStringf("%s::%s",cname,last); + String *decl = NewString("f()."); + String *csymname = Getattr(n,"sym:name"); + String *symname = Swig_name_object_get(Swig_cparse_rename(), cname, last, decl); + if (!symname) { + symname = Copy(csymname); + } + + Node *cn = NewHash(); + set_nodeType(cn,"constructor"); + Setattr(cn,"name",name); + Setattr(cn,"sym:name",symname); + SetFlag(cn,"feature:new"); + Setattr(cn,"decl",decl); + Setattr(cn,"parentNode",n); + Setattr(cn,"default_constructor","1"); + + Symtab *oldscope = Swig_symbol_setscope(Getattr(n,"symtab")); + Node *on = Swig_symbol_add(symname, cn); + Swig_symbol_setscope(oldscope); + Swig_features_get(Swig_cparse_features(), 0, name, decl, cn); + + if (on == cn) { + Node *access = NewHash(); + set_nodeType(access,"access"); + Setattr(access,"kind","public"); + appendChild(n,access); + appendChild(n,cn); + Setattr(n,"has_default_constructor","1"); + Setattr(n,"allocate:default_constructor","1"); + Delete(access); + } + Delete(cn); + Delete(last); + Delete(name); + Delete(decl); + Delete(symname); +} + +static void addDestructor(Node *n) +{ + String *cname = Getattr(n,"name"); + String *last = Swig_scopename_last(cname); + Insert(last,0,"~"); + String *name = NewStringf("%s::%s",cname,last); + String *decl = NewString("f()."); + String *symname = Swig_name_object_get(Swig_cparse_rename(), cname, last, decl); + if (!symname) { + symname = NewStringf("~%s",Getattr(n,"sym:name")); + } + + Node *cn = NewHash(); + set_nodeType(cn,"destructor"); + Setattr(cn,"name",name); + Setattr(cn,"sym:name",symname); + Setattr(cn,"decl","f()."); + Setattr(cn,"parentNode",n); + + Symtab *oldscope = Swig_symbol_setscope(Getattr(n,"symtab")); + Node *on = Swig_symbol_add(symname, cn); + Swig_symbol_setscope(oldscope); + Swig_features_get(Swig_cparse_features(), 0, name, decl, cn); + + if (on == cn) { + Node *access = NewHash(); + set_nodeType(access,"access"); + Setattr(access,"kind","public"); + appendChild(n,access); + appendChild(n,cn); + Setattr(n,"has_destructor","1"); + Setattr(n,"allocate:destructor","1"); + Delete(access); + } + Delete(cn); + Delete(last); + Delete(name); + Delete(decl); + Delete(symname); +} int Language::classDeclaration(Node *n) { String *ochildren = Getattr(n,"feature:onlychildren"); @@ -2027,15 +2159,43 @@ int Language::classDeclaration(Node *n) { /* Call classHandler() here */ if (!ImportMode) { - int ndir = GetFlag(n, "feature:director"); - int nndir = GetFlag(n, "feature:nodirector"); - /* 'nodirector' has precedence over 'director' */ - int dir = (ndir || nndir) ? (ndir && !nndir) : 0; - if (directorsEnabled() && dir) { + int dir = 0; + if (directorsEnabled()) { + int ndir = GetFlag(n, "feature:director"); + int nndir = GetFlag(n, "feature:nodirector"); + /* 'nodirector' has precedence over 'director' */ + dir = (ndir || nndir) ? (ndir && !nndir) : 0; + } + int abstract = !dir && abstractClassTest(n); + int odefault = (GenerateDefault && !GetFlag(n,"feature:nodefault")); + + /* default constructor */ + if (!abstract && !GetFlag(n,"feature:nodefaultctor") && odefault) { + if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) { + addDefaultConstructor(n); + } + } + /* copy constructor */ + if (CPlusPlus && !abstract && GetFlag(n,"feature:copyctor")) { + if (!Getattr(n,"has_copy_constructor") && !Getattr(n,"allocate:has_copy_constructor") + && (Getattr(n,"allocate:copy_constructor"))) { + addCopyConstructor(n); + } + } + /* default destructor */ + if (!GetFlag(n,"feature:nodefaultdtor") && odefault) { + if (!Getattr(n,"has_destructor") && (!Getattr(n,"allocate:has_destructor")) + && (Getattr(n,"allocate:default_destructor"))) { + addDestructor(n); + } + } + + if (dir) { classDirector(n); } /* check for abstract after resolving directors */ Abstract = abstractClassTest(n); + classHandler(n); } else { Abstract = abstractClassTest(n); @@ -2054,97 +2214,13 @@ int Language::classDeclaration(Node *n) { /* ---------------------------------------------------------------------- * Language::classHandler() * ---------------------------------------------------------------------- */ -static Node *makeCopyConstructor(Node *n) -{ - Node *cn = NewHash(); - set_nodeType(cn,"constructor"); - String *name = Getattr(n,"name"); - String *symname = Getattr(n,"sym:name"); - String *cc = NewStringf("r.q(const).%s", name); - String *decl = NewStringf("f(%s).",cc); - Parm *p = NewParm(cc,""); - Setattr(cn,"name",name); - Setattr(cn,"sym:name",symname); - SetFlag(cn,"feature:new"); - Setattr(cn,"decl",decl); - Setattr(cn,"parentNode",n); - Setattr(cn,"parms",p); - Setattr(cn,"copy_constructor","1"); - Setattr(cn,"allocate:copy_constructor","1"); - Symtab *oldscope = Swig_symbol_setscope(Getattr(n,"symtab")); - Swig_symbol_add(symname, cn); - Swig_symbol_setscope(oldscope); - return cn; -} -/* -static Node *makeConstructor(Node *n) -{ - Node *cn = NewHash(); - set_nodeType(cn,"constructor"); - String *name = Getattr(n,"name"); - String *symname = Getattr(n,"sym:name"); - Setattr(cn,"name",name); - Setattr(cn,"sym:name",symname); - SetFlag(cn,"feature:new"); - Setattr(cn,"decl","f()."); - Setattr(cn,"parentNode",n); - Symtab *oldscope = Swig_symbol_setscope(Getattr(n,"symtab")); - Swig_symbol_add(symname, cn); - Swig_symbol_setscope(oldscope); - return cn; -} -*/ - -static Node *makeConstructor(Node *n) -{ - Node *cn = Copy(n); - String *name = Getattr(n,"name"); - String *rname = 0; - String *dname = NewStringf("%s::",name); - - if (SwigType_istemplate(name)) { - rname = SwigType_templateprefix(name); - name = rname; - } - String *lname = Swig_scopename_last(name); - Append(dname,lname); - SetFlag(cn,"feature:new"); - Setattr(cn,"decl","f()."); - Swig_features_get(Swig_cparse_features(), 0, dname, Getattr(cn,"decl"), cn); - Delete(rname); - Delete(dname); - Delete(lname); - - return cn; -} - -static Node *makeDestructor(Node *n) -{ - Node *cn = Copy(n); - String *name = Getattr(n,"name"); - String *rname = 0; - String *dname = NewStringf("%s::~",name); - - if (SwigType_istemplate(name)) { - rname = SwigType_templateprefix(name); - name = rname; - } - String *lname = Swig_scopename_last(name); - Append(dname,lname); - Setattr(cn,"decl","f()."); - Swig_features_get(Swig_cparse_features(), 0, dname, Getattr(cn,"decl"), cn); - Delete(rname); - Delete(dname); - Delete(lname); - - return cn; -} - int Language::classHandler(Node *n) { bool hasDirector = Swig_directorclass(n) ? true : false; + + /* Emit all of the class members */ emit_children(n); @@ -2161,25 +2237,6 @@ int Language::classHandler(Node *n) { } cplus_mode = PUBLIC; - int odefault = (GenerateDefault && !GetFlag(n,"feature:nodefault")); - if (!ImportMode && (GenerateDefault && !GetFlag(n,"feature:nodefault"))) { - if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) { - /* Note: will need to change this to support different kinds of classes */ - if (!Abstract) { - Node *cn = makeConstructor(CurrentClass); - constructorHandler(cn); - Delete(cn); - } - } - } - if (!ImportMode && !GetFlag(n,"feature:nodefaultdtor") && odefault) { - if (!Getattr(n,"has_destructor") && (!Getattr(n,"allocate:has_destructor")) - && (Getattr(n,"allocate:default_destructor"))) { - Node *cn = makeDestructor(CurrentClass); - destructorHandler(cn); - Delete(cn); - } - } /* emit director disown method */ if (hasDirector) { @@ -2238,6 +2295,21 @@ int Language::constructorDeclaration(Node *n) { if (!CurrentClass) return SWIG_NOWRAP; if (ImportMode) return SWIG_NOWRAP; + if (Extend) { + /* extend default constructor can be safetly ignored if there is + already one */ + int num_required = ParmList_numrequired(Getattr(n,"parms")); + if ((num_required == 0) && Getattr(CurrentClass,"has_default_constructor")) { + return SWIG_NOWRAP; + } + if ((num_required == 1) && Getattr(CurrentClass,"has_copy_constructor")) { + String *ccdecl = Getattr(CurrentClass,"copy_constructor_decl"); + if (ccdecl && (Strcmp(ccdecl,Getattr(n,"decl")) == 0)) { + return SWIG_NOWRAP; + } + } + } + /* clean protected overloaded constructors, in case they are not needed anymore */ Node *over = Swig_symbol_isoverloaded(n); @@ -2410,6 +2482,13 @@ int Language::destructorDeclaration(Node *n) { if (cplus_mode != PUBLIC) return SWIG_NOWRAP; if (ImportMode) return SWIG_NOWRAP; + if (Extend) { + /* extend destructor can be safetly ignored if there is already one */ + if (Getattr(CurrentClass,"has_destructor")) { + return SWIG_NOWRAP; + } + } + Swig_save("destructorDeclaration",n,"name", "sym:name",NIL); char *c = GetChar(n,"name");