github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/compile/internal/gc/noder.go (about) 1 // Copyright 2016 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 package gc 6 7 import ( 8 "fmt" 9 "os" 10 "strconv" 11 "strings" 12 "unicode/utf8" 13 14 "cmd/compile/internal/syntax" 15 ) 16 17 func parseFile(filename string) { 18 src, err := os.Open(filename) 19 if err != nil { 20 fmt.Println(err) 21 errorexit() 22 } 23 defer src.Close() 24 25 p := noder{baseline: lexlineno} 26 file, _ := syntax.Parse(src, p.error, p.pragma, 0) // errors are tracked via p.error 27 28 p.file(file) 29 30 if !imported_unsafe { 31 for _, x := range p.linknames { 32 p.error(syntax.Error{Line: x, Msg: "//go:linkname only allowed in Go files that import \"unsafe\""}) 33 } 34 } 35 36 if nsyntaxerrors == 0 { 37 // Always run testdclstack here, even when debug_dclstack is not set, as a sanity measure. 38 testdclstack() 39 } 40 } 41 42 // noder transforms package syntax's AST into a Nod tree. 43 type noder struct { 44 baseline int32 45 linknames []int // tracks //go:linkname lines 46 } 47 48 func (p *noder) file(file *syntax.File) { 49 p.lineno(file.PkgName) 50 mkpackage(file.PkgName.Value) 51 52 xtop = append(xtop, p.decls(file.DeclList)...) 53 54 lexlineno = p.baseline + int32(file.Lines) - 1 55 lineno = lexlineno 56 } 57 58 func (p *noder) decls(decls []syntax.Decl) (l []*Node) { 59 var lastConstGroup *syntax.Group 60 var lastConstRHS []*Node 61 var iotaVal int64 62 63 for _, decl := range decls { 64 p.lineno(decl) 65 switch decl := decl.(type) { 66 case *syntax.ImportDecl: 67 p.importDecl(decl) 68 69 case *syntax.VarDecl: 70 l = append(l, p.varDecl(decl)...) 71 72 case *syntax.ConstDecl: 73 // Tricky to handle golang.org/issue/15550 correctly. 74 75 prevIota := iota_ 76 77 if decl.Group == nil || decl.Group != lastConstGroup { 78 iotaVal = 0 79 lastConstRHS = nil 80 } 81 82 iota_ = iotaVal 83 lastconst = lastConstRHS 84 85 l = append(l, p.constDecl(decl)...) 86 87 lastConstRHS = lastconst 88 lastconst = nil 89 90 iota_ = prevIota 91 iotaVal++ 92 93 lastConstGroup = decl.Group 94 95 case *syntax.TypeDecl: 96 l = append(l, p.typeDecl(decl)) 97 98 case *syntax.FuncDecl: 99 l = append(l, p.funcDecl(decl)) 100 101 default: 102 panic("unhandled Decl") 103 } 104 } 105 106 return 107 } 108 109 func (p *noder) importDecl(imp *syntax.ImportDecl) { 110 val := p.basicLit(imp.Path) 111 importfile(&val, nil) 112 ipkg := importpkg 113 importpkg = nil 114 115 if ipkg == nil { 116 if nerrors == 0 { 117 Fatalf("phase error in import") 118 } 119 return 120 } 121 122 ipkg.Direct = true 123 124 var my *Sym 125 if imp.LocalPkgName != nil { 126 my = p.name(imp.LocalPkgName) 127 } else { 128 my = lookup(ipkg.Name) 129 } 130 131 pack := p.nod(imp, OPACK, nil, nil) 132 pack.Sym = my 133 pack.Name.Pkg = ipkg 134 135 if my.Name == "." { 136 importdot(ipkg, pack) 137 return 138 } 139 if my.Name == "init" { 140 yyerrorl(pack.Lineno, "cannot import package as init - init must be a func") 141 return 142 } 143 if my.Name == "_" { 144 return 145 } 146 if my.Def != nil { 147 lineno = pack.Lineno 148 redeclare(my, "as imported package name") 149 } 150 my.Def = pack 151 my.Lastlineno = pack.Lineno 152 my.Block = 1 // at top level 153 } 154 155 func (p *noder) varDecl(decl *syntax.VarDecl) []*Node { 156 names := p.declNames(decl.NameList) 157 158 var typ *Node 159 if decl.Type != nil { 160 typ = p.typeExpr(decl.Type) 161 } 162 163 var exprs []*Node 164 if decl.Values != nil { 165 exprs = p.exprList(decl.Values) 166 } 167 168 p.lineno(decl) 169 return variter(names, typ, exprs) 170 } 171 172 func (p *noder) constDecl(decl *syntax.ConstDecl) []*Node { 173 names := p.declNames(decl.NameList) 174 175 var typ *Node 176 if decl.Type != nil { 177 typ = p.typeExpr(decl.Type) 178 } 179 180 var exprs []*Node 181 if decl.Values != nil { 182 exprs = p.exprList(decl.Values) 183 } 184 185 return constiter(names, typ, exprs) 186 } 187 188 func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node { 189 name := typedcl0(p.name(decl.Name)) 190 name.Name.Param.Pragma = Pragma(decl.Pragma) 191 192 var typ *Node 193 if decl.Type != nil { 194 typ = p.typeExpr(decl.Type) 195 } 196 197 return typedcl1(name, typ, true) 198 } 199 200 func (p *noder) declNames(names []*syntax.Name) []*Node { 201 var nodes []*Node 202 for _, name := range names { 203 nodes = append(nodes, p.declName(name)) 204 } 205 return nodes 206 } 207 208 func (p *noder) declName(name *syntax.Name) *Node { 209 // TODO(mdempsky): Set lineno? 210 return dclname(p.name(name)) 211 } 212 213 func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node { 214 f := p.funcHeader(fun) 215 if f == nil { 216 return nil 217 } 218 219 var body []*Node 220 if fun.Body != nil { 221 body = p.stmts(fun.Body) 222 if body == nil { 223 body = []*Node{p.nod(fun, OEMPTY, nil, nil)} 224 } 225 } 226 227 pragma := Pragma(fun.Pragma) 228 229 f.Nbody.Set(body) 230 f.Noescape = pragma&Noescape != 0 231 if f.Noescape && len(body) != 0 { 232 yyerror("can only use //go:noescape with external func implementations") 233 } 234 f.Func.Pragma = pragma 235 lineno = p.baseline + int32(fun.EndLine) - 1 236 f.Func.Endlineno = lineno 237 238 funcbody(f) 239 240 return f 241 } 242 243 func (p *noder) funcHeader(fun *syntax.FuncDecl) *Node { 244 name := p.name(fun.Name) 245 t := p.signature(fun.Recv, fun.Type) 246 f := p.nod(fun, ODCLFUNC, nil, nil) 247 248 if fun.Recv == nil { 249 // FunctionName Signature 250 if name.Name == "init" { 251 name = renameinit() 252 if t.List.Len() > 0 || t.Rlist.Len() > 0 { 253 yyerror("func init must have no arguments and no return values") 254 } 255 } 256 257 if localpkg.Name == "main" && name.Name == "main" { 258 if t.List.Len() > 0 || t.Rlist.Len() > 0 { 259 yyerror("func main must have no arguments and no return values") 260 } 261 } 262 263 f.Func.Nname = newfuncname(name) 264 } else { 265 // Receiver MethodName Signature 266 267 f.Func.Shortname = newfuncname(name) 268 f.Func.Nname = methodname(f.Func.Shortname, t.Left.Right) 269 } 270 271 f.Func.Nname.Name.Defn = f 272 f.Func.Nname.Name.Param.Ntype = t // TODO: check if nname already has an ntype 273 274 declare(f.Func.Nname, PFUNC) 275 funchdr(f) 276 return f 277 } 278 279 func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *Node { 280 n := p.nod(typ, OTFUNC, nil, nil) 281 if recv != nil { 282 n.Left = p.param(recv, false, false) 283 } 284 n.List.Set(p.params(typ.ParamList, true)) 285 n.Rlist.Set(p.params(typ.ResultList, false)) 286 return n 287 } 288 289 func (p *noder) params(params []*syntax.Field, dddOk bool) []*Node { 290 var nodes []*Node 291 for i, param := range params { 292 p.lineno(param) 293 nodes = append(nodes, p.param(param, dddOk, i+1 == len(params))) 294 } 295 return nodes 296 } 297 298 func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node { 299 var name *Node 300 if param.Name != nil { 301 name = p.newname(param.Name) 302 } 303 304 typ := p.typeExpr(param.Type) 305 n := p.nod(param, ODCLFIELD, name, typ) 306 307 // rewrite ...T parameter 308 if typ.Op == ODDD { 309 if !dddOk { 310 yyerror("cannot use ... in receiver or result parameter list") 311 } else if !final { 312 yyerror("can only use ... with final parameter in list") 313 } 314 typ.Op = OTARRAY 315 typ.Right = typ.Left 316 typ.Left = nil 317 n.Isddd = true 318 if n.Left != nil { 319 n.Left.Isddd = true 320 } 321 } 322 323 return n 324 } 325 326 func (p *noder) exprList(expr syntax.Expr) []*Node { 327 if list, ok := expr.(*syntax.ListExpr); ok { 328 return p.exprs(list.ElemList) 329 } 330 return []*Node{p.expr(expr)} 331 } 332 333 func (p *noder) exprs(exprs []syntax.Expr) []*Node { 334 var nodes []*Node 335 for _, expr := range exprs { 336 nodes = append(nodes, p.expr(expr)) 337 } 338 return nodes 339 } 340 341 func (p *noder) expr(expr syntax.Expr) *Node { 342 p.lineno(expr) 343 switch expr := expr.(type) { 344 case nil: 345 return nil 346 case *syntax.Name: 347 return p.mkname(expr) 348 case *syntax.BasicLit: 349 return p.setlineno(expr, nodlit(p.basicLit(expr))) 350 351 case *syntax.CompositeLit: 352 n := p.nod(expr, OCOMPLIT, nil, nil) 353 if expr.Type != nil { 354 n.Right = p.expr(expr.Type) 355 } 356 l := p.exprs(expr.ElemList) 357 for i, e := range l { 358 l[i] = p.wrapname(expr.ElemList[i], e) 359 } 360 n.List.Set(l) 361 lineno = p.baseline + int32(expr.EndLine) - 1 362 return n 363 case *syntax.KeyValueExpr: 364 return p.nod(expr, OKEY, p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value))) 365 case *syntax.FuncLit: 366 closurehdr(p.typeExpr(expr.Type)) 367 body := p.stmts(expr.Body) 368 lineno = p.baseline + int32(expr.EndLine) - 1 369 return p.setlineno(expr, closurebody(body)) 370 case *syntax.ParenExpr: 371 return p.nod(expr, OPAREN, p.expr(expr.X), nil) 372 case *syntax.SelectorExpr: 373 // parser.new_dotname 374 obj := p.expr(expr.X) 375 if obj.Op == OPACK { 376 obj.Used = true 377 return oldname(restrictlookup(expr.Sel.Value, obj.Name.Pkg)) 378 } 379 return p.setlineno(expr, nodSym(OXDOT, obj, p.name(expr.Sel))) 380 case *syntax.IndexExpr: 381 return p.nod(expr, OINDEX, p.expr(expr.X), p.expr(expr.Index)) 382 case *syntax.SliceExpr: 383 op := OSLICE 384 if expr.Full { 385 op = OSLICE3 386 } 387 n := p.nod(expr, op, p.expr(expr.X), nil) 388 var index [3]*Node 389 for i, x := range expr.Index { 390 if x != nil { 391 index[i] = p.expr(x) 392 } 393 } 394 n.SetSliceBounds(index[0], index[1], index[2]) 395 return n 396 case *syntax.AssertExpr: 397 if expr.Type == nil { 398 panic("unexpected AssertExpr") 399 } 400 // TODO(mdempsky): parser.pexpr uses p.expr(), but 401 // seems like the type field should be parsed with 402 // ntype? Shrug, doesn't matter here. 403 return p.nod(expr, ODOTTYPE, p.expr(expr.X), p.expr(expr.Type)) 404 case *syntax.Operation: 405 x := p.expr(expr.X) 406 if expr.Y == nil { 407 if expr.Op == syntax.And { 408 x = unparen(x) // TODO(mdempsky): Needed? 409 if x.Op == OCOMPLIT { 410 // Special case for &T{...}: turn into (*T){...}. 411 // TODO(mdempsky): Switch back to p.nod after we 412 // get rid of gcCompat. 413 x.Right = nod(OIND, x.Right, nil) 414 x.Right.Implicit = true 415 return x 416 } 417 } 418 return p.nod(expr, p.unOp(expr.Op), x, nil) 419 } 420 return p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y)) 421 case *syntax.CallExpr: 422 n := p.nod(expr, OCALL, p.expr(expr.Fun), nil) 423 n.List.Set(p.exprs(expr.ArgList)) 424 n.Isddd = expr.HasDots 425 return n 426 427 case *syntax.ArrayType: 428 var len *Node 429 if expr.Len != nil { 430 len = p.expr(expr.Len) 431 } else { 432 len = p.nod(expr, ODDD, nil, nil) 433 } 434 return p.nod(expr, OTARRAY, len, p.typeExpr(expr.Elem)) 435 case *syntax.SliceType: 436 return p.nod(expr, OTARRAY, nil, p.typeExpr(expr.Elem)) 437 case *syntax.DotsType: 438 return p.nod(expr, ODDD, p.typeExpr(expr.Elem), nil) 439 case *syntax.StructType: 440 return p.structType(expr) 441 case *syntax.InterfaceType: 442 return p.interfaceType(expr) 443 case *syntax.FuncType: 444 return p.signature(nil, expr) 445 case *syntax.MapType: 446 return p.nod(expr, OTMAP, p.typeExpr(expr.Key), p.typeExpr(expr.Value)) 447 case *syntax.ChanType: 448 n := p.nod(expr, OTCHAN, p.typeExpr(expr.Elem), nil) 449 n.Etype = EType(p.chanDir(expr.Dir)) 450 return n 451 452 case *syntax.TypeSwitchGuard: 453 n := p.nod(expr, OTYPESW, nil, p.expr(expr.X)) 454 if expr.Lhs != nil { 455 n.Left = p.declName(expr.Lhs) 456 if isblank(n.Left) { 457 yyerror("invalid variable name %v in type switch", n.Left) 458 } 459 } 460 return n 461 } 462 panic("unhandled Expr") 463 } 464 465 func (p *noder) typeExpr(typ syntax.Expr) *Node { 466 // TODO(mdempsky): Be stricter? typecheck should handle errors anyway. 467 return p.expr(typ) 468 } 469 470 func (p *noder) chanDir(dir syntax.ChanDir) ChanDir { 471 switch dir { 472 case 0: 473 return Cboth 474 case syntax.SendOnly: 475 return Csend 476 case syntax.RecvOnly: 477 return Crecv 478 } 479 panic("unhandled ChanDir") 480 } 481 482 func (p *noder) structType(expr *syntax.StructType) *Node { 483 var l []*Node 484 for i, field := range expr.FieldList { 485 p.lineno(field) 486 var n *Node 487 if field.Name == nil { 488 n = p.embedded(field.Type) 489 } else { 490 n = p.nod(field, ODCLFIELD, p.newname(field.Name), p.typeExpr(field.Type)) 491 } 492 if i < len(expr.TagList) && expr.TagList[i] != nil { 493 n.SetVal(p.basicLit(expr.TagList[i])) 494 } 495 l = append(l, n) 496 } 497 498 p.lineno(expr) 499 n := p.nod(expr, OTSTRUCT, nil, nil) 500 n.List.Set(l) 501 return n 502 } 503 504 func (p *noder) interfaceType(expr *syntax.InterfaceType) *Node { 505 var l []*Node 506 for _, method := range expr.MethodList { 507 p.lineno(method) 508 var n *Node 509 if method.Name == nil { 510 n = p.nod(method, ODCLFIELD, nil, oldname(p.packname(method.Type))) 511 } else { 512 mname := p.newname(method.Name) 513 sig := p.typeExpr(method.Type) 514 sig.Left = fakethis() 515 n = p.nod(method, ODCLFIELD, mname, sig) 516 ifacedcl(n) 517 } 518 l = append(l, n) 519 } 520 521 n := p.nod(expr, OTINTER, nil, nil) 522 n.List.Set(l) 523 return n 524 } 525 526 func (p *noder) packname(expr syntax.Expr) *Sym { 527 switch expr := expr.(type) { 528 case *syntax.Name: 529 name := p.name(expr) 530 if n := oldname(name); n.Name != nil && n.Name.Pack != nil { 531 n.Name.Pack.Used = true 532 } 533 return name 534 case *syntax.SelectorExpr: 535 name := p.name(expr.X.(*syntax.Name)) 536 var pkg *Pkg 537 if name.Def == nil || name.Def.Op != OPACK { 538 yyerror("%v is not a package", name) 539 pkg = localpkg 540 } else { 541 name.Def.Used = true 542 pkg = name.Def.Name.Pkg 543 } 544 return restrictlookup(expr.Sel.Value, pkg) 545 } 546 panic(fmt.Sprintf("unexpected packname: %#v", expr)) 547 } 548 549 func (p *noder) embedded(typ syntax.Expr) *Node { 550 op, isStar := typ.(*syntax.Operation) 551 if isStar { 552 if op.Op != syntax.Mul || op.Y != nil { 553 panic("unexpected Operation") 554 } 555 typ = op.X 556 } 557 n := embedded(p.packname(typ), localpkg) 558 if isStar { 559 n.Right = p.nod(op, OIND, n.Right, nil) 560 } 561 return n 562 } 563 564 func (p *noder) stmts(stmts []syntax.Stmt) []*Node { 565 var nodes []*Node 566 for _, stmt := range stmts { 567 s := p.stmt(stmt) 568 if s == nil { 569 } else if s.Op == OBLOCK && s.Ninit.Len() == 0 { 570 nodes = append(nodes, s.List.Slice()...) 571 } else { 572 nodes = append(nodes, s) 573 } 574 } 575 return nodes 576 } 577 578 func (p *noder) stmt(stmt syntax.Stmt) *Node { 579 p.lineno(stmt) 580 switch stmt := stmt.(type) { 581 case *syntax.EmptyStmt: 582 return nil 583 case *syntax.LabeledStmt: 584 return p.labeledStmt(stmt) 585 case *syntax.BlockStmt: 586 return p.body(stmt.Body) 587 case *syntax.ExprStmt: 588 return p.wrapname(stmt, p.expr(stmt.X)) 589 case *syntax.SendStmt: 590 return p.nod(stmt, OSEND, p.expr(stmt.Chan), p.expr(stmt.Value)) 591 case *syntax.DeclStmt: 592 return liststmt(p.decls(stmt.DeclList)) 593 case *syntax.AssignStmt: 594 if stmt.Op != 0 && stmt.Op != syntax.Def { 595 n := p.nod(stmt, OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs)) 596 n.Implicit = stmt.Rhs == syntax.ImplicitOne 597 n.Etype = EType(p.binOp(stmt.Op)) 598 return n 599 } 600 601 lhs := p.exprList(stmt.Lhs) 602 rhs := p.exprList(stmt.Rhs) 603 604 n := p.nod(stmt, OAS, nil, nil) // assume common case 605 606 if stmt.Op == syntax.Def { 607 n.Colas = true 608 colasdefn(lhs, n) // modifies lhs, call before using lhs[0] in common case 609 } 610 611 if len(lhs) == 1 && len(rhs) == 1 { 612 // common case 613 n.Left = lhs[0] 614 n.Right = rhs[0] 615 } else { 616 n.Op = OAS2 617 n.List.Set(lhs) 618 n.Rlist.Set(rhs) 619 } 620 return n 621 622 case *syntax.BranchStmt: 623 var op Op 624 switch stmt.Tok { 625 case syntax.Break: 626 op = OBREAK 627 case syntax.Continue: 628 op = OCONTINUE 629 case syntax.Fallthrough: 630 op = OXFALL 631 case syntax.Goto: 632 op = OGOTO 633 default: 634 panic("unhandled BranchStmt") 635 } 636 n := p.nod(stmt, op, nil, nil) 637 if stmt.Label != nil { 638 n.Left = p.newname(stmt.Label) 639 } 640 if op == OGOTO { 641 n.Sym = dclstack // context, for goto restriction 642 } 643 if op == OXFALL { 644 n.Xoffset = int64(block) 645 } 646 return n 647 case *syntax.CallStmt: 648 var op Op 649 switch stmt.Tok { 650 case syntax.Defer: 651 op = ODEFER 652 case syntax.Go: 653 op = OPROC 654 default: 655 panic("unhandled CallStmt") 656 } 657 return p.nod(stmt, op, p.expr(stmt.Call), nil) 658 case *syntax.ReturnStmt: 659 var results []*Node 660 if stmt.Results != nil { 661 results = p.exprList(stmt.Results) 662 } 663 n := p.nod(stmt, ORETURN, nil, nil) 664 n.List.Set(results) 665 if n.List.Len() == 0 && Curfn != nil { 666 for _, ln := range Curfn.Func.Dcl { 667 if ln.Class == PPARAM { 668 continue 669 } 670 if ln.Class != PPARAMOUT { 671 break 672 } 673 if ln.Sym.Def != ln { 674 yyerror("%s is shadowed during return", ln.Sym.Name) 675 } 676 } 677 } 678 return n 679 case *syntax.IfStmt: 680 return p.ifStmt(stmt) 681 case *syntax.ForStmt: 682 return p.forStmt(stmt) 683 case *syntax.SwitchStmt: 684 return p.switchStmt(stmt) 685 case *syntax.SelectStmt: 686 return p.selectStmt(stmt) 687 } 688 panic("unhandled Stmt") 689 } 690 691 func (p *noder) body(body []syntax.Stmt) *Node { 692 l := p.bodyList(body) 693 if len(l) == 0 { 694 // TODO(mdempsky): Line number? 695 return nod(OEMPTY, nil, nil) 696 } 697 return liststmt(l) 698 } 699 700 func (p *noder) bodyList(body []syntax.Stmt) []*Node { 701 markdcl() 702 nodes := p.stmts(body) 703 popdcl() 704 return nodes 705 } 706 707 func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node { 708 markdcl() 709 n := p.nod(stmt, OIF, nil, nil) 710 if stmt.Init != nil { 711 n.Ninit.Set1(p.stmt(stmt.Init)) 712 } 713 if stmt.Cond != nil { 714 n.Left = p.expr(stmt.Cond) 715 } 716 n.Nbody.Set(p.bodyList(stmt.Then)) 717 if stmt.Else != nil { 718 e := p.stmt(stmt.Else) 719 if e.Op == OBLOCK && e.Ninit.Len() == 0 { 720 n.Rlist.Set(e.List.Slice()) 721 } else { 722 n.Rlist.Set1(e) 723 } 724 } 725 popdcl() 726 return n 727 } 728 729 func (p *noder) forStmt(stmt *syntax.ForStmt) *Node { 730 markdcl() 731 var n *Node 732 if r, ok := stmt.Init.(*syntax.RangeClause); ok { 733 if stmt.Cond != nil || stmt.Post != nil { 734 panic("unexpected RangeClause") 735 } 736 737 n = p.nod(r, ORANGE, nil, p.expr(r.X)) 738 if r.Lhs != nil { 739 lhs := p.exprList(r.Lhs) 740 n.List.Set(lhs) 741 if r.Def { 742 n.Colas = true 743 colasdefn(lhs, n) 744 } 745 } 746 } else { 747 n = p.nod(stmt, OFOR, nil, nil) 748 if stmt.Init != nil { 749 n.Ninit.Set1(p.stmt(stmt.Init)) 750 } 751 if stmt.Cond != nil { 752 n.Left = p.expr(stmt.Cond) 753 } 754 if stmt.Post != nil { 755 n.Right = p.stmt(stmt.Post) 756 } 757 } 758 n.Nbody.Set(p.bodyList(stmt.Body)) 759 popdcl() 760 return n 761 } 762 763 func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node { 764 markdcl() 765 n := p.nod(stmt, OSWITCH, nil, nil) 766 if stmt.Init != nil { 767 n.Ninit.Set1(p.stmt(stmt.Init)) 768 } 769 if stmt.Tag != nil { 770 n.Left = p.expr(stmt.Tag) 771 } 772 773 tswitch := n.Left 774 if tswitch != nil && (tswitch.Op != OTYPESW || tswitch.Left == nil) { 775 tswitch = nil 776 } 777 778 n.List.Set(p.caseClauses(stmt.Body, tswitch)) 779 780 popdcl() 781 return n 782 } 783 784 func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node) []*Node { 785 var nodes []*Node 786 for _, clause := range clauses { 787 p.lineno(clause) 788 markdcl() 789 n := p.nod(clause, OXCASE, nil, nil) 790 if clause.Cases != nil { 791 n.List.Set(p.exprList(clause.Cases)) 792 } 793 if tswitch != nil { 794 nn := newname(tswitch.Left.Sym) 795 declare(nn, dclcontext) 796 n.Rlist.Set1(nn) 797 // keep track of the instances for reporting unused 798 nn.Name.Defn = tswitch 799 } 800 n.Xoffset = int64(block) 801 n.Nbody.Set(p.stmts(clause.Body)) 802 popdcl() 803 nodes = append(nodes, n) 804 } 805 return nodes 806 } 807 808 func (p *noder) selectStmt(stmt *syntax.SelectStmt) *Node { 809 n := p.nod(stmt, OSELECT, nil, nil) 810 n.List.Set(p.commClauses(stmt.Body)) 811 return n 812 } 813 814 func (p *noder) commClauses(clauses []*syntax.CommClause) []*Node { 815 var nodes []*Node 816 for _, clause := range clauses { 817 p.lineno(clause) 818 markdcl() 819 n := p.nod(clause, OXCASE, nil, nil) 820 if clause.Comm != nil { 821 n.List.Set1(p.stmt(clause.Comm)) 822 } 823 n.Xoffset = int64(block) 824 n.Nbody.Set(p.stmts(clause.Body)) 825 popdcl() 826 nodes = append(nodes, n) 827 } 828 return nodes 829 } 830 831 func (p *noder) labeledStmt(label *syntax.LabeledStmt) *Node { 832 lhs := p.nod(label, OLABEL, p.newname(label.Label), nil) 833 lhs.Sym = dclstack 834 835 var ls *Node 836 if label.Stmt != nil { // TODO(mdempsky): Should always be present. 837 ls = p.stmt(label.Stmt) 838 } 839 840 lhs.Name.Defn = ls 841 l := []*Node{lhs} 842 if ls != nil { 843 if ls.Op == OBLOCK && ls.Ninit.Len() == 0 { 844 l = append(l, ls.List.Slice()...) 845 } else { 846 l = append(l, ls) 847 } 848 } 849 return liststmt(l) 850 } 851 852 var unOps = [...]Op{ 853 syntax.Recv: ORECV, 854 syntax.Mul: OIND, 855 syntax.And: OADDR, 856 857 syntax.Not: ONOT, 858 syntax.Xor: OCOM, 859 syntax.Add: OPLUS, 860 syntax.Sub: OMINUS, 861 } 862 863 func (p *noder) unOp(op syntax.Operator) Op { 864 if uint64(op) >= uint64(len(unOps)) || unOps[op] == 0 { 865 panic("invalid Operator") 866 } 867 return unOps[op] 868 } 869 870 var binOps = [...]Op{ 871 syntax.OrOr: OOROR, 872 syntax.AndAnd: OANDAND, 873 874 syntax.Eql: OEQ, 875 syntax.Neq: ONE, 876 syntax.Lss: OLT, 877 syntax.Leq: OLE, 878 syntax.Gtr: OGT, 879 syntax.Geq: OGE, 880 881 syntax.Add: OADD, 882 syntax.Sub: OSUB, 883 syntax.Or: OOR, 884 syntax.Xor: OXOR, 885 886 syntax.Mul: OMUL, 887 syntax.Div: ODIV, 888 syntax.Rem: OMOD, 889 syntax.And: OAND, 890 syntax.AndNot: OANDNOT, 891 syntax.Shl: OLSH, 892 syntax.Shr: ORSH, 893 } 894 895 func (p *noder) binOp(op syntax.Operator) Op { 896 if uint64(op) >= uint64(len(binOps)) || binOps[op] == 0 { 897 panic("invalid Operator") 898 } 899 return binOps[op] 900 } 901 902 func (p *noder) basicLit(lit *syntax.BasicLit) Val { 903 // TODO: Don't try to convert if we had syntax errors (conversions may fail). 904 // Use dummy values so we can continue to compile. Eventually, use a 905 // form of "unknown" literals that are ignored during type-checking so 906 // we can continue type-checking w/o spurious follow-up errors. 907 switch s := lit.Value; lit.Kind { 908 case syntax.IntLit: 909 x := new(Mpint) 910 x.SetString(s) 911 return Val{U: x} 912 913 case syntax.FloatLit: 914 x := newMpflt() 915 x.SetString(s) 916 return Val{U: x} 917 918 case syntax.ImagLit: 919 x := new(Mpcplx) 920 x.Imag.SetString(strings.TrimSuffix(s, "i")) 921 return Val{U: x} 922 923 case syntax.RuneLit: 924 var r rune 925 if u, err := strconv.Unquote(s); err == nil && len(u) > 0 { 926 // Package syntax already reported any errors. 927 // Check for them again though because 0 is a 928 // better fallback value for invalid rune 929 // literals than 0xFFFD. 930 if len(u) == 1 { 931 r = rune(u[0]) 932 } else { 933 r, _ = utf8.DecodeRuneInString(u) 934 } 935 } 936 x := new(Mpint) 937 x.SetInt64(int64(r)) 938 x.Rune = true 939 return Val{U: x} 940 941 case syntax.StringLit: 942 if len(s) > 0 && s[0] == '`' { 943 // strip carriage returns from raw string 944 s = strings.Replace(s, "\r", "", -1) 945 } 946 // Ignore errors because package syntax already reported them. 947 u, _ := strconv.Unquote(s) 948 return Val{U: u} 949 950 default: 951 panic("unhandled BasicLit kind") 952 } 953 } 954 955 func (p *noder) name(name *syntax.Name) *Sym { 956 return lookup(name.Value) 957 } 958 959 func (p *noder) mkname(name *syntax.Name) *Node { 960 // TODO(mdempsky): Set line number? 961 return mkname(p.name(name)) 962 } 963 964 func (p *noder) newname(name *syntax.Name) *Node { 965 // TODO(mdempsky): Set line number? 966 return newname(p.name(name)) 967 } 968 969 func (p *noder) wrapname(n syntax.Node, x *Node) *Node { 970 // These nodes do not carry line numbers. 971 // Introduce a wrapper node to give them the correct line. 972 switch x.Op { 973 case OTYPE, OLITERAL: 974 if x.Sym == nil { 975 break 976 } 977 fallthrough 978 case ONAME, ONONAME, OPACK: 979 x = p.nod(n, OPAREN, x, nil) 980 x.Implicit = true 981 } 982 return x 983 } 984 985 func (p *noder) nod(orig syntax.Node, op Op, left, right *Node) *Node { 986 return p.setlineno(orig, nod(op, left, right)) 987 } 988 989 func (p *noder) setlineno(src syntax.Node, dst *Node) *Node { 990 l := int32(src.Line()) 991 if l == 0 { 992 // TODO(mdempsky): Shouldn't happen. Fix package syntax. 993 return dst 994 } 995 dst.Lineno = p.baseline + l - 1 996 return dst 997 } 998 999 func (p *noder) lineno(n syntax.Node) { 1000 if n == nil { 1001 return 1002 } 1003 l := int32(n.Line()) 1004 if l == 0 { 1005 // TODO(mdempsky): Shouldn't happen. Fix package syntax. 1006 return 1007 } 1008 lineno = p.baseline + l - 1 1009 } 1010 1011 func (p *noder) error(err error) { 1012 line := p.baseline 1013 var msg string 1014 if err, ok := err.(syntax.Error); ok { 1015 line += int32(err.Line) - 1 1016 msg = err.Msg 1017 } else { 1018 msg = err.Error() 1019 } 1020 yyerrorl(line, "%s", msg) 1021 } 1022 1023 func (p *noder) pragma(pos, line int, text string) syntax.Pragma { 1024 switch { 1025 case strings.HasPrefix(text, "line "): 1026 // Want to use LastIndexByte below but it's not defined in Go1.4 and bootstrap fails. 1027 i := strings.LastIndex(text, ":") // look from right (Windows filenames may contain ':') 1028 if i < 0 { 1029 break 1030 } 1031 n, err := strconv.Atoi(text[i+1:]) 1032 if err != nil { 1033 // TODO: make this an error instead? it is almost certainly a bug. 1034 break 1035 } 1036 if n > 1e8 { 1037 p.error(syntax.Error{Pos: pos, Line: line, Msg: "line number out of range"}) 1038 errorexit() 1039 } 1040 if n <= 0 { 1041 break 1042 } 1043 lexlineno = p.baseline + int32(line) 1044 linehistupdate(text[5:i], n) 1045 1046 case strings.HasPrefix(text, "go:linkname "): 1047 // Record line number so we can emit an error later if 1048 // the file doesn't import package unsafe. 1049 p.linknames = append(p.linknames, line) 1050 1051 f := strings.Fields(text) 1052 if len(f) != 3 { 1053 p.error(syntax.Error{Pos: pos, Line: line, Msg: "usage: //go:linkname localname linkname"}) 1054 break 1055 } 1056 lookup(f[1]).Linkname = f[2] 1057 1058 case strings.HasPrefix(text, "go:cgo_"): 1059 lineno = p.baseline + int32(line) - 1 // pragcgo may call yyerror 1060 pragcgobuf += pragcgo(text) 1061 fallthrough // because of //go:cgo_unsafe_args 1062 default: 1063 verb := text 1064 if i := strings.Index(text, " "); i >= 0 { 1065 verb = verb[:i] 1066 } 1067 lineno = p.baseline + int32(line) - 1 // pragmaValue may call yyerror 1068 return syntax.Pragma(pragmaValue(verb)) 1069 } 1070 1071 return 0 1072 } 1073 1074 func mkname(sym *Sym) *Node { 1075 n := oldname(sym) 1076 if n.Name != nil && n.Name.Pack != nil { 1077 n.Name.Pack.Used = true 1078 } 1079 return n 1080 } 1081 1082 func unparen(x *Node) *Node { 1083 for x.Op == OPAREN { 1084 x = x.Left 1085 } 1086 return x 1087 }