aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doc/Manual/CPlusPlus11.html23
-rw-r--r--Examples/test-suite/common.mk1
-rw-r--r--Examples/test-suite/cpp11_noexcept.i48
-rw-r--r--Source/CParse/cscanner.c2
-rw-r--r--Source/CParse/parser.y90
5 files changed, 144 insertions, 20 deletions
diff --git a/Doc/Manual/CPlusPlus11.html b/Doc/Manual/CPlusPlus11.html
index 30b88d6fa..0d2f22aff 100644
--- a/Doc/Manual/CPlusPlus11.html
+++ b/Doc/Manual/CPlusPlus11.html
@@ -37,6 +37,7 @@
<li><a href="#CPlusPlus11_type_long_long_int">Type long long int</a>
<li><a href="#CPlusPlus11_static_assertions">Static assertions</a>
<li><a href="#CPlusPlus11_allow_sizeof_to_work_on_members_of_classes_without_an_explicit_object">Allow sizeof to work on members of classes without an explicit object</a>
+<li><a href="#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
</ul>
<li><a href="#CPlusPlus11_standard_library_changes">Standard library changes</a>
<ul>
@@ -583,7 +584,7 @@ struct point {
int x_, y_;
};
-#include <new> // For placement 'new' in the constructor below
+#include &lt;new&gt; // For placement 'new' in the constructor below
union P {
int z;
double w;
@@ -800,6 +801,23 @@ const int SIZE = sizeof(A::member); // does not work with C++03. Okay with C++11
8
</pre></div>
+<H3><a name="CPlusPlus11_noexcept"></a>7.2.25 Exception specifications and noexcept</H3>
+
+
+<p>
+C++11 added in the noexcept specification to exception specifications to indicate that a function simply may or may not throw an exception, without actually naming any exception.
+SWIG understands these, although there isn't any useful way that this information can be taken advantage of by target languages,
+so it is as good as ignored during the wrapping process.
+Below are some examples of noexcept in function declarations:
+</p>
+
+<div class="code"><pre>
+static void noex1() noexcept;
+int noex2(int) noexcept(true);
+int noex3(int, bool) noexcept(false);
+</pre></div>
+
+
<H2><a name="CPlusPlus11_standard_library_changes"></a>7.3 Standard library changes</H2>
@@ -885,7 +903,7 @@ Example of supported usage of the plain functor from Python is shown below.
It does not involve <tt>std::function</tt>.
</p>
-<div class="targetlang">
+<div class="targetlang"><pre>
t = Test()
b = t(1,2) # invoke C++ function object
</pre></div>
@@ -944,5 +962,6 @@ typename std::result_of&lt;Fun(Arg)&gt;::type test_result_impl(Fun fun, Arg arg)
</pre></div>
<p>Instead, please use <tt>decltype()</tt> where possible for now.</p>
+
</body>
</html>
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 0d360830d..e5127fd0c 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -491,6 +491,7 @@ CPP11_TEST_CASES = \
cpp11_initializer_list \
cpp11_initializer_list_extend \
cpp11_lambda_functions \
+ cpp11_noexcept \
cpp11_null_pointer_constant \
cpp11_raw_string_literals \
cpp11_rvalue_reference \
diff --git a/Examples/test-suite/cpp11_noexcept.i b/Examples/test-suite/cpp11_noexcept.i
new file mode 100644
index 000000000..27476fa70
--- /dev/null
+++ b/Examples/test-suite/cpp11_noexcept.i
@@ -0,0 +1,48 @@
+%module cpp11_noexcept
+
+%ignore NoExceptClass(NoExceptClass&&);
+%rename(Assignment) NoExceptClass::operator=;
+
+%inline %{
+
+extern "C" void global_noexcept(int, bool) noexcept;
+
+struct NoExceptClass {
+ static const bool VeryTrue = true;
+
+ NoExceptClass() noexcept {}
+ NoExceptClass(const NoExceptClass&) noexcept {}
+ NoExceptClass(NoExceptClass&&) noexcept {}
+ NoExceptClass& operator=(const NoExceptClass&) noexcept {}
+ ~NoExceptClass() noexcept {}
+
+ void noex0() noexcept {}
+ void noex1() noexcept(sizeof(int) == 4) {}
+ void noex2() noexcept(true) {}
+ void noex3() noexcept(false) {}
+ void noex4() noexcept(VeryTrue) {}
+
+ template<typename T> void template_noexcept(T) noexcept {}
+
+ void noo1() const noexcept {}
+ static void noo2() noexcept {}
+ virtual void noo3() const noexcept {}
+ virtual void noo4() const noexcept = delete;
+ virtual void noo5() const throw() = delete;
+};
+
+struct NoExceptAbstract {
+ virtual void noo4() const noexcept = 0;
+ virtual ~NoExceptAbstract() noexcept = 0;
+};
+
+struct NoExceptDefaultDelete {
+// NoExceptDefaultDelete() noexcept = default;
+// NoExceptDefaultDelete(const NoExceptDefaultDelete&) noexcept = delete;
+ NoExceptDefaultDelete(NoExceptDefaultDelete&&) = delete;
+ NoExceptDefaultDelete& operator=(const NoExceptDefaultDelete&) = delete;
+ ~NoExceptDefaultDelete() noexcept = default;
+};
+
+%}
+
diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c
index 8b484f8a7..c04ce4688 100644
--- a/Source/CParse/cscanner.c
+++ b/Source/CParse/cscanner.c
@@ -705,6 +705,8 @@ int yylex(void) {
}
if (strcmp(yytext, "throw") == 0)
return (THROW);
+ if (strcmp(yytext, "noexcept") == 0)
+ return (NOEXCEPT);
if (strcmp(yytext, "try") == 0)
return (yylex());
if (strcmp(yytext, "catch") == 0)
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 1328d6e0d..bb1b5c1cc 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -1669,6 +1669,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
String *bitfield;
Parm *throws;
String *throwf;
+ String *nexcept;
} dtype;
struct {
char *type;
@@ -1683,6 +1684,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
short have_parms;
ParmList *throws;
String *throwf;
+ String *nexcept;
} decl;
Parm *tparms;
struct {
@@ -1716,7 +1718,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
%token ILLEGAL CONSTANT
%token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS
%token ENUM
-%token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT AUTO
+%token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT AUTO NOEXCEPT
%token STATIC_ASSERT CONSTEXPR THREAD_LOCAL DECLTYPE /* C++11 keywords */
%token USING
%token <node> NAMESPACE
@@ -1771,7 +1773,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
%type <node> kwargs options;
/* Misc */
-%type <dtype> initializer cpp_const ;
+%type <dtype> initializer cpp_const exception_specification;
%type <id> storage_class;
%type <pl> parms ptail rawparms varargs_parms ;
%type <pl> templateparameters templateparameterstail;
@@ -3234,6 +3236,7 @@ c_decl : storage_class type declarator initializer c_decl_tail {
Setattr($$,"value",$4.val);
Setattr($$,"throws",$4.throws);
Setattr($$,"throw",$4.throwf);
+ Setattr($$,"noexcept",$4.nexcept);
if (!$5) {
if (Len(scanner_ccode)) {
String *code = Copy(scanner_ccode);
@@ -3293,6 +3296,7 @@ c_decl : storage_class type declarator initializer c_decl_tail {
Setattr($$,"value",$6.val);
Setattr($$,"throws",$6.throws);
Setattr($$,"throw",$6.throwf);
+ Setattr($$,"noexcept",$6.nexcept);
if (!$7) {
if (Len(scanner_ccode)) {
String *code = Copy(scanner_ccode);
@@ -3352,6 +3356,7 @@ c_decl_tail : SEMI {
Setattr($$,"value",$3.val);
Setattr($$,"throws",$3.throws);
Setattr($$,"throw",$3.throwf);
+ Setattr($$,"noexcept",$3.nexcept);
if ($3.bitfield) {
Setattr($$,"bitfield", $3.bitfield);
}
@@ -3376,24 +3381,28 @@ initializer : def_args {
$$.qualifier = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
| type_qualifier def_args {
$$ = $2;
$$.qualifier = $1;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
- | THROW LPAREN parms RPAREN def_args {
- $$ = $5;
+ | exception_specification def_args {
+ $$ = $2;
$$.qualifier = 0;
- $$.throws = $3;
- $$.throwf = NewString("1");
+ $$.throws = $1.throws;
+ $$.throwf = $1.throwf;
+ $$.nexcept = $1.nexcept;
}
- | type_qualifier THROW LPAREN parms RPAREN def_args {
- $$ = $6;
+ | type_qualifier exception_specification def_args {
+ $$ = $3;
$$.qualifier = $1;
- $$.throws = $4;
- $$.throwf = NewString("1");
+ $$.throws = $2.throws;
+ $$.throwf = $2.throwf;
+ $$.nexcept = $2.nexcept;
}
;
@@ -3669,6 +3678,7 @@ c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
}
Setattr($$,"throws",$6.throws);
Setattr($$,"throw",$6.throwf);
+ Setattr($$,"noexcept",$6.nexcept);
err = 0;
}
}
@@ -4698,6 +4708,7 @@ cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
Setattr($$,"decl",decl);
Setattr($$,"throws",$6.throws);
Setattr($$,"throw",$6.throwf);
+ Setattr($$,"noexcept",$6.nexcept);
if (Len(scanner_ccode)) {
String *code = Copy(scanner_ccode);
Setattr($$,"code",code);
@@ -4733,6 +4744,7 @@ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
}
Setattr($$,"throws",$6.throws);
Setattr($$,"throw",$6.throwf);
+ Setattr($$,"noexcept",$6.nexcept);
if ($6.val)
Setattr($$,"value",$6.val);
add_symbols($$);
@@ -4750,6 +4762,7 @@ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
Delete(name);
Setattr($$,"throws",$7.throws);
Setattr($$,"throw",$7.throwf);
+ Setattr($$,"noexcept",$7.nexcept);
if ($7.val)
Setattr($$,"value",$7.val);
if (Len(scanner_ccode)) {
@@ -4996,18 +5009,21 @@ cpp_end : cpp_const SEMI {
$$.val = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
+ $$.nexcept = $1.nexcept;
}
| cpp_const EQUAL default_delete SEMI {
Clear(scanner_ccode);
$$.val = $3.val;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
+ $$.nexcept = $1.nexcept;
}
| cpp_const LBRACE {
skip_balanced('{','}');
$$.val = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
+ $$.nexcept = $1.nexcept;
}
;
@@ -5018,6 +5034,7 @@ cpp_vend : cpp_const SEMI {
$$.bitfield = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
+ $$.nexcept = $1.nexcept;
}
| cpp_const EQUAL definetype SEMI {
Clear(scanner_ccode);
@@ -5026,6 +5043,7 @@ cpp_vend : cpp_const SEMI {
$$.bitfield = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
+ $$.nexcept = $1.nexcept;
}
| cpp_const LBRACE {
skip_balanced('{','}');
@@ -5034,6 +5052,7 @@ cpp_vend : cpp_const SEMI {
$$.bitfield = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
+ $$.nexcept = $1.nexcept;
}
;
@@ -5085,6 +5104,7 @@ storage_class : EXTERN { $$ = "extern"; }
| FRIEND { $$ = "friend"; }
| EXPLICIT { $$ = "explicit"; }
| CONSTEXPR { $$ = "constexpr"; }
+ | STATIC CONSTEXPR { $$ = "static constexpr"; }
| THREAD_LOCAL { $$ = "thread_local"; }
| THREAD_LOCAL STATIC { $$ = "static thread_local"; }
| STATIC THREAD_LOCAL { $$ = "static thread_local"; }
@@ -5222,6 +5242,7 @@ def_args : EQUAL definetype {
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
}
| EQUAL definetype LBRACKET expr RBRACKET {
@@ -5234,6 +5255,7 @@ def_args : EQUAL definetype {
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
} else {
$$.val = NewStringf("%s[%s]",$2.val,$4.val);
}
@@ -5246,6 +5268,7 @@ def_args : EQUAL definetype {
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
| COLON expr {
$$.val = 0;
@@ -5254,6 +5277,7 @@ def_args : EQUAL definetype {
$$.bitfield = $2.val;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
| empty {
$$.val = 0;
@@ -5262,6 +5286,7 @@ def_args : EQUAL definetype {
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
;
@@ -6166,6 +6191,7 @@ definetype : { /* scanner_check_typedef(); */ } expr {
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
scanner_ignore_typedef();
}
| default_delete {
@@ -6179,6 +6205,7 @@ definetype : { /* scanner_check_typedef(); */ } expr {
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
*/
;
@@ -6200,6 +6227,7 @@ deleted_definition : DELETE_KW {
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
;
@@ -6212,6 +6240,7 @@ explicit_default : DEFAULT {
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
;
@@ -6331,6 +6360,7 @@ valexpr : exprnum { $$ = $1; }
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
| WCHARCONST {
$$.val = NewString($1);
@@ -6343,6 +6373,7 @@ valexpr : exprnum { $$ = $1; }
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
/* grouping */
@@ -6668,25 +6699,43 @@ opt_virtual : VIRTUAL
| empty
;
+exception_specification : THROW LPAREN parms RPAREN {
+ $$.throws = $3;
+ $$.throwf = NewString("1");
+ $$.nexcept = 0;
+ }
+ | NOEXCEPT {
+ $$.throws = 0;
+ $$.throwf = 0;
+ $$.nexcept = NewString("true");
+ }
+
+ | NOEXCEPT LPAREN expr RPAREN {
+ $$.throws = 0;
+ $$.throwf = 0;
+ $$.nexcept = $3.val;
+ }
+ ;
+
cpp_const : type_qualifier {
- $$.qualifier = $1;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
+ $$.qualifier = $1;
}
- | THROW LPAREN parms RPAREN {
+ | exception_specification {
+ $$ = $1;
$$.qualifier = 0;
- $$.throws = $3;
- $$.throwf = NewString("1");
}
- | type_qualifier THROW LPAREN parms RPAREN {
+ | type_qualifier exception_specification {
+ $$ = $2;
$$.qualifier = $1;
- $$.throws = $4;
- $$.throwf = NewString("1");
}
| empty {
- $$.qualifier = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
+ $$.qualifier = 0;
}
;
@@ -6696,6 +6745,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.defarg = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
+ $$.nexcept = $1.nexcept;
}
| cpp_const ctor_initializer LBRACE {
skip_balanced('{','}');
@@ -6703,6 +6753,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.defarg = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
+ $$.nexcept = $1.nexcept;
}
| LPAREN parms RPAREN SEMI {
Clear(scanner_ccode);
@@ -6711,6 +6762,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.defarg = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
| LPAREN parms RPAREN LBRACE {
skip_balanced('{','}');
@@ -6719,12 +6771,14 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.defarg = 0;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
| EQUAL definetype SEMI {
$$.have_parms = 0;
$$.defarg = $2.val;
$$.throws = 0;
$$.throwf = 0;
+ $$.nexcept = 0;
}
;