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