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:
William S Fulton 2019-03-03 15:12:53 +00:00
commit bc0645ce2b
14 changed files with 128 additions and 20 deletions

View file

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

View file

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

View file

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