Date: Fri, 23 Oct 2009 06:48:38 +0000
Subject: [PATCH 045/146] Document improved template explicit specialization
and partial specialization
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11713 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Doc/Manual/SWIGPlus.html | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index f3befa54b..f318af6a3 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -3246,22 +3246,39 @@ public:
-SWIG should be able to handle most simple uses of partial specialization. However, it may fail
-to match templates properly in more complicated cases. For example, if you have this code,
+SWIG supports both template explicit specialization and partial specialization. Consider:
-template<class T1, class T2> class Foo<T1, T2 *> { };
+template<class T1, class T2> class Foo { }; // (1) primary template
+template<> class Foo<double *, int *> { }; // (2) explicit specialization
+template<class T1, class T2> class Foo<T1, T2 *> { }; // (3) partial specialization
-SWIG isn't able to match it properly for instantiations like Foo<int *, int *>.
-This problem is not due to parsing, but due to the fact that SWIG does not currently implement all
-of the C++ argument deduction rules.
+SWIG is able to properly match explicit instantiations:
+
+
+Foo<double *, int *> // explicit specialization matching (2)
+
+
+
+
+SWIG implements template argument deduction so that the following partial specialization examples work just like they would with a C++ compiler:
+
+
+
+
+Foo<int *, int *> // partial specialization matching (3)
+Foo<int *, const int *> // partial specialization matching (3)
+Foo<int *, int **> // partial specialization matching (3)
+
+
+
Member function templates are supported. The underlying principle is the same
as for normal templates--SWIG can't create a wrapper unless you provide
From 283fd3c7ec13662f36653480996a32d357b20482 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 24 Oct 2009 21:58:06 +0000
Subject: [PATCH 046/146] minor improvement to testcase
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11715 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
.../java/template_nested_typemaps_runme.java | 2 ++
Examples/test-suite/template_nested_typemaps.i | 14 +++++++++++---
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/Examples/test-suite/java/template_nested_typemaps_runme.java b/Examples/test-suite/java/template_nested_typemaps_runme.java
index 3bd8aa1df..443faca4f 100644
--- a/Examples/test-suite/java/template_nested_typemaps_runme.java
+++ b/Examples/test-suite/java/template_nested_typemaps_runme.java
@@ -21,6 +21,7 @@ public class template_nested_typemaps_runme {
if (template_nested_typemaps.globalInt1(v) != v) throw new RuntimeException("failed");
if (template_nested_typemaps.globalInt2(v) != v) throw new RuntimeException("failed");
+ if (template_nested_typemaps.globalInt3(v) != vTypemap) throw new RuntimeException("failed");
}
{
@@ -31,6 +32,7 @@ public class template_nested_typemaps_runme {
if (template_nested_typemaps.globalShort1(v) != v) throw new RuntimeException("failed");
if (template_nested_typemaps.globalShort2(v) != v) throw new RuntimeException("failed");
+ if (template_nested_typemaps.globalShort3(v) != vTypemap) throw new RuntimeException("failed");
}
}
}
diff --git a/Examples/test-suite/template_nested_typemaps.i b/Examples/test-suite/template_nested_typemaps.i
index 8ed02eaea..54f5bc503 100644
--- a/Examples/test-suite/template_nested_typemaps.i
+++ b/Examples/test-suite/template_nested_typemaps.i
@@ -2,12 +2,14 @@
%module template_nested_typemaps
+// Testing that the typemaps invoked within a class via %template are picked up by appropriate methods
+
template struct Typemap {
%typemap(in) T {
$1 = -99;
}
};
-template <> struct Typemap {
+template <> struct Typemap { // Note explicit specialization
%typemap(in) short {
$1 = -77;
}
@@ -22,14 +24,14 @@ template struct Breeze {
#if defined(SWIG)
%template() Typemap;
#endif
- int methodInt2(int s) { return s; } // only this method should pick up the typemap within Typemap
+ int methodInt2(int s) { return s; } // should pick up the typemap within Typemap
void takeIt(T t) {}
short methodShort1(short s) { return s; }
#if defined(SWIG)
%template(TypemapShort) Typemap; // should issue warning SWIGWARN_PARSE_NESTED_TEMPLATE
#endif
- short methodShort2(short s) { return s; } // only this method should pick up the typemap within Typemap - note specialization
+ short methodShort2(short s) { return s; } // should pick up the typemap within Typemap
};
int globalInt2(int s) { return s; }
@@ -37,3 +39,9 @@ short globalShort2(short s) { return s; }
%}
%template(BreezeString) Breeze;
+
+%inline %{
+int globalInt3(int s) { return s; } // should pick up the typemap within Typemap
+short globalShort3(short s) { return s; } // should pick up the typemap within Typemap
+%}
+
From 70e8072612c4f1229b11047fca8f2141dd664ba5 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Mon, 2 Nov 2009 06:31:45 +0000
Subject: [PATCH 047/146] [Python] Fix potential memory leak in initialisation
code for the generated module.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11717 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 4 ++++
Lib/python/pyinit.swg | 18 +++++++++---------
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index b8565d9cd..692c0522c 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,10 @@
Version 1.3.41 (in progress)
============================
+2009-11-02: olly
+ [Python] Fix potential memory leak in initialisation code for the
+ generated module.
+
2009-10-23: wsfulton
Fix seg fault when using a named nested template instantiation using %template(name)
within a class. A warning that these are not supported is now issued plus processing
diff --git a/Lib/python/pyinit.swg b/Lib/python/pyinit.swg
index 058934b04..5af8d2491 100644
--- a/Lib/python/pyinit.swg
+++ b/Lib/python/pyinit.swg
@@ -279,15 +279,15 @@ SWIG_Python_FixMethods(PyMethodDef *methods,
}
}
if (ci) {
- size_t shift = (ci->ptype) - types;
- swig_type_info *ty = types_initial[shift];
- size_t ldoc = (c - methods[i].ml_doc);
- size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
- char *ndoc = (char*)malloc(ldoc + lptr + 10);
- if (ndoc) {
- char *buff = ndoc;
- void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
- if (ptr) {
+ void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
+ if (ptr) {
+ size_t shift = (ci->ptype) - types;
+ swig_type_info *ty = types_initial[shift];
+ size_t ldoc = (c - methods[i].ml_doc);
+ size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
+ char *ndoc = (char*)malloc(ldoc + lptr + 10);
+ if (ndoc) {
+ char *buff = ndoc;
strncpy(buff, methods[i].ml_doc, ldoc);
buff += ldoc;
strncpy(buff, "swig_ptr: ", 10);
From da1fc3ab8f30e097f17a056db023b099b383c68c Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 3 Nov 2009 19:14:37 +0000
Subject: [PATCH 048/146] Fix some usage of global scope operator ::
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11719 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 22 +++++++++++++++++++
.../template_partial_specialization.i | 2 ++
Examples/test-suite/using_namespace.i | 11 ++++++++++
Examples/test-suite/valuewrapper_const.i | 6 +++++
Source/Swig/symbol.c | 8 +++++++
5 files changed, 49 insertions(+)
diff --git a/CHANGES.current b/CHANGES.current
index 692c0522c..0f5f6be84 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,28 @@
Version 1.3.41 (in progress)
============================
+2009-11-03: wsfulton
+ Fix some usage of global scope operator, for example:
+
+ namespace AA { /* ... */ }
+ using namespace ::AA;
+
+ and bug #1816802 - SwigValueWrapper should be used ::
+
+ struct CC {
+ CC(int); // no default constructor
+ };
+ ::CC x();
+
+ and in template parameter specializations:
+
+ struct S {};
+ template struct X { void a() {}; };
+ template <> struct X { void b() {}; };
+ %template(MyTConcrete) X< ::S >;
+
+ plus probably some other corner case usage of ::.
+
2009-11-02: olly
[Python] Fix potential memory leak in initialisation code for the
generated module.
diff --git a/Examples/test-suite/template_partial_specialization.i b/Examples/test-suite/template_partial_specialization.i
index a81bc47a5..8781fbbda 100644
--- a/Examples/test-suite/template_partial_specialization.i
+++ b/Examples/test-suite/template_partial_specialization.i
@@ -69,6 +69,7 @@ namespace Two {
template struct TwoParm { void e() {} };
template struct TwoParm { void f() {} };
template <> struct TwoParm { void g() {} };
+ template <> struct TwoParm { void h() {} };
}
%}
@@ -90,6 +91,7 @@ namespace Two {
%template(B1_) ::Two::TwoParm;
%template(E1_) Two::TwoParm;
%template(E2_) Two::TwoParm;
+%template(H_) Two::TwoParm< ::Concrete, ::Concrete * >;
// Many template parameters
diff --git a/Examples/test-suite/using_namespace.i b/Examples/test-suite/using_namespace.i
index 799c7cfb5..ce02e9a87 100644
--- a/Examples/test-suite/using_namespace.i
+++ b/Examples/test-suite/using_namespace.i
@@ -74,3 +74,14 @@ struct X {
};
}
+
+%inline %{
+namespace SpaceMan {
+ typedef double SpaceManDouble;
+}
+using namespace ::SpaceMan; // global namespace prefix
+
+SpaceManDouble useSpaceMan(SpaceManDouble s) { return s; }
+
+%}
+
diff --git a/Examples/test-suite/valuewrapper_const.i b/Examples/test-suite/valuewrapper_const.i
index db1c807c8..3091df30e 100644
--- a/Examples/test-suite/valuewrapper_const.i
+++ b/Examples/test-suite/valuewrapper_const.i
@@ -24,6 +24,12 @@ public:
const B GetBconst() const {
return b;
}
+ ::B GetBGlobalQualifier() {
+ return b;
+ }
+ const ::B GetBconstGlobalGlobalQualifier() const {
+ return b;
+ }
};
%}
diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
index 055af854f..3f9ce86af 100644
--- a/Source/Swig/symbol.c
+++ b/Source/Swig/symbol.c
@@ -998,6 +998,8 @@ Node *Swig_symbol_clookup(const_String_or_char_ptr name, Symtab *n) {
String *nname = NewString(cname + 2);
if (Swig_scopename_check(nname)) {
s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0);
+ } else {
+ s = symbol_lookup(nname, global_scope, 0);
}
Delete(nname);
} else {
@@ -1070,6 +1072,8 @@ Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*
String *nname = NewString(cname + 2);
if (Swig_scopename_check(nname)) {
s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc);
+ } else {
+ s = symbol_lookup(nname, global_scope, checkfunc);
}
Delete(nname);
} else {
@@ -1134,6 +1138,8 @@ Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) {
String *nname = NewString(cname + 2);
if (Swig_scopename_check(nname)) {
s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0);
+ } else {
+ s = symbol_lookup(nname, global_scope, 0);
}
Delete(nname);
} else {
@@ -1182,6 +1188,8 @@ Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n,
String *nname = NewString(cname + 2);
if (Swig_scopename_check(nname)) {
s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc);
+ } else {
+ s = symbol_lookup(nname, global_scope, checkfunc);
}
Delete(nname);
} else {
From 57fff12d5f8e67be14218e3a1ed57e2291cc5c6b Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 3 Nov 2009 19:52:12 +0000
Subject: [PATCH 049/146] Fix seg fault for some template parameters which have
no type, just a default value
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11720 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Source/CParse/parser.y | 3 +++
Source/Swig/parms.c | 17 ++++++++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 4d4401572..b8691ab9c 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -2644,6 +2644,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
n = Swig_cparse_template_locate($5,$7,tscope);
/* Patch the argument types to respect namespaces */
+Printf(stdout, " p before patching: %s\n", ParmList_str_defaultargs($7));
p = $7;
while (p) {
SwigType *value = Getattr(p,"value");
@@ -2669,6 +2670,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
p = nextSibling(p);
}
+Printf(stdout, " p after patching: %s\n", ParmList_str_defaultargs($7));
/* Look for the template */
{
@@ -2746,6 +2748,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
def_supplied = 1;
}
}
+Printf(stdout, " p tempar patching: %s\n", ParmList_str_defaultargs(temparms));
templnode = copy_node(nn);
/* We need to set the node name based on name used to instantiate */
diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c
index 9b58f5fcb..6b0863ee4 100644
--- a/Source/Swig/parms.c
+++ b/Source/Swig/parms.c
@@ -114,6 +114,14 @@ int ParmList_len(ParmList *p) {
return i;
}
+/* ---------------------------------------------------------------------
+ * get_empty_type()
+ * ---------------------------------------------------------------------- */
+
+static SwigType *get_empty_type() {
+ return NewStringEmpty();
+}
+
/* ---------------------------------------------------------------------
* ParmList_str()
*
@@ -123,7 +131,8 @@ int ParmList_len(ParmList *p) {
String *ParmList_str(ParmList *p) {
String *out = NewStringEmpty();
while (p) {
- String *pstr = SwigType_str(Getattr(p, "type"), Getattr(p, "name"));
+ String *type = Getattr(p, "type");
+ String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name"));
Append(out, pstr);
p = nextSibling(p);
if (p) {
@@ -144,7 +153,8 @@ String *ParmList_str_defaultargs(ParmList *p) {
String *out = NewStringEmpty();
while (p) {
String *value = Getattr(p, "value");
- String *pstr = SwigType_str(Getattr(p, "type"), Getattr(p, "name"));
+ String *type = Getattr(p, "type");
+ String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name"));
Append(out, pstr);
if (value) {
Printf(out, "=%s", value);
@@ -167,7 +177,8 @@ String *ParmList_str_defaultargs(ParmList *p) {
String *ParmList_protostr(ParmList *p) {
String *out = NewStringEmpty();
while (p) {
- String *pstr = SwigType_str(Getattr(p, "type"), 0);
+ String *type = Getattr(p, "type");
+ String *pstr = SwigType_str(type ? type : get_empty_type(), 0);
Append(out, pstr);
p = nextSibling(p);
if (p) {
From dbe46033ee68af08508f84ddb08ba264cc8878ea Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 3 Nov 2009 19:57:35 +0000
Subject: [PATCH 050/146] remove debug in last commit
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11721 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Source/CParse/parser.y | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index b8691ab9c..4d4401572 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -2644,7 +2644,6 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
n = Swig_cparse_template_locate($5,$7,tscope);
/* Patch the argument types to respect namespaces */
-Printf(stdout, " p before patching: %s\n", ParmList_str_defaultargs($7));
p = $7;
while (p) {
SwigType *value = Getattr(p,"value");
@@ -2670,7 +2669,6 @@ Printf(stdout, " p before patching: %s\n", ParmList_str_defaultargs($7));
p = nextSibling(p);
}
-Printf(stdout, " p after patching: %s\n", ParmList_str_defaultargs($7));
/* Look for the template */
{
@@ -2748,7 +2746,6 @@ Printf(stdout, " p after patching: %s\n", ParmList_str_defaultargs($7));
def_supplied = 1;
}
}
-Printf(stdout, " p tempar patching: %s\n", ParmList_str_defaultargs(temparms));
templnode = copy_node(nn);
/* We need to set the node name based on name used to instantiate */
From e351dfceaf5b1869fcda492c427149577056e1fe Mon Sep 17 00:00:00 2001
From: Joseph Wang
Date: Wed, 4 Nov 2009 03:48:17 +0000
Subject: [PATCH 051/146] first pass at making fcompact work with R
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11722 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Lib/r/rtype.swg | 16 ++++++++--------
Source/Modules/r.cxx | 34 +++++++++++++++++-----------------
2 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/Lib/r/rtype.swg b/Lib/r/rtype.swg
index d388d1eae..04441c03f 100644
--- a/Lib/r/rtype.swg
+++ b/Lib/r/rtype.swg
@@ -100,30 +100,30 @@
long *,
long &,
long[ANY]
- "$input = as.integer($input) ";
+ "$input = as.integer($input); ";
%typemap(scoercein) char *, string, std::string,
string &, std::string &
-%{ $input = as($input, "character") %}
+%{ $input = as($input, "character"); %}
%typemap(scoerceout) enum SWIGTYPE
- %{ $result = enumFromInteger($result, "$R_class") %}
+ %{ $result = enumFromInteger($result, "$R_class"); %}
%typemap(scoerceout) enum SWIGTYPE &
- %{ $result = enumFromInteger($result, "$R_class") %}
+ %{ $result = enumFromInteger($result, "$R_class"); %}
%typemap(scoerceout) enum SWIGTYPE *
- %{ $result = enumToInteger($result, "$R_class") %}
+ %{ $result = enumToInteger($result, "$R_class"); %}
%typemap(scoerceout) SWIGTYPE
- %{ class($result) <- "$&R_class" %}
+ %{ class($result) <- "$&R_class"; %}
%typemap(scoerceout) SWIGTYPE &
- %{ class($result) <- "$R_class" %}
+ %{ class($result) <- "$R_class"; %}
%typemap(scoerceout) SWIGTYPE *
- %{ class($result) <- "$R_class" %}
+ %{ class($result) <- "$R_class"; %}
/* Override the SWIGTYPE * above. */
%typemap(scoerceout) char,
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
index c48e2e266..e142c3bee 100644
--- a/Source/Modules/r.cxx
+++ b/Source/Modules/r.cxx
@@ -1101,7 +1101,7 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
Delete(pitem);
}
Delete(itemList);
- Printf(f->code, ")\n");
+ Printf(f->code, ");\n");
if (!isSet && varaccessor > 0) {
Printf(f->code, "%svaccessors = c(", tab8);
@@ -1117,7 +1117,7 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
Printf(f->code, "'%s'%s", item, vcount < varaccessor ? ", " : "");
}
}
- Printf(f->code, ")\n");
+ Printf(f->code, ");\n");
}
@@ -1129,24 +1129,24 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
"stop(\"No ", (isSet ? "modifiable" : "accessible"), " field named \", name, \" in ", className,
": fields are \", paste(names(accessorFuns), sep = \", \")",
")", "\n}\n", NIL); */
- Printv(f->code, tab8,
- "idx = pmatch(name, names(accessorFuns))\n",
+ Printv(f->code, ";", tab8,
+ "idx = pmatch(name, names(accessorFuns));\n",
tab8,
"if(is.na(idx)) \n",
tab8, tab4, NIL);
- Printf(f->code, "return(callNextMethod(x, name%s))\n",
+ Printf(f->code, "return(callNextMethod(x, name%s));\n",
isSet ? ", value" : "");
- Printv(f->code, tab8, "f = accessorFuns[[idx]]\n", NIL);
+ Printv(f->code, tab8, "f = accessorFuns[[idx]];\n", NIL);
if(isSet) {
- Printv(f->code, tab8, "f(x, value)\n", NIL);
- Printv(f->code, tab8, "x\n", NIL); // make certain to return the S value.
+ Printv(f->code, tab8, "f(x, value);\n", NIL);
+ Printv(f->code, tab8, "x;\n", NIL); // make certain to return the S value.
} else {
- Printv(f->code, tab8, "formals(f)[[1]] = x\n", NIL);
+ Printv(f->code, tab8, "formals(f)[[1]] = x;\n", NIL);
if (varaccessor) {
Printv(f->code, tab8,
- "if (is.na(match(name, vaccessors))) f else f(x)\n", NIL);
+ "if (is.na(match(name, vaccessors))) f else f(x);\n", NIL);
} else {
- Printv(f->code, tab8, "f\n", NIL);
+ Printv(f->code, tab8, "f;\n", NIL);
}
}
Printf(f->code, "}\n");
@@ -1157,15 +1157,15 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
isSet ? "<-" : "",
getRClassName(className));
Wrapper_print(f, out);
- Printf(out, ")\n");
+ Printf(out, ");\n");
if(isSet) {
Printf(out, "setMethod('[[<-', c('_p%s', 'character'),",
getRClassName(className));
- Insert(f->code, 2, "name = i\n");
+ Insert(f->code, 2, "name = i;\n");
Printf(attr->code, "%s", f->code);
Wrapper_print(attr, out);
- Printf(out, ")\n");
+ Printf(out, ");\n");
}
DelWrapper(attr);
@@ -2090,10 +2090,10 @@ int R::functionWrapper(Node *n) {
}
- Printv(sfun->code, (Len(tm) ? "ans = " : ""), ".Call('", wname,
- "', ", sargs, "PACKAGE='", Rpackage, "')\n", NIL);
+ Printv(sfun->code, ";", (Len(tm) ? "ans = " : ""), ".Call('", wname,
+ "', ", sargs, "PACKAGE='", Rpackage, "');\n", NIL);
if(Len(tm))
- Printf(sfun->code, "%s\n\nans\n", tm);
+ Printf(sfun->code, "%s\n\nans;\n", tm);
if (destructor)
Printv(f->code, "R_ClearExternalPtr(self);\n", NIL);
From 9683047b9a5f6975f2470858a311de9f885a2db7 Mon Sep 17 00:00:00 2001
From: Joseph Wang
Date: Wed, 4 Nov 2009 03:50:09 +0000
Subject: [PATCH 052/146] move fPIC location to be in front of -o
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11723 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Examples/Makefile.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index 561f7cc29..3516d6f28 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -1124,7 +1124,7 @@ RRSRC = $(INTERFACE:.i=.R)
r: $(SRCS)
$(SWIG) -r $(SWIGOPT) $(INTERFACEPATH)
- +( PKG_LIBS="$(SRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o -fPIC $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) )
+ +( PKG_LIBS="$(SRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -fPIC -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) )
r_cpp: $(CXXSRCS)
$(SWIG) -c++ -r $(SWIGOPT) -o $(RCXXSRCS) $(INTERFACEPATH)
From 64d1b6f0c650ac7a84e182cee4cc965271131f76 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 4 Nov 2009 22:49:39 +0000
Subject: [PATCH 053/146] Add -debug-symtabs and -debug-qsymtabs options for
debugging symbol tables
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11724 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 6 +++++
Doc/Manual/Extending.html | 2 ++
Source/CParse/parser.y | 14 +++-------
Source/Modules/main.cxx | 18 +++++++++++++
Source/Swig/swig.h | 3 +++
Source/Swig/symbol.c | 56 +++++++++++++++++++++++++++------------
6 files changed, 72 insertions(+), 27 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 0f5f6be84..b577367db 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,12 @@
Version 1.3.41 (in progress)
============================
+2009-11-04: wsfulton
+ Add new debug options:
+ -debug-symtabs - Display symbol tables information
+ -debug-qsymtabs - Display symbol tables summary information using fully
+ qualified names
+
2009-11-03: wsfulton
Fix some usage of global scope operator, for example:
diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html
index 111644e7f..11578db97 100644
--- a/Doc/Manual/Extending.html
+++ b/Doc/Manual/Extending.html
@@ -3598,6 +3598,8 @@ There are various command line options which can aid debugging a SWIG interface
-debug-classes - Display information about the classes found in the interface
-debug-module <n> - Display module parse tree at stages 1-4, <n> is a csv list of stages
+-debug-symtabs - Display symbol tables information
+-debug-qsymtabs - Display symbol tables summary information using fully qualified names
-debug-tags - Display information about the tags found in the interface
-debug-template - Display information for debugging templates
-debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 4d4401572..954b7af77 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -817,14 +817,8 @@ static List *make_inherit_list(String *clsname, List *names) {
/* If the class name is qualified. We need to create or lookup namespace entries */
-static Symtab *get_global_scope() {
- Symtab *symtab = Swig_symbol_current();
- Node *pn = parentNode(symtab);
- while (pn) {
- symtab = pn;
- pn = parentNode(symtab);
- if (!pn) break;
- }
+static Symtab *set_scope_to_global() {
+ Symtab *symtab = Swig_symbol_global_scope();
Swig_symbol_setscope(symtab);
return symtab;
}
@@ -869,11 +863,11 @@ static String *resolve_node_scope(String *cname) {
String *nprefix = NewString(Char(prefix)+2);
Delete(prefix);
prefix= nprefix;
- gscope = get_global_scope();
+ gscope = set_scope_to_global();
}
if (!prefix || (Len(prefix) == 0)) {
/* Use the global scope, but we need to add a 'global' namespace. */
- if (!gscope) gscope = get_global_scope();
+ if (!gscope) gscope = set_scope_to_global();
/* note that this namespace is not the "unnamed" one,
and we don't use Setattr(nscope,"name", ""),
because the unnamed namespace is private */
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index c824db6f9..30e8eb18a 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -62,6 +62,8 @@ static const char *usage1 = (const char *) "\
-copyright - Display copyright notices\n\
-debug-classes - Display information about the classes found in the interface\n\
-debug-module - Display module parse tree at stages 1-4, is a csv list of stages\n\
+ -debug-symtabs - Display symbol tables information\n\
+ -debug-qsymtabs - Display symbol tables summary information using fully qualified names\n\
-debug-tags - Display information about the tags found in the interface\n\
-debug-template - Display information for debugging templates\n\
-debug-top - Display entire parse tree at stages 1-4, is a csv list of stages\n\
@@ -162,6 +164,8 @@ static int no_cpp = 0;
static char *outfile_name = 0;
static char *outfile_name_h = 0;
static int tm_debug = 0;
+static int dump_symtabs = 0;
+static int dump_qsymtabs = 0;
static int dump_tags = 0;
static int dump_module = 0;
static int dump_top = 0;
@@ -716,6 +720,12 @@ void SWIG_getoptions(int argc, char *argv[]) {
} else if (strncmp(argv[i], "-w", 2) == 0) {
Swig_mark_arg(i);
Swig_warnfilter(argv[i] + 2, 1);
+ } else if (strcmp(argv[i], "-debug-symtabs") == 0) {
+ dump_symtabs = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-debug-qsymtabs") == 0) {
+ dump_qsymtabs = 1;
+ Swig_mark_arg(i);
} else if ((strcmp(argv[i], "-debug-tags") == 0) || (strcmp(argv[i], "-dump_tags") == 0)) {
dump_tags = 1;
Swig_mark_arg(i);
@@ -1145,6 +1155,14 @@ int SWIG_main(int argc, char *argv[], Language *l) {
SwigType_print_scope(0);
}
+ if (dump_symtabs) {
+ Swig_symbol_tables_print(Swig_symbol_global_scope());
+ }
+
+ if (dump_qsymtabs) {
+ Swig_symbol_tables_summary_print();
+ }
+
if (dump_tags) {
Swig_print_tags(top, 0);
}
diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
index a5f13bd77..e415493a0 100644
--- a/Source/Swig/swig.h
+++ b/Source/Swig/swig.h
@@ -200,6 +200,8 @@ extern "C" {
/* --- Symbol table module --- */
+ extern void Swig_symbol_tables_print(Symtab *symtab);
+ extern void Swig_symbol_tables_summary_print(void);
extern void Swig_symbol_init(void);
extern void Swig_symbol_setscopename(const_String_or_char_ptr name);
extern String *Swig_symbol_getscopename(void);
@@ -207,6 +209,7 @@ extern "C" {
extern Symtab *Swig_symbol_newscope(void);
extern Symtab *Swig_symbol_setscope(Symtab *);
extern Symtab *Swig_symbol_getscope(const_String_or_char_ptr symname);
+ extern Symtab *Swig_symbol_global_scope(void);
extern Symtab *Swig_symbol_current(void);
extern Symtab *Swig_symbol_popscope(void);
extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *node);
diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
index 3f9ce86af..a13361aa8 100644
--- a/Source/Swig/symbol.c
+++ b/Source/Swig/symbol.c
@@ -175,20 +175,32 @@ static Hash *global_scope = 0; /* Global scope */
/* common attribute keys, to avoid calling find_key all the times */
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_tables_print()
+ *
+ * Debug display of symbol tables
+ * ----------------------------------------------------------------------------- */
-#if 0
-void Swig_symbol_dump_symtable() {
- Printf(stdout, "DUMPING SYMTABLE start =======================================\n");
- {
- Hash *cst = Getattr(current_symtab, "csymtab");
- Swig_print_tree(cst);
- /*
- Swig_print_tree(Getattr(cst, "NumSpace"));
- */
- }
- Printf(stdout, "DUMPING SYMTABLE end =======================================\n");
+void Swig_symbol_tables_print(Symtab *symtab) {
+ if (!symtab)
+ symtab = current_symtab;
+
+ Printf(stdout, "SYMBOL TABLES start =======================================\n");
+ Swig_print_tree(symtab);
+ Printf(stdout, "SYMBOL TABLES finish =======================================\n");
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_tables_summary_print()
+ *
+ * Debug summary display of all symbol tables by fully-qualified name
+ * ----------------------------------------------------------------------------- */
+
+void Swig_symbol_tables_summary_print(void) {
+ Printf(stdout, "SYMBOL TABLES SUMMARY start =======================================\n");
+ Swig_print_node(symtabs);
+ Printf(stdout, "SYMBOL TABLES SUMMARY finish =======================================\n");
}
-#endif
/* -----------------------------------------------------------------------------
* Swig_symbol_init()
@@ -196,7 +208,7 @@ void Swig_symbol_dump_symtable() {
* Create a new symbol table object
* ----------------------------------------------------------------------------- */
-void Swig_symbol_init() {
+void Swig_symbol_init(void) {
current = NewHash();
current_symtab = NewHash();
@@ -240,7 +252,7 @@ void Swig_symbol_setscopename(const_String_or_char_ptr name) {
* Get the C scopename of the current symbol table
* ----------------------------------------------------------------------------- */
-String *Swig_symbol_getscopename() {
+String *Swig_symbol_getscopename(void) {
return Getattr(current_symtab, "name");
}
@@ -295,7 +307,7 @@ String *Swig_symbol_qualifiedscopename(Symtab *symtab) {
* Create a new scope. Returns the newly created scope.
* ----------------------------------------------------------------------------- */
-Symtab *Swig_symbol_newscope() {
+Symtab *Swig_symbol_newscope(void) {
Hash *n;
Hash *hsyms, *h;
@@ -346,7 +358,7 @@ Symtab *Swig_symbol_setscope(Symtab *sym) {
* scope to the parent scope.
* ----------------------------------------------------------------------------- */
-Symtab *Swig_symbol_popscope() {
+Symtab *Swig_symbol_popscope(void) {
Hash *h = current_symtab;
current_symtab = Getattr(current_symtab, "parentNode");
assert(current_symtab);
@@ -357,13 +369,23 @@ Symtab *Swig_symbol_popscope() {
return h;
}
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_global_scope()
+ *
+ * Return the symbol table for the global scope.
+ * ----------------------------------------------------------------------------- */
+
+Symtab *Swig_symbol_global_scope(void) {
+ return global_scope;
+}
+
/* -----------------------------------------------------------------------------
* Swig_symbol_current()
*
* Return the current symbol table.
* ----------------------------------------------------------------------------- */
-Symtab *Swig_symbol_current() {
+Symtab *Swig_symbol_current(void) {
return current_symtab;
}
From deba0e9285e15396c84314bbdb18bc44d99ef30c Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 7 Nov 2009 20:44:20 +0000
Subject: [PATCH 054/146] re-organise symbol debugging options - add in
-debug-symbols and -debug-csymbols, and remove -debug-qsymtab
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11726 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 8 +++---
Doc/Manual/Extending.html | 39 ++++++++++++++-------------
Source/Modules/main.cxx | 24 ++++++++++++-----
Source/Swig/swig.h | 6 +++--
Source/Swig/symbol.c | 56 ++++++++++++++++++++++++++++++++++++---
5 files changed, 97 insertions(+), 36 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index b577367db..67d9f9aa1 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,11 +1,11 @@
Version 1.3.41 (in progress)
============================
-2009-11-04: wsfulton
+2009-11-07: wsfulton
Add new debug options:
- -debug-symtabs - Display symbol tables information
- -debug-qsymtabs - Display symbol tables summary information using fully
- qualified names
+ -debug-symtabs - Display symbol tables information
+ -debug-symbols - Display target language symbols in the symbol tables
+ -debug-csymbols - Display C symbols in the symbol tables
2009-11-03: wsfulton
Fix some usage of global scope operator, for example:
diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html
index 11578db97..040eb65c7 100644
--- a/Doc/Manual/Extending.html
+++ b/Doc/Manual/Extending.html
@@ -2604,24 +2604,24 @@ void Language::main(int argc, char *argv[]) {
} else {
Swig_arg_error();
}
- } else if (strcmp(argv[i],"-globals") == 0) {
- if (argv[i+1]) {
- global_name = NewString(argv[i+1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i+1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if ( (strcmp(argv[i],"-proxy") == 0)) {
- proxy_flag = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-keyword") == 0) {
- use_kw = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-help") == 0) {
- fputs(usage,stderr);
- }
+ } else if (strcmp(argv[i],"-globals") == 0) {
+ if (argv[i+1]) {
+ global_name = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if ( (strcmp(argv[i],"-proxy") == 0)) {
+ proxy_flag = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-keyword") == 0) {
+ use_kw = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-help") == 0) {
+ fputs(usage,stderr);
+ }
...
}
}
@@ -3599,7 +3599,8 @@ There are various command line options which can aid debugging a SWIG interface
-debug-classes - Display information about the classes found in the interface
-debug-module <n> - Display module parse tree at stages 1-4, <n> is a csv list of stages
-debug-symtabs - Display symbol tables information
--debug-qsymtabs - Display symbol tables summary information using fully qualified names
+-debug-symbols - Display target language symbols in the symbol tables
+-debug-csymbols - Display C symbols in the symbol tables
-debug-tags - Display information about the tags found in the interface
-debug-template - Display information for debugging templates
-debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index 30e8eb18a..30d12f26b 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -63,7 +63,8 @@ static const char *usage1 = (const char *) "\
-debug-classes - Display information about the classes found in the interface\n\
-debug-module - Display module parse tree at stages 1-4, is a csv list of stages\n\
-debug-symtabs - Display symbol tables information\n\
- -debug-qsymtabs - Display symbol tables summary information using fully qualified names\n\
+ -debug-symbols - Display target language symbols in the symbol tables\n\
+ -debug-csymbols - Display C symbols in the symbol tables\n\
-debug-tags - Display information about the tags found in the interface\n\
-debug-template - Display information for debugging templates\n\
-debug-top - Display entire parse tree at stages 1-4, is a csv list of stages\n\
@@ -165,7 +166,8 @@ static char *outfile_name = 0;
static char *outfile_name_h = 0;
static int tm_debug = 0;
static int dump_symtabs = 0;
-static int dump_qsymtabs = 0;
+static int dump_symbols = 0;
+static int dump_csymbols = 0;
static int dump_tags = 0;
static int dump_module = 0;
static int dump_top = 0;
@@ -723,8 +725,11 @@ void SWIG_getoptions(int argc, char *argv[]) {
} else if (strcmp(argv[i], "-debug-symtabs") == 0) {
dump_symtabs = 1;
Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-debug-qsymtabs") == 0) {
- dump_qsymtabs = 1;
+ } else if (strcmp(argv[i], "-debug-symbols") == 0) {
+ dump_symbols = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-debug-csymbols") == 0) {
+ dump_csymbols = 1;
Swig_mark_arg(i);
} else if ((strcmp(argv[i], "-debug-tags") == 0) || (strcmp(argv[i], "-dump_tags") == 0)) {
dump_tags = 1;
@@ -1156,11 +1161,16 @@ int SWIG_main(int argc, char *argv[], Language *l) {
}
if (dump_symtabs) {
- Swig_symbol_tables_print(Swig_symbol_global_scope());
+ Swig_symbol_print_tables(Swig_symbol_global_scope());
+ Swig_symbol_print_tables_summary();
}
- if (dump_qsymtabs) {
- Swig_symbol_tables_summary_print();
+ if (dump_symbols) {
+ Swig_symbol_print_symbols();
+ }
+
+ if (dump_csymbols) {
+ Swig_symbol_print_csymbols();
}
if (dump_tags) {
diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
index e415493a0..33f977b52 100644
--- a/Source/Swig/swig.h
+++ b/Source/Swig/swig.h
@@ -200,8 +200,10 @@ extern "C" {
/* --- Symbol table module --- */
- extern void Swig_symbol_tables_print(Symtab *symtab);
- extern void Swig_symbol_tables_summary_print(void);
+ extern void Swig_symbol_print_tables(Symtab *symtab);
+ extern void Swig_symbol_print_tables_summary(void);
+ extern void Swig_symbol_print_symbols(void);
+ extern void Swig_symbol_print_csymbols(void);
extern void Swig_symbol_init(void);
extern void Swig_symbol_setscopename(const_String_or_char_ptr name);
extern String *Swig_symbol_getscopename(void);
diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
index a13361aa8..ae8a274c6 100644
--- a/Source/Swig/symbol.c
+++ b/Source/Swig/symbol.c
@@ -176,12 +176,12 @@ static Hash *global_scope = 0; /* Global scope */
/* -----------------------------------------------------------------------------
- * Swig_symbol_tables_print()
+ * Swig_symbol_print_tables()
*
* Debug display of symbol tables
* ----------------------------------------------------------------------------- */
-void Swig_symbol_tables_print(Symtab *symtab) {
+void Swig_symbol_print_tables(Symtab *symtab) {
if (!symtab)
symtab = current_symtab;
@@ -191,17 +191,65 @@ void Swig_symbol_tables_print(Symtab *symtab) {
}
/* -----------------------------------------------------------------------------
- * Swig_symbol_tables_summary_print()
+ * Swig_symbol_print_tables_summary()
*
* Debug summary display of all symbol tables by fully-qualified name
* ----------------------------------------------------------------------------- */
-void Swig_symbol_tables_summary_print(void) {
+void Swig_symbol_print_tables_summary(void) {
Printf(stdout, "SYMBOL TABLES SUMMARY start =======================================\n");
Swig_print_node(symtabs);
Printf(stdout, "SYMBOL TABLES SUMMARY finish =======================================\n");
}
+/* -----------------------------------------------------------------------------
+ * symbol_print_symbols()
+ * ----------------------------------------------------------------------------- */
+
+static void symbol_print_symbols(const char *symboltabletype) {
+ Node *obj = symtabs;
+ Iterator ki = First(obj);
+ while (ki.key) {
+ String *k = ki.key;
+ Printf(stdout, "===================================================\n");
+ Printf(stdout, "%s -\n", k);
+ {
+ Symtab *symtab = Getattr(Getattr(obj, k), symboltabletype);
+ Iterator it = First(symtab);
+ while (it.key) {
+ String *symname = it.key;
+ Printf(stdout, " %s\n", symname);
+ it = Next(it);
+ }
+ }
+ ki = Next(ki);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_print_symbols()
+ *
+ * Debug display of all the target language symbols
+ * ----------------------------------------------------------------------------- */
+
+void Swig_symbol_print_symbols(void) {
+ Printf(stdout, "SYMBOLS start =======================================\n");
+ symbol_print_symbols("symtab");
+ Printf(stdout, "SYMBOLS finish =======================================\n");
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_print_csymbols()
+ *
+ * Debug display of all the C symbols
+ * ----------------------------------------------------------------------------- */
+
+void Swig_symbol_print_csymbols(void) {
+ Printf(stdout, "CSYMBOLS start =======================================\n");
+ symbol_print_symbols("csymtab");
+ Printf(stdout, "CSYMBOLS finish =======================================\n");
+}
+
/* -----------------------------------------------------------------------------
* Swig_symbol_init()
*
From ec6bf1ec9625f5f9cd42d619369c1cd35e65092d Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 8 Nov 2009 00:14:47 +0000
Subject: [PATCH 055/146] Fix nested template classes within a namespace
generating uncompileable code by incorrectly adding in symbols into the
symbol tables and not setting the scope correctly after the nested template
was parsed
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11727 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 7 +-
Examples/test-suite/common.mk | 1 +
.../java/template_nested_runme.java | 30 +
Examples/test-suite/template_nested.i | 91 +++
Source/CParse/parser.y | 704 +++++++++---------
5 files changed, 500 insertions(+), 333 deletions(-)
create mode 100644 Examples/test-suite/java/template_nested_runme.java
create mode 100644 Examples/test-suite/template_nested.i
diff --git a/CHANGES.current b/CHANGES.current
index 67d9f9aa1..8192f30b5 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,11 @@
Version 1.3.41 (in progress)
============================
+2009-11-07: wsfulton
+ Bug #1514681 - Fix nested template classes within a namespace generated uncompileable
+ code and introduced strange side effects to other wrapper code especially code
+ after the nested template class. Note that nested template classes are still ignored.
+
2009-11-07: wsfulton
Add new debug options:
-debug-symtabs - Display symbol tables information
@@ -13,7 +18,7 @@ Version 1.3.41 (in progress)
namespace AA { /* ... */ }
using namespace ::AA;
- and bug #1816802 - SwigValueWrapper should be used ::
+ and bug #1816802 - SwigValueWrapper should be used:
struct CC {
CC(int); // no default constructor
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 7bc5a9fa0..473d6579d 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -330,6 +330,7 @@ CPP_TEST_CASES += \
template_inherit_abstract \
template_int_const \
template_methods \
+ template_nested \
template_nested_typemaps \
template_ns \
template_ns2 \
diff --git a/Examples/test-suite/java/template_nested_runme.java b/Examples/test-suite/java/template_nested_runme.java
new file mode 100644
index 000000000..407821674
--- /dev/null
+++ b/Examples/test-suite/java/template_nested_runme.java
@@ -0,0 +1,30 @@
+
+import template_nested.*;
+
+public class template_nested_runme {
+
+ static {
+ try {
+ System.loadLibrary("template_nested");
+ } 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[]) {
+ new T_NormalTemplateNormalClass().tmethod(new NormalClass());
+ new OuterClass().T_OuterTMethodNormalClass(new NormalClass());
+
+ TemplateFuncs tf = new TemplateFuncs();
+ if (tf.T_TemplateFuncs1Int(-10) != -10)
+ throw new RuntimeException("it failed");
+ if (tf.T_TemplateFuncs2Double(-12.3) != -12.3)
+ throw new RuntimeException("it failed");
+
+ T_NestedOuterTemplateDouble tn = new T_NestedOuterTemplateDouble();
+ if (tn.hohum(-12.3) != -12.3)
+ throw new RuntimeException("it failed");
+ }
+}
+
diff --git a/Examples/test-suite/template_nested.i b/Examples/test-suite/template_nested.i
new file mode 100644
index 000000000..cb5eddb50
--- /dev/null
+++ b/Examples/test-suite/template_nested.i
@@ -0,0 +1,91 @@
+%module template_nested
+
+// Test nested templates - that is template classes and template methods within a class.
+
+#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
+
+%inline %{
+
+namespace ns {
+
+ class NormalClass {
+ public:
+ NormalClass() {}
+ ~NormalClass() {}
+ };
+
+ template struct NormalTemplate {
+ void tmethod(T t) {}
+ };
+
+ class OuterClass {
+ public:
+ template struct Inner1 {
+ template struct SuperInner1 {
+ void method1(U t) {}
+ };
+ template struct SuperInner2 {
+ void method1(V t) {}
+ };
+ template void tmethod(W w) {}
+ template void tmethodAgain(X x) {}
+ template struct SuperBase : public SuperInner1 {
+ void method1(Y y) {}
+ };
+ };
+
+ template void InnerTMethod(Z z) {}
+
+ template class Inner2 : public NormalTemplate {
+ public:
+ template class SuperInner1 {
+ public:
+ SuperInner1() {}
+ void method1(U t) {}
+ };
+ template struct SuperInner2 {
+ void method1(V t) {}
+ };
+ int embeddedVar;
+ template void tmethod(X x) {}
+ template struct SuperBase : public SuperInner1 {
+ void method1(Y y) {}
+ };
+ };
+ int iii;
+ };
+ struct ABC {
+ ABC() {}
+ ~ABC() {}
+ };
+
+ struct TemplateFuncs {
+ template X templateMethod1(X x) { return x; }
+ template X templateMethod2(X x) { return x; }
+ };
+
+ template struct OuterTemplate {
+ template struct NestedInnerTemplate1 {
+ template void NestedInnerInnerTMethod(Z z) {}
+ void hohum() {}
+ };
+ template void NestedInnerTMethod(UU u, W w) {}
+ template struct NestedInnerTemplate2 {
+ void hohum() {}
+ };
+ UU hohum(UU u) { return u; }
+ struct NestedStruct {
+ NestedStruct() {}
+ void hohum() {}
+ };
+ };
+}
+
+%}
+
+%template(T_NormalTemplateNormalClass) ns::NormalTemplate;
+%template(T_OuterTMethodNormalClass) ns::OuterClass::InnerTMethod;
+%template(T_TemplateFuncs1Int) ns::TemplateFuncs::templateMethod1;
+%template(T_TemplateFuncs2Double) ns::TemplateFuncs::templateMethod2;
+%template(T_NestedOuterTemplateDouble) ns::OuterTemplate;
+
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 954b7af77..1cd7dc750 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -43,6 +43,7 @@ static Node *module_node = 0;
static String *Classprefix = 0;
static String *Namespaceprefix = 0;
static int inclass = 0;
+static int nested_template = 0; /* template class/function definition within a class */
static char *last_cpptype = 0;
static int inherit_list = 0;
static Parm *template_parameters = 0;
@@ -272,6 +273,14 @@ static int add_only_one = 0;
static void add_symbols(Node *n) {
String *decl;
String *wrn = 0;
+
+ if (nested_template) {
+ if (!(n && Equal(nodeType(n), "template"))) {
+ return;
+ }
+ /* continue if template function, but not template class, declared within a class */
+ }
+
if (inclass && n) {
cparse_normalize_void(n);
}
@@ -3227,10 +3236,10 @@ cpp_declaration : cpp_class_decl { $$ = $1; }
| cpp_catch_decl { $$ = 0; }
;
-cpp_class_decl :
/* A simple class/struct/union definition */
- storage_class cpptype idcolon inherit LBRACE {
+cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
+ if (nested_template == 0) {
List *bases = 0;
Node *scope = 0;
$$ = new_node("class");
@@ -3344,120 +3353,128 @@ cpp_class_decl :
}
class_decl[class_level++] = $$;
inclass = 1;
+ }
} cpp_members RBRACE cpp_opt_declarators {
- Node *p;
- SwigType *ty;
- Symtab *cscope = prev_symtab;
- Node *am = 0;
- String *scpname = 0;
- $$ = class_decl[--class_level];
- inclass = 0;
-
- /* Check for pure-abstract class */
- Setattr($$,"abstract", pure_abstract($7));
-
- /* This bit of code merges in a previously defined %extend directive (if any) */
-
- if (extendhash) {
- String *clsname = Swig_symbol_qualifiedscopename(0);
- am = Getattr(extendhash,clsname);
- if (am) {
- merge_extensions($$,am);
- Delattr(extendhash,clsname);
+ if (nested_template == 0) {
+ Node *p;
+ SwigType *ty;
+ Symtab *cscope = prev_symtab;
+ Node *am = 0;
+ String *scpname = 0;
+ $$ = class_decl[--class_level];
+ inclass = 0;
+
+ /* Check for pure-abstract class */
+ Setattr($$,"abstract", pure_abstract($7));
+
+ /* This bit of code merges in a previously defined %extend directive (if any) */
+
+ if (extendhash) {
+ String *clsname = Swig_symbol_qualifiedscopename(0);
+ am = Getattr(extendhash,clsname);
+ if (am) {
+ merge_extensions($$,am);
+ Delattr(extendhash,clsname);
+ }
+ Delete(clsname);
}
- Delete(clsname);
- }
- if (!classes) classes = NewHash();
- scpname = Swig_symbol_qualifiedscopename(0);
- Setattr(classes,scpname,$$);
- Delete(scpname);
+ if (!classes) classes = NewHash();
+ scpname = Swig_symbol_qualifiedscopename(0);
+ Setattr(classes,scpname,$$);
+ Delete(scpname);
- appendChild($$,$7);
-
- if (am) append_previous_extension($$,am);
+ appendChild($$,$7);
+
+ if (am) append_previous_extension($$,am);
- p = $9;
- if (p) {
- set_nextSibling($$,p);
- }
-
- if (cparse_cplusplus && !cparse_externc) {
- ty = NewString($3);
- } else {
- ty = NewStringf("%s %s", $2,$3);
- }
- while (p) {
- Setattr(p,"storage",$1);
- Setattr(p,"type",ty);
- p = nextSibling(p);
- }
- /* Dump nested classes */
- {
- String *name = $3;
- if ($9) {
- SwigType *decltype = Getattr($9,"decl");
- if (Cmp($1,"typedef") == 0) {
- if (!decltype || !Len(decltype)) {
- String *cname;
- name = Getattr($9,"name");
- cname = Copy(name);
- Setattr($$,"tdname",cname);
- Delete(cname);
+ p = $9;
+ if (p) {
+ set_nextSibling($$,p);
+ }
+
+ if (cparse_cplusplus && !cparse_externc) {
+ ty = NewString($3);
+ } else {
+ ty = NewStringf("%s %s", $2,$3);
+ }
+ while (p) {
+ Setattr(p,"storage",$1);
+ Setattr(p,"type",ty);
+ p = nextSibling(p);
+ }
+ /* Dump nested classes */
+ {
+ String *name = $3;
+ if ($9) {
+ SwigType *decltype = Getattr($9,"decl");
+ if (Cmp($1,"typedef") == 0) {
+ if (!decltype || !Len(decltype)) {
+ String *cname;
+ name = Getattr($9,"name");
+ cname = Copy(name);
+ Setattr($$,"tdname",cname);
+ Delete(cname);
- /* Use typedef name as class name */
- if (class_rename && (Strcmp(class_rename,$3) == 0)) {
- Delete(class_rename);
- class_rename = NewString(name);
+ /* Use typedef name as class name */
+ if (class_rename && (Strcmp(class_rename,$3) == 0)) {
+ Delete(class_rename);
+ class_rename = NewString(name);
+ }
+ if (!Getattr(classes,name)) {
+ Setattr(classes,name,$$);
+ }
+ Setattr($$,"decl",decltype);
}
- if (!Getattr(classes,name)) {
- Setattr(classes,name,$$);
- }
- Setattr($$,"decl",decltype);
}
}
+ appendChild($$,dump_nested(Char(name)));
}
- appendChild($$,dump_nested(Char(name)));
- }
- if (cplus_mode != CPLUS_PUBLIC) {
- /* we 'open' the class at the end, to allow %template
- to add new members */
- Node *pa = new_node("access");
- Setattr(pa,"kind","public");
- cplus_mode = CPLUS_PUBLIC;
- appendChild($$,pa);
- Delete(pa);
- }
+ if (cplus_mode != CPLUS_PUBLIC) {
+ /* we 'open' the class at the end, to allow %template
+ to add new members */
+ Node *pa = new_node("access");
+ Setattr(pa,"kind","public");
+ cplus_mode = CPLUS_PUBLIC;
+ appendChild($$,pa);
+ Delete(pa);
+ }
- Setattr($$,"symtab",Swig_symbol_popscope());
+ Setattr($$,"symtab",Swig_symbol_popscope());
- Classprefix = 0;
- if (nscope_inner) {
- /* this is tricky */
- /* we add the declaration in the original namespace */
- appendChild(nscope_inner,$$);
- Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- add_symbols($$);
- if (nscope) $$ = nscope;
- /* but the variable definition in the current scope */
+ Classprefix = 0;
+ if (nscope_inner) {
+ /* this is tricky */
+ /* we add the declaration in the original namespace */
+ appendChild(nscope_inner,$$);
+ Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($$);
+ if (nscope) $$ = nscope;
+ /* but the variable definition in the current scope */
+ Swig_symbol_setscope(cscope);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($9);
+ } else {
+ Delete(yyrename);
+ yyrename = Copy(class_rename);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+
+ add_symbols($$);
+ add_symbols($9);
+ }
Swig_symbol_setscope(cscope);
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- add_symbols($9);
} else {
- Delete(yyrename);
- yyrename = Copy(class_rename);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
-
- add_symbols($$);
- add_symbols($9);
+ $$ = new_node("class");
+ Setattr($$,"kind",$2);
+ Setattr($$,"name",NewString($3));
+ SetFlag($$,"nestedtemplateclass");
}
- Swig_symbol_setscope(cscope);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
}
/* An unnamed struct, possibly with a typedef */
@@ -3617,253 +3634,276 @@ cpp_forward_class_decl : storage_class cpptype idcolon SEMI {
template<...> decl
------------------------------------------------------------ */
-cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_parameters = $3; } cpp_temp_possible {
- String *tname = 0;
- int error = 0;
+cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN {
+ template_parameters = $3;
+ if (inclass)
+ nested_template++;
- /* check if we get a namespace node with a class declaration, and retrieve the class */
- Symtab *cscope = Swig_symbol_current();
- Symtab *sti = 0;
- Node *ntop = $6;
- Node *ni = ntop;
- SwigType *ntype = ni ? nodeType(ni) : 0;
- while (ni && Strcmp(ntype,"namespace") == 0) {
- sti = Getattr(ni,"symtab");
- ni = firstChild(ni);
- ntype = nodeType(ni);
- }
- if (sti) {
- Swig_symbol_setscope(sti);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- $6 = ni;
- }
+ } cpp_temp_possible {
- template_parameters = 0;
- $$ = $6;
- if ($$) tname = Getattr($$,"name");
-
- /* Check if the class is a template specialization */
- if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) {
- /* If a specialization. Check if defined. */
- Node *tempn = 0;
- {
- String *tbase = SwigType_templateprefix(tname);
- tempn = Swig_symbol_clookup_local(tbase,0);
- if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) {
- SWIG_WARN_NODE_BEGIN(tempn);
- Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase);
- SWIG_WARN_NODE_END(tempn);
- tempn = 0;
- error = 1;
- }
- Delete(tbase);
+ /* Don't ignore templated functions declared within a class, unless the templated function is within a nested class */
+ if (nested_template <= 1) {
+ int is_nested_template_class = $6 && GetFlag($6, "nestedtemplateclass");
+ if (is_nested_template_class) {
+ /* Nested template classes would probably better be ignored like ordinary nested classes using cpp_nested, but that introduces shift/reduce conflicts */
+ if (cplus_mode == CPLUS_PUBLIC) {
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested template %s not currently supported (%s ignored)\n", Getattr($6, "kind"), Getattr($6, "name"));
}
- Setattr($$,"specialization","1");
- Setattr($$,"templatetype",nodeType($$));
- set_nodeType($$,"template");
- /* Template partial specialization */
- if (tempn && ($3) && ($6)) {
- List *tlist;
- String *targs = SwigType_templateargs(tname);
- tlist = SwigType_parmlist(targs);
- /* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
+ Delete($6);
+ $$ = 0;
+ } else {
+ String *tname = 0;
+ int error = 0;
+
+ /* check if we get a namespace node with a class declaration, and retrieve the class */
+ Symtab *cscope = Swig_symbol_current();
+ Symtab *sti = 0;
+ Node *ntop = $6;
+ Node *ni = ntop;
+ SwigType *ntype = ni ? nodeType(ni) : 0;
+ while (ni && Strcmp(ntype,"namespace") == 0) {
+ sti = Getattr(ni,"symtab");
+ ni = firstChild(ni);
+ ntype = nodeType(ni);
+ }
+ if (sti) {
+ Swig_symbol_setscope(sti);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ $6 = ni;
+ }
+
+ $$ = $6;
+ if ($$) tname = Getattr($$,"name");
+
+ /* Check if the class is a template specialization */
+ if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) {
+ /* If a specialization. Check if defined. */
+ Node *tempn = 0;
+ {
+ String *tbase = SwigType_templateprefix(tname);
+ tempn = Swig_symbol_clookup_local(tbase,0);
+ if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) {
+ SWIG_WARN_NODE_BEGIN(tempn);
+ Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase);
+ SWIG_WARN_NODE_END(tempn);
+ tempn = 0;
+ error = 1;
+ }
+ Delete(tbase);
+ }
+ Setattr($$,"specialization","1");
+ Setattr($$,"templatetype",nodeType($$));
+ set_nodeType($$,"template");
+ /* Template partial specialization */
+ if (tempn && ($3) && ($6)) {
+ List *tlist;
+ String *targs = SwigType_templateargs(tname);
+ tlist = SwigType_parmlist(targs);
+ /* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
+ if (!Getattr($$,"sym:weak")) {
+ Setattr($$,"sym:typename","1");
+ }
+
+ if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
+ Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
+
+ } else {
+
+ /* This code builds the argument list for the partial template
+ specialization. This is a little hairy, but the idea is as
+ follows:
+
+ $3 contains a list of arguments supplied for the template.
+ For example template.
+
+ tlist is a list of the specialization arguments--which may be
+ different. For example class.
+
+ tp is a copy of the arguments in the original template definition.
+
+ The patching algorithm walks through the list of supplied
+ arguments ($3), finds the position in the specialization arguments
+ (tlist), and then patches the name in the argument list of the
+ original template.
+ */
+
+ {
+ String *pn;
+ Parm *p, *p1;
+ int i, nargs;
+ Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
+ nargs = Len(tlist);
+ p = $3;
+ while (p) {
+ for (i = 0; i < nargs; i++){
+ pn = Getattr(p,"name");
+ if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
+ int j;
+ Parm *p1 = tp;
+ for (j = 0; j < i; j++) {
+ p1 = nextSibling(p1);
+ }
+ Setattr(p1,"name",pn);
+ Setattr(p1,"partialarg","1");
+ }
+ }
+ p = nextSibling(p);
+ }
+ p1 = tp;
+ i = 0;
+ while (p1) {
+ if (!Getattr(p1,"partialarg")) {
+ Delattr(p1,"name");
+ Setattr(p1,"type", Getitem(tlist,i));
+ }
+ i++;
+ p1 = nextSibling(p1);
+ }
+ Setattr($$,"templateparms",tp);
+ Delete(tp);
+ }
+ #if 0
+ /* Patch the parameter list */
+ if (tempn) {
+ Parm *p,*p1;
+ ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
+ p = $3;
+ p1 = tp;
+ while (p && p1) {
+ String *pn = Getattr(p,"name");
+ Printf(stdout,"pn = '%s'\n", pn);
+ if (pn) Setattr(p1,"name",pn);
+ else Delattr(p1,"name");
+ pn = Getattr(p,"type");
+ if (pn) Setattr(p1,"type",pn);
+ p = nextSibling(p);
+ p1 = nextSibling(p1);
+ }
+ Setattr($$,"templateparms",tp);
+ Delete(tp);
+ } else {
+ Setattr($$,"templateparms",$3);
+ }
+ #endif
+ Delattr($$,"specialization");
+ Setattr($$,"partialspecialization","1");
+ /* Create a specialized name for matching */
+ {
+ Parm *p = $3;
+ String *fname = NewString(Getattr($$,"name"));
+ String *ffname = 0;
+ ParmList *partialparms = 0;
+
+ char tmp[32];
+ int i, ilen;
+ while (p) {
+ String *n = Getattr(p,"name");
+ if (!n) {
+ p = nextSibling(p);
+ continue;
+ }
+ ilen = Len(tlist);
+ for (i = 0; i < ilen; i++) {
+ if (Strstr(Getitem(tlist,i),n)) {
+ sprintf(tmp,"$%d",i+1);
+ Replaceid(fname,n,tmp);
+ }
+ }
+ p = nextSibling(p);
+ }
+ /* Patch argument names with typedef */
+ {
+ Iterator tt;
+ Parm *parm_current = 0;
+ List *tparms = SwigType_parmlist(fname);
+ ffname = SwigType_templateprefix(fname);
+ Append(ffname,"<(");
+ for (tt = First(tparms); tt.item; ) {
+ SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0);
+ SwigType *ttr = Swig_symbol_type_qualify(rtt,0);
+
+ Parm *newp = NewParm(ttr, 0);
+ if (partialparms)
+ set_nextSibling(parm_current, newp);
+ else
+ partialparms = newp;
+ parm_current = newp;
+
+ Append(ffname,ttr);
+ tt = Next(tt);
+ if (tt.item) Putc(',',ffname);
+ Delete(rtt);
+ Delete(ttr);
+ }
+ Delete(tparms);
+ Append(ffname,")>");
+ }
+ {
+ Node *new_partial = NewHash();
+ String *partials = Getattr(tempn,"partials");
+ if (!partials) {
+ partials = NewList();
+ Setattr(tempn,"partials",partials);
+ Delete(partials);
+ }
+ /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
+ Setattr(new_partial, "partialparms", partialparms);
+ Setattr(new_partial, "templcsymname", ffname);
+ Append(partials, new_partial);
+ }
+ Setattr($$,"partialargs",ffname);
+ Swig_symbol_cadd(ffname,$$);
+ }
+ }
+ Delete(tlist);
+ Delete(targs);
+ } else {
+ /* An explicit template specialization */
+ /* add default args from primary (unspecialized) template */
+ String *ty = Swig_symbol_template_deftype(tname,0);
+ String *fname = Swig_symbol_type_qualify(ty,0);
+ Swig_symbol_cadd(fname,$$);
+ Delete(ty);
+ Delete(fname);
+ }
+ } else if ($$) {
+ Setattr($$,"templatetype",nodeType($6));
+ set_nodeType($$,"template");
+ Setattr($$,"templateparms", $3);
if (!Getattr($$,"sym:weak")) {
Setattr($$,"sym:typename","1");
}
-
- if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
- Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
-
- } else {
-
- /* This code builds the argument list for the partial template
- specialization. This is a little hairy, but the idea is as
- follows:
-
- $3 contains a list of arguments supplied for the template.
- For example template.
-
- tlist is a list of the specialization arguments--which may be
- different. For example class.
-
- tp is a copy of the arguments in the original template definition.
-
- The patching algorithm walks through the list of supplied
- arguments ($3), finds the position in the specialization arguments
- (tlist), and then patches the name in the argument list of the
- original template.
- */
-
+ add_symbols($$);
+ default_arguments($$);
+ /* We also place a fully parameterized version in the symbol table */
{
- String *pn;
- Parm *p, *p1;
- int i, nargs;
- Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
- nargs = Len(tlist);
+ Parm *p;
+ String *fname = NewStringf("%s<(", Getattr($$,"name"));
p = $3;
- while (p) {
- for (i = 0; i < nargs; i++){
- pn = Getattr(p,"name");
- if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
- int j;
- Parm *p1 = tp;
- for (j = 0; j < i; j++) {
- p1 = nextSibling(p1);
- }
- Setattr(p1,"name",pn);
- Setattr(p1,"partialarg","1");
- }
- }
- p = nextSibling(p);
- }
- p1 = tp;
- i = 0;
- while (p1) {
- if (!Getattr(p1,"partialarg")) {
- Delattr(p1,"name");
- Setattr(p1,"type", Getitem(tlist,i));
- }
- i++;
- p1 = nextSibling(p1);
- }
- Setattr($$,"templateparms",tp);
- Delete(tp);
- }
-#if 0
- /* Patch the parameter list */
- if (tempn) {
- Parm *p,*p1;
- ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
- p = $3;
- p1 = tp;
- while (p && p1) {
- String *pn = Getattr(p,"name");
- Printf(stdout,"pn = '%s'\n", pn);
- if (pn) Setattr(p1,"name",pn);
- else Delattr(p1,"name");
- pn = Getattr(p,"type");
- if (pn) Setattr(p1,"type",pn);
- p = nextSibling(p);
- p1 = nextSibling(p1);
- }
- Setattr($$,"templateparms",tp);
- Delete(tp);
- } else {
- Setattr($$,"templateparms",$3);
- }
-#endif
- Delattr($$,"specialization");
- Setattr($$,"partialspecialization","1");
- /* Create a specialized name for matching */
- {
- Parm *p = $3;
- String *fname = NewString(Getattr($$,"name"));
- String *ffname = 0;
- ParmList *partialparms = 0;
-
- char tmp[32];
- int i, ilen;
while (p) {
String *n = Getattr(p,"name");
- if (!n) {
- p = nextSibling(p);
- continue;
- }
- ilen = Len(tlist);
- for (i = 0; i < ilen; i++) {
- if (Strstr(Getitem(tlist,i),n)) {
- sprintf(tmp,"$%d",i+1);
- Replaceid(fname,n,tmp);
- }
- }
+ if (!n) n = Getattr(p,"type");
+ Append(fname,n);
p = nextSibling(p);
+ if (p) Putc(',',fname);
}
- /* Patch argument names with typedef */
- {
- Iterator tt;
- Parm *parm_current = 0;
- List *tparms = SwigType_parmlist(fname);
- ffname = SwigType_templateprefix(fname);
- Append(ffname,"<(");
- for (tt = First(tparms); tt.item; ) {
- SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0);
- SwigType *ttr = Swig_symbol_type_qualify(rtt,0);
-
- Parm *newp = NewParm(ttr, 0);
- if (partialparms)
- set_nextSibling(parm_current, newp);
- else
- partialparms = newp;
- parm_current = newp;
-
- Append(ffname,ttr);
- tt = Next(tt);
- if (tt.item) Putc(',',ffname);
- Delete(rtt);
- Delete(ttr);
- }
- Delete(tparms);
- Append(ffname,")>");
- }
- {
- Node *new_partial = NewHash();
- String *partials = Getattr(tempn,"partials");
- if (!partials) {
- partials = NewList();
- Setattr(tempn,"partials",partials);
- Delete(partials);
- }
- /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
- Setattr(new_partial, "partialparms", partialparms);
- Setattr(new_partial, "templcsymname", ffname);
- Append(partials, new_partial);
- }
- Setattr($$,"partialargs",ffname);
- Swig_symbol_cadd(ffname,$$);
+ Append(fname,")>");
+ Swig_symbol_cadd(fname,$$);
}
- }
- Delete(tlist);
- Delete(targs);
- } else {
- /* An explicit template specialization */
- /* add default args from primary (unspecialized) template */
- String *ty = Swig_symbol_template_deftype(tname,0);
- String *fname = Swig_symbol_type_qualify(ty,0);
- Swig_symbol_cadd(fname,$$);
- Delete(ty);
- Delete(fname);
- }
- } else if ($$) {
- Setattr($$,"templatetype",nodeType($6));
- set_nodeType($$,"template");
- Setattr($$,"templateparms", $3);
- if (!Getattr($$,"sym:weak")) {
- Setattr($$,"sym:typename","1");
- }
- add_symbols($$);
- default_arguments($$);
- /* We also place a fully parameterized version in the symbol table */
- {
- Parm *p;
- String *fname = NewStringf("%s<(", Getattr($$,"name"));
- p = $3;
- while (p) {
- String *n = Getattr(p,"name");
- if (!n) n = Getattr(p,"type");
- Append(fname,n);
- p = nextSibling(p);
- if (p) Putc(',',fname);
- }
- Append(fname,")>");
- Swig_symbol_cadd(fname,$$);
}
+ $$ = ntop;
+ Swig_symbol_setscope(cscope);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ if (error) $$ = 0;
}
- $$ = ntop;
- Swig_symbol_setscope(cscope);
- Delete(Namespaceprefix);
- Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- if (error) $$ = 0;
+ } else {
+ $$ = 0;
+ }
+ template_parameters = 0;
+ if (inclass)
+ nested_template--;
}
| TEMPLATE cpptype idcolon {
Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
@@ -4377,7 +4417,6 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
if (cplus_mode == CPLUS_PUBLIC) {
if (strcmp($2,"class") == 0) {
Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
- /* Generate some code for a new class */
} else if ($5.id) {
/* Generate some code for a new class */
Nested *n = (Nested *) malloc(sizeof(Nested));
@@ -4409,6 +4448,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
}
}
+/* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */
/*
| TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
} SEMI {
From 9d65c100b977bd74151ac2c1c6cd03d1a27ed641 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 8 Nov 2009 01:18:45 +0000
Subject: [PATCH 056/146] Ignored nested class/struct warnings now display the
name of the ignored class/struct.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11728 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 3 +++
Doc/Manual/Warnings.html | 3 +--
Examples/test-suite/common.mk | 1 +
Examples/test-suite/derived_nested.i | 7 +++++
Examples/test-suite/nested_class.i | 40 ++++++++++++++++++++++++++++
Source/CParse/parser.y | 11 +++++---
6 files changed, 59 insertions(+), 6 deletions(-)
create mode 100644 Examples/test-suite/nested_class.i
diff --git a/CHANGES.current b/CHANGES.current
index 8192f30b5..2791a7a45 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,9 @@
Version 1.3.41 (in progress)
============================
+2009-11-08: wsfulton
+ Ignored nested class/struct warnings now display the name of the ignored class/struct.
+
2009-11-07: wsfulton
Bug #1514681 - Fix nested template classes within a namespace generated uncompileable
code and introduced strange side effects to other wrapper code especially code
diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html
index df05478a6..1150c4dc5 100644
--- a/Doc/Manual/Warnings.html
+++ b/Doc/Manual/Warnings.html
@@ -399,8 +399,7 @@ example.i(4): Syntax error in input.
308. Namespace alias 'name' not allowed here. Assuming 'name'
309. [private | protected] inheritance ignored.
310. Template 'name' was already wrapped as 'name' (ignored)
-311. Template partial specialization not supported.
-312. Nested classes not currently supported (ignored).
+312. Nested class not currently supported (name ignored).
313. Unrecognized extern type "name" (ignored).
314. 'identifier' is a lang keyword.
315. Nothing known about 'identifier'.
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 473d6579d..cf9faaad9 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -242,6 +242,7 @@ CPP_TEST_CASES += \
namespace_typemap \
namespace_virtual_method \
naturalvar \
+ nested_class \
nested_comment \
newobject1 \
null_pointer \
diff --git a/Examples/test-suite/derived_nested.i b/Examples/test-suite/derived_nested.i
index 2e9ace304..babcac0aa 100644
--- a/Examples/test-suite/derived_nested.i
+++ b/Examples/test-suite/derived_nested.i
@@ -3,6 +3,8 @@ This was reported in bug #909389 */
%module derived_nested
+#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
+
%inline %{
class A { int x; };
@@ -11,5 +13,10 @@ class B {
class D : public A { int z; }; //ok
};
+struct BB {
+ class CC { int y; };
+ class DD : public A { int z; };
+ struct EE : public A { int z; };
+};
%}
diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i
new file mode 100644
index 000000000..139c0c4cf
--- /dev/null
+++ b/Examples/test-suite/nested_class.i
@@ -0,0 +1,40 @@
+%module nested_class
+
+#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
+
+%inline %{
+struct Outer {
+ struct Inner1 {
+ int x;
+ };
+
+ class Inner2 {
+ public:
+ int x;
+ };
+
+ class {
+ public:
+ int a;
+ };
+
+ struct {
+ int b;
+ };
+
+ union {
+ int c;
+ double d;
+ };
+
+ class Inner3 {
+ public:
+ int x;
+ } Inner3Name;
+
+ struct Inner4 {
+ int x;
+ } Inner4Name;
+};
+
+%}
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 1cd7dc750..5eccc2df0 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -4395,7 +4395,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
n->next = 0;
add_nested(n);
} else {
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3);
if (strcmp($2, "class") == 0) {
/* For now, just treat the nested class as a forward
* declaration (SF bug #909387). */
@@ -4416,7 +4416,10 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
if (strcmp($2,"class") == 0) {
- Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
+ if ($5.id)
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested class not currently supported (%s ignored)\n", $5.id);
+ else
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
} else if ($5.id) {
/* Generate some code for a new class */
Nested *n = (Nested *) malloc(sizeof(Nested));
@@ -4445,7 +4448,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
} SEMI {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
- Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $3);
}
}
/* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */
@@ -4454,7 +4457,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
} SEMI {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
- Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $5, $6);
}
}
*/
From 99565a7c35a9936cac6c2b97f0861404900e969a Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 8 Nov 2009 20:33:19 +0000
Subject: [PATCH 057/146] Add unions to the nested class test
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11729 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Examples/test-suite/nested_class.i | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i
index 139c0c4cf..744519b96 100644
--- a/Examples/test-suite/nested_class.i
+++ b/Examples/test-suite/nested_class.i
@@ -4,15 +4,20 @@
%inline %{
struct Outer {
- struct Inner1 {
+ struct InnerStruct1 {
int x;
};
- class Inner2 {
+ class InnerClass1 {
public:
int x;
};
+ union InnerUnion1 {
+ int x;
+ double y;
+ };
+
class {
public:
int a;
@@ -27,14 +32,19 @@ struct Outer {
double d;
};
- class Inner3 {
+ class InnerClass2 {
public:
int x;
- } Inner3Name;
+ } InnerClass2Name;
- struct Inner4 {
+ struct InnerStruct2 {
int x;
- } Inner4Name;
+ } InnerStruct2Name;
+
+ union InnerUnion2 {
+ int x;
+ double y;
+ } InnerUnion2Name;
};
%}
From 9b318c45bc1e93c6e03a12ec5e6ab7b7e8326a04 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 8 Nov 2009 20:45:48 +0000
Subject: [PATCH 058/146] inner declared types are treated as forward
declarations - consistency now between innner/nested unions/structs and
classes - only relevant to C++
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11730 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 11 +++++++++++
Examples/test-suite/nested_class.i | 5 +++++
Examples/test-suite/nested_structs.i | 10 ----------
Source/CParse/parser.y | 22 +++++++++++-----------
4 files changed, 27 insertions(+), 21 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 2791a7a45..9568a0c14 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,17 @@
Version 1.3.41 (in progress)
============================
+2009-11-08: wsfulton
+ Fix inconsistency for inner structs/unions/classes. Uncompileable code was being
+ generated when inner struct and union declarations were used as types within
+ the inner struct. The inner struct/union is now treated as a forward declaration making the
+ behaviour the same as an inner class. (C++ code), eg:
+
+ struct Outer {
+ struct InnerStruct { int x; };
+ InnerStruct* getInnerStruct();
+ };
+
2009-11-08: wsfulton
Ignored nested class/struct warnings now display the name of the ignored class/struct.
diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i
index 744519b96..ce45b2981 100644
--- a/Examples/test-suite/nested_class.i
+++ b/Examples/test-suite/nested_class.i
@@ -45,6 +45,11 @@ struct Outer {
int x;
double y;
} InnerUnion2Name;
+
+ // bug #909387 - inner declared types are treated as forward declarations
+ InnerStruct1* getInnerStruct1() { return 0; }
+ InnerClass1* getInnerClass1() { return 0; }
+ InnerUnion1* getInnerUnion1() { return 0; }
};
%}
diff --git a/Examples/test-suite/nested_structs.i b/Examples/test-suite/nested_structs.i
index 4b13ff69d..41cdd63fb 100644
--- a/Examples/test-suite/nested_structs.i
+++ b/Examples/test-suite/nested_structs.i
@@ -10,13 +10,3 @@ int a;
%}
-// bug #909387
-%inline %{
-struct foo {
- struct happy; // no warning
- struct sad { int x; }; // warning
- happy *good(); // produces good code
- sad *bad(); // produces bad code
-};
-%}
-
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 5eccc2df0..9c68cc647 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -4396,17 +4396,16 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
add_nested(n);
} else {
Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3);
- if (strcmp($2, "class") == 0) {
- /* For now, just treat the nested class as a forward
- * declaration (SF bug #909387). */
- $$ = new_node("classforward");
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- Setattr($$,"kind",$2);
- Setattr($$,"name",$3);
- Setattr($$,"sym:weak", "1");
- add_symbols($$);
- }
+
+ /* For now, just treat the nested class/struct/union as a forward
+ * declaration (SF bug #909387). */
+ $$ = new_node("classforward");
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"kind",$2);
+ Setattr($$,"name",$3);
+ Setattr($$,"sym:weak", "1");
+ add_symbols($$);
}
}
}
@@ -4446,6 +4445,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
*****/
| storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
} SEMI {
+Printf(stdout, "cpp_nested (c)\n");
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $3);
From b279cd3dde30f8285d8621d5e57dab8563956bd8 Mon Sep 17 00:00:00 2001
From: Joseph Wang
Date: Tue, 10 Nov 2009 02:32:29 +0000
Subject: [PATCH 059/146] add std_map fix compact mode
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11731 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Lib/r/r.swg | 8 ++++----
Lib/r/rtype.swg | 10 +++++-----
Lib/r/std_map.i | 5 +++++
Lib/r/std_pair.i | 6 +++++-
Source/Modules/r.cxx | 34 +++++++++++++++++-----------------
5 files changed, 36 insertions(+), 27 deletions(-)
create mode 100644 Lib/r/std_map.i
diff --git a/Lib/r/r.swg b/Lib/r/r.swg
index 7fd6d761f..b70d80581 100644
--- a/Lib/r/r.swg
+++ b/Lib/r/r.swg
@@ -50,7 +50,7 @@ SWIG_InitializeModule(0);
%typemap(scheck) SWIGTYPE[ANY]
%{
# assert(length($input) > $1_dim0)
- assert(all(sapply($input, class) == "$R_class"))
+ assert(all(sapply($input, class) == "$R_class"));
%}
%typemap(out) void "";
@@ -122,14 +122,14 @@ SWIG_InitializeModule(0);
/* Handling vector case to avoid warnings,
although we just use the first one. */
%typemap(scheck) unsigned int %{
- assert(length($input) == 1 && $input >= 0, "All values must be non-negative")
+ assert(length($input) == 1 && $input >= 0, "All values must be non-negative");
%}
%typemap(scheck) int, long %{
if(length($input) > 1) {
- warning("using only the first element of $input")
- }
+ warning("using only the first element of $input");
+ };
%}
diff --git a/Lib/r/rtype.swg b/Lib/r/rtype.swg
index 04441c03f..ee01d07d7 100644
--- a/Lib/r/rtype.swg
+++ b/Lib/r/rtype.swg
@@ -60,11 +60,11 @@
%typemap(scoercein) std::string, std::string *, std::string &
%{ $input = as($input, "character"); %}
%typemap(scoercein) enum SWIGTYPE
- %{ $input = enumToInteger($input, "$R_class") %}
+ %{ $input = enumToInteger($input, "$R_class"); %}
%typemap(scoercein) enum SWIGTYPE &
- %{ $input = enumToInteger($input, "$R_class") %}
+ %{ $input = enumToInteger($input, "$R_class"); %}
%typemap(scoercein) enum SWIGTYPE *
- %{ $input = enumToInteger($input, "$R_class") %}
+ %{ $input = enumToInteger($input, "$R_class"); %}
%typemap(scoercein) SWIGTYPE, SWIGTYPE *, SWIGTYPE &
@@ -84,14 +84,14 @@
%typemap(scoercein) SWIGTYPE[ANY]
%{
if(is.list($input))
- assert(all(sapply($input, class) == "$R_class"))
+ assert(all(sapply($input, class) == "$R_class"));
%}
/* **************************************************************** */
%typemap(scoercein) bool, bool *, bool &
- "$input = as.logical($input) ";
+ "$input = as.logical($input);";
%typemap(scoercein) int,
int *,
int &,
diff --git a/Lib/r/std_map.i b/Lib/r/std_map.i
new file mode 100644
index 000000000..56057514c
--- /dev/null
+++ b/Lib/r/std_map.i
@@ -0,0 +1,5 @@
+%fragment("StdMapTraits","header")
+%{
+%}
+
+%include
diff --git a/Lib/r/std_pair.i b/Lib/r/std_pair.i
index 3ac795704..e9803449e 100644
--- a/Lib/r/std_pair.i
+++ b/Lib/r/std_pair.i
@@ -1 +1,5 @@
-%include
\ No newline at end of file
+%fragment("StdPairTraits","header")
+%{
+%}
+
+%include
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
index e142c3bee..41058284f 100644
--- a/Source/Modules/r.cxx
+++ b/Source/Modules/r.cxx
@@ -1601,9 +1601,9 @@ void R::dispatchFunction(Node *n) {
List *dispatch = Swig_overload_rank(n, true);
int nfunc = Len(dispatch);
Printv(f->code,
- "argtypes <- mapply(class, list(...))\n",
- "argv <- list(...)\n",
- "argc <- length(argtypes)\n", NIL );
+ "argtypes <- mapply(class, list(...));\n",
+ "argv <- list(...);\n",
+ "argc <- length(argtypes);\n", NIL );
Printf(f->code, "# dispatch functions %d\n", nfunc);
int cur_args = -1;
@@ -1649,16 +1649,16 @@ void R::dispatchFunction(Node *n) {
}
p = Getattr(p, "tmap:in:next");
}
- Printf(f->code, ") { f <- %s%s }\n", sfname, overname);
+ Printf(f->code, ") { f <- %s%s; }\n", sfname, overname);
} else {
- Printf(f->code, "f <- %s%s", sfname, overname);
+ Printf(f->code, "f <- %s%s; ", sfname, overname);
}
}
if (cur_args != -1) {
Printv(f->code, "}", NIL);
}
- Printv(f->code, "\nf(...)", NIL);
- Printv(f->code, "\n}", NIL);
+ Printv(f->code, ";\nf(...)", NIL);
+ Printv(f->code, ";\n}", NIL);
Wrapper_print(f, sfile);
Printv(sfile, "# Dispatch function\n", NIL);
DelWrapper(f);
@@ -1886,16 +1886,16 @@ int R::functionWrapper(Node *n) {
String *snargs = NewStringf("%d", nargs);
Printv(sfun->code, "if(is.function(", name, ")) {", "\n",
"assert('...' %in% names(formals(", name,
- ")) || length(formals(", name, ")) >= ", snargs, ")\n} ", NIL);
+ ")) || length(formals(", name, ")) >= ", snargs, ");\n} ", NIL);
Delete(snargs);
Printv(sfun->code, "else {\n",
"if(is.character(", name, ")) {\n",
- name, " = getNativeSymbolInfo(", name, ")",
- "\n}\n",
+ name, " = getNativeSymbolInfo(", name, ");",
+ "\n};\n",
"if(is(", name, ", \"NativeSymbolInfo\")) {\n",
- name, " = ", name, "$address", "\n}\n",
- "}\n",
+ name, " = ", name, "$address", ";\n}\n",
+ "}; \n",
NIL);
} else {
Printf(sfun->code, "%s\n", tm);
@@ -2452,11 +2452,11 @@ int R::generateCopyRoutines(Node *n) {
/* The S functions to get and set the member value. */
String *elNameT = replaceInitialDash(elName);
- Printf(copyToR->code, "obj@%s = value$%s\n", elNameT, elNameT);
- Printf(copyToC->code, "obj$%s = value@%s\n", elNameT, elNameT);
+ Printf(copyToR->code, "obj@%s = value$%s;\n", elNameT, elNameT);
+ Printf(copyToC->code, "obj$%s = value@%s;\n", elNameT, elNameT);
Delete(elNameT);
}
- Printf(copyToR->code, "obj\n}\n\n");
+ Printf(copyToR->code, "obj;\n}\n\n");
String *rclassName = getRClassNameCopyStruct(type, 0); // without the Ref.
Printf(sfile, "# Start definition of copy functions & methods for %s\n", rclassName);
@@ -2466,9 +2466,9 @@ int R::generateCopyRoutines(Node *n) {
Printf(sfile, "# Start definition of copy methods for %s\n", rclassName);
- Printf(sfile, "setMethod('copyToR', '_p_%s', CopyToR%s)\n", rclassName,
+ Printf(sfile, "setMethod('copyToR', '_p_%s', CopyToR%s);\n", rclassName,
mangledName);
- Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s)\n\n", rclassName,
+ Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s);\n\n", rclassName,
mangledName);
Printf(sfile, "# End definition of copy methods for %s\n", rclassName);
From f5e1371733a7264d7584ae869066d040ec2f4766 Mon Sep 17 00:00:00 2001
From: Joseph Wang
Date: Tue, 10 Nov 2009 02:38:11 +0000
Subject: [PATCH 060/146] add R changes to change list
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11732 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 2 ++
1 file changed, 2 insertions(+)
diff --git a/CHANGES.current b/CHANGES.current
index 9568a0c14..bfcb65514 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,5 +1,7 @@
Version 1.3.41 (in progress)
============================
+2009-11-09: drjoe
+ Fix R for -fcompact and add std_map.i
2009-11-08: wsfulton
Fix inconsistency for inner structs/unions/classes. Uncompileable code was being
From a0ff0a86d046e66da8355c7e290388ea9a392463 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 11 Nov 2009 00:22:38 +0000
Subject: [PATCH 061/146] Obscure seg fault bug fix
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11733 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Source/Swig/typesys.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c
index 2562e12f8..2022daf6a 100644
--- a/Source/Swig/typesys.c
+++ b/Source/Swig/typesys.c
@@ -1120,11 +1120,13 @@ int SwigType_typedef_using(const_String_or_char_ptr name) {
/* Figure out the scope the using directive refers to */
{
prefix = Swig_scopename_prefix(name);
- s = SwigType_find_scope(current_scope, prefix);
- if (s) {
- Hash *ttab = Getattr(s, "typetab");
- if (!Getattr(ttab, base) && defined_name) {
- Setattr(ttab, base, defined_name);
+ if (prefix) {
+ s = SwigType_find_scope(current_scope, prefix);
+ if (s) {
+ Hash *ttab = Getattr(s, "typetab");
+ if (!Getattr(ttab, base) && defined_name) {
+ Setattr(ttab, base, defined_name);
+ }
}
}
}
From ebed6508e4cc3cee2a782fd6e15d6017c8cdcb25 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 11 Nov 2009 00:30:34 +0000
Subject: [PATCH 062/146] Nested class improvements - Fixed inconsistency in
handling C++ nested classes - sometimes they were treated as forward
declarations, other times as if C nested struct was parsed. Added the
nestedworkaround feature for C++ nested class handling. Document improved
nested class handling. Numerous C and C++ nested struct/class/union test
cases added.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11734 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 24 +++-
Doc/Manual/Introduction.html | 2 +-
Doc/Manual/SWIG.html | 14 ++-
Doc/Manual/SWIGPlus.html | 107 +++++++++++++-----
Examples/test-suite/common.mk | 1 +
Examples/test-suite/nested.i | 21 ++++
Examples/test-suite/nested_class.i | 60 ++++++++--
Examples/test-suite/nested_workaround.i | 38 +++++++
.../python/nested_workaround_runme.py | 13 +++
Lib/swig.swg | 5 +
Source/CParse/parser.y | 94 ++++++++-------
Source/Swig/symbol.c | 3 +-
12 files changed, 300 insertions(+), 82 deletions(-)
create mode 100644 Examples/test-suite/nested_workaround.i
create mode 100644 Examples/test-suite/python/nested_workaround_runme.py
diff --git a/CHANGES.current b/CHANGES.current
index bfcb65514..e03d6773a 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,12 +1,30 @@
Version 1.3.41 (in progress)
============================
+2009-11-11: wsfulton
+ Added the nestedworkaround feature as a way to use the full functionality of a nested class
+ (C++ mode only). It removes the nested class from SWIG's type information so it is as if SWIG
+ had never parsed the nested class. The documented nested class workarounds using a global
+ fake class stopped working when SWIG treated the nested class as an opaque pointer, and
+ this feature reverts this behaviour. The documentation has been updated with details of how
+ to use and implement it, see the "Nested classes" section in SWIGPlus.html.
+
+2009-11-11: wsfulton
+ There were a number of C++ cases where nested classes/structs/unions were being handled
+ as if C code was being parsed which would oftentimes lead to uncompileable code as an
+ attempt was made to wrap the nested structs like it is documented for C code. Now all
+ nested structs/classes/unions are ignored in C++ mode, as was always documented. However,
+ there is an improvement as usage of nested structs/classes/unions is now always treated
+ as an opaque type by default, resulting in generated code that should always compile.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
2009-11-09: drjoe
Fix R for -fcompact and add std_map.i
2009-11-08: wsfulton
- Fix inconsistency for inner structs/unions/classes. Uncompileable code was being
- generated when inner struct and union declarations were used as types within
- the inner struct. The inner struct/union is now treated as a forward declaration making the
+ Fix inconsistency for nested structs/unions/classes. Uncompileable code was being
+ generated when inner struct and union declarations were used as types within the
+ inner struct. The inner struct/union is now treated as a forward declaration making the
behaviour the same as an inner class. (C++ code), eg:
struct Outer {
diff --git a/Doc/Manual/Introduction.html b/Doc/Manual/Introduction.html
index 099454cf0..df8d03fdf 100644
--- a/Doc/Manual/Introduction.html
+++ b/Doc/Manual/Introduction.html
@@ -334,7 +334,7 @@ major features include:
Currently, the only major C++ feature not supported is nested classes--a limitation
-that will be removed in a future release.
+that should be removed in a future release, but has some workarounds for the moment.
diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html
index 8705fa182..dd1b22095 100644
--- a/Doc/Manual/SWIG.html
+++ b/Doc/Manual/SWIG.html
@@ -334,6 +334,7 @@ currently supported:
For example, SWIG does not support declarations such as the following
(even though this is legal C):
+
/* Non-conventional placement of storage specifier (extern) */
@@ -347,6 +348,7 @@ void bar(Spam (Grok)(Doh));
+
In practice, few (if any) C programmers actually write code like
@@ -360,6 +362,7 @@ is not recommended. Even though SWIG can parse C++ class declarations,
it ignores declarations that are decoupled from their
original class definition (the declarations are parsed, but a lot of warning
messages may be generated). For example:
+
@@ -369,11 +372,12 @@ int foo::bar(int) {
}
+
Certain advanced features of C++ such as nested classes
-are not yet supported. Please see the section on using SWIG
-with C++ for more information.
+are not yet fully supported. Please see the C++ section
+for more information.
@@ -2633,6 +2637,12 @@ If you have a lot nested structure declarations, it is
advisable to double-check them after running SWIG. Although,
there is a good chance that they will work, you may have to
modify the interface file in certain cases.
+
+
+
+Finally, note that nesting is handled differently in C++ mode,
+see Nested classes.
+
5.5.8 Other things to note about structure wrapping
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index f318af6a3..936fd3fb1 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -4695,37 +4695,49 @@ public:
-There is limited support for nested structs and unions when wrapping C code, see Nested structures for further details.
-However, there is no nested class/struct/union support when wrapping C++ code (using the -c++ commandline option).
-This may be added at a future date, however, until then some of the following workarounds can be applied.
+There is some support for nested structs and unions when wrapping C code,
+see Nested structures for further details.
+The added complexity of C++ compared to C means this approach does not work well for
+C++ code (when using the -c++ command line option).
+For C++, a nested class is treated much like an opaque pointer, so anything useful within the nested class, such as its
+methods and variables, are not accessible from the target language.
+True nested class support may be added to SWIG in the future, however,
+until then some of the following workarounds can be applied to improve the situation.
-It might be possible to use partial class information. Since
-SWIG does not need the entire class specification to work, conditional
-compilation can be used to comment out the problematic nested class definition, you might do this:
+It might be possible to use partial class information as often you can accept that the nested class is not needed,
+especially if it is not actually used in any methods you need from the target language.
+Imagine you are wrapping the following Outer class which contains a nested class Inner.
+The easiest thing to do is turn a blind eye to the warning that SWIG generates, or simply suppress it:
-class Foo {
+#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
+class Outer {
public:
-#ifndef SWIG
- class Bar {
- public:
- ...
- };
-#endif
- Foo();
- ~Foo();
- ...
+ class Inner {
+ public:
+ ...
+ };
+ Inner getInner();
+ void useInner(const Inner& inner);
+ ...
};
-The next workaround assumes you cannot modify the source code as was done above and it provides a solution for methods that use nested class types.
-Imagine we are wrapping the Outer class which contains a nested class Inner:
+Note that if Inner can be used as an opaque type, the default wrapping approach suffices.
+For example, if the nested class does not need to be created from the target language, but can be obtained via a method
+call, such as the getInner() method above, the returned value can then be passed around, such as passed into the
+useInner() method.
+
+
+
+With some more effort the above situation can be improved somewhat and a nested class can be constructed and used
+from the target language much like any other non-nested class. Assuming we have the Outer class in a header file:
@@ -4738,14 +4750,18 @@ public:
int var;
Inner(int v = 0) : var(v) {}
};
- void method(Inner inner);
+ Inner getInner();
+ void useInner(const Inner& inner);
};
-The following interface file works around SWIG nested class limitations by redefining the nested class as a global class.
-A typedef for the compiler is also required in order for the generated wrappers to compile.
+The following interface file works around the nested class limitations by redefining the nested class as a global class.
+A typedef for the compiler and the nestedworkaround
+feature flag is also required in
+order for the generated wrappers to compile. This flag simply removes all the type information from SWIG, so SWIG treats
+the nested class as if it had not been parsed at all.
@@ -4753,9 +4769,6 @@ A typedef for the compiler is also required in order for the generated wrappers
// File : example.i
%module example
-// Suppress SWIG warning
-#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
-
// Redefine nested class in global scope in order for SWIG to generate
// a proxy class. Only SWIG parses this definition.
class Inner {
@@ -4764,24 +4777,62 @@ class Inner {
Inner(int v = 0) : var(v) {}
};
+%nestedworkaround Outer::Inner;
+
%{
#include "outer.h"
%}
%include "outer.h"
+// We've fooled SWIG into thinking that Inner is a global class, so now we need
+// to trick the C++ compiler into understanding this apparent global type.
%{
-// SWIG thinks that Inner is a global class, so we need to trick the C++
-// compiler into understanding this so called global type.
typedef Outer::Inner Inner;
%}
-
-The downside to this approach is having to maintain two definitions of Inner, the real one and the one in the interface file that SWIG parses.
+The downside to this approach is a more complex interface file and having to maintain two definitions of Inner,
+the real one and the one in the interface file that SWIG parses.
+However, the upside is that all the methods/variables in the nested class are available from the target language
+as a proxy class is generated instead of treating the nested class as an opaque type.
+The proxy class can be constructed from the target language and passed into any methods accepting the nested class.
+Also note that the original header file is parsed unmodified.
+
+Finally, conditional compilation can be used as a workaround to comment out nested class definitions in the actual headers,
+assuming you are able to modify them.
+
+
+
+
+// File outer.h
+class Outer {
+public:
+#ifndef SWIG
+ class Inner {
+ public:
+ ...
+ };
+#endif
+ ...
+};
+
+
+
+
+This workaround used to be common when SWIG could not deal with nested classes particulary well.
+This should just be a last resort for unusual corner cases now as SWIG can parse nested classes and even handle nested template classes fairly well.
+
+
+
+Compatibility Note: SWIG-1.3.40 and earlier versions did not have the nestedworkaround feature
+and the generated code resulting from parsing nested classes did not always compile.
+
+
+
6.27 A brief rant about const-correctness
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index cf9faaad9..93c1cc909 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -244,6 +244,7 @@ CPP_TEST_CASES += \
naturalvar \
nested_class \
nested_comment \
+ nested_workaround \
newobject1 \
null_pointer \
operator_overload \
diff --git a/Examples/test-suite/nested.i b/Examples/test-suite/nested.i
index 0b93be46a..004cb4814 100644
--- a/Examples/test-suite/nested.i
+++ b/Examples/test-suite/nested.i
@@ -12,6 +12,27 @@ struct TestStruct {
int a;
};
+struct OuterStructNamed {
+ struct InnerStructNamed {
+ double dd;
+ } inner_struct_named;
+ union InnerUnionNamed {
+ double ee;
+ int ff;
+ } inner_union_named;
+};
+
+struct OuterStructUnnamed {
+ struct {
+ double xx;
+ } inner_struct_unnamed;
+ union {
+ double yy;
+ int zz;
+ } inner_union_unnamed;
+};
+
+
typedef struct OuterStruct {
union {
diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i
index ce45b2981..3b964f756 100644
--- a/Examples/test-suite/nested_class.i
+++ b/Examples/test-suite/nested_class.i
@@ -4,52 +4,94 @@
%inline %{
struct Outer {
+ typedef int Integer;
+ ///////////////////////////////////////////
struct InnerStruct1 {
- int x;
+ Integer x;
};
class InnerClass1 {
public:
- int x;
+ Integer x;
};
union InnerUnion1 {
- int x;
+ Integer x;
double y;
};
+ ///////////////////////////////////////////
class {
public:
- int a;
+ Integer a;
};
struct {
- int b;
+ Integer b;
};
union {
- int c;
+ Integer c;
double d;
};
+ ///////////////////////////////////////////
class InnerClass2 {
public:
- int x;
+ Integer x;
} InnerClass2Name;
struct InnerStruct2 {
- int x;
+ Integer x;
} InnerStruct2Name;
union InnerUnion2 {
- int x;
+ Integer x;
double y;
} InnerUnion2Name;
+ ///////////////////////////////////////////
+ class {
+ public:
+ Integer x;
+ } InnerClass3Name;
+
+ struct {
+ Integer x;
+ } InnerStruct3Name;
+
+ union {
+ Integer x;
+ double y;
+ } InnerUnion3Name;
+
+ ///////////////////////////////////////////
+ typedef class {
+ public:
+ Integer x;
+ } InnerClass4;
+
+ typedef struct {
+ Integer x;
+ } InnerStruct4;
+
+ typedef union {
+ Integer x;
+ double y;
+ } InnerUnion4;
+
// bug #909387 - inner declared types are treated as forward declarations
InnerStruct1* getInnerStruct1() { return 0; }
InnerClass1* getInnerClass1() { return 0; }
InnerUnion1* getInnerUnion1() { return 0; }
+
+ InnerStruct2* getInnerStruct2() { return 0; }
+ InnerClass2* getInnerClass2() { return 0; }
+ InnerUnion2* getInnerUnion2() { return 0; }
+
+ InnerStruct4* getInnerStruct4() { return 0; }
+ InnerClass4* getInnerClass4() { return 0; }
+ InnerUnion4* getInnerUnion4() { return 0; }
};
%}
diff --git a/Examples/test-suite/nested_workaround.i b/Examples/test-suite/nested_workaround.i
new file mode 100644
index 000000000..9727dacee
--- /dev/null
+++ b/Examples/test-suite/nested_workaround.i
@@ -0,0 +1,38 @@
+%module nested_workaround
+// Similar to "Nested classes" documentation example.
+
+class Inner {
+ int val;
+ public:
+ Inner(int v = 0) : val(v) {}
+ void setValue(int v) { val = v; }
+ int getValue() const { return val; }
+};
+%nestedworkaround Outer::Inner;
+
+%inline %{
+class Outer {
+public:
+ class Inner {
+ int val;
+ public:
+ Inner(int v = 0) : val(v) {}
+ void setValue(int v) { val = v; }
+ int getValue() const { return val; }
+ };
+ Inner createInner(int v) const { return Inner(v); }
+ int getInnerValue(const Inner& i) const { return i.getValue(); }
+ Inner doubleInnerValue(Inner inner) {
+ inner.setValue(inner.getValue() * 2);
+ return inner;
+ }
+};
+%}
+
+// We've fooled SWIG into thinking that Inner is a global class, so now we need
+// to trick the C++ compiler into understanding this apparent global type.
+%{
+typedef Outer::Inner Inner;
+%}
+
+
diff --git a/Examples/test-suite/python/nested_workaround_runme.py b/Examples/test-suite/python/nested_workaround_runme.py
new file mode 100644
index 000000000..a8a75d370
--- /dev/null
+++ b/Examples/test-suite/python/nested_workaround_runme.py
@@ -0,0 +1,13 @@
+from nested_workaround import *
+
+inner = Inner(5)
+outer = Outer()
+newInner = outer.doubleInnerValue(inner)
+if newInner.getValue() != 10:
+ raise RuntimeError
+
+outer = Outer()
+inner = outer.createInner(3)
+newInner = outer.doubleInnerValue(inner)
+if outer.getInnerValue(newInner) != 6:
+ raise RuntimeError
diff --git a/Lib/swig.swg b/Lib/swig.swg
index c0ecad9dd..af7fa6a30 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -136,6 +136,11 @@
#define %nocallback %feature("callback","0")
#define %clearcallback %feature("callback","")
+/* the %nestedworkaround directive */
+#define %nestedworkaround %feature("nestedworkaround")
+#define %nonestedworkaround %feature("nestedworkaround","0")
+#define %clearnestedworkaround %feature("nestedworkaround","")
+
/* the %fastdispatch directive */
#define %fastdispatch %feature("fastdispatch")
#define %nofastdispatch %feature("fastdispatch","0")
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 9c68cc647..295f0a60c 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -4374,18 +4374,33 @@ cpp_protection_decl : PUBLIC COLON {
by SWIG or this whole thing is going to puke.
---------------------------------------------------------------------- */
-/* A struct sname { } id; declaration */
+/* struct sname { } id; or struct sname { }; declaration */
cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
} nested_decl SEMI {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
- if ($6.id && strcmp($2, "class") != 0) {
+ if (cparse_cplusplus) {
+ /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */
+ $$ = new_node("classforward");
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"kind",$2);
+ Setattr($$,"name",$3);
+ Setattr($$,"sym:weak", "1");
+ add_symbols($$);
+
+ if (GetFlag($$, "feature:nestedworkaround")) {
+ Swig_symbol_remove($$);
+ $$ = 0;
+ } else {
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3);
+ }
+ } else if ($6.id) {
+ /* Generate some code for a new struct */
Nested *n = (Nested *) malloc(sizeof(Nested));
n->code = NewStringEmpty();
- Printv(n->code, "typedef ", $2, " ",
- Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL);
-
+ Printv(n->code, "typedef ", $2, " ", Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL);
n->name = Swig_copy_string($6.id);
n->line = cparse_start_line;
n->type = NewStringEmpty();
@@ -4394,50 +4409,53 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
SwigType_push(n->type, $6.type);
n->next = 0;
add_nested(n);
- } else {
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3);
-
- /* For now, just treat the nested class/struct/union as a forward
- * declaration (SF bug #909387). */
- $$ = new_node("classforward");
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- Setattr($$,"kind",$2);
- Setattr($$,"name",$3);
- Setattr($$,"sym:weak", "1");
- add_symbols($$);
}
}
}
-/* A struct { } id; declaration */
+
+/* struct { } id; or struct { }; declaration */
+
| storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
} nested_decl SEMI {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
- if (strcmp($2,"class") == 0) {
- if ($5.id)
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested class not currently supported (%s ignored)\n", $5.id);
- else
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
- } else if ($5.id) {
- /* Generate some code for a new class */
- Nested *n = (Nested *) malloc(sizeof(Nested));
- n->code = NewStringEmpty();
- Printv(n->code, "typedef ", $2, " " ,
- Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL);
- n->name = Swig_copy_string($5.id);
- n->line = cparse_start_line;
- n->type = NewStringEmpty();
- n->kind = $2;
- n->unnamed = 1;
- SwigType_push(n->type,$5.type);
- n->next = 0;
- add_nested(n);
+ if ($5.id) {
+ if (cparse_cplusplus) {
+ /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */
+ $$ = new_node("classforward");
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"kind",$2);
+ Setattr($$,"name",$5.id);
+ Setattr($$,"sym:weak", "1");
+ add_symbols($$);
+
+ if (GetFlag($$, "feature:nestedworkaround")) {
+ Swig_symbol_remove($$);
+ $$ = 0;
+ } else {
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $5.id);
+ }
+ } else {
+ /* Generate some code for a new struct */
+ Nested *n = (Nested *) malloc(sizeof(Nested));
+ n->code = NewStringEmpty();
+ Printv(n->code, "typedef ", $2, " " , Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL);
+ n->name = Swig_copy_string($5.id);
+ n->line = cparse_start_line;
+ n->type = NewStringEmpty();
+ n->kind = $2;
+ n->unnamed = 1;
+ SwigType_push(n->type,$5.type);
+ n->next = 0;
+ add_nested(n);
+ }
} else {
Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
}
}
}
+
/* A 'class name : base_list { };' declaration, always ignored */
/*****
This fixes derived_nested.i, but it adds one shift/reduce. Anyway,
@@ -4445,12 +4463,12 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
*****/
| storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
} SEMI {
-Printf(stdout, "cpp_nested (c)\n");
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $3);
}
}
+
/* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */
/*
| TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
index ae8a274c6..b5ed37c0c 100644
--- a/Source/Swig/symbol.c
+++ b/Source/Swig/symbol.c
@@ -1331,7 +1331,8 @@ void Swig_symbol_remove(Node *n) {
Setattr(symtab, symname, symnext);
fixovername = symnext; /* fix as symbol to remove is at head of linked list */
} else {
- Delattr(symtab, symname);
+ if (symname)
+ Delattr(symtab, symname);
}
}
if (symnext) {
From aa61c716a81d95ead028b34350cf98da87d68d14 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Thu, 12 Nov 2009 19:47:04 +0000
Subject: [PATCH 063/146] Stop generating uncompileable code when using nested
template classes in functions. Replace SWIGWARN_PARSE_NESTED_CLASS with
SWIGWARN_PARSE_NAMED_NESTED_CLASS and SWIGWARN_PARSE_UNNAMED_NESTED_CLASS for
named and unnamed nested classes respectively. Named nested class ignored
warnings can now be suppressed by name using %warnfilter
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11735 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 18 ++++++++
Doc/Manual/SWIGPlus.html | 4 +-
Doc/Manual/Warnings.html | 3 +-
Examples/test-suite/derived_nested.i | 5 ++-
Examples/test-suite/namespace_class.i | 3 +-
Examples/test-suite/nested_class.i | 14 +++++-
Examples/test-suite/nested_comment.i | 3 ++
Examples/test-suite/template_classes.i | 12 ------
Examples/test-suite/template_nested.i | 8 +++-
Examples/test-suite/union_scope.i | 1 +
Source/CParse/parser.y | 60 ++++++++++++++++++++------
Source/Include/swigwarn.h | 3 +-
12 files changed, 103 insertions(+), 31 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index e03d6773a..533c64dff 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,5 +1,23 @@
Version 1.3.41 (in progress)
============================
+
+2009-11-12: wsfulton
+ Fix usage of nested template classes so that compileable code is generated - the nested
+ template class is now treated like a normal nested classes that is as an opaque type
+ unless the nestedworkaround feature is used.
+
+2009-11-12: wsfulton
+ Replace SWIGWARN_PARSE_NESTED_CLASS with SWIGWARN_PARSE_NAMED_NESTED_CLASS and
+ SWIGWARN_PARSE_UNNAMED_NESTED_CLASS for named and unnamed nested classes respectively.
+
+ Named nested class ignored warnings can now be suppressed by name using %warnfilter, eg:
+
+ %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
+
+ but clearly unnamed nested classes cannot and the global suppression is still required, eg:
+
+ #pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
+
2009-11-11: wsfulton
Added the nestedworkaround feature as a way to use the full functionality of a nested class
(C++ mode only). It removes the nested class from SWIG's type information so it is as if SWIG
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index 936fd3fb1..3836c86a7 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -4714,7 +4714,8 @@ The easiest thing to do is turn a blind eye to the warning that SWIG generates,
-#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
+
class Outer {
public:
class Inner {
@@ -4830,6 +4831,7 @@ This should just be a last resort for unusual corner cases now as SWIG can parse
Compatibility Note: SWIG-1.3.40 and earlier versions did not have the nestedworkaround feature
and the generated code resulting from parsing nested classes did not always compile.
+Nested class warnings could also not be suppressed using %warnfilter.
diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html
index 1150c4dc5..15f3aa9d2 100644
--- a/Doc/Manual/Warnings.html
+++ b/Doc/Manual/Warnings.html
@@ -399,7 +399,7 @@ example.i(4): Syntax error in input.
308. Namespace alias 'name' not allowed here. Assuming 'name'
309. [private | protected] inheritance ignored.
310. Template 'name' was already wrapped as 'name' (ignored)
-312. Nested class not currently supported (name ignored).
+312. Unnamed nested class not currently supported (ignored).
313. Unrecognized extern type "name" (ignored).
314. 'identifier' is a lang keyword.
315. Nothing known about 'identifier'.
@@ -412,6 +412,7 @@ example.i(4): Syntax error in input.
322. Redundant redeclaration of 'name'.
323. Recursive scope inheritance of 'name'.
324. Named nested template instantiations not supported. Processing as if no name was given to %template().
+325. Nested class not currently supported (name ignored).
350. operator new ignored.
351. operator delete ignored.
352. operator+ ignored.
diff --git a/Examples/test-suite/derived_nested.i b/Examples/test-suite/derived_nested.i
index babcac0aa..9a7cfce07 100644
--- a/Examples/test-suite/derived_nested.i
+++ b/Examples/test-suite/derived_nested.i
@@ -3,7 +3,9 @@ This was reported in bug #909389 */
%module derived_nested
-#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::CC;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::DD;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::EE;
%inline %{
@@ -17,6 +19,7 @@ struct BB {
class CC { int y; };
class DD : public A { int z; };
struct EE : public A { int z; };
+ void useEE(const EE& e) {}
};
%}
diff --git a/Examples/test-suite/namespace_class.i b/Examples/test-suite/namespace_class.i
index 5e9545ce6..7dc9139cd 100644
--- a/Examples/test-suite/namespace_class.i
+++ b/Examples/test-suite/namespace_class.i
@@ -1,5 +1,7 @@
%module namespace_class
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Ala::Ola;
+
%inline %{
template void foobar(T t) {}
namespace test {
@@ -210,7 +212,6 @@ namespace a
%}
-#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
// %copyctor doesn't work with nested class workaround
%nocopyctor;
diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i
index 3b964f756..cccebb136 100644
--- a/Examples/test-suite/nested_class.i
+++ b/Examples/test-suite/nested_class.i
@@ -1,6 +1,18 @@
%module nested_class
-#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
+#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct1;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass1;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion1;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass2;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct2;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion2;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass3Name;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct3Name;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion3Name;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4;
%inline %{
struct Outer {
diff --git a/Examples/test-suite/nested_comment.i b/Examples/test-suite/nested_comment.i
index a9948eb0f..c246b8dab 100644
--- a/Examples/test-suite/nested_comment.i
+++ b/Examples/test-suite/nested_comment.i
@@ -1,5 +1,8 @@
%module nested_comment
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) s1::n;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) a::d;
+
// this example shows a problem with 'dump_nested' (parser.y).
// bug #949654
diff --git a/Examples/test-suite/template_classes.i b/Examples/test-suite/template_classes.i
index a05eb9b58..ebe13bd9f 100644
--- a/Examples/test-suite/template_classes.i
+++ b/Examples/test-suite/template_classes.i
@@ -3,12 +3,6 @@
%module template_classes
-
-#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
-
-%{
-%}
-
%inline %{
template
@@ -27,21 +21,16 @@ public:
private:
Point point;
-
template
struct pair2nd_eq
{
};
-
-
-
struct Foo : Point
{
};
Foo foo;
-
};
%}
@@ -49,4 +38,3 @@ private:
%template(PointInt) Point;
%template(RectangleInt) RectangleTest;
-
diff --git a/Examples/test-suite/template_nested.i b/Examples/test-suite/template_nested.i
index cb5eddb50..86b9230ae 100644
--- a/Examples/test-suite/template_nested.i
+++ b/Examples/test-suite/template_nested.i
@@ -2,7 +2,11 @@
// Test nested templates - that is template classes and template methods within a class.
-#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterClass::Inner1;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterClass::Inner2;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate1;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate2;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedStruct;
%inline %{
@@ -33,6 +37,7 @@ namespace ns {
void method1(Y y) {}
};
};
+ Inner1 useInner1(const Inner1& inner) { return inner; }
template void InnerTMethod(Z z) {}
@@ -52,6 +57,7 @@ namespace ns {
void method1(Y y) {}
};
};
+ Inner2 useInner2(const Inner2& inner) { return inner; }
int iii;
};
struct ABC {
diff --git a/Examples/test-suite/union_scope.i b/Examples/test-suite/union_scope.i
index 67093eff6..a41b30406 100644
--- a/Examples/test-suite/union_scope.i
+++ b/Examples/test-suite/union_scope.i
@@ -2,6 +2,7 @@
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState; // Ruby, wrong class name
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState_rstate; // Ruby, wrong class name
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) nRState::rstate;
%inline %{
class nRState {
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 295f0a60c..f310d489b 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -3645,12 +3645,30 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN {
if (nested_template <= 1) {
int is_nested_template_class = $6 && GetFlag($6, "nestedtemplateclass");
if (is_nested_template_class) {
+ $$ = 0;
/* Nested template classes would probably better be ignored like ordinary nested classes using cpp_nested, but that introduces shift/reduce conflicts */
if (cplus_mode == CPLUS_PUBLIC) {
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested template %s not currently supported (%s ignored)\n", Getattr($6, "kind"), Getattr($6, "name"));
+ /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */
+ String *kind = Getattr($6, "kind");
+ String *name = Getattr($6, "name");
+ $$ = new_node("template");
+ Setattr($$,"kind",kind);
+ Setattr($$,"name",name);
+ Setattr($$,"sym:weak", "1");
+ Setattr($$,"templatetype","classforward");
+ Setattr($$,"templateparms", $3);
+ add_symbols($$);
+
+ if (GetFlag($$, "feature:nestedworkaround")) {
+ Swig_symbol_remove($$);
+ $$ = 0;
+ } else {
+ SWIG_WARN_NODE_BEGIN($$);
+ Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested template %s not currently supported (%s ignored).\n", kind, name);
+ SWIG_WARN_NODE_END($$);
+ }
}
Delete($6);
- $$ = 0;
} else {
String *tname = 0;
int error = 0;
@@ -4394,7 +4412,9 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
Swig_symbol_remove($$);
$$ = 0;
} else {
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3);
+ SWIG_WARN_NODE_BEGIN($$);
+ Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3);
+ SWIG_WARN_NODE_END($$);
}
} else if ($6.id) {
/* Generate some code for a new struct */
@@ -4434,7 +4454,9 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
Swig_symbol_remove($$);
$$ = 0;
} else {
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $5.id);
+ SWIG_WARN_NODE_BEGIN($$);
+ Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $5.id);
+ SWIG_WARN_NODE_END($$);
}
} else {
/* Generate some code for a new struct */
@@ -4451,21 +4473,35 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
add_nested(n);
}
} else {
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
+ Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
}
}
}
-/* A 'class name : base_list { };' declaration, always ignored */
-/*****
- This fixes derived_nested.i, but it adds one shift/reduce. Anyway,
- we are waiting for the nested class support.
- *****/
+/* class name : base_list { }; declaration */
+/* This adds one shift/reduce. */
+
| storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
} SEMI {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $3);
+ /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */
+ $$ = new_node("classforward");
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"kind",$2);
+ Setattr($$,"name",$3);
+ Setattr($$,"sym:weak", "1");
+ add_symbols($$);
+
+ if (GetFlag($$, "feature:nestedworkaround")) {
+ Swig_symbol_remove($$);
+ $$ = 0;
+ } else {
+ SWIG_WARN_NODE_BEGIN($$);
+ Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3);
+ SWIG_WARN_NODE_END($$);
+ }
}
}
@@ -4475,7 +4511,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
} SEMI {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
- Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $5, $6);
+ Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $5, $6);
}
}
*/
diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h
index 6c54c55bd..b400fbdeb 100644
--- a/Source/Include/swigwarn.h
+++ b/Source/Include/swigwarn.h
@@ -72,7 +72,7 @@
#define WARN_PARSE_PRIVATE_INHERIT 309
#define WARN_PARSE_TEMPLATE_REPEAT 310
#define WARN_PARSE_TEMPLATE_PARTIAL 311
-#define WARN_PARSE_NESTED_CLASS 312
+#define WARN_PARSE_UNNAMED_NESTED_CLASS 312
#define WARN_PARSE_UNDEFINED_EXTERN 313
#define WARN_PARSE_KEYWORD 314
#define WARN_PARSE_USING_UNDEF 315
@@ -85,6 +85,7 @@
#define WARN_PARSE_REDUNDANT 322
#define WARN_PARSE_REC_INHERITANCE 323
#define WARN_PARSE_NESTED_TEMPLATE 324
+#define WARN_PARSE_NAMED_NESTED_CLASS 325
#define WARN_IGNORE_OPERATOR_NEW 350 /* new */
#define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */
From dd5714ea28db35cb31badfc686026aba909c86c3 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Fri, 13 Nov 2009 07:15:08 +0000
Subject: [PATCH 064/146] [php] Fix place where class prefix (as specified with
-prefix) wasn't being used. Patch from gverbruggen in SF#2892647.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11736 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 4 ++++
Source/Modules/php.cxx | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/CHANGES.current b/CHANGES.current
index 533c64dff..6cfdc012a 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,10 @@
Version 1.3.41 (in progress)
============================
+2009-11-13: olly
+ [php] Fix place where class prefix (as specified with -prefix)
+ wasn't being used. Patch from gverbruggen in SF#2892647.
+
2009-11-12: wsfulton
Fix usage of nested template classes so that compileable code is generated - the nested
template class is now treated like a normal nested classes that is as an opaque type
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index eee4d1fcc..cbad1ee84 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -1684,7 +1684,7 @@ public:
Printf(output, "\t\t\t$c='%s'.substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n", prefix);
}
Printf(output, "\t\t\tif (!class_exists($c)) {\n");
- Printf(output, "\t\t\t\treturn new %s($r);\n", Getattr(classLookup(d), "sym:name"));
+ Printf(output, "\t\t\t\treturn new %s%s($r);\n", prefix, Getattr(classLookup(d), "sym:name"));
Printf(output, "\t\t\t}\n");
Printf(output, "\t\t\treturn new $c($r);\n");
} else {
From b502f4fc5aa70e6d16d10787514f0e80d8562a63 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 13 Nov 2009 08:04:01 +0000
Subject: [PATCH 065/146] Fix usage of nested template classes within templated
classes so that compileable code is generated.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11737 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 6 +++++-
Examples/test-suite/template_nested.i | 19 +++++++++++++++++++
Source/Swig/stype.c | 8 +++++++-
3 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 6cfdc012a..58742c56f 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,13 +1,17 @@
Version 1.3.41 (in progress)
============================
+2009-11-13: wsfulton
+ Fix usage of nested template classes within templated classes so that compileable code
+ is generated.
+
2009-11-13: olly
[php] Fix place where class prefix (as specified with -prefix)
wasn't being used. Patch from gverbruggen in SF#2892647.
2009-11-12: wsfulton
Fix usage of nested template classes so that compileable code is generated - the nested
- template class is now treated like a normal nested classes that is as an opaque type
+ template class is now treated like a normal nested classes, that is, as an opaque type
unless the nestedworkaround feature is used.
2009-11-12: wsfulton
diff --git a/Examples/test-suite/template_nested.i b/Examples/test-suite/template_nested.i
index 86b9230ae..1bb1c686a 100644
--- a/Examples/test-suite/template_nested.i
+++ b/Examples/test-suite/template_nested.i
@@ -6,8 +6,20 @@
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterClass::Inner2;
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate1;
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate2;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate3;
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedStruct;
+namespace ns {
+template struct ForwardTemplate;
+}
+%{
+namespace ns {
+ template struct ForwardTemplate {
+ void tmethod(T t) {}
+ };
+}
+%}
+
%inline %{
namespace ns {
@@ -80,10 +92,17 @@ namespace ns {
void hohum() {}
};
UU hohum(UU u) { return u; }
+ template struct NestedInnerTemplate3 : public NestedInnerTemplate2 {
+ void hohum() {}
+ };
struct NestedStruct {
NestedStruct() {}
void hohum() {}
};
+ NestedInnerTemplate1 useNestedInnerTemplate1(const NestedInnerTemplate1& inner) { return inner; }
+ NestedInnerTemplate2 useNestedInnerTemplate2(const NestedInnerTemplate2& inner) { return inner; }
+ NestedInnerTemplate3 useNestedInnerTemplate3(const NestedInnerTemplate3& inner) { return inner; }
+ NestedStruct useNestedStruct(const NestedStruct& inner) { return inner; }
};
}
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c
index 8a7700bec..aa5d448a3 100644
--- a/Source/Swig/stype.c
+++ b/Source/Swig/stype.c
@@ -525,7 +525,13 @@ String *SwigType_namestr(const SwigType *t) {
Putc(' ', r);
Putc('>', r);
suffix = SwigType_templatesuffix(t);
- Append(r, suffix);
+ if (Len(suffix) > 0) {
+ String *suffix_namestr = SwigType_namestr(suffix);
+ Append(r, suffix_namestr);
+ Delete(suffix_namestr);
+ } else {
+ Append(r, suffix);
+ }
Delete(suffix);
Delete(p);
return r;
From 1b951d68f4194efd46a389ca8bd56a400b224053 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 13 Nov 2009 18:27:41 +0000
Subject: [PATCH 066/146] nested classes code refactor
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11738 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Source/CParse/parser.y | 81 ++++++++++++++++--------------------------
1 file changed, 30 insertions(+), 51 deletions(-)
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index f310d489b..886e77fd8 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -1428,6 +1428,33 @@ static void default_arguments(Node *n) {
}
}
+/* -----------------------------------------------------------------------------
+ * nested_forward_declaration()
+ *
+ * Treat the nested class/struct/union as a forward declaration until a proper
+ * nested class solution is implemented.
+ * ----------------------------------------------------------------------------- */
+
+static Node *nested_forward_declaration(const char *kind, const char *name) {
+ Node *n = new_node("classforward");
+ Setfile(n,cparse_file);
+ Setline(n,cparse_line);
+ Setattr(n,"kind", kind);
+ Setattr(n,"name", name);
+ Setattr(n,"sym:weak", "1");
+ add_symbols(n);
+
+ if (GetFlag(n, "feature:nestedworkaround")) {
+ Swig_symbol_remove(n);
+ n = 0;
+ } else {
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name);
+ SWIG_WARN_NODE_END(n);
+ }
+ return n;
+}
+
/* -----------------------------------------------------------------------------
* tag_nodes()
*
@@ -4399,23 +4426,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
if (cparse_cplusplus) {
- /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */
- $$ = new_node("classforward");
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- Setattr($$,"kind",$2);
- Setattr($$,"name",$3);
- Setattr($$,"sym:weak", "1");
- add_symbols($$);
-
- if (GetFlag($$, "feature:nestedworkaround")) {
- Swig_symbol_remove($$);
- $$ = 0;
- } else {
- SWIG_WARN_NODE_BEGIN($$);
- Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3);
- SWIG_WARN_NODE_END($$);
- }
+ $$ = nested_forward_declaration($2, $3);
} else if ($6.id) {
/* Generate some code for a new struct */
Nested *n = (Nested *) malloc(sizeof(Nested));
@@ -4441,23 +4452,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
if (cplus_mode == CPLUS_PUBLIC) {
if ($5.id) {
if (cparse_cplusplus) {
- /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */
- $$ = new_node("classforward");
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- Setattr($$,"kind",$2);
- Setattr($$,"name",$5.id);
- Setattr($$,"sym:weak", "1");
- add_symbols($$);
-
- if (GetFlag($$, "feature:nestedworkaround")) {
- Swig_symbol_remove($$);
- $$ = 0;
- } else {
- SWIG_WARN_NODE_BEGIN($$);
- Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $5.id);
- SWIG_WARN_NODE_END($$);
- }
+ $$ = nested_forward_declaration($2, $5.id);
} else {
/* Generate some code for a new struct */
Nested *n = (Nested *) malloc(sizeof(Nested));
@@ -4485,23 +4480,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
} SEMI {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
- /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */
- $$ = new_node("classforward");
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- Setattr($$,"kind",$2);
- Setattr($$,"name",$3);
- Setattr($$,"sym:weak", "1");
- add_symbols($$);
-
- if (GetFlag($$, "feature:nestedworkaround")) {
- Swig_symbol_remove($$);
- $$ = 0;
- } else {
- SWIG_WARN_NODE_BEGIN($$);
- Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3);
- SWIG_WARN_NODE_END($$);
- }
+ $$ = nested_forward_declaration($2, $3);
}
}
From cd53dc68eeb48fab248fdea57293c75ececa4e86 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 13 Nov 2009 18:34:54 +0000
Subject: [PATCH 067/146] remove SWIGMAC and SWIGWIN32/SWIGWIN macros which
have no effect
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11739 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Doc/Manual/Preprocessor.html | 2 --
Source/Modules/main.cxx | 6 ------
2 files changed, 8 deletions(-)
diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html
index 5afa59243..2dd79dac5 100644
--- a/Doc/Manual/Preprocessor.html
+++ b/Doc/Manual/Preprocessor.html
@@ -102,8 +102,6 @@ by SWIG when it is parsing the interface:
SWIG Always defined when SWIG is processing a file
SWIGIMPORTED Defined when SWIG is importing a file with %import
-SWIGMAC Defined when running SWIG on the Macintosh
-SWIGWIN Defined when running SWIG under Windows
SWIG_VERSION Hexadecimal number containing SWIG version,
such as 0x010311 (corresponding to SWIG-1.3.11).
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index 30d12f26b..4903416cd 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -844,12 +844,6 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Preprocessor_define((DOH *) "SWIG 1", 0);
Preprocessor_define((DOH *) "__STDC__", 0);
-#ifdef MACSWIG
- Preprocessor_define((DOH *) "SWIGMAC 1", 0);
-#endif
-#ifdef SWIGWIN32
- Preprocessor_define((DOH *) "SWIGWIN32 1", 0);
-#endif
// Set the SWIG version value in format 0xAABBCC from package version expected to be in format A.B.C
String *package_version = NewString(PACKAGE_VERSION); /* Note that the fakeversion has not been set at this point */
From 2bf42357e0e420d024b7a3628d997cd8e93907ae Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 13 Nov 2009 19:04:28 +0000
Subject: [PATCH 068/146] fix suggested casts for displaying SWIG types in a
debugger
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11740 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Doc/Devel/internals.html | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/Doc/Devel/internals.html b/Doc/Devel/internals.html
index d27ec12fa..63a8626ff 100644
--- a/Doc/Devel/internals.html
+++ b/Doc/Devel/internals.html
@@ -1070,25 +1070,25 @@ With each is the cast that can be used in the debugger to extract the underlying
String *s;
-(String *)((DohBase *)s)->data
+(struct String *)((DohBase *)s)->data
The underlying char * string can be displayed with
-((String *)((DohBase *)s)->data)->str
+(*(struct String *)(((DohBase *)s)->data)).str
SwigType *t;
-(String *)((DohBase *)t)->data
+(struct String *)((DohBase *)t)->data
The underlying char * string can be displayed with
-((String *)((DohBase *)t)->data)->str
+(*(struct String *)(((DohBase *)t)->data)).str
-
String_or_char *sc;
+const_String_or_char_ptr sc;
Either
-((String *)((DohBase *)sc)->data)->str
+(*(struct String *)(((DohBase *)sc)->data)).str
or
(char *)sc
will work depending on whether the underlying type is really a String * or char *.
From 0509dbb95152a25aaa927a96ef70ca0f952b8444 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 13 Nov 2009 19:21:33 +0000
Subject: [PATCH 069/146] some parser code comments added
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11741 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Source/CParse/parser.y | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 886e77fd8..81663abf8 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -859,6 +859,12 @@ static String *remove_block(Node *kw, const String *inputcode) {
static Node *nscope = 0;
static Node *nscope_inner = 0;
+
+/* Remove the scope prefix from cname and return the base name without the prefix.
+ * The scopes specified in the prefix are found, or created in the current namespace.
+ * So ultimately the scope is changed to that required for the base name.
+ * For example AA::BB::CC as input returns CC and creates the namespace AA then inner
+ * namespace BB in the current scope. If no scope separator (::) in the input, then nothing happens! */
static String *resolve_node_scope(String *cname) {
Symtab *gscope = 0;
nscope = 0;
@@ -2848,10 +2854,10 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
Swig_symbol_setscope(csyms);
}
- /* Merge in addmethods for this class */
+ /* Merge in %extend methods for this class */
/* !!! This may be broken. We may have to add the
- addmethods at the beginning of the class */
+ %extend methods at the beginning of the class */
if (extendhash) {
String *stmp = 0;
From 7ae45bc020e463f6b6ad3062607370b86af8e624 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 14 Nov 2009 15:55:23 +0000
Subject: [PATCH 070/146] Fix #2310483 - function pointer typedef within extern
C block.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11742 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 3 +++
Examples/test-suite/common.mk | 1 +
Examples/test-suite/extern_c.i | 16 ++++++++++++++++
Examples/test-suite/python/extern_c_runme.py | 4 ++++
Source/CParse/parser.y | 2 +-
5 files changed, 25 insertions(+), 1 deletion(-)
create mode 100644 Examples/test-suite/extern_c.i
create mode 100644 Examples/test-suite/python/extern_c_runme.py
diff --git a/CHANGES.current b/CHANGES.current
index 58742c56f..8469fa815 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,9 @@
Version 1.3.41 (in progress)
============================
+2009-11-14: wsfulton
+ Fix #2310483 - function pointer typedef within extern "C" block.
+
2009-11-13: wsfulton
Fix usage of nested template classes within templated classes so that compileable code
is generated.
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 93c1cc909..d7882a462 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -191,6 +191,7 @@ CPP_TEST_CASES += \
extend_placement \
extend_template \
extend_template_ns \
+ extern_c \
extern_namespace \
extern_throws \
features \
diff --git a/Examples/test-suite/extern_c.i b/Examples/test-suite/extern_c.i
new file mode 100644
index 000000000..9c17d18fb
--- /dev/null
+++ b/Examples/test-suite/extern_c.i
@@ -0,0 +1,16 @@
+%module extern_c
+
+%inline %{
+extern "C" {
+void RealFunction(int value);
+typedef void Function1(int value); // Fails
+typedef int Integer1;
+}
+typedef void Function2(int value); // Works
+typedef int Integer2;
+%}
+
+%{
+void RealFunction(int value) {}
+%}
+
diff --git a/Examples/test-suite/python/extern_c_runme.py b/Examples/test-suite/python/extern_c_runme.py
new file mode 100644
index 000000000..1a6d2aa12
--- /dev/null
+++ b/Examples/test-suite/python/extern_c_runme.py
@@ -0,0 +1,4 @@
+import extern_c
+
+extern_c.RealFunction(2)
+
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 81663abf8..f78d5255b 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -2965,7 +2965,7 @@ c_declaration : c_decl {
appendChild($$,n);
while (n) {
SwigType *decl = Getattr(n,"decl");
- if (SwigType_isfunction(decl)) {
+ if (SwigType_isfunction(decl) && Strcmp(Getattr(n, "storage"), "typedef") != 0) {
Setattr(n,"storage","externc");
}
n = nextSibling(n);
From e0dd20350f434bce0edc5dfa5c4401c9b77f937c Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 14 Nov 2009 21:50:41 +0000
Subject: [PATCH 071/146] Add caveat about using percent in varargs example as
per suggestion in bug #2106353
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11743 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Examples/python/class/example.i | 8 +----
Examples/python/class/runme.py | 55 +++++----------------------------
2 files changed, 8 insertions(+), 55 deletions(-)
diff --git a/Examples/python/class/example.i b/Examples/python/class/example.i
index 75700b305..aa28dde80 100644
--- a/Examples/python/class/example.i
+++ b/Examples/python/class/example.i
@@ -1,10 +1,4 @@
/* File : example.i */
%module example
-%{
-#include "example.h"
-%}
-
-/* Let's just grab the original header file here */
-%include "example.h"
-
+int printf(const char *fmt, ...);
diff --git a/Examples/python/class/runme.py b/Examples/python/class/runme.py
index f1272ae81..54543be67 100644
--- a/Examples/python/class/runme.py
+++ b/Examples/python/class/runme.py
@@ -1,51 +1,10 @@
-# file: runme.py
-# This file illustrates the proxy class C++ interface generated
-# by SWIG.
+from example import *
-import example
-
-# ----- Object creation -----
-
-print "Creating some objects:"
-c = example.Circle(10)
-print " Created circle", c
-s = example.Square(10)
-print " Created square", s
-
-# ----- Access a static member -----
-
-print "\nA total of", example.cvar.Shape_nshapes,"shapes were created"
-
-# ----- Member data access -----
-
-# Set the location of the object
-
-c.x = 20
-c.y = 30
-
-s.x = -10
-s.y = 5
-
-print "\nHere is their current position:"
-print " Circle = (%f, %f)" % (c.x,c.y)
-print " Square = (%f, %f)" % (s.x,s.y)
-
-# ----- Call some methods -----
-
-print "\nHere are some properties of the shapes:"
-for o in [c,s]:
- print " ", o
- print " area = ", o.area()
- print " perimeter = ", o.perimeter()
-
-print "\nGuess I'll clean up now"
-
-# Note: this invokes the virtual destructor
-del c
-del s
-
-s = 3
-print example.cvar.Shape_nshapes,"shapes remain"
-print "Goodbye"
+printf("hello\n")
+name = "%shoot"
+num = 22
+printf("Hello %s. Your number is %d\n" % (name, num))
+print("hello there %s." % name);
+printf("Your result is 90%.\n")
From 22c0c8ea9798ec79dcce647a5eb1c617457f19c7 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 14 Nov 2009 21:54:18 +0000
Subject: [PATCH 072/146] Minor change to previous commit about varargs
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11744 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Doc/Manual/Varargs.html | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html
index f40a1ff1f..fb34a3ad9 100644
--- a/Doc/Manual/Varargs.html
+++ b/Doc/Manual/Varargs.html
@@ -270,21 +270,37 @@ traceprintf(arg1, NULL);
Arguably, this approach seems to defeat the whole point of variable length arguments. However,
-this actually provides enough support for many simple kinds of varargs functions to still be useful. For
-instance, you could make function calls like this (in Python):
+this actually provides enough support for many simple kinds of varargs functions to still be useful, however it does come with a caveat.
+For instance, you could make function calls like this (in Python):
>>> traceprintf("Hello World")
>>> traceprintf("Hello %s. Your number is %d\n" % (name, num))
+>>> traceprintf("Your result is 90%%.")
Notice how string formatting is being done in Python instead of C.
+The caveat is the strings passed must be safe to use in C though.
+For example if name was to contain a "%" it should be double escaped in order to avoid unpredictable
+behaviour:
+
+
+>>> traceprintf("Your result is 90%.\n") # unpredictable behaviour
+>>> traceprintf("Your result is 90%%.\n") # good
+
+
+
+
+Read on for further solutions.
+
+
+
13.4 Argument replacement using %varargs
From dde16ac54a26f7a844f666396c90f5c72c5df648 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 14 Nov 2009 22:07:51 +0000
Subject: [PATCH 073/146] Removed empty sections
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11745 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Doc/Manual/Python.html | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html
index a739543df..fcaebc014 100644
--- a/Doc/Manual/Python.html
+++ b/Doc/Manual/Python.html
@@ -3854,15 +3854,6 @@ If you need to return binary data, you might use the
also be used to extra binary data from arbitrary pointers.
-31.7.5 Arrays
-
-
-31.7.6 String arrays
-
-
-31.7.7 STL wrappers
-
-
31.8 Typemaps
From 5ea1852ecb1515ac45fc333bd737ec7931f5c44f Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 14 Nov 2009 23:51:12 +0000
Subject: [PATCH 074/146] namespace_union.i now works given recent nested class
improvements. Closes bug #811906
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11746 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Examples/test-suite/common.mk | 2 +-
Examples/test-suite/namespace_union.i | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index d7882a462..c8ca09013 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -80,7 +80,6 @@ CPP_TEST_BROKEN += \
exception_partial_info \
extend_variable \
li_std_vector_ptr \
- namespace_union \
nested_structs \
overload_complicated \
template_default_pointer \
@@ -241,6 +240,7 @@ CPP_TEST_CASES += \
namespace_template \
namespace_typedef_class \
namespace_typemap \
+ namespace_union \
namespace_virtual_method \
naturalvar \
nested_class \
diff --git a/Examples/test-suite/namespace_union.i b/Examples/test-suite/namespace_union.i
index edade9640..70698682e 100644
--- a/Examples/test-suite/namespace_union.i
+++ b/Examples/test-suite/namespace_union.i
@@ -1,4 +1,7 @@
%module namespace_union
+
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) SpatialIndex::Variant::val;
+
%inline %{
namespace SpatialIndex
{
From 107c61d979480a4777e836f019dc1ea2530e6c56 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 15 Nov 2009 00:05:25 +0000
Subject: [PATCH 075/146] Remove bugs which have been fixed over time from
cpp_broken.i
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11747 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Examples/test-suite/cpp_broken.i | 63 --------------------------------
1 file changed, 63 deletions(-)
diff --git a/Examples/test-suite/cpp_broken.i b/Examples/test-suite/cpp_broken.i
index fe109ea43..84d6122e5 100644
--- a/Examples/test-suite/cpp_broken.i
+++ b/Examples/test-suite/cpp_broken.i
@@ -1,36 +1,6 @@
%module cpp_broken
-// bug #1060789
-%inline %{
-#define MASK(shift, size) (((1 << (size)) - 1) << (shift))
-#define SOME_MASK_DEF (80*MASK(8, 10))
-%}
-
-// bug #1060079
-%inline %{
-#define FIELD(name, width) unsigned int name:width
-#define SOME_CONST 2
-#define NEXT_CONST (2 * SOME_CONST)
-
-typedef struct {
-FIELD(a, SOME_CONST);
-FIELD(b, NEXT_CONST);
-} MyStruct_t;
-%}
-
-%{
-#ifdef max
-#undef max
-#endif
-%}
-
-// bug #994301
-%inline %{
-#define max(a,b) ((a) > (b) ? (a) : (b))
-%}
-
-
// bug #940318
%inline %{
typedef enum {
@@ -40,36 +10,3 @@ eZero = 0
%}
-// bug #754443
-
-%inline %{
-#define MAG_STYLE_BORDER_OFFS 0
-#define MAG_STYLE_BORDER_BITS 3
-#define MAG_STYLE_BORDER_MASK (((1UL<
Date: Sun, 15 Nov 2009 00:36:22 +0000
Subject: [PATCH 076/146] Fix #1960977 - Syntax error parsing derived nested
class declaration and member variable instance
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11748 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 4 ++++
Examples/test-suite/derived_nested.i | 2 ++
Source/CParse/parser.y | 2 +-
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGES.current b/CHANGES.current
index 8469fa815..3d5c27950 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,10 @@
Version 1.3.41 (in progress)
============================
+2009-11-15: wsfulton
+ Fix #1960977 - Syntax error parsing derived nested class declaration and member
+ variable instance.
+
2009-11-14: wsfulton
Fix #2310483 - function pointer typedef within extern "C" block.
diff --git a/Examples/test-suite/derived_nested.i b/Examples/test-suite/derived_nested.i
index 9a7cfce07..29114d5a0 100644
--- a/Examples/test-suite/derived_nested.i
+++ b/Examples/test-suite/derived_nested.i
@@ -6,6 +6,7 @@ This was reported in bug #909389 */
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::CC;
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::DD;
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::EE;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::FF;
%inline %{
@@ -19,6 +20,7 @@ struct BB {
class CC { int y; };
class DD : public A { int z; };
struct EE : public A { int z; };
+ struct FF : public A { int z; } ff_instance; // Bug 1960977
void useEE(const EE& e) {}
};
%}
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index f78d5255b..b87ba9368 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -4483,7 +4483,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
/* This adds one shift/reduce. */
| storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
- } SEMI {
+ } cpp_opt_declarators {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
$$ = nested_forward_declaration($2, $3);
From 7fd36f5bd6c28331cf9375dc9d35fb5c58aecce3 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 17 Nov 2009 18:45:53 +0000
Subject: [PATCH 077/146] Fix parsing of struct declaration and initialization
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11750 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 7 +++++
Examples/test-suite/common.mk | 2 ++
.../python/struct_initialization_runme.py | 20 ++++++++++++
Examples/test-suite/struct_initialization.i | 31 +++++++++++++++++++
.../test-suite/struct_initialization_cpp.i | 5 +++
Source/CParse/parser.y | 10 +++---
6 files changed, 70 insertions(+), 5 deletions(-)
create mode 100644 Examples/test-suite/python/struct_initialization_runme.py
create mode 100644 Examples/test-suite/struct_initialization.i
create mode 100644 Examples/test-suite/struct_initialization_cpp.i
diff --git a/CHANGES.current b/CHANGES.current
index 3d5c27950..e97bbc58a 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,13 @@
Version 1.3.41 (in progress)
============================
+2009-11-17: wsfulton
+ Fix parsing of struct declaration and initialization, for example:
+
+ struct S {
+ int x;
+ } instance = { 10 };
+
2009-11-15: wsfulton
Fix #1960977 - Syntax error parsing derived nested class declaration and member
variable instance.
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index c8ca09013..db28917ef 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -303,6 +303,7 @@ CPP_TEST_CASES += \
static_array_member \
static_const_member \
static_const_member_2 \
+ struct_initialization_cpp \
struct_value \
template \
template_arg_replace \
@@ -470,6 +471,7 @@ C_TEST_CASES += \
sizeof_pointer \
sneaky1 \
struct_rename \
+ struct_initialization \
typedef_struct \
typemap_subst \
union_parameter \
diff --git a/Examples/test-suite/python/struct_initialization_runme.py b/Examples/test-suite/python/struct_initialization_runme.py
new file mode 100644
index 000000000..fbed6a5e9
--- /dev/null
+++ b/Examples/test-suite/python/struct_initialization_runme.py
@@ -0,0 +1,20 @@
+from struct_initialization import *
+
+if cvar.instanceC1.x != 10:
+ raise RuntimeError
+
+if cvar.instanceD1.x != 10:
+ raise RuntimeError
+
+if cvar.instanceD2.x != 20:
+ raise RuntimeError
+
+if cvar.instanceD3.x != 30:
+ raise RuntimeError
+
+if cvar.instanceE1.x != 1:
+ raise RuntimeError
+
+if cvar.instanceF1.x != 1:
+ raise RuntimeError
+
diff --git a/Examples/test-suite/struct_initialization.i b/Examples/test-suite/struct_initialization.i
new file mode 100644
index 000000000..c378ba31d
--- /dev/null
+++ b/Examples/test-suite/struct_initialization.i
@@ -0,0 +1,31 @@
+// Test declaration and initialization of structs (C code)
+%module struct_initialization
+
+%inline %{
+
+// Named types
+struct StructA {
+ int x;
+} instanceA1;
+
+struct StructB {
+ int x;
+} instanceB1, instanceB2, instanceB3;
+
+struct StructC {
+ int x;
+} instanceC1 = { 10 };
+
+struct StructD {
+ int x;
+} instanceD1 = { 10 }, instanceD2 = { 20 }, instanceD3 = { 30 };
+
+struct StructE {
+ int x;
+} instanceE1[3] = { { 1 }, { 2 }, { 3} };
+
+struct StructF {
+ int x;
+} instanceF1[3] = { { 1 }, { 2 } }, instanceF2[2] = { { -1 }, { -2 } }, instanceF3[2] = { { 11 }, { 22 } };
+
+%}
diff --git a/Examples/test-suite/struct_initialization_cpp.i b/Examples/test-suite/struct_initialization_cpp.i
new file mode 100644
index 000000000..dc47077b5
--- /dev/null
+++ b/Examples/test-suite/struct_initialization_cpp.i
@@ -0,0 +1,5 @@
+// Test declaration and initialization of structs (C++ code)
+%module struct_initialization_cpp
+
+%include "struct_initialization.i" // C code
+
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index b87ba9368..0da3666f8 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -3546,7 +3546,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
Classprefix = NewStringEmpty();
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- } cpp_members RBRACE declarator c_decl_tail {
+ } cpp_members RBRACE declarator initializer c_decl_tail {
String *unnamed;
Node *n;
Classprefix = 0;
@@ -3564,8 +3564,8 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
Setattr(n,"decl",$7.type);
Setattr(n,"parms",$7.parms);
Setattr(n,"storage",$1);
- if ($8) {
- Node *p = $8;
+ if ($9) {
+ Node *p = $9;
set_nextSibling(n,p);
while (p) {
String *type = Copy(unnamed);
@@ -3635,12 +3635,12 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
;
cpp_opt_declarators : SEMI { $$ = 0; }
- | declarator c_decl_tail {
+ | declarator initializer c_decl_tail {
$$ = new_node("cdecl");
Setattr($$,"name",$1.id);
Setattr($$,"decl",$1.type);
Setattr($$,"parms",$1.parms);
- set_nextSibling($$,$2);
+ set_nextSibling($$,$3);
}
;
/* ------------------------------------------------------------
From f62c54c0f6d8a177580c9a715321f54cddae0e2c Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 17 Nov 2009 19:28:29 +0000
Subject: [PATCH 078/146] add missing nested_workaround runtime test
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11751 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
.../java/nested_workaround_runme.java | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 Examples/test-suite/java/nested_workaround_runme.java
diff --git a/Examples/test-suite/java/nested_workaround_runme.java b/Examples/test-suite/java/nested_workaround_runme.java
new file mode 100644
index 000000000..761a2da8e
--- /dev/null
+++ b/Examples/test-suite/java/nested_workaround_runme.java
@@ -0,0 +1,31 @@
+import nested_workaround.*;
+
+public class nested_workaround_runme {
+
+ static {
+ try {
+ System.loadLibrary("nested_workaround");
+ } 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[]) {
+ {
+ Inner inner = new Inner(5);
+ Outer outer = new Outer();
+ Inner newInner = outer.doubleInnerValue(inner);
+ if (newInner.getValue() != 10)
+ throw new RuntimeException("inner failed");
+ }
+
+ {
+ Outer outer = new Outer();
+ Inner inner = outer.createInner(3);
+ Inner newInner = outer.doubleInnerValue(inner);
+ if (outer.getInnerValue(newInner) != 6)
+ throw new RuntimeException("inner failed");
+ }
+ }
+}
From 7cb4e902d59aa73009cd4f928d5470fa68803f36 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 17 Nov 2009 19:31:13 +0000
Subject: [PATCH 079/146] Fix parsing of enum declaration and initialization
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11752 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 9 +++++++++
Examples/test-suite/enums.i | 20 ++++++++++++++++++--
Examples/test-suite/octave/enums_runme.m | 16 ++++++++++++++++
Examples/test-suite/python/enums_runme.py | 12 ++++++++++++
Source/CParse/parser.y | 6 +++---
5 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index e97bbc58a..bc28d8fc1 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,15 @@
Version 1.3.41 (in progress)
============================
+2009-11-17: wsfulton
+ Fix parsing of enum declaration and initialization, for example:
+
+ enum ABC {
+ a,
+ b,
+ c
+ } A = a, *pC = &C, array[3] = {a, b, c};
+
2009-11-17: wsfulton
Fix parsing of struct declaration and initialization, for example:
diff --git a/Examples/test-suite/enums.i b/Examples/test-suite/enums.i
index 00499f800..40be28e94 100644
--- a/Examples/test-suite/enums.i
+++ b/Examples/test-suite/enums.i
@@ -8,6 +8,7 @@
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) globalinstance1;
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) globalinstance2;
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) globalinstance3;
+%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK);
%inline %{
@@ -64,7 +65,7 @@ typedef struct _iFoo
enum {
Phoo = +50,
Char = 'a'
- } e;
+ } e;
} iFoo;
%}
#else
@@ -77,5 +78,20 @@ struct iFoo
};
};
%}
-
#endif
+
+// enum declaration and initialization
+%inline %{
+enum Exclamation {
+ goodness,
+ gracious,
+ me
+} enumInstance = me;
+
+enum ContainYourself {
+ slap = 10,
+ my,
+ thigh
+} Slap = slap, My = my, Thigh = thigh, *pThigh = &Thigh, arrayContainYourself[3] = {slap, my, thigh};
+%}
+
diff --git a/Examples/test-suite/octave/enums_runme.m b/Examples/test-suite/octave/enums_runme.m
index 91f2ce2bf..789f7c9e4 100644
--- a/Examples/test-suite/octave/enums_runme.m
+++ b/Examples/test-suite/octave/enums_runme.m
@@ -5,3 +5,19 @@ enums.bar2(1)
enums.bar3(1)
enums.bar1(1)
+if (enums.cvar.enumInstance != 2)
+ error
+endif
+
+if (enums.cvar.Slap != 10)
+ error
+endif
+
+if (enums.cvar.My != 11)
+ error
+endif
+
+if (enums.cvar.Thigh != 12)
+ error
+endif
+
diff --git a/Examples/test-suite/python/enums_runme.py b/Examples/test-suite/python/enums_runme.py
index 59a982974..e8dbe6942 100644
--- a/Examples/test-suite/python/enums_runme.py
+++ b/Examples/test-suite/python/enums_runme.py
@@ -5,3 +5,15 @@ _enums.bar2(1)
_enums.bar3(1)
_enums.bar1(1)
+if _enums.cvar.enumInstance != 2:
+ raise RuntimeError
+
+if _enums.cvar.Slap != 10:
+ raise RuntimeError
+
+if _enums.cvar.My != 11:
+ raise RuntimeError
+
+if _enums.cvar.Thigh != 12:
+ raise RuntimeError
+
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 0da3666f8..8b4521ef1 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -3132,7 +3132,7 @@ c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI {
add_symbols($$); /* Add to tag space */
add_symbols($5); /* Add enum values to id space */
}
- | storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail {
+ | storage_class ENUM ename LBRACE enumlist RBRACE declarator initializer c_decl_tail {
Node *n;
SwigType *ty = 0;
String *unnamed = 0;
@@ -3174,8 +3174,8 @@ c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI {
SetFlag(n,"unnamedinstance");
Delete(cty);
}
- if ($8) {
- Node *p = $8;
+ if ($9) {
+ Node *p = $9;
set_nextSibling(n,p);
while (p) {
SwigType *cty = Copy(ty);
From a9ccc5a8662ea11776ab5c1b0aad66fade8086bf Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 18 Nov 2009 20:24:06 +0000
Subject: [PATCH 080/146] Fix multiple declarations of nested structs (C code)
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11753 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 8 +
Examples/test-suite/common.mk | 2 +-
.../test-suite/java/nested_structs_runme.java | 37 ++++
Examples/test-suite/nested_class.i | 5 +
Examples/test-suite/nested_structs.i | 25 ++-
Source/CParse/parser.y | 179 ++++++++++--------
6 files changed, 176 insertions(+), 80 deletions(-)
create mode 100644 Examples/test-suite/java/nested_structs_runme.java
diff --git a/CHANGES.current b/CHANGES.current
index bc28d8fc1..e00984fe0 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,14 @@
Version 1.3.41 (in progress)
============================
+2009-11-18: wsfulton
+ Fix #491476 - multiple declarations of nested structs, for example:
+ struct Outer {
+ struct {
+ int val;
+ } inner1, inner2, *inner3, inner4[1];
+ } outer;
+
2009-11-17: wsfulton
Fix parsing of enum declaration and initialization, for example:
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index db28917ef..f9e06c0c4 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -80,7 +80,6 @@ CPP_TEST_BROKEN += \
exception_partial_info \
extend_variable \
li_std_vector_ptr \
- nested_structs \
overload_complicated \
template_default_pointer \
template_expr
@@ -461,6 +460,7 @@ C_TEST_CASES += \
long_long \
name \
nested \
+ nested_structs \
newobject2 \
overload_extend \
overload_extendc \
diff --git a/Examples/test-suite/java/nested_structs_runme.java b/Examples/test-suite/java/nested_structs_runme.java
new file mode 100644
index 000000000..6e103cd12
--- /dev/null
+++ b/Examples/test-suite/java/nested_structs_runme.java
@@ -0,0 +1,37 @@
+
+import nested_structs.*;
+
+public class nested_structs_runme {
+
+ static {
+ try {
+ System.loadLibrary("nested_structs");
+ } 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[]) {
+ Outer outer = new Outer();
+ nested_structs.setValues(outer, 10);
+
+ Outer_inner1 inner1 = outer.getInner1();
+ Outer_inner2 inner2 = outer.getInner2();
+ Outer_inner3 inner3 = outer.getInner3();
+ Outer_inner4 inner4 = outer.getInner4();
+ if (inner1.getVal() != 10) throw new RuntimeException("failed inner1");
+ if (inner2.getVal() != 20) throw new RuntimeException("failed inner2");
+ if (inner3.getVal() != 20) throw new RuntimeException("failed inner3");
+ if (inner4.getVal() != 40) throw new RuntimeException("failed inner4");
+
+ Outer_inside1 inside1 = outer.getInside1();
+ Outer_inside2 inside2 = outer.getInside2();
+ Outer_inside3 inside3 = outer.getInside3();
+ Outer_inside4 inside4 = outer.getInside4();
+ if (inside1.getVal() != 100) throw new RuntimeException("failed inside1");
+ if (inside2.getVal() != 200) throw new RuntimeException("failed inside2");
+ if (inside3.getVal() != 200) throw new RuntimeException("failed inside3");
+ if (inside4.getVal() != 400) throw new RuntimeException("failed inside4");
+ }
+}
diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i
index cccebb136..89c9a8058 100644
--- a/Examples/test-suite/nested_class.i
+++ b/Examples/test-suite/nested_class.i
@@ -104,6 +104,11 @@ struct Outer {
InnerStruct4* getInnerStruct4() { return 0; }
InnerClass4* getInnerClass4() { return 0; }
InnerUnion4* getInnerUnion4() { return 0; }
+
+ ///////////////////////////////////////////
+ struct InnerMultiple {
+ Integer x;
+ } MultipleInstance1, MultipleInstance2;
};
%}
diff --git a/Examples/test-suite/nested_structs.i b/Examples/test-suite/nested_structs.i
index 41cdd63fb..60e34a638 100644
--- a/Examples/test-suite/nested_structs.i
+++ b/Examples/test-suite/nested_structs.i
@@ -2,11 +2,26 @@
// bug #491476
%inline %{
-struct {
-struct {
-int a;
-} a, b;
-} a;
+struct Outer {
+ struct {
+ int val;
+ } inner1, inner2, *inner3, inner4[1];
+ struct Named {
+ int val;
+ } inside1, inside2, *inside3, inside4[1];
+} outer;
+void setValues(struct Outer *outer, int val) {
+ outer->inner1.val = val;
+ outer->inner2.val = val * 2;
+ outer->inner3 = &outer->inner2;
+ outer->inner4[0].val = val * 4;
+
+ val = val * 10;
+ outer->inside1.val = val;
+ outer->inside2.val = val * 2;
+ outer->inside3 = &outer->inside2;
+ outer->inside4[0].val = val * 4;
+}
%}
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 8b4521ef1..c7ca713f0 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -985,18 +985,16 @@ static String *resolve_node_scope(String *cname) {
-
-
/* Structures for handling code fragments built for nested classes */
typedef struct Nested {
String *code; /* Associated code fragment */
int line; /* line number where it starts */
- char *name; /* Name associated with this nested class */
- char *kind; /* Kind of class */
+ const char *name; /* Name associated with this nested class */
+ const char *kind; /* Kind of class */
int unnamed; /* unnamed class */
SwigType *type; /* Datatype associated with the name */
- struct Nested *next; /* Next code fragment in list */
+ struct Nested *next; /* Next code fragment in list */
} Nested;
/* Some internal variables for saving nested class information */
@@ -1006,15 +1004,96 @@ static Nested *nested_list = 0;
/* Add a function to the nested list */
static void add_nested(Nested *n) {
- Nested *n1;
- if (!nested_list) nested_list = n;
- else {
- n1 = nested_list;
- while (n1->next) n1 = n1->next;
+ if (!nested_list) {
+ nested_list = n;
+ } else {
+ Nested *n1 = nested_list;
+ while (n1->next)
+ n1 = n1->next;
n1->next = n;
}
}
+/* -----------------------------------------------------------------------------
+ * nested_new_struct()
+ *
+ * Nested struct handling creates a global struct from the nested struct.
+ * ----------------------------------------------------------------------------- */
+
+static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, String *struct_code) {
+ String *name;
+ String *decl;
+
+ /* Create a new global struct declaration which is just a copy of the nested struct */
+ Nested *nested = (Nested *) malloc(sizeof(Nested));
+ Nested *n = nested;
+
+ name = Getattr(cpp_opt_declarators, "name");
+ decl = Getattr(cpp_opt_declarators, "decl");
+ n->code = NewStringEmpty();
+ Printv(n->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
+ n->name = Swig_copy_string(Char(name));
+ n->line = cparse_start_line;
+ n->type = NewStringEmpty();
+ n->kind = kind;
+ n->unnamed = 0;
+ SwigType_push(n->type, decl);
+ n->next = 0;
+
+ /* Repeat for any multiple instances of the nested struct */
+ {
+ Node *p = cpp_opt_declarators;
+ p = nextSibling(p);
+ while (p) {
+ Nested *nn = (Nested *) malloc(sizeof(Nested));
+
+ name = Getattr(p, "name");
+ decl = Getattr(p, "decl");
+ nn->code = NewStringEmpty();
+ Printv(nn->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
+ nn->name = Swig_copy_string(Char(name));
+ nn->line = cparse_start_line;
+ nn->type = NewStringEmpty();
+ nn->kind = kind;
+ nn->unnamed = 0;
+ SwigType_push(nn->type, decl);
+ nn->next = 0;
+ n->next = nn;
+ n = nn;
+ p = nextSibling(p);
+ }
+ }
+
+ add_nested(nested);
+}
+
+/* -----------------------------------------------------------------------------
+ * nested_forward_declaration()
+ *
+ * Treat the nested class/struct/union as a forward declaration until a proper
+ * nested class solution is implemented.
+ * ----------------------------------------------------------------------------- */
+
+static Node *nested_forward_declaration(const char *kind, const char *name) {
+ Node *n = new_node("classforward");
+ Setfile(n,cparse_file);
+ Setline(n,cparse_line);
+ Setattr(n,"kind", kind);
+ Setattr(n,"name", name);
+ Setattr(n,"sym:weak", "1");
+ add_symbols(n);
+
+ if (GetFlag(n, "feature:nestedworkaround")) {
+ Swig_symbol_remove(n);
+ n = 0;
+ } else {
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name);
+ SWIG_WARN_NODE_END(n);
+ }
+ return n;
+}
+
/* Strips C-style and C++-style comments from string in-place. */
static void strip_comments(char *string) {
int state = 0; /*
@@ -1434,33 +1513,6 @@ static void default_arguments(Node *n) {
}
}
-/* -----------------------------------------------------------------------------
- * nested_forward_declaration()
- *
- * Treat the nested class/struct/union as a forward declaration until a proper
- * nested class solution is implemented.
- * ----------------------------------------------------------------------------- */
-
-static Node *nested_forward_declaration(const char *kind, const char *name) {
- Node *n = new_node("classforward");
- Setfile(n,cparse_file);
- Setline(n,cparse_line);
- Setattr(n,"kind", kind);
- Setattr(n,"name", name);
- Setattr(n,"sym:weak", "1");
- add_symbols(n);
-
- if (GetFlag(n, "feature:nestedworkaround")) {
- Swig_symbol_remove(n);
- n = 0;
- } else {
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name);
- SWIG_WARN_NODE_END(n);
- }
- return n;
-}
-
/* -----------------------------------------------------------------------------
* tag_nodes()
*
@@ -1609,7 +1661,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
%type pragma_arg;
%type includetype;
%type pointer primitive_type;
-%type declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator nested_decl;
+%type declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator;
%type abstract_declarator direct_abstract_declarator ctor_end;
%type typemap_type;
%type idcolon idcolontail idcolonnt idcolontailnt idtemplate stringbrace stringbracesemi;
@@ -4427,56 +4479,40 @@ cpp_protection_decl : PUBLIC COLON {
/* struct sname { } id; or struct sname { }; declaration */
-cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
- } nested_decl SEMI {
+cpp_nested : storage_class cpptype ID LBRACE {
+ cparse_start_line = cparse_line; skip_balanced('{','}');
+ $$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
+ } cpp_opt_declarators {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
if (cparse_cplusplus) {
$$ = nested_forward_declaration($2, $3);
- } else if ($6.id) {
- /* Generate some code for a new struct */
- Nested *n = (Nested *) malloc(sizeof(Nested));
- n->code = NewStringEmpty();
- Printv(n->code, "typedef ", $2, " ", Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL);
- n->name = Swig_copy_string($6.id);
- n->line = cparse_start_line;
- n->type = NewStringEmpty();
- n->kind = $2;
- n->unnamed = 0;
- SwigType_push(n->type, $6.type);
- n->next = 0;
- add_nested(n);
+ } else if ($6) {
+ nested_new_struct($6, $2, $5);
}
}
+ Delete($5);
}
/* struct { } id; or struct { }; declaration */
- | storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
- } nested_decl SEMI {
+ | storage_class cpptype LBRACE {
+ cparse_start_line = cparse_line; skip_balanced('{','}');
+ $$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
+ } cpp_opt_declarators {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
- if ($5.id) {
+ if ($5) {
if (cparse_cplusplus) {
- $$ = nested_forward_declaration($2, $5.id);
+ $$ = nested_forward_declaration($2, Getattr($5, "name"));
} else {
- /* Generate some code for a new struct */
- Nested *n = (Nested *) malloc(sizeof(Nested));
- n->code = NewStringEmpty();
- Printv(n->code, "typedef ", $2, " " , Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL);
- n->name = Swig_copy_string($5.id);
- n->line = cparse_start_line;
- n->type = NewStringEmpty();
- n->kind = $2;
- n->unnamed = 1;
- SwigType_push(n->type,$5.type);
- n->next = 0;
- add_nested(n);
+ nested_new_struct($5, $2, $4);
}
} else {
Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
}
}
+ Delete($4);
}
/* class name : base_list { }; declaration */
@@ -4502,11 +4538,6 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
*/
;
-nested_decl : declarator { $$ = $1;}
- | empty { $$.id = 0; }
- ;
-
-
/* These directives can be included inside a class definition */
cpp_swig_directive: pragma_directive { $$ = $1; }
From aa6712e3f2d39bb38e42f897508f323aad0023ee Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 18 Nov 2009 20:37:23 +0000
Subject: [PATCH 081/146] pretty print the nested structs generated as global
structs
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11754 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Source/CParse/parser.y | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index c7ca713f0..bf437cd66 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -1021,6 +1021,7 @@ static void add_nested(Nested *n) {
* ----------------------------------------------------------------------------- */
static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, String *struct_code) {
+ String *new_struct_decl;
String *name;
String *decl;
@@ -1030,8 +1031,13 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin
name = Getattr(cpp_opt_declarators, "name");
decl = Getattr(cpp_opt_declarators, "decl");
+
n->code = NewStringEmpty();
- Printv(n->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
+ new_struct_decl = NewStringEmpty();
+ Printv(new_struct_decl, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
+ Wrapper_pretty_print(new_struct_decl, n->code);
+ Delete(new_struct_decl);
+
n->name = Swig_copy_string(Char(name));
n->line = cparse_start_line;
n->type = NewStringEmpty();
@@ -1049,8 +1055,13 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin
name = Getattr(p, "name");
decl = Getattr(p, "decl");
+
+ new_struct_decl = NewStringEmpty();
nn->code = NewStringEmpty();
- Printv(nn->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
+ Printv(new_struct_decl, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
+ Wrapper_pretty_print(new_struct_decl, n->code);
+ Delete(new_struct_decl);
+
nn->name = Swig_copy_string(Char(name));
nn->line = cparse_start_line;
nn->type = NewStringEmpty();
From 43b6292681c8fd9629b1b4ebf39a87afd42a6952 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 18 Nov 2009 23:59:10 +0000
Subject: [PATCH 082/146] Nested struct pretty print rewrite and fix. The
wrappers for C nested structs are now generated in the same order as declared
in the parsed code.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11755 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 4 ++++
Source/CParse/parser.y | 47 ++++++++++++++----------------------------
2 files changed, 20 insertions(+), 31 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index e00984fe0..10056a24b 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,10 @@
Version 1.3.41 (in progress)
============================
+2009-11-18: wsfulton
+ The wrappers for C nested structs are now generated in the same order as declared
+ in the parsed code.
+
2009-11-18: wsfulton
Fix #491476 - multiple declarations of nested structs, for example:
struct Outer {
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index bf437cd66..431190790 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -1021,7 +1021,6 @@ static void add_nested(Nested *n) {
* ----------------------------------------------------------------------------- */
static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, String *struct_code) {
- String *new_struct_decl;
String *name;
String *decl;
@@ -1033,11 +1032,7 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin
decl = Getattr(cpp_opt_declarators, "decl");
n->code = NewStringEmpty();
- new_struct_decl = NewStringEmpty();
- Printv(new_struct_decl, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
- Wrapper_pretty_print(new_struct_decl, n->code);
- Delete(new_struct_decl);
-
+ Printv(n->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
n->name = Swig_copy_string(Char(name));
n->line = cparse_start_line;
n->type = NewStringEmpty();
@@ -1056,12 +1051,8 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin
name = Getattr(p, "name");
decl = Getattr(p, "decl");
- new_struct_decl = NewStringEmpty();
nn->code = NewStringEmpty();
- Printv(new_struct_decl, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
- Wrapper_pretty_print(new_struct_decl, n->code);
- Delete(new_struct_decl);
-
+ Printv(nn->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL);
nn->name = Swig_copy_string(Char(name));
nn->line = cparse_start_line;
nn->type = NewStringEmpty();
@@ -1176,6 +1167,7 @@ static void strip_comments(char *string) {
static Node *dump_nested(const char *parent) {
Nested *n,*n1;
Node *ret = 0;
+ Node *last = 0;
n = nested_list;
if (!parent) {
nested_list = 0;
@@ -1205,20 +1197,12 @@ static Node *dump_nested(const char *parent) {
add_symbols(retx);
if (ret) {
- set_nextSibling(retx,ret);
- Delete(ret);
+ set_nextSibling(last, retx);
+ Delete(retx);
+ } else {
+ ret = retx;
}
- ret = retx;
-
- /* Insert a forward class declaration */
- /* Disabled: [ 597599 ] union in class: incorrect scope
- retx = new_node("classforward");
- Setattr(retx,"kind",n->kind);
- Setattr(retx,"name",Copy(n->type));
- Setattr(retx,"sym:name", make_name(n->type,0));
- set_nextSibling(retx,ret);
- ret = retx;
- */
+ last = retx;
/* Strip comments - further code may break in presence of comments. */
strip_comments(Char(n->code));
@@ -1267,17 +1251,18 @@ static Node *dump_nested(const char *parent) {
}
}
{
- Node *head = new_node("insert");
- String *code = NewStringf("\n%s\n",n->code);
- Setattr(head,"code", code);
+ Node *newnode = new_node("insert");
+ String *code = NewStringEmpty();
+ Wrapper_pretty_print(n->code, code);
+ Setattr(newnode,"code", code);
Delete(code);
- set_nextSibling(head,ret);
- Delete(ret);
- ret = head;
+ set_nextSibling(last, newnode);
+ Delete(newnode);
+ last = newnode;
}
/* Dump the code to the scanner */
- start_inline(Char(n->code),n->line);
+ start_inline(Char(Getattr(last, "code")),n->line);
n1 = n->next;
Delete(n->code);
From 2a59a2e6a9c411be9da20de1c42869eaf4d91a1b Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 23 Nov 2009 23:02:01 +0000
Subject: [PATCH 083/146] Improved C++ nested class support - nested typedef'd
classes now parsed and treated as forward class declaration
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11756 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 6 +
.../test-suite/java/nested_class_runme.java | 72 ++++++++
Examples/test-suite/namespace_union.i | 2 +-
Examples/test-suite/nested_class.i | 144 ++++++++++++---
Examples/test-suite/nested_comment.i | 31 ++--
Source/CParse/parser.y | 168 ++++++++++++------
6 files changed, 324 insertions(+), 99 deletions(-)
create mode 100644 Examples/test-suite/java/nested_class_runme.java
diff --git a/CHANGES.current b/CHANGES.current
index 10056a24b..bed2fea3f 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,12 @@
Version 1.3.41 (in progress)
============================
+2009-11-23: wsfulton
+ C++ nested typedef classes can now be handled too, for example:
+ struct Outer {
+ typedef Foo { } FooTypedef1, FooTypedef2;
+ };
+
2009-11-18: wsfulton
The wrappers for C nested structs are now generated in the same order as declared
in the parsed code.
diff --git a/Examples/test-suite/java/nested_class_runme.java b/Examples/test-suite/java/nested_class_runme.java
new file mode 100644
index 000000000..f1c67a0af
--- /dev/null
+++ b/Examples/test-suite/java/nested_class_runme.java
@@ -0,0 +1,72 @@
+
+import nested_class.*;
+
+public class nested_class_runme {
+
+ static {
+ try {
+ System.loadLibrary("nested_class");
+ } 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[]) {
+ Outer outer = new Outer();
+ SWIGTYPE_p_Outer__InnerStruct1 is1 = outer.makeInnerStruct1();
+ SWIGTYPE_p_Outer__InnerClass1 ic1 = outer.makeInnerClass1();
+ SWIGTYPE_p_Outer__InnerUnion1 iu1 = outer.makeInnerUnion1();
+
+ SWIGTYPE_p_Outer__InnerStruct2 is2 = outer.makeInnerStruct2();
+ SWIGTYPE_p_Outer__InnerClass2 ic2 = outer.makeInnerClass2();
+ SWIGTYPE_p_Outer__InnerUnion2 iu2 = outer.makeInnerUnion2();
+
+ SWIGTYPE_p_Outer__InnerClass4Typedef ic4 = outer.makeInnerClass4Typedef();
+ SWIGTYPE_p_Outer__InnerStruct4Typedef is4 = outer.makeInnerStruct4Typedef();
+ SWIGTYPE_p_Outer__InnerUnion4Typedef iu4 = outer.makeInnerUnion4Typedef();
+
+ SWIGTYPE_p_Outer__InnerClass5 ic5 = outer.makeInnerClass5();
+ SWIGTYPE_p_Outer__InnerStruct5 is5 = outer.makeInnerStruct5();
+ SWIGTYPE_p_Outer__InnerUnion5 iu5 = outer.makeInnerUnion5();
+
+ ic5 = outer.makeInnerClass5Typedef();
+ is5 = outer.makeInnerStruct5Typedef();
+ iu5 = outer.makeInnerUnion5Typedef();
+
+ {
+ SWIGTYPE_p_Outer__InnerMultiple im1 = outer.getMultipleInstance1();
+ SWIGTYPE_p_Outer__InnerMultiple im2 = outer.getMultipleInstance2();
+ SWIGTYPE_p_Outer__InnerMultiple im3 = outer.getMultipleInstance3();
+ SWIGTYPE_p_Outer__InnerMultiple im4 = outer.getMultipleInstance4();
+ }
+
+ {
+ SWIGTYPE_p_Outer__InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1();
+ SWIGTYPE_p_Outer__InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2();
+ SWIGTYPE_p_Outer__InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3();
+ SWIGTYPE_p_Outer__InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4();
+ }
+
+ {
+ SWIGTYPE_p_Outer__InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1();
+ SWIGTYPE_p_Outer__InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2();
+ SWIGTYPE_p_Outer__InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3();
+ SWIGTYPE_p_Outer__InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4();
+ }
+
+ {
+ SWIGTYPE_p_Outer__InnerMultipleAnonTypedef1 mat1 = outer.makeInnerMultipleAnonTypedef1();
+ SWIGTYPE_p_Outer__InnerMultipleAnonTypedef2 mat2 = outer.makeInnerMultipleAnonTypedef2();
+ SWIGTYPE_p_Outer__InnerMultipleAnonTypedef3 mat3 = outer.makeInnerMultipleAnonTypedef3();
+
+ SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt = outer.makeInnerMultipleNamedTypedef();
+ SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt1 = outer.makeInnerMultipleNamedTypedef1();
+ SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt2 = outer.makeInnerMultipleNamedTypedef2();
+ SWIGTYPE_p_p_Outer__InnerMultipleNamedTypedef mnt3 = outer.makeInnerMultipleNamedTypedef3();
+ }
+ {
+ SWIGTYPE_p_Outer__InnerSameName isn = outer.makeInnerSameName();
+ }
+ }
+}
diff --git a/Examples/test-suite/namespace_union.i b/Examples/test-suite/namespace_union.i
index 70698682e..85885f399 100644
--- a/Examples/test-suite/namespace_union.i
+++ b/Examples/test-suite/namespace_union.i
@@ -1,6 +1,6 @@
%module namespace_union
-%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) SpatialIndex::Variant::val;
+#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
%inline %{
namespace SpatialIndex
diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i
index 89c9a8058..71d91f022 100644
--- a/Examples/test-suite/nested_class.i
+++ b/Examples/test-suite/nested_class.i
@@ -7,12 +7,18 @@
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass2;
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct2;
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion2;
-%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass3Name;
-%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct3Name;
-%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion3Name;
-%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4;
-%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4;
-%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4Typedef;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4Typedef;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4Typedef;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass5;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct5;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion5;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultiple;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleDerived;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleAnonTypedef1;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleNamedTypedef;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerSameName;
+%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer2::IgnoreMe;
%inline %{
struct Outer {
@@ -51,64 +57,150 @@ struct Outer {
class InnerClass2 {
public:
Integer x;
- } InnerClass2Name;
+ } InnerClass2Instance;
struct InnerStruct2 {
Integer x;
- } InnerStruct2Name;
+ } InnerStruct2Instance;
union InnerUnion2 {
Integer x;
double y;
- } InnerUnion2Name;
+ } InnerUnion2Instance;
///////////////////////////////////////////
class {
public:
Integer x;
- } InnerClass3Name;
+ } InnerClass3Instance;
struct {
Integer x;
- } InnerStruct3Name;
+ } InnerStruct3Instance;
union {
Integer x;
double y;
- } InnerUnion3Name;
+ } InnerUnion3Instance;
///////////////////////////////////////////
typedef class {
public:
Integer x;
- } InnerClass4;
+ } InnerClass4Typedef;
typedef struct {
Integer x;
- } InnerStruct4;
+ } InnerStruct4Typedef;
typedef union {
Integer x;
double y;
- } InnerUnion4;
+ } InnerUnion4Typedef;
+
+ ///////////////////////////////////////////
+ typedef class InnerClass5 {
+ public:
+ Integer x;
+ } InnerClass5Typedef;
+
+ typedef struct InnerStruct5 {
+ Integer x;
+ } InnerStruct5Typedef;
+
+ typedef union InnerUnion5 {
+ Integer x;
+ double y;
+ } InnerUnion5Typedef;
// bug #909387 - inner declared types are treated as forward declarations
- InnerStruct1* getInnerStruct1() { return 0; }
- InnerClass1* getInnerClass1() { return 0; }
- InnerUnion1* getInnerUnion1() { return 0; }
+ InnerStruct1* makeInnerStruct1() { return 0; }
+ InnerClass1* makeInnerClass1() { return 0; }
+ InnerUnion1* makeInnerUnion1() { return 0; }
- InnerStruct2* getInnerStruct2() { return 0; }
- InnerClass2* getInnerClass2() { return 0; }
- InnerUnion2* getInnerUnion2() { return 0; }
+ InnerStruct2* makeInnerStruct2() { return 0; }
+ InnerClass2* makeInnerClass2() { return 0; }
+ InnerUnion2* makeInnerUnion2() { return 0; }
- InnerStruct4* getInnerStruct4() { return 0; }
- InnerClass4* getInnerClass4() { return 0; }
- InnerUnion4* getInnerUnion4() { return 0; }
+ InnerStruct4Typedef* makeInnerStruct4Typedef() { return 0; }
+ InnerClass4Typedef* makeInnerClass4Typedef() { return 0; }
+ InnerUnion4Typedef* makeInnerUnion4Typedef() { return 0; }
+
+ InnerStruct5* makeInnerStruct5() { return 0; }
+ InnerClass5* makeInnerClass5() { return 0; }
+ InnerUnion5* makeInnerUnion5() { return 0; }
+
+ InnerStruct5Typedef* makeInnerStruct5Typedef() { return 0; }
+ InnerClass5Typedef* makeInnerClass5Typedef() { return 0; }
+ InnerUnion5Typedef* makeInnerUnion5Typedef() { return 0; }
///////////////////////////////////////////
struct InnerMultiple {
Integer x;
- } MultipleInstance1, MultipleInstance2;
+ } MultipleInstance1, MultipleInstance2, *MultipleInstance3, MultipleInstance4[2];
+
+ struct InnerMultipleDerived : public InnerMultiple {
+ Integer xx;
+ } MultipleDerivedInstance1, MultipleDerivedInstance2, *MultipleDerivedInstance3, MultipleDerivedInstance4[2];
+
+ struct {
+ Integer x;
+ } MultipleInstanceAnon1, MultipleInstanceAnon2, *MultipleInstanceAnon3, MultipleInstanceAnon4[2];
+
+ struct : public InnerMultiple {
+ Integer xx;
+ } MultipleInstanceAnonDerived1, MultipleInstanceAnonDerived2, *MultipleInstanceAnonDerived3, MultipleInstanceAnonDerived4[2];
+
+ struct : public InnerMultiple {
+ Integer xx;
+ };
+
+ class : public InnerMultiple {
+ public:
+ Integer yy;
+ };
+
+ ///////////////////////////////////////////
+ typedef struct {
+ Integer x;
+ } InnerMultipleAnonTypedef1, InnerMultipleAnonTypedef2, *InnerMultipleAnonTypedef3;
+
+ InnerMultipleAnonTypedef1* makeInnerMultipleAnonTypedef1() { return 0; }
+ InnerMultipleAnonTypedef2* makeInnerMultipleAnonTypedef2() { return 0; }
+ InnerMultipleAnonTypedef3* makeInnerMultipleAnonTypedef3() { return 0; }
+
+ typedef struct InnerMultipleNamedTypedef {
+ Integer x;
+ } InnerMultipleNamedTypedef1, InnerMultipleNamedTypedef2, *InnerMultipleNamedTypedef3;
+
+ InnerMultipleNamedTypedef* makeInnerMultipleNamedTypedef() { return 0; }
+ InnerMultipleNamedTypedef1* makeInnerMultipleNamedTypedef1() { return 0; }
+ InnerMultipleNamedTypedef2* makeInnerMultipleNamedTypedef2() { return 0; }
+ InnerMultipleNamedTypedef3* makeInnerMultipleNamedTypedef3() { return 0; }
+
+ ///////////////////////////////////////////
+ typedef struct InnerSameName {
+ Integer x;
+ } InnerSameName;
+
+ InnerSameName* makeInnerSameName() { return 0; }
+};
+%}
+
+// Ignore nested struct instance
+%ignore Outer2::IgnoreMeInstance;
+%{
+struct Outer2 {
+ struct IgnoreMe {
+ int xx;
+ };
+};
+%}
+
+struct Outer2 {
+ struct IgnoreMe {
+ int xx;
+ } IgnoreMeInstance;
};
-%}
+
diff --git a/Examples/test-suite/nested_comment.i b/Examples/test-suite/nested_comment.i
index c246b8dab..99d0ffb43 100644
--- a/Examples/test-suite/nested_comment.i
+++ b/Examples/test-suite/nested_comment.i
@@ -1,26 +1,25 @@
%module nested_comment
-%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) s1::n;
-%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) a::d;
+#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
// this example shows a problem with 'dump_nested' (parser.y).
// bug #949654
%inline %{
-typedef struct s1 {
-union {
-int fsc; /* genie structure hiding - Conductor
-*/
-int fso; /* genie structure hiding - FSOptions
-*/
-struct {
-double *vals;
-int size;
-} vector_val; /* matrix values are mainly used
-in rlgc models */
-char *name;
-} n ;
-} s2;
+ typedef struct s1 {
+ union {
+ int fsc; /* genie structure hiding - Conductor
+ */
+ int fso; /* genie structure hiding - FSOptions
+ */
+ struct {
+ double *vals;
+ int size;
+ } vector_val; /* matrix values are mainly used
+ in rlgc models */
+ char *name;
+ } n ;
+ } s2;
%}
// comment in nested struct
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 431190790..46485593f 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -1017,10 +1017,21 @@ static void add_nested(Nested *n) {
/* -----------------------------------------------------------------------------
* nested_new_struct()
*
- * Nested struct handling creates a global struct from the nested struct.
+ * Nested struct handling for C code only creates a global struct from the nested struct.
+ *
+ * Nested structure. This is a sick "hack". If we encounter
+ * a nested structure, we're going to grab the text of its definition and
+ * feed it back into the scanner. In the meantime, we need to grab
+ * variable declaration information and generate the associated wrapper
+ * code later. Yikes!
+ *
+ * This really only works in a limited sense. Since we use the
+ * code attached to the nested class to generate both C code
+ * it can't have any SWIG directives in it. It also needs to be parsable
+ * by SWIG or this whole thing is going to puke.
* ----------------------------------------------------------------------------- */
-static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, String *struct_code) {
+static void nested_new_struct(const char *kind, String *struct_code, Node *cpp_opt_declarators) {
String *name;
String *decl;
@@ -1072,28 +1083,76 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin
/* -----------------------------------------------------------------------------
* nested_forward_declaration()
*
+ * Nested struct handling for C++ code only.
+ *
* Treat the nested class/struct/union as a forward declaration until a proper
* nested class solution is implemented.
* ----------------------------------------------------------------------------- */
-static Node *nested_forward_declaration(const char *kind, const char *name) {
- Node *n = new_node("classforward");
- Setfile(n,cparse_file);
- Setline(n,cparse_line);
- Setattr(n,"kind", kind);
- Setattr(n,"name", name);
- Setattr(n,"sym:weak", "1");
- add_symbols(n);
+static Node *nested_forward_declaration(const char *storage, const char *kind, String *sname, const char *name, Node *cpp_opt_declarators) {
+ Node *nn = 0;
+ int warned = 0;
- if (GetFlag(n, "feature:nestedworkaround")) {
- Swig_symbol_remove(n);
- n = 0;
- } else {
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name);
- SWIG_WARN_NODE_END(n);
+ if (sname) {
+ /* Add forward declaration of the nested type */
+ Node *n = new_node("classforward");
+ Setfile(n, cparse_file);
+ Setline(n, cparse_line);
+ Setattr(n, "kind", kind);
+ Setattr(n, "name", sname);
+ Setattr(n, "storage", storage);
+ Setattr(n, "sym:weak", "1");
+ add_symbols(n);
+ nn = n;
}
- return n;
+
+ /* Add any variable instances. Also add in any further typedefs of the nested type.
+ Note that anonymous typedefs (eg typedef struct {...} a, b;) are treated as class forward declarations */
+ if (cpp_opt_declarators) {
+ int storage_typedef = (storage && (strcmp(storage, "typedef") == 0));
+ int variable_of_anonymous_type = !sname && !storage_typedef;
+ if (!variable_of_anonymous_type) {
+ int anonymous_typedef = !sname && (storage && (strcmp(storage, "typedef") == 0));
+ Node *n = cpp_opt_declarators;
+ SwigType *type = NewString(name);
+ while (n) {
+ Setattr(n, "type", type);
+ Setattr(n, "storage", storage);
+ if (anonymous_typedef) {
+ Setattr(n, "nodeType", "classforward");
+ Setattr(n, "sym:weak", "1");
+ }
+ n = nextSibling(n);
+ }
+ Delete(type);
+ add_symbols(cpp_opt_declarators);
+
+ if (nn) {
+ set_nextSibling(nn, cpp_opt_declarators);
+ } else {
+ nn = cpp_opt_declarators;
+ }
+ }
+ }
+
+ if (nn && Equal(nodeType(nn), "classforward")) {
+ Node *n = nn;
+ if (GetFlag(n, "feature:nestedworkaround")) {
+ Swig_symbol_remove(n);
+ nn = 0;
+ warned = 1;
+ } else {
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, sname ? sname : name);
+ SWIG_WARN_NODE_END(n);
+ warned = 1;
+ }
+ }
+
+ if (!warned)
+ Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", kind);
+
+ return nn;
}
/* Strips C-style and C++-style comments from string in-place. */
@@ -4460,67 +4519,64 @@ cpp_protection_decl : PUBLIC COLON {
;
-/* ----------------------------------------------------------------------
- Nested structure. This is a sick "hack". If we encounter
- a nested structure, we're going to grab the text of its definition and
- feed it back into the scanner. In the meantime, we need to grab
- variable declaration information and generate the associated wrapper
- code later. Yikes!
+/* ------------------------------------------------------------
+ Named nested structs:
+ struct sname { };
+ struct sname { } id;
+ struct sname : bases { };
+ struct sname : bases { } id;
+ typedef sname struct { } td;
+ typedef sname struct : bases { } td;
- This really only works in a limited sense. Since we use the
- code attached to the nested class to generate both C/C++ code,
- it can't have any SWIG directives in it. It also needs to be parsable
- by SWIG or this whole thing is going to puke.
- ---------------------------------------------------------------------- */
+ Adding inheritance, ie replacing 'ID' with 'idcolon inherit'
+ added one shift/reduce
+ ------------------------------------------------------------ */
-/* struct sname { } id; or struct sname { }; declaration */
-
-cpp_nested : storage_class cpptype ID LBRACE {
+cpp_nested : storage_class cpptype idcolon inherit LBRACE {
cparse_start_line = cparse_line; skip_balanced('{','}');
$$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
} cpp_opt_declarators {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
if (cparse_cplusplus) {
- $$ = nested_forward_declaration($2, $3);
- } else if ($6) {
- nested_new_struct($6, $2, $5);
+ $$ = nested_forward_declaration($1, $2, $3, $3, $7);
+ } else if ($7) {
+ nested_new_struct($2, $6, $7);
}
}
- Delete($5);
+ Delete($6);
}
-/* struct { } id; or struct { }; declaration */
+/* ------------------------------------------------------------
+ Unnamed/anonymous nested structs:
+ struct { };
+ struct { } id;
+ struct : bases { };
+ struct : bases { } id;
+ typedef struct { } td;
+ typedef struct : bases { } td;
+ ------------------------------------------------------------ */
- | storage_class cpptype LBRACE {
+ | storage_class cpptype inherit LBRACE {
cparse_start_line = cparse_line; skip_balanced('{','}');
$$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
} cpp_opt_declarators {
$$ = 0;
if (cplus_mode == CPLUS_PUBLIC) {
- if ($5) {
- if (cparse_cplusplus) {
- $$ = nested_forward_declaration($2, Getattr($5, "name"));
- } else {
- nested_new_struct($5, $2, $4);
- }
+ if (cparse_cplusplus) {
+ const char *name = $6 ? Getattr($6, "name") : 0;
+ $$ = nested_forward_declaration($1, $2, 0, name, $6);
} else {
- Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
+ if ($6) {
+ nested_new_struct($2, $5, $6);
+ } else {
+ Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
+ }
}
}
- Delete($4);
+ Delete($5);
}
-/* class name : base_list { }; declaration */
-/* This adds one shift/reduce. */
-
- | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
- } cpp_opt_declarators {
- $$ = 0;
- if (cplus_mode == CPLUS_PUBLIC) {
- $$ = nested_forward_declaration($2, $3);
- }
- }
/* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */
/*
From a07092b60c93de02beacf5c689693772bf499a6f Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 24 Nov 2009 07:16:26 +0000
Subject: [PATCH 084/146] Clarify typedef matching is typedef reduction only
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11757 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Doc/Manual/Typemaps.html | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html
index da4fdadc9..7a89a679a 100644
--- a/Doc/Manual/Typemaps.html
+++ b/Doc/Manual/Typemaps.html
@@ -1245,6 +1245,26 @@ is rather esoteric--there's little practical reason to write a typemap quite lik
to confuse your coworkers even more.
+
+As a point of clarification, it is worth emphasizing that typedef matching is a typedef reduction process only, that is, SWIG does not search for every single possible typedef.
+Given a type in a declaration, it will only reduce the type, it won't build it up looking for typedefs.
+For example, given the type Struct, the typemap below will not be used for the aStruct parameter,
+because Struct is fully reduced:
+
+
+
+
+struct Struct {...};
+typedef Struct StructTypedef;
+
+%typemap(in) StructTypedef {
+ ...
+}
+
+void go(Struct aStruct);
+
+
+
10.3.3 Default typemaps
From 1dd50f5ea8e75fe8035598661baf7a7535ee5de2 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Thu, 26 Nov 2009 19:20:31 +0000
Subject: [PATCH 085/146] Fix %javaconst(1)/%csconst(1) for static const member
variables to use the actual constant value if available
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11758 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 11 +++++++++++
Examples/test-suite/static_const_member.i | 6 ++++++
Source/Modules/csharp.cxx | 2 +-
Source/Modules/java.cxx | 2 +-
4 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index bed2fea3f..e7ee49381 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,17 @@
Version 1.3.41 (in progress)
============================
+2009-11-26: wsfulton
+ [Java, C#] Fix %javaconst(1)/%csconst(1) for static const member variables to
+ use the actual constant value if it is specified, rather than the C++ code to
+ access the member.
+
+ %javaconst(1) EN;
+ %csconst(1) EN;
+ struct X {
+ static const int EN = 2;
+ };
+
2009-11-23: wsfulton
C++ nested typedef classes can now be handled too, for example:
struct Outer {
diff --git a/Examples/test-suite/static_const_member.i b/Examples/test-suite/static_const_member.i
index 99dc89bd1..a650b8936 100644
--- a/Examples/test-suite/static_const_member.i
+++ b/Examples/test-suite/static_const_member.i
@@ -5,6 +5,12 @@
%module static_const_member
+#if SWIGJAVA
+%javaconst(1) EN;
+#elif SWIGCSHARP
+%csconst(1) EN;
+#endif
+
%inline %{
class X {
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index a752fb933..1fb57baf3 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -1394,7 +1394,7 @@ public:
enum_constant_flag = false;
} else {
// Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code
- Printf(constants_code, "%s;\n", Getattr(n, "value"));
+ Printf(constants_code, "%s;\n", Getattr(n, "wrappedasconstant") ? Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value"));
}
// Emit the generated code to appropriate place
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
index fd6c768c9..20a665726 100644
--- a/Source/Modules/java.cxx
+++ b/Source/Modules/java.cxx
@@ -1426,7 +1426,7 @@ public:
enum_constant_flag = false;
} else {
// Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code
- Printf(constants_code, "%s;\n", Getattr(n, "value"));
+ Printf(constants_code, "%s;\n", Getattr(n, "wrappedasconstant") ? Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value"));
}
// Emit the generated code to appropriate place
From d756b28611396a8b2ac2c2df05a88babf0a585b2 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Thu, 26 Nov 2009 19:32:14 +0000
Subject: [PATCH 086/146] Correct %exception documentation so no memory is
leaked - bug #2903761
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11759 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Doc/Manual/Customization.html | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/Doc/Manual/Customization.html b/Doc/Manual/Customization.html
index ec73e5460..82e1c411f 100644
--- a/Doc/Manual/Customization.html
+++ b/Doc/Manual/Customization.html
@@ -53,6 +53,21 @@ The %exception directive allows you to define a general purpose excepti
handler. For example, you can specify the following:
+
+%exception {
+ try {
+ $action
+ }
+ catch (RangeError) {
+ ... handle error ...
+ }
+}
+
+
+
+How the exception is handled depends on the target language, for example, Python:
+
+
%exception {
try {
@@ -60,7 +75,7 @@ handler. For example, you can specify the following:
}
catch (RangeError) {
PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
- return NULL;
+ SWIG_fail;
}
}
From bf8ba3bf55f7b2e7d1cb1f18c637ee2e2b543f21 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 29 Nov 2009 01:29:26 +0000
Subject: [PATCH 087/146] Fix generated quoting when using
%javaconst(1)/%csconst(1) for static const char member variables.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11760 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 10 ++++++++++
Examples/test-suite/static_const_member.i | 4 +++-
Source/Modules/csharp.cxx | 9 ++++++++-
Source/Modules/java.cxx | 9 ++++++++-
4 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index e7ee49381..50c15c9e7 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,16 @@
Version 1.3.41 (in progress)
============================
+2009-11-29: wsfulton
+ [Java, C#] Fix generated quoting when using %javaconst(1)/%csconst(1) for
+ static const char member variables.
+
+ %javaconst(1) A;
+ %csconst(1) A;
+ struct X {
+ static const char A = 'A';
+ };
+
2009-11-26: wsfulton
[Java, C#] Fix %javaconst(1)/%csconst(1) for static const member variables to
use the actual constant value if it is specified, rather than the C++ code to
diff --git a/Examples/test-suite/static_const_member.i b/Examples/test-suite/static_const_member.i
index a650b8936..126f86496 100644
--- a/Examples/test-suite/static_const_member.i
+++ b/Examples/test-suite/static_const_member.i
@@ -6,9 +6,10 @@
%module static_const_member
#if SWIGJAVA
-%javaconst(1) EN;
+%javaconst(1) CHARTEST;
#elif SWIGCSHARP
%csconst(1) EN;
+%csconst(1) CHARTEST;
#endif
%inline %{
@@ -18,6 +19,7 @@ public:
static const int PN = 0;
static const int CN = 1;
static const int EN = 2;
+ static const char CHARTEST = 'A';
};
%}
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index 1fb57baf3..82a9a629c 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -1394,7 +1394,14 @@ public:
enum_constant_flag = false;
} else {
// Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code
- Printf(constants_code, "%s;\n", Getattr(n, "wrappedasconstant") ? Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value"));
+ if (Getattr(n, "wrappedasconstant")) {
+ if (SwigType_type(t) == T_CHAR)
+ Printf(constants_code, "\'%s\';\n", Getattr(n, "staticmembervariableHandler:value"));
+ else
+ Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
+ } else {
+ Printf(constants_code, "%s;\n", Getattr(n, "value"));
+ }
}
// Emit the generated code to appropriate place
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
index 20a665726..7fccab5e1 100644
--- a/Source/Modules/java.cxx
+++ b/Source/Modules/java.cxx
@@ -1426,7 +1426,14 @@ public:
enum_constant_flag = false;
} else {
// Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code
- Printf(constants_code, "%s;\n", Getattr(n, "wrappedasconstant") ? Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value"));
+ if (Getattr(n, "wrappedasconstant")) {
+ if (SwigType_type(t) == T_CHAR)
+ Printf(constants_code, "\'%s\';\n", Getattr(n, "staticmembervariableHandler:value"));
+ else
+ Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
+ } else {
+ Printf(constants_code, "%s;\n", Getattr(n, "value"));
+ }
}
// Emit the generated code to appropriate place
From b9817010fb597babea511adee712cf8d379f219c Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 29 Nov 2009 01:50:21 +0000
Subject: [PATCH 088/146] add in missing line since last commit
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11761 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
Examples/test-suite/static_const_member.i | 1 +
1 file changed, 1 insertion(+)
diff --git a/Examples/test-suite/static_const_member.i b/Examples/test-suite/static_const_member.i
index 126f86496..3db60b4c2 100644
--- a/Examples/test-suite/static_const_member.i
+++ b/Examples/test-suite/static_const_member.i
@@ -6,6 +6,7 @@
%module static_const_member
#if SWIGJAVA
+%javaconst(1) EN;
%javaconst(1) CHARTEST;
#elif SWIGCSHARP
%csconst(1) EN;
From 2bd190dbf1cd79c5c4072d3b0891054c6b03ff1e Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 2 Dec 2009 00:01:31 +0000
Subject: [PATCH 089/146] Revert support for %extend and memberin typemaps
added in swig-1.3.39. The memberin typemaps are ignored again for member
variables within a %extend block. Documentation inconsistency reported by
Torsten Landschoff.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11762 626c5289-ae23-0410-ae9c-e8d60b6d4f22
---
CHANGES.current | 5 +++
Doc/Manual/SWIG.html | 10 ++---
Examples/test-suite/common.mk | 1 +
Examples/test-suite/memberin_extend.i | 15 ++++++-
Examples/test-suite/memberin_extend_c.i | 25 +++++++++++
.../python/memberin_extend_c_runme.py | 6 +++
Source/Modules/lang.cxx | 45 +++++++++----------
Source/Swig/cwrap.c | 14 +++---
Source/Swig/swig.h | 2 +-
9 files changed, 85 insertions(+), 38 deletions(-)
create mode 100644 Examples/test-suite/memberin_extend_c.i
create mode 100644 Examples/test-suite/python/memberin_extend_c_runme.py
diff --git a/CHANGES.current b/CHANGES.current
index 50c15c9e7..d5b5e9670 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,11 @@
Version 1.3.41 (in progress)
============================
+2009-12-01: wsfulton
+ Revert support for %extend and memberin typemaps added in swig-1.3.39. The
+ memberin typemaps are ignored again for member variables within a %extend block.
+ Documentation inconsistency reported by Torsten Landschoff.
+
2009-11-29: wsfulton
[Java, C#] Fix generated quoting when using %javaconst(1)/%csconst(1) for
static const char member variables.
diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html
index dd1b22095..8818a6c60 100644
--- a/Doc/Manual/SWIG.html
+++ b/Doc/Manual/SWIG.html
@@ -2493,7 +2493,7 @@ instead of a method. To do this, you might write some code like this:
// Now supply the implementation of the Vector_magnitude_get function
%{
const double Vector_magnitude_get(Vector *v) {
- return (const double) return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
+ return (const double) sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
}
%}
@@ -2512,10 +2512,10 @@ For example, consider this interface:
-struct Person {
+typedef struct {
char name[50];
...
-}
+} Person;
@@ -2527,12 +2527,12 @@ as follows to change this:
-struct Person {
+typedef struct {
%extend {
char *name;
}
...
-}
+} Person;
// Specific implementation of set/get functions
%{
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index f9e06c0c4..bb72e4988 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -458,6 +458,7 @@ C_TEST_CASES += \
li_cpointer \
li_math \
long_long \
+ memberin_extend_c \
name \
nested \
nested_structs \
diff --git a/Examples/test-suite/memberin_extend.i b/Examples/test-suite/memberin_extend.i
index f20617b66..94d2cab3f 100644
--- a/Examples/test-suite/memberin_extend.i
+++ b/Examples/test-suite/memberin_extend.i
@@ -12,8 +12,19 @@ struct ExtendMe {
%{
#include