n := &BasicLit{val: val}
n.op = OLITERAL
n.pos = pos
- if k := val.Kind(); k != constant.Unknown {
- n.SetType(idealType(k))
- }
+ n.SetType(idealType(val.Kind()))
+ n.SetTypecheck(1)
return n
}
}
// A NilExpr represents the predefined untyped constant nil.
-// (It may be copied and assigned a type, though.)
type NilExpr struct {
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.pos = pos
n.op = ONIL
+ n.SetType(typ)
+ n.SetTypecheck(1)
return n
}
}
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.typ = typ
n.op = OLINKSYMOFFSET
+ n.SetTypecheck(1)
return n
}
}
func Nil(pos src.XPos, typ *types.Type) ir.Node {
- return typed(typ, ir.NewNilExpr(pos))
+ return ir.NewNilExpr(pos, typ)
}
// Expressions
// 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 {
- var n ir.Node
if len(args) == 0 {
- n = ir.NewNilExpr(pos)
- n.SetType(typ)
- } else {
- args = append([]ir.Node(nil), args...)
- lit := ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, args)
- lit.SetImplicit(true)
- n = lit
+ return ir.NewNilExpr(pos, typ)
}
- 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 {
base.FatalfAt(pos, "mkdotargslice: typecheck failed")
}
}
func NodNil() ir.Node {
- n := ir.NewNilExpr(base.Pos)
- n.SetType(types.Types[types.TNIL])
- return n
+ return ir.NewNilExpr(base.Pos, types.Types[types.TNIL])
}
// AddImplicitDots finds missing fields in obj.field that
// But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
if n.Typecheck() == 1 || n.Typecheck() == 3 {
switch n.Op() {
- case ir.ONAME, ir.OTYPE, ir.OLITERAL:
+ case ir.ONAME:
break
default:
base.Fatalf("typecheck %v", n.Op())
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:
n := n.(*ir.Name)
if n.BuiltinOp != 0 {
}
return n
- case ir.OLINKSYMOFFSET:
- // type already set
- return n
-
- // types (ODEREF is with exprs)
- case ir.OTYPE:
- return n
-
// type or expr
case ir.ODEREF:
n := n.(*ir.StarExpr)
types.InitTypes(func(sym *types.Sym, typ *types.Type) types.Object {
n := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, sym)
n.SetType(typ)
+ n.SetTypecheck(1)
sym.Def = n
return n
})