demangle.go
func (st *state) unqualifiedName() (r AST, isCast bool) {
	if len(st.str) < 1 {
		st.fail("expected unqualified name")
	}
	var a AST
	isCast = false
	c := st.str[0]
	if isDigit(c) {
		a = st.sourceName()
	} else if isLower(c) {
		a, _ = st.operatorName(false)
		if _, ok := a.(*Cast); ok {
			isCast = true
		}
		if op, ok := a.(*Operator); ok && op.Name == `operator"" ` {
			n := st.sourceName()
			a = &Unary{Op: op, Expr: n, Suffix: false, SizeofType: false}
		}
	} else {
		switch c {
		case 'C', 'D':
			st.fail("constructor/destructor not in nested name")
		case 'L':
			st.advance(1)
			a = st.sourceName()
			a = st.discriminator(a)
		case 'U':
			if len(st.str) < 2 {
				st.advance(1)
				st.fail("expected closure or unnamed type")
			}
			c := st.str[1]
			switch c {
			case 'l':
				a = st.closureTypeName()
			case 't':
				a = st.unnamedTypeName()
			default:
				st.advance(1)
				st.fail("expected closure or unnamed type")
			}
		default:
			st.fail("expected unqualified name")
		}
	}

	if len(st.str) > 0 && st.str[0] == 'B' {
		a = st.taggedName(a)
	}

	return a, isCast
}
func (st *state) unqualifiedName() (r AST, isCast bool) {
	if len(st.str) < 1 {
		st.fail("expected unqualified name")
	}
	var a AST
	isCast = false
	c := st.str[0]
	if isDigit(c) {
		a = st.sourceName()
	} else if isLower(c) {
		a, _ = st.operatorName(false)
		if _, ok := a.(*Cast); ok {
			isCast = true
		}
		if op, ok := a.(*Operator); ok && op.Name == `operator"" ` {
			n := st.sourceName()
			a = &Unary{Op: op, Expr: n, Suffix: false, SizeofType: false}
		}
	} else {
		switch c {
		case 'C', 'D':
			st.fail("constructor/destructor not in nested name")
		case 'L':
			st.advance(1)
			a = st.sourceName()
			a = st.discriminator(a)
		case 'U':
			if len(st.str) < 2 {
				st.advance(1)
				st.fail("expected closure or unnamed type")
			}
			c := st.str[1]
			switch c {
			case 'l':
				a = st.closureTypeName()
			case 't':
				a = st.unnamedTypeName()
			default:
				st.advance(1)
				st.fail("expected closure or unnamed type")
			}
		default:
			st.fail("expected unqualified name")
		}
	}

	if len(st.str) > 0 && st.str[0] == 'B' {
		a = st.taggedName(a)
	}

	return a, isCast
}
func ( st * state ) unqualifiedName ( ) ( r AST , isCast bool ) { if len ( st . str ) < 1 { st . fail ( " " ) } var a AST isCast = false c := st . str [ 0 ] if isDigit ( c ) { a = st . sourceName ( ) } else if isLower ( c ) { a , _ = st . operatorName ( false ) if _ , ok := a . ( * Cast ) ; ok { isCast = true } if op , ok := a . ( * Operator ) ; ok && op . Name == `operator"" ` { n := st . sourceName ( ) a = & Unary { Op : op , Expr : n , Suffix : false , SizeofType : false } } } else { switch c { case 'C' , 'D' : st . fail ( " " ) case 'L' : st . advance ( 1 ) a = st . sourceName ( ) a = st . discriminator ( a ) case 'U' : if len ( st . str ) < 2 { st . advance ( 1 ) st . fail ( " " ) } c := st . str [ 1 ] switch c { case 'l' : a = st . closureTypeName ( ) case 't' : a = st . unnamedTypeName ( ) default : st . advance ( 1 ) st . fail ( " " ) } default : st . fail ( " " ) } } if len ( st . str ) > 0 && st . str [ 0 ] == 'B' { a = st . taggedName ( a ) } return a , isCast }
// <unqualified-name> ::= <operator-name>
//                    ::= <ctor-dtor-name>
//                    ::= <source-name>
//                    ::= <local-source-name>
//
//  <local-source-name>	::= L <source-name> <discriminator>
<unqualified - name > :: = <operator - name > :: = <ctor - dtor - name > :: = <source - name > :: = <local - source - name > <local - source - name > :: = L <source - name > <discriminator >