Add support for C++11 noexcept specification in exception specifications

This commit is contained in:
William S Fulton 2013-11-21 19:31:59 +00:00
commit f4ada30a7e
5 changed files with 151 additions and 27 deletions

View file

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

View file

@ -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 \

View file

@ -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;
};
%}

View file

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

View file

@ -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
;
cpp_const : type_qualifier {
$$.qualifier = $1;
$$.throws = 0;
$$.throwf = 0;
}
| THROW LPAREN parms RPAREN {
$$.qualifier = 0;
exception_specification : THROW LPAREN parms RPAREN {
$$.throws = $3;
$$.throwf = NewString("1");
}
| type_qualifier THROW LPAREN parms RPAREN {
$$.qualifier = $1;
$$.throws = $4;
$$.throwf = NewString("1");
}
| empty {
$$.qualifier = 0;
$$.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 {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.qualifier = $1;
}
| exception_specification {
$$ = $1;
$$.qualifier = 0;
}
| type_qualifier exception_specification {
$$ = $2;
$$.qualifier = $1;
}
| empty {
$$.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;
}
;