Commit 97360096 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: replace Ctype switches with type switches

Instead of switching on Ctype (which internally uses a type switch)
and then scattering lots of type assertions throughout the CTFOO case
clauses, just use type switches directly on the underlying constant
value.

Passes toolstash/buildall.

Change-Id: I9bc172cc67e5f391cddc15539907883b4010689e
Reviewed-on: https://go-review.googlesource.com/22384
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 2d342fba
...@@ -378,22 +378,22 @@ bad: ...@@ -378,22 +378,22 @@ bad:
} }
func copyval(v Val) Val { func copyval(v Val) Val {
switch v.Ctype() { switch u := v.U.(type) {
case CTINT, CTRUNE: case *Mpint:
i := new(Mpint) i := new(Mpint)
i.Set(v.U.(*Mpint)) i.Set(u)
i.Rune = v.U.(*Mpint).Rune i.Rune = u.Rune
v.U = i v.U = i
case CTFLT: case *Mpflt:
f := newMpflt() f := newMpflt()
f.Set(v.U.(*Mpflt)) f.Set(u)
v.U = f v.U = f
case CTCPLX: case *Mpcplx:
c := new(Mpcplx) c := new(Mpcplx)
c.Real.Set(&v.U.(*Mpcplx).Real) c.Real.Set(&u.Real)
c.Imag.Set(&v.U.(*Mpcplx).Imag) c.Imag.Set(&u.Imag)
v.U = c v.U = c
} }
...@@ -401,16 +401,16 @@ func copyval(v Val) Val { ...@@ -401,16 +401,16 @@ func copyval(v Val) Val {
} }
func tocplx(v Val) Val { func tocplx(v Val) Val {
switch v.Ctype() { switch u := v.U.(type) {
case CTINT, CTRUNE: case *Mpint:
c := new(Mpcplx) c := new(Mpcplx)
c.Real.SetInt(v.U.(*Mpint)) c.Real.SetInt(u)
c.Imag.SetFloat64(0.0) c.Imag.SetFloat64(0.0)
v.U = c v.U = c
case CTFLT: case *Mpflt:
c := new(Mpcplx) c := new(Mpcplx)
c.Real.Set(v.U.(*Mpflt)) c.Real.Set(u)
c.Imag.SetFloat64(0.0) c.Imag.SetFloat64(0.0)
v.U = c v.U = c
} }
...@@ -419,17 +419,17 @@ func tocplx(v Val) Val { ...@@ -419,17 +419,17 @@ func tocplx(v Val) Val {
} }
func toflt(v Val) Val { func toflt(v Val) Val {
switch v.Ctype() { switch u := v.U.(type) {
case CTINT, CTRUNE: case *Mpint:
f := newMpflt() f := newMpflt()
f.SetInt(v.U.(*Mpint)) f.SetInt(u)
v.U = f v.U = f
case CTCPLX: case *Mpcplx:
f := newMpflt() f := newMpflt()
f.Set(&v.U.(*Mpcplx).Real) f.Set(&u.Real)
if v.U.(*Mpcplx).Imag.CmpFloat64(0) != 0 { if u.Imag.CmpFloat64(0) != 0 {
Yyerror("constant %v%vi truncated to real", Fconv(&v.U.(*Mpcplx).Real, FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, FmtSharp|FmtSign)) Yyerror("constant %v%vi truncated to real", Fconv(&u.Real, FmtSharp), Fconv(&u.Imag, FmtSharp|FmtSign))
} }
v.U = f v.U = f
} }
...@@ -438,31 +438,33 @@ func toflt(v Val) Val { ...@@ -438,31 +438,33 @@ func toflt(v Val) Val {
} }
func toint(v Val) Val { func toint(v Val) Val {
switch v.Ctype() { switch u := v.U.(type) {
case CTRUNE: case *Mpint:
if u.Rune {
i := new(Mpint) i := new(Mpint)
i.Set(v.U.(*Mpint)) i.Set(u)
v.U = i v.U = i
}
case CTFLT: case *Mpflt:
i := new(Mpint) i := new(Mpint)
if f := v.U.(*Mpflt); i.SetFloat(f) < 0 { if i.SetFloat(u) < 0 {
msg := "constant %v truncated to integer" msg := "constant %v truncated to integer"
// provide better error message if SetFloat failed because f was too large // provide better error message if SetFloat failed because f was too large
if f.Val.IsInt() { if u.Val.IsInt() {
msg = "constant %v overflows integer" msg = "constant %v overflows integer"
} }
Yyerror(msg, Fconv(f, FmtSharp)) Yyerror(msg, Fconv(u, FmtSharp))
} }
v.U = i v.U = i
case CTCPLX: case *Mpcplx:
i := new(Mpint) i := new(Mpint)
if i.SetFloat(&v.U.(*Mpcplx).Real) < 0 { if i.SetFloat(&u.Real) < 0 {
Yyerror("constant %v%vi truncated to integer", Fconv(&v.U.(*Mpcplx).Real, FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, FmtSharp|FmtSign)) Yyerror("constant %v%vi truncated to integer", Fconv(&u.Real, FmtSharp), Fconv(&u.Imag, FmtSharp|FmtSign))
} }
if v.U.(*Mpcplx).Imag.CmpFloat64(0) != 0 { if u.Imag.CmpFloat64(0) != 0 {
Yyerror("constant %v%vi truncated to real", Fconv(&v.U.(*Mpcplx).Real, FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, FmtSharp|FmtSign)) Yyerror("constant %v%vi truncated to real", Fconv(&u.Real, FmtSharp), Fconv(&u.Imag, FmtSharp|FmtSign))
} }
v.U = i v.U = i
} }
...@@ -471,30 +473,25 @@ func toint(v Val) Val { ...@@ -471,30 +473,25 @@ func toint(v Val) Val {
} }
func doesoverflow(v Val, t *Type) bool { func doesoverflow(v Val, t *Type) bool {
switch v.Ctype() { switch u := v.U.(type) {
case CTINT, CTRUNE: case *Mpint:
if !t.IsInteger() { if !t.IsInteger() {
Fatalf("overflow: %v integer constant", t) Fatalf("overflow: %v integer constant", t)
} }
if v.U.(*Mpint).Cmp(Minintval[t.Etype]) < 0 || v.U.(*Mpint).Cmp(Maxintval[t.Etype]) > 0 { return u.Cmp(Minintval[t.Etype]) < 0 || u.Cmp(Maxintval[t.Etype]) > 0
return true
}
case CTFLT: case *Mpflt:
if !t.IsFloat() { if !t.IsFloat() {
Fatalf("overflow: %v floating-point constant", t) Fatalf("overflow: %v floating-point constant", t)
} }
if v.U.(*Mpflt).Cmp(minfltval[t.Etype]) <= 0 || v.U.(*Mpflt).Cmp(maxfltval[t.Etype]) >= 0 { return u.Cmp(minfltval[t.Etype]) <= 0 || u.Cmp(maxfltval[t.Etype]) >= 0
return true
}
case CTCPLX: case *Mpcplx:
if !t.IsComplex() { if !t.IsComplex() {
Fatalf("overflow: %v complex constant", t) Fatalf("overflow: %v complex constant", t)
} }
if v.U.(*Mpcplx).Real.Cmp(minfltval[t.Etype]) <= 0 || v.U.(*Mpcplx).Real.Cmp(maxfltval[t.Etype]) >= 0 || v.U.(*Mpcplx).Imag.Cmp(minfltval[t.Etype]) <= 0 || v.U.(*Mpcplx).Imag.Cmp(maxfltval[t.Etype]) >= 0 { return u.Real.Cmp(minfltval[t.Etype]) <= 0 || u.Real.Cmp(maxfltval[t.Etype]) >= 0 ||
return true u.Imag.Cmp(minfltval[t.Etype]) <= 0 || u.Imag.Cmp(maxfltval[t.Etype]) >= 0
}
} }
return false return false
...@@ -518,21 +515,16 @@ func overflow(v Val, t *Type) { ...@@ -518,21 +515,16 @@ func overflow(v Val, t *Type) {
} }
func tostr(v Val) Val { func tostr(v Val) Val {
switch v.Ctype() { switch u := v.U.(type) {
case CTINT, CTRUNE: case *Mpint:
var i int64 = 0xFFFD var i int64 = 0xFFFD
if u := v.U.(*Mpint); u.Cmp(Minintval[TUINT32]) >= 0 && u.Cmp(Maxintval[TUINT32]) <= 0 { if u.Cmp(Minintval[TUINT32]) >= 0 && u.Cmp(Maxintval[TUINT32]) <= 0 {
i = u.Int64() i = u.Int64()
} }
v = Val{}
v.U = string(i) v.U = string(i)
case CTFLT: case *NilVal:
Yyerror("no float -> string") // Can happen because of string([]byte(nil)).
fallthrough
case CTNIL:
v = Val{}
v.U = "" v.U = ""
} }
......
...@@ -89,8 +89,9 @@ func subnode(nr *Node, ni *Node, nc *Node) { ...@@ -89,8 +89,9 @@ func subnode(nr *Node, ni *Node, nc *Node) {
t := Types[tc] t := Types[tc]
if nc.Op == OLITERAL { if nc.Op == OLITERAL {
nodfconst(nr, t, &nc.Val().U.(*Mpcplx).Real) u := nc.Val().U.(*Mpcplx)
nodfconst(ni, t, &nc.Val().U.(*Mpcplx).Imag) nodfconst(nr, t, &u.Real)
nodfconst(ni, t, &u.Imag)
return return
} }
......
...@@ -755,17 +755,13 @@ func structfield(n *Node) *Field { ...@@ -755,17 +755,13 @@ func structfield(n *Node) *Field {
f.Broke = true f.Broke = true
} }
switch n.Val().Ctype() { switch u := n.Val().U.(type) {
case CTSTR: case string:
f.Note = new(string) f.Note = &u
*f.Note = n.Val().U.(string)
default: default:
Yyerror("field annotation must be string") Yyerror("field annotation must be string")
fallthrough case nil:
// noop
case CTxxx:
f.Note = nil
} }
if n.Left != nil && n.Left.Op == ONAME { if n.Left != nil && n.Left.Op == ONAME {
......
...@@ -334,15 +334,16 @@ func Jconv(n *Node, flag FmtFlag) string { ...@@ -334,15 +334,16 @@ func Jconv(n *Node, flag FmtFlag) string {
// Fmt "%V": Values // Fmt "%V": Values
func Vconv(v Val, flag FmtFlag) string { func Vconv(v Val, flag FmtFlag) string {
switch v.Ctype() { switch u := v.U.(type) {
case CTINT: case *Mpint:
if !u.Rune {
if (flag&FmtSharp != 0) || fmtmode == FExp { if (flag&FmtSharp != 0) || fmtmode == FExp {
return Bconv(v.U.(*Mpint), FmtSharp) return Bconv(u, FmtSharp)
}
return Bconv(u, 0)
} }
return Bconv(v.U.(*Mpint), 0)
case CTRUNE: x := u.Int64()
x := v.U.(*Mpint).Int64()
if ' ' <= x && x < utf8.RuneSelf && x != '\\' && x != '\'' { if ' ' <= x && x < utf8.RuneSelf && x != '\\' && x != '\'' {
return fmt.Sprintf("'%c'", int(x)) return fmt.Sprintf("'%c'", int(x))
} }
...@@ -352,39 +353,39 @@ func Vconv(v Val, flag FmtFlag) string { ...@@ -352,39 +353,39 @@ func Vconv(v Val, flag FmtFlag) string {
if 0 <= x && x <= utf8.MaxRune { if 0 <= x && x <= utf8.MaxRune {
return fmt.Sprintf("'\\U%08x'", uint64(x)) return fmt.Sprintf("'\\U%08x'", uint64(x))
} }
return fmt.Sprintf("('\\x00' + %v)", v.U.(*Mpint)) return fmt.Sprintf("('\\x00' + %v)", u)
case CTFLT: case *Mpflt:
if (flag&FmtSharp != 0) || fmtmode == FExp { if (flag&FmtSharp != 0) || fmtmode == FExp {
return Fconv(v.U.(*Mpflt), 0) return Fconv(u, 0)
} }
return Fconv(v.U.(*Mpflt), FmtSharp) return Fconv(u, FmtSharp)
case CTCPLX: case *Mpcplx:
if (flag&FmtSharp != 0) || fmtmode == FExp { if (flag&FmtSharp != 0) || fmtmode == FExp {
return fmt.Sprintf("(%v+%vi)", &v.U.(*Mpcplx).Real, &v.U.(*Mpcplx).Imag) return fmt.Sprintf("(%v+%vi)", &u.Real, &u.Imag)
} }
if v.U.(*Mpcplx).Real.CmpFloat64(0) == 0 { if v.U.(*Mpcplx).Real.CmpFloat64(0) == 0 {
return fmt.Sprintf("%vi", Fconv(&v.U.(*Mpcplx).Imag, FmtSharp)) return fmt.Sprintf("%vi", Fconv(&u.Imag, FmtSharp))
} }
if v.U.(*Mpcplx).Imag.CmpFloat64(0) == 0 { if v.U.(*Mpcplx).Imag.CmpFloat64(0) == 0 {
return Fconv(&v.U.(*Mpcplx).Real, FmtSharp) return Fconv(&u.Real, FmtSharp)
} }
if v.U.(*Mpcplx).Imag.CmpFloat64(0) < 0 { if v.U.(*Mpcplx).Imag.CmpFloat64(0) < 0 {
return fmt.Sprintf("(%v%vi)", Fconv(&v.U.(*Mpcplx).Real, FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, FmtSharp)) return fmt.Sprintf("(%v%vi)", Fconv(&u.Real, FmtSharp), Fconv(&u.Imag, FmtSharp))
} }
return fmt.Sprintf("(%v+%vi)", Fconv(&v.U.(*Mpcplx).Real, FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, FmtSharp)) return fmt.Sprintf("(%v+%vi)", Fconv(&u.Real, FmtSharp), Fconv(&u.Imag, FmtSharp))
case CTSTR: case string:
return strconv.Quote(v.U.(string)) return strconv.Quote(u)
case CTBOOL: case bool:
if v.U.(bool) { if u {
return "true" return "true"
} }
return "false" return "false"
case CTNIL: case *NilVal:
return "nil" return "nil"
} }
......
...@@ -430,28 +430,28 @@ func Naddr(a *obj.Addr, n *Node) { ...@@ -430,28 +430,28 @@ func Naddr(a *obj.Addr, n *Node) {
if Thearch.LinkArch.Family == sys.I386 { if Thearch.LinkArch.Family == sys.I386 {
a.Width = 0 a.Width = 0
} }
switch n.Val().Ctype() { switch u := n.Val().U.(type) {
default: default:
Fatalf("naddr: const %v", Tconv(n.Type, FmtLong)) Fatalf("naddr: const %v", Tconv(n.Type, FmtLong))
case CTFLT: case *Mpflt:
a.Type = obj.TYPE_FCONST a.Type = obj.TYPE_FCONST
a.Val = n.Val().U.(*Mpflt).Float64() a.Val = u.Float64()
case CTINT, CTRUNE: case *Mpint:
a.Sym = nil a.Sym = nil
a.Type = obj.TYPE_CONST a.Type = obj.TYPE_CONST
a.Offset = n.Int64() a.Offset = u.Int64()
case CTSTR: case string:
datagostring(n.Val().U.(string), a) datagostring(u, a)
case CTBOOL: case bool:
a.Sym = nil a.Sym = nil
a.Type = obj.TYPE_CONST a.Type = obj.TYPE_CONST
a.Offset = int64(obj.Bool2int(n.Val().U.(bool))) a.Offset = int64(obj.Bool2int(u))
case CTNIL: case *NilVal:
a.Sym = nil a.Sym = nil
a.Type = obj.TYPE_CONST a.Type = obj.TYPE_CONST
a.Offset = 0 a.Offset = 0
......
...@@ -342,20 +342,23 @@ func gdata(nam *Node, nr *Node, wid int) { ...@@ -342,20 +342,23 @@ func gdata(nam *Node, nr *Node, wid int) {
switch nr.Op { switch nr.Op {
case OLITERAL: case OLITERAL:
switch nr.Val().Ctype() { switch u := nr.Val().U.(type) {
case CTCPLX: case *Mpcplx:
gdatacomplex(nam, nr.Val().U.(*Mpcplx)) gdatacomplex(nam, u)
case CTSTR: case string:
gdatastring(nam, nr.Val().U.(string)) gdatastring(nam, u)
case CTINT, CTRUNE, CTBOOL: case bool:
i, _ := nr.IntLiteral() i := int64(obj.Bool2int(u))
Linksym(nam.Sym).WriteInt(Ctxt, nam.Xoffset, wid, i) Linksym(nam.Sym).WriteInt(Ctxt, nam.Xoffset, wid, i)
case CTFLT: case *Mpint:
Linksym(nam.Sym).WriteInt(Ctxt, nam.Xoffset, wid, u.Int64())
case *Mpflt:
s := Linksym(nam.Sym) s := Linksym(nam.Sym)
f := nr.Val().U.(*Mpflt).Float64() f := u.Float64()
switch nam.Type.Etype { switch nam.Type.Etype {
case TFLOAT32: case TFLOAT32:
s.WriteFloat32(Ctxt, nam.Xoffset, float32(f)) s.WriteFloat32(Ctxt, nam.Xoffset, float32(f))
......
...@@ -3246,17 +3246,14 @@ func (p *parser) hidden_literal() *Node { ...@@ -3246,17 +3246,14 @@ func (p *parser) hidden_literal() *Node {
if p.tok == LLITERAL { if p.tok == LLITERAL {
ss := nodlit(p.val) ss := nodlit(p.val)
p.next() p.next()
switch ss.Val().Ctype() { switch u := ss.Val().U.(type) {
case CTINT, CTRUNE: case *Mpint:
ss.Val().U.(*Mpint).Neg() u.Neg()
break case *Mpflt:
case CTFLT: u.Neg()
ss.Val().U.(*Mpflt).Neg() case *Mpcplx:
break u.Real.Neg()
case CTCPLX: u.Imag.Neg()
ss.Val().U.(*Mpcplx).Real.Neg()
ss.Val().U.(*Mpcplx).Imag.Neg()
break
default: default:
Yyerror("bad negated constant") Yyerror("bad negated constant")
} }
......
...@@ -1309,28 +1309,22 @@ func addvalue(p *InitPlan, xoffset int64, n *Node) { ...@@ -1309,28 +1309,22 @@ func addvalue(p *InitPlan, xoffset int64, n *Node) {
func iszero(n *Node) bool { func iszero(n *Node) bool {
switch n.Op { switch n.Op {
case OLITERAL: case OLITERAL:
switch n.Val().Ctype() { switch u := n.Val().U.(type) {
default: default:
Dump("unexpected literal", n) Dump("unexpected literal", n)
Fatalf("iszero") Fatalf("iszero")
case *NilVal:
case CTNIL:
return true return true
case string:
case CTSTR: return u == ""
return n.Val().U.(string) == "" case bool:
return !u
case CTBOOL: case *Mpint:
return !n.Val().U.(bool) return u.CmpInt64(0) == 0
case *Mpflt:
case CTINT, CTRUNE: return u.CmpFloat64(0) == 0
return n.Val().U.(*Mpint).CmpInt64(0) == 0 case *Mpcplx:
return u.Real.CmpFloat64(0) == 0 && u.Imag.CmpFloat64(0) == 0
case CTFLT:
return n.Val().U.(*Mpflt).CmpFloat64(0) == 0
case CTCPLX:
return n.Val().U.(*Mpcplx).Real.CmpFloat64(0) == 0 && n.Val().U.(*Mpcplx).Imag.CmpFloat64(0) == 0
} }
case OARRAYLIT: case OARRAYLIT:
......
...@@ -1448,9 +1448,9 @@ func (s *state) expr(n *Node) *ssa.Value { ...@@ -1448,9 +1448,9 @@ func (s *state) expr(n *Node) *ssa.Value {
addr := s.addr(n, false) addr := s.addr(n, false)
return s.newValue2(ssa.OpLoad, n.Type, addr, s.mem()) return s.newValue2(ssa.OpLoad, n.Type, addr, s.mem())
case OLITERAL: case OLITERAL:
switch n.Val().Ctype() { switch u := n.Val().U.(type) {
case CTINT: case *Mpint:
i := n.Int64() i := u.Int64()
switch n.Type.Size() { switch n.Type.Size() {
case 1: case 1:
return s.constInt8(n.Type, int8(i)) return s.constInt8(n.Type, int8(i))
...@@ -1464,13 +1464,13 @@ func (s *state) expr(n *Node) *ssa.Value { ...@@ -1464,13 +1464,13 @@ func (s *state) expr(n *Node) *ssa.Value {
s.Fatalf("bad integer size %d", n.Type.Size()) s.Fatalf("bad integer size %d", n.Type.Size())
return nil return nil
} }
case CTSTR: case string:
if n.Val().U == "" { if u == "" {
return s.constEmptyString(n.Type) return s.constEmptyString(n.Type)
} }
return s.entryNewValue0A(ssa.OpConstString, n.Type, n.Val().U) return s.entryNewValue0A(ssa.OpConstString, n.Type, u)
case CTBOOL: case bool:
v := s.constBool(n.Val().U.(bool)) v := s.constBool(u)
// For some reason the frontend gets the line numbers of // For some reason the frontend gets the line numbers of
// CTBOOL literals totally wrong. Fix it here by grabbing // CTBOOL literals totally wrong. Fix it here by grabbing
// the line number of the enclosing AST node. // the line number of the enclosing AST node.
...@@ -1478,7 +1478,7 @@ func (s *state) expr(n *Node) *ssa.Value { ...@@ -1478,7 +1478,7 @@ func (s *state) expr(n *Node) *ssa.Value {
v.Line = s.line[len(s.line)-2] v.Line = s.line[len(s.line)-2]
} }
return v return v
case CTNIL: case *NilVal:
t := n.Type t := n.Type
switch { switch {
case t.IsSlice(): case t.IsSlice():
...@@ -1488,36 +1488,30 @@ func (s *state) expr(n *Node) *ssa.Value { ...@@ -1488,36 +1488,30 @@ func (s *state) expr(n *Node) *ssa.Value {
default: default:
return s.constNil(t) return s.constNil(t)
} }
case CTFLT: case *Mpflt:
f := n.Val().U.(*Mpflt)
switch n.Type.Size() { switch n.Type.Size() {
case 4: case 4:
return s.constFloat32(n.Type, f.Float32()) return s.constFloat32(n.Type, u.Float32())
case 8: case 8:
return s.constFloat64(n.Type, f.Float64()) return s.constFloat64(n.Type, u.Float64())
default: default:
s.Fatalf("bad float size %d", n.Type.Size()) s.Fatalf("bad float size %d", n.Type.Size())
return nil return nil
} }
case CTCPLX: case *Mpcplx:
c := n.Val().U.(*Mpcplx) r := &u.Real
r := &c.Real i := &u.Imag
i := &c.Imag
switch n.Type.Size() { switch n.Type.Size() {
case 8: case 8:
{
pt := Types[TFLOAT32] pt := Types[TFLOAT32]
return s.newValue2(ssa.OpComplexMake, n.Type, return s.newValue2(ssa.OpComplexMake, n.Type,
s.constFloat32(pt, r.Float32()), s.constFloat32(pt, r.Float32()),
s.constFloat32(pt, i.Float32())) s.constFloat32(pt, i.Float32()))
}
case 16: case 16:
{
pt := Types[TFLOAT64] pt := Types[TFLOAT64]
return s.newValue2(ssa.OpComplexMake, n.Type, return s.newValue2(ssa.OpComplexMake, n.Type,
s.constFloat64(pt, r.Float64()), s.constFloat64(pt, r.Float64()),
s.constFloat64(pt, i.Float64())) s.constFloat64(pt, i.Float64()))
}
default: default:
s.Fatalf("bad float size %d", n.Type.Size()) s.Fatalf("bad float size %d", n.Type.Size())
return nil return nil
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment