demangle.go
func (st *state) specialName() AST {
	if st.str[0] == 'T' {
		st.advance(1)
		if len(st.str) == 0 {
			st.fail("expected special name code")
		}
		c := st.str[0]
		st.advance(1)
		switch c {
		case 'V':
			t := st.demangleType(false)
			return &Special{Prefix: "vtable for ", Val: t}
		case 'T':
			t := st.demangleType(false)
			return &Special{Prefix: "VTT for ", Val: t}
		case 'I':
			t := st.demangleType(false)
			return &Special{Prefix: "typeinfo for ", Val: t}
		case 'S':
			t := st.demangleType(false)
			return &Special{Prefix: "typeinfo name for ", Val: t}
		case 'h':
			st.callOffset('h')
			v := st.encoding(true, notForLocalName)
			return &Special{Prefix: "non-virtual thunk to ", Val: v}
		case 'v':
			st.callOffset('v')
			v := st.encoding(true, notForLocalName)
			return &Special{Prefix: "virtual thunk to ", Val: v}
		case 'c':
			st.callOffset(0)
			st.callOffset(0)
			v := st.encoding(true, notForLocalName)
			return &Special{Prefix: "covariant return thunk to ", Val: v}
		case 'C':
			derived := st.demangleType(false)
			off := st.off
			offset := st.number()
			if offset < 0 {
				st.failEarlier("expected positive offset", st.off-off)
			}
			if len(st.str) == 0 || st.str[0] != '_' {
				st.fail("expected _ after number")
			}
			st.advance(1)
			base := st.demangleType(false)
			return &Special2{Prefix: "construction vtable for ", Val1: base, Middle: "-in-", Val2: derived}
		case 'F':
			t := st.demangleType(false)
			return &Special{Prefix: "typeinfo fn for ", Val: t}
		case 'J':
			t := st.demangleType(false)
			return &Special{Prefix: "java Class for ", Val: t}
		case 'H':
			n := st.name()
			return &Special{Prefix: "TLS init function for ", Val: n}
		case 'W':
			n := st.name()
			return &Special{Prefix: "TLS wrapper function for ", Val: n}
		default:
			st.fail("unrecognized special T name code")
			panic("not reached")
		}
	} else {
		st.checkChar('G')
		if len(st.str) == 0 {
			st.fail("expected special name code")
		}
		c := st.str[0]
		st.advance(1)
		switch c {
		case 'V':
			n := st.name()
			return &Special{Prefix: "guard variable for ", Val: n}
		case 'R':
			n := st.name()
			i := st.number()
			return &Special{Prefix: fmt.Sprintf("reference temporary #%d for ", i), Val: n}
		case 'A':
			v := st.encoding(true, notForLocalName)
			return &Special{Prefix: "hidden alias for ", Val: v}
		case 'T':
			if len(st.str) == 0 {
				st.fail("expected special GT name code")
			}
			c := st.str[0]
			st.advance(1)
			v := st.encoding(true, notForLocalName)
			switch c {
			case 'n':
				return &Special{Prefix: "non-transaction clone for ", Val: v}
			default:
				// The proposal is that different
				// letters stand for different types
				// of transactional cloning.  Treat
				// them all the same for now.
				fallthrough
			case 't':
				return &Special{Prefix: "transaction clone for ", Val: v}
			}
		case 'r':
			return st.javaResource()
		default:
			st.fail("unrecognized special G name code")
			panic("not reached")
		}
	}
}
func (st *state) specialName() AST {
	if st.str[0] == 'T' {
		st.advance(1)
		if len(st.str) == 0 {
			st.fail("expected special name code")
		}
		c := st.str[0]
		st.advance(1)
		switch c {
		case 'V':
			t := st.demangleType(false)
			return &Special{Prefix: "vtable for ", Val: t}
		case 'T':
			t := st.demangleType(false)
			return &Special{Prefix: "VTT for ", Val: t}
		case 'I':
			t := st.demangleType(false)
			return &Special{Prefix: "typeinfo for ", Val: t}
		case 'S':
			t := st.demangleType(false)
			return &Special{Prefix: "typeinfo name for ", Val: t}
		case 'h':
			st.callOffset('h')
			v := st.encoding(true, notForLocalName)
			return &Special{Prefix: "non-virtual thunk to ", Val: v}
		case 'v':
			st.callOffset('v')
			v := st.encoding(true, notForLocalName)
			return &Special{Prefix: "virtual thunk to ", Val: v}
		case 'c':
			st.callOffset(0)
			st.callOffset(0)
			v := st.encoding(true, notForLocalName)
			return &Special{Prefix: "covariant return thunk to ", Val: v}
		case 'C':
			derived := st.demangleType(false)
			off := st.off
			offset := st.number()
			if offset < 0 {
				st.failEarlier("expected positive offset", st.off-off)
			}
			if len(st.str) == 0 || st.str[0] != '_' {
				st.fail("expected _ after number")
			}
			st.advance(1)
			base := st.demangleType(false)
			return &Special2{Prefix: "construction vtable for ", Val1: base, Middle: "-in-", Val2: derived}
		case 'F':
			t := st.demangleType(false)
			return &Special{Prefix: "typeinfo fn for ", Val: t}
		case 'J':
			t := st.demangleType(false)
			return &Special{Prefix: "java Class for ", Val: t}
		case 'H':
			n := st.name()
			return &Special{Prefix: "TLS init function for ", Val: n}
		case 'W':
			n := st.name()
			return &Special{Prefix: "TLS wrapper function for ", Val: n}
		default:
			st.fail("unrecognized special T name code")
			panic("not reached")
		}
	} else {
		st.checkChar('G')
		if len(st.str) == 0 {
			st.fail("expected special name code")
		}
		c := st.str[0]
		st.advance(1)
		switch c {
		case 'V':
			n := st.name()
			return &Special{Prefix: "guard variable for ", Val: n}
		case 'R':
			n := st.name()
			i := st.number()
			return &Special{Prefix: fmt.Sprintf("reference temporary #%d for ", i), Val: n}
		case 'A':
			v := st.encoding(true, notForLocalName)
			return &Special{Prefix: "hidden alias for ", Val: v}
		case 'T':
			if len(st.str) == 0 {
				st.fail("expected special GT name code")
			}
			c := st.str[0]
			st.advance(1)
			v := st.encoding(true, notForLocalName)
			switch c {
			case 'n':
				return &Special{Prefix: "non-transaction clone for ", Val: v}
			default:
				// The proposal is that different
				// letters stand for different types
				// of transactional cloning.  Treat
				// them all the same for now.
				fallthrough
			case 't':
				return &Special{Prefix: "transaction clone for ", Val: v}
			}
		case 'r':
			return st.javaResource()
		default:
			st.fail("unrecognized special G name code")
			panic("not reached")
		}
	}
}
func ( st * state ) specialName ( ) AST { if st . str [ 0 ] == 'T' { st . advance ( 1 ) if len ( st . str ) == 0 { st . fail ( " " ) } c := st . str [ 0 ] st . advance ( 1 ) switch c { case 'V' : t := st . demangleType ( false ) return & Special { Prefix : " " , Val : t } case 'T' : t := st . demangleType ( false ) return & Special { Prefix : " " , Val : t } case 'I' : t := st . demangleType ( false ) return & Special { Prefix : " " , Val : t } case 'S' : t := st . demangleType ( false ) return & Special { Prefix : " " , Val : t } case 'h' : st . callOffset ( 'h' ) v := st . encoding ( true , notForLocalName ) return & Special { Prefix : " " , Val : v } case 'v' : st . callOffset ( 'v' ) v := st . encoding ( true , notForLocalName ) return & Special { Prefix : " " , Val : v } case 'c' : st . callOffset ( 0 ) st . callOffset ( 0 ) v := st . encoding ( true , notForLocalName ) return & Special { Prefix : " " , Val : v } case 'C' : derived := st . demangleType ( false ) off := st . off offset := st . number ( ) if offset < 0 { st . failEarlier ( " " , st . off - off ) } if len ( st . str ) == 0 || st . str [ 0 ] != '_' { st . fail ( " " ) } st . advance ( 1 ) base := st . demangleType ( false ) return & Special2 { Prefix : " " , Val1 : base , Middle : " " , Val2 : derived } case 'F' : t := st . demangleType ( false ) return & Special { Prefix : " " , Val : t } case 'J' : t := st . demangleType ( false ) return & Special { Prefix : " " , Val : t } case 'H' : n := st . name ( ) return & Special { Prefix : " " , Val : n } case 'W' : n := st . name ( ) return & Special { Prefix : " " , Val : n } default : st . fail ( " " ) panic ( " " ) } } else { st . checkChar ( 'G' ) if len ( st . str ) == 0 { st . fail ( " " ) } c := st . str [ 0 ] st . advance ( 1 ) switch c { case 'V' : n := st . name ( ) return & Special { Prefix : " " , Val : n } case 'R' : n := st . name ( ) i := st . number ( ) return & Special { Prefix : fmt . Sprintf ( " " , i ) , Val : n } case 'A' : v := st . encoding ( true , notForLocalName ) return & Special { Prefix : " " , Val : v } case 'T' : if len ( st . str ) == 0 { st . fail ( " " ) } c := st . str [ 0 ] st . advance ( 1 ) v := st . encoding ( true , notForLocalName ) switch c { case 'n' : return & Special { Prefix : " " , Val : v } default : // The proposal is that different // letters stand for different types // of transactional cloning.  Treat // them all the same for now. fallthrough case 't' : return & Special { Prefix : " " , Val : v } } case 'r' : return st . javaResource ( ) default : st . fail ( " " ) panic ( " " ) } } }
// <special-name> ::= TV <type>
//                ::= TT <type>
//                ::= TI <type>
//                ::= TS <type>
//                ::= GV <(object) name>
//                ::= T <call-offset> <(base) encoding>
//                ::= Tc <call-offset> <call-offset> <(base) encoding>
// Also g++ extensions:
//                ::= TC <type> <(offset) number> _ <(base) type>
//                ::= TF <type>
//                ::= TJ <type>
//                ::= GR <name>
//                ::= GA <encoding>
//                ::= Gr <resource name>
//                ::= GTt <encoding>
//                ::= GTn <encoding>
<special - name > :: = TV <type > :: = TT <type > :: = TI <type > :: = TS <type > :: = GV < ( object ) name > :: = T <call - offset > < ( base ) encoding > :: = Tc <call - offset > <call - offset > < ( base ) encoding > Also g ++ extensions : :: = TC <type > < ( offset ) number > _ < ( base ) type > :: = TF <type > :: = TJ <type > :: = GR <name > :: = GA <encoding > :: = Gr <resource name > :: = GTt <encoding > :: = GTn <encoding >