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