github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/syntax.go (about)

     1  // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/gc/syntax.go
     2  
     3  // Copyright 2009 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // “Abstract” syntax representation.
     8  
     9  package gc
    10  
    11  // A Node is a single node in the syntax tree.
    12  // Actually the syntax tree is a syntax DAG, because there is only one
    13  // node with Op=ONAME for a given instance of a variable x.
    14  // The same is true for Op=OTYPE and Op=OLITERAL.
    15  type Node struct {
    16  	// Tree structure.
    17  	// Generic recursive walks should follow these fields.
    18  	Left  *Node
    19  	Right *Node
    20  	Ntest *Node
    21  	Nincr *Node
    22  	Ninit *NodeList
    23  	Nbody *NodeList
    24  	Nelse *NodeList
    25  	List  *NodeList
    26  	Rlist *NodeList
    27  
    28  	Op          uint8
    29  	Nointerface bool
    30  	Ullman      uint8 // sethi/ullman number
    31  	Addable     bool  // addressable
    32  	Etype       uint8 // op for OASOP, etype for OTYPE, exclam for export
    33  	Bounded     bool  // bounds check unnecessary
    34  	Class       uint8 // PPARAM, PAUTO, PEXTERN, etc
    35  	Method      bool  // OCALLMETH is direct method call
    36  	Embedded    uint8 // ODCLFIELD embedded type
    37  	Colas       bool  // OAS resulting from :=
    38  	Diag        uint8 // already printed error about this
    39  	Noescape    bool  // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360)
    40  	Walkdef     uint8
    41  	Typecheck   uint8
    42  	Local       bool
    43  	Dodata      uint8
    44  	Initorder   uint8
    45  	Used        bool
    46  	Isddd       bool // is the argument variadic
    47  	Readonly    bool
    48  	Implicit    bool
    49  	Addrtaken   bool  // address taken, even if not moved to heap
    50  	Assigned    bool  // is the variable ever assigned to
    51  	Captured    bool  // is the variable captured by a closure
    52  	Byval       bool  // is the variable captured by value or by reference
    53  	Reslice     bool  // this is a reslice x = x[0:y] or x = append(x, ...)
    54  	Likely      int8  // likeliness of if statement
    55  	Hasbreak    bool  // has break statement
    56  	Needzero    bool  // if it contains pointers, needs to be zeroed on function entry
    57  	Esc         uint8 // EscXXX
    58  	Funcdepth   int32
    59  
    60  	// most nodes
    61  	Type  *Type
    62  	Orig  *Node // original form, for printing, and tracking copies of ONAMEs
    63  	Nname *Node
    64  
    65  	// func
    66  	Func *Func
    67  
    68  	// OLITERAL
    69  	Val Val
    70  
    71  	// OREGISTER, OINDREG
    72  	Reg int16
    73  
    74  	// ONAME
    75  	Ntype     *Node
    76  	Defn      *Node // ONAME: initializing assignment; OLABEL: labeled statement
    77  	Pack      *Node // real package for import . names
    78  	Curfn     *Node // function for local variables
    79  	Paramfld  *Type // TFIELD for this PPARAM; also for ODOT, curfn
    80  	Decldepth int   // declaration loop depth, increased for every loop or label
    81  
    82  	// ONAME func param with PHEAP
    83  	Heapaddr   *Node // temp holding heap address of param
    84  	Outerexpr  *Node // expression copied into closure for variable
    85  	Stackparam *Node // OPARAM node referring to stack copy of param
    86  	Alloc      *Node // allocation call
    87  
    88  	// ONAME closure param with PPARAMREF
    89  	Outer   *Node // outer PPARAMREF in nested closure
    90  	Closure *Node // ONAME/PHEAP <-> ONAME/PPARAMREF
    91  	Top     int   // top context (Ecall, Eproc, etc)
    92  
    93  	// ONAME substitute while inlining
    94  	Inlvar *Node
    95  
    96  	// OPACK
    97  	Pkg *Pkg
    98  
    99  	// OARRAYLIT, OMAPLIT, OSTRUCTLIT.
   100  	Initplan *InitPlan
   101  
   102  	// Escape analysis.
   103  	Escflowsrc   *NodeList // flow(this, src)
   104  	Escretval    *NodeList // on OCALLxxx, list of dummy return values
   105  	Escloopdepth int       // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes
   106  
   107  	Sym      *Sym  // various
   108  	Vargen   int32 // unique name for OTYPE/ONAME
   109  	Lineno   int32
   110  	Xoffset  int64
   111  	Stkdelta int64 // offset added by stack frame compaction phase.
   112  	Ostk     int32 // 6g only
   113  	Iota     int32
   114  	Walkgen  uint32
   115  	Esclevel int32
   116  	Opt      interface{} // for optimization passes
   117  }
   118  
   119  // Func holds Node fields used only with function-like nodes.
   120  type Func struct {
   121  	Shortname *Node
   122  	Enter     *NodeList
   123  	Exit      *NodeList
   124  	Cvars     *NodeList // closure params
   125  	Dcl       *NodeList // autodcl for this func/closure
   126  	Inldcl    *NodeList // copy of dcl for use in inlining
   127  	Closgen   int
   128  	Outerfunc *Node
   129  
   130  	Inl     *NodeList // copy of the body for use in inlining
   131  	InlCost int32
   132  
   133  	Endlineno int32
   134  
   135  	Nosplit        bool // func should not execute on separate stack
   136  	Nowritebarrier bool // emit compiler error instead of write barrier
   137  	Dupok          bool // duplicate definitions ok
   138  	Wrapper        bool // is method wrapper
   139  	Needctxt       bool // function uses context register (has closure variables)
   140  }
   141  
   142  // Node ops.
   143  const (
   144  	OXXX = iota
   145  
   146  	// names
   147  	ONAME    // var, const or func name
   148  	ONONAME  // unnamed arg or return value: f(int, string) (int, error) { etc }
   149  	OTYPE    // type name
   150  	OPACK    // import
   151  	OLITERAL // literal
   152  
   153  	// expressions
   154  	OADD             // x + y
   155  	OSUB             // x - y
   156  	OOR              // x | y
   157  	OXOR             // x ^ y
   158  	OADDSTR          // s + "foo"
   159  	OADDR            // &x
   160  	OANDAND          // b0 && b1
   161  	OAPPEND          // append
   162  	OARRAYBYTESTR    // string(bytes)
   163  	OARRAYBYTESTRTMP // string(bytes) ephemeral
   164  	OARRAYRUNESTR    // string(runes)
   165  	OSTRARRAYBYTE    // []byte(s)
   166  	OSTRARRAYBYTETMP // []byte(s) ephemeral
   167  	OSTRARRAYRUNE    // []rune(s)
   168  	OAS              // x = y or x := y
   169  	OAS2             // x, y, z = xx, yy, zz
   170  	OAS2FUNC         // x, y = f()
   171  	OAS2RECV         // x, ok = <-c
   172  	OAS2MAPR         // x, ok = m["foo"]
   173  	OAS2DOTTYPE      // x, ok = I.(int)
   174  	OASOP            // x += y
   175  	OASWB            // OAS but with write barrier
   176  	OCALL            // function call, method call or type conversion, possibly preceded by defer or go.
   177  	OCALLFUNC        // f()
   178  	OCALLMETH        // t.Method()
   179  	OCALLINTER       // err.Error()
   180  	OCALLPART        // t.Method (without ())
   181  	OCAP             // cap
   182  	OCLOSE           // close
   183  	OCLOSURE         // f = func() { etc }
   184  	OCMPIFACE        // err1 == err2
   185  	OCMPSTR          // s1 == s2
   186  	OCOMPLIT         // composite literal, typechecking may convert to a more specific OXXXLIT.
   187  	OMAPLIT          // M{"foo":3, "bar":4}
   188  	OSTRUCTLIT       // T{x:3, y:4}
   189  	OARRAYLIT        // [2]int{3, 4}
   190  	OPTRLIT          // &T{x:3, y:4}
   191  	OCONV            // var i int; var u uint; i = int(u)
   192  	OCONVIFACE       // I(t)
   193  	OCONVNOP         // type Int int; var i int; var j Int; i = int(j)
   194  	OCOPY            // copy
   195  	ODCL             // var x int
   196  	ODCLFUNC         // func f() or func (r) f()
   197  	ODCLFIELD        // struct field, interface field, or func/method argument/return value.
   198  	ODCLCONST        // const pi = 3.14
   199  	ODCLTYPE         // type Int int
   200  	ODELETE          // delete
   201  	ODOT             // t.x
   202  	ODOTPTR          // p.x that is implicitly (*p).x
   203  	ODOTMETH         // t.Method
   204  	ODOTINTER        // err.Error
   205  	OXDOT            // t.x, typechecking may convert to a more specific ODOTXXX.
   206  	ODOTTYPE         // e = err.(MyErr)
   207  	ODOTTYPE2        // e, ok = err.(MyErr)
   208  	OEQ              // x == y
   209  	ONE              // x != y
   210  	OLT              // x < y
   211  	OLE              // x <= y
   212  	OGE              // x >= y
   213  	OGT              // x > y
   214  	OIND             // *p
   215  	OINDEX           // a[i]
   216  	OINDEXMAP        // m[s]
   217  	OKEY             // The x:3 in t{x:3, y:4}, the 1:2 in a[1:2], the 2:20 in [3]int{2:20}, etc.
   218  	OPARAM           // The on-stack copy of a parameter or return value that escapes.
   219  	OLEN             // len
   220  	OMAKE            // make, typechecking may convert to a more specific OMAKEXXX.
   221  	OMAKECHAN        // make(chan int)
   222  	OMAKEMAP         // make(map[string]int)
   223  	OMAKESLICE       // make([]int, 0)
   224  	OMUL             // *
   225  	ODIV             // x / y
   226  	OMOD             // x % y
   227  	OLSH             // x << u
   228  	ORSH             // x >> u
   229  	OAND             // x & y
   230  	OANDNOT          // x &^ y
   231  	ONEW             // new
   232  	ONOT             // !b
   233  	OCOM             // ^x
   234  	OPLUS            // +x
   235  	OMINUS           // -y
   236  	OOROR            // b1 || b2
   237  	OPANIC           // panic
   238  	OPRINT           // print
   239  	OPRINTN          // println
   240  	OPAREN           // (x)
   241  	OSEND            // c <- x
   242  	OSLICE           // v[1:2], typechecking may convert to a more specific OSLICEXXX.
   243  	OSLICEARR        // a[1:2]
   244  	OSLICESTR        // s[1:2]
   245  	OSLICE3          // v[1:2:3], typechecking may convert to OSLICE3ARR.
   246  	OSLICE3ARR       // a[1:2:3]
   247  	ORECOVER         // recover
   248  	ORECV            // <-c
   249  	ORUNESTR         // string(i)
   250  	OSELRECV         // case x = <-c:
   251  	OSELRECV2        // case x, ok = <-c:
   252  	OIOTA            // iota
   253  	OREAL            // real
   254  	OIMAG            // imag
   255  	OCOMPLEX         // complex
   256  
   257  	// statements
   258  	OBLOCK    // block of code
   259  	OBREAK    // break
   260  	OCASE     // case, after being verified by swt.c's casebody.
   261  	OXCASE    // case, before verification.
   262  	OCONTINUE // continue
   263  	ODEFER    // defer
   264  	OEMPTY    // no-op
   265  	OFALL     // fallthrough, after being verified by swt.c's casebody.
   266  	OXFALL    // fallthrough, before verification.
   267  	OFOR      // for
   268  	OGOTO     // goto
   269  	OIF       // if
   270  	OLABEL    // label:
   271  	OPROC     // go
   272  	ORANGE    // range
   273  	ORETURN   // return
   274  	OSELECT   // select
   275  	OSWITCH   // switch x
   276  	OTYPESW   // switch err.(type)
   277  
   278  	// types
   279  	OTCHAN   // chan int
   280  	OTMAP    // map[string]int
   281  	OTSTRUCT // struct{}
   282  	OTINTER  // interface{}
   283  	OTFUNC   // func()
   284  	OTARRAY  // []int, [8]int, [N]int or [...]int
   285  
   286  	// misc
   287  	ODDD        // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
   288  	ODDDARG     // func f(args ...int), introduced by escape analysis.
   289  	OINLCALL    // intermediary representation of an inlined call.
   290  	OEFACE      // itable and data words of an empty-interface value.
   291  	OITAB       // itable word of an interface value.
   292  	OSPTR       // base pointer of a slice or string.
   293  	OCLOSUREVAR // variable reference at beginning of closure function
   294  	OCFUNC      // reference to c function pointer (not go func value)
   295  	OCHECKNIL   // emit code to ensure pointer/interface not nil
   296  	OVARKILL    // variable is dead
   297  
   298  	// thearch-specific registers
   299  	OREGISTER // a register, such as AX.
   300  	OINDREG   // offset plus indirect of a register, such as 8(SP).
   301  
   302  	// arch-specific opcodes
   303  	OCMP    // compare: ACMP.
   304  	ODEC    // decrement: ADEC.
   305  	OINC    // increment: AINC.
   306  	OEXTEND // extend: ACWD/ACDQ/ACQO.
   307  	OHMUL   // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both).
   308  	OLROT   // left rotate: AROL.
   309  	ORROTC  // right rotate-carry: ARCR.
   310  	ORETJMP // return to other function
   311  	OPS     // compare parity set (for x86 NaN check)
   312  	OPC     // compare parity clear (for x86 NaN check)
   313  	OSQRT   // sqrt(float64), on systems that have hw support
   314  	OGETG   // runtime.getg() (read g pointer)
   315  
   316  	OEND
   317  )
   318  
   319  /*
   320   * Every node has a walkgen field.
   321   * If you want to do a traversal of a node graph that
   322   * might contain duplicates and want to avoid
   323   * visiting the same nodes twice, increment walkgen
   324   * before starting.  Then before processing a node, do
   325   *
   326   *	if(n->walkgen == walkgen)
   327   *		return;
   328   *	n->walkgen = walkgen;
   329   *
   330   * Such a walk cannot call another such walk recursively,
   331   * because of the use of the global walkgen.
   332   */
   333  var walkgen uint32
   334  
   335  // A NodeList is a linked list of nodes.
   336  // TODO(rsc): Some uses of NodeList should be made into slices.
   337  // The remaining ones probably just need a simple linked list,
   338  // not one with concatenation support.
   339  type NodeList struct {
   340  	N    *Node
   341  	Next *NodeList
   342  	End  *NodeList
   343  }
   344  
   345  // concat returns the concatenation of the lists a and b.
   346  // The storage taken by both is reused for the result.
   347  func concat(a *NodeList, b *NodeList) *NodeList {
   348  	if a == nil {
   349  		return b
   350  	}
   351  	if b == nil {
   352  		return a
   353  	}
   354  
   355  	a.End.Next = b
   356  	a.End = b.End
   357  	b.End = nil
   358  	return a
   359  }
   360  
   361  // list1 returns a one-element list containing n.
   362  func list1(n *Node) *NodeList {
   363  	if n == nil {
   364  		return nil
   365  	}
   366  	if n.Op == OBLOCK && n.Ninit == nil {
   367  		// Flatten list and steal storage.
   368  		// Poison pointer to catch errant uses.
   369  		l := n.List
   370  
   371  		n.List = nil
   372  		return l
   373  	}
   374  
   375  	l := new(NodeList)
   376  	l.N = n
   377  	l.End = l
   378  	return l
   379  }
   380  
   381  // list returns the result of appending n to l.
   382  func list(l *NodeList, n *Node) *NodeList {
   383  	return concat(l, list1(n))
   384  }
   385  
   386  // listsort sorts *l in place according to the 3-way comparison function f.
   387  // The algorithm is mergesort, so it is guaranteed to be O(n log n).
   388  func listsort(l **NodeList, f func(*Node, *Node) int) {
   389  	if *l == nil || (*l).Next == nil {
   390  		return
   391  	}
   392  
   393  	l1 := *l
   394  	l2 := *l
   395  	for {
   396  		l2 = l2.Next
   397  		if l2 == nil {
   398  			break
   399  		}
   400  		l2 = l2.Next
   401  		if l2 == nil {
   402  			break
   403  		}
   404  		l1 = l1.Next
   405  	}
   406  
   407  	l2 = l1.Next
   408  	l1.Next = nil
   409  	l2.End = (*l).End
   410  	(*l).End = l1
   411  
   412  	l1 = *l
   413  	listsort(&l1, f)
   414  	listsort(&l2, f)
   415  
   416  	if f(l1.N, l2.N) < 0 {
   417  		*l = l1
   418  	} else {
   419  		*l = l2
   420  		l2 = l1
   421  		l1 = *l
   422  	}
   423  
   424  	// now l1 == *l; and l1 < l2
   425  
   426  	var le *NodeList
   427  	for (l1 != nil) && (l2 != nil) {
   428  		for (l1.Next != nil) && f(l1.Next.N, l2.N) < 0 {
   429  			l1 = l1.Next
   430  		}
   431  
   432  		// l1 is last one from l1 that is < l2
   433  		le = l1.Next // le is the rest of l1, first one that is >= l2
   434  		if le != nil {
   435  			le.End = (*l).End
   436  		}
   437  
   438  		(*l).End = l1       // cut *l at l1
   439  		*l = concat(*l, l2) // glue l2 to *l's tail
   440  
   441  		l1 = l2 // l1 is the first element of *l that is < the new l2
   442  		l2 = le // ... because l2 now is the old tail of l1
   443  	}
   444  
   445  	*l = concat(*l, l2) // any remainder
   446  }
   447  
   448  // count returns the length of the list l.
   449  func count(l *NodeList) int {
   450  	n := int64(0)
   451  	for ; l != nil; l = l.Next {
   452  		n++
   453  	}
   454  	if int64(int(n)) != n { // Overflow.
   455  		Yyerror("too many elements in list")
   456  	}
   457  	return int(n)
   458  }