@@ -143,14 +143,15 @@ type Result<T> = result::Result<T, Error>;
143143
144144bitflags ! {
145145 pub struct StorageClass : u32 {
146- const CONST = 0b0000_0001 ;
147- const VOLATILE = 0b0000_0010 ;
148- const FAR = 0b0000_0100 ;
149- const HUGE = 0b0000_1000 ;
150- const UNALIGNED = 0b0001_0000 ;
151- const RESTRICT = 0b0010_0000 ;
152- const LVALUE_QUAL = 0b0100_0000 ;
153- const RVALUE_QUAL = 0b1000_0000 ;
146+ const CONST = 0b0_0000_0001 ;
147+ const VOLATILE = 0b0_0000_0010 ;
148+ const FAR = 0b0_0000_0100 ;
149+ const HUGE = 0b0_0000_1000 ;
150+ const UNALIGNED = 0b0_0001_0000 ;
151+ const RESTRICT = 0b0_0010_0000 ;
152+ const PTR64 = 0b0_0100_0000 ;
153+ const LVALUE_QUAL = 0b0_1000_0000 ;
154+ const RVALUE_QUAL = 0b1_0000_0000 ;
154155 }
155156}
156157
@@ -201,6 +202,9 @@ bitflags! {
201202 const HUG_TYPE = 0x40_0000 ;
202203 /// Insert a space before pointers.
203204 const SPACE_BEFORE_POINTER = 0x80_0000 ;
205+ /// Add ptr64 to output. This is disabled by default because it's also not
206+ /// added by LLVM. This is in a way the inverse of the DIA `UNDNAME_NO_PTR64`
207+ const WITH_PTR64 = 0x100_000 ;
204208 }
205209}
206210
@@ -610,7 +614,11 @@ impl<'a> ParserState<'a> {
610614 let access_class = if func_class. contains ( FuncClass :: STATIC ) {
611615 StorageClass :: empty ( )
612616 } else {
613- let _is_64bit_ptr = self . expect ( b"E" ) ;
617+ let ptr64 = if self . consume ( b"E" ) {
618+ StorageClass :: PTR64
619+ } else {
620+ StorageClass :: empty ( )
621+ } ;
614622 let restrict = if self . consume ( b"I" ) {
615623 StorageClass :: RESTRICT
616624 } else {
@@ -627,7 +635,7 @@ impl<'a> ParserState<'a> {
627635 }
628636 _ => StorageClass :: empty ( ) ,
629637 } ;
630- self . read_qualifier ( ) | restrict | ref_qualifiers
638+ self . read_qualifier ( ) | ptr64 | restrict | ref_qualifiers
631639 } ;
632640
633641 let calling_conv = self . read_calling_conv ( ) ?;
@@ -1207,12 +1215,16 @@ impl<'a> ParserState<'a> {
12071215
12081216 fn read_member_function_pointer ( & mut self , read_qualifiers : bool ) -> Result < Type < ' a > > {
12091217 let symbol = self . read_name ( true ) ?;
1210- let _is_64bit_ptr = self . consume ( b"E" ) ;
1218+ let ptr64 = if self . consume ( b"E" ) {
1219+ StorageClass :: PTR64
1220+ } else {
1221+ StorageClass :: empty ( )
1222+ } ;
12111223 let ( access_class, func_class) = if read_qualifiers {
1212- ( self . read_qualifier ( ) , FuncClass :: empty ( ) )
1224+ ( self . read_qualifier ( ) | ptr64 , FuncClass :: empty ( ) )
12131225 } else {
12141226 let c = self . get ( ) ?;
1215- ( StorageClass :: empty ( ) , self . read_func_class ( c) ?)
1227+ ( ptr64 , self . read_func_class ( c) ?)
12161228 } ;
12171229 let calling_conv = self . read_calling_conv ( ) ?;
12181230 let storage_class_for_return = self . read_storage_class_for_return ( ) ?;
@@ -1352,9 +1364,13 @@ impl<'a> ParserState<'a> {
13521364 }
13531365
13541366 fn read_pointee ( & mut self ) -> Result < Type < ' a > > {
1355- let _is_64bit_ptr = self . expect ( b"E" ) ;
1367+ let ptr64 = if self . consume ( b"E" ) {
1368+ StorageClass :: PTR64
1369+ } else {
1370+ StorageClass :: empty ( )
1371+ } ;
13561372 let storage_class = self . read_storage_class ( ) ;
1357- self . read_var_type ( storage_class)
1373+ self . read_var_type ( storage_class | ptr64 )
13581374 }
13591375
13601376 fn read_array ( & mut self ) -> Result < Type < ' a > > {
@@ -1825,6 +1841,7 @@ impl<'a> Serializer<'a> {
18251841 }
18261842
18271843 fn write_memfn_qualifiers ( & mut self , sc : StorageClass ) -> Result < ( ) > {
1844+ let with_ptr64 = self . flags . contains ( DemangleFlags :: WITH_PTR64 ) ;
18281845 if self . flags . contains ( DemangleFlags :: NO_THISTYPE ) {
18291846 // TODO: should probably check for NO_CV_THISTYPE and NO_MS_THISTYPE
18301847 // separately but I don't know what exactly those affect.
@@ -1840,6 +1857,9 @@ impl<'a> Serializer<'a> {
18401857 } ;
18411858
18421859 write_one_qual ( StorageClass :: CONST , b"const" ) ?;
1860+ if with_ptr64 {
1861+ write_one_qual ( StorageClass :: PTR64 , b"__ptr64" ) ?;
1862+ }
18431863 // __restrict is different than `restrict`, keep the underscores!
18441864 write_one_qual ( StorageClass :: RESTRICT , b"__restrict" ) ?;
18451865 // TODO: undname prints ref-qualifiers tightly to previous qualifiers.
0 commit comments