diff options
author | Dan Scales <danscales@google.com> | 2021-03-24 14:50:02 -0700 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-03-25 23:23:10 +0000 |
commit | b587b050ca55661120912b5a1d6071a1922ad0ea (patch) | |
tree | beec6285bd589315d1e82755b8bd5472c4c84371 /src/cmd/compile/internal/typecheck/typecheck.go | |
parent | 374b1904750931ed09d342e3c4c6e01fdb2802aa (diff) | |
download | go-b587b050ca55661120912b5a1d6071a1922ad0ea.tar.gz go-b587b050ca55661120912b5a1d6071a1922ad0ea.zip |
cmd/compile: add transform functions for OXDOT and builtins
Pull out the tranformation part of the typechecking functions for:
- selector expressions (OXDOT)
- calls to builtin functions (which go through the typechecker loop
twice, once for the call and once for each different kind of
builtin).
Some of the transformation functions create new nodes that should have
the same type as the original node. For consistency, now each of the
transformation functions requires that the node passed in has its type
and typecheck flag set. If the transformation function replaces or adds
new nodes, it will set the type and typecheck flag for those new nodes.
As usual, passes all the gotests, even with -G=3 enabled.
Change-Id: Ic48b0ce5f58425f4a358afa78315bfc7c28066c4
Reviewed-on: https://go-review.googlesource.com/c/go/+/304729
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/typecheck/typecheck.go')
-rw-r--r-- | src/cmd/compile/internal/typecheck/typecheck.go | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go index f06a8623d0..54f7cd9efa 100644 --- a/src/cmd/compile/internal/typecheck/typecheck.go +++ b/src/cmd/compile/internal/typecheck/typecheck.go @@ -1058,7 +1058,11 @@ func needTwoArgs(n *ir.CallExpr) (ir.Node, ir.Node, bool) { return n.Args[0], n.Args[1], true } -func lookdot1(errnode ir.Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field { +// Lookdot1 looks up the specified method s in the list fs of methods, returning +// the matching field or nil. If dostrcmp is 0, it matches the symbols. If +// dostrcmp is 1, it matches by name exactly. If dostrcmp is 2, it matches names +// with case folding. +func Lookdot1(errnode ir.Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field { var r *types.Field for _, f := range fs.Slice() { if dostrcmp != 0 && f.Sym.Name == s.Name { @@ -1123,9 +1127,9 @@ func typecheckMethodExpr(n *ir.SelectorExpr) (res ir.Node) { } s := n.Sel - m := lookdot1(n, s, t, ms, 0) + m := Lookdot1(n, s, t, ms, 0) if m == nil { - if lookdot1(n, s, t, ms, 1) != nil { + if Lookdot1(n, s, t, ms, 1) != nil { base.Errorf("%v undefined (cannot refer to unexported method %v)", n, s) } else if _, ambig := dotpath(s, t, nil, false); ambig { base.Errorf("%v undefined (ambiguous selector)", n) // method or field @@ -1155,20 +1159,26 @@ func derefall(t *types.Type) *types.Type { return t } -func lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field { +// Lookdot looks up field or method n.Sel in the type t and returns the matching +// field. It transforms the op of node n to ODOTINTER or ODOTMETH, if appropriate. +// It also may add a StarExpr node to n.X as needed for access to non-pointer +// methods. If dostrcmp is 0, it matches the field/method with the exact symbol +// as n.Sel (appropriate for exported fields). If dostrcmp is 1, it matches by name +// exactly. If dostrcmp is 2, it matches names with case folding. +func Lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field { s := n.Sel types.CalcSize(t) var f1 *types.Field if t.IsStruct() || t.IsInterface() { - f1 = lookdot1(n, s, t, t.Fields(), dostrcmp) + f1 = Lookdot1(n, s, t, t.Fields(), dostrcmp) } var f2 *types.Field if n.X.Type() == t || n.X.Type().Sym() == nil { mt := types.ReceiverBaseType(t) if mt != nil { - f2 = lookdot1(n, s, mt, mt.Methods(), dostrcmp) + f2 = Lookdot1(n, s, mt, mt.Methods(), dostrcmp) } } @@ -1181,7 +1191,7 @@ func lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field { base.Errorf("%v is both field and method", n.Sel) } if f1.Offset == types.BADWIDTH { - base.Fatalf("lookdot badwidth t=%v, f1=%v@%p", t, f1, f1) + base.Fatalf("Lookdot badwidth t=%v, f1=%v@%p", t, f1, f1) } n.Selection = f1 n.SetType(f1.Type) |