]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/noder/noder.go
[dev.typeparams] all: merge dev.regabi (7e0a81d) into dev.typeparams
[gostls13.git] / src / cmd / compile / internal / noder / noder.go
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 noder
6
7 import (
8         "fmt"
9         "go/constant"
10         "go/token"
11         "os"
12         "path/filepath"
13         "runtime"
14         "strconv"
15         "strings"
16         "unicode"
17         "unicode/utf8"
18
19         "cmd/compile/internal/base"
20         "cmd/compile/internal/dwarfgen"
21         "cmd/compile/internal/ir"
22         "cmd/compile/internal/syntax"
23         "cmd/compile/internal/typecheck"
24         "cmd/compile/internal/types"
25         "cmd/internal/objabi"
26         "cmd/internal/src"
27 )
28
29 func LoadPackage(filenames []string) {
30         base.Timer.Start("fe", "parse")
31
32         mode := syntax.CheckBranches
33         if base.Flag.G != 0 {
34                 mode |= syntax.AllowGenerics
35         }
36
37         // Limit the number of simultaneously open files.
38         sem := make(chan struct{}, runtime.GOMAXPROCS(0)+10)
39
40         noders := make([]*noder, len(filenames))
41         for i, filename := range filenames {
42                 p := noder{
43                         err:         make(chan syntax.Error),
44                         trackScopes: base.Flag.Dwarf,
45                 }
46                 noders[i] = &p
47
48                 filename := filename
49                 go func() {
50                         sem <- struct{}{}
51                         defer func() { <-sem }()
52                         defer close(p.err)
53                         fbase := syntax.NewFileBase(filename)
54
55                         f, err := os.Open(filename)
56                         if err != nil {
57                                 p.error(syntax.Error{Msg: err.Error()})
58                                 return
59                         }
60                         defer f.Close()
61
62                         p.file, _ = syntax.Parse(fbase, f, p.error, p.pragma, mode) // errors are tracked via p.error
63                 }()
64         }
65
66         var lines uint
67         for _, p := range noders {
68                 for e := range p.err {
69                         p.errorAt(e.Pos, "%s", e.Msg)
70                 }
71                 lines += p.file.EOF.Line()
72         }
73         base.Timer.AddEvent(int64(lines), "lines")
74
75         if base.Flag.G != 0 {
76                 // Use types2 to type-check and possibly generate IR.
77                 check2(noders)
78                 return
79         }
80
81         for _, p := range noders {
82                 p.node()
83                 p.file = nil // release memory
84         }
85
86         if base.SyntaxErrors() != 0 {
87                 base.ErrorExit()
88         }
89         types.CheckDclstack()
90
91         for _, p := range noders {
92                 p.processPragmas()
93         }
94
95         // Typecheck.
96         types.LocalPkg.Height = myheight
97         typecheck.DeclareUniverse()
98         typecheck.TypecheckAllowed = true
99
100         // Process top-level declarations in phases.
101
102         // Phase 1: const, type, and names and types of funcs.
103         //   This will gather all the information about types
104         //   and methods but doesn't depend on any of it.
105         //
106         //   We also defer type alias declarations until phase 2
107         //   to avoid cycles like #18640.
108         //   TODO(gri) Remove this again once we have a fix for #25838.
109
110         // Don't use range--typecheck can add closures to Target.Decls.
111         base.Timer.Start("fe", "typecheck", "top1")
112         for i := 0; i < len(typecheck.Target.Decls); i++ {
113                 n := typecheck.Target.Decls[i]
114                 if op := n.Op(); op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.(*ir.Decl).X.Alias()) {
115                         typecheck.Target.Decls[i] = typecheck.Stmt(n)
116                 }
117         }
118
119         // Phase 2: Variable assignments.
120         //   To check interface assignments, depends on phase 1.
121
122         // Don't use range--typecheck can add closures to Target.Decls.
123         base.Timer.Start("fe", "typecheck", "top2")
124         for i := 0; i < len(typecheck.Target.Decls); i++ {
125                 n := typecheck.Target.Decls[i]
126                 if op := n.Op(); op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.(*ir.Decl).X.Alias() {
127                         typecheck.Target.Decls[i] = typecheck.Stmt(n)
128                 }
129         }
130
131         // Phase 3: Type check function bodies.
132         // Don't use range--typecheck can add closures to Target.Decls.
133         base.Timer.Start("fe", "typecheck", "func")
134         var fcount int64
135         for i := 0; i < len(typecheck.Target.Decls); i++ {
136                 n := typecheck.Target.Decls[i]
137                 if n.Op() == ir.ODCLFUNC {
138                         if base.Flag.W > 1 {
139                                 s := fmt.Sprintf("\nbefore typecheck %v", n)
140                                 ir.Dump(s, n)
141                         }
142                         typecheck.FuncBody(n.(*ir.Func))
143                         if base.Flag.W > 1 {
144                                 s := fmt.Sprintf("\nafter typecheck %v", n)
145                                 ir.Dump(s, n)
146                         }
147                         fcount++
148                 }
149         }
150
151         // Phase 4: Check external declarations.
152         // TODO(mdempsky): This should be handled when type checking their
153         // corresponding ODCL nodes.
154         base.Timer.Start("fe", "typecheck", "externdcls")
155         for i, n := range typecheck.Target.Externs {
156                 if n.Op() == ir.ONAME {
157                         typecheck.Target.Externs[i] = typecheck.Expr(typecheck.Target.Externs[i])
158                 }
159         }
160
161         // Phase 5: With all user code type-checked, it's now safe to verify map keys.
162         // With all user code typechecked, it's now safe to verify unused dot imports.
163         typecheck.CheckMapKeys()
164         CheckDotImports()
165         base.ExitIfErrors()
166 }
167
168 func (p *noder) errorAt(pos syntax.Pos, format string, args ...interface{}) {
169         base.ErrorfAt(p.makeXPos(pos), format, args...)
170 }
171
172 // TODO(gri) Can we eliminate fileh in favor of absFilename?
173 func fileh(name string) string {
174         return objabi.AbsFile("", name, base.Flag.TrimPath)
175 }
176
177 func absFilename(name string) string {
178         return objabi.AbsFile(base.Ctxt.Pathname, name, base.Flag.TrimPath)
179 }
180
181 // noder transforms package syntax's AST into a Node tree.
182 type noder struct {
183         posMap
184
185         file           *syntax.File
186         linknames      []linkname
187         pragcgobuf     [][]string
188         err            chan syntax.Error
189         importedUnsafe bool
190         importedEmbed  bool
191         trackScopes    bool
192
193         funcState *funcState
194 }
195
196 // funcState tracks all per-function state to make handling nested
197 // functions easier.
198 type funcState struct {
199         // scopeVars is a stack tracking the number of variables declared in
200         // the current function at the moment each open scope was opened.
201         scopeVars []int
202         marker    dwarfgen.ScopeMarker
203
204         lastCloseScopePos syntax.Pos
205 }
206
207 func (p *noder) funcBody(fn *ir.Func, block *syntax.BlockStmt) {
208         outerFuncState := p.funcState
209         p.funcState = new(funcState)
210         typecheck.StartFuncBody(fn)
211
212         if block != nil {
213                 body := p.stmts(block.List)
214                 if body == nil {
215                         body = []ir.Node{ir.NewBlockStmt(base.Pos, nil)}
216                 }
217                 fn.Body = body
218
219                 base.Pos = p.makeXPos(block.Rbrace)
220                 fn.Endlineno = base.Pos
221         }
222
223         typecheck.FinishFuncBody()
224         p.funcState.marker.WriteTo(fn)
225         p.funcState = outerFuncState
226 }
227
228 func (p *noder) openScope(pos syntax.Pos) {
229         fs := p.funcState
230         types.Markdcl()
231
232         if p.trackScopes {
233                 fs.scopeVars = append(fs.scopeVars, len(ir.CurFunc.Dcl))
234                 fs.marker.Push(p.makeXPos(pos))
235         }
236 }
237
238 func (p *noder) closeScope(pos syntax.Pos) {
239         fs := p.funcState
240         fs.lastCloseScopePos = pos
241         types.Popdcl()
242
243         if p.trackScopes {
244                 scopeVars := fs.scopeVars[len(fs.scopeVars)-1]
245                 fs.scopeVars = fs.scopeVars[:len(fs.scopeVars)-1]
246                 if scopeVars == len(ir.CurFunc.Dcl) {
247                         // no variables were declared in this scope, so we can retract it.
248                         fs.marker.Unpush()
249                 } else {
250                         fs.marker.Pop(p.makeXPos(pos))
251                 }
252         }
253 }
254
255 // closeAnotherScope is like closeScope, but it reuses the same mark
256 // position as the last closeScope call. This is useful for "for" and
257 // "if" statements, as their implicit blocks always end at the same
258 // position as an explicit block.
259 func (p *noder) closeAnotherScope() {
260         p.closeScope(p.funcState.lastCloseScopePos)
261 }
262
263 // linkname records a //go:linkname directive.
264 type linkname struct {
265         pos    syntax.Pos
266         local  string
267         remote string
268 }
269
270 func (p *noder) node() {
271         p.importedUnsafe = false
272         p.importedEmbed = false
273
274         p.setlineno(p.file.PkgName)
275         mkpackage(p.file.PkgName.Value)
276
277         if pragma, ok := p.file.Pragma.(*pragmas); ok {
278                 pragma.Flag &^= ir.GoBuildPragma
279                 p.checkUnused(pragma)
280         }
281
282         typecheck.Target.Decls = append(typecheck.Target.Decls, p.decls(p.file.DeclList)...)
283
284         base.Pos = src.NoXPos
285         clearImports()
286 }
287
288 func (p *noder) processPragmas() {
289         for _, l := range p.linknames {
290                 if !p.importedUnsafe {
291                         p.errorAt(l.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
292                         continue
293                 }
294                 n := ir.AsNode(typecheck.Lookup(l.local).Def)
295                 if n == nil || n.Op() != ir.ONAME {
296                         // TODO(mdempsky): Change to p.errorAt before Go 1.17 release.
297                         // base.WarnfAt(p.makeXPos(l.pos), "//go:linkname must refer to declared function or variable (will be an error in Go 1.17)")
298                         continue
299                 }
300                 if n.Sym().Linkname != "" {
301                         p.errorAt(l.pos, "duplicate //go:linkname for %s", l.local)
302                         continue
303                 }
304                 n.Sym().Linkname = l.remote
305         }
306         typecheck.Target.CgoPragmas = append(typecheck.Target.CgoPragmas, p.pragcgobuf...)
307 }
308
309 func (p *noder) decls(decls []syntax.Decl) (l []ir.Node) {
310         var cs constState
311
312         for _, decl := range decls {
313                 p.setlineno(decl)
314                 switch decl := decl.(type) {
315                 case *syntax.ImportDecl:
316                         p.importDecl(decl)
317
318                 case *syntax.VarDecl:
319                         l = append(l, p.varDecl(decl)...)
320
321                 case *syntax.ConstDecl:
322                         l = append(l, p.constDecl(decl, &cs)...)
323
324                 case *syntax.TypeDecl:
325                         l = append(l, p.typeDecl(decl))
326
327                 case *syntax.FuncDecl:
328                         l = append(l, p.funcDecl(decl))
329
330                 default:
331                         panic("unhandled Decl")
332                 }
333         }
334
335         return
336 }
337
338 func (p *noder) importDecl(imp *syntax.ImportDecl) {
339         if imp.Path == nil || imp.Path.Bad {
340                 return // avoid follow-on errors if there was a syntax error
341         }
342
343         if pragma, ok := imp.Pragma.(*pragmas); ok {
344                 p.checkUnused(pragma)
345         }
346
347         ipkg := importfile(imp)
348         if ipkg == nil {
349                 if base.Errors() == 0 {
350                         base.Fatalf("phase error in import")
351                 }
352                 return
353         }
354
355         if ipkg == ir.Pkgs.Unsafe {
356                 p.importedUnsafe = true
357         }
358         if ipkg.Path == "embed" {
359                 p.importedEmbed = true
360         }
361
362         var my *types.Sym
363         if imp.LocalPkgName != nil {
364                 my = p.name(imp.LocalPkgName)
365         } else {
366                 my = typecheck.Lookup(ipkg.Name)
367         }
368
369         pack := ir.NewPkgName(p.pos(imp), my, ipkg)
370
371         switch my.Name {
372         case ".":
373                 importDot(pack)
374                 return
375         case "init":
376                 base.ErrorfAt(pack.Pos(), "cannot import package as init - init must be a func")
377                 return
378         case "_":
379                 return
380         }
381         if my.Def != nil {
382                 typecheck.Redeclared(pack.Pos(), my, "as imported package name")
383         }
384         my.Def = pack
385         my.Lastlineno = pack.Pos()
386         my.Block = 1 // at top level
387 }
388
389 func (p *noder) varDecl(decl *syntax.VarDecl) []ir.Node {
390         names := p.declNames(ir.ONAME, decl.NameList)
391         typ := p.typeExprOrNil(decl.Type)
392         exprs := p.exprList(decl.Values)
393
394         if pragma, ok := decl.Pragma.(*pragmas); ok {
395                 varEmbed(p.makeXPos, names[0], decl, pragma, p.importedEmbed)
396                 p.checkUnused(pragma)
397         }
398
399         var init []ir.Node
400         p.setlineno(decl)
401
402         if len(names) > 1 && len(exprs) == 1 {
403                 as2 := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, exprs)
404                 for _, v := range names {
405                         as2.Lhs.Append(v)
406                         typecheck.Declare(v, typecheck.DeclContext)
407                         v.Ntype = typ
408                         v.Defn = as2
409                         if ir.CurFunc != nil {
410                                 init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v))
411                         }
412                 }
413
414                 return append(init, as2)
415         }
416
417         for i, v := range names {
418                 var e ir.Node
419                 if i < len(exprs) {
420                         e = exprs[i]
421                 }
422
423                 typecheck.Declare(v, typecheck.DeclContext)
424                 v.Ntype = typ
425
426                 if ir.CurFunc != nil {
427                         init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v))
428                 }
429                 as := ir.NewAssignStmt(base.Pos, v, e)
430                 init = append(init, as)
431                 if e != nil || ir.CurFunc == nil {
432                         v.Defn = as
433                 }
434         }
435
436         if len(exprs) != 0 && len(names) != len(exprs) {
437                 base.Errorf("assignment mismatch: %d variables but %d values", len(names), len(exprs))
438         }
439
440         return init
441 }
442
443 // constState tracks state between constant specifiers within a
444 // declaration group. This state is kept separate from noder so nested
445 // constant declarations are handled correctly (e.g., issue 15550).
446 type constState struct {
447         group  *syntax.Group
448         typ    ir.Ntype
449         values []ir.Node
450         iota   int64
451 }
452
453 func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []ir.Node {
454         if decl.Group == nil || decl.Group != cs.group {
455                 *cs = constState{
456                         group: decl.Group,
457                 }
458         }
459
460         if pragma, ok := decl.Pragma.(*pragmas); ok {
461                 p.checkUnused(pragma)
462         }
463
464         names := p.declNames(ir.OLITERAL, decl.NameList)
465         typ := p.typeExprOrNil(decl.Type)
466
467         var values []ir.Node
468         if decl.Values != nil {
469                 values = p.exprList(decl.Values)
470                 cs.typ, cs.values = typ, values
471         } else {
472                 if typ != nil {
473                         base.Errorf("const declaration cannot have type without expression")
474                 }
475                 typ, values = cs.typ, cs.values
476         }
477
478         nn := make([]ir.Node, 0, len(names))
479         for i, n := range names {
480                 if i >= len(values) {
481                         base.Errorf("missing value in const declaration")
482                         break
483                 }
484                 v := values[i]
485                 if decl.Values == nil {
486                         v = ir.DeepCopy(n.Pos(), v)
487                 }
488                 typecheck.Declare(n, typecheck.DeclContext)
489
490                 n.Ntype = typ
491                 n.Defn = v
492                 n.SetIota(cs.iota)
493
494                 nn = append(nn, ir.NewDecl(p.pos(decl), ir.ODCLCONST, n))
495         }
496
497         if len(values) > len(names) {
498                 base.Errorf("extra expression in const declaration")
499         }
500
501         cs.iota++
502
503         return nn
504 }
505
506 func (p *noder) typeDecl(decl *syntax.TypeDecl) ir.Node {
507         n := p.declName(ir.OTYPE, decl.Name)
508         typecheck.Declare(n, typecheck.DeclContext)
509
510         // decl.Type may be nil but in that case we got a syntax error during parsing
511         typ := p.typeExprOrNil(decl.Type)
512
513         n.Ntype = typ
514         n.SetAlias(decl.Alias)
515         if pragma, ok := decl.Pragma.(*pragmas); ok {
516                 if !decl.Alias {
517                         n.SetPragma(pragma.Flag & typePragmas)
518                         pragma.Flag &^= typePragmas
519                 }
520                 p.checkUnused(pragma)
521         }
522
523         nod := ir.NewDecl(p.pos(decl), ir.ODCLTYPE, n)
524         if n.Alias() && !types.AllowsGoVersion(types.LocalPkg, 1, 9) {
525                 base.ErrorfAt(nod.Pos(), "type aliases only supported as of -lang=go1.9")
526         }
527         return nod
528 }
529
530 func (p *noder) declNames(op ir.Op, names []*syntax.Name) []*ir.Name {
531         nodes := make([]*ir.Name, 0, len(names))
532         for _, name := range names {
533                 nodes = append(nodes, p.declName(op, name))
534         }
535         return nodes
536 }
537
538 func (p *noder) declName(op ir.Op, name *syntax.Name) *ir.Name {
539         return ir.NewDeclNameAt(p.pos(name), op, p.name(name))
540 }
541
542 func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node {
543         name := p.name(fun.Name)
544         t := p.signature(fun.Recv, fun.Type)
545         f := ir.NewFunc(p.pos(fun))
546
547         if fun.Recv == nil {
548                 if name.Name == "init" {
549                         name = renameinit()
550                         if len(t.Params) > 0 || len(t.Results) > 0 {
551                                 base.ErrorfAt(f.Pos(), "func init must have no arguments and no return values")
552                         }
553                         typecheck.Target.Inits = append(typecheck.Target.Inits, f)
554                 }
555
556                 if types.LocalPkg.Name == "main" && name.Name == "main" {
557                         if len(t.Params) > 0 || len(t.Results) > 0 {
558                                 base.ErrorfAt(f.Pos(), "func main must have no arguments and no return values")
559                         }
560                 }
561         } else {
562                 f.Shortname = name
563                 name = ir.BlankNode.Sym() // filled in by tcFunc
564         }
565
566         f.Nname = ir.NewNameAt(p.pos(fun.Name), name)
567         f.Nname.Func = f
568         f.Nname.Defn = f
569         f.Nname.Ntype = t
570
571         if pragma, ok := fun.Pragma.(*pragmas); ok {
572                 f.Pragma = pragma.Flag & funcPragmas
573                 if pragma.Flag&ir.Systemstack != 0 && pragma.Flag&ir.Nosplit != 0 {
574                         base.ErrorfAt(f.Pos(), "go:nosplit and go:systemstack cannot be combined")
575                 }
576                 pragma.Flag &^= funcPragmas
577                 p.checkUnused(pragma)
578         }
579
580         if fun.Recv == nil {
581                 typecheck.Declare(f.Nname, ir.PFUNC)
582         }
583
584         p.funcBody(f, fun.Body)
585
586         if fun.Body != nil {
587                 if f.Pragma&ir.Noescape != 0 {
588                         base.ErrorfAt(f.Pos(), "can only use //go:noescape with external func implementations")
589                 }
590         } else {
591                 if base.Flag.Complete || strings.HasPrefix(ir.FuncName(f), "init.") {
592                         // Linknamed functions are allowed to have no body. Hopefully
593                         // the linkname target has a body. See issue 23311.
594                         isLinknamed := false
595                         for _, n := range p.linknames {
596                                 if ir.FuncName(f) == n.local {
597                                         isLinknamed = true
598                                         break
599                                 }
600                         }
601                         if !isLinknamed {
602                                 base.ErrorfAt(f.Pos(), "missing function body")
603                         }
604                 }
605         }
606
607         return f
608 }
609
610 func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *ir.FuncType {
611         var rcvr *ir.Field
612         if recv != nil {
613                 rcvr = p.param(recv, false, false)
614         }
615         return ir.NewFuncType(p.pos(typ), rcvr,
616                 p.params(typ.ParamList, true),
617                 p.params(typ.ResultList, false))
618 }
619
620 func (p *noder) params(params []*syntax.Field, dddOk bool) []*ir.Field {
621         nodes := make([]*ir.Field, 0, len(params))
622         for i, param := range params {
623                 p.setlineno(param)
624                 nodes = append(nodes, p.param(param, dddOk, i+1 == len(params)))
625         }
626         return nodes
627 }
628
629 func (p *noder) param(param *syntax.Field, dddOk, final bool) *ir.Field {
630         var name *types.Sym
631         if param.Name != nil {
632                 name = p.name(param.Name)
633         }
634
635         typ := p.typeExpr(param.Type)
636         n := ir.NewField(p.pos(param), name, typ, nil)
637
638         // rewrite ...T parameter
639         if typ, ok := typ.(*ir.SliceType); ok && typ.DDD {
640                 if !dddOk {
641                         // We mark these as syntax errors to get automatic elimination
642                         // of multiple such errors per line (see ErrorfAt in subr.go).
643                         base.Errorf("syntax error: cannot use ... in receiver or result parameter list")
644                 } else if !final {
645                         if param.Name == nil {
646                                 base.Errorf("syntax error: cannot use ... with non-final parameter")
647                         } else {
648                                 p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
649                         }
650                 }
651                 typ.DDD = false
652                 n.IsDDD = true
653         }
654
655         return n
656 }
657
658 func (p *noder) exprList(expr syntax.Expr) []ir.Node {
659         switch expr := expr.(type) {
660         case nil:
661                 return nil
662         case *syntax.ListExpr:
663                 return p.exprs(expr.ElemList)
664         default:
665                 return []ir.Node{p.expr(expr)}
666         }
667 }
668
669 func (p *noder) exprs(exprs []syntax.Expr) []ir.Node {
670         nodes := make([]ir.Node, 0, len(exprs))
671         for _, expr := range exprs {
672                 nodes = append(nodes, p.expr(expr))
673         }
674         return nodes
675 }
676
677 func (p *noder) expr(expr syntax.Expr) ir.Node {
678         p.setlineno(expr)
679         switch expr := expr.(type) {
680         case nil, *syntax.BadExpr:
681                 return nil
682         case *syntax.Name:
683                 return p.mkname(expr)
684         case *syntax.BasicLit:
685                 n := ir.NewBasicLit(p.pos(expr), p.basicLit(expr))
686                 if expr.Kind == syntax.RuneLit {
687                         n.SetType(types.UntypedRune)
688                 }
689                 n.SetDiag(expr.Bad) // avoid follow-on errors if there was a syntax error
690                 return n
691         case *syntax.CompositeLit:
692                 n := ir.NewCompLitExpr(p.pos(expr), ir.OCOMPLIT, p.typeExpr(expr.Type), nil)
693                 l := p.exprs(expr.ElemList)
694                 for i, e := range l {
695                         l[i] = p.wrapname(expr.ElemList[i], e)
696                 }
697                 n.List = l
698                 base.Pos = p.makeXPos(expr.Rbrace)
699                 return n
700         case *syntax.KeyValueExpr:
701                 // use position of expr.Key rather than of expr (which has position of ':')
702                 return ir.NewKeyExpr(p.pos(expr.Key), p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value)))
703         case *syntax.FuncLit:
704                 return p.funcLit(expr)
705         case *syntax.ParenExpr:
706                 return ir.NewParenExpr(p.pos(expr), p.expr(expr.X))
707         case *syntax.SelectorExpr:
708                 // parser.new_dotname
709                 obj := p.expr(expr.X)
710                 if obj.Op() == ir.OPACK {
711                         pack := obj.(*ir.PkgName)
712                         pack.Used = true
713                         return importName(pack.Pkg.Lookup(expr.Sel.Value))
714                 }
715                 n := ir.NewSelectorExpr(base.Pos, ir.OXDOT, obj, p.name(expr.Sel))
716                 n.SetPos(p.pos(expr)) // lineno may have been changed by p.expr(expr.X)
717                 return n
718         case *syntax.IndexExpr:
719                 return ir.NewIndexExpr(p.pos(expr), p.expr(expr.X), p.expr(expr.Index))
720         case *syntax.SliceExpr:
721                 op := ir.OSLICE
722                 if expr.Full {
723                         op = ir.OSLICE3
724                 }
725                 x := p.expr(expr.X)
726                 var index [3]ir.Node
727                 for i, n := range &expr.Index {
728                         if n != nil {
729                                 index[i] = p.expr(n)
730                         }
731                 }
732                 return ir.NewSliceExpr(p.pos(expr), op, x, index[0], index[1], index[2])
733         case *syntax.AssertExpr:
734                 return ir.NewTypeAssertExpr(p.pos(expr), p.expr(expr.X), p.typeExpr(expr.Type))
735         case *syntax.Operation:
736                 if expr.Op == syntax.Add && expr.Y != nil {
737                         return p.sum(expr)
738                 }
739                 x := p.expr(expr.X)
740                 if expr.Y == nil {
741                         pos, op := p.pos(expr), p.unOp(expr.Op)
742                         switch op {
743                         case ir.OADDR:
744                                 return typecheck.NodAddrAt(pos, x)
745                         case ir.ODEREF:
746                                 return ir.NewStarExpr(pos, x)
747                         }
748                         return ir.NewUnaryExpr(pos, op, x)
749                 }
750
751                 pos, op, y := p.pos(expr), p.binOp(expr.Op), p.expr(expr.Y)
752                 switch op {
753                 case ir.OANDAND, ir.OOROR:
754                         return ir.NewLogicalExpr(pos, op, x, y)
755                 }
756                 return ir.NewBinaryExpr(pos, op, x, y)
757         case *syntax.CallExpr:
758                 n := ir.NewCallExpr(p.pos(expr), ir.OCALL, p.expr(expr.Fun), p.exprs(expr.ArgList))
759                 n.IsDDD = expr.HasDots
760                 return n
761
762         case *syntax.ArrayType:
763                 var len ir.Node
764                 if expr.Len != nil {
765                         len = p.expr(expr.Len)
766                 }
767                 return ir.NewArrayType(p.pos(expr), len, p.typeExpr(expr.Elem))
768         case *syntax.SliceType:
769                 return ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
770         case *syntax.DotsType:
771                 t := ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
772                 t.DDD = true
773                 return t
774         case *syntax.StructType:
775                 return p.structType(expr)
776         case *syntax.InterfaceType:
777                 return p.interfaceType(expr)
778         case *syntax.FuncType:
779                 return p.signature(nil, expr)
780         case *syntax.MapType:
781                 return ir.NewMapType(p.pos(expr),
782                         p.typeExpr(expr.Key), p.typeExpr(expr.Value))
783         case *syntax.ChanType:
784                 return ir.NewChanType(p.pos(expr),
785                         p.typeExpr(expr.Elem), p.chanDir(expr.Dir))
786
787         case *syntax.TypeSwitchGuard:
788                 var tag *ir.Ident
789                 if expr.Lhs != nil {
790                         tag = ir.NewIdent(p.pos(expr.Lhs), p.name(expr.Lhs))
791                         if ir.IsBlank(tag) {
792                                 base.Errorf("invalid variable name %v in type switch", tag)
793                         }
794                 }
795                 return ir.NewTypeSwitchGuard(p.pos(expr), tag, p.expr(expr.X))
796         }
797         panic("unhandled Expr")
798 }
799
800 // sum efficiently handles very large summation expressions (such as
801 // in issue #16394). In particular, it avoids left recursion and
802 // collapses string literals.
803 func (p *noder) sum(x syntax.Expr) ir.Node {
804         // While we need to handle long sums with asymptotic
805         // efficiency, the vast majority of sums are very small: ~95%
806         // have only 2 or 3 operands, and ~99% of string literals are
807         // never concatenated.
808
809         adds := make([]*syntax.Operation, 0, 2)
810         for {
811                 add, ok := x.(*syntax.Operation)
812                 if !ok || add.Op != syntax.Add || add.Y == nil {
813                         break
814                 }
815                 adds = append(adds, add)
816                 x = add.X
817         }
818
819         // nstr is the current rightmost string literal in the
820         // summation (if any), and chunks holds its accumulated
821         // substrings.
822         //
823         // Consider the expression x + "a" + "b" + "c" + y. When we
824         // reach the string literal "a", we assign nstr to point to
825         // its corresponding Node and initialize chunks to {"a"}.
826         // Visiting the subsequent string literals "b" and "c", we
827         // simply append their values to chunks. Finally, when we
828         // reach the non-constant operand y, we'll join chunks to form
829         // "abc" and reassign the "a" string literal's value.
830         //
831         // N.B., we need to be careful about named string constants
832         // (indicated by Sym != nil) because 1) we can't modify their
833         // value, as doing so would affect other uses of the string
834         // constant, and 2) they may have types, which we need to
835         // handle correctly. For now, we avoid these problems by
836         // treating named string constants the same as non-constant
837         // operands.
838         var nstr ir.Node
839         chunks := make([]string, 0, 1)
840
841         n := p.expr(x)
842         if ir.IsConst(n, constant.String) && n.Sym() == nil {
843                 nstr = n
844                 chunks = append(chunks, ir.StringVal(nstr))
845         }
846
847         for i := len(adds) - 1; i >= 0; i-- {
848                 add := adds[i]
849
850                 r := p.expr(add.Y)
851                 if ir.IsConst(r, constant.String) && r.Sym() == nil {
852                         if nstr != nil {
853                                 // Collapse r into nstr instead of adding to n.
854                                 chunks = append(chunks, ir.StringVal(r))
855                                 continue
856                         }
857
858                         nstr = r
859                         chunks = append(chunks, ir.StringVal(nstr))
860                 } else {
861                         if len(chunks) > 1 {
862                                 nstr.SetVal(constant.MakeString(strings.Join(chunks, "")))
863                         }
864                         nstr = nil
865                         chunks = chunks[:0]
866                 }
867                 n = ir.NewBinaryExpr(p.pos(add), ir.OADD, n, r)
868         }
869         if len(chunks) > 1 {
870                 nstr.SetVal(constant.MakeString(strings.Join(chunks, "")))
871         }
872
873         return n
874 }
875
876 func (p *noder) typeExpr(typ syntax.Expr) ir.Ntype {
877         // TODO(mdempsky): Be stricter? typecheck should handle errors anyway.
878         n := p.expr(typ)
879         if n == nil {
880                 return nil
881         }
882         if _, ok := n.(ir.Ntype); !ok {
883                 ir.Dump("NOT NTYPE", n)
884         }
885         return n.(ir.Ntype)
886 }
887
888 func (p *noder) typeExprOrNil(typ syntax.Expr) ir.Ntype {
889         if typ != nil {
890                 return p.typeExpr(typ)
891         }
892         return nil
893 }
894
895 func (p *noder) chanDir(dir syntax.ChanDir) types.ChanDir {
896         switch dir {
897         case 0:
898                 return types.Cboth
899         case syntax.SendOnly:
900                 return types.Csend
901         case syntax.RecvOnly:
902                 return types.Crecv
903         }
904         panic("unhandled ChanDir")
905 }
906
907 func (p *noder) structType(expr *syntax.StructType) ir.Node {
908         l := make([]*ir.Field, 0, len(expr.FieldList))
909         for i, field := range expr.FieldList {
910                 p.setlineno(field)
911                 var n *ir.Field
912                 if field.Name == nil {
913                         n = p.embedded(field.Type)
914                 } else {
915                         n = ir.NewField(p.pos(field), p.name(field.Name), p.typeExpr(field.Type), nil)
916                 }
917                 if i < len(expr.TagList) && expr.TagList[i] != nil {
918                         n.Note = constant.StringVal(p.basicLit(expr.TagList[i]))
919                 }
920                 l = append(l, n)
921         }
922
923         p.setlineno(expr)
924         return ir.NewStructType(p.pos(expr), l)
925 }
926
927 func (p *noder) interfaceType(expr *syntax.InterfaceType) ir.Node {
928         l := make([]*ir.Field, 0, len(expr.MethodList))
929         for _, method := range expr.MethodList {
930                 p.setlineno(method)
931                 var n *ir.Field
932                 if method.Name == nil {
933                         n = ir.NewField(p.pos(method), nil, importName(p.packname(method.Type)).(ir.Ntype), nil)
934                 } else {
935                         mname := p.name(method.Name)
936                         if mname.IsBlank() {
937                                 base.Errorf("methods must have a unique non-blank name")
938                                 continue
939                         }
940                         sig := p.typeExpr(method.Type).(*ir.FuncType)
941                         sig.Recv = fakeRecv()
942                         n = ir.NewField(p.pos(method), mname, sig, nil)
943                 }
944                 l = append(l, n)
945         }
946
947         return ir.NewInterfaceType(p.pos(expr), l)
948 }
949
950 func (p *noder) packname(expr syntax.Expr) *types.Sym {
951         switch expr := expr.(type) {
952         case *syntax.Name:
953                 name := p.name(expr)
954                 if n := oldname(name); n.Name() != nil && n.Name().PkgName != nil {
955                         n.Name().PkgName.Used = true
956                 }
957                 return name
958         case *syntax.SelectorExpr:
959                 name := p.name(expr.X.(*syntax.Name))
960                 def := ir.AsNode(name.Def)
961                 if def == nil {
962                         base.Errorf("undefined: %v", name)
963                         return name
964                 }
965                 var pkg *types.Pkg
966                 if def.Op() != ir.OPACK {
967                         base.Errorf("%v is not a package", name)
968                         pkg = types.LocalPkg
969                 } else {
970                         def := def.(*ir.PkgName)
971                         def.Used = true
972                         pkg = def.Pkg
973                 }
974                 return pkg.Lookup(expr.Sel.Value)
975         }
976         panic(fmt.Sprintf("unexpected packname: %#v", expr))
977 }
978
979 func (p *noder) embedded(typ syntax.Expr) *ir.Field {
980         op, isStar := typ.(*syntax.Operation)
981         if isStar {
982                 if op.Op != syntax.Mul || op.Y != nil {
983                         panic("unexpected Operation")
984                 }
985                 typ = op.X
986         }
987
988         sym := p.packname(typ)
989         n := ir.NewField(p.pos(typ), typecheck.Lookup(sym.Name), importName(sym).(ir.Ntype), nil)
990         n.Embedded = true
991
992         if isStar {
993                 n.Ntype = ir.NewStarExpr(p.pos(op), n.Ntype)
994         }
995         return n
996 }
997
998 func (p *noder) stmts(stmts []syntax.Stmt) []ir.Node {
999         return p.stmtsFall(stmts, false)
1000 }
1001
1002 func (p *noder) stmtsFall(stmts []syntax.Stmt, fallOK bool) []ir.Node {
1003         var nodes []ir.Node
1004         for i, stmt := range stmts {
1005                 s := p.stmtFall(stmt, fallOK && i+1 == len(stmts))
1006                 if s == nil {
1007                 } else if s.Op() == ir.OBLOCK && len(s.(*ir.BlockStmt).List) > 0 {
1008                         // Inline non-empty block.
1009                         // Empty blocks must be preserved for CheckReturn.
1010                         nodes = append(nodes, s.(*ir.BlockStmt).List...)
1011                 } else {
1012                         nodes = append(nodes, s)
1013                 }
1014         }
1015         return nodes
1016 }
1017
1018 func (p *noder) stmt(stmt syntax.Stmt) ir.Node {
1019         return p.stmtFall(stmt, false)
1020 }
1021
1022 func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
1023         p.setlineno(stmt)
1024         switch stmt := stmt.(type) {
1025         case nil, *syntax.EmptyStmt:
1026                 return nil
1027         case *syntax.LabeledStmt:
1028                 return p.labeledStmt(stmt, fallOK)
1029         case *syntax.BlockStmt:
1030                 l := p.blockStmt(stmt)
1031                 if len(l) == 0 {
1032                         // TODO(mdempsky): Line number?
1033                         return ir.NewBlockStmt(base.Pos, nil)
1034                 }
1035                 return ir.NewBlockStmt(src.NoXPos, l)
1036         case *syntax.ExprStmt:
1037                 return p.wrapname(stmt, p.expr(stmt.X))
1038         case *syntax.SendStmt:
1039                 return ir.NewSendStmt(p.pos(stmt), p.expr(stmt.Chan), p.expr(stmt.Value))
1040         case *syntax.DeclStmt:
1041                 return ir.NewBlockStmt(src.NoXPos, p.decls(stmt.DeclList))
1042         case *syntax.AssignStmt:
1043                 if stmt.Rhs == nil {
1044                         pos := p.pos(stmt)
1045                         n := ir.NewAssignOpStmt(pos, p.binOp(stmt.Op), p.expr(stmt.Lhs), ir.NewBasicLit(pos, one))
1046                         n.IncDec = true
1047                         return n
1048                 }
1049
1050                 if stmt.Op != 0 && stmt.Op != syntax.Def {
1051                         n := ir.NewAssignOpStmt(p.pos(stmt), p.binOp(stmt.Op), p.expr(stmt.Lhs), p.expr(stmt.Rhs))
1052                         return n
1053                 }
1054
1055                 rhs := p.exprList(stmt.Rhs)
1056                 if list, ok := stmt.Lhs.(*syntax.ListExpr); ok && len(list.ElemList) != 1 || len(rhs) != 1 {
1057                         n := ir.NewAssignListStmt(p.pos(stmt), ir.OAS2, nil, nil)
1058                         n.Def = stmt.Op == syntax.Def
1059                         n.Lhs = p.assignList(stmt.Lhs, n, n.Def)
1060                         n.Rhs = rhs
1061                         return n
1062                 }
1063
1064                 n := ir.NewAssignStmt(p.pos(stmt), nil, nil)
1065                 n.Def = stmt.Op == syntax.Def
1066                 n.X = p.assignList(stmt.Lhs, n, n.Def)[0]
1067                 n.Y = rhs[0]
1068                 return n
1069
1070         case *syntax.BranchStmt:
1071                 var op ir.Op
1072                 switch stmt.Tok {
1073                 case syntax.Break:
1074                         op = ir.OBREAK
1075                 case syntax.Continue:
1076                         op = ir.OCONTINUE
1077                 case syntax.Fallthrough:
1078                         if !fallOK {
1079                                 base.Errorf("fallthrough statement out of place")
1080                         }
1081                         op = ir.OFALL
1082                 case syntax.Goto:
1083                         op = ir.OGOTO
1084                 default:
1085                         panic("unhandled BranchStmt")
1086                 }
1087                 var sym *types.Sym
1088                 if stmt.Label != nil {
1089                         sym = p.name(stmt.Label)
1090                 }
1091                 return ir.NewBranchStmt(p.pos(stmt), op, sym)
1092         case *syntax.CallStmt:
1093                 var op ir.Op
1094                 switch stmt.Tok {
1095                 case syntax.Defer:
1096                         op = ir.ODEFER
1097                 case syntax.Go:
1098                         op = ir.OGO
1099                 default:
1100                         panic("unhandled CallStmt")
1101                 }
1102                 return ir.NewGoDeferStmt(p.pos(stmt), op, p.expr(stmt.Call))
1103         case *syntax.ReturnStmt:
1104                 n := ir.NewReturnStmt(p.pos(stmt), p.exprList(stmt.Results))
1105                 if len(n.Results) == 0 && ir.CurFunc != nil {
1106                         for _, ln := range ir.CurFunc.Dcl {
1107                                 if ln.Class == ir.PPARAM {
1108                                         continue
1109                                 }
1110                                 if ln.Class != ir.PPARAMOUT {
1111                                         break
1112                                 }
1113                                 if ln.Sym().Def != ln {
1114                                         base.Errorf("%s is shadowed during return", ln.Sym().Name)
1115                                 }
1116                         }
1117                 }
1118                 return n
1119         case *syntax.IfStmt:
1120                 return p.ifStmt(stmt)
1121         case *syntax.ForStmt:
1122                 return p.forStmt(stmt)
1123         case *syntax.SwitchStmt:
1124                 return p.switchStmt(stmt)
1125         case *syntax.SelectStmt:
1126                 return p.selectStmt(stmt)
1127         }
1128         panic("unhandled Stmt")
1129 }
1130
1131 func (p *noder) assignList(expr syntax.Expr, defn ir.InitNode, colas bool) []ir.Node {
1132         if !colas {
1133                 return p.exprList(expr)
1134         }
1135
1136         var exprs []syntax.Expr
1137         if list, ok := expr.(*syntax.ListExpr); ok {
1138                 exprs = list.ElemList
1139         } else {
1140                 exprs = []syntax.Expr{expr}
1141         }
1142
1143         res := make([]ir.Node, len(exprs))
1144         seen := make(map[*types.Sym]bool, len(exprs))
1145
1146         newOrErr := false
1147         for i, expr := range exprs {
1148                 p.setlineno(expr)
1149                 res[i] = ir.BlankNode
1150
1151                 name, ok := expr.(*syntax.Name)
1152                 if !ok {
1153                         p.errorAt(expr.Pos(), "non-name %v on left side of :=", p.expr(expr))
1154                         newOrErr = true
1155                         continue
1156                 }
1157
1158                 sym := p.name(name)
1159                 if sym.IsBlank() {
1160                         continue
1161                 }
1162
1163                 if seen[sym] {
1164                         p.errorAt(expr.Pos(), "%v repeated on left side of :=", sym)
1165                         newOrErr = true
1166                         continue
1167                 }
1168                 seen[sym] = true
1169
1170                 if sym.Block == types.Block {
1171                         res[i] = oldname(sym)
1172                         continue
1173                 }
1174
1175                 newOrErr = true
1176                 n := typecheck.NewName(sym)
1177                 typecheck.Declare(n, typecheck.DeclContext)
1178                 n.Defn = defn
1179                 defn.PtrInit().Append(ir.NewDecl(base.Pos, ir.ODCL, n))
1180                 res[i] = n
1181         }
1182
1183         if !newOrErr {
1184                 base.ErrorfAt(defn.Pos(), "no new variables on left side of :=")
1185         }
1186         return res
1187 }
1188
1189 func (p *noder) blockStmt(stmt *syntax.BlockStmt) []ir.Node {
1190         p.openScope(stmt.Pos())
1191         nodes := p.stmts(stmt.List)
1192         p.closeScope(stmt.Rbrace)
1193         return nodes
1194 }
1195
1196 func (p *noder) ifStmt(stmt *syntax.IfStmt) ir.Node {
1197         p.openScope(stmt.Pos())
1198         init := p.stmt(stmt.Init)
1199         n := ir.NewIfStmt(p.pos(stmt), p.expr(stmt.Cond), p.blockStmt(stmt.Then), nil)
1200         if init != nil {
1201                 *n.PtrInit() = []ir.Node{init}
1202         }
1203         if stmt.Else != nil {
1204                 e := p.stmt(stmt.Else)
1205                 if e.Op() == ir.OBLOCK {
1206                         e := e.(*ir.BlockStmt)
1207                         n.Else = e.List
1208                 } else {
1209                         n.Else = []ir.Node{e}
1210                 }
1211         }
1212         p.closeAnotherScope()
1213         return n
1214 }
1215
1216 func (p *noder) forStmt(stmt *syntax.ForStmt) ir.Node {
1217         p.openScope(stmt.Pos())
1218         if r, ok := stmt.Init.(*syntax.RangeClause); ok {
1219                 if stmt.Cond != nil || stmt.Post != nil {
1220                         panic("unexpected RangeClause")
1221                 }
1222
1223                 n := ir.NewRangeStmt(p.pos(r), nil, nil, p.expr(r.X), nil)
1224                 if r.Lhs != nil {
1225                         n.Def = r.Def
1226                         lhs := p.assignList(r.Lhs, n, n.Def)
1227                         n.Key = lhs[0]
1228                         if len(lhs) > 1 {
1229                                 n.Value = lhs[1]
1230                         }
1231                 }
1232                 n.Body = p.blockStmt(stmt.Body)
1233                 p.closeAnotherScope()
1234                 return n
1235         }
1236
1237         n := ir.NewForStmt(p.pos(stmt), p.stmt(stmt.Init), p.expr(stmt.Cond), p.stmt(stmt.Post), p.blockStmt(stmt.Body))
1238         p.closeAnotherScope()
1239         return n
1240 }
1241
1242 func (p *noder) switchStmt(stmt *syntax.SwitchStmt) ir.Node {
1243         p.openScope(stmt.Pos())
1244
1245         init := p.stmt(stmt.Init)
1246         n := ir.NewSwitchStmt(p.pos(stmt), p.expr(stmt.Tag), nil)
1247         if init != nil {
1248                 *n.PtrInit() = []ir.Node{init}
1249         }
1250
1251         var tswitch *ir.TypeSwitchGuard
1252         if l := n.Tag; l != nil && l.Op() == ir.OTYPESW {
1253                 tswitch = l.(*ir.TypeSwitchGuard)
1254         }
1255         n.Cases = p.caseClauses(stmt.Body, tswitch, stmt.Rbrace)
1256
1257         p.closeScope(stmt.Rbrace)
1258         return n
1259 }
1260
1261 func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *ir.TypeSwitchGuard, rbrace syntax.Pos) []*ir.CaseClause {
1262         nodes := make([]*ir.CaseClause, 0, len(clauses))
1263         for i, clause := range clauses {
1264                 p.setlineno(clause)
1265                 if i > 0 {
1266                         p.closeScope(clause.Pos())
1267                 }
1268                 p.openScope(clause.Pos())
1269
1270                 n := ir.NewCaseStmt(p.pos(clause), p.exprList(clause.Cases), nil)
1271                 if tswitch != nil && tswitch.Tag != nil {
1272                         nn := typecheck.NewName(tswitch.Tag.Sym())
1273                         typecheck.Declare(nn, typecheck.DeclContext)
1274                         n.Var = nn
1275                         // keep track of the instances for reporting unused
1276                         nn.Defn = tswitch
1277                 }
1278
1279                 // Trim trailing empty statements. We omit them from
1280                 // the Node AST anyway, and it's easier to identify
1281                 // out-of-place fallthrough statements without them.
1282                 body := clause.Body
1283                 for len(body) > 0 {
1284                         if _, ok := body[len(body)-1].(*syntax.EmptyStmt); !ok {
1285                                 break
1286                         }
1287                         body = body[:len(body)-1]
1288                 }
1289
1290                 n.Body = p.stmtsFall(body, true)
1291                 if l := len(n.Body); l > 0 && n.Body[l-1].Op() == ir.OFALL {
1292                         if tswitch != nil {
1293                                 base.Errorf("cannot fallthrough in type switch")
1294                         }
1295                         if i+1 == len(clauses) {
1296                                 base.Errorf("cannot fallthrough final case in switch")
1297                         }
1298                 }
1299
1300                 nodes = append(nodes, n)
1301         }
1302         if len(clauses) > 0 {
1303                 p.closeScope(rbrace)
1304         }
1305         return nodes
1306 }
1307
1308 func (p *noder) selectStmt(stmt *syntax.SelectStmt) ir.Node {
1309         return ir.NewSelectStmt(p.pos(stmt), p.commClauses(stmt.Body, stmt.Rbrace))
1310 }
1311
1312 func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*ir.CommClause {
1313         nodes := make([]*ir.CommClause, len(clauses))
1314         for i, clause := range clauses {
1315                 p.setlineno(clause)
1316                 if i > 0 {
1317                         p.closeScope(clause.Pos())
1318                 }
1319                 p.openScope(clause.Pos())
1320
1321                 nodes[i] = ir.NewCommStmt(p.pos(clause), p.stmt(clause.Comm), p.stmts(clause.Body))
1322         }
1323         if len(clauses) > 0 {
1324                 p.closeScope(rbrace)
1325         }
1326         return nodes
1327 }
1328
1329 func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) ir.Node {
1330         sym := p.name(label.Label)
1331         lhs := ir.NewLabelStmt(p.pos(label), sym)
1332
1333         var ls ir.Node
1334         if label.Stmt != nil { // TODO(mdempsky): Should always be present.
1335                 ls = p.stmtFall(label.Stmt, fallOK)
1336                 // Attach label directly to control statement too.
1337                 if ls != nil {
1338                         switch ls.Op() {
1339                         case ir.OFOR:
1340                                 ls := ls.(*ir.ForStmt)
1341                                 ls.Label = sym
1342                         case ir.ORANGE:
1343                                 ls := ls.(*ir.RangeStmt)
1344                                 ls.Label = sym
1345                         case ir.OSWITCH:
1346                                 ls := ls.(*ir.SwitchStmt)
1347                                 ls.Label = sym
1348                         case ir.OSELECT:
1349                                 ls := ls.(*ir.SelectStmt)
1350                                 ls.Label = sym
1351                         }
1352                 }
1353         }
1354
1355         l := []ir.Node{lhs}
1356         if ls != nil {
1357                 if ls.Op() == ir.OBLOCK {
1358                         ls := ls.(*ir.BlockStmt)
1359                         l = append(l, ls.List...)
1360                 } else {
1361                         l = append(l, ls)
1362                 }
1363         }
1364         return ir.NewBlockStmt(src.NoXPos, l)
1365 }
1366
1367 var unOps = [...]ir.Op{
1368         syntax.Recv: ir.ORECV,
1369         syntax.Mul:  ir.ODEREF,
1370         syntax.And:  ir.OADDR,
1371
1372         syntax.Not: ir.ONOT,
1373         syntax.Xor: ir.OBITNOT,
1374         syntax.Add: ir.OPLUS,
1375         syntax.Sub: ir.ONEG,
1376 }
1377
1378 func (p *noder) unOp(op syntax.Operator) ir.Op {
1379         if uint64(op) >= uint64(len(unOps)) || unOps[op] == 0 {
1380                 panic("invalid Operator")
1381         }
1382         return unOps[op]
1383 }
1384
1385 var binOps = [...]ir.Op{
1386         syntax.OrOr:   ir.OOROR,
1387         syntax.AndAnd: ir.OANDAND,
1388
1389         syntax.Eql: ir.OEQ,
1390         syntax.Neq: ir.ONE,
1391         syntax.Lss: ir.OLT,
1392         syntax.Leq: ir.OLE,
1393         syntax.Gtr: ir.OGT,
1394         syntax.Geq: ir.OGE,
1395
1396         syntax.Add: ir.OADD,
1397         syntax.Sub: ir.OSUB,
1398         syntax.Or:  ir.OOR,
1399         syntax.Xor: ir.OXOR,
1400
1401         syntax.Mul:    ir.OMUL,
1402         syntax.Div:    ir.ODIV,
1403         syntax.Rem:    ir.OMOD,
1404         syntax.And:    ir.OAND,
1405         syntax.AndNot: ir.OANDNOT,
1406         syntax.Shl:    ir.OLSH,
1407         syntax.Shr:    ir.ORSH,
1408 }
1409
1410 func (p *noder) binOp(op syntax.Operator) ir.Op {
1411         if uint64(op) >= uint64(len(binOps)) || binOps[op] == 0 {
1412                 panic("invalid Operator")
1413         }
1414         return binOps[op]
1415 }
1416
1417 // checkLangCompat reports an error if the representation of a numeric
1418 // literal is not compatible with the current language version.
1419 func checkLangCompat(lit *syntax.BasicLit) {
1420         s := lit.Value
1421         if len(s) <= 2 || types.AllowsGoVersion(types.LocalPkg, 1, 13) {
1422                 return
1423         }
1424         // len(s) > 2
1425         if strings.Contains(s, "_") {
1426                 base.ErrorfVers("go1.13", "underscores in numeric literals")
1427                 return
1428         }
1429         if s[0] != '0' {
1430                 return
1431         }
1432         radix := s[1]
1433         if radix == 'b' || radix == 'B' {
1434                 base.ErrorfVers("go1.13", "binary literals")
1435                 return
1436         }
1437         if radix == 'o' || radix == 'O' {
1438                 base.ErrorfVers("go1.13", "0o/0O-style octal literals")
1439                 return
1440         }
1441         if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
1442                 base.ErrorfVers("go1.13", "hexadecimal floating-point literals")
1443         }
1444 }
1445
1446 func (p *noder) basicLit(lit *syntax.BasicLit) constant.Value {
1447         // We don't use the errors of the conversion routines to determine
1448         // if a literal string is valid because the conversion routines may
1449         // accept a wider syntax than the language permits. Rely on lit.Bad
1450         // instead.
1451         if lit.Bad {
1452                 return constant.MakeUnknown()
1453         }
1454
1455         switch lit.Kind {
1456         case syntax.IntLit, syntax.FloatLit, syntax.ImagLit:
1457                 checkLangCompat(lit)
1458         }
1459
1460         v := constant.MakeFromLiteral(lit.Value, tokenForLitKind[lit.Kind], 0)
1461         if v.Kind() == constant.Unknown {
1462                 // TODO(mdempsky): Better error message?
1463                 p.errorAt(lit.Pos(), "malformed constant: %s", lit.Value)
1464         }
1465
1466         // go/constant uses big.Rat by default, which is more precise, but
1467         // causes toolstash -cmp and some tests to fail. For now, convert
1468         // to big.Float to match cmd/compile's historical precision.
1469         // TODO(mdempsky): Remove.
1470         if v.Kind() == constant.Float {
1471                 v = constant.Make(ir.BigFloat(v))
1472         }
1473
1474         return v
1475 }
1476
1477 var tokenForLitKind = [...]token.Token{
1478         syntax.IntLit:    token.INT,
1479         syntax.RuneLit:   token.CHAR,
1480         syntax.FloatLit:  token.FLOAT,
1481         syntax.ImagLit:   token.IMAG,
1482         syntax.StringLit: token.STRING,
1483 }
1484
1485 func (p *noder) name(name *syntax.Name) *types.Sym {
1486         return typecheck.Lookup(name.Value)
1487 }
1488
1489 func (p *noder) mkname(name *syntax.Name) ir.Node {
1490         // TODO(mdempsky): Set line number?
1491         return mkname(p.name(name))
1492 }
1493
1494 func (p *noder) wrapname(n syntax.Node, x ir.Node) ir.Node {
1495         // These nodes do not carry line numbers.
1496         // Introduce a wrapper node to give them the correct line.
1497         switch x.Op() {
1498         case ir.OTYPE, ir.OLITERAL:
1499                 if x.Sym() == nil {
1500                         break
1501                 }
1502                 fallthrough
1503         case ir.ONAME, ir.ONONAME, ir.OPACK:
1504                 p := ir.NewParenExpr(p.pos(n), x)
1505                 p.SetImplicit(true)
1506                 return p
1507         }
1508         return x
1509 }
1510
1511 func (p *noder) setlineno(n syntax.Node) {
1512         if n != nil {
1513                 base.Pos = p.pos(n)
1514         }
1515 }
1516
1517 // error is called concurrently if files are parsed concurrently.
1518 func (p *noder) error(err error) {
1519         p.err <- err.(syntax.Error)
1520 }
1521
1522 // pragmas that are allowed in the std lib, but don't have
1523 // a syntax.Pragma value (see lex.go) associated with them.
1524 var allowedStdPragmas = map[string]bool{
1525         "go:cgo_export_static":  true,
1526         "go:cgo_export_dynamic": true,
1527         "go:cgo_import_static":  true,
1528         "go:cgo_import_dynamic": true,
1529         "go:cgo_ldflag":         true,
1530         "go:cgo_dynamic_linker": true,
1531         "go:embed":              true,
1532         "go:generate":           true,
1533 }
1534
1535 // *pragmas is the value stored in a syntax.pragmas during parsing.
1536 type pragmas struct {
1537         Flag   ir.PragmaFlag // collected bits
1538         Pos    []pragmaPos   // position of each individual flag
1539         Embeds []pragmaEmbed
1540 }
1541
1542 type pragmaPos struct {
1543         Flag ir.PragmaFlag
1544         Pos  syntax.Pos
1545 }
1546
1547 type pragmaEmbed struct {
1548         Pos      syntax.Pos
1549         Patterns []string
1550 }
1551
1552 func (p *noder) checkUnused(pragma *pragmas) {
1553         for _, pos := range pragma.Pos {
1554                 if pos.Flag&pragma.Flag != 0 {
1555                         p.errorAt(pos.Pos, "misplaced compiler directive")
1556                 }
1557         }
1558         if len(pragma.Embeds) > 0 {
1559                 for _, e := range pragma.Embeds {
1560                         p.errorAt(e.Pos, "misplaced go:embed directive")
1561                 }
1562         }
1563 }
1564
1565 func (p *noder) checkUnusedDuringParse(pragma *pragmas) {
1566         for _, pos := range pragma.Pos {
1567                 if pos.Flag&pragma.Flag != 0 {
1568                         p.error(syntax.Error{Pos: pos.Pos, Msg: "misplaced compiler directive"})
1569                 }
1570         }
1571         if len(pragma.Embeds) > 0 {
1572                 for _, e := range pragma.Embeds {
1573                         p.error(syntax.Error{Pos: e.Pos, Msg: "misplaced go:embed directive"})
1574                 }
1575         }
1576 }
1577
1578 // pragma is called concurrently if files are parsed concurrently.
1579 func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.Pragma) syntax.Pragma {
1580         pragma, _ := old.(*pragmas)
1581         if pragma == nil {
1582                 pragma = new(pragmas)
1583         }
1584
1585         if text == "" {
1586                 // unused pragma; only called with old != nil.
1587                 p.checkUnusedDuringParse(pragma)
1588                 return nil
1589         }
1590
1591         if strings.HasPrefix(text, "line ") {
1592                 // line directives are handled by syntax package
1593                 panic("unreachable")
1594         }
1595
1596         if !blankLine {
1597                 // directive must be on line by itself
1598                 p.error(syntax.Error{Pos: pos, Msg: "misplaced compiler directive"})
1599                 return pragma
1600         }
1601
1602         switch {
1603         case strings.HasPrefix(text, "go:linkname "):
1604                 f := strings.Fields(text)
1605                 if !(2 <= len(f) && len(f) <= 3) {
1606                         p.error(syntax.Error{Pos: pos, Msg: "usage: //go:linkname localname [linkname]"})
1607                         break
1608                 }
1609                 // The second argument is optional. If omitted, we use
1610                 // the default object symbol name for this and
1611                 // linkname only serves to mark this symbol as
1612                 // something that may be referenced via the object
1613                 // symbol name from another package.
1614                 var target string
1615                 if len(f) == 3 {
1616                         target = f[2]
1617                 } else if base.Ctxt.Pkgpath != "" {
1618                         // Use the default object symbol name if the
1619                         // user didn't provide one.
1620                         target = objabi.PathToPrefix(base.Ctxt.Pkgpath) + "." + f[1]
1621                 } else {
1622                         p.error(syntax.Error{Pos: pos, Msg: "//go:linkname requires linkname argument or -p compiler flag"})
1623                         break
1624                 }
1625                 p.linknames = append(p.linknames, linkname{pos, f[1], target})
1626
1627         case text == "go:embed", strings.HasPrefix(text, "go:embed "):
1628                 args, err := parseGoEmbed(text[len("go:embed"):])
1629                 if err != nil {
1630                         p.error(syntax.Error{Pos: pos, Msg: err.Error()})
1631                 }
1632                 if len(args) == 0 {
1633                         p.error(syntax.Error{Pos: pos, Msg: "usage: //go:embed pattern..."})
1634                         break
1635                 }
1636                 pragma.Embeds = append(pragma.Embeds, pragmaEmbed{pos, args})
1637
1638         case strings.HasPrefix(text, "go:cgo_import_dynamic "):
1639                 // This is permitted for general use because Solaris
1640                 // code relies on it in golang.org/x/sys/unix and others.
1641                 fields := pragmaFields(text)
1642                 if len(fields) >= 4 {
1643                         lib := strings.Trim(fields[3], `"`)
1644                         if lib != "" && !safeArg(lib) && !isCgoGeneratedFile(pos) {
1645                                 p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("invalid library name %q in cgo_import_dynamic directive", lib)})
1646                         }
1647                         p.pragcgo(pos, text)
1648                         pragma.Flag |= pragmaFlag("go:cgo_import_dynamic")
1649                         break
1650                 }
1651                 fallthrough
1652         case strings.HasPrefix(text, "go:cgo_"):
1653                 // For security, we disallow //go:cgo_* directives other
1654                 // than cgo_import_dynamic outside cgo-generated files.
1655                 // Exception: they are allowed in the standard library, for runtime and syscall.
1656                 if !isCgoGeneratedFile(pos) && !base.Flag.Std {
1657                         p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in cgo-generated code", text)})
1658                 }
1659                 p.pragcgo(pos, text)
1660                 fallthrough // because of //go:cgo_unsafe_args
1661         default:
1662                 verb := text
1663                 if i := strings.Index(text, " "); i >= 0 {
1664                         verb = verb[:i]
1665                 }
1666                 flag := pragmaFlag(verb)
1667                 const runtimePragmas = ir.Systemstack | ir.Nowritebarrier | ir.Nowritebarrierrec | ir.Yeswritebarrierrec
1668                 if !base.Flag.CompilingRuntime && flag&runtimePragmas != 0 {
1669                         p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)})
1670                 }
1671                 if flag == 0 && !allowedStdPragmas[verb] && base.Flag.Std {
1672                         p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s is not allowed in the standard library", verb)})
1673                 }
1674                 pragma.Flag |= flag
1675                 pragma.Pos = append(pragma.Pos, pragmaPos{flag, pos})
1676         }
1677
1678         return pragma
1679 }
1680
1681 // isCgoGeneratedFile reports whether pos is in a file
1682 // generated by cgo, which is to say a file with name
1683 // beginning with "_cgo_". Such files are allowed to
1684 // contain cgo directives, and for security reasons
1685 // (primarily misuse of linker flags), other files are not.
1686 // See golang.org/issue/23672.
1687 func isCgoGeneratedFile(pos syntax.Pos) bool {
1688         return strings.HasPrefix(filepath.Base(filepath.Clean(fileh(pos.Base().Filename()))), "_cgo_")
1689 }
1690
1691 // safeArg reports whether arg is a "safe" command-line argument,
1692 // meaning that when it appears in a command-line, it probably
1693 // doesn't have some special meaning other than its own name.
1694 // This is copied from SafeArg in cmd/go/internal/load/pkg.go.
1695 func safeArg(name string) bool {
1696         if name == "" {
1697                 return false
1698         }
1699         c := name[0]
1700         return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
1701 }
1702
1703 func mkname(sym *types.Sym) ir.Node {
1704         n := oldname(sym)
1705         if n.Name() != nil && n.Name().PkgName != nil {
1706                 n.Name().PkgName.Used = true
1707         }
1708         return n
1709 }
1710
1711 // parseGoEmbed parses the text following "//go:embed" to extract the glob patterns.
1712 // It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings.
1713 // go/build/read.go also processes these strings and contains similar logic.
1714 func parseGoEmbed(args string) ([]string, error) {
1715         var list []string
1716         for args = strings.TrimSpace(args); args != ""; args = strings.TrimSpace(args) {
1717                 var path string
1718         Switch:
1719                 switch args[0] {
1720                 default:
1721                         i := len(args)
1722                         for j, c := range args {
1723                                 if unicode.IsSpace(c) {
1724                                         i = j
1725                                         break
1726                                 }
1727                         }
1728                         path = args[:i]
1729                         args = args[i:]
1730
1731                 case '`':
1732                         i := strings.Index(args[1:], "`")
1733                         if i < 0 {
1734                                 return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
1735                         }
1736                         path = args[1 : 1+i]
1737                         args = args[1+i+1:]
1738
1739                 case '"':
1740                         i := 1
1741                         for ; i < len(args); i++ {
1742                                 if args[i] == '\\' {
1743                                         i++
1744                                         continue
1745                                 }
1746                                 if args[i] == '"' {
1747                                         q, err := strconv.Unquote(args[:i+1])
1748                                         if err != nil {
1749                                                 return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args[:i+1])
1750                                         }
1751                                         path = q
1752                                         args = args[i+1:]
1753                                         break Switch
1754                                 }
1755                         }
1756                         if i >= len(args) {
1757                                 return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
1758                         }
1759                 }
1760
1761                 if args != "" {
1762                         r, _ := utf8.DecodeRuneInString(args)
1763                         if !unicode.IsSpace(r) {
1764                                 return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
1765                         }
1766                 }
1767                 list = append(list, path)
1768         }
1769         return list, nil
1770 }
1771
1772 func fakeRecv() *ir.Field {
1773         return ir.NewField(base.Pos, nil, nil, types.FakeRecvType())
1774 }
1775
1776 func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
1777         xtype := p.typeExpr(expr.Type)
1778
1779         fn := ir.NewFunc(p.pos(expr))
1780         fn.SetIsHiddenClosure(ir.CurFunc != nil)
1781
1782         fn.Nname = ir.NewNameAt(p.pos(expr), ir.BlankNode.Sym()) // filled in by tcClosure
1783         fn.Nname.Func = fn
1784         fn.Nname.Ntype = xtype
1785         fn.Nname.Defn = fn
1786
1787         clo := ir.NewClosureExpr(p.pos(expr), fn)
1788         fn.OClosure = clo
1789
1790         p.funcBody(fn, expr.Body)
1791
1792         ir.FinishCaptureNames(base.Pos, ir.CurFunc, fn)
1793
1794         return clo
1795 }
1796
1797 // A function named init is a special case.
1798 // It is called by the initialization before main is run.
1799 // To make it unique within a package and also uncallable,
1800 // the name, normally "pkg.init", is altered to "pkg.init.0".
1801 var renameinitgen int
1802
1803 func renameinit() *types.Sym {
1804         s := typecheck.LookupNum("init.", renameinitgen)
1805         renameinitgen++
1806         return s
1807 }
1808
1809 // oldname returns the Node that declares symbol s in the current scope.
1810 // If no such Node currently exists, an ONONAME Node is returned instead.
1811 // Automatically creates a new closure variable if the referenced symbol was
1812 // declared in a different (containing) function.
1813 func oldname(s *types.Sym) ir.Node {
1814         if s.Pkg != types.LocalPkg {
1815                 return ir.NewIdent(base.Pos, s)
1816         }
1817
1818         n := ir.AsNode(s.Def)
1819         if n == nil {
1820                 // Maybe a top-level declaration will come along later to
1821                 // define s. resolve will check s.Def again once all input
1822                 // source has been processed.
1823                 return ir.NewIdent(base.Pos, s)
1824         }
1825
1826         if n, ok := n.(*ir.Name); ok {
1827                 // TODO(rsc): If there is an outer variable x and we
1828                 // are parsing x := 5 inside the closure, until we get to
1829                 // the := it looks like a reference to the outer x so we'll
1830                 // make x a closure variable unnecessarily.
1831                 return ir.CaptureName(base.Pos, ir.CurFunc, n)
1832         }
1833
1834         return n
1835 }
1836
1837 func varEmbed(makeXPos func(syntax.Pos) src.XPos, name *ir.Name, decl *syntax.VarDecl, pragma *pragmas, haveEmbed bool) {
1838         if pragma.Embeds == nil {
1839                 return
1840         }
1841
1842         pragmaEmbeds := pragma.Embeds
1843         pragma.Embeds = nil
1844         pos := makeXPos(pragmaEmbeds[0].Pos)
1845
1846         if !haveEmbed {
1847                 base.ErrorfAt(pos, "go:embed only allowed in Go files that import \"embed\"")
1848                 return
1849         }
1850         if len(decl.NameList) > 1 {
1851                 base.ErrorfAt(pos, "go:embed cannot apply to multiple vars")
1852                 return
1853         }
1854         if decl.Values != nil {
1855                 base.ErrorfAt(pos, "go:embed cannot apply to var with initializer")
1856                 return
1857         }
1858         if decl.Type == nil {
1859                 // Should not happen, since Values == nil now.
1860                 base.ErrorfAt(pos, "go:embed cannot apply to var without type")
1861                 return
1862         }
1863         if typecheck.DeclContext != ir.PEXTERN {
1864                 base.ErrorfAt(pos, "go:embed cannot apply to var inside func")
1865                 return
1866         }
1867
1868         var embeds []ir.Embed
1869         for _, e := range pragmaEmbeds {
1870                 embeds = append(embeds, ir.Embed{Pos: makeXPos(e.Pos), Patterns: e.Patterns})
1871         }
1872         typecheck.Target.Embeds = append(typecheck.Target.Embeds, name)
1873         name.Embed = &embeds
1874 }