demangle.go
func (st *state) operatorName(inExpression bool) (AST, int) {
	if len(st.str) < 2 {
		st.fail("missing operator code")
	}
	code := st.str[:2]
	st.advance(2)
	if code[0] == 'v' && isDigit(code[1]) {
		name := st.sourceName()
		return &Operator{Name: name.(*Name).Name}, int(code[1] - '0')
	} else if code == "cv" {
		// Push a nil on templates to indicate that template
		// parameters will have their template filled in
		// later.
		if !inExpression {
			st.templates = append(st.templates, nil)
		}

		t := st.demangleType(!inExpression)

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

		return &Cast{To: t}, 1
	} else if op, ok := operators[code]; ok {
		return &Operator{Name: op.name}, op.args
	} else {
		st.failEarlier("unrecognized operator code", 2)
		panic("not reached")
	}
}
func (st *state) operatorName(inExpression bool) (AST, int) {
	if len(st.str) < 2 {
		st.fail("missing operator code")
	}
	code := st.str[:2]
	st.advance(2)
	if code[0] == 'v' && isDigit(code[1]) {
		name := st.sourceName()
		return &Operator{Name: name.(*Name).Name}, int(code[1] - '0')
	} else if code == "cv" {
		// Push a nil on templates to indicate that template
		// parameters will have their template filled in
		// later.
		if !inExpression {
			st.templates = append(st.templates, nil)
		}

		t := st.demangleType(!inExpression)

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

		return &Cast{To: t}, 1
	} else if op, ok := operators[code]; ok {
		return &Operator{Name: op.name}, op.args
	} else {
		st.failEarlier("unrecognized operator code", 2)
		panic("not reached")
	}
}
// operator_name ::= many different two character encodings.
//               ::= cv <type>
//               ::= v <digit> <source-name>
//
// We need to know whether we are in an expression because it affects
// how we handle template parameters in the type of a cast operator.