From: Keith Randall Date: Fri, 2 Sep 2022 20:50:10 +0000 (-0700) Subject: cmd/compile: abstract type type+value obtained from types2 X-Git-Tag: go1.20rc1~905 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b52783c1e9673793da85dc7a9fb433d033da2e10;p=gostls13.git cmd/compile: abstract type type+value obtained from types2 In preparation for encoding it in a more efficient way. Change-Id: I299dd2befc3d07107a1b7b49225bbb9f2e48a343 Reviewed-on: https://go-review.googlesource.com/c/go/+/432896 Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot Run-TryBot: Keith Randall Reviewed-by: Matthew Dempsky --- diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go index 54b07c39f4..f391339c36 100644 --- a/src/cmd/compile/internal/noder/expr.go +++ b/src/cmd/compile/internal/noder/expr.go @@ -27,10 +27,7 @@ func (g *irgen) expr(expr syntax.Expr) ir.Node { return ir.BlankNode } - tv, ok := g.info.Types[expr] - if !ok { - base.FatalfAt(g.pos(expr), "missing type for %v (%T)", expr, expr) - } + tv := g.typeAndValue(expr) switch { case tv.IsBuiltin(): // Qualified builtins, such as unsafe.Add and unsafe.Slice. @@ -105,8 +102,7 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node { case *syntax.IndexExpr: args := unpackListExpr(expr.Index) if len(args) == 1 { - tv, ok := g.info.Types[args[0]] - assert(ok) + tv := g.typeAndValue(args[0]) if tv.IsValue() { // This is just a normal index expression n := Index(pos, g.typ(typ), g.expr(expr.X), g.expr(args[0])) diff --git a/src/cmd/compile/internal/noder/irgen.go b/src/cmd/compile/internal/noder/irgen.go index bf471e08fa..e867594620 100644 --- a/src/cmd/compile/internal/noder/irgen.go +++ b/src/cmd/compile/internal/noder/irgen.go @@ -390,3 +390,19 @@ func (g *irgen) unhandled(what string, p poser) { func (g *irgen) delayTransform() bool { return g.topFuncIsGeneric } + +func (g *irgen) typeAndValue(x syntax.Expr) types2.TypeAndValue { + tv, ok := g.info.Types[x] + if !ok { + base.FatalfAt(g.pos(x), "missing type for %v (%T)", x, x) + } + return tv +} + +func (g *irgen) type2(x syntax.Expr) types2.Type { + tv, ok := g.info.Types[x] + if !ok { + base.FatalfAt(g.pos(x), "missing type for %v (%T)", x, x) + } + return tv.Type +} diff --git a/src/cmd/compile/internal/noder/validate.go b/src/cmd/compile/internal/noder/validate.go index dcacae7480..baf8bd3076 100644 --- a/src/cmd/compile/internal/noder/validate.go +++ b/src/cmd/compile/internal/noder/validate.go @@ -53,7 +53,7 @@ func (g *irgen) match(t1 *types.Type, t2 types2.Type, hasOK bool) bool { func (g *irgen) validate(n syntax.Node) { switch n := n.(type) { case *syntax.CallExpr: - tv := g.info.Types[n.Fun] + tv := g.typeAndValue(n.Fun) if tv.IsBuiltin() { fun := n.Fun for { @@ -81,7 +81,7 @@ func (g *irgen) validateBuiltin(name string, call *syntax.CallExpr) { // Check that types2+gcSizes calculates sizes the same // as cmd/compile does. - tv := g.info.Types[call] + tv := g.typeAndValue(call) if !tv.IsValue() { base.FatalfAt(g.pos(call), "expected a value") } @@ -106,9 +106,9 @@ func (g *irgen) validateBuiltin(name string, call *syntax.CallExpr) { func (g *irgen) unsafeExpr(name string, arg syntax.Expr) int64 { switch name { case "Alignof": - return g.typ(g.info.Types[arg].Type).Alignment() + return g.typ(g.type2(arg)).Alignment() case "Sizeof": - return g.typ(g.info.Types[arg].Type).Size() + return g.typ(g.type2(arg)).Size() } // Offsetof @@ -116,7 +116,7 @@ func (g *irgen) unsafeExpr(name string, arg syntax.Expr) int64 { sel := arg.(*syntax.SelectorExpr) selection := g.info.Selections[sel] - typ := g.typ(g.info.Types[sel.X].Type) + typ := g.typ(g.type2(sel.X)) typ = deref(typ) var offset int64 diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index 198bae7190..b39a57a13f 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -120,12 +120,21 @@ func (pw *pkgWriter) unexpected(what string, p poser) { pw.fatalf(p, "unexpected %s: %v (%T)", what, p, p) } -// typeOf returns the Type of the given value expression. -func (pw *pkgWriter) typeOf(expr syntax.Expr) types2.Type { - tv, ok := pw.info.Types[expr] +func (pw *pkgWriter) typeAndValue(x syntax.Expr) types2.TypeAndValue { + tv, ok := pw.info.Types[x] if !ok { - pw.fatalf(expr, "missing Types entry: %v", syntax.String(expr)) + pw.fatalf(x, "missing Types entry: %v", syntax.String(x)) } + return tv +} +func (pw *pkgWriter) maybeTypeAndValue(x syntax.Expr) (types2.TypeAndValue, bool) { + tv, ok := pw.info.Types[x] + return tv, ok +} + +// typeOf returns the Type of the given value expression. +func (pw *pkgWriter) typeOf(expr syntax.Expr) types2.Type { + tv := pw.typeAndValue(expr) if !tv.IsValue() { pw.fatalf(expr, "expected value: %v", syntax.String(expr)) } @@ -811,8 +820,7 @@ func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj { // // TODO(mdempsky): Document how this differs from exprType. func (w *writer) typExpr(expr syntax.Expr) { - tv, ok := w.p.info.Types[expr] - assert(ok) + tv := w.p.typeAndValue(expr) assert(tv.IsType()) w.typ(tv.Type) } @@ -1533,7 +1541,7 @@ func (w *writer) switchStmt(stmt *syntax.SwitchStmt) { if iface != nil { w.Len(len(cases)) for _, cas := range cases { - if w.Bool(isNil(w.p.info, cas)) { + if w.Bool(isNil(w.p, cas)) { continue } w.exprType(iface, cas) @@ -1598,10 +1606,10 @@ func (w *writer) expr(expr syntax.Expr) { expr = unparen(expr) // skip parens; unneeded after typecheck - obj, inst := lookupObj(w.p.info, expr) + obj, inst := lookupObj(w.p, expr) targs := inst.TypeArgs - if tv, ok := w.p.info.Types[expr]; ok { + if tv, ok := w.p.maybeTypeAndValue(expr); ok { if tv.IsType() { w.p.fatalf(expr, "unexpected type expression %v", syntax.String(expr)) } @@ -1698,8 +1706,7 @@ func (w *writer) expr(expr syntax.Expr) { case types2.MethodExpr: w.Code(exprMethodExpr) - tv, ok := w.p.info.Types[expr.X] - assert(ok) + tv := w.p.typeAndValue(expr.X) assert(tv.IsType()) index := sel.Index() @@ -1793,8 +1800,7 @@ func (w *writer) expr(expr syntax.Expr) { w.implicitConvExpr(commonType, expr.Y) case *syntax.CallExpr: - tv, ok := w.p.info.Types[expr.Fun] - assert(ok) + tv := w.p.typeAndValue(expr.Fun) if tv.IsType() { assert(len(expr.ArgList) == 1) assert(!expr.HasDots) @@ -1804,7 +1810,7 @@ func (w *writer) expr(expr syntax.Expr) { var rtype types2.Type if tv.IsBuiltin() { - switch obj, _ := lookupObj(w.p.info, expr.Fun); obj.Name() { + switch obj, _ := lookupObj(w.p, expr.Fun); obj.Name() { case "make": assert(len(expr.ArgList) >= 1) assert(!expr.HasDots) @@ -1870,7 +1876,7 @@ func (w *writer) expr(expr syntax.Expr) { w.Bool(false) // not a method call (i.e., normal function call) - if obj, inst := lookupObj(w.p.info, fun); w.Bool(obj != nil && inst.TypeArgs.Len() != 0) { + if obj, inst := lookupObj(w.p, fun); w.Bool(obj != nil && inst.TypeArgs.Len() != 0) { obj := obj.(*types2.Func) w.pos(fun) @@ -2244,8 +2250,7 @@ func (w *writer) convRTTI(src, dst types2.Type) { func (w *writer) exprType(iface types2.Type, typ syntax.Expr) { base.Assertf(iface == nil || isInterface(iface), "%v must be nil or an interface type", iface) - tv, ok := w.p.info.Types[typ] - assert(ok) + tv := w.p.typeAndValue(typ) assert(tv.IsType()) w.Sync(pkgbits.SyncExprType) @@ -2597,12 +2602,11 @@ func isGlobal(obj types2.Object) bool { // lookupObj returns the object that expr refers to, if any. If expr // is an explicit instantiation of a generic object, then the instance // object is returned as well. -func lookupObj(info *types2.Info, expr syntax.Expr) (obj types2.Object, inst types2.Instance) { +func lookupObj(p *pkgWriter, expr syntax.Expr) (obj types2.Object, inst types2.Instance) { if index, ok := expr.(*syntax.IndexExpr); ok { args := unpackListExpr(index.Index) if len(args) == 1 { - tv, ok := info.Types[args[0]] - assert(ok) + tv := p.typeAndValue(args[0]) if tv.IsValue() { return // normal index expression } @@ -2613,15 +2617,15 @@ func lookupObj(info *types2.Info, expr syntax.Expr) (obj types2.Object, inst typ // Strip package qualifier, if present. if sel, ok := expr.(*syntax.SelectorExpr); ok { - if !isPkgQual(info, sel) { + if !isPkgQual(p.info, sel) { return // normal selector expression } expr = sel.Sel } if name, ok := expr.(*syntax.Name); ok { - obj = info.Uses[name] - inst = info.Instances[name] + obj = p.info.Uses[name] + inst = p.info.Instances[name] } return } @@ -2636,24 +2640,10 @@ func isPkgQual(info *types2.Info, sel *syntax.SelectorExpr) bool { return false } -// isMultiValueExpr reports whether expr is a function call expression -// that yields multiple values. -func isMultiValueExpr(info *types2.Info, expr syntax.Expr) bool { - tv, ok := info.Types[expr] - assert(ok) - assert(tv.IsValue()) - if tuple, ok := tv.Type.(*types2.Tuple); ok { - assert(tuple.Len() > 1) - return true - } - return false -} - // isNil reports whether expr is a (possibly parenthesized) reference // to the predeclared nil value. -func isNil(info *types2.Info, expr syntax.Expr) bool { - tv, ok := info.Types[expr] - assert(ok) +func isNil(p *pkgWriter, expr syntax.Expr) bool { + tv := p.typeAndValue(expr) return tv.IsNil() }