github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/gc/syntax.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 gc
     8  
     9  import (
    10  	"github.com/gagliardetto/golang-go/cmd/compile/internal/ssa"
    11  	"github.com/gagliardetto/golang-go/cmd/compile/internal/syntax"
    12  	"github.com/gagliardetto/golang-go/cmd/compile/internal/types"
    13  	"github.com/gagliardetto/golang-go/cmd/internal/obj"
    14  	"github.com/gagliardetto/golang-go/cmd/internal/src"
    15  	"sort"
    16  )
    17  
    18  // A Node is a single node in the syntax tree.
    19  // Actually the syntax tree is a syntax DAG, because there is only one
    20  // node with Op=ONAME for a given instance of a variable x.
    21  // The same is true for Op=OTYPE and Op=OLITERAL. See Node.mayBeShared.
    22  type Node struct {
    23  	// Tree structure.
    24  	// Generic recursive walks should follow these fields.
    25  	Left  *Node
    26  	Right *Node
    27  	Ninit Nodes
    28  	Nbody Nodes
    29  	List  Nodes
    30  	Rlist Nodes
    31  
    32  	// most nodes
    33  	Type *types.Type
    34  	Orig *Node // original form, for printing, and tracking copies of ONAMEs
    35  
    36  	// func
    37  	Func *Func
    38  
    39  	// ONAME, OTYPE, OPACK, OLABEL, some OLITERAL
    40  	Name *Name
    41  
    42  	Sym *types.Sym  // various
    43  	E   interface{} // Opt or Val, see methods below
    44  
    45  	// Various. Usually an offset into a struct. For example:
    46  	// - ONAME nodes that refer to local variables use it to identify their stack frame position.
    47  	// - ODOT, ODOTPTR, and ORESULT use it to indicate offset relative to their base address.
    48  	// - OSTRUCTKEY uses it to store the named field's offset.
    49  	// - Named OLITERALs use it to store their ambient iota value.
    50  	// - OINLMARK stores an index into the inlTree data structure.
    51  	// - OCLOSURE uses it to store ambient iota value, if any.
    52  	// Possibly still more uses. If you find any, document them.
    53  	Xoffset int64
    54  
    55  	Pos src.XPos
    56  
    57  	flags bitset32
    58  
    59  	Esc uint16 // EscXXX
    60  
    61  	Op  Op
    62  	aux uint8
    63  }
    64  
    65  func (n *Node) ResetAux() {
    66  	n.aux = 0
    67  }
    68  
    69  func (n *Node) SubOp() Op {
    70  	switch n.Op {
    71  	case OASOP, ONAME:
    72  	default:
    73  		Fatalf("unexpected op: %v", n.Op)
    74  	}
    75  	return Op(n.aux)
    76  }
    77  
    78  func (n *Node) SetSubOp(op Op) {
    79  	switch n.Op {
    80  	case OASOP, ONAME:
    81  	default:
    82  		Fatalf("unexpected op: %v", n.Op)
    83  	}
    84  	n.aux = uint8(op)
    85  }
    86  
    87  func (n *Node) IndexMapLValue() bool {
    88  	if n.Op != OINDEXMAP {
    89  		Fatalf("unexpected op: %v", n.Op)
    90  	}
    91  	return n.aux != 0
    92  }
    93  
    94  func (n *Node) SetIndexMapLValue(b bool) {
    95  	if n.Op != OINDEXMAP {
    96  		Fatalf("unexpected op: %v", n.Op)
    97  	}
    98  	if b {
    99  		n.aux = 1
   100  	} else {
   101  		n.aux = 0
   102  	}
   103  }
   104  
   105  func (n *Node) TChanDir() types.ChanDir {
   106  	if n.Op != OTCHAN {
   107  		Fatalf("unexpected op: %v", n.Op)
   108  	}
   109  	return types.ChanDir(n.aux)
   110  }
   111  
   112  func (n *Node) SetTChanDir(dir types.ChanDir) {
   113  	if n.Op != OTCHAN {
   114  		Fatalf("unexpected op: %v", n.Op)
   115  	}
   116  	n.aux = uint8(dir)
   117  }
   118  
   119  func (n *Node) IsSynthetic() bool {
   120  	name := n.Sym.Name
   121  	return name[0] == '.' || name[0] == '~'
   122  }
   123  
   124  // IsAutoTmp indicates if n was created by the compiler as a temporary,
   125  // based on the setting of the .AutoTemp flag in n's Name.
   126  func (n *Node) IsAutoTmp() bool {
   127  	if n == nil || n.Op != ONAME {
   128  		return false
   129  	}
   130  	return n.Name.AutoTemp()
   131  }
   132  
   133  const (
   134  	nodeClass, _     = iota, 1 << iota // PPARAM, PAUTO, PEXTERN, etc; three bits; first in the list because frequently accessed
   135  	_, _                               // second nodeClass bit
   136  	_, _                               // third nodeClass bit
   137  	nodeWalkdef, _                     // tracks state during typecheckdef; 2 == loop detected; two bits
   138  	_, _                               // second nodeWalkdef bit
   139  	nodeTypecheck, _                   // tracks state during typechecking; 2 == loop detected; two bits
   140  	_, _                               // second nodeTypecheck bit
   141  	nodeInitorder, _                   // tracks state during init1; two bits
   142  	_, _                               // second nodeInitorder bit
   143  	_, nodeHasBreak
   144  	_, nodeNoInline // used internally by inliner to indicate that a function call should not be inlined; set for OCALLFUNC and OCALLMETH only
   145  	_, nodeImplicit
   146  	_, nodeIsDDD     // is the argument variadic
   147  	_, nodeDiag      // already printed error about this
   148  	_, nodeColas     // OAS resulting from :=
   149  	_, nodeNonNil    // guaranteed to be non-nil
   150  	_, nodeTransient // storage can be reused immediately after this statement
   151  	_, nodeBounded   // bounds check unnecessary
   152  	_, nodeHasCall   // expression contains a function call
   153  	_, nodeLikely    // if statement condition likely
   154  	_, nodeHasVal    // node.E contains a Val
   155  	_, nodeHasOpt    // node.E contains an Opt
   156  	_, nodeEmbedded  // ODCLFIELD embedded type
   157  )
   158  
   159  func (n *Node) Class() Class     { return Class(n.flags.get3(nodeClass)) }
   160  func (n *Node) Walkdef() uint8   { return n.flags.get2(nodeWalkdef) }
   161  func (n *Node) Typecheck() uint8 { return n.flags.get2(nodeTypecheck) }
   162  func (n *Node) Initorder() uint8 { return n.flags.get2(nodeInitorder) }
   163  
   164  func (n *Node) HasBreak() bool  { return n.flags&nodeHasBreak != 0 }
   165  func (n *Node) NoInline() bool  { return n.flags&nodeNoInline != 0 }
   166  func (n *Node) Implicit() bool  { return n.flags&nodeImplicit != 0 }
   167  func (n *Node) IsDDD() bool     { return n.flags&nodeIsDDD != 0 }
   168  func (n *Node) Diag() bool      { return n.flags&nodeDiag != 0 }
   169  func (n *Node) Colas() bool     { return n.flags&nodeColas != 0 }
   170  func (n *Node) NonNil() bool    { return n.flags&nodeNonNil != 0 }
   171  func (n *Node) Transient() bool { return n.flags&nodeTransient != 0 }
   172  func (n *Node) Bounded() bool   { return n.flags&nodeBounded != 0 }
   173  func (n *Node) HasCall() bool   { return n.flags&nodeHasCall != 0 }
   174  func (n *Node) Likely() bool    { return n.flags&nodeLikely != 0 }
   175  func (n *Node) HasVal() bool    { return n.flags&nodeHasVal != 0 }
   176  func (n *Node) HasOpt() bool    { return n.flags&nodeHasOpt != 0 }
   177  func (n *Node) Embedded() bool  { return n.flags&nodeEmbedded != 0 }
   178  
   179  func (n *Node) SetClass(b Class)     { n.flags.set3(nodeClass, uint8(b)) }
   180  func (n *Node) SetWalkdef(b uint8)   { n.flags.set2(nodeWalkdef, b) }
   181  func (n *Node) SetTypecheck(b uint8) { n.flags.set2(nodeTypecheck, b) }
   182  func (n *Node) SetInitorder(b uint8) { n.flags.set2(nodeInitorder, b) }
   183  
   184  func (n *Node) SetHasBreak(b bool)  { n.flags.set(nodeHasBreak, b) }
   185  func (n *Node) SetNoInline(b bool)  { n.flags.set(nodeNoInline, b) }
   186  func (n *Node) SetImplicit(b bool)  { n.flags.set(nodeImplicit, b) }
   187  func (n *Node) SetIsDDD(b bool)     { n.flags.set(nodeIsDDD, b) }
   188  func (n *Node) SetDiag(b bool)      { n.flags.set(nodeDiag, b) }
   189  func (n *Node) SetColas(b bool)     { n.flags.set(nodeColas, b) }
   190  func (n *Node) SetNonNil(b bool)    { n.flags.set(nodeNonNil, b) }
   191  func (n *Node) SetTransient(b bool) { n.flags.set(nodeTransient, b) }
   192  func (n *Node) SetBounded(b bool)   { n.flags.set(nodeBounded, b) }
   193  func (n *Node) SetHasCall(b bool)   { n.flags.set(nodeHasCall, b) }
   194  func (n *Node) SetLikely(b bool)    { n.flags.set(nodeLikely, b) }
   195  func (n *Node) SetHasVal(b bool)    { n.flags.set(nodeHasVal, b) }
   196  func (n *Node) SetHasOpt(b bool)    { n.flags.set(nodeHasOpt, b) }
   197  func (n *Node) SetEmbedded(b bool)  { n.flags.set(nodeEmbedded, b) }
   198  
   199  // Val returns the Val for the node.
   200  func (n *Node) Val() Val {
   201  	if !n.HasVal() {
   202  		return Val{}
   203  	}
   204  	return Val{n.E}
   205  }
   206  
   207  // SetVal sets the Val for the node, which must not have been used with SetOpt.
   208  func (n *Node) SetVal(v Val) {
   209  	if n.HasOpt() {
   210  		Debug['h'] = 1
   211  		Dump("have Opt", n)
   212  		Fatalf("have Opt")
   213  	}
   214  	n.SetHasVal(true)
   215  	n.E = v.U
   216  }
   217  
   218  // Opt returns the optimizer data for the node.
   219  func (n *Node) Opt() interface{} {
   220  	if !n.HasOpt() {
   221  		return nil
   222  	}
   223  	return n.E
   224  }
   225  
   226  // SetOpt sets the optimizer data for the node, which must not have been used with SetVal.
   227  // SetOpt(nil) is ignored for Vals to simplify call sites that are clearing Opts.
   228  func (n *Node) SetOpt(x interface{}) {
   229  	if x == nil && n.HasVal() {
   230  		return
   231  	}
   232  	if n.HasVal() {
   233  		Debug['h'] = 1
   234  		Dump("have Val", n)
   235  		Fatalf("have Val")
   236  	}
   237  	n.SetHasOpt(true)
   238  	n.E = x
   239  }
   240  
   241  func (n *Node) Iota() int64 {
   242  	return n.Xoffset
   243  }
   244  
   245  func (n *Node) SetIota(x int64) {
   246  	n.Xoffset = x
   247  }
   248  
   249  // mayBeShared reports whether n may occur in multiple places in the AST.
   250  // Extra care must be taken when mutating such a node.
   251  func (n *Node) mayBeShared() bool {
   252  	switch n.Op {
   253  	case ONAME, OLITERAL, OTYPE:
   254  		return true
   255  	}
   256  	return false
   257  }
   258  
   259  // isMethodExpression reports whether n represents a method expression T.M.
   260  func (n *Node) isMethodExpression() bool {
   261  	return n.Op == ONAME && n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME
   262  }
   263  
   264  // funcname returns the name (without the package) of the function n.
   265  func (n *Node) funcname() string {
   266  	if n == nil || n.Func == nil || n.Func.Nname == nil {
   267  		return "<nil>"
   268  	}
   269  	return n.Func.Nname.Sym.Name
   270  }
   271  
   272  // pkgFuncName returns the name of the function referenced by n, with package prepended.
   273  // This differs from the compiler's internal convention where local functions lack a package
   274  // because the ultimate consumer of this is a human looking at an IDE; package is only empty
   275  // if the compilation package is actually the empty string.
   276  func (n *Node) pkgFuncName() string {
   277  	var s *types.Sym
   278  	if n == nil {
   279  		return "<nil>"
   280  	}
   281  	if n.Op == ONAME {
   282  		s = n.Sym
   283  	} else {
   284  		if n.Func == nil || n.Func.Nname == nil {
   285  			return "<nil>"
   286  		}
   287  		s = n.Func.Nname.Sym
   288  	}
   289  	pkg := s.Pkg
   290  
   291  	p := myimportpath
   292  	if pkg != nil && pkg.Path != "" {
   293  		p = pkg.Path
   294  	}
   295  	if p == "" {
   296  		return s.Name
   297  	}
   298  	return p + "." + s.Name
   299  }
   300  
   301  // Name holds Node fields used only by named nodes (ONAME, OTYPE, OPACK, OLABEL, some OLITERAL).
   302  type Name struct {
   303  	Pack      *Node      // real package for import . names
   304  	Pkg       *types.Pkg // pkg for OPACK nodes
   305  	Defn      *Node      // initializing assignment
   306  	Curfn     *Node      // function for local variables
   307  	Param     *Param     // additional fields for ONAME, OTYPE
   308  	Decldepth int32      // declaration loop depth, increased for every loop or label
   309  	Vargen    int32      // unique name for ONAME within a function.  Function outputs are numbered starting at one.
   310  	flags     bitset16
   311  }
   312  
   313  const (
   314  	nameCaptured = 1 << iota // is the variable captured by a closure
   315  	nameReadonly
   316  	nameByval                 // is the variable captured by value or by reference
   317  	nameNeedzero              // if it contains pointers, needs to be zeroed on function entry
   318  	nameKeepalive             // mark value live across unknown assembly call
   319  	nameAutoTemp              // is the variable a temporary (implies no dwarf info. reset if escapes to heap)
   320  	nameUsed                  // for variable declared and not used error
   321  	nameIsClosureVar          // PAUTOHEAP closure pseudo-variable; original at n.Name.Defn
   322  	nameIsOutputParamHeapAddr // pointer to a result parameter's heap copy
   323  	nameAssigned              // is the variable ever assigned to
   324  	nameAddrtaken             // address taken, even if not moved to heap
   325  	nameInlFormal             // PAUTO created by inliner, derived from callee formal
   326  	nameInlLocal              // PAUTO created by inliner, derived from callee local
   327  	nameOpenDeferSlot         // if temporary var storing info for open-coded defers
   328  	nameLibfuzzerExtraCounter // if PEXTERN should be assigned to __libfuzzer_extra_counters section
   329  )
   330  
   331  func (n *Name) Captured() bool              { return n.flags&nameCaptured != 0 }
   332  func (n *Name) Readonly() bool              { return n.flags&nameReadonly != 0 }
   333  func (n *Name) Byval() bool                 { return n.flags&nameByval != 0 }
   334  func (n *Name) Needzero() bool              { return n.flags&nameNeedzero != 0 }
   335  func (n *Name) Keepalive() bool             { return n.flags&nameKeepalive != 0 }
   336  func (n *Name) AutoTemp() bool              { return n.flags&nameAutoTemp != 0 }
   337  func (n *Name) Used() bool                  { return n.flags&nameUsed != 0 }
   338  func (n *Name) IsClosureVar() bool          { return n.flags&nameIsClosureVar != 0 }
   339  func (n *Name) IsOutputParamHeapAddr() bool { return n.flags&nameIsOutputParamHeapAddr != 0 }
   340  func (n *Name) Assigned() bool              { return n.flags&nameAssigned != 0 }
   341  func (n *Name) Addrtaken() bool             { return n.flags&nameAddrtaken != 0 }
   342  func (n *Name) InlFormal() bool             { return n.flags&nameInlFormal != 0 }
   343  func (n *Name) InlLocal() bool              { return n.flags&nameInlLocal != 0 }
   344  func (n *Name) OpenDeferSlot() bool         { return n.flags&nameOpenDeferSlot != 0 }
   345  func (n *Name) LibfuzzerExtraCounter() bool { return n.flags&nameLibfuzzerExtraCounter != 0 }
   346  
   347  func (n *Name) SetCaptured(b bool)              { n.flags.set(nameCaptured, b) }
   348  func (n *Name) SetReadonly(b bool)              { n.flags.set(nameReadonly, b) }
   349  func (n *Name) SetByval(b bool)                 { n.flags.set(nameByval, b) }
   350  func (n *Name) SetNeedzero(b bool)              { n.flags.set(nameNeedzero, b) }
   351  func (n *Name) SetKeepalive(b bool)             { n.flags.set(nameKeepalive, b) }
   352  func (n *Name) SetAutoTemp(b bool)              { n.flags.set(nameAutoTemp, b) }
   353  func (n *Name) SetUsed(b bool)                  { n.flags.set(nameUsed, b) }
   354  func (n *Name) SetIsClosureVar(b bool)          { n.flags.set(nameIsClosureVar, b) }
   355  func (n *Name) SetIsOutputParamHeapAddr(b bool) { n.flags.set(nameIsOutputParamHeapAddr, b) }
   356  func (n *Name) SetAssigned(b bool)              { n.flags.set(nameAssigned, b) }
   357  func (n *Name) SetAddrtaken(b bool)             { n.flags.set(nameAddrtaken, b) }
   358  func (n *Name) SetInlFormal(b bool)             { n.flags.set(nameInlFormal, b) }
   359  func (n *Name) SetInlLocal(b bool)              { n.flags.set(nameInlLocal, b) }
   360  func (n *Name) SetOpenDeferSlot(b bool)         { n.flags.set(nameOpenDeferSlot, b) }
   361  func (n *Name) SetLibfuzzerExtraCounter(b bool) { n.flags.set(nameLibfuzzerExtraCounter, b) }
   362  
   363  type Param struct {
   364  	Ntype    *Node
   365  	Heapaddr *Node // temp holding heap address of param
   366  
   367  	// ONAME PAUTOHEAP
   368  	Stackcopy *Node // the PPARAM/PPARAMOUT on-stack slot (moved func params only)
   369  
   370  	// ONAME closure linkage
   371  	// Consider:
   372  	//
   373  	//	func f() {
   374  	//		x := 1 // x1
   375  	//		func() {
   376  	//			use(x) // x2
   377  	//			func() {
   378  	//				use(x) // x3
   379  	//				--- parser is here ---
   380  	//			}()
   381  	//		}()
   382  	//	}
   383  	//
   384  	// There is an original declaration of x and then a chain of mentions of x
   385  	// leading into the current function. Each time x is mentioned in a new closure,
   386  	// we create a variable representing x for use in that specific closure,
   387  	// since the way you get to x is different in each closure.
   388  	//
   389  	// Let's number the specific variables as shown in the code:
   390  	// x1 is the original x, x2 is when mentioned in the closure,
   391  	// and x3 is when mentioned in the closure in the closure.
   392  	//
   393  	// We keep these linked (assume N > 1):
   394  	//
   395  	//   - x1.Defn = original declaration statement for x (like most variables)
   396  	//   - x1.Innermost = current innermost closure x (in this case x3), or nil for none
   397  	//   - x1.IsClosureVar() = false
   398  	//
   399  	//   - xN.Defn = x1, N > 1
   400  	//   - xN.IsClosureVar() = true, N > 1
   401  	//   - x2.Outer = nil
   402  	//   - xN.Outer = x(N-1), N > 2
   403  	//
   404  	//
   405  	// When we look up x in the symbol table, we always get x1.
   406  	// Then we can use x1.Innermost (if not nil) to get the x
   407  	// for the innermost known closure function,
   408  	// but the first reference in a closure will find either no x1.Innermost
   409  	// or an x1.Innermost with .Funcdepth < Funcdepth.
   410  	// In that case, a new xN must be created, linked in with:
   411  	//
   412  	//     xN.Defn = x1
   413  	//     xN.Outer = x1.Innermost
   414  	//     x1.Innermost = xN
   415  	//
   416  	// When we finish the function, we'll process its closure variables
   417  	// and find xN and pop it off the list using:
   418  	//
   419  	//     x1 := xN.Defn
   420  	//     x1.Innermost = xN.Outer
   421  	//
   422  	// We leave xN.Innermost set so that we can still get to the original
   423  	// variable quickly. Not shown here, but once we're
   424  	// done parsing a function and no longer need xN.Outer for the
   425  	// lexical x reference links as described above, closurebody
   426  	// recomputes xN.Outer as the semantic x reference link tree,
   427  	// even filling in x in intermediate closures that might not
   428  	// have mentioned it along the way to inner closures that did.
   429  	// See closurebody for details.
   430  	//
   431  	// During the eventual compilation, then, for closure variables we have:
   432  	//
   433  	//     xN.Defn = original variable
   434  	//     xN.Outer = variable captured in next outward scope
   435  	//                to make closure where xN appears
   436  	//
   437  	// Because of the sharding of pieces of the node, x.Defn means x.Name.Defn
   438  	// and x.Innermost/Outer means x.Name.Param.Innermost/Outer.
   439  	Innermost *Node
   440  	Outer     *Node
   441  
   442  	// OTYPE
   443  	//
   444  	// TODO: Should Func pragmas also be stored on the Name?
   445  	Pragma syntax.Pragma
   446  	Alias  bool // node is alias for Ntype (only used when type-checking ODCLTYPE)
   447  }
   448  
   449  // Functions
   450  //
   451  // A simple function declaration is represented as an ODCLFUNC node f
   452  // and an ONAME node n. They're linked to one another through
   453  // f.Func.Nname == n and n.Name.Defn == f. When functions are
   454  // referenced by name in an expression, the function's ONAME node is
   455  // used directly.
   456  //
   457  // Function names have n.Class() == PFUNC. This distinguishes them
   458  // from variables of function type.
   459  //
   460  // Confusingly, n.Func and f.Func both exist, but commonly point to
   461  // different Funcs. (Exception: an OCALLPART's Func does point to its
   462  // ODCLFUNC's Func.)
   463  //
   464  // A method declaration is represented like functions, except n.Sym
   465  // will be the qualified method name (e.g., "T.m") and
   466  // f.Func.Shortname is the bare method name (e.g., "m").
   467  //
   468  // Method expressions are represented as ONAME/PFUNC nodes like
   469  // function names, but their Left and Right fields still point to the
   470  // type and method, respectively. They can be distinguished from
   471  // normal functions with isMethodExpression. Also, unlike function
   472  // name nodes, method expression nodes exist for each method
   473  // expression. The declaration ONAME can be accessed with
   474  // x.Type.Nname(), where x is the method expression ONAME node.
   475  //
   476  // Method values are represented by ODOTMETH/ODOTINTER when called
   477  // immediately, and OCALLPART otherwise. They are like method
   478  // expressions, except that for ODOTMETH/ODOTINTER the method name is
   479  // stored in Sym instead of Right.
   480  //
   481  // Closures are represented by OCLOSURE node c. They link back and
   482  // forth with the ODCLFUNC via Func.Closure; that is, c.Func.Closure
   483  // == f and f.Func.Closure == c.
   484  //
   485  // Function bodies are stored in f.Nbody, and inline function bodies
   486  // are stored in n.Func.Inl. Pragmas are stored in f.Func.Pragma.
   487  //
   488  // Imported functions skip the ODCLFUNC, so n.Name.Defn is nil. They
   489  // also use Dcl instead of Inldcl.
   490  
   491  // Func holds Node fields used only with function-like nodes.
   492  type Func struct {
   493  	Shortname *types.Sym
   494  	Enter     Nodes // for example, allocate and initialize memory for escaping parameters
   495  	Exit      Nodes
   496  	Cvars     Nodes   // closure params
   497  	Dcl       []*Node // autodcl for this func/closure
   498  
   499  	// Parents records the parent scope of each scope within a
   500  	// function. The root scope (0) has no parent, so the i'th
   501  	// scope's parent is stored at Parents[i-1].
   502  	Parents []ScopeID
   503  
   504  	// Marks records scope boundary changes.
   505  	Marks []Mark
   506  
   507  	// Closgen tracks how many closures have been generated within
   508  	// this function. Used by closurename for creating unique
   509  	// function names.
   510  	Closgen int
   511  
   512  	FieldTrack map[*types.Sym]struct{}
   513  	DebugInfo  *ssa.FuncDebug
   514  	Ntype      *Node // signature
   515  	Top        int   // top context (ctxCallee, etc)
   516  	Closure    *Node // OCLOSURE <-> ODCLFUNC
   517  	Nname      *Node
   518  	lsym       *obj.LSym
   519  
   520  	Inl *Inline
   521  
   522  	Label int32 // largest auto-generated label in this function
   523  
   524  	Endlineno src.XPos
   525  	WBPos     src.XPos // position of first write barrier; see SetWBPos
   526  
   527  	Pragma syntax.Pragma // go:xxx function annotations
   528  
   529  	flags      bitset16
   530  	numDefers  int // number of defer calls in the function
   531  	numReturns int // number of explicit returns in the function
   532  
   533  	// nwbrCalls records the LSyms of functions called by this
   534  	// function for go:nowritebarrierrec analysis. Only filled in
   535  	// if nowritebarrierrecCheck != nil.
   536  	nwbrCalls *[]nowritebarrierrecCallSym
   537  }
   538  
   539  // An Inline holds fields used for function bodies that can be inlined.
   540  type Inline struct {
   541  	Cost int32 // heuristic cost of inlining this function
   542  
   543  	// Copies of Func.Dcl and Nbody for use during inlining.
   544  	Dcl  []*Node
   545  	Body []*Node
   546  }
   547  
   548  // A Mark represents a scope boundary.
   549  type Mark struct {
   550  	// Pos is the position of the token that marks the scope
   551  	// change.
   552  	Pos src.XPos
   553  
   554  	// Scope identifies the innermost scope to the right of Pos.
   555  	Scope ScopeID
   556  }
   557  
   558  // A ScopeID represents a lexical scope within a function.
   559  type ScopeID int32
   560  
   561  const (
   562  	funcDupok         = 1 << iota // duplicate definitions ok
   563  	funcWrapper                   // is method wrapper
   564  	funcNeedctxt                  // function uses context register (has closure variables)
   565  	funcReflectMethod             // function calls reflect.Type.Method or MethodByName
   566  	funcIsHiddenClosure
   567  	funcHasDefer                 // contains a defer statement
   568  	funcNilCheckDisabled         // disable nil checks when compiling this function
   569  	funcInlinabilityChecked      // inliner has already determined whether the function is inlinable
   570  	funcExportInline             // include inline body in export data
   571  	funcInstrumentBody           // add race/msan instrumentation during SSA construction
   572  	funcOpenCodedDeferDisallowed // can't do open-coded defers
   573  )
   574  
   575  func (f *Func) Dupok() bool                    { return f.flags&funcDupok != 0 }
   576  func (f *Func) Wrapper() bool                  { return f.flags&funcWrapper != 0 }
   577  func (f *Func) Needctxt() bool                 { return f.flags&funcNeedctxt != 0 }
   578  func (f *Func) ReflectMethod() bool            { return f.flags&funcReflectMethod != 0 }
   579  func (f *Func) IsHiddenClosure() bool          { return f.flags&funcIsHiddenClosure != 0 }
   580  func (f *Func) HasDefer() bool                 { return f.flags&funcHasDefer != 0 }
   581  func (f *Func) NilCheckDisabled() bool         { return f.flags&funcNilCheckDisabled != 0 }
   582  func (f *Func) InlinabilityChecked() bool      { return f.flags&funcInlinabilityChecked != 0 }
   583  func (f *Func) ExportInline() bool             { return f.flags&funcExportInline != 0 }
   584  func (f *Func) InstrumentBody() bool           { return f.flags&funcInstrumentBody != 0 }
   585  func (f *Func) OpenCodedDeferDisallowed() bool { return f.flags&funcOpenCodedDeferDisallowed != 0 }
   586  
   587  func (f *Func) SetDupok(b bool)                    { f.flags.set(funcDupok, b) }
   588  func (f *Func) SetWrapper(b bool)                  { f.flags.set(funcWrapper, b) }
   589  func (f *Func) SetNeedctxt(b bool)                 { f.flags.set(funcNeedctxt, b) }
   590  func (f *Func) SetReflectMethod(b bool)            { f.flags.set(funcReflectMethod, b) }
   591  func (f *Func) SetIsHiddenClosure(b bool)          { f.flags.set(funcIsHiddenClosure, b) }
   592  func (f *Func) SetHasDefer(b bool)                 { f.flags.set(funcHasDefer, b) }
   593  func (f *Func) SetNilCheckDisabled(b bool)         { f.flags.set(funcNilCheckDisabled, b) }
   594  func (f *Func) SetInlinabilityChecked(b bool)      { f.flags.set(funcInlinabilityChecked, b) }
   595  func (f *Func) SetExportInline(b bool)             { f.flags.set(funcExportInline, b) }
   596  func (f *Func) SetInstrumentBody(b bool)           { f.flags.set(funcInstrumentBody, b) }
   597  func (f *Func) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, b) }
   598  
   599  func (f *Func) setWBPos(pos src.XPos) {
   600  	if Debug_wb != 0 {
   601  		Warnl(pos, "write barrier")
   602  	}
   603  	if !f.WBPos.IsKnown() {
   604  		f.WBPos = pos
   605  	}
   606  }
   607  
   608  //go:generate stringer -type=Op -trimprefix=O
   609  
   610  type Op uint8
   611  
   612  // Node ops.
   613  const (
   614  	OXXX Op = iota
   615  
   616  	// names
   617  	ONAME    // var or func name
   618  	ONONAME  // unnamed arg or return value: f(int, string) (int, error) { etc }
   619  	OTYPE    // type name
   620  	OPACK    // import
   621  	OLITERAL // literal
   622  
   623  	// expressions
   624  	OADD          // Left + Right
   625  	OSUB          // Left - Right
   626  	OOR           // Left | Right
   627  	OXOR          // Left ^ Right
   628  	OADDSTR       // +{List} (string addition, list elements are strings)
   629  	OADDR         // &Left
   630  	OANDAND       // Left && Right
   631  	OAPPEND       // append(List); after walk, Left may contain elem type descriptor
   632  	OBYTES2STR    // Type(Left) (Type is string, Left is a []byte)
   633  	OBYTES2STRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral)
   634  	ORUNES2STR    // Type(Left) (Type is string, Left is a []rune)
   635  	OSTR2BYTES    // Type(Left) (Type is []byte, Left is a string)
   636  	OSTR2BYTESTMP // Type(Left) (Type is []byte, Left is a string, ephemeral)
   637  	OSTR2RUNES    // Type(Left) (Type is []rune, Left is a string)
   638  	OAS           // Left = Right or (if Colas=true) Left := Right
   639  	OAS2          // List = Rlist (x, y, z = a, b, c)
   640  	OAS2DOTTYPE   // List = Right (x, ok = I.(int))
   641  	OAS2FUNC      // List = Right (x, y = f())
   642  	OAS2MAPR      // List = Right (x, ok = m["foo"])
   643  	OAS2RECV      // List = Right (x, ok = <-c)
   644  	OASOP         // Left Etype= Right (x += y)
   645  	OCALL         // Left(List) (function call, method call or type conversion)
   646  
   647  	// OCALLFUNC, OCALLMETH, and OCALLINTER have the same structure.
   648  	// Prior to walk, they are: Left(List), where List is all regular arguments.
   649  	// If present, Right is an ODDDARG that holds the
   650  	// generated slice used in a call to a variadic function.
   651  	// After walk, List is a series of assignments to temporaries,
   652  	// and Rlist is an updated set of arguments, including any ODDDARG slice.
   653  	// TODO(josharian/khr): Use Ninit instead of List for the assignments to temporaries. See CL 114797.
   654  	OCALLFUNC  // Left(List/Rlist) (function call f(args))
   655  	OCALLMETH  // Left(List/Rlist) (direct method call x.Method(args))
   656  	OCALLINTER // Left(List/Rlist) (interface method call x.Method(args))
   657  	OCALLPART  // Left.Right (method expression x.Method, not called)
   658  	OCAP       // cap(Left)
   659  	OCLOSE     // close(Left)
   660  	OCLOSURE   // func Type { Body } (func literal)
   661  	OCOMPLIT   // Right{List} (composite literal, not yet lowered to specific form)
   662  	OMAPLIT    // Type{List} (composite literal, Type is map)
   663  	OSTRUCTLIT // Type{List} (composite literal, Type is struct)
   664  	OARRAYLIT  // Type{List} (composite literal, Type is array)
   665  	OSLICELIT  // Type{List} (composite literal, Type is slice) Right.Int64() = slice length.
   666  	OPTRLIT    // &Left (left is composite literal)
   667  	OCONV      // Type(Left) (type conversion)
   668  	OCONVIFACE // Type(Left) (type conversion, to interface)
   669  	OCONVNOP   // Type(Left) (type conversion, no effect)
   670  	OCOPY      // copy(Left, Right)
   671  	ODCL       // var Left (declares Left of type Left.Type)
   672  
   673  	// Used during parsing but don't last.
   674  	ODCLFUNC  // func f() or func (r) f()
   675  	ODCLFIELD // struct field, interface field, or func/method argument/return value.
   676  	ODCLCONST // const pi = 3.14
   677  	ODCLTYPE  // type Int int or type Int = int
   678  
   679  	ODELETE      // delete(Left, Right)
   680  	ODOT         // Left.Sym (Left is of struct type)
   681  	ODOTPTR      // Left.Sym (Left is of pointer to struct type)
   682  	ODOTMETH     // Left.Sym (Left is non-interface, Right is method name)
   683  	ODOTINTER    // Left.Sym (Left is interface, Right is method name)
   684  	OXDOT        // Left.Sym (before rewrite to one of the preceding)
   685  	ODOTTYPE     // Left.Right or Left.Type (.Right during parsing, .Type once resolved); after walk, .Right contains address of interface type descriptor and .Right.Right contains address of concrete type descriptor
   686  	ODOTTYPE2    // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE); after walk, .Right contains address of interface type descriptor
   687  	OEQ          // Left == Right
   688  	ONE          // Left != Right
   689  	OLT          // Left < Right
   690  	OLE          // Left <= Right
   691  	OGE          // Left >= Right
   692  	OGT          // Left > Right
   693  	ODEREF       // *Left
   694  	OINDEX       // Left[Right] (index of array or slice)
   695  	OINDEXMAP    // Left[Right] (index of map)
   696  	OKEY         // Left:Right (key:value in struct/array/map literal)
   697  	OSTRUCTKEY   // Sym:Left (key:value in struct literal, after type checking)
   698  	OLEN         // len(Left)
   699  	OMAKE        // make(List) (before type checking converts to one of the following)
   700  	OMAKECHAN    // make(Type, Left) (type is chan)
   701  	OMAKEMAP     // make(Type, Left) (type is map)
   702  	OMAKESLICE   // make(Type, Left, Right) (type is slice)
   703  	OMUL         // Left * Right
   704  	ODIV         // Left / Right
   705  	OMOD         // Left % Right
   706  	OLSH         // Left << Right
   707  	ORSH         // Left >> Right
   708  	OAND         // Left & Right
   709  	OANDNOT      // Left &^ Right
   710  	ONEW         // new(Left); corresponds to calls to new in source code
   711  	ONEWOBJ      // runtime.newobject(n.Type); introduced by walk; Left is type descriptor
   712  	ONOT         // !Left
   713  	OBITNOT      // ^Left
   714  	OPLUS        // +Left
   715  	ONEG         // -Left
   716  	OOROR        // Left || Right
   717  	OPANIC       // panic(Left)
   718  	OPRINT       // print(List)
   719  	OPRINTN      // println(List)
   720  	OPAREN       // (Left)
   721  	OSEND        // Left <- Right
   722  	OSLICE       // Left[List[0] : List[1]] (Left is untypechecked or slice)
   723  	OSLICEARR    // Left[List[0] : List[1]] (Left is array)
   724  	OSLICESTR    // Left[List[0] : List[1]] (Left is string)
   725  	OSLICE3      // Left[List[0] : List[1] : List[2]] (Left is untypedchecked or slice)
   726  	OSLICE3ARR   // Left[List[0] : List[1] : List[2]] (Left is array)
   727  	OSLICEHEADER // sliceheader{Left, List[0], List[1]} (Left is unsafe.Pointer, List[0] is length, List[1] is capacity)
   728  	ORECOVER     // recover()
   729  	ORECV        // <-Left
   730  	ORUNESTR     // Type(Left) (Type is string, Left is rune)
   731  	OSELRECV     // Left = <-Right.Left: (appears as .Left of OCASE; Right.Op == ORECV)
   732  	OSELRECV2    // List = <-Right.Left: (appears as .Left of OCASE; count(List) == 2, Right.Op == ORECV)
   733  	OIOTA        // iota
   734  	OREAL        // real(Left)
   735  	OIMAG        // imag(Left)
   736  	OCOMPLEX     // complex(Left, Right) or complex(List[0]) where List[0] is a 2-result function call
   737  	OALIGNOF     // unsafe.Alignof(Left)
   738  	OOFFSETOF    // unsafe.Offsetof(Left)
   739  	OSIZEOF      // unsafe.Sizeof(Left)
   740  
   741  	// statements
   742  	OBLOCK    // { List } (block of code)
   743  	OBREAK    // break [Sym]
   744  	OCASE     // case List: Nbody (List==nil means default)
   745  	OCONTINUE // continue [Sym]
   746  	ODEFER    // defer Left (Left must be call)
   747  	OEMPTY    // no-op (empty statement)
   748  	OFALL     // fallthrough
   749  	OFOR      // for Ninit; Left; Right { Nbody }
   750  	// OFORUNTIL is like OFOR, but the test (Left) is applied after the body:
   751  	// 	Ninit
   752  	// 	top: { Nbody }   // Execute the body at least once
   753  	// 	cont: Right
   754  	// 	if Left {        // And then test the loop condition
   755  	// 		List     // Before looping to top, execute List
   756  	// 		goto top
   757  	// 	}
   758  	// OFORUNTIL is created by walk. There's no way to write this in Go code.
   759  	OFORUNTIL
   760  	OGOTO   // goto Sym
   761  	OIF     // if Ninit; Left { Nbody } else { Rlist }
   762  	OLABEL  // Sym:
   763  	OGO     // go Left (Left must be call)
   764  	ORANGE  // for List = range Right { Nbody }
   765  	ORETURN // return List
   766  	OSELECT // select { List } (List is list of OCASE)
   767  	OSWITCH // switch Ninit; Left { List } (List is a list of OCASE)
   768  	OTYPESW // Left = Right.(type) (appears as .Left of OSWITCH)
   769  
   770  	// types
   771  	OTCHAN   // chan int
   772  	OTMAP    // map[string]int
   773  	OTSTRUCT // struct{}
   774  	OTINTER  // interface{}
   775  	OTFUNC   // func()
   776  	OTARRAY  // []int, [8]int, [N]int or [...]int
   777  
   778  	// misc
   779  	ODDD        // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
   780  	ODDDARG     // func f(args ...int), introduced by escape analysis.
   781  	OINLCALL    // intermediary representation of an inlined call.
   782  	OEFACE      // itable and data words of an empty-interface value.
   783  	OITAB       // itable word of an interface value.
   784  	OIDATA      // data word of an interface value in Left
   785  	OSPTR       // base pointer of a slice or string.
   786  	OCLOSUREVAR // variable reference at beginning of closure function
   787  	OCFUNC      // reference to c function pointer (not go func value)
   788  	OCHECKNIL   // emit code to ensure pointer/interface not nil
   789  	OVARDEF     // variable is about to be fully initialized
   790  	OVARKILL    // variable is dead
   791  	OVARLIVE    // variable is alive
   792  	ORESULT     // result of a function call; Xoffset is stack offset
   793  	OINLMARK    // start of an inlined body, with file/line of caller. Xoffset is an index into the inline tree.
   794  
   795  	// arch-specific opcodes
   796  	ORETJMP // return to other function
   797  	OGETG   // runtime.getg() (read g pointer)
   798  
   799  	OEND
   800  )
   801  
   802  // Nodes is a pointer to a slice of *Node.
   803  // For fields that are not used in most nodes, this is used instead of
   804  // a slice to save space.
   805  type Nodes struct{ slice *[]*Node }
   806  
   807  // asNodes returns a slice of *Node as a Nodes value.
   808  func asNodes(s []*Node) Nodes {
   809  	return Nodes{&s}
   810  }
   811  
   812  // Slice returns the entries in Nodes as a slice.
   813  // Changes to the slice entries (as in s[i] = n) will be reflected in
   814  // the Nodes.
   815  func (n Nodes) Slice() []*Node {
   816  	if n.slice == nil {
   817  		return nil
   818  	}
   819  	return *n.slice
   820  }
   821  
   822  // Len returns the number of entries in Nodes.
   823  func (n Nodes) Len() int {
   824  	if n.slice == nil {
   825  		return 0
   826  	}
   827  	return len(*n.slice)
   828  }
   829  
   830  // Index returns the i'th element of Nodes.
   831  // It panics if n does not have at least i+1 elements.
   832  func (n Nodes) Index(i int) *Node {
   833  	return (*n.slice)[i]
   834  }
   835  
   836  // First returns the first element of Nodes (same as n.Index(0)).
   837  // It panics if n has no elements.
   838  func (n Nodes) First() *Node {
   839  	return (*n.slice)[0]
   840  }
   841  
   842  // Second returns the second element of Nodes (same as n.Index(1)).
   843  // It panics if n has fewer than two elements.
   844  func (n Nodes) Second() *Node {
   845  	return (*n.slice)[1]
   846  }
   847  
   848  // Set sets n to a slice.
   849  // This takes ownership of the slice.
   850  func (n *Nodes) Set(s []*Node) {
   851  	if len(s) == 0 {
   852  		n.slice = nil
   853  	} else {
   854  		// Copy s and take address of t rather than s to avoid
   855  		// allocation in the case where len(s) == 0 (which is
   856  		// over 3x more common, dynamically, for make.bash).
   857  		t := s
   858  		n.slice = &t
   859  	}
   860  }
   861  
   862  // Set1 sets n to a slice containing a single node.
   863  func (n *Nodes) Set1(n1 *Node) {
   864  	n.slice = &[]*Node{n1}
   865  }
   866  
   867  // Set2 sets n to a slice containing two nodes.
   868  func (n *Nodes) Set2(n1, n2 *Node) {
   869  	n.slice = &[]*Node{n1, n2}
   870  }
   871  
   872  // Set3 sets n to a slice containing three nodes.
   873  func (n *Nodes) Set3(n1, n2, n3 *Node) {
   874  	n.slice = &[]*Node{n1, n2, n3}
   875  }
   876  
   877  // MoveNodes sets n to the contents of n2, then clears n2.
   878  func (n *Nodes) MoveNodes(n2 *Nodes) {
   879  	n.slice = n2.slice
   880  	n2.slice = nil
   881  }
   882  
   883  // SetIndex sets the i'th element of Nodes to node.
   884  // It panics if n does not have at least i+1 elements.
   885  func (n Nodes) SetIndex(i int, node *Node) {
   886  	(*n.slice)[i] = node
   887  }
   888  
   889  // SetFirst sets the first element of Nodes to node.
   890  // It panics if n does not have at least one elements.
   891  func (n Nodes) SetFirst(node *Node) {
   892  	(*n.slice)[0] = node
   893  }
   894  
   895  // SetSecond sets the second element of Nodes to node.
   896  // It panics if n does not have at least two elements.
   897  func (n Nodes) SetSecond(node *Node) {
   898  	(*n.slice)[1] = node
   899  }
   900  
   901  // Addr returns the address of the i'th element of Nodes.
   902  // It panics if n does not have at least i+1 elements.
   903  func (n Nodes) Addr(i int) **Node {
   904  	return &(*n.slice)[i]
   905  }
   906  
   907  // Append appends entries to Nodes.
   908  func (n *Nodes) Append(a ...*Node) {
   909  	if len(a) == 0 {
   910  		return
   911  	}
   912  	if n.slice == nil {
   913  		s := make([]*Node, len(a))
   914  		copy(s, a)
   915  		n.slice = &s
   916  		return
   917  	}
   918  	*n.slice = append(*n.slice, a...)
   919  }
   920  
   921  // Prepend prepends entries to Nodes.
   922  // If a slice is passed in, this will take ownership of it.
   923  func (n *Nodes) Prepend(a ...*Node) {
   924  	if len(a) == 0 {
   925  		return
   926  	}
   927  	if n.slice == nil {
   928  		n.slice = &a
   929  	} else {
   930  		*n.slice = append(a, *n.slice...)
   931  	}
   932  }
   933  
   934  // AppendNodes appends the contents of *n2 to n, then clears n2.
   935  func (n *Nodes) AppendNodes(n2 *Nodes) {
   936  	switch {
   937  	case n2.slice == nil:
   938  	case n.slice == nil:
   939  		n.slice = n2.slice
   940  	default:
   941  		*n.slice = append(*n.slice, *n2.slice...)
   942  	}
   943  	n2.slice = nil
   944  }
   945  
   946  // inspect invokes f on each node in an AST in depth-first order.
   947  // If f(n) returns false, inspect skips visiting n's children.
   948  func inspect(n *Node, f func(*Node) bool) {
   949  	if n == nil || !f(n) {
   950  		return
   951  	}
   952  	inspectList(n.Ninit, f)
   953  	inspect(n.Left, f)
   954  	inspect(n.Right, f)
   955  	inspectList(n.List, f)
   956  	inspectList(n.Nbody, f)
   957  	inspectList(n.Rlist, f)
   958  }
   959  
   960  func inspectList(l Nodes, f func(*Node) bool) {
   961  	for _, n := range l.Slice() {
   962  		inspect(n, f)
   963  	}
   964  }
   965  
   966  // nodeQueue is a FIFO queue of *Node. The zero value of nodeQueue is
   967  // a ready-to-use empty queue.
   968  type nodeQueue struct {
   969  	ring       []*Node
   970  	head, tail int
   971  }
   972  
   973  // empty reports whether q contains no Nodes.
   974  func (q *nodeQueue) empty() bool {
   975  	return q.head == q.tail
   976  }
   977  
   978  // pushRight appends n to the right of the queue.
   979  func (q *nodeQueue) pushRight(n *Node) {
   980  	if len(q.ring) == 0 {
   981  		q.ring = make([]*Node, 16)
   982  	} else if q.head+len(q.ring) == q.tail {
   983  		// Grow the ring.
   984  		nring := make([]*Node, len(q.ring)*2)
   985  		// Copy the old elements.
   986  		part := q.ring[q.head%len(q.ring):]
   987  		if q.tail-q.head <= len(part) {
   988  			part = part[:q.tail-q.head]
   989  			copy(nring, part)
   990  		} else {
   991  			pos := copy(nring, part)
   992  			copy(nring[pos:], q.ring[:q.tail%len(q.ring)])
   993  		}
   994  		q.ring, q.head, q.tail = nring, 0, q.tail-q.head
   995  	}
   996  
   997  	q.ring[q.tail%len(q.ring)] = n
   998  	q.tail++
   999  }
  1000  
  1001  // popLeft pops a node from the left of the queue. It panics if q is
  1002  // empty.
  1003  func (q *nodeQueue) popLeft() *Node {
  1004  	if q.empty() {
  1005  		panic("dequeue empty")
  1006  	}
  1007  	n := q.ring[q.head%len(q.ring)]
  1008  	q.head++
  1009  	return n
  1010  }
  1011  
  1012  // NodeSet is a set of Nodes.
  1013  type NodeSet map[*Node]struct{}
  1014  
  1015  // Has reports whether s contains n.
  1016  func (s NodeSet) Has(n *Node) bool {
  1017  	_, isPresent := s[n]
  1018  	return isPresent
  1019  }
  1020  
  1021  // Add adds n to s.
  1022  func (s *NodeSet) Add(n *Node) {
  1023  	if *s == nil {
  1024  		*s = make(map[*Node]struct{})
  1025  	}
  1026  	(*s)[n] = struct{}{}
  1027  }
  1028  
  1029  // Sorted returns s sorted according to less.
  1030  func (s NodeSet) Sorted(less func(*Node, *Node) bool) []*Node {
  1031  	var res []*Node
  1032  	for n := range s {
  1033  		res = append(res, n)
  1034  	}
  1035  	sort.Slice(res, func(i, j int) bool { return less(res[i], res[j]) })
  1036  	return res
  1037  }