Source file src/cmd/compile/internal/ir/expr.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ir
     6  
     7  import (
     8  	"bytes"
     9  	"cmd/compile/internal/base"
    10  	"cmd/compile/internal/types"
    11  	"cmd/internal/obj"
    12  	"cmd/internal/src"
    13  	"fmt"
    14  	"go/constant"
    15  	"go/token"
    16  )
    17  
    18  // An Expr is a Node that can appear as an expression.
    19  type Expr interface {
    20  	Node
    21  	isExpr()
    22  }
    23  
    24  // A miniExpr is a miniNode with extra fields common to expressions.
    25  // TODO(rsc): Once we are sure about the contents, compact the bools
    26  // into a bit field and leave extra bits available for implementations
    27  // embedding miniExpr. Right now there are ~60 unused bits sitting here.
    28  type miniExpr struct {
    29  	miniNode
    30  	typ   *types.Type
    31  	init  Nodes // TODO(rsc): Don't require every Node to have an init
    32  	flags bitset8
    33  }
    34  
    35  const (
    36  	miniExprNonNil = 1 << iota
    37  	miniExprTransient
    38  	miniExprBounded
    39  	miniExprImplicit // for use by implementations; not supported by every Expr
    40  	miniExprCheckPtr
    41  )
    42  
    43  func (*miniExpr) isExpr() {}
    44  
    45  func (n *miniExpr) Type() *types.Type     { return n.typ }
    46  func (n *miniExpr) SetType(x *types.Type) { n.typ = x }
    47  func (n *miniExpr) NonNil() bool          { return n.flags&miniExprNonNil != 0 }
    48  func (n *miniExpr) MarkNonNil()           { n.flags |= miniExprNonNil }
    49  func (n *miniExpr) Transient() bool       { return n.flags&miniExprTransient != 0 }
    50  func (n *miniExpr) SetTransient(b bool)   { n.flags.set(miniExprTransient, b) }
    51  func (n *miniExpr) Bounded() bool         { return n.flags&miniExprBounded != 0 }
    52  func (n *miniExpr) SetBounded(b bool)     { n.flags.set(miniExprBounded, b) }
    53  func (n *miniExpr) Init() Nodes           { return n.init }
    54  func (n *miniExpr) PtrInit() *Nodes       { return &n.init }
    55  func (n *miniExpr) SetInit(x Nodes)       { n.init = x }
    56  
    57  // An AddStringExpr is a string concatenation Expr[0] + Exprs[1] + ... + Expr[len(Expr)-1].
    58  type AddStringExpr struct {
    59  	miniExpr
    60  	List     Nodes
    61  	Prealloc *Name
    62  }
    63  
    64  func NewAddStringExpr(pos src.XPos, list []Node) *AddStringExpr {
    65  	n := &AddStringExpr{}
    66  	n.pos = pos
    67  	n.op = OADDSTR
    68  	n.List = list
    69  	return n
    70  }
    71  
    72  // An AddrExpr is an address-of expression &X.
    73  // It may end up being a normal address-of or an allocation of a composite literal.
    74  type AddrExpr struct {
    75  	miniExpr
    76  	X        Node
    77  	Prealloc *Name // preallocated storage if any
    78  }
    79  
    80  func NewAddrExpr(pos src.XPos, x Node) *AddrExpr {
    81  	n := &AddrExpr{X: x}
    82  	n.op = OADDR
    83  	n.pos = pos
    84  	return n
    85  }
    86  
    87  func (n *AddrExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
    88  func (n *AddrExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
    89  
    90  func (n *AddrExpr) SetOp(op Op) {
    91  	switch op {
    92  	default:
    93  		panic(n.no("SetOp " + op.String()))
    94  	case OADDR, OPTRLIT:
    95  		n.op = op
    96  	}
    97  }
    98  
    99  // A BasicLit is a literal of basic type.
   100  type BasicLit struct {
   101  	miniExpr
   102  	val constant.Value
   103  }
   104  
   105  func NewBasicLit(pos src.XPos, val constant.Value) Node {
   106  	n := &BasicLit{val: val}
   107  	n.op = OLITERAL
   108  	n.pos = pos
   109  	if k := val.Kind(); k != constant.Unknown {
   110  		n.SetType(idealType(k))
   111  	}
   112  	return n
   113  }
   114  
   115  func (n *BasicLit) Val() constant.Value       { return n.val }
   116  func (n *BasicLit) SetVal(val constant.Value) { n.val = val }
   117  
   118  // A BinaryExpr is a binary expression X Op Y,
   119  // or Op(X, Y) for builtin functions that do not become calls.
   120  type BinaryExpr struct {
   121  	miniExpr
   122  	X Node
   123  	Y Node
   124  }
   125  
   126  func NewBinaryExpr(pos src.XPos, op Op, x, y Node) *BinaryExpr {
   127  	n := &BinaryExpr{X: x, Y: y}
   128  	n.pos = pos
   129  	n.SetOp(op)
   130  	return n
   131  }
   132  
   133  func (n *BinaryExpr) SetOp(op Op) {
   134  	switch op {
   135  	default:
   136  		panic(n.no("SetOp " + op.String()))
   137  	case OADD, OADDSTR, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
   138  		OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
   139  		OCOPY, OCOMPLEX, OUNSAFEADD, OUNSAFESLICE,
   140  		OEFACE:
   141  		n.op = op
   142  	}
   143  }
   144  
   145  // A CallExpr is a function call X(Args).
   146  type CallExpr struct {
   147  	miniExpr
   148  	origNode
   149  	X         Node
   150  	Args      Nodes
   151  	KeepAlive []*Name // vars to be kept alive until call returns
   152  	IsDDD     bool
   153  	NoInline  bool
   154  }
   155  
   156  func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
   157  	n := &CallExpr{X: fun}
   158  	n.pos = pos
   159  	n.orig = n
   160  	n.SetOp(op)
   161  	n.Args = args
   162  	return n
   163  }
   164  
   165  func (*CallExpr) isStmt() {}
   166  
   167  func (n *CallExpr) SetOp(op Op) {
   168  	switch op {
   169  	default:
   170  		panic(n.no("SetOp " + op.String()))
   171  	case OAPPEND,
   172  		OCALL, OCALLFUNC, OCALLINTER, OCALLMETH,
   173  		ODELETE,
   174  		OGETG, OGETCALLERPC, OGETCALLERSP,
   175  		OMAKE, OPRINT, OPRINTN,
   176  		ORECOVER, ORECOVERFP:
   177  		n.op = op
   178  	}
   179  }
   180  
   181  // A ClosureExpr is a function literal expression.
   182  type ClosureExpr struct {
   183  	miniExpr
   184  	Func     *Func `mknode:"-"`
   185  	Prealloc *Name
   186  	IsGoWrap bool // whether this is wrapper closure of a go statement
   187  }
   188  
   189  // Deprecated: Use NewClosureFunc instead.
   190  func NewClosureExpr(pos src.XPos, fn *Func) *ClosureExpr {
   191  	n := &ClosureExpr{Func: fn}
   192  	n.op = OCLOSURE
   193  	n.pos = pos
   194  	return n
   195  }
   196  
   197  // A CompLitExpr is a composite literal Type{Vals}.
   198  // Before type-checking, the type is Ntype.
   199  type CompLitExpr struct {
   200  	miniExpr
   201  	origNode
   202  	Ntype    Ntype
   203  	List     Nodes // initialized values
   204  	Prealloc *Name
   205  	Len      int64 // backing array length for OSLICELIT
   206  }
   207  
   208  func NewCompLitExpr(pos src.XPos, op Op, typ Ntype, list []Node) *CompLitExpr {
   209  	n := &CompLitExpr{Ntype: typ}
   210  	n.pos = pos
   211  	n.SetOp(op)
   212  	n.List = list
   213  	n.orig = n
   214  	return n
   215  }
   216  
   217  func (n *CompLitExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   218  func (n *CompLitExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   219  
   220  func (n *CompLitExpr) SetOp(op Op) {
   221  	switch op {
   222  	default:
   223  		panic(n.no("SetOp " + op.String()))
   224  	case OARRAYLIT, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OSLICELIT:
   225  		n.op = op
   226  	}
   227  }
   228  
   229  type ConstExpr struct {
   230  	miniExpr
   231  	origNode
   232  	val constant.Value
   233  }
   234  
   235  func NewConstExpr(val constant.Value, orig Node) Node {
   236  	n := &ConstExpr{val: val}
   237  	n.op = OLITERAL
   238  	n.pos = orig.Pos()
   239  	n.orig = orig
   240  	n.SetType(orig.Type())
   241  	n.SetTypecheck(orig.Typecheck())
   242  	n.SetDiag(orig.Diag())
   243  	return n
   244  }
   245  
   246  func (n *ConstExpr) Sym() *types.Sym     { return n.orig.Sym() }
   247  func (n *ConstExpr) Val() constant.Value { return n.val }
   248  
   249  // A ConvExpr is a conversion Type(X).
   250  // It may end up being a value or a type.
   251  type ConvExpr struct {
   252  	miniExpr
   253  	X           Node
   254  	NonEscaping bool // The allocation needed for the conversion to interface is known not to escape
   255  }
   256  
   257  func NewConvExpr(pos src.XPos, op Op, typ *types.Type, x Node) *ConvExpr {
   258  	n := &ConvExpr{X: x}
   259  	n.pos = pos
   260  	n.typ = typ
   261  	n.SetOp(op)
   262  	return n
   263  }
   264  
   265  func (n *ConvExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   266  func (n *ConvExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   267  func (n *ConvExpr) CheckPtr() bool     { return n.flags&miniExprCheckPtr != 0 }
   268  func (n *ConvExpr) SetCheckPtr(b bool) { n.flags.set(miniExprCheckPtr, b) }
   269  
   270  func (n *ConvExpr) SetOp(op Op) {
   271  	switch op {
   272  	default:
   273  		panic(n.no("SetOp " + op.String()))
   274  	case OCONV, OCONVIFACE, OCONVIDATA, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARRPTR:
   275  		n.op = op
   276  	}
   277  }
   278  
   279  // An IndexExpr is an index expression X[Index].
   280  type IndexExpr struct {
   281  	miniExpr
   282  	X        Node
   283  	Index    Node
   284  	Assigned bool
   285  }
   286  
   287  func NewIndexExpr(pos src.XPos, x, index Node) *IndexExpr {
   288  	n := &IndexExpr{X: x, Index: index}
   289  	n.pos = pos
   290  	n.op = OINDEX
   291  	return n
   292  }
   293  
   294  func (n *IndexExpr) SetOp(op Op) {
   295  	switch op {
   296  	default:
   297  		panic(n.no("SetOp " + op.String()))
   298  	case OINDEX, OINDEXMAP:
   299  		n.op = op
   300  	}
   301  }
   302  
   303  // A KeyExpr is a Key: Value composite literal key.
   304  type KeyExpr struct {
   305  	miniExpr
   306  	Key   Node
   307  	Value Node
   308  }
   309  
   310  func NewKeyExpr(pos src.XPos, key, value Node) *KeyExpr {
   311  	n := &KeyExpr{Key: key, Value: value}
   312  	n.pos = pos
   313  	n.op = OKEY
   314  	return n
   315  }
   316  
   317  // A StructKeyExpr is an Field: Value composite literal key.
   318  type StructKeyExpr struct {
   319  	miniExpr
   320  	Field *types.Field
   321  	Value Node
   322  }
   323  
   324  func NewStructKeyExpr(pos src.XPos, field *types.Field, value Node) *StructKeyExpr {
   325  	n := &StructKeyExpr{Field: field, Value: value}
   326  	n.pos = pos
   327  	n.op = OSTRUCTKEY
   328  	return n
   329  }
   330  
   331  func (n *StructKeyExpr) Sym() *types.Sym { return n.Field.Sym }
   332  
   333  // An InlinedCallExpr is an inlined function call.
   334  type InlinedCallExpr struct {
   335  	miniExpr
   336  	Body       Nodes
   337  	ReturnVars Nodes // must be side-effect free
   338  }
   339  
   340  func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr {
   341  	n := &InlinedCallExpr{}
   342  	n.pos = pos
   343  	n.op = OINLCALL
   344  	n.Body = body
   345  	n.ReturnVars = retvars
   346  	return n
   347  }
   348  
   349  func (n *InlinedCallExpr) SingleResult() Node {
   350  	if have := len(n.ReturnVars); have != 1 {
   351  		base.FatalfAt(n.Pos(), "inlined call has %v results, expected 1", have)
   352  	}
   353  	if !n.Type().HasShape() && n.ReturnVars[0].Type().HasShape() {
   354  		// If the type of the call is not a shape, but the type of the return value
   355  		// is a shape, we need to do an implicit conversion, so the real type
   356  		// of n is maintained.
   357  		r := NewConvExpr(n.Pos(), OCONVNOP, n.Type(), n.ReturnVars[0])
   358  		r.SetTypecheck(1)
   359  		return r
   360  	}
   361  	return n.ReturnVars[0]
   362  }
   363  
   364  // A LogicalExpr is a expression X Op Y where Op is && or ||.
   365  // It is separate from BinaryExpr to make room for statements
   366  // that must be executed before Y but after X.
   367  type LogicalExpr struct {
   368  	miniExpr
   369  	X Node
   370  	Y Node
   371  }
   372  
   373  func NewLogicalExpr(pos src.XPos, op Op, x, y Node) *LogicalExpr {
   374  	n := &LogicalExpr{X: x, Y: y}
   375  	n.pos = pos
   376  	n.SetOp(op)
   377  	return n
   378  }
   379  
   380  func (n *LogicalExpr) SetOp(op Op) {
   381  	switch op {
   382  	default:
   383  		panic(n.no("SetOp " + op.String()))
   384  	case OANDAND, OOROR:
   385  		n.op = op
   386  	}
   387  }
   388  
   389  // A MakeExpr is a make expression: make(Type[, Len[, Cap]]).
   390  // Op is OMAKECHAN, OMAKEMAP, OMAKESLICE, or OMAKESLICECOPY,
   391  // but *not* OMAKE (that's a pre-typechecking CallExpr).
   392  type MakeExpr struct {
   393  	miniExpr
   394  	Len Node
   395  	Cap Node
   396  }
   397  
   398  func NewMakeExpr(pos src.XPos, op Op, len, cap Node) *MakeExpr {
   399  	n := &MakeExpr{Len: len, Cap: cap}
   400  	n.pos = pos
   401  	n.SetOp(op)
   402  	return n
   403  }
   404  
   405  func (n *MakeExpr) SetOp(op Op) {
   406  	switch op {
   407  	default:
   408  		panic(n.no("SetOp " + op.String()))
   409  	case OMAKECHAN, OMAKEMAP, OMAKESLICE, OMAKESLICECOPY:
   410  		n.op = op
   411  	}
   412  }
   413  
   414  // A NilExpr represents the predefined untyped constant nil.
   415  // (It may be copied and assigned a type, though.)
   416  type NilExpr struct {
   417  	miniExpr
   418  	Sym_ *types.Sym // TODO: Remove
   419  }
   420  
   421  func NewNilExpr(pos src.XPos) *NilExpr {
   422  	n := &NilExpr{}
   423  	n.pos = pos
   424  	n.op = ONIL
   425  	return n
   426  }
   427  
   428  func (n *NilExpr) Sym() *types.Sym     { return n.Sym_ }
   429  func (n *NilExpr) SetSym(x *types.Sym) { n.Sym_ = x }
   430  
   431  // A ParenExpr is a parenthesized expression (X).
   432  // It may end up being a value or a type.
   433  type ParenExpr struct {
   434  	miniExpr
   435  	X Node
   436  }
   437  
   438  func NewParenExpr(pos src.XPos, x Node) *ParenExpr {
   439  	n := &ParenExpr{X: x}
   440  	n.op = OPAREN
   441  	n.pos = pos
   442  	return n
   443  }
   444  
   445  func (n *ParenExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   446  func (n *ParenExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   447  
   448  func (*ParenExpr) CanBeNtype() {}
   449  
   450  // SetOTYPE changes n to be an OTYPE node returning t,
   451  // like all the type nodes in type.go.
   452  func (n *ParenExpr) SetOTYPE(t *types.Type) {
   453  	n.op = OTYPE
   454  	n.typ = t
   455  	t.SetNod(n)
   456  }
   457  
   458  // A RawOrigExpr represents an arbitrary Go expression as a string value.
   459  // When printed in diagnostics, the string value is written out exactly as-is.
   460  type RawOrigExpr struct {
   461  	miniExpr
   462  	Raw string
   463  }
   464  
   465  func NewRawOrigExpr(pos src.XPos, op Op, raw string) *RawOrigExpr {
   466  	n := &RawOrigExpr{Raw: raw}
   467  	n.pos = pos
   468  	n.op = op
   469  	return n
   470  }
   471  
   472  // A ResultExpr represents a direct access to a result.
   473  type ResultExpr struct {
   474  	miniExpr
   475  	Index int64 // index of the result expr.
   476  }
   477  
   478  func NewResultExpr(pos src.XPos, typ *types.Type, index int64) *ResultExpr {
   479  	n := &ResultExpr{Index: index}
   480  	n.pos = pos
   481  	n.op = ORESULT
   482  	n.typ = typ
   483  	return n
   484  }
   485  
   486  // A LinksymOffsetExpr refers to an offset within a global variable.
   487  // It is like a SelectorExpr but without the field name.
   488  type LinksymOffsetExpr struct {
   489  	miniExpr
   490  	Linksym *obj.LSym
   491  	Offset_ int64
   492  }
   493  
   494  func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr {
   495  	n := &LinksymOffsetExpr{Linksym: lsym, Offset_: offset}
   496  	n.typ = typ
   497  	n.op = OLINKSYMOFFSET
   498  	return n
   499  }
   500  
   501  // NewLinksymExpr is NewLinksymOffsetExpr, but with offset fixed at 0.
   502  func NewLinksymExpr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *LinksymOffsetExpr {
   503  	return NewLinksymOffsetExpr(pos, lsym, 0, typ)
   504  }
   505  
   506  // NewNameOffsetExpr is NewLinksymOffsetExpr, but taking a *Name
   507  // representing a global variable instead of an *obj.LSym directly.
   508  func NewNameOffsetExpr(pos src.XPos, name *Name, offset int64, typ *types.Type) *LinksymOffsetExpr {
   509  	if name == nil || IsBlank(name) || !(name.Op() == ONAME && name.Class == PEXTERN) {
   510  		base.FatalfAt(pos, "cannot take offset of nil, blank name or non-global variable: %v", name)
   511  	}
   512  	return NewLinksymOffsetExpr(pos, name.Linksym(), offset, typ)
   513  }
   514  
   515  // A SelectorExpr is a selector expression X.Sel.
   516  type SelectorExpr struct {
   517  	miniExpr
   518  	X Node
   519  	// Sel is the name of the field or method being selected, without (in the
   520  	// case of methods) any preceding type specifier. If the field/method is
   521  	// exported, than the Sym uses the local package regardless of the package
   522  	// of the containing type.
   523  	Sel *types.Sym
   524  	// The actual selected field - may not be filled in until typechecking.
   525  	Selection *types.Field
   526  	Prealloc  *Name // preallocated storage for OMETHVALUE, if any
   527  }
   528  
   529  func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr {
   530  	n := &SelectorExpr{X: x, Sel: sel}
   531  	n.pos = pos
   532  	n.SetOp(op)
   533  	return n
   534  }
   535  
   536  func (n *SelectorExpr) SetOp(op Op) {
   537  	switch op {
   538  	default:
   539  		panic(n.no("SetOp " + op.String()))
   540  	case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OMETHVALUE, OMETHEXPR:
   541  		n.op = op
   542  	}
   543  }
   544  
   545  func (n *SelectorExpr) Sym() *types.Sym    { return n.Sel }
   546  func (n *SelectorExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   547  func (n *SelectorExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   548  func (n *SelectorExpr) Offset() int64      { return n.Selection.Offset }
   549  
   550  func (n *SelectorExpr) FuncName() *Name {
   551  	if n.Op() != OMETHEXPR {
   552  		panic(n.no("FuncName"))
   553  	}
   554  	fn := NewNameAt(n.Selection.Pos, MethodSym(n.X.Type(), n.Sel))
   555  	fn.Class = PFUNC
   556  	fn.SetType(n.Type())
   557  	if n.Selection.Nname != nil {
   558  		// TODO(austin): Nname is nil for interface method
   559  		// expressions (I.M), so we can't attach a Func to
   560  		// those here. reflectdata.methodWrapper generates the
   561  		// Func.
   562  		fn.Func = n.Selection.Nname.(*Name).Func
   563  	}
   564  	return fn
   565  }
   566  
   567  // Before type-checking, bytes.Buffer is a SelectorExpr.
   568  // After type-checking it becomes a Name.
   569  func (*SelectorExpr) CanBeNtype() {}
   570  
   571  // A SliceExpr is a slice expression X[Low:High] or X[Low:High:Max].
   572  type SliceExpr struct {
   573  	miniExpr
   574  	X    Node
   575  	Low  Node
   576  	High Node
   577  	Max  Node
   578  }
   579  
   580  func NewSliceExpr(pos src.XPos, op Op, x, low, high, max Node) *SliceExpr {
   581  	n := &SliceExpr{X: x, Low: low, High: high, Max: max}
   582  	n.pos = pos
   583  	n.op = op
   584  	return n
   585  }
   586  
   587  func (n *SliceExpr) SetOp(op Op) {
   588  	switch op {
   589  	default:
   590  		panic(n.no("SetOp " + op.String()))
   591  	case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
   592  		n.op = op
   593  	}
   594  }
   595  
   596  // IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
   597  // o must be a slicing op.
   598  func (o Op) IsSlice3() bool {
   599  	switch o {
   600  	case OSLICE, OSLICEARR, OSLICESTR:
   601  		return false
   602  	case OSLICE3, OSLICE3ARR:
   603  		return true
   604  	}
   605  	base.Fatalf("IsSlice3 op %v", o)
   606  	return false
   607  }
   608  
   609  // A SliceHeader expression constructs a slice header from its parts.
   610  type SliceHeaderExpr struct {
   611  	miniExpr
   612  	Ptr Node
   613  	Len Node
   614  	Cap Node
   615  }
   616  
   617  func NewSliceHeaderExpr(pos src.XPos, typ *types.Type, ptr, len, cap Node) *SliceHeaderExpr {
   618  	n := &SliceHeaderExpr{Ptr: ptr, Len: len, Cap: cap}
   619  	n.pos = pos
   620  	n.op = OSLICEHEADER
   621  	n.typ = typ
   622  	return n
   623  }
   624  
   625  // A StarExpr is a dereference expression *X.
   626  // It may end up being a value or a type.
   627  type StarExpr struct {
   628  	miniExpr
   629  	X Node
   630  }
   631  
   632  func NewStarExpr(pos src.XPos, x Node) *StarExpr {
   633  	n := &StarExpr{X: x}
   634  	n.op = ODEREF
   635  	n.pos = pos
   636  	return n
   637  }
   638  
   639  func (n *StarExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   640  func (n *StarExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   641  
   642  func (*StarExpr) CanBeNtype() {}
   643  
   644  // SetOTYPE changes n to be an OTYPE node returning t,
   645  // like all the type nodes in type.go.
   646  func (n *StarExpr) SetOTYPE(t *types.Type) {
   647  	n.op = OTYPE
   648  	n.X = nil
   649  	n.typ = t
   650  	t.SetNod(n)
   651  }
   652  
   653  // A TypeAssertionExpr is a selector expression X.(Type).
   654  // Before type-checking, the type is Ntype.
   655  type TypeAssertExpr struct {
   656  	miniExpr
   657  	X     Node
   658  	Ntype Ntype
   659  
   660  	// Runtime type information provided by walkDotType for
   661  	// assertions from non-empty interface to concrete type.
   662  	Itab *AddrExpr `mknode:"-"` // *runtime.itab for Type implementing X's type
   663  }
   664  
   665  func NewTypeAssertExpr(pos src.XPos, x Node, typ Ntype) *TypeAssertExpr {
   666  	n := &TypeAssertExpr{X: x, Ntype: typ}
   667  	n.pos = pos
   668  	n.op = ODOTTYPE
   669  	return n
   670  }
   671  
   672  func (n *TypeAssertExpr) SetOp(op Op) {
   673  	switch op {
   674  	default:
   675  		panic(n.no("SetOp " + op.String()))
   676  	case ODOTTYPE, ODOTTYPE2:
   677  		n.op = op
   678  	}
   679  }
   680  
   681  // A DynamicTypeAssertExpr asserts that X is of dynamic type T.
   682  type DynamicTypeAssertExpr struct {
   683  	miniExpr
   684  	X Node
   685  	// N = not an interface
   686  	// E = empty interface
   687  	// I = nonempty interface
   688  	// For E->N, T is a *runtime.type for N
   689  	// For I->N, T is a *runtime.itab for N+I
   690  	// For E->I, T is a *runtime.type for I
   691  	// For I->I, ditto
   692  	// For I->E, T is a *runtime.type for interface{} (unnecessary, but just to fill in the slot)
   693  	// For E->E, ditto
   694  	T Node
   695  }
   696  
   697  func NewDynamicTypeAssertExpr(pos src.XPos, op Op, x, t Node) *DynamicTypeAssertExpr {
   698  	n := &DynamicTypeAssertExpr{X: x, T: t}
   699  	n.pos = pos
   700  	n.op = op
   701  	return n
   702  }
   703  
   704  func (n *DynamicTypeAssertExpr) SetOp(op Op) {
   705  	switch op {
   706  	default:
   707  		panic(n.no("SetOp " + op.String()))
   708  	case ODYNAMICDOTTYPE, ODYNAMICDOTTYPE2:
   709  		n.op = op
   710  	}
   711  }
   712  
   713  // A UnaryExpr is a unary expression Op X,
   714  // or Op(X) for a builtin function that does not end up being a call.
   715  type UnaryExpr struct {
   716  	miniExpr
   717  	X Node
   718  }
   719  
   720  func NewUnaryExpr(pos src.XPos, op Op, x Node) *UnaryExpr {
   721  	n := &UnaryExpr{X: x}
   722  	n.pos = pos
   723  	n.SetOp(op)
   724  	return n
   725  }
   726  
   727  func (n *UnaryExpr) SetOp(op Op) {
   728  	switch op {
   729  	default:
   730  		panic(n.no("SetOp " + op.String()))
   731  	case OBITNOT, ONEG, ONOT, OPLUS, ORECV,
   732  		OALIGNOF, OCAP, OCLOSE, OIMAG, OLEN, ONEW,
   733  		OOFFSETOF, OPANIC, OREAL, OSIZEOF,
   734  		OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR, OVARDEF, OVARKILL, OVARLIVE:
   735  		n.op = op
   736  	}
   737  }
   738  
   739  // Probably temporary: using Implicit() flag to mark generic function nodes that
   740  // are called to make getGfInfo analysis easier in one pre-order pass.
   741  func (n *InstExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
   742  func (n *InstExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
   743  
   744  // An InstExpr is a generic function or type instantiation.
   745  type InstExpr struct {
   746  	miniExpr
   747  	X     Node
   748  	Targs []Node
   749  }
   750  
   751  func NewInstExpr(pos src.XPos, op Op, x Node, targs []Node) *InstExpr {
   752  	n := &InstExpr{X: x, Targs: targs}
   753  	n.pos = pos
   754  	n.op = op
   755  	return n
   756  }
   757  
   758  func IsZero(n Node) bool {
   759  	switch n.Op() {
   760  	case ONIL:
   761  		return true
   762  
   763  	case OLITERAL:
   764  		switch u := n.Val(); u.Kind() {
   765  		case constant.String:
   766  			return constant.StringVal(u) == ""
   767  		case constant.Bool:
   768  			return !constant.BoolVal(u)
   769  		default:
   770  			return constant.Sign(u) == 0
   771  		}
   772  
   773  	case OARRAYLIT:
   774  		n := n.(*CompLitExpr)
   775  		for _, n1 := range n.List {
   776  			if n1.Op() == OKEY {
   777  				n1 = n1.(*KeyExpr).Value
   778  			}
   779  			if !IsZero(n1) {
   780  				return false
   781  			}
   782  		}
   783  		return true
   784  
   785  	case OSTRUCTLIT:
   786  		n := n.(*CompLitExpr)
   787  		for _, n1 := range n.List {
   788  			n1 := n1.(*StructKeyExpr)
   789  			if !IsZero(n1.Value) {
   790  				return false
   791  			}
   792  		}
   793  		return true
   794  	}
   795  
   796  	return false
   797  }
   798  
   799  // lvalue etc
   800  func IsAddressable(n Node) bool {
   801  	switch n.Op() {
   802  	case OINDEX:
   803  		n := n.(*IndexExpr)
   804  		if n.X.Type() != nil && n.X.Type().IsArray() {
   805  			return IsAddressable(n.X)
   806  		}
   807  		if n.X.Type() != nil && n.X.Type().IsString() {
   808  			return false
   809  		}
   810  		fallthrough
   811  	case ODEREF, ODOTPTR:
   812  		return true
   813  
   814  	case ODOT:
   815  		n := n.(*SelectorExpr)
   816  		return IsAddressable(n.X)
   817  
   818  	case ONAME:
   819  		n := n.(*Name)
   820  		if n.Class == PFUNC {
   821  			return false
   822  		}
   823  		return true
   824  
   825  	case OLINKSYMOFFSET:
   826  		return true
   827  	}
   828  
   829  	return false
   830  }
   831  
   832  func StaticValue(n Node) Node {
   833  	for {
   834  		if n.Op() == OCONVNOP {
   835  			n = n.(*ConvExpr).X
   836  			continue
   837  		}
   838  
   839  		if n.Op() == OINLCALL {
   840  			n = n.(*InlinedCallExpr).SingleResult()
   841  			continue
   842  		}
   843  
   844  		n1 := staticValue1(n)
   845  		if n1 == nil {
   846  			return n
   847  		}
   848  		n = n1
   849  	}
   850  }
   851  
   852  // staticValue1 implements a simple SSA-like optimization. If n is a local variable
   853  // that is initialized and never reassigned, staticValue1 returns the initializer
   854  // expression. Otherwise, it returns nil.
   855  func staticValue1(nn Node) Node {
   856  	if nn.Op() != ONAME {
   857  		return nil
   858  	}
   859  	n := nn.(*Name)
   860  	if n.Class != PAUTO {
   861  		return nil
   862  	}
   863  
   864  	defn := n.Defn
   865  	if defn == nil {
   866  		return nil
   867  	}
   868  
   869  	var rhs Node
   870  FindRHS:
   871  	switch defn.Op() {
   872  	case OAS:
   873  		defn := defn.(*AssignStmt)
   874  		rhs = defn.Y
   875  	case OAS2:
   876  		defn := defn.(*AssignListStmt)
   877  		for i, lhs := range defn.Lhs {
   878  			if lhs == n {
   879  				rhs = defn.Rhs[i]
   880  				break FindRHS
   881  			}
   882  		}
   883  		base.Fatalf("%v missing from LHS of %v", n, defn)
   884  	default:
   885  		return nil
   886  	}
   887  	if rhs == nil {
   888  		base.Fatalf("RHS is nil: %v", defn)
   889  	}
   890  
   891  	if reassigned(n) {
   892  		return nil
   893  	}
   894  
   895  	return rhs
   896  }
   897  
   898  // reassigned takes an ONAME node, walks the function in which it is defined, and returns a boolean
   899  // indicating whether the name has any assignments other than its declaration.
   900  // The second return value is the first such assignment encountered in the walk, if any. It is mostly
   901  // useful for -m output documenting the reason for inhibited optimizations.
   902  // NB: global variables are always considered to be re-assigned.
   903  // TODO: handle initial declaration not including an assignment and followed by a single assignment?
   904  func reassigned(name *Name) bool {
   905  	if name.Op() != ONAME {
   906  		base.Fatalf("reassigned %v", name)
   907  	}
   908  	// no way to reliably check for no-reassignment of globals, assume it can be
   909  	if name.Curfn == nil {
   910  		return true
   911  	}
   912  
   913  	// TODO(mdempsky): This is inefficient and becoming increasingly
   914  	// unwieldy. Figure out a way to generalize escape analysis's
   915  	// reassignment detection for use by inlining and devirtualization.
   916  
   917  	// isName reports whether n is a reference to name.
   918  	isName := func(x Node) bool {
   919  		n, ok := x.(*Name)
   920  		return ok && n.Canonical() == name
   921  	}
   922  
   923  	var do func(n Node) bool
   924  	do = func(n Node) bool {
   925  		switch n.Op() {
   926  		case OAS:
   927  			n := n.(*AssignStmt)
   928  			if isName(n.X) && n != name.Defn {
   929  				return true
   930  			}
   931  		case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
   932  			n := n.(*AssignListStmt)
   933  			for _, p := range n.Lhs {
   934  				if isName(p) && n != name.Defn {
   935  					return true
   936  				}
   937  			}
   938  		case OADDR:
   939  			n := n.(*AddrExpr)
   940  			if isName(OuterValue(n.X)) {
   941  				return true
   942  			}
   943  		case OCLOSURE:
   944  			n := n.(*ClosureExpr)
   945  			if Any(n.Func, do) {
   946  				return true
   947  			}
   948  		}
   949  		return false
   950  	}
   951  	return Any(name.Curfn, do)
   952  }
   953  
   954  // IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation.
   955  var IsIntrinsicCall = func(*CallExpr) bool { return false }
   956  
   957  // SameSafeExpr checks whether it is safe to reuse one of l and r
   958  // instead of computing both. SameSafeExpr assumes that l and r are
   959  // used in the same statement or expression. In order for it to be
   960  // safe to reuse l or r, they must:
   961  // * be the same expression
   962  // * not have side-effects (no function calls, no channel ops);
   963  //   however, panics are ok
   964  // * not cause inappropriate aliasing; e.g. two string to []byte
   965  //   conversions, must result in two distinct slices
   966  //
   967  // The handling of OINDEXMAP is subtle. OINDEXMAP can occur both
   968  // as an lvalue (map assignment) and an rvalue (map access). This is
   969  // currently OK, since the only place SameSafeExpr gets used on an
   970  // lvalue expression is for OSLICE and OAPPEND optimizations, and it
   971  // is correct in those settings.
   972  func SameSafeExpr(l Node, r Node) bool {
   973  	if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) {
   974  		return false
   975  	}
   976  
   977  	switch l.Op() {
   978  	case ONAME:
   979  		return l == r
   980  
   981  	case ODOT, ODOTPTR:
   982  		l := l.(*SelectorExpr)
   983  		r := r.(*SelectorExpr)
   984  		return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && SameSafeExpr(l.X, r.X)
   985  
   986  	case ODEREF:
   987  		l := l.(*StarExpr)
   988  		r := r.(*StarExpr)
   989  		return SameSafeExpr(l.X, r.X)
   990  
   991  	case ONOT, OBITNOT, OPLUS, ONEG:
   992  		l := l.(*UnaryExpr)
   993  		r := r.(*UnaryExpr)
   994  		return SameSafeExpr(l.X, r.X)
   995  
   996  	case OCONVNOP:
   997  		l := l.(*ConvExpr)
   998  		r := r.(*ConvExpr)
   999  		return SameSafeExpr(l.X, r.X)
  1000  
  1001  	case OCONV:
  1002  		l := l.(*ConvExpr)
  1003  		r := r.(*ConvExpr)
  1004  		// Some conversions can't be reused, such as []byte(str).
  1005  		// Allow only numeric-ish types. This is a bit conservative.
  1006  		return types.IsSimple[l.Type().Kind()] && SameSafeExpr(l.X, r.X)
  1007  
  1008  	case OINDEX, OINDEXMAP:
  1009  		l := l.(*IndexExpr)
  1010  		r := r.(*IndexExpr)
  1011  		return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Index, r.Index)
  1012  
  1013  	case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
  1014  		l := l.(*BinaryExpr)
  1015  		r := r.(*BinaryExpr)
  1016  		return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Y, r.Y)
  1017  
  1018  	case OLITERAL:
  1019  		return constant.Compare(l.Val(), token.EQL, r.Val())
  1020  
  1021  	case ONIL:
  1022  		return true
  1023  	}
  1024  
  1025  	return false
  1026  }
  1027  
  1028  // ShouldCheckPtr reports whether pointer checking should be enabled for
  1029  // function fn at a given level. See debugHelpFooter for defined
  1030  // levels.
  1031  func ShouldCheckPtr(fn *Func, level int) bool {
  1032  	return base.Debug.Checkptr >= level && fn.Pragma&NoCheckPtr == 0
  1033  }
  1034  
  1035  // IsReflectHeaderDataField reports whether l is an expression p.Data
  1036  // where p has type reflect.SliceHeader or reflect.StringHeader.
  1037  func IsReflectHeaderDataField(l Node) bool {
  1038  	if l.Type() != types.Types[types.TUINTPTR] {
  1039  		return false
  1040  	}
  1041  
  1042  	var tsym *types.Sym
  1043  	switch l.Op() {
  1044  	case ODOT:
  1045  		l := l.(*SelectorExpr)
  1046  		tsym = l.X.Type().Sym()
  1047  	case ODOTPTR:
  1048  		l := l.(*SelectorExpr)
  1049  		tsym = l.X.Type().Elem().Sym()
  1050  	default:
  1051  		return false
  1052  	}
  1053  
  1054  	if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" {
  1055  		return false
  1056  	}
  1057  	return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
  1058  }
  1059  
  1060  func ParamNames(ft *types.Type) []Node {
  1061  	args := make([]Node, ft.NumParams())
  1062  	for i, f := range ft.Params().FieldSlice() {
  1063  		args[i] = AsNode(f.Nname)
  1064  	}
  1065  	return args
  1066  }
  1067  
  1068  // MethodSym returns the method symbol representing a method name
  1069  // associated with a specific receiver type.
  1070  //
  1071  // Method symbols can be used to distinguish the same method appearing
  1072  // in different method sets. For example, T.M and (*T).M have distinct
  1073  // method symbols.
  1074  //
  1075  // The returned symbol will be marked as a function.
  1076  func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym {
  1077  	sym := MethodSymSuffix(recv, msym, "")
  1078  	sym.SetFunc(true)
  1079  	return sym
  1080  }
  1081  
  1082  // MethodSymSuffix is like methodsym, but allows attaching a
  1083  // distinguisher suffix. To avoid collisions, the suffix must not
  1084  // start with a letter, number, or period.
  1085  func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
  1086  	if msym.IsBlank() {
  1087  		base.Fatalf("blank method name")
  1088  	}
  1089  
  1090  	rsym := recv.Sym()
  1091  	if recv.IsPtr() {
  1092  		if rsym != nil {
  1093  			base.Fatalf("declared pointer receiver type: %v", recv)
  1094  		}
  1095  		rsym = recv.Elem().Sym()
  1096  	}
  1097  
  1098  	// Find the package the receiver type appeared in. For
  1099  	// anonymous receiver types (i.e., anonymous structs with
  1100  	// embedded fields), use the "go" pseudo-package instead.
  1101  	rpkg := Pkgs.Go
  1102  	if rsym != nil {
  1103  		rpkg = rsym.Pkg
  1104  	}
  1105  
  1106  	var b bytes.Buffer
  1107  	if recv.IsPtr() {
  1108  		// The parentheses aren't really necessary, but
  1109  		// they're pretty traditional at this point.
  1110  		fmt.Fprintf(&b, "(%-S)", recv)
  1111  	} else {
  1112  		fmt.Fprintf(&b, "%-S", recv)
  1113  	}
  1114  
  1115  	// A particular receiver type may have multiple non-exported
  1116  	// methods with the same name. To disambiguate them, include a
  1117  	// package qualifier for names that came from a different
  1118  	// package than the receiver type.
  1119  	if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
  1120  		b.WriteString(".")
  1121  		b.WriteString(msym.Pkg.Prefix)
  1122  	}
  1123  
  1124  	b.WriteString(".")
  1125  	b.WriteString(msym.Name)
  1126  	b.WriteString(suffix)
  1127  
  1128  	return rpkg.LookupBytes(b.Bytes())
  1129  }
  1130  
  1131  // MethodExprName returns the ONAME representing the method
  1132  // referenced by expression n, which must be a method selector,
  1133  // method expression, or method value.
  1134  func MethodExprName(n Node) *Name {
  1135  	name, _ := MethodExprFunc(n).Nname.(*Name)
  1136  	return name
  1137  }
  1138  
  1139  // MethodExprFunc is like MethodExprName, but returns the types.Field instead.
  1140  func MethodExprFunc(n Node) *types.Field {
  1141  	switch n.Op() {
  1142  	case ODOTMETH, OMETHEXPR, OMETHVALUE:
  1143  		return n.(*SelectorExpr).Selection
  1144  	}
  1145  	base.Fatalf("unexpected node: %v (%v)", n, n.Op())
  1146  	panic("unreachable")
  1147  }
  1148  

View as plain text