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 }