demangle.go
func (st *state) encoding(params bool, local forLocalNameType) AST {
	if len(st.str) < 1 {
		st.fail("expected encoding")
	}

	if st.str[0] == 'G' || st.str[0] == 'T' {
		return st.specialName()
	}

	a := st.name()
	a = simplify(a)

	if !params {
		// Don't demangle the parameters.

		// Strip CV-qualifiers, as they apply to the 'this'
		// parameter, and are not output by the standard
		// demangler without parameters.
		if mwq, ok := a.(*MethodWithQualifiers); ok {
			a = mwq.Method
		}

		// If this is a local name, there may be CV-qualifiers
		// on the name that really apply to the top level, and
		// therefore must be discarded when discarding
		// parameters.  This can happen when parsing a class
		// that is local to a function.
		if q, ok := a.(*Qualified); ok && q.LocalName {
			p := &q.Name
			if da, ok := (*p).(*DefaultArg); ok {
				p = &da.Arg
			}
			if mwq, ok := (*p).(*MethodWithQualifiers); ok {
				*p = mwq.Method
			}
		}

		return a
	}

	if len(st.str) == 0 || st.str[0] == 'E' {
		// There are no parameters--this is a data symbol, not
		// a function symbol.
		return a
	}

	check := a
	mwq, _ := check.(*MethodWithQualifiers)
	if mwq != nil {
		check = mwq.Method
	}
	template, _ := check.(*Template)
	if template != nil {
		st.templates = append(st.templates, template)
	}

	ft := st.bareFunctionType(hasReturnType(a))

	if template != nil {
		st.templates = st.templates[:len(st.templates)-1]
	}

	ft = simplify(ft)

	// For a local name, discard the return type, so that it
	// doesn't get confused with the top level return type.
	if local == forLocalName {
		if functype, ok := ft.(*FunctionType); ok {
			functype.Return = nil
		}
	}

	// Any top-level qualifiers belong to the function type.
	if mwq != nil {
		a = mwq.Method
		mwq.Method = ft
		ft = mwq
	}
	if q, ok := a.(*Qualified); ok && q.LocalName {
		p := &q.Name
		if da, ok := (*p).(*DefaultArg); ok {
			p = &da.Arg
		}
		if mwq, ok := (*p).(*MethodWithQualifiers); ok {
			*p = mwq.Method
			mwq.Method = ft
			ft = mwq
		}
	}

	return &Typed{Name: a, Type: ft}
}
func (st *state) encoding(params bool, local forLocalNameType) AST {
	if len(st.str) < 1 {
		st.fail("expected encoding")
	}

	if st.str[0] == 'G' || st.str[0] == 'T' {
		return st.specialName()
	}

	a := st.name()
	a = simplify(a)

	if !params {
		// Don't demangle the parameters.

		// Strip CV-qualifiers, as they apply to the 'this'
		// parameter, and are not output by the standard
		// demangler without parameters.
		if mwq, ok := a.(*MethodWithQualifiers); ok {
			a = mwq.Method
		}

		// If this is a local name, there may be CV-qualifiers
		// on the name that really apply to the top level, and
		// therefore must be discarded when discarding
		// parameters.  This can happen when parsing a class
		// that is local to a function.
		if q, ok := a.(*Qualified); ok && q.LocalName {
			p := &q.Name
			if da, ok := (*p).(*DefaultArg); ok {
				p = &da.Arg
			}
			if mwq, ok := (*p).(*MethodWithQualifiers); ok {
				*p = mwq.Method
			}
		}

		return a
	}

	if len(st.str) == 0 || st.str[0] == 'E' {
		// There are no parameters--this is a data symbol, not
		// a function symbol.
		return a
	}

	check := a
	mwq, _ := check.(*MethodWithQualifiers)
	if mwq != nil {
		check = mwq.Method
	}
	template, _ := check.(*Template)
	if template != nil {
		st.templates = append(st.templates, template)
	}

	ft := st.bareFunctionType(hasReturnType(a))

	if template != nil {
		st.templates = st.templates[:len(st.templates)-1]
	}

	ft = simplify(ft)

	// For a local name, discard the return type, so that it
	// doesn't get confused with the top level return type.
	if local == forLocalName {
		if functype, ok := ft.(*FunctionType); ok {
			functype.Return = nil
		}
	}

	// Any top-level qualifiers belong to the function type.
	if mwq != nil {
		a = mwq.Method
		mwq.Method = ft
		ft = mwq
	}
	if q, ok := a.(*Qualified); ok && q.LocalName {
		p := &q.Name
		if da, ok := (*p).(*DefaultArg); ok {
			p = &da.Arg
		}
		if mwq, ok := (*p).(*MethodWithQualifiers); ok {
			*p = mwq.Method
			mwq.Method = ft
			ft = mwq
		}
	}

	return &Typed{Name: a, Type: ft}
}
func ( st * state ) encoding ( params bool , local forLocalNameType ) AST { if len ( st . str ) < 1 { st . fail ( " " ) } if st . str [ 0 ] == 'G' || st . str [ 0 ] == 'T' { return st . specialName ( ) } a := st . name ( ) a = simplify ( a ) if ! params { // Don't demangle the parameters. // Strip CV-qualifiers, as they apply to the 'this' // parameter, and are not output by the standard // demangler without parameters. if mwq , ok := a . ( * MethodWithQualifiers ) ; ok { a = mwq . Method } // If this is a local name, there may be CV-qualifiers // on the name that really apply to the top level, and // therefore must be discarded when discarding // parameters.  This can happen when parsing a class // that is local to a function. if q , ok := a . ( * Qualified ) ; ok && q . LocalName { p := & q . Name if da , ok := ( * p ) . ( * DefaultArg ) ; ok { p = & da . Arg } if mwq , ok := ( * p ) . ( * MethodWithQualifiers ) ; ok { * p = mwq . Method } } return a } if len ( st . str ) == 0 || st . str [ 0 ] == 'E' { // There are no parameters--this is a data symbol, not // a function symbol. return a } check := a mwq , _ := check . ( * MethodWithQualifiers ) if mwq != nil { check = mwq . Method } template , _ := check . ( * Template ) if template != nil { st . templates = append ( st . templates , template ) } ft := st . bareFunctionType ( hasReturnType ( a ) ) if template != nil { st . templates = st . templates [ : len ( st . templates ) - 1 ] } ft = simplify ( ft ) // For a local name, discard the return type, so that it // doesn't get confused with the top level return type. if local == forLocalName { if functype , ok := ft . ( * FunctionType ) ; ok { functype . Return = nil } } // Any top-level qualifiers belong to the function type. if mwq != nil { a = mwq . Method mwq . Method = ft ft = mwq } if q , ok := a . ( * Qualified ) ; ok && q . LocalName { p := & q . Name if da , ok := ( * p ) . ( * DefaultArg ) ; ok { p = & da . Arg } if mwq , ok := ( * p ) . ( * MethodWithQualifiers ) ; ok { * p = mwq . Method mwq . Method = ft ft = mwq } } return & Typed { Name : a , Type : ft } }
// encoding ::= <(function) name> <bare-function-type>
//              <(data) name>
//              <special-name>
encoding :: = < ( function ) name > <bare - function - type > < ( data ) name > <special - name >