github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/cmd/compile/internal/ir/expr.go (about)

     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  	"github.com/shogo82148/std/cmd/compile/internal/types"
     9  	"github.com/shogo82148/std/cmd/internal/obj"
    10  	"github.com/shogo82148/std/cmd/internal/src"
    11  	"github.com/shogo82148/std/go/constant"
    12  )
    13  
    14  // An Expr is a Node that can appear as an expression.
    15  type Expr interface {
    16  	Node
    17  	isExpr()
    18  }
    19  
    20  // An AddStringExpr is a string concatenation List[0] + List[1] + ... + List[len(List)-1].
    21  type AddStringExpr struct {
    22  	miniExpr
    23  	List     Nodes
    24  	Prealloc *Name
    25  }
    26  
    27  func NewAddStringExpr(pos src.XPos, list []Node) *AddStringExpr
    28  
    29  // An AddrExpr is an address-of expression &X.
    30  // It may end up being a normal address-of or an allocation of a composite literal.
    31  type AddrExpr struct {
    32  	miniExpr
    33  	X        Node
    34  	Prealloc *Name
    35  }
    36  
    37  func NewAddrExpr(pos src.XPos, x Node) *AddrExpr
    38  
    39  func (n *AddrExpr) Implicit() bool
    40  func (n *AddrExpr) SetImplicit(b bool)
    41  
    42  func (n *AddrExpr) SetOp(op Op)
    43  
    44  // A BasicLit is a literal of basic type.
    45  type BasicLit struct {
    46  	miniExpr
    47  	val constant.Value
    48  }
    49  
    50  // NewBasicLit returns an OLITERAL representing val with the given type.
    51  func NewBasicLit(pos src.XPos, typ *types.Type, val constant.Value) Node
    52  
    53  func (n *BasicLit) Val() constant.Value
    54  func (n *BasicLit) SetVal(val constant.Value)
    55  
    56  // NewConstExpr returns an OLITERAL representing val, copying the
    57  // position and type from orig.
    58  func NewConstExpr(val constant.Value, orig Node) Node
    59  
    60  // A BinaryExpr is a binary expression X Op Y,
    61  // or Op(X, Y) for builtin functions that do not become calls.
    62  type BinaryExpr struct {
    63  	miniExpr
    64  	X     Node
    65  	Y     Node
    66  	RType Node `mknode:"-"`
    67  }
    68  
    69  func NewBinaryExpr(pos src.XPos, op Op, x, y Node) *BinaryExpr
    70  
    71  func (n *BinaryExpr) SetOp(op Op)
    72  
    73  // A CallExpr is a function call Fun(Args).
    74  type CallExpr struct {
    75  	miniExpr
    76  	Fun       Node
    77  	Args      Nodes
    78  	DeferAt   Node
    79  	RType     Node `mknode:"-"`
    80  	KeepAlive []*Name
    81  	IsDDD     bool
    82  	GoDefer   bool
    83  	NoInline  bool
    84  }
    85  
    86  func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr
    87  
    88  func (n *CallExpr) SetOp(op Op)
    89  
    90  // A ClosureExpr is a function literal expression.
    91  type ClosureExpr struct {
    92  	miniExpr
    93  	Func     *Func `mknode:"-"`
    94  	Prealloc *Name
    95  	IsGoWrap bool
    96  }
    97  
    98  // A CompLitExpr is a composite literal Type{Vals}.
    99  // Before type-checking, the type is Ntype.
   100  type CompLitExpr struct {
   101  	miniExpr
   102  	List     Nodes
   103  	RType    Node `mknode:"-"`
   104  	Prealloc *Name
   105  	// For OSLICELIT, Len is the backing array length.
   106  	// For OMAPLIT, Len is the number of entries that we've removed from List and
   107  	// generated explicit mapassign calls for. This is used to inform the map alloc hint.
   108  	Len int64
   109  }
   110  
   111  func NewCompLitExpr(pos src.XPos, op Op, typ *types.Type, list []Node) *CompLitExpr
   112  
   113  func (n *CompLitExpr) Implicit() bool
   114  func (n *CompLitExpr) SetImplicit(b bool)
   115  
   116  func (n *CompLitExpr) SetOp(op Op)
   117  
   118  // A ConvExpr is a conversion Type(X).
   119  // It may end up being a value or a type.
   120  type ConvExpr struct {
   121  	miniExpr
   122  	X Node
   123  
   124  	// For implementing OCONVIFACE expressions.
   125  	//
   126  	// TypeWord is an expression yielding a *runtime._type or
   127  	// *runtime.itab value to go in the type word of the iface/eface
   128  	// result. See reflectdata.ConvIfaceTypeWord for further details.
   129  	//
   130  	// SrcRType is an expression yielding a *runtime._type value for X,
   131  	// if it's not pointer-shaped and needs to be heap allocated.
   132  	TypeWord Node `mknode:"-"`
   133  	SrcRType Node `mknode:"-"`
   134  
   135  	// For -d=checkptr instrumentation of conversions from
   136  	// unsafe.Pointer to *Elem or *[Len]Elem.
   137  	//
   138  	// TODO(mdempsky): We only ever need one of these, but currently we
   139  	// don't decide which one until walk. Longer term, it probably makes
   140  	// sense to have a dedicated IR op for `(*[Len]Elem)(ptr)[:n:m]`
   141  	// expressions.
   142  	ElemRType     Node `mknode:"-"`
   143  	ElemElemRType Node `mknode:"-"`
   144  }
   145  
   146  func NewConvExpr(pos src.XPos, op Op, typ *types.Type, x Node) *ConvExpr
   147  
   148  func (n *ConvExpr) Implicit() bool
   149  func (n *ConvExpr) SetImplicit(b bool)
   150  func (n *ConvExpr) CheckPtr() bool
   151  func (n *ConvExpr) SetCheckPtr(b bool)
   152  
   153  func (n *ConvExpr) SetOp(op Op)
   154  
   155  // An IndexExpr is an index expression X[Index].
   156  type IndexExpr struct {
   157  	miniExpr
   158  	X        Node
   159  	Index    Node
   160  	RType    Node `mknode:"-"`
   161  	Assigned bool
   162  }
   163  
   164  func NewIndexExpr(pos src.XPos, x, index Node) *IndexExpr
   165  
   166  func (n *IndexExpr) SetOp(op Op)
   167  
   168  // A KeyExpr is a Key: Value composite literal key.
   169  type KeyExpr struct {
   170  	miniExpr
   171  	Key   Node
   172  	Value Node
   173  }
   174  
   175  func NewKeyExpr(pos src.XPos, key, value Node) *KeyExpr
   176  
   177  // A StructKeyExpr is a Field: Value composite literal key.
   178  type StructKeyExpr struct {
   179  	miniExpr
   180  	Field *types.Field
   181  	Value Node
   182  }
   183  
   184  func NewStructKeyExpr(pos src.XPos, field *types.Field, value Node) *StructKeyExpr
   185  
   186  func (n *StructKeyExpr) Sym() *types.Sym
   187  
   188  // An InlinedCallExpr is an inlined function call.
   189  type InlinedCallExpr struct {
   190  	miniExpr
   191  	Body       Nodes
   192  	ReturnVars Nodes
   193  }
   194  
   195  func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr
   196  
   197  func (n *InlinedCallExpr) SingleResult() Node
   198  
   199  // A LogicalExpr is an expression X Op Y where Op is && or ||.
   200  // It is separate from BinaryExpr to make room for statements
   201  // that must be executed before Y but after X.
   202  type LogicalExpr struct {
   203  	miniExpr
   204  	X Node
   205  	Y Node
   206  }
   207  
   208  func NewLogicalExpr(pos src.XPos, op Op, x, y Node) *LogicalExpr
   209  
   210  func (n *LogicalExpr) SetOp(op Op)
   211  
   212  // A MakeExpr is a make expression: make(Type[, Len[, Cap]]).
   213  // Op is OMAKECHAN, OMAKEMAP, OMAKESLICE, or OMAKESLICECOPY,
   214  // but *not* OMAKE (that's a pre-typechecking CallExpr).
   215  type MakeExpr struct {
   216  	miniExpr
   217  	RType Node `mknode:"-"`
   218  	Len   Node
   219  	Cap   Node
   220  }
   221  
   222  func NewMakeExpr(pos src.XPos, op Op, len, cap Node) *MakeExpr
   223  
   224  func (n *MakeExpr) SetOp(op Op)
   225  
   226  // A NilExpr represents the predefined untyped constant nil.
   227  type NilExpr struct {
   228  	miniExpr
   229  }
   230  
   231  func NewNilExpr(pos src.XPos, typ *types.Type) *NilExpr
   232  
   233  // A ParenExpr is a parenthesized expression (X).
   234  // It may end up being a value or a type.
   235  type ParenExpr struct {
   236  	miniExpr
   237  	X Node
   238  }
   239  
   240  func NewParenExpr(pos src.XPos, x Node) *ParenExpr
   241  
   242  func (n *ParenExpr) Implicit() bool
   243  func (n *ParenExpr) SetImplicit(b bool)
   244  
   245  // A ResultExpr represents a direct access to a result.
   246  type ResultExpr struct {
   247  	miniExpr
   248  	Index int64
   249  }
   250  
   251  func NewResultExpr(pos src.XPos, typ *types.Type, index int64) *ResultExpr
   252  
   253  // A LinksymOffsetExpr refers to an offset within a global variable.
   254  // It is like a SelectorExpr but without the field name.
   255  type LinksymOffsetExpr struct {
   256  	miniExpr
   257  	Linksym *obj.LSym
   258  	Offset_ int64
   259  }
   260  
   261  func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr
   262  
   263  // NewLinksymExpr is NewLinksymOffsetExpr, but with offset fixed at 0.
   264  func NewLinksymExpr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *LinksymOffsetExpr
   265  
   266  // NewNameOffsetExpr is NewLinksymOffsetExpr, but taking a *Name
   267  // representing a global variable instead of an *obj.LSym directly.
   268  func NewNameOffsetExpr(pos src.XPos, name *Name, offset int64, typ *types.Type) *LinksymOffsetExpr
   269  
   270  // A SelectorExpr is a selector expression X.Sel.
   271  type SelectorExpr struct {
   272  	miniExpr
   273  	X Node
   274  	// Sel is the name of the field or method being selected, without (in the
   275  	// case of methods) any preceding type specifier. If the field/method is
   276  	// exported, than the Sym uses the local package regardless of the package
   277  	// of the containing type.
   278  	Sel *types.Sym
   279  	// The actual selected field - may not be filled in until typechecking.
   280  	Selection *types.Field
   281  	Prealloc  *Name
   282  }
   283  
   284  func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr
   285  
   286  func (n *SelectorExpr) SetOp(op Op)
   287  
   288  func (n *SelectorExpr) Sym() *types.Sym
   289  func (n *SelectorExpr) Implicit() bool
   290  func (n *SelectorExpr) SetImplicit(b bool)
   291  func (n *SelectorExpr) Offset() int64
   292  
   293  func (n *SelectorExpr) FuncName() *Name
   294  
   295  // A SliceExpr is a slice expression X[Low:High] or X[Low:High:Max].
   296  type SliceExpr struct {
   297  	miniExpr
   298  	X    Node
   299  	Low  Node
   300  	High Node
   301  	Max  Node
   302  }
   303  
   304  func NewSliceExpr(pos src.XPos, op Op, x, low, high, max Node) *SliceExpr
   305  
   306  func (n *SliceExpr) SetOp(op Op)
   307  
   308  // IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
   309  // o must be a slicing op.
   310  func (o Op) IsSlice3() bool
   311  
   312  // A SliceHeader expression constructs a slice header from its parts.
   313  type SliceHeaderExpr struct {
   314  	miniExpr
   315  	Ptr Node
   316  	Len Node
   317  	Cap Node
   318  }
   319  
   320  func NewSliceHeaderExpr(pos src.XPos, typ *types.Type, ptr, len, cap Node) *SliceHeaderExpr
   321  
   322  // A StringHeaderExpr expression constructs a string header from its parts.
   323  type StringHeaderExpr struct {
   324  	miniExpr
   325  	Ptr Node
   326  	Len Node
   327  }
   328  
   329  func NewStringHeaderExpr(pos src.XPos, ptr, len Node) *StringHeaderExpr
   330  
   331  // A StarExpr is a dereference expression *X.
   332  // It may end up being a value or a type.
   333  type StarExpr struct {
   334  	miniExpr
   335  	X Node
   336  }
   337  
   338  func NewStarExpr(pos src.XPos, x Node) *StarExpr
   339  
   340  func (n *StarExpr) Implicit() bool
   341  func (n *StarExpr) SetImplicit(b bool)
   342  
   343  // A TypeAssertionExpr is a selector expression X.(Type).
   344  // Before type-checking, the type is Ntype.
   345  type TypeAssertExpr struct {
   346  	miniExpr
   347  	X Node
   348  
   349  	// Runtime type information provided by walkDotType for
   350  	// assertions from non-empty interface to concrete type.
   351  	ITab Node `mknode:"-"`
   352  
   353  	// An internal/abi.TypeAssert descriptor to pass to the runtime.
   354  	Descriptor *obj.LSym
   355  }
   356  
   357  func NewTypeAssertExpr(pos src.XPos, x Node, typ *types.Type) *TypeAssertExpr
   358  
   359  func (n *TypeAssertExpr) SetOp(op Op)
   360  
   361  // A DynamicTypeAssertExpr asserts that X is of dynamic type RType.
   362  type DynamicTypeAssertExpr struct {
   363  	miniExpr
   364  	X Node
   365  
   366  	// SrcRType is an expression that yields a *runtime._type value
   367  	// representing X's type. It's used in failed assertion panic
   368  	// messages.
   369  	SrcRType Node
   370  
   371  	// RType is an expression that yields a *runtime._type value
   372  	// representing the asserted type.
   373  	//
   374  	// BUG(mdempsky): If ITab is non-nil, RType may be nil.
   375  	RType Node
   376  
   377  	// ITab is an expression that yields a *runtime.itab value
   378  	// representing the asserted type within the assertee expression's
   379  	// original interface type.
   380  	//
   381  	// ITab is only used for assertions from non-empty interface type to
   382  	// a concrete (i.e., non-interface) type. For all other assertions,
   383  	// ITab is nil.
   384  	ITab Node
   385  }
   386  
   387  func NewDynamicTypeAssertExpr(pos src.XPos, op Op, x, rtype Node) *DynamicTypeAssertExpr
   388  
   389  func (n *DynamicTypeAssertExpr) SetOp(op Op)
   390  
   391  // A UnaryExpr is a unary expression Op X,
   392  // or Op(X) for a builtin function that does not end up being a call.
   393  type UnaryExpr struct {
   394  	miniExpr
   395  	X Node
   396  }
   397  
   398  func NewUnaryExpr(pos src.XPos, op Op, x Node) *UnaryExpr
   399  
   400  func (n *UnaryExpr) SetOp(op Op)
   401  
   402  func IsZero(n Node) bool
   403  
   404  // lvalue etc
   405  func IsAddressable(n Node) bool
   406  
   407  // StaticValue analyzes n to find the earliest expression that always
   408  // evaluates to the same value as n, which might be from an enclosing
   409  // function.
   410  //
   411  // For example, given:
   412  //
   413  //	var x int = g()
   414  //	func() {
   415  //		y := x
   416  //		*p = int(y)
   417  //	}
   418  //
   419  // calling StaticValue on the "int(y)" expression returns the outer
   420  // "g()" expression.
   421  func StaticValue(n Node) Node
   422  
   423  // Reassigned takes an ONAME node, walks the function in which it is
   424  // defined, and returns a boolean indicating whether the name has any
   425  // assignments other than its declaration.
   426  // NB: global variables are always considered to be re-assigned.
   427  // TODO: handle initial declaration not including an assignment and
   428  // followed by a single assignment?
   429  // NOTE: any changes made here should also be made in the corresponding
   430  // code in the ReassignOracle.Init method.
   431  func Reassigned(name *Name) bool
   432  
   433  // StaticCalleeName returns the ONAME/PFUNC for n, if known.
   434  func StaticCalleeName(n Node) *Name
   435  
   436  // IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation.
   437  var IsIntrinsicCall = func(*CallExpr) bool { return false }
   438  
   439  // SameSafeExpr checks whether it is safe to reuse one of l and r
   440  // instead of computing both. SameSafeExpr assumes that l and r are
   441  // used in the same statement or expression. In order for it to be
   442  // safe to reuse l or r, they must:
   443  //   - be the same expression
   444  //   - not have side-effects (no function calls, no channel ops);
   445  //     however, panics are ok
   446  //   - not cause inappropriate aliasing; e.g. two string to []byte
   447  //     conversions, must result in two distinct slices
   448  //
   449  // The handling of OINDEXMAP is subtle. OINDEXMAP can occur both
   450  // as an lvalue (map assignment) and an rvalue (map access). This is
   451  // currently OK, since the only place SameSafeExpr gets used on an
   452  // lvalue expression is for OSLICE and OAPPEND optimizations, and it
   453  // is correct in those settings.
   454  func SameSafeExpr(l Node, r Node) bool
   455  
   456  // ShouldCheckPtr reports whether pointer checking should be enabled for
   457  // function fn at a given level. See debugHelpFooter for defined
   458  // levels.
   459  func ShouldCheckPtr(fn *Func, level int) bool
   460  
   461  // ShouldAsanCheckPtr reports whether pointer checking should be enabled for
   462  // function fn when -asan is enabled.
   463  func ShouldAsanCheckPtr(fn *Func) bool
   464  
   465  // IsReflectHeaderDataField reports whether l is an expression p.Data
   466  // where p has type reflect.SliceHeader or reflect.StringHeader.
   467  func IsReflectHeaderDataField(l Node) bool
   468  
   469  func ParamNames(ft *types.Type) []Node
   470  
   471  // MethodSym returns the method symbol representing a method name
   472  // associated with a specific receiver type.
   473  //
   474  // Method symbols can be used to distinguish the same method appearing
   475  // in different method sets. For example, T.M and (*T).M have distinct
   476  // method symbols.
   477  //
   478  // The returned symbol will be marked as a function.
   479  func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym
   480  
   481  // MethodSymSuffix is like MethodSym, but allows attaching a
   482  // distinguisher suffix. To avoid collisions, the suffix must not
   483  // start with a letter, number, or period.
   484  func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym
   485  
   486  // LookupMethodSelector returns the types.Sym of the selector for a method
   487  // named in local symbol name, as well as the types.Sym of the receiver.
   488  //
   489  // TODO(prattmic): this does not attempt to handle method suffixes (wrappers).
   490  func LookupMethodSelector(pkg *types.Pkg, name string) (typ, meth *types.Sym, err error)
   491  
   492  // MethodExprName returns the ONAME representing the method
   493  // referenced by expression n, which must be a method selector,
   494  // method expression, or method value.
   495  func MethodExprName(n Node) *Name
   496  
   497  // MethodExprFunc is like MethodExprName, but returns the types.Field instead.
   498  func MethodExprFunc(n Node) *types.Field