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)
============================
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

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">
<pre>
#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
<p>
<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.
Nested class warnings could also not be suppressed using %warnfilter.
</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>309. [private | protected] inheritance 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>314. '<em>identifier</em>' is a <em>lang</em> keyword.
<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>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>350. operator new ignored.
<li>351. operator delete ignored.
<li>352. operator+ ignored.

View file

@ -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) {}
};
%}

View file

@ -1,5 +1,7 @@
%module namespace_class
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Ala::Ola;
%inline %{
template<class T> 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;

View file

@ -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 {

View file

@ -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

View file

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

View file

@ -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<int> useInner1(const Inner1<int>& inner) { return inner; }
template <class Z> void InnerTMethod(Z z) {}
@ -52,6 +57,7 @@ namespace ns {
void method1(Y y) {}
};
};
Inner2<int> useInner2(const Inner2<int>& inner) { return inner; }
int iii;
};
struct ABC {

View file

@ -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 {

View file

@ -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);
}
}
*/

View file

@ -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 */