1
0
mirror of https://github.com/golang/go synced 2024-11-17 20:54:48 -07:00

cmd/compile: construct more IR nodes as typed

As of this CL, all OLITERAL, OLINKSYMOFFSET, ONIL, and OTYPE nodes are
constructed as typed and typechecked.

Change-Id: I39b2ad772a9b0419c701890a505a0949f9ea456e
Reviewed-on: https://go-review.googlesource.com/c/go/+/520795
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2023-08-18 00:54:28 -07:00 committed by Gopher Robot
parent ca858a43f4
commit 8789b5d72f
6 changed files with 22 additions and 43 deletions

View File

@ -106,9 +106,8 @@ func NewBasicLit(pos src.XPos, val constant.Value) Node {
n := &BasicLit{val: val} n := &BasicLit{val: val}
n.op = OLITERAL n.op = OLITERAL
n.pos = pos n.pos = pos
if k := val.Kind(); k != constant.Unknown { n.SetType(idealType(val.Kind()))
n.SetType(idealType(k)) n.SetTypecheck(1)
}
return n return n
} }
@ -432,15 +431,19 @@ func (n *MakeExpr) SetOp(op Op) {
} }
// A NilExpr represents the predefined untyped constant nil. // A NilExpr represents the predefined untyped constant nil.
// (It may be copied and assigned a type, though.)
type NilExpr struct { type NilExpr struct {
miniExpr miniExpr
} }
func NewNilExpr(pos src.XPos) *NilExpr { func NewNilExpr(pos src.XPos, typ *types.Type) *NilExpr {
if typ == nil {
base.FatalfAt(pos, "missing type")
}
n := &NilExpr{} n := &NilExpr{}
n.pos = pos n.pos = pos
n.op = ONIL n.op = ONIL
n.SetType(typ)
n.SetTypecheck(1)
return n return n
} }
@ -498,9 +501,13 @@ type LinksymOffsetExpr struct {
} }
func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr { func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr {
if typ == nil {
base.FatalfAt(pos, "nil type")
}
n := &LinksymOffsetExpr{Linksym: lsym, Offset_: offset} n := &LinksymOffsetExpr{Linksym: lsym, Offset_: offset}
n.typ = typ n.typ = typ
n.op = OLINKSYMOFFSET n.op = OLINKSYMOFFSET
n.SetTypecheck(1)
return n return n
} }

View File

@ -66,7 +66,7 @@ func FixValue(typ *types.Type, val constant.Value) constant.Value {
} }
func Nil(pos src.XPos, typ *types.Type) ir.Node { func Nil(pos src.XPos, typ *types.Type) ir.Node {
return typed(typ, ir.NewNilExpr(pos)) return ir.NewNilExpr(pos, typ)
} }
// Expressions // Expressions

View File

@ -17,18 +17,15 @@ import (
// MakeDotArgs package all the arguments that match a ... T parameter into a []T. // MakeDotArgs package all the arguments that match a ... T parameter into a []T.
func MakeDotArgs(pos src.XPos, typ *types.Type, args []ir.Node) ir.Node { func MakeDotArgs(pos src.XPos, typ *types.Type, args []ir.Node) ir.Node {
var n ir.Node
if len(args) == 0 { if len(args) == 0 {
n = ir.NewNilExpr(pos) return ir.NewNilExpr(pos, typ)
n.SetType(typ)
} else {
args = append([]ir.Node(nil), args...)
lit := ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, args)
lit.SetImplicit(true)
n = lit
} }
n = Expr(n) args = append([]ir.Node(nil), args...)
lit := ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, args)
lit.SetImplicit(true)
n := Expr(lit)
if n.Type() == nil { if n.Type() == nil {
base.FatalfAt(pos, "mkdotargslice: typecheck failed") base.FatalfAt(pos, "mkdotargslice: typecheck failed")
} }

View File

@ -120,9 +120,7 @@ func LinksymAddr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *ir.AddrExpr {
} }
func NodNil() ir.Node { func NodNil() ir.Node {
n := ir.NewNilExpr(base.Pos) return ir.NewNilExpr(base.Pos, types.Types[types.TNIL])
n.SetType(types.Types[types.TNIL])
return n
} }
// AddImplicitDots finds missing fields in obj.field that // AddImplicitDots finds missing fields in obj.field that

View File

@ -177,7 +177,7 @@ func typecheck(n ir.Node, top int) (res ir.Node) {
// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed. // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
if n.Typecheck() == 1 || n.Typecheck() == 3 { if n.Typecheck() == 1 || n.Typecheck() == 3 {
switch n.Op() { switch n.Op() {
case ir.ONAME, ir.OTYPE, ir.OLITERAL: case ir.ONAME:
break break
default: default:
@ -230,22 +230,6 @@ func typecheck1(n ir.Node, top int) ir.Node {
base.Fatalf("typecheck %v", n.Op()) base.Fatalf("typecheck %v", n.Op())
panic("unreachable") panic("unreachable")
case ir.OLITERAL:
if n.Sym() == nil && n.Type() == nil {
base.Fatalf("literal missing type: %v", n)
}
return n
case ir.ONIL:
return n
// names
case ir.ONONAME:
// Note: adderrorname looks for this string and
// adds context about the outer expression
base.FatalfAt(n.Pos(), "undefined: %v", n.Sym())
panic("unreachable")
case ir.ONAME: case ir.ONAME:
n := n.(*ir.Name) n := n.(*ir.Name)
if n.BuiltinOp != 0 { if n.BuiltinOp != 0 {
@ -267,14 +251,6 @@ func typecheck1(n ir.Node, top int) ir.Node {
} }
return n return n
case ir.OLINKSYMOFFSET:
// type already set
return n
// types (ODEREF is with exprs)
case ir.OTYPE:
return n
// type or expr // type or expr
case ir.ODEREF: case ir.ODEREF:
n := n.(*ir.StarExpr) n := n.(*ir.StarExpr)

View File

@ -70,6 +70,7 @@ func InitUniverse() {
types.InitTypes(func(sym *types.Sym, typ *types.Type) types.Object { types.InitTypes(func(sym *types.Sym, typ *types.Type) types.Object {
n := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, sym) n := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, sym)
n.SetType(typ) n.SetType(typ)
n.SetTypecheck(1)
sym.Def = n sym.Def = n
return n return n
}) })