diff --git a/src/lib.rs b/src/lib.rs index b0f915e..77ff55b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -125,6 +125,7 @@ pub struct Params<'a> { pub enum Type<'a> { None, MemberFunction(Params<'a>, StorageClass, Box>), // StorageClass is for the 'this' pointer + MemberFunctionPointer(Name<'a>, Params<'a>, StorageClass, Box>), NonMemberFunction(Params<'a>, StorageClass, Box>), CXXVBTable(NameSequence<'a>, StorageClass), CXXVFTable(NameSequence<'a>, StorageClass), @@ -656,7 +657,7 @@ impl<'a> ParserState<'a> { } if self.consume(b"P8") { - let _name = self.read_unqualified_name(true); + let name = self.read_unqualified_name(true)?; self.expect(b"@")?; let _is_64bit_ptr = self.expect(b"E")?; let access_class = self.read_func_access_class(); @@ -664,13 +665,11 @@ impl<'a> ParserState<'a> { let storage_class_for_return = self.read_storage_class_for_return()?; let return_type = self.read_func_return_type(storage_class_for_return)?; let params = self.read_func_params()?; - return Ok(Type::Ptr( - Box::new(Type::MemberFunction( - params, - access_class, - Box::new(return_type), - )), - sc, + return Ok(Type::MemberFunctionPointer( + name, + params, + access_class, + Box::new(return_type), )); } @@ -917,6 +916,19 @@ impl<'a> Serializer<'a> { self.write_pre(inner)?; return Ok(()); } + &Type::MemberFunctionPointer(ref name, _, _, ref inner) => { + self.write_pre(inner)?; + if self.flags == DemangleFlags::LotsOfWhitespace { + self.write_space()?; + } + write!(self.w, "(")?; + if self.flags == DemangleFlags::LotsOfWhitespace { + self.write_space()?; + } + self.write_one_name(name)?; + write!(self.w, "::*)")?; + return Ok(()); + } &Type::NonMemberFunction(_, _, ref inner) => { self.write_pre(inner)?; return Ok(()); @@ -1092,6 +1104,20 @@ impl<'a> Serializer<'a> { } } } + &Type::MemberFunctionPointer(_, ref params, sc, ref return_type) => { + write!(self.w, "(")?; + self.write_params(params)?; + write!(self.w, ")")?; + + self.write_post(return_type)?; + + if sc.contains(StorageClass::CONST) { + write!(self.w, "const")?; + if self.flags == DemangleFlags::LotsOfWhitespace { + self.write_space()?; + } + } + } &Type::CXXVBTable(ref names, _sc) => { self.write_name(names)?; write!(self.w, "{}", "\'}")?; // the rest of the "operator"