@@ -419,6 +419,7 @@ pub enum Type<'a> {
419419 Array ( i32 , Box < Type < ' a > > , StorageClass ) ,
420420 Var ( Box < Type < ' a > > , VarStorageKind , StorageClass ) ,
421421
422+ Alias ( Symbol < ' a > , StorageClass ) ,
422423 Struct ( Symbol < ' a > , StorageClass ) ,
423424 Union ( Symbol < ' a > , StorageClass ) ,
424425 Class ( Symbol < ' a > , StorageClass ) ,
@@ -616,28 +617,7 @@ impl<'a> ParserState<'a> {
616617 let access_class = if func_class. contains ( FuncClass :: STATIC ) {
617618 StorageClass :: empty ( )
618619 } else {
619- let ptr64 = if self . consume ( b"E" ) {
620- StorageClass :: PTR64
621- } else {
622- StorageClass :: empty ( )
623- } ;
624- let restrict = if self . consume ( b"I" ) {
625- StorageClass :: RESTRICT
626- } else {
627- StorageClass :: empty ( )
628- } ;
629- let ref_qualifiers = match self . peek ( ) {
630- Some ( b'G' ) => {
631- self . expect ( b"G" ) ?;
632- StorageClass :: LVALUE_QUAL
633- }
634- Some ( b'H' ) => {
635- self . expect ( b"H" ) ?;
636- StorageClass :: RVALUE_QUAL
637- }
638- _ => StorageClass :: empty ( ) ,
639- } ;
640- self . read_qualifier ( ) | ptr64 | restrict | ref_qualifiers
620+ self . read_func_qualifiers ( ) ?
641621 } ;
642622
643623 let calling_conv = self . read_calling_conv ( ) ?;
@@ -953,22 +933,57 @@ impl<'a> ParserState<'a> {
953933 Ok ( Symbol { name, scope } )
954934 }
955935
956- fn read_func_type ( & mut self ) -> Result < Type < ' a > > {
936+ fn read_func_qualifiers ( & mut self ) -> Result < StorageClass > {
937+ let ptr64 = if self . consume ( b"E" ) {
938+ StorageClass :: PTR64
939+ } else {
940+ StorageClass :: empty ( )
941+ } ;
942+ let restrict = if self . consume ( b"I" ) {
943+ StorageClass :: RESTRICT
944+ } else {
945+ StorageClass :: empty ( )
946+ } ;
947+ let unaligned = if self . consume ( b"F" ) {
948+ StorageClass :: UNALIGNED
949+ } else {
950+ StorageClass :: empty ( )
951+ } ;
952+ let ref_qualifiers = match self . peek ( ) {
953+ Some ( b'G' ) => {
954+ self . expect ( b"G" ) ?;
955+ StorageClass :: LVALUE_QUAL
956+ }
957+ Some ( b'H' ) => {
958+ self . expect ( b"H" ) ?;
959+ StorageClass :: RVALUE_QUAL
960+ }
961+ _ => StorageClass :: empty ( ) ,
962+ } ;
963+ Ok ( self . read_qualifier ( ) | ptr64 | restrict | unaligned | ref_qualifiers)
964+ }
965+
966+ fn read_func_type ( & mut self , read_qualifiers : bool ) -> Result < Type < ' a > > {
967+ let sc = if read_qualifiers {
968+ self . read_func_qualifiers ( ) ?
969+ } else {
970+ StorageClass :: empty ( )
971+ } ;
957972 let calling_conv = self . read_calling_conv ( ) ?;
958973 // this might have to be conditional on template context. For now
959974 // this does not cause issues. For more information see
960975 // https://github.com/mstange/msvc-demangler-rust/issues/21
961- let sc = if self . consume ( b"?" ) {
976+ let var_sc = if self . consume ( b"?" ) {
962977 self . read_storage_class ( )
963978 } else {
964979 StorageClass :: empty ( )
965980 } ;
966- let return_type = self . read_var_type ( sc ) ?;
981+ let return_type = self . read_var_type ( var_sc ) ?;
967982 let params = self . read_func_params ( ) ?;
968983 Ok ( Type :: NonMemberFunction (
969984 calling_conv,
970985 params,
971- StorageClass :: empty ( ) ,
986+ sc ,
972987 Box :: new ( return_type) ,
973988 ) )
974989 }
@@ -1149,6 +1164,10 @@ impl<'a> ParserState<'a> {
11491164 Some ( b'B' ) => StorageClass :: CONST ,
11501165 Some ( b'C' ) => StorageClass :: VOLATILE ,
11511166 Some ( b'D' ) => StorageClass :: CONST | StorageClass :: VOLATILE ,
1167+ Some ( b'Q' ) => StorageClass :: empty ( ) ,
1168+ Some ( b'R' ) => StorageClass :: CONST ,
1169+ Some ( b'S' ) => StorageClass :: VOLATILE ,
1170+ Some ( b'T' ) => StorageClass :: CONST | StorageClass :: VOLATILE ,
11521171 _ => return StorageClass :: empty ( ) ,
11531172 } ;
11541173 self . advance ( 1 ) ;
@@ -1250,12 +1269,12 @@ impl<'a> ParserState<'a> {
12501269 }
12511270
12521271 if self . consume ( b"A6" ) {
1253- let func_type = self . read_func_type ( ) ?;
1272+ let func_type = self . read_func_type ( false ) ?;
12541273 return Ok ( Type :: Ref ( Box :: new ( func_type) , sc) ) ;
12551274 }
12561275
12571276 if self . consume ( b"P6" ) {
1258- let func_type = self . read_func_type ( ) ?;
1277+ let func_type = self . read_func_type ( false ) ?;
12591278 return Ok ( Type :: Ptr ( Box :: new ( func_type) , sc) ) ;
12601279 }
12611280
@@ -1289,7 +1308,14 @@ impl<'a> ParserState<'a> {
12891308 return Ok ( Type :: Nullptr ) ;
12901309 }
12911310 if self . consume ( b"$A6" ) {
1292- return self . read_func_type ( ) ;
1311+ return self . read_func_type ( false ) ;
1312+ }
1313+ if self . consume ( b"$A8@@" ) {
1314+ return self . read_func_type ( true ) ;
1315+ }
1316+ if self . consume ( b"$Y" ) {
1317+ let name = self . read_name ( true ) ?;
1318+ return Ok ( Type :: Alias ( name, sc) ) ;
12931319 }
12941320 // These next cases can fallthrough, so be careful adding new ones!
12951321 if self . consume ( b"$C" ) {
@@ -1712,6 +1738,10 @@ impl<'a> Serializer<'a> {
17121738 self . write_pre ( inner) ?;
17131739 sc
17141740 }
1741+ Type :: Alias ( ref names, sc) => {
1742+ self . write_name ( names, None ) ?;
1743+ sc
1744+ }
17151745 Type :: Struct ( ref names, sc) => {
17161746 self . write_class ( names, "struct" ) ?;
17171747 sc
@@ -1877,6 +1907,7 @@ impl<'a> Serializer<'a> {
18771907 } ;
18781908
18791909 write_one_qual ( StorageClass :: CONST , b"const" ) ?;
1910+ write_one_qual ( StorageClass :: VOLATILE , b"volatile" ) ?;
18801911 if with_ptr64 {
18811912 write_one_qual ( StorageClass :: PTR64 , b"__ptr64" ) ?;
18821913 }
0 commit comments