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