@@ -255,6 +255,7 @@ pub enum VarStorageKind {
255
255
// Represents an identifier which may be a template.
256
256
#[ derive( Clone , PartialEq ) ]
257
257
pub enum Name < ' a > {
258
+ Md5 ( & ' a [ u8 ] ) ,
258
259
Operator ( Operator < ' a > ) ,
259
260
NonTemplate ( & ' a [ u8 ] ) ,
260
261
AsInterface ( & ' a [ u8 ] ) ,
@@ -267,6 +268,10 @@ pub enum Name<'a> {
267
268
impl < ' a > fmt:: Debug for Name < ' a > {
268
269
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
269
270
match * self {
271
+ Name :: Md5 ( s) => f
272
+ . debug_tuple ( "Md5" )
273
+ . field ( & String :: from_utf8_lossy ( s) )
274
+ . finish ( ) ,
270
275
Name :: Operator ( ref op) => f. debug_tuple ( "Operator" ) . field ( & op) . finish ( ) ,
271
276
Name :: NonTemplate ( s) => f
272
277
. debug_tuple ( "NonTemplate" )
@@ -500,6 +505,17 @@ impl<'a> ParserState<'a> {
500
505
return Err ( self . fail ( "does not start with b'?'" ) ) ;
501
506
}
502
507
508
+ if self . consume ( b"?@" ) {
509
+ let name = self . read_md5_name ( ) ?;
510
+ return Ok ( ParseResult {
511
+ symbol : Symbol {
512
+ name,
513
+ scope : NameSequence { names : Vec :: new ( ) } ,
514
+ } ,
515
+ symbol_type : Type :: None ,
516
+ } ) ;
517
+ }
518
+
503
519
if self . consume ( b"$" ) {
504
520
if self . consume ( b"TSS" ) {
505
521
let mut guard_num: i32 = i32:: from (
@@ -687,6 +703,21 @@ impl<'a> ParserState<'a> {
687
703
}
688
704
}
689
705
706
+ /// An MD5 mangled name is `??@` followed by 32 characters and a terminating `@`.
707
+ ///
708
+ /// See https://github.com/llvm/llvm-project/blob/818cf30b83305fa4a2f75821349210b0f7aff4a4/llvm/lib/Demangle/MicrosoftDemangle.cpp#L754
709
+ fn read_md5_name ( & mut self ) -> Result < Name < ' a > > {
710
+ let start_offset = self . offset ;
711
+
712
+ while self . read_hex_digit ( ) . is_some ( ) { }
713
+ let end_offset = self . offset ;
714
+
715
+ if self . offset - start_offset != 32 || !self . consume ( b"@" ) {
716
+ return Err ( self . fail ( "expected MD5 mangled name of length 32" ) ) ;
717
+ }
718
+ Ok ( Name :: Md5 ( & self . input . as_bytes ( ) [ start_offset..end_offset] ) )
719
+ }
720
+
690
721
fn read_digit ( & mut self ) -> Option < u8 > {
691
722
match self . peek ( ) {
692
723
Some ( first) => {
@@ -2180,6 +2211,11 @@ impl<'a> Serializer<'a> {
2180
2211
2181
2212
fn write_one_name ( & mut self , name : & Name ) -> Result < ( ) > {
2182
2213
match * name {
2214
+ Name :: Md5 ( ref name) => {
2215
+ write ! ( self . w, "??@" ) ?;
2216
+ self . w . write_all ( name) ?;
2217
+ write ! ( self . w, "@" ) ?;
2218
+ }
2183
2219
Name :: Operator ( ref op) => {
2184
2220
self . write_space ( ) ?;
2185
2221
self . write_operator_name ( op) ?;
@@ -2244,6 +2280,11 @@ impl<'a> Serializer<'a> {
2244
2280
}
2245
2281
2246
2282
match names. name {
2283
+ Name :: Md5 ( ref name) => {
2284
+ write ! ( self . w, "??@" ) ?;
2285
+ self . w . write_all ( name) ?;
2286
+ write ! ( self . w, "@" ) ?;
2287
+ }
2247
2288
Name :: Operator ( ref op) => {
2248
2289
match * op {
2249
2290
Operator :: Ctor => {
0 commit comments