Merge branch 'ZackerySpytz-director-classes-final-methods'
* ZackerySpytz-director-classes-final-methods: Warning tweaks for destructors that are final in director classes Documentation for directors and virtual final methods Fixes for final destructors in director classes Warning fix for final destructor in directors Remove a useless warning filter Fix the handling of director classes with final methods
This commit is contained in:
commit
bc0645ce2b
14 changed files with 128 additions and 20 deletions
|
|
@ -47,6 +47,9 @@ Version 4.0.0 (in progress)
|
|||
2019-02-22: tamuratak
|
||||
#984 Add support for RTypedData introduced in Ruby 1.9.3.
|
||||
|
||||
2019-02-22: ZackerySpytz
|
||||
#1483 Fix compilation failures when a director class has final methods.
|
||||
|
||||
2019-02-21: wsfulton
|
||||
#1240 Suppress Java 9 deprecation warnings on finalize method.
|
||||
|
||||
|
|
|
|||
|
|
@ -785,7 +785,9 @@ In order to override virtual methods on a C++ class with Go methods the
|
|||
<tt>NewDirectorClassName</tt> constructor functions receives a
|
||||
<tt>DirectorInterface</tt> argument. The methods in the <tt>
|
||||
DirectorInterface</tt> are a subset of the public and protected virtual methods
|
||||
of the C++ class. If the <tt>DirectorInterface</tt> contains a method with a
|
||||
of the C++ class.
|
||||
Virtual methods that have a final specifier are unsurprisingly excluded.
|
||||
If the <tt>DirectorInterface</tt> contains a method with a
|
||||
matching signature to a virtual method of the C++ class then the virtual C++
|
||||
method will be overwritten with the Go method. As Go doesn't support protected
|
||||
methods all overridden protected virtual C++ methods will be public in Go.
|
||||
|
|
|
|||
|
|
@ -3629,7 +3629,7 @@ The %feature directive can be applied globally, to specific classes, and to spec
|
|||
// generate directors for all classes that have virtual methods
|
||||
%feature("director");
|
||||
|
||||
// generate directors for all virtual methods in class Foo
|
||||
// generate directors for the virtual methods in class Foo
|
||||
%feature("director") Foo;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3647,7 +3647,7 @@ So for example,
|
|||
</div>
|
||||
|
||||
<p>
|
||||
will generate directors for all virtual methods of class Foo except bar().
|
||||
will generate directors for the virtual methods of class Foo except bar().
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -3683,7 +3683,8 @@ The director classes store a pointer to their underlying Java proxy classes.
|
|||
<p>
|
||||
For simplicity let's ignore the <tt>Swig::Director</tt> class and refer to the original C++ class as the director's base class.
|
||||
By default, a director class extends all virtual methods in the inheritance chain of its base class (see the preceding section for how to modify this behavior).
|
||||
Thus all virtual method calls, whether they originate in C++ or in Java via proxy classes, eventually end up in at the implementation in the director class.
|
||||
Virtual methods that have a final specifier are unsurprisingly excluded.
|
||||
Thus the virtual method calls, whether they originate in C++ or in Java via proxy classes, eventually end up in at the implementation in the director class.
|
||||
The job of the director methods is to route these method calls to the appropriate place in the inheritance chain.
|
||||
By "appropriate place" we mean the method that would have been called if the C++ base class and its Java derived classes were seamlessly integrated.
|
||||
That seamless integration is exactly what the director classes provide, transparently skipping over all the messy JNI glue code that binds the two languages together.
|
||||
|
|
|
|||
|
|
@ -3070,7 +3070,7 @@ globally, to specific classes, and to specific methods, like this:
|
|||
// generate directors for all classes that have virtual methods
|
||||
%feature("director");
|
||||
|
||||
// generate directors for all virtual methods in class Foo
|
||||
// generate directors for the virtual methods in class Foo
|
||||
%feature("director") Foo;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3088,7 +3088,7 @@ directors for specific classes or methods. So for example,
|
|||
</div>
|
||||
|
||||
<p>
|
||||
will generate directors for all virtual methods of class Foo except
|
||||
will generate directors for the virtual methods of class Foo except
|
||||
bar().
|
||||
</p>
|
||||
|
||||
|
|
@ -3153,7 +3153,8 @@ For simplicity let's ignore the <tt>Swig::Director</tt> class and refer to the
|
|||
original C++ class as the director's base class. By default, a director
|
||||
class extends all virtual methods in the inheritance chain of its base
|
||||
class (see the preceding section for how to modify this behavior).
|
||||
Thus all virtual method calls, whether they originate in C++ or in
|
||||
Virtual methods that have a final specifier are unsurprisingly excluded.
|
||||
Thus the virtual method calls, whether they originate in C++ or in
|
||||
Perl via proxy classes, eventually end up in at the implementation in
|
||||
the director class. The job of the director methods is to route these
|
||||
method calls to the appropriate place in the inheritance chain. By
|
||||
|
|
|
|||
|
|
@ -937,7 +937,7 @@ globally, to specific classes, and to specific methods, like this:
|
|||
// generate directors for all classes that have virtual methods
|
||||
%feature("director");
|
||||
|
||||
// generate directors for all virtual methods in class Foo
|
||||
// generate directors for the virtual methods in class Foo
|
||||
%feature("director") Foo;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -955,7 +955,7 @@ directors for specific classes or methods. So for example,
|
|||
</div>
|
||||
|
||||
<p>
|
||||
will generate directors for all virtual methods of class Foo except
|
||||
will generate directors for the virtual methods of class Foo except
|
||||
bar().
|
||||
</p>
|
||||
|
||||
|
|
@ -1020,7 +1020,8 @@ For simplicity let's ignore the <tt>Swig::Director</tt> class and refer to the
|
|||
original C++ class as the director's base class. By default, a director
|
||||
class extends all virtual methods in the inheritance chain of its base
|
||||
class (see the preceding section for how to modify this behavior).
|
||||
Thus all virtual method calls, whether they originate in C++ or in
|
||||
Virtual methods that have a final specifier are unsurprisingly excluded.
|
||||
Thus the virtual method calls, whether they originate in C++ or in
|
||||
PHP via proxy classes, eventually end up in at the implementation in the
|
||||
director class. The job of the director methods is to route these method
|
||||
calls to the appropriate place in the inheritance chain. By "appropriate
|
||||
|
|
|
|||
|
|
@ -2934,7 +2934,7 @@ globally, to specific classes, and to specific methods, like this:
|
|||
// generate directors for all classes that have virtual methods
|
||||
%feature("director");
|
||||
|
||||
// generate directors for all virtual methods in class Foo
|
||||
// generate directors for the virtual methods in class Foo
|
||||
%feature("director") Foo;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2952,7 +2952,7 @@ directors for specific classes or methods. So for example,
|
|||
</div>
|
||||
|
||||
<p>
|
||||
will generate directors for all virtual methods of class Foo except
|
||||
will generate directors for the virtual methods of class Foo except
|
||||
bar().
|
||||
</p>
|
||||
|
||||
|
|
@ -3018,7 +3018,8 @@ For simplicity let's ignore the <tt>Swig::Director</tt> class and refer to the
|
|||
original C++ class as the director's base class. By default, a director
|
||||
class extends all virtual methods in the inheritance chain of its base
|
||||
class (see the preceding section for how to modify this behavior).
|
||||
Thus all virtual method calls, whether they originate in C++ or in
|
||||
Virtual methods that have a final specifier are unsurprisingly excluded.
|
||||
Thus the virtual method calls, whether they originate in C++ or in
|
||||
Python via proxy classes, eventually end up in at the implementation in
|
||||
the director class. The job of the director methods is to route these
|
||||
method calls to the appropriate place in the inheritance chain. By
|
||||
|
|
|
|||
|
|
@ -535,6 +535,7 @@ example.i(4) : Syntax error in input(1).
|
|||
<li>522. Use of an illegal constructor name '<em>name</em>' in %extend is deprecated, the constructor name should be '<em>name</em>'.
|
||||
<li>523. Use of an illegal destructor name '<em>name</em>' in %extend is deprecated, the destructor name should be '<em>name</em>'.
|
||||
<li>524. Experimental target language. Target language <em>language</em> specified by <em>lang</em> is an experimental language. Please read about SWIG experimental languages, <em>htmllink</em>.
|
||||
<li>525. Destructor <em>declaration</em> is final, <em>name</em> cannot be a director class.
|
||||
</ul>
|
||||
|
||||
<H3><a name="Warnings_doxygen">18.9.6 Doxygen comments (560-599)</a></H3>
|
||||
|
|
|
|||
|
|
@ -572,6 +572,7 @@ CPP11_TEST_CASES += \
|
|||
cpp11_director_enums \
|
||||
cpp11_directors \
|
||||
cpp11_explicit_conversion_operators \
|
||||
cpp11_final_directors \
|
||||
cpp11_final_override \
|
||||
cpp11_function_objects \
|
||||
cpp11_inheriting_constructors \
|
||||
|
|
|
|||
33
Examples/test-suite/cpp11_final_directors.i
Normal file
33
Examples/test-suite/cpp11_final_directors.i
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
%module(directors="1") cpp11_final_directors
|
||||
|
||||
%director Derived;
|
||||
|
||||
// Check SWIG will not wrap these classes as directors where the destructors are final
|
||||
%director BaseFinalDestructor;
|
||||
%director BaseFinalDestructor2;
|
||||
|
||||
%warnfilter(SWIGWARN_LANG_DIRECTOR_FINAL) BaseFinalDestructor::~BaseFinalDestructor;
|
||||
%warnfilter(SWIGWARN_LANG_DIRECTOR_FINAL) BaseFinalDestructor2::~BaseFinalDestructor2;
|
||||
|
||||
%inline %{
|
||||
struct Base {
|
||||
virtual void basemeth() final {}
|
||||
virtual ~Base() {}
|
||||
};
|
||||
|
||||
struct Derived : Base {
|
||||
virtual int derivedmeth() final { return 1; }
|
||||
virtual int meth() { return 2; }
|
||||
virtual ~Derived() {}
|
||||
};
|
||||
|
||||
struct BaseFinalDestructor {
|
||||
virtual void basefinalmeth() final {}
|
||||
virtual ~BaseFinalDestructor() final {}
|
||||
};
|
||||
|
||||
struct BaseFinalDestructor2 {
|
||||
virtual void basefinalmeth() {}
|
||||
virtual ~BaseFinalDestructor2() final {}
|
||||
};
|
||||
%}
|
||||
1
Examples/test-suite/errors/cpp_final_destructor.stderr
Normal file
1
Examples/test-suite/errors/cpp_final_destructor.stderr
Normal file
|
|
@ -0,0 +1 @@
|
|||
cpp_final_destructor.i:7: Warning 525: Destructor BaseFinal::~BaseFinal() is final, BaseFinal cannot be a director class.
|
||||
11
Examples/test-suite/python/cpp11_final_directors_runme.py
Normal file
11
Examples/test-suite/python/cpp11_final_directors_runme.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import cpp11_final_directors
|
||||
|
||||
class Derived2(cpp11_final_directors.Derived):
|
||||
|
||||
def meth(self):
|
||||
return 3
|
||||
|
||||
|
||||
b = Derived2()
|
||||
if b.meth() != 3:
|
||||
raise RuntimeError
|
||||
|
|
@ -1552,6 +1552,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
|
|||
Parm *throws;
|
||||
String *throwf;
|
||||
String *nexcept;
|
||||
String *final;
|
||||
} dtype;
|
||||
struct {
|
||||
const char *type;
|
||||
|
|
@ -1567,6 +1568,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
|
|||
ParmList *throws;
|
||||
String *throwf;
|
||||
String *nexcept;
|
||||
String *final;
|
||||
} decl;
|
||||
Parm *tparms;
|
||||
struct {
|
||||
|
|
@ -3189,6 +3191,7 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
|
|||
Setattr($$,"throws",$4.throws);
|
||||
Setattr($$,"throw",$4.throwf);
|
||||
Setattr($$,"noexcept",$4.nexcept);
|
||||
Setattr($$,"final",$4.final);
|
||||
if ($5.val && $5.type) {
|
||||
/* store initializer type as it might be different to the declared type */
|
||||
SwigType *valuetype = NewSwigType($5.type);
|
||||
|
|
@ -3266,6 +3269,7 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
|
|||
Setattr($$,"throws",$4.throws);
|
||||
Setattr($$,"throw",$4.throwf);
|
||||
Setattr($$,"noexcept",$4.nexcept);
|
||||
Setattr($$,"final",$4.final);
|
||||
if (!$9) {
|
||||
if (Len(scanner_ccode)) {
|
||||
String *code = Copy(scanner_ccode);
|
||||
|
|
@ -3330,6 +3334,7 @@ c_decl_tail : SEMI {
|
|||
Setattr($$,"throws",$3.throws);
|
||||
Setattr($$,"throw",$3.throwf);
|
||||
Setattr($$,"noexcept",$3.nexcept);
|
||||
Setattr($$,"final",$3.final);
|
||||
if ($4.bitfield) {
|
||||
Setattr($$,"bitfield", $4.bitfield);
|
||||
}
|
||||
|
|
@ -3638,6 +3643,7 @@ c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
|
|||
Setattr($$,"throws",$6.throws);
|
||||
Setattr($$,"throw",$6.throwf);
|
||||
Setattr($$,"noexcept",$6.nexcept);
|
||||
Setattr($$,"final",$6.final);
|
||||
err = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -4704,6 +4710,7 @@ cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
|
|||
Setattr($$,"throws",$6.throws);
|
||||
Setattr($$,"throw",$6.throwf);
|
||||
Setattr($$,"noexcept",$6.nexcept);
|
||||
Setattr($$,"final",$6.final);
|
||||
if (Len(scanner_ccode)) {
|
||||
String *code = Copy(scanner_ccode);
|
||||
Setattr($$,"code",code);
|
||||
|
|
@ -4740,6 +4747,7 @@ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
|
|||
Setattr($$,"throws",$6.throws);
|
||||
Setattr($$,"throw",$6.throwf);
|
||||
Setattr($$,"noexcept",$6.nexcept);
|
||||
Setattr($$,"final",$6.final);
|
||||
if ($6.val)
|
||||
Setattr($$,"value",$6.val);
|
||||
if ($6.qualifier)
|
||||
|
|
@ -4760,6 +4768,7 @@ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
|
|||
Setattr($$,"throws",$7.throws);
|
||||
Setattr($$,"throw",$7.throwf);
|
||||
Setattr($$,"noexcept",$7.nexcept);
|
||||
Setattr($$,"final",$7.final);
|
||||
if ($7.val)
|
||||
Setattr($$,"value",$7.val);
|
||||
if (Len(scanner_ccode)) {
|
||||
|
|
@ -4941,6 +4950,7 @@ cpp_end : cpp_const SEMI {
|
|||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.final = $1.final;
|
||||
}
|
||||
| cpp_const EQUAL default_delete SEMI {
|
||||
Clear(scanner_ccode);
|
||||
|
|
@ -4951,6 +4961,7 @@ cpp_end : cpp_const SEMI {
|
|||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.final = $1.final;
|
||||
}
|
||||
| cpp_const LBRACE {
|
||||
skip_balanced('{','}');
|
||||
|
|
@ -4961,6 +4972,7 @@ cpp_end : cpp_const SEMI {
|
|||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.final = $1.final;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -4973,6 +4985,7 @@ cpp_vend : cpp_const SEMI {
|
|||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.final = $1.final;
|
||||
}
|
||||
| cpp_const EQUAL definetype SEMI {
|
||||
Clear(scanner_ccode);
|
||||
|
|
@ -4982,7 +4995,8 @@ cpp_vend : cpp_const SEMI {
|
|||
$$.bitfield = 0;
|
||||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.final = $1.final;
|
||||
}
|
||||
| cpp_const LBRACE {
|
||||
skip_balanced('{','}');
|
||||
|
|
@ -4992,7 +5006,8 @@ cpp_vend : cpp_const SEMI {
|
|||
$$.bitfield = 0;
|
||||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.final = $1.final;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -5210,6 +5225,7 @@ def_args : EQUAL definetype {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
}
|
||||
| EQUAL definetype LBRACKET expr RBRACKET {
|
||||
|
|
@ -5223,6 +5239,7 @@ def_args : EQUAL definetype {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
} else {
|
||||
$$.val = NewStringf("%s[%s]",$2.val,$4.val);
|
||||
}
|
||||
|
|
@ -5236,6 +5253,7 @@ def_args : EQUAL definetype {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
| COLON expr {
|
||||
$$.val = 0;
|
||||
|
|
@ -5245,6 +5263,7 @@ def_args : EQUAL definetype {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
| empty {
|
||||
$$.val = 0;
|
||||
|
|
@ -5254,6 +5273,7 @@ def_args : EQUAL definetype {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -6293,6 +6313,7 @@ definetype : { /* scanner_check_typedef(); */ } expr {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
scanner_ignore_typedef();
|
||||
}
|
||||
| default_delete {
|
||||
|
|
@ -6319,6 +6340,7 @@ deleted_definition : DELETE_KW {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -6333,6 +6355,7 @@ explicit_default : DEFAULT {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -6525,6 +6548,7 @@ valexpr : exprnum {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
| WCHARCONST {
|
||||
$$.val = NewString($1);
|
||||
|
|
@ -6538,6 +6562,7 @@ valexpr : exprnum {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
|
||||
/* grouping */
|
||||
|
|
@ -6892,18 +6917,18 @@ virt_specifier_seq : OVERRIDE {
|
|||
$$ = 0;
|
||||
}
|
||||
| FINAL {
|
||||
$$ = 0;
|
||||
$$ = NewString("1");
|
||||
}
|
||||
| FINAL OVERRIDE {
|
||||
$$ = 0;
|
||||
$$ = NewString("1");
|
||||
}
|
||||
| OVERRIDE FINAL {
|
||||
$$ = 0;
|
||||
$$ = NewString("1");
|
||||
}
|
||||
;
|
||||
|
||||
virt_specifier_seq_opt : virt_specifier_seq {
|
||||
$$ = 0;
|
||||
$$ = $1;
|
||||
}
|
||||
| empty {
|
||||
$$ = 0;
|
||||
|
|
@ -6914,31 +6939,37 @@ exception_specification : THROW LPAREN parms RPAREN {
|
|||
$$.throws = $3;
|
||||
$$.throwf = NewString("1");
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
| NOEXCEPT {
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = NewString("true");
|
||||
$$.final = 0;
|
||||
}
|
||||
| virt_specifier_seq {
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = $1;
|
||||
}
|
||||
| THROW LPAREN parms RPAREN virt_specifier_seq {
|
||||
$$.throws = $3;
|
||||
$$.throwf = NewString("1");
|
||||
$$.nexcept = 0;
|
||||
$$.final = $5;
|
||||
}
|
||||
| NOEXCEPT virt_specifier_seq {
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = NewString("true");
|
||||
$$.final = $2;
|
||||
}
|
||||
| NOEXCEPT LPAREN expr RPAREN {
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = $3.val;
|
||||
$$.final = 0;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -6946,6 +6977,7 @@ qualifiers_exception_specification : cv_ref_qualifier {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
$$.qualifier = $1.qualifier;
|
||||
$$.refqualifier = $1.refqualifier;
|
||||
}
|
||||
|
|
@ -6968,6 +7000,7 @@ cpp_const : qualifiers_exception_specification {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
$$.qualifier = 0;
|
||||
$$.refqualifier = 0;
|
||||
}
|
||||
|
|
@ -6980,6 +7013,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
|
|||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.final = $1.final;
|
||||
if ($1.qualifier)
|
||||
Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
|
||||
}
|
||||
|
|
@ -6990,6 +7024,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
|
|||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.final = $1.final;
|
||||
if ($1.qualifier)
|
||||
Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
|
||||
}
|
||||
|
|
@ -7001,6 +7036,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
| LPAREN parms RPAREN LBRACE {
|
||||
skip_balanced('{','}');
|
||||
|
|
@ -7010,6 +7046,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
| EQUAL definetype SEMI {
|
||||
$$.have_parms = 0;
|
||||
|
|
@ -7017,6 +7054,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
|
|||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.final = 0;
|
||||
}
|
||||
| exception_specification EQUAL default_delete SEMI {
|
||||
$$.have_parms = 0;
|
||||
|
|
@ -7024,6 +7062,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
|
|||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
$$.final = $1.final;
|
||||
if ($1.qualifier)
|
||||
Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@
|
|||
#define WARN_LANG_EXTEND_CONSTRUCTOR 522
|
||||
#define WARN_LANG_EXTEND_DESTRUCTOR 523
|
||||
#define WARN_LANG_EXPERIMENTAL 524
|
||||
#define WARN_LANG_DIRECTOR_FINAL 525
|
||||
|
||||
/* -- Doxygen comments -- */
|
||||
|
||||
|
|
|
|||
|
|
@ -1894,6 +1894,8 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_
|
|||
}
|
||||
if (!checkAttribute(nn, "storage", "virtual"))
|
||||
continue;
|
||||
if (GetFlag(nn, "final"))
|
||||
continue;
|
||||
/* we need to add methods(cdecl) and destructor (to check for throw decl) */
|
||||
int is_destructor = (Cmp(nodeType, "destructor") == 0);
|
||||
if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
|
||||
|
|
@ -2109,7 +2111,7 @@ int Language::classDirectorMethods(Node *n) {
|
|||
Node *item = Getitem(vtable, i);
|
||||
String *method = Getattr(item, "methodNode");
|
||||
String *fqdname = Getattr(item, "fqdname");
|
||||
if (GetFlag(method, "feature:nodirector"))
|
||||
if (GetFlag(method, "feature:nodirector") || GetFlag(method, "final"))
|
||||
continue;
|
||||
|
||||
String *wrn = Getattr(method, "feature:warnfilter");
|
||||
|
|
@ -2198,6 +2200,16 @@ int Language::classDirector(Node *n) {
|
|||
String *using_protected_members_code = NewString("");
|
||||
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
|
||||
Node *nodeType = Getattr(ni, "nodeType");
|
||||
if (Cmp(nodeType, "destructor") == 0 && GetFlag(ni, "final")) {
|
||||
String *classtype = Getattr(n, "classtype");
|
||||
SWIG_WARN_NODE_BEGIN(ni);
|
||||
Swig_warning(WARN_LANG_DIRECTOR_FINAL, input_file, line_number, "Destructor %s is final, %s cannot be a director class.\n", Swig_name_decl(ni), classtype);
|
||||
SWIG_WARN_NODE_END(ni);
|
||||
SetFlag(n, "feature:nodirector");
|
||||
Delete(vtable);
|
||||
Delete(using_protected_members_code);
|
||||
return SWIG_OK;
|
||||
}
|
||||
bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
|
||||
if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
|
||||
if (isNonVirtualProtectedAccess(ni)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue