demangle.go
func (st *state) pointerToMemberType(isCast bool) AST {
	st.checkChar('M')
	cl := st.demangleType(false)

	// The ABI says, "The type of a non-static member function is
	// considered to be different, for the purposes of
	// substitution, from the type of a namespace-scope or static
	// member function whose type appears similar. The types of
	// two non-static member functions are considered to be
	// different, for the purposes of substitution, if the
	// functions are members of different classes. In other words,
	// for the purposes of substitution, the class of which the
	// function is a member is considered part of the type of
	// function."
	//
	// For a pointer to member function, this call to demangleType
	// will end up adding a (possibly qualified) non-member
	// function type to the substitution table, which is not
	// correct; however, the member function type will never be
	// used in a substitution, so putting the wrong type in the
	// substitution table is harmless.
	mem := st.demangleType(isCast)
	return &PtrMem{Class: cl, Member: mem}
}
func (st *state) pointerToMemberType(isCast bool) AST {
	st.checkChar('M')
	cl := st.demangleType(false)

	// The ABI says, "The type of a non-static member function is
	// considered to be different, for the purposes of
	// substitution, from the type of a namespace-scope or static
	// member function whose type appears similar. The types of
	// two non-static member functions are considered to be
	// different, for the purposes of substitution, if the
	// functions are members of different classes. In other words,
	// for the purposes of substitution, the class of which the
	// function is a member is considered part of the type of
	// function."
	//
	// For a pointer to member function, this call to demangleType
	// will end up adding a (possibly qualified) non-member
	// function type to the substitution table, which is not
	// correct; however, the member function type will never be
	// used in a substitution, so putting the wrong type in the
	// substitution table is harmless.
	mem := st.demangleType(isCast)
	return &PtrMem{Class: cl, Member: mem}
}
// <pointer-to-member-type> ::= M <(class) type> <(member) type>