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 }