summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2013-02-18 19:53:37 +0000
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2013-02-18 19:53:37 +0000
commitb80f4dc5e257a343381e3dbeebb206c1376e3ca3 (patch)
treecf066844423f973be18460e727a6490c8ed867ee
parent054f9dba1a6f2914d1ed69042162aa4f9d72e0ef (diff)
downloadswig-b80f4dc5e257a343381e3dbeebb206c1376e3ca3.tar.gz
Restrict the name used in %extend to be just the struct/class name and not a typedef to a class/struct. Typedefs were only partially working anyway. Anonymous struct typedefs excluded. Deprecate with a warning for now.
-rw-r--r--CHANGES.current19
-rw-r--r--Doc/Manual/SWIG.html43
-rw-r--r--Doc/Manual/Warnings.html3
-rw-r--r--Examples/test-suite/errors/expected.log4
-rwxr-xr-xExamples/test-suite/errors/make.sh1
-rw-r--r--Examples/test-suite/errors/swig_extend.i35
-rw-r--r--Examples/test-suite/extend_constructor_destructor.i3
-rw-r--r--Examples/test-suite/extend_typedef_class.i3
-rw-r--r--Source/CParse/parser.y42
-rw-r--r--Source/Include/swigwarn.h1
10 files changed, 134 insertions, 20 deletions
diff --git a/CHANGES.current b/CHANGES.current
index 9436c29e7..a111818d9 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -5,6 +5,25 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.10 (in progress)
============================
+2013-02-15: wsfulton
+ Deprecate typedef names used in %extend that are not the real class/struct name. For example:
+
+ typedef struct StructBName {
+ int myint;
+ } StructB;
+
+ %extend StructB {
+ void method() {}
+ }
+
+ will now trigger a warning:
+
+ swig_extend.i:19: Warning 326: Deprecated %extend name used - the struct name StructBName
+ should be used instead of the typedef name StructB.
+
+ This is only partially working anyway (the %extend only worked if placed after the class
+ definition).
+
2013-02-09: wsfulton
[CFFI] Apply patch #22 - Fix missing package before &body
diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html
index 58a3c8e55..25dc899de 100644
--- a/Doc/Manual/SWIG.html
+++ b/Doc/Manual/SWIG.html
@@ -2699,7 +2699,7 @@ the following declaration :</p>
<div class="code"><pre>
/* file : vector.h */
...
-typedef struct {
+typedef struct Vector {
double x,y,z;
} Vector;
@@ -2772,7 +2772,7 @@ of the Vector structure. For example:</p>
#include "vector.h"
%}
-typedef struct {
+typedef struct Vector {
double x,y,z;
%extend {
Vector(double x, double y, double z) { ... }
@@ -2783,7 +2783,7 @@ typedef struct {
</pre></div>
<p>
-Finally, <tt>%extend</tt> can be used to access externally written
+Note that <tt>%extend</tt> can be used to access externally written
functions provided they follow the naming convention used in this
example :</p>
@@ -2814,7 +2814,7 @@ double Vector_magnitude(Vector *v) {
#include "vector.h"
%}
-typedef struct {
+typedef struct Vector {
double x,y,z;
%extend {
Vector(int,int,int); // This calls new_Vector()
@@ -2827,6 +2827,37 @@ typedef struct {
</div>
<p>
+The name used for %extend should be the name of the struct and not the name of any typedef to the struct.
+For example:
+</p>
+
+<div class="code"><pre>
+typedef struct Integer {
+ int value;
+} Int;
+%extend Integer { ... } /* Correct name */
+%extend Int { ... } /* Incorrect name */
+
+struct Float {
+ float value;
+};
+typedef struct Float FloatValue;
+%extend Float { ... } /* Correct name */
+%extend FloatValue { ... } /* Incorrect name */
+</pre></div>
+
+<p>
+There is one exception to this rule and that is when the struct is anonymously named such as:
+</p>
+
+<div class="code"><pre>
+typedef struct {
+ double value;
+} Double;
+%extend Double { ... } /* Okay */
+</pre></div>
+
+<p>
A little known feature of the <tt>%extend</tt> directive is that
it can also be used to add synthesized attributes or to modify the
behavior of existing data attributes. For example, suppose you wanted
@@ -2862,7 +2893,7 @@ For example, consider this interface:
<div class="code">
<pre>
-typedef struct {
+typedef struct Person {
char name[50];
...
} Person;
@@ -2876,7 +2907,7 @@ the interface as follows to ensure this occurs whenever a name is read or writte
<div class="code">
<pre>
-typedef struct {
+typedef struct Person {
%extend {
char name[50];
}
diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html
index 1571146f1..ccb1751d5 100644
--- a/Doc/Manual/Warnings.html
+++ b/Doc/Manual/Warnings.html
@@ -423,7 +423,8 @@ example.i(4) : Syntax error in input.
<li>322. Redundant redeclaration of '<em>name</em>'.
<li>323. Recursive scope inheritance of '<em>name</em>'.
<li>324. Named nested template instantiations not supported. Processing as if no name was given to %template().
-<li>325. Nested class not currently supported (<em>name</em> ignored).
+<li>325. Nested <em>kind</em> not currently supported (<em>name</em> ignored).
+<li>326. Deprecated %extend name used - the <em>kind</em> name '<em>name</em>' should be used instead of the typedef name '<em>name</em>'.
<li>350. operator new ignored.
<li>351. operator delete ignored.
<li>352. operator+ ignored.
diff --git a/Examples/test-suite/errors/expected.log b/Examples/test-suite/errors/expected.log
index 9d4e5db77..d344d076b 100644
--- a/Examples/test-suite/errors/expected.log
+++ b/Examples/test-suite/errors/expected.log
@@ -188,6 +188,10 @@ pp_variable_args.i:6: Error: Variable length macro argument must be last paramet
:::::::::::::::::::::::::::::::: swig_apply_nargs.i :::::::::::::::::::::::::::::::::::
swig_apply_nargs.i:6: Error: Can't apply (char *str,int len) to (int x). Number of arguments don't match.
+:::::::::::::::::::::::::::::::: swig_extend.i :::::::::::::::::::::::::::::::::::
+swig_extend.i:19: Warning 326: Deprecated %extend name used - the struct name 'StructBName' should be used instead of the typedef name 'StructB'.
+swig_extend.i:34: Warning 303: %extend defined for an undeclared class StructDName.
+
:::::::::::::::::::::::::::::::: swig_identifier.i :::::::::::::::::::::::::::::::::::
swig_identifier.i:5: Warning 503: Can't wrap 'foo bar' unless renamed to a valid identifier.
diff --git a/Examples/test-suite/errors/make.sh b/Examples/test-suite/errors/make.sh
index 90f17a92a..b194299c9 100755
--- a/Examples/test-suite/errors/make.sh
+++ b/Examples/test-suite/errors/make.sh
@@ -54,6 +54,7 @@ pp_unterm_comment
pp_unterm_string
pp_variable_args
swig_apply_nargs
+swig_extend
swig_identifier
swig_insert_bad
swig_typemap_copy
diff --git a/Examples/test-suite/errors/swig_extend.i b/Examples/test-suite/errors/swig_extend.i
new file mode 100644
index 000000000..ef0652320
--- /dev/null
+++ b/Examples/test-suite/errors/swig_extend.i
@@ -0,0 +1,35 @@
+%module xxx
+
+typedef struct {
+ int myint;
+} StructA;
+
+typedef struct StructBName {
+ int myint;
+} StructB;
+
+typedef struct StructC {
+ int myint;
+} StructC;
+
+%extend StructA {
+ void method() {}
+}
+
+%extend StructB {
+ void method() {}
+}
+
+%extend StructC {
+ void method() {}
+}
+
+struct StructD {
+ int myint;
+};
+typedef struct StructD StructDName;
+
+%extend StructDName {
+ void method() {}
+}
+
diff --git a/Examples/test-suite/extend_constructor_destructor.i b/Examples/test-suite/extend_constructor_destructor.i
index a0ab1a0f6..95b48a6c5 100644
--- a/Examples/test-suite/extend_constructor_destructor.i
+++ b/Examples/test-suite/extend_constructor_destructor.i
@@ -1,5 +1,8 @@
%module extend_constructor_destructor
+%warnfilter(SWIGWARN_PARSE_EXTEND_NAME) Space::tagCStruct;
+%warnfilter(SWIGWARN_PARSE_EXTEND_NAME) tagEStruct;
+
%inline %{
int globalVar = 0;
diff --git a/Examples/test-suite/extend_typedef_class.i b/Examples/test-suite/extend_typedef_class.i
index 731802573..2b8c38351 100644
--- a/Examples/test-suite/extend_typedef_class.i
+++ b/Examples/test-suite/extend_typedef_class.i
@@ -1,5 +1,8 @@
%module extend_typedef_class
+%warnfilter(SWIGWARN_PARSE_EXTEND_NAME) tagCClass;
+%warnfilter(SWIGWARN_PARSE_EXTEND_NAME) tagCStruct;
+
// classes in global namespace
%inline %{
typedef struct tagAClass {
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 36adf5a09..74d41079c 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -38,6 +38,7 @@ static Node *top = 0; /* Top of the generated parse tree */
static int unnamed = 0; /* Unnamed datatype counter */
static Hash *extendhash = 0; /* Hash table of added methods */
static Hash *classes = 0; /* Hash table of classes */
+static Hash *classes_typedefs = 0; /* Hash table of typedef classes: typedef struct X {...} Y; */
static Symtab *prev_symtab = 0;
static Node *current_class = 0;
String *ModuleName = 0;
@@ -718,7 +719,7 @@ static void check_extensions() {
for (ki = First(extendhash); ki.key; ki = Next(ki)) {
if (!Strchr(ki.key,'<')) {
SWIG_WARN_NODE_BEGIN(ki.item);
- Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key);
+ Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", SwigType_namestr(ki.key));
SWIG_WARN_NODE_END(ki.item);
}
}
@@ -1909,20 +1910,34 @@ extend_directive : EXTEND options idcolon LBRACE {
String *clsname;
cplus_mode = CPLUS_PUBLIC;
if (!classes) classes = NewHash();
+ if (!classes_typedefs) classes_typedefs = NewHash();
if (!extendhash) extendhash = NewHash();
clsname = make_class_name($3);
cls = Getattr(classes,clsname);
if (!cls) {
- /* No previous definition. Create a new scope */
- Node *am = Getattr(extendhash,clsname);
- if (!am) {
- Swig_symbol_newscope();
- Swig_symbol_setscopename($3);
- prev_symtab = 0;
+ cls = Getattr(classes_typedefs, clsname);
+ if (!cls) {
+ /* No previous definition. Create a new scope */
+ Node *am = Getattr(extendhash,clsname);
+ if (!am) {
+ Swig_symbol_newscope();
+ Swig_symbol_setscopename($3);
+ prev_symtab = 0;
+ } else {
+ prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab"));
+ }
+ current_class = 0;
} else {
- prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab"));
+ /* Previous typedef class definition. Use its symbol table.
+ Deprecated, just the real name should be used.
+ Note that %extend before the class typedef never worked, only %extend after the class typdef. */
+ prev_symtab = Swig_symbol_setscope(Getattr(cls, "symtab"));
+ current_class = cls;
+ extendmode = 1;
+ SWIG_WARN_NODE_BEGIN(cls);
+ Swig_warning(WARN_PARSE_EXTEND_NAME, cparse_file, cparse_line, "Deprecated %%extend name used - the %s name '%s' should be used instead of the typedef name '%s'.\n", Getattr(cls, "kind"), SwigType_namestr(Getattr(cls, "name")), $3);
+ SWIG_WARN_NODE_END(cls);
}
- current_class = 0;
} else {
/* Previous class definition. Use its symbol table */
prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab"));
@@ -3585,7 +3600,6 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
if (!classes) classes = NewHash();
scpname = Swig_symbol_qualifiedscopename(0);
Setattr(classes,scpname,$$);
- Delete(scpname);
appendChild($$,$7);
@@ -3606,7 +3620,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
Setattr(p,"type",ty);
p = nextSibling(p);
}
- /* Dump nested classes */
+ /* Class typedefs */
{
String *name = $3;
if ($9) {
@@ -3626,8 +3640,9 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
Delete(class_rename);
class_rename = NewString(name);
}
- if (!Getattr(classes,tdscopename)) {
- Setattr(classes,tdscopename,$$);
+ if (!classes_typedefs) classes_typedefs = NewHash();
+ if (!Equal(scpname, tdscopename) && !Getattr(classes_typedefs, tdscopename)) {
+ Setattr(classes_typedefs, tdscopename, $$);
}
Setattr($$,"decl",decltype);
Delete(class_scope);
@@ -3638,6 +3653,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
}
appendChild($$,dump_nested(Char(name)));
}
+ Delete(scpname);
if (cplus_mode != CPLUS_PUBLIC) {
/* we 'open' the class at the end, to allow %template
diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h
index 76f61ea93..a3fb31012 100644
--- a/Source/Include/swigwarn.h
+++ b/Source/Include/swigwarn.h
@@ -89,6 +89,7 @@
#define WARN_PARSE_REC_INHERITANCE 323
#define WARN_PARSE_NESTED_TEMPLATE 324
#define WARN_PARSE_NAMED_NESTED_CLASS 325
+#define WARN_PARSE_EXTEND_NAME 326
#define WARN_IGNORE_OPERATOR_NEW 350 /* new */
#define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */