github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/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 // 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 Ninit Nodes 19 Nbody Nodes 20 List Nodes 21 Rlist Nodes 22 23 // most nodes 24 Type *Type 25 Orig *Node // original form, for printing, and tracking copies of ONAMEs 26 27 // func 28 Func *Func 29 30 // ONAME 31 Name *Name 32 33 Sym *Sym // various 34 E interface{} // Opt or Val, see methods below 35 36 // Various. Usually an offset into a struct. For example, ONAME nodes 37 // that refer to local variables use it to identify their stack frame 38 // position. ODOT, ODOTPTR, and OINDREG use it to indicate offset 39 // relative to their base address. ONAME nodes on the left side of an 40 // OKEY within an OSTRUCTLIT use it to store the named field's offset. 41 // OXCASE and OXFALL use it to validate the use of fallthrough. 42 // Possibly still more uses. If you find any, document them. 43 Xoffset int64 44 45 Lineno int32 46 47 // OREGISTER, OINDREG 48 Reg int16 49 50 Esc uint16 // EscXXX 51 52 Op Op 53 Ullman uint8 // sethi/ullman number 54 Addable bool // addressable 55 Etype EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg, ChanDir for OTCHAN 56 Bounded bool // bounds check unnecessary 57 Class Class // PPARAM, PAUTO, PEXTERN, etc 58 Embedded uint8 // ODCLFIELD embedded type 59 Colas bool // OAS resulting from := 60 Diag uint8 // already printed error about this 61 Noescape bool // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360) 62 Walkdef uint8 63 Typecheck uint8 64 Local bool 65 Dodata uint8 66 Initorder uint8 67 Used bool 68 Isddd bool // is the argument variadic 69 Implicit bool 70 Addrtaken bool // address taken, even if not moved to heap 71 Assigned bool // is the variable ever assigned to 72 Likely int8 // likeliness of if statement 73 Hasbreak bool // has break statement 74 hasVal int8 // +1 for Val, -1 for Opt, 0 for not yet set 75 } 76 77 // Val returns the Val for the node. 78 func (n *Node) Val() Val { 79 if n.hasVal != +1 { 80 return Val{} 81 } 82 return Val{n.E} 83 } 84 85 // SetVal sets the Val for the node, which must not have been used with SetOpt. 86 func (n *Node) SetVal(v Val) { 87 if n.hasVal == -1 { 88 Debug['h'] = 1 89 Dump("have Opt", n) 90 Fatalf("have Opt") 91 } 92 n.hasVal = +1 93 n.E = v.U 94 } 95 96 // Opt returns the optimizer data for the node. 97 func (n *Node) Opt() interface{} { 98 if n.hasVal != -1 { 99 return nil 100 } 101 return n.E 102 } 103 104 // SetOpt sets the optimizer data for the node, which must not have been used with SetVal. 105 // SetOpt(nil) is ignored for Vals to simplify call sites that are clearing Opts. 106 func (n *Node) SetOpt(x interface{}) { 107 if x == nil && n.hasVal >= 0 { 108 return 109 } 110 if n.hasVal == +1 { 111 Debug['h'] = 1 112 Dump("have Val", n) 113 Fatalf("have Val") 114 } 115 n.hasVal = -1 116 n.E = x 117 } 118 119 // Name holds Node fields used only by named nodes (ONAME, OPACK, some OLITERAL). 120 type Name struct { 121 Pack *Node // real package for import . names 122 Pkg *Pkg // pkg for OPACK nodes 123 Heapaddr *Node // temp holding heap address of param 124 Inlvar *Node // ONAME substitute while inlining 125 Defn *Node // initializing assignment 126 Curfn *Node // function for local variables 127 Param *Param 128 Decldepth int32 // declaration loop depth, increased for every loop or label 129 Vargen int32 // unique name for ONAME within a function. Function outputs are numbered starting at one. 130 Iota int32 // value if this name is iota 131 Funcdepth int32 132 Method bool // OCALLMETH name 133 Readonly bool 134 Captured bool // is the variable captured by a closure 135 Byval bool // is the variable captured by value or by reference 136 Needzero bool // if it contains pointers, needs to be zeroed on function entry 137 Keepalive bool // mark value live across unknown assembly call 138 } 139 140 type Param struct { 141 Ntype *Node 142 143 // ONAME func param with PHEAP 144 Outerexpr *Node // expression copied into closure for variable 145 Stackparam *Node // OPARAM node referring to stack copy of param 146 147 // ONAME PPARAM 148 Field *Field // TFIELD in arg struct 149 150 // ONAME closure param with PPARAMREF 151 Outer *Node // outer PPARAMREF in nested closure 152 Closure *Node // ONAME/PHEAP <-> ONAME/PPARAMREF 153 } 154 155 // Func holds Node fields used only with function-like nodes. 156 type Func struct { 157 Shortname *Node 158 Enter Nodes // for example, allocate and initialize memory for escaping parameters 159 Exit Nodes 160 Cvars Nodes // closure params 161 Dcl []*Node // autodcl for this func/closure 162 Inldcl Nodes // copy of dcl for use in inlining 163 Closgen int 164 Outerfunc *Node 165 FieldTrack map[*Sym]struct{} 166 Outer *Node // outer func for closure 167 Ntype *Node // signature 168 Top int // top context (Ecall, Eproc, etc) 169 Closure *Node // OCLOSURE <-> ODCLFUNC 170 FCurfn *Node 171 Nname *Node 172 173 Inl Nodes // copy of the body for use in inlining 174 InlCost int32 175 Depth int32 176 177 Endlineno int32 178 WBLineno int32 // line number of first write barrier 179 180 Pragma Pragma // go:xxx function annotations 181 Dupok bool // duplicate definitions ok 182 Wrapper bool // is method wrapper 183 Needctxt bool // function uses context register (has closure variables) 184 ReflectMethod bool // function calls reflect.Type.Method or MethodByName 185 } 186 187 type Op uint8 188 189 // Node ops. 190 const ( 191 OXXX = Op(iota) 192 193 // names 194 ONAME // var, const or func name 195 ONONAME // unnamed arg or return value: f(int, string) (int, error) { etc } 196 OTYPE // type name 197 OPACK // import 198 OLITERAL // literal 199 200 // expressions 201 OADD // Left + Right 202 OSUB // Left - Right 203 OOR // Left | Right 204 OXOR // Left ^ Right 205 OADDSTR // +{List} (string addition, list elements are strings) 206 OADDR // &Left 207 OANDAND // Left && Right 208 OAPPEND // append(List) 209 OARRAYBYTESTR // Type(Left) (Type is string, Left is a []byte) 210 OARRAYBYTESTRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral) 211 OARRAYRUNESTR // Type(Left) (Type is string, Left is a []rune) 212 OSTRARRAYBYTE // Type(Left) (Type is []byte, Left is a string) 213 OSTRARRAYBYTETMP // Type(Left) (Type is []byte, Left is a string, ephemeral) 214 OSTRARRAYRUNE // Type(Left) (Type is []rune, Left is a string) 215 OAS // Left = Right or (if Colas=true) Left := Right 216 OAS2 // List = Rlist (x, y, z = a, b, c) 217 OAS2FUNC // List = Rlist (x, y = f()) 218 OAS2RECV // List = Rlist (x, ok = <-c) 219 OAS2MAPR // List = Rlist (x, ok = m["foo"]) 220 OAS2DOTTYPE // List = Rlist (x, ok = I.(int)) 221 OASOP // Left Etype= Right (x += y) 222 OASWB // Left = Right (with write barrier) 223 OCALL // Left(List) (function call, method call or type conversion) 224 OCALLFUNC // Left(List) (function call f(args)) 225 OCALLMETH // Left(List) (direct method call x.Method(args)) 226 OCALLINTER // Left(List) (interface method call x.Method(args)) 227 OCALLPART // Left.Right (method expression x.Method, not called) 228 OCAP // cap(Left) 229 OCLOSE // close(Left) 230 OCLOSURE // func Type { Body } (func literal) 231 OCMPIFACE // Left Etype Right (interface comparison, x == y or x != y) 232 OCMPSTR // Left Etype Right (string comparison, x == y, x < y, etc) 233 OCOMPLIT // Right{List} (composite literal, not yet lowered to specific form) 234 OMAPLIT // Type{List} (composite literal, Type is map) 235 OSTRUCTLIT // Type{List} (composite literal, Type is struct) 236 OARRAYLIT // Type{List} (composite literal, Type is array or slice) 237 OPTRLIT // &Left (left is composite literal) 238 OCONV // Type(Left) (type conversion) 239 OCONVIFACE // Type(Left) (type conversion, to interface) 240 OCONVNOP // Type(Left) (type conversion, no effect) 241 OCOPY // copy(Left, Right) 242 ODCL // var Left (declares Left of type Left.Type) 243 244 // Used during parsing but don't last. 245 ODCLFUNC // func f() or func (r) f() 246 ODCLFIELD // struct field, interface field, or func/method argument/return value. 247 ODCLCONST // const pi = 3.14 248 ODCLTYPE // type Int int 249 250 ODELETE // delete(Left, Right) 251 ODOT // Left.Sym (Left is of struct type) 252 ODOTPTR // Left.Sym (Left is of pointer to struct type) 253 ODOTMETH // Left.Sym (Left is non-interface, Right is method name) 254 ODOTINTER // Left.Sym (Left is interface, Right is method name) 255 OXDOT // Left.Sym (before rewrite to one of the preceding) 256 ODOTTYPE // Left.Right or Left.Type (.Right during parsing, .Type once resolved) 257 ODOTTYPE2 // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE) 258 OEQ // Left == Right 259 ONE // Left != Right 260 OLT // Left < Right 261 OLE // Left <= Right 262 OGE // Left >= Right 263 OGT // Left > Right 264 OIND // *Left 265 OINDEX // Left[Right] (index of array or slice) 266 OINDEXMAP // Left[Right] (index of map) 267 OKEY // Left:Right (key:value in struct/array/map literal, or slice index pair) 268 OPARAM // variant of ONAME for on-stack copy of a parameter or return value that escapes. 269 OLEN // len(Left) 270 OMAKE // make(List) (before type checking converts to one of the following) 271 OMAKECHAN // make(Type, Left) (type is chan) 272 OMAKEMAP // make(Type, Left) (type is map) 273 OMAKESLICE // make(Type, Left, Right) (type is slice) 274 OMUL // Left * Right 275 ODIV // Left / Right 276 OMOD // Left % Right 277 OLSH // Left << Right 278 ORSH // Left >> Right 279 OAND // Left & Right 280 OANDNOT // Left &^ Right 281 ONEW // new(Left) 282 ONOT // !Left 283 OCOM // ^Left 284 OPLUS // +Left 285 OMINUS // -Left 286 OOROR // Left || Right 287 OPANIC // panic(Left) 288 OPRINT // print(List) 289 OPRINTN // println(List) 290 OPAREN // (Left) 291 OSEND // Left <- Right 292 OSLICE // Left[Right.Left : Right.Right] (Left is untypechecked or slice; Right.Op==OKEY) 293 OSLICEARR // Left[Right.Left : Right.Right] (Left is array) 294 OSLICESTR // Left[Right.Left : Right.Right] (Left is string) 295 OSLICE3 // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is untypedchecked or slice; R.Op and R.R.Op==OKEY) 296 OSLICE3ARR // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is array; R.Op and R.R.Op==OKEY) 297 ORECOVER // recover() 298 ORECV // <-Left 299 ORUNESTR // Type(Left) (Type is string, Left is rune) 300 OSELRECV // Left = <-Right.Left: (appears as .Left of OCASE; Right.Op == ORECV) 301 OSELRECV2 // List = <-Right.Left: (apperas as .Left of OCASE; count(List) == 2, Right.Op == ORECV) 302 OIOTA // iota 303 OREAL // real(Left) 304 OIMAG // imag(Left) 305 OCOMPLEX // complex(Left, Right) 306 307 // statements 308 OBLOCK // { List } (block of code) 309 OBREAK // break 310 OCASE // case List: Nbody (select case after processing; List==nil means default) 311 OXCASE // case List: Nbody (select case before processing; List==nil means default) 312 OCONTINUE // continue 313 ODEFER // defer Left (Left must be call) 314 OEMPTY // no-op (empty statement) 315 OFALL // fallthrough (after processing) 316 OXFALL // fallthrough (before processing) 317 OFOR // for Ninit; Left; Right { Nbody } 318 OGOTO // goto Left 319 OIF // if Ninit; Left { Nbody } else { Rlist } 320 OLABEL // Left: 321 OPROC // go Left (Left must be call) 322 ORANGE // for List = range Right { Nbody } 323 ORETURN // return List 324 OSELECT // select { List } (List is list of OXCASE or OCASE) 325 OSWITCH // switch Ninit; Left { List } (List is a list of OXCASE or OCASE) 326 OTYPESW // List = Left.(type) (appears as .Left of OSWITCH) 327 328 // types 329 OTCHAN // chan int 330 OTMAP // map[string]int 331 OTSTRUCT // struct{} 332 OTINTER // interface{} 333 OTFUNC // func() 334 OTARRAY // []int, [8]int, [N]int or [...]int 335 336 // misc 337 ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}. 338 ODDDARG // func f(args ...int), introduced by escape analysis. 339 OINLCALL // intermediary representation of an inlined call. 340 OEFACE // itable and data words of an empty-interface value. 341 OITAB // itable word of an interface value. 342 OSPTR // base pointer of a slice or string. 343 OCLOSUREVAR // variable reference at beginning of closure function 344 OCFUNC // reference to c function pointer (not go func value) 345 OCHECKNIL // emit code to ensure pointer/interface not nil 346 OVARKILL // variable is dead 347 OVARLIVE // variable is alive 348 349 // thearch-specific registers 350 OREGISTER // a register, such as AX. 351 OINDREG // offset plus indirect of a register, such as 8(SP). 352 353 // arch-specific opcodes 354 OCMP // compare: ACMP. 355 ODEC // decrement: ADEC. 356 OINC // increment: AINC. 357 OEXTEND // extend: ACWD/ACDQ/ACQO. 358 OHMUL // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both). 359 OLROT // left rotate: AROL. 360 ORROTC // right rotate-carry: ARCR. 361 ORETJMP // return to other function 362 OPS // compare parity set (for x86 NaN check) 363 OPC // compare parity clear (for x86 NaN check) 364 OSQRT // sqrt(float64), on systems that have hw support 365 OGETG // runtime.getg() (read g pointer) 366 367 OEND 368 ) 369 370 // Nodes is a pointer to a slice of *Node. 371 // For fields that are not used in most nodes, this is used instead of 372 // a slice to save space. 373 type Nodes struct{ slice *[]*Node } 374 375 // Slice returns the entries in Nodes as a slice. 376 // Changes to the slice entries (as in s[i] = n) will be reflected in 377 // the Nodes. 378 func (n Nodes) Slice() []*Node { 379 if n.slice == nil { 380 return nil 381 } 382 return *n.slice 383 } 384 385 // Len returns the number of entries in Nodes. 386 func (n Nodes) Len() int { 387 if n.slice == nil { 388 return 0 389 } 390 return len(*n.slice) 391 } 392 393 // Index returns the i'th element of Nodes. 394 // It panics if n does not have at least i+1 elements. 395 func (n Nodes) Index(i int) *Node { 396 return (*n.slice)[i] 397 } 398 399 // First returns the first element of Nodes (same as n.Index(0)). 400 // It panics if n has no elements. 401 func (n Nodes) First() *Node { 402 return (*n.slice)[0] 403 } 404 405 // Second returns the second element of Nodes (same as n.Index(1)). 406 // It panics if n has fewer than two elements. 407 func (n Nodes) Second() *Node { 408 return (*n.slice)[1] 409 } 410 411 // Set sets n to a slice. 412 // This takes ownership of the slice. 413 func (n *Nodes) Set(s []*Node) { 414 if len(s) == 0 { 415 n.slice = nil 416 } else { 417 // Copy s and take address of t rather than s to avoid 418 // allocation in the case where len(s) == 0 (which is 419 // over 3x more common, dynamically, for make.bash). 420 t := s 421 n.slice = &t 422 } 423 } 424 425 // Set1 sets n to a slice containing a single node. 426 func (n *Nodes) Set1(node *Node) { 427 n.slice = &[]*Node{node} 428 } 429 430 // MoveNodes sets n to the contents of n2, then clears n2. 431 func (n *Nodes) MoveNodes(n2 *Nodes) { 432 n.slice = n2.slice 433 n2.slice = nil 434 } 435 436 // SetIndex sets the i'th element of Nodes to node. 437 // It panics if n does not have at least i+1 elements. 438 func (n Nodes) SetIndex(i int, node *Node) { 439 (*n.slice)[i] = node 440 } 441 442 // Addr returns the address of the i'th element of Nodes. 443 // It panics if n does not have at least i+1 elements. 444 func (n Nodes) Addr(i int) **Node { 445 return &(*n.slice)[i] 446 } 447 448 // Append appends entries to Nodes. 449 // If a slice is passed in, this will take ownership of it. 450 func (n *Nodes) Append(a ...*Node) { 451 if n.slice == nil { 452 if len(a) > 0 { 453 n.slice = &a 454 } 455 } else { 456 *n.slice = append(*n.slice, a...) 457 } 458 } 459 460 // AppendNodes appends the contents of *n2 to n, then clears n2. 461 func (n *Nodes) AppendNodes(n2 *Nodes) { 462 switch { 463 case n2.slice == nil: 464 case n.slice == nil: 465 n.slice = n2.slice 466 default: 467 *n.slice = append(*n.slice, *n2.slice...) 468 } 469 n2.slice = nil 470 }