@@ -5427,6 +5427,7 @@ where
5427
5427
/// ::= at <type> # alignof (type)
5428
5428
/// ::= az <expression> # alignof (expression)
5429
5429
/// ::= nx <expression> # noexcept (expression)
5430
+ /// ::= so <subobject-expr>
5430
5431
/// ::= <template-param>
5431
5432
/// ::= <function-param>
5432
5433
/// ::= dt <expression> <unresolved-name> # expr.name
@@ -5537,6 +5538,9 @@ pub enum Expression {
5537
5538
/// `noexcept (expression)`
5538
5539
Noexcept ( Box < Expression > ) ,
5539
5540
5541
+ /// Subobject expression,
5542
+ Subobject ( SubobjectExpr ) ,
5543
+
5540
5544
/// A named template parameter.
5541
5545
TemplateParam ( TemplateParam ) ,
5542
5546
@@ -5693,6 +5697,11 @@ impl Parse for Expression {
5693
5697
let expr = Expression :: Noexcept ( Box :: new ( expr) ) ;
5694
5698
return Ok ( ( expr, tail) ) ;
5695
5699
}
5700
+ b"so" => {
5701
+ let ( expr, tail) = SubobjectExpr :: parse ( ctx, subs, tail) ?;
5702
+ let expr = Expression :: Subobject ( expr) ;
5703
+ return Ok ( ( expr, tail) ) ;
5704
+ }
5696
5705
b"dt" => {
5697
5706
let ( expr, tail) = Expression :: parse ( ctx, subs, tail) ?;
5698
5707
let ( name, tail) = MemberName :: parse ( ctx, subs, tail) ?;
@@ -6152,6 +6161,7 @@ where
6152
6161
write ! ( ctx, ")" ) ?;
6153
6162
Ok ( ( ) )
6154
6163
}
6164
+ Expression :: Subobject ( ref expr) => expr. demangle ( ctx, scope) ,
6155
6165
Expression :: TemplateParam ( ref param) => param. demangle ( ctx, scope) ,
6156
6166
Expression :: FunctionParam ( ref param) => param. demangle ( ctx, scope) ,
6157
6167
Expression :: Member ( ref expr, ref name) => {
@@ -7751,6 +7761,65 @@ where
7751
7761
Ok ( ( ) )
7752
7762
}
7753
7763
}
7764
+
7765
+ /// The subobject expression production.
7766
+ ///
7767
+ /// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
7768
+ /// <union-selector> ::= _ [<number>]
7769
+ ///
7770
+ /// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
7771
+ /// But it has been shipping in clang for some time.
7772
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
7773
+ pub struct SubobjectExpr {
7774
+ ty : TypeHandle ,
7775
+ expr : Box < Expression > ,
7776
+ offset : isize ,
7777
+ }
7778
+
7779
+ impl Parse for SubobjectExpr {
7780
+ fn parse < ' a , ' b > (
7781
+ ctx : & ' a ParseContext ,
7782
+ subs : & ' a mut SubstitutionTable ,
7783
+ input : IndexStr < ' b > ,
7784
+ ) -> Result < ( SubobjectExpr , IndexStr < ' b > ) > {
7785
+ try_begin_parse ! ( "SubobjectExpr" , ctx, input) ;
7786
+
7787
+ let ( ty, tail) = TypeHandle :: parse ( ctx, subs, input) ?;
7788
+ let ( expr, tail) = Expression :: parse ( ctx, subs, tail) ?;
7789
+ let ( offset, tail) = parse_number ( 10 , true , tail) . unwrap_or ( ( 0 , tail) ) ;
7790
+
7791
+ // XXXkhuey handle union-selector and [p]
7792
+ let tail = consume ( b"E" , tail) ?;
7793
+ Ok ( (
7794
+ SubobjectExpr {
7795
+ ty : ty,
7796
+ expr : Box :: new ( expr) ,
7797
+ offset : offset,
7798
+ } ,
7799
+ tail,
7800
+ ) )
7801
+ }
7802
+ }
7803
+
7804
+ impl < ' subs , W > Demangle < ' subs , W > for SubobjectExpr
7805
+ where
7806
+ W : ' subs + DemangleWrite ,
7807
+ {
7808
+ #[ inline]
7809
+ fn demangle < ' prev , ' ctx > (
7810
+ & ' subs self ,
7811
+ ctx : & ' ctx mut DemangleContext < ' subs , W > ,
7812
+ scope : Option < ArgScopeStack < ' prev , ' subs > > ,
7813
+ ) -> fmt:: Result {
7814
+ let ctx = try_begin_demangle ! ( self , ctx, scope) ;
7815
+
7816
+ self . expr . demangle ( ctx, scope) ?;
7817
+ write ! ( ctx, ".<" ) ?;
7818
+ self . ty . demangle ( ctx, scope) ?;
7819
+ write ! ( ctx, " at offset {}>" , self . offset)
7820
+ }
7821
+ }
7822
+
7754
7823
/// Expect and consume the given byte str, and return the advanced `IndexStr` if
7755
7824
/// we saw the expectation. Otherwise return an error of kind
7756
7825
/// `error::Error::UnexpectedText` if the input doesn't match, or
@@ -7866,8 +7935,8 @@ mod tests {
7866
7935
FunctionType , GlobalCtorDtor , Identifier , Initializer , LambdaSig , LocalName , MangledName ,
7867
7936
MemberName , Name , NestedName , NonSubstitution , Number , NvOffset , OperatorName , Parse ,
7868
7937
ParseContext , PointerToMemberType , Prefix , PrefixHandle , RefQualifier , ResourceName , SeqId ,
7869
- SimpleId , SimpleOperatorName , SourceName , SpecialName , StandardBuiltinType , Substitution ,
7870
- TaggedName , TemplateArg , TemplateArgs , TemplateParam , TemplateTemplateParam ,
7938
+ SimpleId , SimpleOperatorName , SourceName , SpecialName , StandardBuiltinType , SubobjectExpr ,
7939
+ Substitution , TaggedName , TemplateArg , TemplateArgs , TemplateParam , TemplateTemplateParam ,
7871
7940
TemplateTemplateParamHandle , Type , TypeHandle , UnnamedTypeName , UnqualifiedName ,
7872
7941
UnresolvedName , UnresolvedQualifierLevel , UnresolvedType , UnresolvedTypeHandle ,
7873
7942
UnscopedName , UnscopedTemplateName , UnscopedTemplateNameHandle , VOffset , VectorType ,
@@ -11370,4 +11439,69 @@ mod tests {
11370
11439
}
11371
11440
} ) ;
11372
11441
}
11442
+
11443
+ #[ test]
11444
+ fn parse_subobject_expr ( ) {
11445
+ assert_parse ! ( SubobjectExpr {
11446
+ with subs [ ] => {
11447
+ Ok => {
11448
+ "PKcL_Z3FooEE..." => {
11449
+ SubobjectExpr {
11450
+ ty: TypeHandle :: BackReference ( 1 ) ,
11451
+ expr: Box :: new( Expression :: Primary (
11452
+ ExprPrimary :: External (
11453
+ MangledName :: Encoding (
11454
+ Encoding :: Data (
11455
+ Name :: Unscoped (
11456
+ UnscopedName :: Unqualified (
11457
+ UnqualifiedName :: Source (
11458
+ SourceName (
11459
+ Identifier {
11460
+ start: 7 ,
11461
+ end: 10 ,
11462
+ }
11463
+ )
11464
+ )
11465
+ )
11466
+ )
11467
+ ) ,
11468
+ vec![ ]
11469
+ )
11470
+ )
11471
+ ) ) ,
11472
+ offset: 0 ,
11473
+ } ,
11474
+ b"..." ,
11475
+ [
11476
+ Substitutable :: Type (
11477
+ Type :: Qualified (
11478
+ CvQualifiers {
11479
+ restrict: false ,
11480
+ volatile: false ,
11481
+ const_: true ,
11482
+ } ,
11483
+ TypeHandle :: Builtin (
11484
+ BuiltinType :: Standard (
11485
+ StandardBuiltinType :: Char ,
11486
+ ) ,
11487
+ ) ,
11488
+ )
11489
+ ) ,
11490
+ Substitutable :: Type (
11491
+ Type :: PointerTo (
11492
+ TypeHandle :: BackReference (
11493
+ 0 ,
11494
+ ) ,
11495
+ ) ,
11496
+ )
11497
+ ]
11498
+ }
11499
+ }
11500
+ Err => {
11501
+ "" => Error :: UnexpectedEnd ,
11502
+ "" => Error :: UnexpectedEnd ,
11503
+ }
11504
+ }
11505
+ } ) ;
11506
+ }
11373
11507
}
0 commit comments