github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/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 Dupok bool // duplicate definitions ok 177 Wrapper bool // is method wrapper 178 Needctxt bool // function uses context register (has closure variables) 179 Systemstack bool // must run on system stack 180 } 181 182 type Op uint8 183 184 // Node ops. 185 const ( 186 OXXX = Op(iota) 187 188 // names 189 ONAME // var, const or func name 190 ONONAME // unnamed arg or return value: f(int, string) (int, error) { etc } 191 OTYPE // type name 192 OPACK // import 193 OLITERAL // literal 194 195 // expressions 196 OADD // Left + Right 197 OSUB // Left - Right 198 OOR // Left | Right 199 OXOR // Left ^ Right 200 OADDSTR // Left + Right (string addition) 201 OADDR // &Left 202 OANDAND // Left && Right 203 OAPPEND // append(List) 204 OARRAYBYTESTR // Type(Left) (Type is string, Left is a []byte) 205 OARRAYBYTESTRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral) 206 OARRAYRUNESTR // Type(Left) (Type is string, Left is a []rune) 207 OSTRARRAYBYTE // Type(Left) (Type is []byte, Left is a string) 208 OSTRARRAYBYTETMP // Type(Left) (Type is []byte, Left is a string, ephemeral) 209 OSTRARRAYRUNE // Type(Left) (Type is []rune, Left is a string) 210 OAS // Left = Right or (if Colas=true) Left := Right 211 OAS2 // List = Rlist (x, y, z = a, b, c) 212 OAS2FUNC // List = Rlist (x, y = f()) 213 OAS2RECV // List = Rlist (x, ok = <-c) 214 OAS2MAPR // List = Rlist (x, ok = m["foo"]) 215 OAS2DOTTYPE // List = Rlist (x, ok = I.(int)) 216 OASOP // Left Etype= Right (x += y) 217 OASWB // Left = Right (with write barrier) 218 OCALL // Left(List) (function call, method call or type conversion) 219 OCALLFUNC // Left(List) (function call f(args)) 220 OCALLMETH // Left(List) (direct method call x.Method(args)) 221 OCALLINTER // Left(List) (interface method call x.Method(args)) 222 OCALLPART // Left.Right (method expression x.Method, not called) 223 OCAP // cap(Left) 224 OCLOSE // close(Left) 225 OCLOSURE // func Type { Body } (func literal) 226 OCMPIFACE // Left Etype Right (interface comparison, x == y or x != y) 227 OCMPSTR // Left Etype Right (string comparison, x == y, x < y, etc) 228 OCOMPLIT // Right{List} (composite literal, not yet lowered to specific form) 229 OMAPLIT // Type{List} (composite literal, Type is map) 230 OSTRUCTLIT // Type{List} (composite literal, Type is struct) 231 OARRAYLIT // Type{List} (composite literal, Type is array or slice) 232 OPTRLIT // &Left (left is composite literal) 233 OCONV // Type(Left) (type conversion) 234 OCONVIFACE // Type(Left) (type conversion, to interface) 235 OCONVNOP // Type(Left) (type conversion, no effect) 236 OCOPY // copy(Left, Right) 237 ODCL // var Left (declares Left of type Left.Type) 238 239 // Used during parsing but don't last. 240 ODCLFUNC // func f() or func (r) f() 241 ODCLFIELD // struct field, interface field, or func/method argument/return value. 242 ODCLCONST // const pi = 3.14 243 ODCLTYPE // type Int int 244 245 ODELETE // delete(Left, Right) 246 ODOT // Left.Right (Left is of struct type) 247 ODOTPTR // Left.Right (Left is of pointer to struct type) 248 ODOTMETH // Left.Right (Left is non-interface, Right is method name) 249 ODOTINTER // Left.Right (Left is interface, Right is method name) 250 OXDOT // Left.Right (before rewrite to one of the preceding) 251 ODOTTYPE // Left.Right or Left.Type (.Right during parsing, .Type once resolved) 252 ODOTTYPE2 // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE) 253 OEQ // Left == Right 254 ONE // Left != Right 255 OLT // Left < Right 256 OLE // Left <= Right 257 OGE // Left >= Right 258 OGT // Left > Right 259 OIND // *Left 260 OINDEX // Left[Right] (index of array or slice) 261 OINDEXMAP // Left[Right] (index of map) 262 OKEY // Left:Right (key:value in struct/array/map literal, or slice index pair) 263 OPARAM // variant of ONAME for on-stack copy of a parameter or return value that escapes. 264 OLEN // len(Left) 265 OMAKE // make(List) (before type checking converts to one of the following) 266 OMAKECHAN // make(Type, Left) (type is chan) 267 OMAKEMAP // make(Type, Left) (type is map) 268 OMAKESLICE // make(Type, Left, Right) (type is slice) 269 OMUL // Left * Right 270 ODIV // Left / Right 271 OMOD // Left % Right 272 OLSH // Left << Right 273 ORSH // Left >> Right 274 OAND // Left & Right 275 OANDNOT // Left &^ Right 276 ONEW // new(Left) 277 ONOT // !Left 278 OCOM // ^Left 279 OPLUS // +Left 280 OMINUS // -Left 281 OOROR // Left || Right 282 OPANIC // panic(Left) 283 OPRINT // print(List) 284 OPRINTN // println(List) 285 OPAREN // (Left) 286 OSEND // Left <- Right 287 OSLICE // Left[Right.Left : Right.Right] (Left is untypechecked or slice; Right.Op==OKEY) 288 OSLICEARR // Left[Right.Left : Right.Right] (Left is array) 289 OSLICESTR // Left[Right.Left : Right.Right] (Left is string) 290 OSLICE3 // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is untypedchecked or slice; R.Op and R.R.Op==OKEY) 291 OSLICE3ARR // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is array; R.Op and R.R.Op==OKEY) 292 ORECOVER // recover() 293 ORECV // <-Left 294 ORUNESTR // Type(Left) (Type is string, Left is rune) 295 OSELRECV // Left = <-Right.Left: (appears as .Left of OCASE; Right.Op == ORECV) 296 OSELRECV2 // List = <-Right.Left: (apperas as .Left of OCASE; count(List) == 2, Right.Op == ORECV) 297 OIOTA // iota 298 OREAL // real(Left) 299 OIMAG // imag(Left) 300 OCOMPLEX // complex(Left, Right) 301 302 // statements 303 OBLOCK // { List } (block of code) 304 OBREAK // break 305 OCASE // case List: Nbody (select case after processing; List==nil means default) 306 OXCASE // case List: Nbody (select case before processing; List==nil means default) 307 OCONTINUE // continue 308 ODEFER // defer Left (Left must be call) 309 OEMPTY // no-op (empty statement) 310 OFALL // fallthrough (after processing) 311 OXFALL // fallthrough (before processing) 312 OFOR // for Ninit; Left; Right { Nbody } 313 OGOTO // goto Left 314 OIF // if Ninit; Left { Nbody } else { Rlist } 315 OLABEL // Left: 316 OPROC // go Left (Left must be call) 317 ORANGE // for List = range Right { Nbody } 318 ORETURN // return List 319 OSELECT // select { List } (List is list of OXCASE or OCASE) 320 OSWITCH // switch Ninit; Left { List } (List is a list of OXCASE or OCASE) 321 OTYPESW // List = Left.(type) (appears as .Left of OSWITCH) 322 323 // types 324 OTCHAN // chan int 325 OTMAP // map[string]int 326 OTSTRUCT // struct{} 327 OTINTER // interface{} 328 OTFUNC // func() 329 OTARRAY // []int, [8]int, [N]int or [...]int 330 331 // misc 332 ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}. 333 ODDDARG // func f(args ...int), introduced by escape analysis. 334 OINLCALL // intermediary representation of an inlined call. 335 OEFACE // itable and data words of an empty-interface value. 336 OITAB // itable word of an interface value. 337 OSPTR // base pointer of a slice or string. 338 OCLOSUREVAR // variable reference at beginning of closure function 339 OCFUNC // reference to c function pointer (not go func value) 340 OCHECKNIL // emit code to ensure pointer/interface not nil 341 OVARKILL // variable is dead 342 343 // thearch-specific registers 344 OREGISTER // a register, such as AX. 345 OINDREG // offset plus indirect of a register, such as 8(SP). 346 347 // arch-specific opcodes 348 OCMP // compare: ACMP. 349 ODEC // decrement: ADEC. 350 OINC // increment: AINC. 351 OEXTEND // extend: ACWD/ACDQ/ACQO. 352 OHMUL // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both). 353 OLROT // left rotate: AROL. 354 ORROTC // right rotate-carry: ARCR. 355 ORETJMP // return to other function 356 OPS // compare parity set (for x86 NaN check) 357 OPC // compare parity clear (for x86 NaN check) 358 OSQRT // sqrt(float64), on systems that have hw support 359 OGETG // runtime.getg() (read g pointer) 360 361 OEND 362 ) 363 364 // A NodeList is a linked list of nodes. 365 // TODO(rsc): Some uses of NodeList should be made into slices. 366 // The remaining ones probably just need a simple linked list, 367 // not one with concatenation support. 368 type NodeList struct { 369 N *Node 370 Next *NodeList 371 End *NodeList 372 } 373 374 // concat returns the concatenation of the lists a and b. 375 // The storage taken by both is reused for the result. 376 func concat(a *NodeList, b *NodeList) *NodeList { 377 if a == nil { 378 return b 379 } 380 if b == nil { 381 return a 382 } 383 384 a.End.Next = b 385 a.End = b.End 386 b.End = nil 387 return a 388 } 389 390 // list1 returns a one-element list containing n. 391 func list1(n *Node) *NodeList { 392 if n == nil { 393 return nil 394 } 395 if n.Op == OBLOCK && n.Ninit == nil { 396 // Flatten list and steal storage. 397 // Poison pointer to catch errant uses. 398 l := n.List 399 400 n.List = nil 401 return l 402 } 403 404 l := new(NodeList) 405 l.N = n 406 l.End = l 407 return l 408 } 409 410 // list returns the result of appending n to l. 411 func list(l *NodeList, n *Node) *NodeList { 412 return concat(l, list1(n)) 413 } 414 415 // listsort sorts *l in place according to the comparison function lt. 416 // The algorithm expects lt(a, b) to be equivalent to a < b. 417 // The algorithm is mergesort, so it is guaranteed to be O(n log n). 418 func listsort(l **NodeList, lt func(*Node, *Node) bool) { 419 if *l == nil || (*l).Next == nil { 420 return 421 } 422 423 l1 := *l 424 l2 := *l 425 for { 426 l2 = l2.Next 427 if l2 == nil { 428 break 429 } 430 l2 = l2.Next 431 if l2 == nil { 432 break 433 } 434 l1 = l1.Next 435 } 436 437 l2 = l1.Next 438 l1.Next = nil 439 l2.End = (*l).End 440 (*l).End = l1 441 442 l1 = *l 443 listsort(&l1, lt) 444 listsort(&l2, lt) 445 446 if lt(l1.N, l2.N) { 447 *l = l1 448 } else { 449 *l = l2 450 l2 = l1 451 l1 = *l 452 } 453 454 // now l1 == *l; and l1 < l2 455 456 var le *NodeList 457 for (l1 != nil) && (l2 != nil) { 458 for (l1.Next != nil) && lt(l1.Next.N, l2.N) { 459 l1 = l1.Next 460 } 461 462 // l1 is last one from l1 that is < l2 463 le = l1.Next // le is the rest of l1, first one that is >= l2 464 if le != nil { 465 le.End = (*l).End 466 } 467 468 (*l).End = l1 // cut *l at l1 469 *l = concat(*l, l2) // glue l2 to *l's tail 470 471 l1 = l2 // l1 is the first element of *l that is < the new l2 472 l2 = le // ... because l2 now is the old tail of l1 473 } 474 475 *l = concat(*l, l2) // any remainder 476 } 477 478 // count returns the length of the list l. 479 func count(l *NodeList) int { 480 n := int64(0) 481 for ; l != nil; l = l.Next { 482 n++ 483 } 484 if int64(int(n)) != n { // Overflow. 485 Yyerror("too many elements in list") 486 } 487 return int(n) 488 }