@@ -255,6 +255,7 @@ pub enum VarStorageKind {
255255// Represents an identifier which may be a template.
256256#[ derive( Clone , PartialEq ) ]
257257pub enum Name < ' a > {
258+ Md5 ( & ' a [ u8 ] ) ,
258259 Operator ( Operator < ' a > ) ,
259260 NonTemplate ( & ' a [ u8 ] ) ,
260261 AsInterface ( & ' a [ u8 ] ) ,
@@ -267,6 +268,10 @@ pub enum Name<'a> {
267268impl < ' a > fmt:: Debug for Name < ' a > {
268269 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
269270 match * self {
271+ Name :: Md5 ( s) => f
272+ . debug_tuple ( "Md5" )
273+ . field ( & String :: from_utf8_lossy ( s) )
274+ . finish ( ) ,
270275 Name :: Operator ( ref op) => f. debug_tuple ( "Operator" ) . field ( & op) . finish ( ) ,
271276 Name :: NonTemplate ( s) => f
272277 . debug_tuple ( "NonTemplate" )
@@ -500,6 +505,17 @@ impl<'a> ParserState<'a> {
500505 return Err ( self . fail ( "does not start with b'?'" ) ) ;
501506 }
502507
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+
503519 if self . consume ( b"$" ) {
504520 if self . consume ( b"TSS" ) {
505521 let mut guard_num: i32 = i32:: from (
@@ -687,6 +703,21 @@ impl<'a> ParserState<'a> {
687703 }
688704 }
689705
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+
690721 fn read_digit ( & mut self ) -> Option < u8 > {
691722 match self . peek ( ) {
692723 Some ( first) => {
@@ -2180,6 +2211,11 @@ impl<'a> Serializer<'a> {
21802211
21812212 fn write_one_name ( & mut self , name : & Name ) -> Result < ( ) > {
21822213 match * name {
2214+ Name :: Md5 ( ref name) => {
2215+ write ! ( self . w, "??@" ) ?;
2216+ self . w . write_all ( name) ?;
2217+ write ! ( self . w, "@" ) ?;
2218+ }
21832219 Name :: Operator ( ref op) => {
21842220 self . write_space ( ) ?;
21852221 self . write_operator_name ( op) ?;
@@ -2244,6 +2280,11 @@ impl<'a> Serializer<'a> {
22442280 }
22452281
22462282 match names. name {
2283+ Name :: Md5 ( ref name) => {
2284+ write ! ( self . w, "??@" ) ?;
2285+ self . w . write_all ( name) ?;
2286+ write ! ( self . w, "@" ) ?;
2287+ }
22472288 Name :: Operator ( ref op) => {
22482289 match * op {
22492290 Operator :: Ctor => {
0 commit comments