@@ -4146,14 +4146,71 @@ impl<'a> GetLeafName<'a> for QualifiedBuiltin {
4146
4146
}
4147
4147
}
4148
4148
4149
+ /// The `<exception-spec>` production.
4150
+ ///
4151
+ /// <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw())
4152
+ /// ::= DO <expression> E # computed (instantiation-dependent) noexcept
4153
+ /// ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types
4154
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
4155
+ pub enum ExceptionSpec {
4156
+ /// noexcept
4157
+ NoExcept ,
4158
+ /// noexcept(expression)
4159
+ Computed ( Expression ) ,
4160
+ // Dynamic exception specification is deprecated, lets see if we can get away with
4161
+ // not implementing it.
4162
+ }
4163
+
4164
+ impl Parse for ExceptionSpec {
4165
+ fn parse < ' a , ' b > (
4166
+ ctx : & ' a ParseContext ,
4167
+ subs : & ' a mut SubstitutionTable ,
4168
+ input : IndexStr < ' b > ,
4169
+ ) -> Result < ( ExceptionSpec , IndexStr < ' b > ) > {
4170
+ try_begin_parse ! ( "ExceptionSpec" , ctx, input) ;
4171
+
4172
+ if let Ok ( tail) = consume ( b"Do" , input) {
4173
+ return Ok ( ( ExceptionSpec :: NoExcept , tail) ) ;
4174
+ }
4175
+
4176
+ let tail = consume ( b"DO" , input) ?;
4177
+ let ( expr, tail) = Expression :: parse ( ctx, subs, tail) ?;
4178
+ let tail = consume ( b"E" , tail) ?;
4179
+ Ok ( ( ExceptionSpec :: Computed ( expr) , tail) )
4180
+ }
4181
+ }
4182
+
4183
+ impl < ' subs , W > Demangle < ' subs , W > for ExceptionSpec
4184
+ where
4185
+ W : ' subs + DemangleWrite ,
4186
+ {
4187
+ fn demangle < ' prev , ' ctx > (
4188
+ & ' subs self ,
4189
+ ctx : & ' ctx mut DemangleContext < ' subs , W > ,
4190
+ scope : Option < ArgScopeStack < ' prev , ' subs > > ,
4191
+ ) -> fmt:: Result {
4192
+ let ctx = try_begin_demangle ! ( self , ctx, scope) ;
4193
+
4194
+ match * self {
4195
+ ExceptionSpec :: NoExcept => write ! ( ctx, "noexcept" ) ,
4196
+ ExceptionSpec :: Computed ( ref expr) => {
4197
+ write ! ( ctx, "noexcept(" ) ?;
4198
+ expr. demangle ( ctx, scope) ?;
4199
+ write ! ( ctx, ")" )
4200
+ }
4201
+ }
4202
+ }
4203
+ }
4204
+
4149
4205
/// The `<function-type>` production.
4150
4206
///
4151
4207
/// ```text
4152
- /// <function-type> ::= [<CV-qualifiers>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
4208
+ /// <function-type> ::= [<CV-qualifiers>] [exception-spec] [ Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
4153
4209
/// ```
4154
4210
#[ derive( Clone , Debug , PartialEq , Eq ) ]
4155
4211
pub struct FunctionType {
4156
4212
cv_qualifiers : CvQualifiers ,
4213
+ exception_spec : Option < ExceptionSpec > ,
4157
4214
transaction_safe : bool ,
4158
4215
extern_c : bool ,
4159
4216
bare : BareFunctionType ,
@@ -4175,6 +4232,13 @@ impl Parse for FunctionType {
4175
4232
( Default :: default ( ) , input)
4176
4233
} ;
4177
4234
4235
+ let ( exception_spec, tail) =
4236
+ if let Ok ( ( exception_spec, tail) ) = ExceptionSpec :: parse ( ctx, subs, tail) {
4237
+ ( Some ( exception_spec) , tail)
4238
+ } else {
4239
+ ( None , tail)
4240
+ } ;
4241
+
4178
4242
let ( transaction_safe, tail) = if let Ok ( tail) = consume ( b"Dx" , tail) {
4179
4243
( true , tail)
4180
4244
} else {
@@ -4202,6 +4266,7 @@ impl Parse for FunctionType {
4202
4266
4203
4267
let func_ty = FunctionType {
4204
4268
cv_qualifiers : cv_qualifiers,
4269
+ exception_spec : exception_spec,
4205
4270
transaction_safe : transaction_safe,
4206
4271
extern_c : extern_c,
4207
4272
bare : bare,
@@ -4227,6 +4292,11 @@ where
4227
4292
if ctx. pop_inner_if ( self ) {
4228
4293
self . demangle_as_inner ( ctx, scope) ?;
4229
4294
}
4295
+ if let Some ( ref es) = self . exception_spec {
4296
+ // Print out a space before printing "noexcept"
4297
+ ctx. ensure_space ( ) ?;
4298
+ es. demangle ( ctx, scope) ?;
4299
+ }
4230
4300
Ok ( ( ) )
4231
4301
}
4232
4302
}
@@ -7792,12 +7862,12 @@ mod tests {
7792
7862
use super :: {
7793
7863
ArrayType , BareFunctionType , BaseUnresolvedName , BuiltinType , CallOffset , ClassEnumType ,
7794
7864
ClosureTypeName , CtorDtorName , CvQualifiers , DataMemberPrefix , Decltype , DestructorName ,
7795
- Discriminator , Encoding , ExprPrimary , Expression , FunctionParam , FunctionType ,
7796
- GlobalCtorDtor , Identifier , Initializer , LambdaSig , LocalName , MangledName , MemberName ,
7797
- Name , NestedName , NonSubstitution , Number , NvOffset , OperatorName , Parse , ParseContext ,
7798
- PointerToMemberType , Prefix , PrefixHandle , RefQualifier , ResourceName , SeqId , SimpleId ,
7799
- SimpleOperatorName , SourceName , SpecialName , StandardBuiltinType , Substitution , TaggedName ,
7800
- TemplateArg , TemplateArgs , TemplateParam , TemplateTemplateParam ,
7865
+ Discriminator , Encoding , ExceptionSpec , ExprPrimary , Expression , FunctionParam ,
7866
+ FunctionType , GlobalCtorDtor , Identifier , Initializer , LambdaSig , LocalName , MangledName ,
7867
+ MemberName , Name , NestedName , NonSubstitution , Number , NvOffset , OperatorName , Parse ,
7868
+ ParseContext , PointerToMemberType , Prefix , PrefixHandle , RefQualifier , ResourceName , SeqId ,
7869
+ SimpleId , SimpleOperatorName , SourceName , SpecialName , StandardBuiltinType , Substitution ,
7870
+ TaggedName , TemplateArg , TemplateArgs , TemplateParam , TemplateTemplateParam ,
7801
7871
TemplateTemplateParamHandle , Type , TypeHandle , UnnamedTypeName , UnqualifiedName ,
7802
7872
UnresolvedName , UnresolvedQualifierLevel , UnresolvedType , UnresolvedTypeHandle ,
7803
7873
UnscopedName , UnscopedTemplateName , UnscopedTemplateNameHandle , VOffset , VectorType ,
@@ -8649,6 +8719,7 @@ mod tests {
8649
8719
volatile: false ,
8650
8720
const_: false ,
8651
8721
} ,
8722
+ exception_spec: None ,
8652
8723
transaction_safe: false ,
8653
8724
extern_c: false ,
8654
8725
bare: BareFunctionType ( vec![ TypeHandle :: BackReference ( 0 ) ] ) ,
@@ -8819,6 +8890,28 @@ mod tests {
8819
8890
} ) ;
8820
8891
}
8821
8892
8893
+ #[ test]
8894
+ fn parse_exception_spec ( ) {
8895
+ assert_parse ! ( ExceptionSpec {
8896
+ Ok => {
8897
+ b"Do..." => {
8898
+ ExceptionSpec :: NoExcept ,
8899
+ b"..."
8900
+ }
8901
+ b"DOtrE..." => {
8902
+ ExceptionSpec :: Computed ( Expression :: Rethrow ) ,
8903
+ b"..."
8904
+ }
8905
+ }
8906
+ Err => {
8907
+ b"DOtre" => Error :: UnexpectedText ,
8908
+ b"DOE" => Error :: UnexpectedText ,
8909
+ b"D" => Error :: UnexpectedEnd ,
8910
+ b"" => Error :: UnexpectedEnd ,
8911
+ }
8912
+ } ) ;
8913
+ }
8914
+
8822
8915
#[ test]
8823
8916
fn parse_function_type ( ) {
8824
8917
assert_parse ! ( FunctionType {
@@ -8835,6 +8928,7 @@ mod tests {
8835
8928
volatile: false ,
8836
8929
const_: true ,
8837
8930
} ,
8931
+ exception_spec: None ,
8838
8932
transaction_safe: true ,
8839
8933
extern_c: true ,
8840
8934
bare: BareFunctionType ( vec![ TypeHandle :: BackReference ( 0 ) ] ) ,
@@ -8850,6 +8944,7 @@ mod tests {
8850
8944
volatile: false ,
8851
8945
const_: false ,
8852
8946
} ,
8947
+ exception_spec: None ,
8853
8948
transaction_safe: true ,
8854
8949
extern_c: true ,
8855
8950
bare: BareFunctionType ( vec![ TypeHandle :: BackReference ( 0 ) ] ) ,
@@ -8865,6 +8960,7 @@ mod tests {
8865
8960
volatile: false ,
8866
8961
const_: false ,
8867
8962
} ,
8963
+ exception_spec: None ,
8868
8964
transaction_safe: false ,
8869
8965
extern_c: true ,
8870
8966
bare: BareFunctionType ( vec![ TypeHandle :: BackReference ( 0 ) ] ) ,
@@ -8880,6 +8976,7 @@ mod tests {
8880
8976
volatile: false ,
8881
8977
const_: false ,
8882
8978
} ,
8979
+ exception_spec: None ,
8883
8980
transaction_safe: false ,
8884
8981
extern_c: false ,
8885
8982
bare: BareFunctionType ( vec![ TypeHandle :: BackReference ( 0 ) ] ) ,
@@ -8895,6 +8992,7 @@ mod tests {
8895
8992
volatile: false ,
8896
8993
const_: false ,
8897
8994
} ,
8995
+ exception_spec: None ,
8898
8996
transaction_safe: false ,
8899
8997
extern_c: false ,
8900
8998
bare: BareFunctionType ( vec![ TypeHandle :: BackReference ( 0 ) ] ) ,
0 commit comments