mirror of https://github.com/swig/swig
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.
This commit is contained in:
parent
054f9dba1a
commit
b80f4dc5e2
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
@ -2826,6 +2826,37 @@ typedef struct {
|
|||
</pre>
|
||||
</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
|
||||
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue