diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index b47b6e33b..0d0a32c8c 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -562,6 +562,7 @@ CPP11_TEST_CASES += \ cpp11_null_pointer_constant \ cpp11_raw_string_literals \ cpp11_ref_qualifiers \ + cpp11_ref_qualifiers_rvalue_unignore \ cpp11_result_of \ cpp11_rvalue_reference \ cpp11_rvalue_reference2 \ diff --git a/Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i b/Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i new file mode 100644 index 000000000..2f5fadfc6 --- /dev/null +++ b/Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i @@ -0,0 +1,15 @@ +%module cpp11_ref_qualifiers_rvalue_unignore + +// This is a minimal test that does not include any C++ headers to make sure the required +// header is generated from a fragment for the generated std::move call + +// m1 and m2 are ignored by default, unignore them +%feature("ignore", "0") RefQualifier::m1() &&; +%feature("ignore", "0") RefQualifier::m2() const &&; + +%inline %{ +struct RefQualifier { + void m1() && {} + void m2() const && {} +}; +%} diff --git a/Examples/test-suite/errors/cpp_refqualifier.i b/Examples/test-suite/errors/cpp_refqualifier.i index 438aacd93..afd6632fc 100644 --- a/Examples/test-suite/errors/cpp_refqualifier.i +++ b/Examples/test-suite/errors/cpp_refqualifier.i @@ -18,5 +18,11 @@ public: void h_ignored() &&; void i_ignored() &&; - void j_ignored() const &&; + void i_ignored() &&; +}; + +%feature("ignore", "0") Unignore::k_unignored() const &&; + +struct Unignore { + void k_unignored() const &&; }; diff --git a/Examples/test-suite/java/cpp11_ref_qualifiers_rvalue_unignore_runme.java b/Examples/test-suite/java/cpp11_ref_qualifiers_rvalue_unignore_runme.java new file mode 100644 index 000000000..bbbe6f788 --- /dev/null +++ b/Examples/test-suite/java/cpp11_ref_qualifiers_rvalue_unignore_runme.java @@ -0,0 +1,20 @@ + +import cpp11_ref_qualifiers_rvalue_unignore.*; + +public class cpp11_ref_qualifiers_rvalue_unignore_runme { + + static { + try { + System.loadLibrary("cpp11_ref_qualifiers_rvalue_unignore"); + } 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[]) { + new RefQualifier().m1(); + new RefQualifier().m2(); + } +} + diff --git a/Examples/test-suite/python/cpp11_ref_qualifiers_rvalue_unignore_runme.py b/Examples/test-suite/python/cpp11_ref_qualifiers_rvalue_unignore_runme.py new file mode 100644 index 000000000..6352c79c2 --- /dev/null +++ b/Examples/test-suite/python/cpp11_ref_qualifiers_rvalue_unignore_runme.py @@ -0,0 +1,4 @@ +import cpp11_ref_qualifiers_rvalue_unignore + +cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m1() +cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m2() diff --git a/Lib/swig.swg b/Lib/swig.swg index 6f48f0d20..6dc215dcf 100644 --- a/Lib/swig.swg +++ b/Lib/swig.swg @@ -309,11 +309,13 @@ static int NAME(TYPE x) { %define %$classname %$ismember,"match$parentNode$name" %enddef %define %$isnested "match$nested"="1" %enddef + /* ----------------------------------------------------------------------------- - * Include all the warnings labels and macros + * Common includes for warning labels, macros, fragments etc * ----------------------------------------------------------------------------- */ %include +%include /* ----------------------------------------------------------------------------- * Overloading support diff --git a/Lib/swigfragments.swg b/Lib/swigfragments.swg new file mode 100644 index 000000000..63bb6c8f4 --- /dev/null +++ b/Lib/swigfragments.swg @@ -0,0 +1,86 @@ +/* ----------------------------------------------------------------------------- + * swigfragments.swg + * + * Common fragments + * ----------------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------------- + * Fragments for C header files + * ----------------------------------------------------------------------------- */ + +%fragment("", "header") %{ +#include +%} + +/* Default compiler options for gcc allow long_long but not LLONG_MAX. + * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */ +%fragment("", "header") %{ +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif +%} + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# ifndef snprintf +# define snprintf _snprintf +# endif +#endif +%} + +%fragment("", "header") %{ +#include +#ifdef _MSC_VER +# ifndef strtoull +# define strtoull _strtoui64 +# endif +# ifndef strtoll +# define strtoll _strtoi64 +# endif +#endif +%} + +%fragment("", "header") %{ +#include +#include +#ifndef WCHAR_MIN +# define WCHAR_MIN 0 +#endif +#ifndef WCHAR_MAX +# define WCHAR_MAX 65535 +#endif +%} + +/* ----------------------------------------------------------------------------- + * Fragments for C++ header files + * ----------------------------------------------------------------------------- */ + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +%} diff --git a/Lib/typemaps/fragments.swg b/Lib/typemaps/fragments.swg index 3f33ca98d..aaf948c05 100644 --- a/Lib/typemaps/fragments.swg +++ b/Lib/typemaps/fragments.swg @@ -96,75 +96,6 @@ * common fragments * ------------------------------------------------------------ */ -/* Default compiler options for gcc allow long_long but not LLONG_MAX. - * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */ -%fragment("","header") %{ -#include -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif -%} - -%fragment("","header") %{ -#include -%} - -%fragment("","header") %{ -#include -#include -#ifndef WCHAR_MIN -# define WCHAR_MIN 0 -#endif -#ifndef WCHAR_MAX -# define WCHAR_MAX 65535 -#endif -%} - -%fragment("","header") %{ -#include -%} - -%fragment("","header") %{ -#include -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# ifndef snprintf -# define snprintf _snprintf -# endif -#endif -%} - -%fragment("","header") %{ -#include -#ifdef _MSC_VER -# ifndef strtoull -# define strtoull _strtoui64 -# endif -# ifndef strtoll -# define strtoll _strtoi64 -# endif -#endif -%} - -%fragment("", "header") %{ -#include -%} - -%fragment("", "header") %{ -#include -%} - -%fragment("", "header") %{ -#include -%} - -%fragment("", "header") %{ -#include -%} - %fragment("SWIG_isfinite","header",fragment=",") %{ /* Getting isfinite working pre C99 across multiple platforms is non-trivial. Users can provide SWIG_isfinite on older platforms. */ #ifndef SWIG_isfinite diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index ccb09e3eb..3e0fd3282 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -485,9 +485,10 @@ static void add_symbols(Node *n) { SetFlag(n,"deleted"); SetFlag(n,"feature:ignore"); } - { - String *refqualifier = Getattr(n, "refqualifier"); - if (SwigType_isrvalue_reference(refqualifier) && Strcmp(symname, "$ignore") != 0) { + if (SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) { + /* Ignore rvalue ref-qualifiers by default + * Use Getattr instead of GetFlag to handle explicit ignore and explicit not ignore */ + if (!(Getattr(n, "feature:ignore") || Strncmp(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 %s ignored.\n", Swig_name_decl(n)); diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 4c3135e3a..d6e5e0cdc 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -1024,6 +1024,15 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas } } + if (!self && SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) { + String *memory_header = NewString(""); + Setfile(memory_header, Getfile(n)); + Setline(memory_header, Getline(n)); + Swig_fragment_emit(memory_header); + self = NewString("std::move(*this)."); + Delete(memory_header); + } + call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type); cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call);