C++11 ref-qualifier support added
Fixes #1059 Methods with rvalue ref-qualifiers are ignored by default as it is not possible to have an rvalue temporary from the target language (which is needed to call the rvalue ref-qualified method). A warning 405 is shown mentioning the ignored rvalue ref-qualifier method which can be seen with the -Wextra option. cpp_refqualifier.i:15: Warning 405: Method with rvalue ref-qualifier ignored h() const &&. Usually rvalue and lvalue ref-qualifier overloaded methods are written - the lvalue method will then be wrapped.
This commit is contained in:
parent
11d1050803
commit
9e19fe7868
10 changed files with 145 additions and 18 deletions
|
|
@ -561,6 +561,7 @@ CPP11_TEST_CASES += \
|
|||
cpp11_noexcept \
|
||||
cpp11_null_pointer_constant \
|
||||
cpp11_raw_string_literals \
|
||||
cpp11_ref_qualifiers \
|
||||
cpp11_result_of \
|
||||
cpp11_rvalue_reference \
|
||||
cpp11_rvalue_reference2 \
|
||||
|
|
|
|||
16
Examples/test-suite/cpp11_ref_qualifiers.i
Normal file
16
Examples/test-suite/cpp11_ref_qualifiers.i
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
%module cpp11_ref_qualifiers
|
||||
|
||||
%inline %{
|
||||
class Host {
|
||||
public:
|
||||
void h1() & {}
|
||||
void h2() const & {}
|
||||
void h3() && {}
|
||||
void h4() const && {}
|
||||
|
||||
void h() & {}
|
||||
void h() const & {}
|
||||
void h() && {}
|
||||
void h() const && {}
|
||||
};
|
||||
%}
|
||||
18
Examples/test-suite/errors/cpp_refqualifier.i
Normal file
18
Examples/test-suite/errors/cpp_refqualifier.i
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
%module cpp_refqualifier
|
||||
|
||||
%ignore Host::h_ignored;
|
||||
|
||||
class Host {
|
||||
public:
|
||||
void h1() &;
|
||||
void h2() const &;
|
||||
void h3() &&;
|
||||
void h4() const &&;
|
||||
|
||||
void h() &;
|
||||
void h() const &;
|
||||
void h() &&;
|
||||
void h() const &&;
|
||||
|
||||
void h_ignored() &&;
|
||||
};
|
||||
6
Examples/test-suite/errors/cpp_refqualifier.stderr
Normal file
6
Examples/test-suite/errors/cpp_refqualifier.stderr
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
cpp_refqualifier.i:9: Warning 405: Method with rvalue ref-qualifier ignored h3() &&.
|
||||
cpp_refqualifier.i:10: Warning 405: Method with rvalue ref-qualifier ignored h4() const &&.
|
||||
cpp_refqualifier.i:14: Warning 405: Method with rvalue ref-qualifier ignored h() &&.
|
||||
cpp_refqualifier.i:15: Warning 405: Method with rvalue ref-qualifier ignored h() const &&.
|
||||
cpp_refqualifier.i:13: Warning 512: Overloaded method Host::h() const & ignored,
|
||||
cpp_refqualifier.i:12: Warning 512: using non-const method Host::h() & instead.
|
||||
22
Examples/test-suite/java/cpp11_ref_qualifiers_runme.java
Normal file
22
Examples/test-suite/java/cpp11_ref_qualifiers_runme.java
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
import cpp11_ref_qualifiers.*;
|
||||
|
||||
public class cpp11_ref_qualifiers_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("cpp11_ref_qualifiers");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
Host h = new Host();
|
||||
h.h1();
|
||||
h.h2();
|
||||
h.h();
|
||||
}
|
||||
}
|
||||
|
||||
6
Examples/test-suite/python/cpp11_ref_qualifiers_runme.py
Normal file
6
Examples/test-suite/python/cpp11_ref_qualifiers_runme.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import cpp11_ref_qualifiers
|
||||
|
||||
h = cpp11_ref_qualifiers.Host()
|
||||
h.h1()
|
||||
h.h2()
|
||||
h.h()
|
||||
|
|
@ -485,6 +485,16 @@ static void add_symbols(Node *n) {
|
|||
SetFlag(n,"deleted");
|
||||
SetFlag(n,"feature:ignore");
|
||||
}
|
||||
{
|
||||
String *refqualifier = Getattr(n, "refqualifier");
|
||||
if (Equal(refqualifier, "&&") && strncmp(Char(symname), "$ignore", 7) != 0) {
|
||||
SWIG_WARN_NODE_BEGIN(n);
|
||||
Swig_warning(WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED, Getfile(n), Getline(n),
|
||||
"Method with rvalue ref-qualifier ignored %s.\n", Swig_name_decl(n));
|
||||
SWIG_WARN_NODE_END(n);
|
||||
SetFlag(n, "feature:ignore");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (only_csymbol || GetFlag(n,"feature:ignore") || strncmp(Char(symname),"$ignore",7) == 0) {
|
||||
/* Only add to C symbol table and continue */
|
||||
|
|
@ -1451,6 +1461,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
|
|||
String *rawval;
|
||||
int type;
|
||||
String *qualifier;
|
||||
String *refqualifier;
|
||||
String *bitfield;
|
||||
Parm *throws;
|
||||
String *throwf;
|
||||
|
|
@ -1560,7 +1571,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
|
|||
|
||||
/* Misc */
|
||||
%type <id> identifier;
|
||||
%type <dtype> initializer cpp_const exception_specification;
|
||||
%type <dtype> initializer cpp_const exception_specification cv_ref_qualifier;
|
||||
%type <id> storage_class extern_string;
|
||||
%type <pl> parms ptail rawparms varargs_parms ;
|
||||
%type <pl> templateparameters templateparameterstail;
|
||||
|
|
@ -1576,7 +1587,8 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
|
|||
%type <dtype> expr exprnum exprcompound valexpr;
|
||||
%type <id> ename ;
|
||||
%type <id> less_valparms_greater;
|
||||
%type <str> type_qualifier ;
|
||||
%type <str> type_qualifier;
|
||||
%type <str> ref_qualifier;
|
||||
%type <id> type_qualifier_raw;
|
||||
%type <id> idstring idstringopt;
|
||||
%type <id> pragma_lang;
|
||||
|
|
@ -3063,6 +3075,7 @@ c_decl : storage_class type declarator initializer c_decl_tail {
|
|||
$$ = new_node("cdecl");
|
||||
if ($4.qualifier)
|
||||
decl = add_qualifier_to_declarator($3.type, $4.qualifier);
|
||||
Setattr($$,"refqualifier",$4.refqualifier);
|
||||
Setattr($$,"type",$2);
|
||||
Setattr($$,"storage",$1);
|
||||
Setattr($$,"name",$3.id);
|
||||
|
|
@ -3136,6 +3149,7 @@ c_decl : storage_class type declarator initializer c_decl_tail {
|
|||
| storage_class AUTO declarator cpp_const ARROW cpp_alternate_rettype initializer c_decl_tail {
|
||||
$$ = new_node("cdecl");
|
||||
if ($4.qualifier) SwigType_push($3.type, $4.qualifier);
|
||||
Setattr($$,"refqualifier",$4.refqualifier);
|
||||
Setattr($$,"type",$6);
|
||||
Setattr($$,"storage",$1);
|
||||
Setattr($$,"name",$3.id);
|
||||
|
|
@ -3198,6 +3212,7 @@ c_decl_tail : SEMI {
|
|||
| COMMA declarator initializer c_decl_tail {
|
||||
$$ = new_node("cdecl");
|
||||
if ($3.qualifier) SwigType_push($2.type,$3.qualifier);
|
||||
Setattr($$,"refqualifier",$3.refqualifier);
|
||||
Setattr($$,"name",$2.id);
|
||||
Setattr($$,"decl",$2.type);
|
||||
Setattr($$,"parms",$2.parms);
|
||||
|
|
@ -3236,13 +3251,15 @@ c_decl_tail : SEMI {
|
|||
initializer : def_args {
|
||||
$$ = $1;
|
||||
$$.qualifier = 0;
|
||||
$$.refqualifier = 0;
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
}
|
||||
| type_qualifier def_args {
|
||||
| cv_ref_qualifier def_args {
|
||||
$$ = $2;
|
||||
$$.qualifier = $1;
|
||||
$$.qualifier = $1.qualifier;
|
||||
$$.refqualifier = $1.refqualifier;
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
|
|
@ -3250,13 +3267,15 @@ initializer : def_args {
|
|||
| exception_specification def_args {
|
||||
$$ = $2;
|
||||
$$.qualifier = 0;
|
||||
$$.refqualifier = 0;
|
||||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
$$.nexcept = $1.nexcept;
|
||||
}
|
||||
| type_qualifier exception_specification def_args {
|
||||
| cv_ref_qualifier exception_specification def_args {
|
||||
$$ = $3;
|
||||
$$.qualifier = $1;
|
||||
$$.qualifier = $1.qualifier;
|
||||
$$.refqualifier = $1.refqualifier;
|
||||
$$.throws = $2.throws;
|
||||
$$.throwf = $2.throwf;
|
||||
$$.nexcept = $2.nexcept;
|
||||
|
|
@ -4809,6 +4828,7 @@ cpp_vend : cpp_const SEMI {
|
|||
Clear(scanner_ccode);
|
||||
$$.val = 0;
|
||||
$$.qualifier = $1.qualifier;
|
||||
$$.refqualifier = 0;
|
||||
$$.bitfield = 0;
|
||||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
|
|
@ -4818,6 +4838,7 @@ cpp_vend : cpp_const SEMI {
|
|||
Clear(scanner_ccode);
|
||||
$$.val = $3.val;
|
||||
$$.qualifier = $1.qualifier;
|
||||
$$.refqualifier = 0;
|
||||
$$.bitfield = 0;
|
||||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
|
|
@ -4827,6 +4848,7 @@ cpp_vend : cpp_const SEMI {
|
|||
skip_balanced('{','}');
|
||||
$$.val = 0;
|
||||
$$.qualifier = $1.qualifier;
|
||||
$$.refqualifier = 0;
|
||||
$$.bitfield = 0;
|
||||
$$.throws = $1.throws;
|
||||
$$.throwf = $1.throwf;
|
||||
|
|
@ -5828,6 +5850,29 @@ pointer : STAR type_qualifier pointer {
|
|||
}
|
||||
;
|
||||
|
||||
/* cv-qualifier plus C++11 ref-qualifier for non-static member functions */
|
||||
cv_ref_qualifier : type_qualifier {
|
||||
$$.qualifier = $1;
|
||||
$$.refqualifier = 0;
|
||||
}
|
||||
| type_qualifier ref_qualifier {
|
||||
$$.qualifier = $1;
|
||||
$$.refqualifier = $2;
|
||||
}
|
||||
| ref_qualifier {
|
||||
$$.qualifier = 0;
|
||||
$$.refqualifier = $1;
|
||||
}
|
||||
;
|
||||
|
||||
ref_qualifier : AND {
|
||||
$$ = NewString("&");
|
||||
}
|
||||
| LAND {
|
||||
$$ = NewString("&&");
|
||||
}
|
||||
;
|
||||
|
||||
type_qualifier : type_qualifier_raw {
|
||||
$$ = NewStringEmpty();
|
||||
if ($1) SwigType_add_qualifier($$,$1);
|
||||
|
|
@ -6049,6 +6094,7 @@ definetype : { /* scanner_check_typedef(); */ } expr {
|
|||
$$.rawval = NewStringf("%s", $$.val);
|
||||
}
|
||||
$$.qualifier = 0;
|
||||
$$.refqualifier = 0;
|
||||
$$.bitfield = 0;
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
|
|
@ -6074,6 +6120,7 @@ deleted_definition : DELETE_KW {
|
|||
$$.rawval = 0;
|
||||
$$.type = T_STRING;
|
||||
$$.qualifier = 0;
|
||||
$$.refqualifier = 0;
|
||||
$$.bitfield = 0;
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
|
|
@ -6087,6 +6134,7 @@ explicit_default : DEFAULT {
|
|||
$$.rawval = 0;
|
||||
$$.type = T_STRING;
|
||||
$$.qualifier = 0;
|
||||
$$.refqualifier = 0;
|
||||
$$.bitfield = 0;
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
|
|
@ -6616,25 +6664,29 @@ exception_specification : THROW LPAREN parms RPAREN {
|
|||
}
|
||||
;
|
||||
|
||||
cpp_const : type_qualifier {
|
||||
cpp_const : cv_ref_qualifier {
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.qualifier = $1;
|
||||
$$.qualifier = $1.qualifier;
|
||||
$$.refqualifier = $1.refqualifier;
|
||||
}
|
||||
| exception_specification {
|
||||
$$ = $1;
|
||||
$$.qualifier = 0;
|
||||
$$.refqualifier = 0;
|
||||
}
|
||||
| type_qualifier exception_specification {
|
||||
| cv_ref_qualifier exception_specification {
|
||||
$$ = $2;
|
||||
$$.qualifier = $1;
|
||||
$$.qualifier = $1.qualifier;
|
||||
$$.refqualifier = $1.refqualifier;
|
||||
}
|
||||
| empty {
|
||||
$$.throws = 0;
|
||||
$$.throwf = 0;
|
||||
$$.nexcept = 0;
|
||||
$$.qualifier = 0;
|
||||
$$.qualifier = 0;
|
||||
$$.refqualifier = 0;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@
|
|||
#define WARN_TYPE_INCOMPLETE 402
|
||||
#define WARN_TYPE_ABSTRACT 403
|
||||
#define WARN_TYPE_REDEFINED 404
|
||||
#define WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
|
||||
|
||||
#define WARN_TYPEMAP_SOURCETARGET 450
|
||||
#define WARN_TYPEMAP_CHARLEAK 451
|
||||
|
|
|
|||
|
|
@ -38,14 +38,15 @@ int NoExcept = 0;
|
|||
int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
|
||||
|
||||
/* Suppress warning messages for private inheritance, preprocessor evaluation etc...
|
||||
WARN_PP_EVALUATION 202
|
||||
WARN_PARSE_PRIVATE_INHERIT 309
|
||||
WARN_TYPE_ABSTRACT 403
|
||||
WARN_LANG_OVERLOAD_CONST 512
|
||||
WARN_PARSE_BUILTIN_NAME 321
|
||||
WARN_PARSE_REDUNDANT 322
|
||||
WARN_PP_EVALUATION 202
|
||||
WARN_PARSE_PRIVATE_INHERIT 309
|
||||
WARN_PARSE_BUILTIN_NAME 321
|
||||
WARN_PARSE_REDUNDANT 322
|
||||
WARN_TYPE_ABSTRACT 403
|
||||
WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
|
||||
WARN_LANG_OVERLOAD_CONST 512
|
||||
*/
|
||||
#define EXTRA_WARNINGS "202,309,403,512,321,322"
|
||||
#define EXTRA_WARNINGS "202,309,403,405,512,321,322"
|
||||
|
||||
extern "C" {
|
||||
extern String *ModuleName;
|
||||
|
|
|
|||
|
|
@ -1681,6 +1681,7 @@ String *Swig_name_str(Node *n) {
|
|||
* "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
|
||||
* "MyNameSpace::ABC::ABC(int,double)"
|
||||
* "MyNameSpace::ABC::constmethod(int) const"
|
||||
* "MyNameSpace::ABC::refqualifiermethod(int) const &"
|
||||
* "MyNameSpace::ABC::variablename"
|
||||
*
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -1688,6 +1689,7 @@ String *Swig_name_str(Node *n) {
|
|||
String *Swig_name_decl(Node *n) {
|
||||
String *qname;
|
||||
String *decl;
|
||||
String *refqualifier = Getattr(n, "refqualifier");
|
||||
|
||||
qname = Swig_name_str(n);
|
||||
|
||||
|
|
@ -1695,6 +1697,8 @@ String *Swig_name_decl(Node *n) {
|
|||
decl = NewStringf("%s", qname);
|
||||
else
|
||||
decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : "");
|
||||
if (refqualifier)
|
||||
Printv(decl, " ", refqualifier, NIL);
|
||||
|
||||
Delete(qname);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue