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
This commit is contained in:
William S Fulton 2009-11-12 19:47:04 +00:00
commit aa61c716a8
12 changed files with 103 additions and 31 deletions

View file

@ -1,5 +1,23 @@
Version 1.3.41 (in progress) 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 2009-11-11: wsfulton
Added the nestedworkaround feature as a way to use the full functionality of a nested class 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 (C++ mode only). It removes the nested class from SWIG's type information so it is as if SWIG

View file

@ -4714,7 +4714,8 @@ The easiest thing to do is turn a blind eye to the warning that SWIG generates,
<div class="code"> <div class="code">
<pre> <pre>
#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
class Outer { class Outer {
public: public:
class Inner { class Inner {
@ -4830,6 +4831,7 @@ This should just be a last resort for unusual corner cases now as SWIG can parse
<p> <p>
<b>Compatibility Note:</b> SWIG-1.3.40 and earlier versions did not have the <tt>nestedworkaround</tt> feature <b>Compatibility Note:</b> SWIG-1.3.40 and earlier versions did not have the <tt>nestedworkaround</tt> feature
and the generated code resulting from parsing nested classes did not always compile. and the generated code resulting from parsing nested classes did not always compile.
Nested class warnings could also not be suppressed using %warnfilter.
</p> </p>

View file

@ -399,7 +399,7 @@ example.i(4): Syntax error in input.
<li>308. Namespace alias '<em>name</em>' not allowed here. Assuming '<em>name</em>' <li>308. Namespace alias '<em>name</em>' not allowed here. Assuming '<em>name</em>'
<li>309. [private | protected] inheritance ignored. <li>309. [private | protected] inheritance ignored.
<li>310. Template '<em>name</em>' was already wrapped as '<em>name</em>' (ignored) <li>310. Template '<em>name</em>' was already wrapped as '<em>name</em>' (ignored)
<li>312. Nested class not currently supported (<em>name</em> ignored). <li>312. Unnamed nested class not currently supported (ignored).
<li>313. Unrecognized extern type "<em>name</em>" (ignored). <li>313. Unrecognized extern type "<em>name</em>" (ignored).
<li>314. '<em>identifier</em>' is a <em>lang</em> keyword. <li>314. '<em>identifier</em>' is a <em>lang</em> keyword.
<li>315. Nothing known about '<em>identifier</em>'. <li>315. Nothing known about '<em>identifier</em>'.
@ -412,6 +412,7 @@ example.i(4): Syntax error in input.
<li>322. Redundant redeclaration of '<em>name</em>'. <li>322. Redundant redeclaration of '<em>name</em>'.
<li>323. Recursive scope inheritance 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>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>350. operator new ignored. <li>350. operator new ignored.
<li>351. operator delete ignored. <li>351. operator delete ignored.
<li>352. operator+ ignored. <li>352. operator+ ignored.

View file

@ -3,7 +3,9 @@ This was reported in bug #909389 */
%module derived_nested %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 %{ %inline %{
@ -17,6 +19,7 @@ struct BB {
class CC { int y; }; class CC { int y; };
class DD : public A { int z; }; class DD : public A { int z; };
struct EE : public A { int z; }; struct EE : public A { int z; };
void useEE(const EE& e) {}
}; };
%} %}

View file

@ -1,5 +1,7 @@
%module namespace_class %module namespace_class
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Ala::Ola;
%inline %{ %inline %{
template<class T> void foobar(T t) {} template<class T> void foobar(T t) {}
namespace test { namespace test {
@ -210,7 +212,6 @@ namespace a
%} %}
#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
// %copyctor doesn't work with nested class workaround // %copyctor doesn't work with nested class workaround
%nocopyctor; %nocopyctor;

View file

@ -1,6 +1,18 @@
%module nested_class %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 %{ %inline %{
struct Outer { struct Outer {

View file

@ -1,5 +1,8 @@
%module nested_comment %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). // this example shows a problem with 'dump_nested' (parser.y).
// bug #949654 // bug #949654

View file

@ -3,12 +3,6 @@
%module template_classes %module template_classes
#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
%{
%}
%inline %{ %inline %{
template <class T> template <class T>
@ -27,21 +21,16 @@ public:
private: private:
Point<T> point; Point<T> point;
template <class Data> template <class Data>
struct pair2nd_eq struct pair2nd_eq
{ {
}; };
struct Foo : Point<int> struct Foo : Point<int>
{ {
}; };
Foo foo; Foo foo;
}; };
%} %}
@ -49,4 +38,3 @@ private:
%template(PointInt) Point<int>; %template(PointInt) Point<int>;
%template(RectangleInt) RectangleTest<int>; %template(RectangleInt) RectangleTest<int>;

View file

@ -2,7 +2,11 @@
// Test nested templates - that is template classes and template methods within a class. // 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 %{ %inline %{
@ -33,6 +37,7 @@ namespace ns {
void method1(Y y) {} void method1(Y y) {}
}; };
}; };
Inner1<int> useInner1(const Inner1<int>& inner) { return inner; }
template <class Z> void InnerTMethod(Z z) {} template <class Z> void InnerTMethod(Z z) {}
@ -52,6 +57,7 @@ namespace ns {
void method1(Y y) {} void method1(Y y) {}
}; };
}; };
Inner2<int> useInner2(const Inner2<int>& inner) { return inner; }
int iii; int iii;
}; };
struct ABC { struct ABC {

View file

@ -2,6 +2,7 @@
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState; // Ruby, wrong class name %warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState; // Ruby, wrong class name
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState_rstate; // Ruby, wrong class name %warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState_rstate; // Ruby, wrong class name
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) nRState::rstate;
%inline %{ %inline %{
class nRState { class nRState {

View file

@ -3645,12 +3645,30 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN {
if (nested_template <= 1) { if (nested_template <= 1) {
int is_nested_template_class = $6 && GetFlag($6, "nestedtemplateclass"); int is_nested_template_class = $6 && GetFlag($6, "nestedtemplateclass");
if (is_nested_template_class) { 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 */ /* 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) { 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); Delete($6);
$$ = 0;
} else { } else {
String *tname = 0; String *tname = 0;
int error = 0; int error = 0;
@ -4394,7 +4412,9 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
Swig_symbol_remove($$); Swig_symbol_remove($$);
$$ = 0; $$ = 0;
} else { } 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) { } else if ($6.id) {
/* Generate some code for a new struct */ /* 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($$); Swig_symbol_remove($$);
$$ = 0; $$ = 0;
} else { } 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 { } else {
/* Generate some code for a new struct */ /* 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); add_nested(n);
} }
} else { } 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 */ /* class name : base_list { }; declaration */
/***** /* This adds one shift/reduce. */
This fixes derived_nested.i, but it adds one shift/reduce. Anyway,
we are waiting for the nested class support.
*****/
| storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
} SEMI { } SEMI {
$$ = 0; $$ = 0;
if (cplus_mode == CPLUS_PUBLIC) { 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 { } SEMI {
$$ = 0; $$ = 0;
if (cplus_mode == CPLUS_PUBLIC) { 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);
} }
} }
*/ */

View file

@ -72,7 +72,7 @@
#define WARN_PARSE_PRIVATE_INHERIT 309 #define WARN_PARSE_PRIVATE_INHERIT 309
#define WARN_PARSE_TEMPLATE_REPEAT 310 #define WARN_PARSE_TEMPLATE_REPEAT 310
#define WARN_PARSE_TEMPLATE_PARTIAL 311 #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_UNDEFINED_EXTERN 313
#define WARN_PARSE_KEYWORD 314 #define WARN_PARSE_KEYWORD 314
#define WARN_PARSE_USING_UNDEF 315 #define WARN_PARSE_USING_UNDEF 315
@ -85,6 +85,7 @@
#define WARN_PARSE_REDUNDANT 322 #define WARN_PARSE_REDUNDANT 322
#define WARN_PARSE_REC_INHERITANCE 323 #define WARN_PARSE_REC_INHERITANCE 323
#define WARN_PARSE_NESTED_TEMPLATE 324 #define WARN_PARSE_NESTED_TEMPLATE 324
#define WARN_PARSE_NAMED_NESTED_CLASS 325
#define WARN_IGNORE_OPERATOR_NEW 350 /* new */ #define WARN_IGNORE_OPERATOR_NEW 350 /* new */
#define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */ #define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */