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

     1  // Copyright 2009 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  // “Abstract” syntax representation.
     6  
     7  package ir
     8  
     9  import (
    10  	"github.com/shogo82148/std/fmt"
    11  	"github.com/shogo82148/std/go/constant"
    12  
    13  	"github.com/shogo82148/std/cmd/compile/internal/types"
    14  	"github.com/shogo82148/std/cmd/internal/src"
    15  )
    16  
    17  // A Node is the abstract interface to an IR node.
    18  type Node interface {
    19  	Format(s fmt.State, verb rune)
    20  
    21  	Pos() src.XPos
    22  	SetPos(x src.XPos)
    23  
    24  	copy() Node
    25  
    26  	doChildren(func(Node) bool) bool
    27  	editChildren(func(Node) Node)
    28  	editChildrenWithHidden(func(Node) Node)
    29  
    30  	Op() Op
    31  	Init() Nodes
    32  
    33  	Type() *types.Type
    34  	SetType(t *types.Type)
    35  	Name() *Name
    36  	Sym() *types.Sym
    37  	Val() constant.Value
    38  	SetVal(v constant.Value)
    39  
    40  	Esc() uint16
    41  	SetEsc(x uint16)
    42  
    43  	Typecheck() uint8
    44  	SetTypecheck(x uint8)
    45  	NonNil() bool
    46  	MarkNonNil()
    47  }
    48  
    49  // Line returns n's position as a string. If n has been inlined,
    50  // it uses the outermost position where n has been inlined.
    51  func Line(n Node) string
    52  
    53  func IsSynthetic(n Node) bool
    54  
    55  // IsAutoTmp indicates if n was created by the compiler as a temporary,
    56  // based on the setting of the .AutoTemp flag in n's Name.
    57  func IsAutoTmp(n Node) bool
    58  
    59  // MayBeShared reports whether n may occur in multiple places in the AST.
    60  // Extra care must be taken when mutating such a node.
    61  func MayBeShared(n Node) bool
    62  
    63  type InitNode interface {
    64  	Node
    65  	PtrInit() *Nodes
    66  	SetInit(x Nodes)
    67  }
    68  
    69  func TakeInit(n Node) Nodes
    70  
    71  type Op uint8
    72  
    73  // Node ops.
    74  const (
    75  	OXXX Op = iota
    76  
    77  	// names
    78  	ONAME
    79  	// Unnamed arg or return value: f(int, string) (int, error) { etc }
    80  	// Also used for a qualified package identifier that hasn't been resolved yet.
    81  	ONONAME
    82  	OTYPE
    83  	OLITERAL
    84  	ONIL
    85  
    86  	// expressions
    87  	OADD
    88  	OSUB
    89  	OOR
    90  	OXOR
    91  	OADDSTR
    92  	OADDR
    93  	OANDAND
    94  	OAPPEND
    95  	OBYTES2STR
    96  	OBYTES2STRTMP
    97  	ORUNES2STR
    98  	OSTR2BYTES
    99  	OSTR2BYTESTMP
   100  	OSTR2RUNES
   101  	OSLICE2ARR
   102  	OSLICE2ARRPTR
   103  	// X = Y or (if Def=true) X := Y
   104  	// If Def, then Init includes a DCL node for X.
   105  	OAS
   106  	// Lhs = Rhs (x, y, z = a, b, c) or (if Def=true) Lhs := Rhs
   107  	// If Def, then Init includes DCL nodes for Lhs
   108  	OAS2
   109  	OAS2DOTTYPE
   110  	OAS2FUNC
   111  	OAS2MAPR
   112  	OAS2RECV
   113  	OASOP
   114  	OCALL
   115  
   116  	// OCALLFUNC, OCALLMETH, and OCALLINTER have the same structure.
   117  	// Prior to walk, they are: X(Args), where Args is all regular arguments.
   118  	// After walk, if any argument whose evaluation might requires temporary variable,
   119  	// that temporary variable will be pushed to Init, Args will contain an updated
   120  	// set of arguments.
   121  	OCALLFUNC
   122  	OCALLMETH
   123  	OCALLINTER
   124  	OCAP
   125  	OCLEAR
   126  	OCLOSE
   127  	OCLOSURE
   128  	OCOMPLIT
   129  	OMAPLIT
   130  	OSTRUCTLIT
   131  	OARRAYLIT
   132  	OSLICELIT
   133  	OPTRLIT
   134  	OCONV
   135  	OCONVIFACE
   136  	OCONVNOP
   137  	OCOPY
   138  	ODCL
   139  
   140  	// Used during parsing but don't last.
   141  	ODCLFUNC
   142  
   143  	ODELETE
   144  	ODOT
   145  	ODOTPTR
   146  	ODOTMETH
   147  	ODOTINTER
   148  	OXDOT
   149  	ODOTTYPE
   150  	ODOTTYPE2
   151  	OEQ
   152  	ONE
   153  	OLT
   154  	OLE
   155  	OGE
   156  	OGT
   157  	ODEREF
   158  	OINDEX
   159  	OINDEXMAP
   160  	OKEY
   161  	OSTRUCTKEY
   162  	OLEN
   163  	OMAKE
   164  	OMAKECHAN
   165  	OMAKEMAP
   166  	OMAKESLICE
   167  	OMAKESLICECOPY
   168  	// OMAKESLICECOPY is created by the order pass and corresponds to:
   169  	//  s = make(Type, Len); copy(s, Cap)
   170  	//
   171  	// Bounded can be set on the node when Len == len(Cap) is known at compile time.
   172  	//
   173  	// This node is created so the walk pass can optimize this pattern which would
   174  	// otherwise be hard to detect after the order pass.
   175  	OMUL
   176  	ODIV
   177  	OMOD
   178  	OLSH
   179  	ORSH
   180  	OAND
   181  	OANDNOT
   182  	ONEW
   183  	ONOT
   184  	OBITNOT
   185  	OPLUS
   186  	ONEG
   187  	OOROR
   188  	OPANIC
   189  	OPRINT
   190  	OPRINTLN
   191  	OPAREN
   192  	OSEND
   193  	OSLICE
   194  	OSLICEARR
   195  	OSLICESTR
   196  	OSLICE3
   197  	OSLICE3ARR
   198  	OSLICEHEADER
   199  	OSTRINGHEADER
   200  	ORECOVER
   201  	ORECOVERFP
   202  	ORECV
   203  	ORUNESTR
   204  	OSELRECV2
   205  	OMIN
   206  	OMAX
   207  	OREAL
   208  	OIMAG
   209  	OCOMPLEX
   210  	OUNSAFEADD
   211  	OUNSAFESLICE
   212  	OUNSAFESLICEDATA
   213  	OUNSAFESTRING
   214  	OUNSAFESTRINGDATA
   215  	OMETHEXPR
   216  	OMETHVALUE
   217  
   218  	// statements
   219  	OBLOCK
   220  	OBREAK
   221  	// OCASE:  case List: Body (List==nil means default)
   222  	//   For OTYPESW, List is a OTYPE node for the specified type (or OLITERAL
   223  	//   for nil) or an ODYNAMICTYPE indicating a runtime type for generics.
   224  	//   If a type-switch variable is specified, Var is an
   225  	//   ONAME for the version of the type-switch variable with the specified
   226  	//   type.
   227  	OCASE
   228  	OCONTINUE
   229  	ODEFER
   230  	OFALL
   231  	OFOR
   232  	OGOTO
   233  	OIF
   234  	OLABEL
   235  	OGO
   236  	ORANGE
   237  	ORETURN
   238  	OSELECT
   239  	OSWITCH
   240  	// OTYPESW:  X := Y.(type) (appears as .Tag of OSWITCH)
   241  	//   X is nil if there is no type-switch variable
   242  	OTYPESW
   243  
   244  	// misc
   245  	// intermediate representation of an inlined call.  Uses Init (assignments
   246  	// for the captured variables, parameters, retvars, & INLMARK op),
   247  	// Body (body of the inlined function), and ReturnVars (list of
   248  	// return values)
   249  	OINLCALL
   250  	OMAKEFACE
   251  	OITAB
   252  	OIDATA
   253  	OSPTR
   254  	OCFUNC
   255  	OCHECKNIL
   256  	ORESULT
   257  	OINLMARK
   258  	OLINKSYMOFFSET
   259  	OJUMPTABLE
   260  	OINTERFACESWITCH
   261  
   262  	// opcodes for generics
   263  	ODYNAMICDOTTYPE
   264  	ODYNAMICDOTTYPE2
   265  	ODYNAMICTYPE
   266  
   267  	// arch-specific opcodes
   268  	OTAILCALL
   269  	OGETG
   270  	OGETCALLERPC
   271  	OGETCALLERSP
   272  
   273  	OEND
   274  )
   275  
   276  // IsCmp reports whether op is a comparison operation (==, !=, <, <=,
   277  // >, or >=).
   278  func (op Op) IsCmp() bool
   279  
   280  // Nodes is a slice of Node.
   281  type Nodes []Node
   282  
   283  // ToNodes returns s as a slice of Nodes.
   284  func ToNodes[T Node](s []T) Nodes
   285  
   286  // Append appends entries to Nodes.
   287  func (n *Nodes) Append(a ...Node)
   288  
   289  // Prepend prepends entries to Nodes.
   290  // If a slice is passed in, this will take ownership of it.
   291  func (n *Nodes) Prepend(a ...Node)
   292  
   293  // Take clears n, returning its former contents.
   294  func (n *Nodes) Take() []Node
   295  
   296  // Copy returns a copy of the content of the slice.
   297  func (n Nodes) Copy() Nodes
   298  
   299  // NameQueue is a FIFO queue of *Name. The zero value of NameQueue is
   300  // a ready-to-use empty queue.
   301  type NameQueue struct {
   302  	ring       []*Name
   303  	head, tail int
   304  }
   305  
   306  // Empty reports whether q contains no Names.
   307  func (q *NameQueue) Empty() bool
   308  
   309  // PushRight appends n to the right of the queue.
   310  func (q *NameQueue) PushRight(n *Name)
   311  
   312  // PopLeft pops a Name from the left of the queue. It panics if q is
   313  // empty.
   314  func (q *NameQueue) PopLeft() *Name
   315  
   316  // NameSet is a set of Names.
   317  type NameSet map[*Name]struct{}
   318  
   319  // Has reports whether s contains n.
   320  func (s NameSet) Has(n *Name) bool
   321  
   322  // Add adds n to s.
   323  func (s *NameSet) Add(n *Name)
   324  
   325  // Sorted returns s sorted according to less.
   326  func (s NameSet) Sorted(less func(*Name, *Name) bool) []*Name
   327  
   328  type PragmaFlag uint16
   329  
   330  const (
   331  	// Func pragmas.
   332  	Nointerface PragmaFlag = 1 << iota
   333  	Noescape
   334  	Norace
   335  	Nosplit
   336  	Noinline
   337  	NoCheckPtr
   338  	CgoUnsafeArgs
   339  	UintptrKeepAlive
   340  	UintptrEscapes
   341  
   342  	// Runtime-only func pragmas.
   343  	// See ../../../../runtime/HACKING.md for detailed descriptions.
   344  	Systemstack
   345  	Nowritebarrier
   346  	Nowritebarrierrec
   347  	Yeswritebarrierrec
   348  
   349  	// Go command pragmas
   350  	GoBuildPragma
   351  
   352  	RegisterParams
   353  )
   354  
   355  var BlankNode *Name
   356  
   357  func IsConst(n Node, ct constant.Kind) bool
   358  
   359  // IsNil reports whether n represents the universal untyped zero value "nil".
   360  func IsNil(n Node) bool
   361  
   362  func IsBlank(n Node) bool
   363  
   364  // IsMethod reports whether n is a method.
   365  // n must be a function or a method.
   366  func IsMethod(n Node) bool
   367  
   368  // HasUniquePos reports whether n has a unique position that can be
   369  // used for reporting error messages.
   370  //
   371  // It's primarily used to distinguish references to named objects,
   372  // whose Pos will point back to their declaration position rather than
   373  // their usage position.
   374  func HasUniquePos(n Node) bool
   375  
   376  func SetPos(n Node) src.XPos
   377  
   378  // The result of InitExpr MUST be assigned back to n, e.g.
   379  //
   380  //	n.X = InitExpr(init, n.X)
   381  func InitExpr(init []Node, expr Node) Node
   382  
   383  // what's the outer value that a write to n affects?
   384  // outer value means containing struct or array.
   385  func OuterValue(n Node) Node
   386  
   387  const (
   388  	EscUnknown = iota
   389  	EscNone
   390  	EscHeap
   391  	EscNever
   392  )