Commit 29267c21 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: add Type.ChanDir

Generated with eg.

Passes toolstash -cmp.

Change-Id: I3af35191e73a558080f777a4eed93bcec7dfe1f5
Reviewed-on: https://go-review.googlesource.com/21469
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 4ae4e81c
...@@ -547,7 +547,7 @@ func (p *exporter) typ(t *Type) { ...@@ -547,7 +547,7 @@ func (p *exporter) typ(t *Type) {
case TCHAN: case TCHAN:
p.tag(chanTag) p.tag(chanTag)
p.int(int(t.Chan)) p.int(int(t.ChanDir()))
p.typ(t.Elem()) p.typ(t.Elem())
default: default:
......
...@@ -596,7 +596,7 @@ func typefmt(t *Type, flag FmtFlag) string { ...@@ -596,7 +596,7 @@ func typefmt(t *Type, flag FmtFlag) string {
return "[]" + t.Elem().String() return "[]" + t.Elem().String()
case TCHAN: case TCHAN:
switch t.Chan { switch t.ChanDir() {
case Crecv: case Crecv:
return "<-chan " + t.Elem().String() return "<-chan " + t.Elem().String()
...@@ -604,7 +604,7 @@ func typefmt(t *Type, flag FmtFlag) string { ...@@ -604,7 +604,7 @@ func typefmt(t *Type, flag FmtFlag) string {
return "chan<- " + t.Elem().String() return "chan<- " + t.Elem().String()
} }
if t.Elem() != nil && t.Elem().IsChan() && t.Elem().Sym == nil && t.Elem().Chan == Crecv { if t.Elem() != nil && t.Elem().IsChan() && t.Elem().Sym == nil && t.Elem().ChanDir() == Crecv {
return "chan (" + t.Elem().String() + ")" return "chan (" + t.Elem().String() + ")"
} }
return "chan " + t.Elem().String() return "chan " + t.Elem().String()
...@@ -1102,7 +1102,7 @@ func exprfmt(n *Node, prec int) string { ...@@ -1102,7 +1102,7 @@ func exprfmt(n *Node, prec int) string {
if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != idealbool && n.Type != idealstring { if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != idealbool && n.Type != idealstring {
// Need parens when type begins with what might // Need parens when type begins with what might
// be misinterpreted as a unary operator: * or <-. // be misinterpreted as a unary operator: * or <-.
if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.Chan == Crecv) { if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == Crecv) {
return fmt.Sprintf("(%v)(%v)", n.Type, Vconv(n.Val(), 0)) return fmt.Sprintf("(%v)(%v)", n.Type, Vconv(n.Val(), 0))
} else { } else {
return fmt.Sprintf("%v(%v)", n.Type, Vconv(n.Val(), 0)) return fmt.Sprintf("%v(%v)", n.Type, Vconv(n.Val(), 0))
......
...@@ -58,7 +58,7 @@ func typecheckrange(n *Node) { ...@@ -58,7 +58,7 @@ func typecheckrange(n *Node) {
t2 = t.Val() t2 = t.Val()
case TCHAN: case TCHAN:
if t.Chan&Crecv == 0 { if t.ChanDir()&Crecv == 0 {
Yyerror("invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type) Yyerror("invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type)
goto out goto out
} }
......
...@@ -1143,7 +1143,7 @@ ok: ...@@ -1143,7 +1143,7 @@ ok:
ot = dcommontype(s, ot, t) ot = dcommontype(s, ot, t)
ot = dsymptr(s, ot, s1, 0) ot = dsymptr(s, ot, s1, 0)
ot = duintptr(s, ot, uint64(t.Chan)) ot = duintptr(s, ot, uint64(t.ChanDir()))
ot = dextratype(s, ot, t, 0) ot = dextratype(s, ot, t, 0)
case TFUNC: case TFUNC:
......
...@@ -721,7 +721,7 @@ func eqtype1(t1, t2 *Type, assumedEqual map[typePair]struct{}) bool { ...@@ -721,7 +721,7 @@ func eqtype1(t1, t2 *Type, assumedEqual map[typePair]struct{}) bool {
} }
case TCHAN: case TCHAN:
if t1.Chan != t2.Chan { if t1.ChanDir() != t2.ChanDir() {
return false return false
} }
...@@ -844,7 +844,7 @@ func assignop(src *Type, dst *Type, why *string) Op { ...@@ -844,7 +844,7 @@ func assignop(src *Type, dst *Type, why *string) Op {
// 4. src is a bidirectional channel value, dst is a channel type, // 4. src is a bidirectional channel value, dst is a channel type,
// src and dst have identical element types, and // src and dst have identical element types, and
// either src or dst is not a named type. // either src or dst is not a named type.
if src.IsChan() && src.Chan == Cboth && dst.IsChan() { if src.IsChan() && src.ChanDir() == Cboth && dst.IsChan() {
if Eqtype(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) { if Eqtype(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) {
return OCONVNOP return OCONVNOP
} }
......
...@@ -817,8 +817,8 @@ func (t *Type) cmp(x *Type) ssa.Cmp { ...@@ -817,8 +817,8 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
} }
case TCHAN: case TCHAN:
if t.Chan != x.Chan { if t.ChanDir() != x.ChanDir() {
return cmpForNe(t.Chan < x.Chan) return cmpForNe(t.ChanDir() < x.ChanDir())
} }
default: default:
...@@ -955,6 +955,13 @@ func (t *Type) SetNumElem(n int64) { ...@@ -955,6 +955,13 @@ func (t *Type) SetNumElem(n int64) {
t.Bound = n t.Bound = n
} }
// ChanDir returns the direction of a channel type t.
// The direction will be one of Crecv, Csend, or Cboth.
func (t *Type) ChanDir() uint8 {
t.wantEtype(TCHAN)
return t.Chan
}
func (t *Type) IsMemory() bool { return false } func (t *Type) IsMemory() bool { return false }
func (t *Type) IsFlags() bool { return false } func (t *Type) IsFlags() bool { return false }
func (t *Type) IsVoid() bool { return false } func (t *Type) IsVoid() bool { return false }
......
...@@ -1048,7 +1048,7 @@ OpSwitch: ...@@ -1048,7 +1048,7 @@ OpSwitch:
return n return n
} }
if t.Chan&Crecv == 0 { if t.ChanDir()&Crecv == 0 {
Yyerror("invalid operation: %v (receive from send-only type %v)", n, t) Yyerror("invalid operation: %v (receive from send-only type %v)", n, t)
n.Type = nil n.Type = nil
return n return n
...@@ -1075,7 +1075,7 @@ OpSwitch: ...@@ -1075,7 +1075,7 @@ OpSwitch:
return n return n
} }
if t.Chan&Csend == 0 { if t.ChanDir()&Csend == 0 {
Yyerror("invalid operation: %v (send to receive-only type %v)", n, t) Yyerror("invalid operation: %v (send to receive-only type %v)", n, t)
n.Type = nil n.Type = nil
return n return n
...@@ -1528,7 +1528,7 @@ OpSwitch: ...@@ -1528,7 +1528,7 @@ OpSwitch:
return n return n
} }
if t.Chan&Csend == 0 { if t.ChanDir()&Csend == 0 {
Yyerror("invalid operation: %v (cannot close receive-only channel)", n) Yyerror("invalid operation: %v (cannot close receive-only channel)", n)
n.Type = nil n.Type = nil
return n return n
......
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