diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2013-02-18 19:53:37 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2013-02-18 19:53:37 +0000 |
commit | b80f4dc5e257a343381e3dbeebb206c1376e3ca3 (patch) | |
tree | cf066844423f973be18460e727a6490c8ed867ee | |
parent | 054f9dba1a6f2914d1ed69042162aa4f9d72e0ef (diff) | |
download | swig-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.current | 19 | ||||
-rw-r--r-- | Doc/Manual/SWIG.html | 43 | ||||
-rw-r--r-- | Doc/Manual/Warnings.html | 3 | ||||
-rw-r--r-- | Examples/test-suite/errors/expected.log | 4 | ||||
-rwxr-xr-x | Examples/test-suite/errors/make.sh | 1 | ||||
-rw-r--r-- | Examples/test-suite/errors/swig_extend.i | 35 | ||||
-rw-r--r-- | Examples/test-suite/extend_constructor_destructor.i | 3 | ||||
-rw-r--r-- | Examples/test-suite/extend_typedef_class.i | 3 | ||||
-rw-r--r-- | Source/CParse/parser.y | 42 | ||||
-rw-r--r-- | Source/Include/swigwarn.h | 1 |
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 */ |