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}
}
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>
<pointer - to - member - type > :: = M < ( class ) type > < ( member ) type >