Black Lives Matter. Support the Equal Justice Initiative.

Source file src/cmd/compile/internal/noder/noder.go

Documentation: cmd/compile/internal/noder

     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  		if p.file == nil {
    72  			base.ErrorExit()
    73  		}
    74  		lines += p.file.EOF.Line()
    75  	}
    76  	base.Timer.AddEvent(int64(lines), "lines")
    77  
    78  	if base.Flag.G != 0 {
    79  		// Use types2 to type-check and possibly generate IR.
    80  		check2(noders)
    81  		return
    82  	}
    83  
    84  	for _, p := range noders {
    85  		p.node()
    86  		p.file = nil // release memory
    87  	}
    88  
    89  	if base.SyntaxErrors() != 0 {
    90  		base.ErrorExit()
    91  	}
    92  	types.CheckDclstack()
    93  
    94  	for _, p := range noders {
    95  		p.processPragmas()
    96  	}
    97  
    98  	// Typecheck.
    99  	types.LocalPkg.Height = myheight
   100  	typecheck.DeclareUniverse()
   101  	typecheck.TypecheckAllowed = true
   102  
   103  	// Process top-level declarations in phases.
   104  
   105  	// Phase 1: const, type, and names and types of funcs.
   106  	//   This will gather all the information about types
   107  	//   and methods but doesn't depend on any of it.
   108  	//
   109  	//   We also defer type alias declarations until phase 2
   110  	//   to avoid cycles like #18640.
   111  	//   TODO(gri) Remove this again once we have a fix for #25838.
   112  
   113  	// Don't use range--typecheck can add closures to Target.Decls.
   114  	base.Timer.Start("fe", "typecheck", "top1")
   115  	for i := 0; i < len(typecheck.Target.Decls); i++ {
   116  		n := typecheck.Target.Decls[i]
   117  		if op := n.Op(); op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.(*ir.Decl).X.Alias()) {
   118  			typecheck.Target.Decls[i] = typecheck.Stmt(n)
   119  		}
   120  	}
   121  
   122  	// Phase 2: Variable assignments.
   123  	//   To check interface assignments, depends on phase 1.
   124  
   125  	// Don't use range--typecheck can add closures to Target.Decls.
   126  	base.Timer.Start("fe", "typecheck", "top2")
   127  	for i := 0; i < len(typecheck.Target.Decls); i++ {
   128  		n := typecheck.Target.Decls[i]
   129  		if op := n.Op(); op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.(*ir.Decl).X.Alias() {
   130  			typecheck.Target.Decls[i] = typecheck.Stmt(n)
   131  		}
   132  	}
   133  
   134  	// Phase 3: Type check function bodies.
   135  	// Don't use range--typecheck can add closures to Target.Decls.
   136  	base.Timer.Start("fe", "typecheck", "func")
   137  	var fcount int64
   138  	for i := 0; i < len(typecheck.Target.Decls); i++ {
   139  		n := typecheck.Target.Decls[i]
   140  		if n.Op() == ir.ODCLFUNC {
   141  			if base.Flag.W > 1 {
   142  				s := fmt.Sprintf("\nbefore typecheck %v", n)
   143  				ir.Dump(s, n)
   144  			}
   145  			typecheck.FuncBody(n.(*ir.Func))
   146  			if base.Flag.W > 1 {
   147  				s := fmt.Sprintf("\nafter typecheck %v", n)
   148  				ir.Dump(s, n)
   149  			}
   150  			fcount++
   151  		}
   152  	}
   153  
   154  	// Phase 4: Check external declarations.
   155  	// TODO(mdempsky): This should be handled when type checking their
   156  	// corresponding ODCL nodes.
   157  	base.Timer.Start("fe", "typecheck", "externdcls")
   158  	for i, n := range typecheck.Target.Externs {
   159  		if n.Op() == ir.ONAME {
   160  			typecheck.Target.Externs[i] = typecheck.Expr(typecheck.Target.Externs[i])
   161  		}
   162  	}
   163  
   164  	// Phase 5: With all user code type-checked, it's now safe to verify map keys.
   165  	// With all user code typechecked, it's now safe to verify unused dot imports.
   166  	typecheck.CheckMapKeys()
   167  	CheckDotImports()
   168  	base.ExitIfErrors()
   169  }
   170  
   171  func (p *noder) errorAt(pos syntax.Pos, format string, args ...interface{}) {
   172  	base.ErrorfAt(p.makeXPos(pos), format, args...)
   173  }
   174  
   175  // TODO(gri) Can we eliminate fileh in favor of absFilename?
   176  func fileh(name string) string {
   177  	return objabi.AbsFile("", name, base.Flag.TrimPath)
   178  }
   179  
   180  func absFilename(name string) string {
   181  	return objabi.AbsFile(base.Ctxt.Pathname, name, base.Flag.TrimPath)
   182  }
   183  
   184  // noder transforms package syntax's AST into a Node tree.
   185  type noder struct {
   186  	posMap
   187  
   188  	file           *syntax.File
   189  	linknames      []linkname
   190  	pragcgobuf     [][]string
   191  	err            chan syntax.Error
   192  	importedUnsafe bool
   193  	importedEmbed  bool
   194  	trackScopes    bool
   195  
   196  	funcState *funcState
   197  }
   198  
   199  // funcState tracks all per-function state to make handling nested
   200  // functions easier.
   201  type funcState struct {
   202  	// scopeVars is a stack tracking the number of variables declared in
   203  	// the current function at the moment each open scope was opened.
   204  	scopeVars []int
   205  	marker    dwarfgen.ScopeMarker
   206  
   207  	lastCloseScopePos syntax.Pos
   208  }
   209  
   210  func (p *noder) funcBody(fn *ir.Func, block *syntax.BlockStmt) {
   211  	outerFuncState := p.funcState
   212  	p.funcState = new(funcState)
   213  	typecheck.StartFuncBody(fn)
   214  
   215  	if block != nil {
   216  		body := p.stmts(block.List)
   217  		if body == nil {
   218  			body = []ir.Node{ir.NewBlockStmt(base.Pos, nil)}
   219  		}
   220  		fn.Body = body
   221  
   222  		base.Pos = p.makeXPos(block.Rbrace)
   223  		fn.Endlineno = base.Pos
   224  	}
   225  
   226  	typecheck.FinishFuncBody()
   227  	p.funcState.marker.WriteTo(fn)
   228  	p.funcState = outerFuncState
   229  }
   230  
   231  func (p *noder) openScope(pos syntax.Pos) {
   232  	fs := p.funcState
   233  	types.Markdcl()
   234  
   235  	if p.trackScopes {
   236  		fs.scopeVars = append(fs.scopeVars, len(ir.CurFunc.Dcl))
   237  		fs.marker.Push(p.makeXPos(pos))
   238  	}
   239  }
   240  
   241  func (p *noder) closeScope(pos syntax.Pos) {
   242  	fs := p.funcState
   243  	fs.lastCloseScopePos = pos
   244  	types.Popdcl()
   245  
   246  	if p.trackScopes {
   247  		scopeVars := fs.scopeVars[len(fs.scopeVars)-1]
   248  		fs.scopeVars = fs.scopeVars[:len(fs.scopeVars)-1]
   249  		if scopeVars == len(ir.CurFunc.Dcl) {
   250  			// no variables were declared in this scope, so we can retract it.
   251  			fs.marker.Unpush()
   252  		} else {
   253  			fs.marker.Pop(p.makeXPos(pos))
   254  		}
   255  	}
   256  }
   257  
   258  // closeAnotherScope is like closeScope, but it reuses the same mark
   259  // position as the last closeScope call. This is useful for "for" and
   260  // "if" statements, as their implicit blocks always end at the same
   261  // position as an explicit block.
   262  func (p *noder) closeAnotherScope() {
   263  	p.closeScope(p.funcState.lastCloseScopePos)
   264  }
   265  
   266  // linkname records a //go:linkname directive.
   267  type linkname struct {
   268  	pos    syntax.Pos
   269  	local  string
   270  	remote string
   271  }
   272  
   273  func (p *noder) node() {
   274  	p.importedUnsafe = false
   275  	p.importedEmbed = false
   276  
   277  	p.setlineno(p.file.PkgName)
   278  	mkpackage(p.file.PkgName.Value)
   279  
   280  	if pragma, ok := p.file.Pragma.(*pragmas); ok {
   281  		pragma.Flag &^= ir.GoBuildPragma
   282  		p.checkUnused(pragma)
   283  	}
   284  
   285  	typecheck.Target.Decls = append(typecheck.Target.Decls, p.decls(p.file.DeclList)...)
   286  
   287  	base.Pos = src.NoXPos
   288  	clearImports()
   289  }
   290  
   291  func (p *noder) processPragmas() {
   292  	for _, l := range p.linknames {
   293  		if !p.importedUnsafe {
   294  			p.errorAt(l.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
   295  			continue
   296  		}
   297  		n := ir.AsNode(typecheck.Lookup(l.local).Def)
   298  		if n == nil || n.Op() != ir.ONAME {
   299  			// TODO(mdempsky): Change to p.errorAt before Go 1.17 release.
   300  			// base.WarnfAt(p.makeXPos(l.pos), "//go:linkname must refer to declared function or variable (will be an error in Go 1.17)")
   301  			continue
   302  		}
   303  		if n.Sym().Linkname != "" {
   304  			p.errorAt(l.pos, "duplicate //go:linkname for %s", l.local)
   305  			continue
   306  		}
   307  		n.Sym().Linkname = l.remote
   308  	}
   309  	typecheck.Target.CgoPragmas = append(typecheck.Target.CgoPragmas, p.pragcgobuf...)
   310  }
   311  
   312  func (p *noder) decls(decls []syntax.Decl) (l []ir.Node) {
   313  	var cs constState
   314  
   315  	for _, decl := range decls {
   316  		p.setlineno(decl)
   317  		switch decl := decl.(type) {
   318  		case *syntax.ImportDecl:
   319  			p.importDecl(decl)
   320  
   321  		case *syntax.VarDecl:
   322  			l = append(l, p.varDecl(decl)...)
   323  
   324  		case *syntax.ConstDecl:
   325  			l = append(l, p.constDecl(decl, &cs)...)
   326  
   327  		case *syntax.TypeDecl:
   328  			l = append(l, p.typeDecl(decl))
   329  
   330  		case *syntax.FuncDecl:
   331  			l = append(l, p.funcDecl(decl))
   332  
   333  		default:
   334  			panic("unhandled Decl")
   335  		}
   336  	}
   337  
   338  	return
   339  }
   340  
   341  func (p *noder) importDecl(imp *syntax.ImportDecl) {
   342  	if imp.Path == nil || imp.Path.Bad {
   343  		return // avoid follow-on errors if there was a syntax error
   344  	}
   345  
   346  	if pragma, ok := imp.Pragma.(*pragmas); ok {
   347  		p.checkUnused(pragma)
   348  	}
   349  
   350  	ipkg := importfile(imp)
   351  	if ipkg == nil {
   352  		if base.Errors() == 0 {
   353  			base.Fatalf("phase error in import")
   354  		}
   355  		return
   356  	}
   357  
   358  	if ipkg == ir.Pkgs.Unsafe {
   359  		p.importedUnsafe = true
   360  	}
   361  	if ipkg.Path == "embed" {
   362  		p.importedEmbed = true
   363  	}
   364  
   365  	var my *types.Sym
   366  	if imp.LocalPkgName != nil {
   367  		my = p.name(imp.LocalPkgName)
   368  	} else {
   369  		my = typecheck.Lookup(ipkg.Name)
   370  	}
   371  
   372  	pack := ir.NewPkgName(p.pos(imp), my, ipkg)
   373  
   374  	switch my.Name {
   375  	case ".":
   376  		importDot(pack)
   377  		return
   378  	case "init":
   379  		base.ErrorfAt(pack.Pos(), "cannot import package as init - init must be a func")
   380  		return
   381  	case "_":
   382  		return
   383  	}
   384  	if my.Def != nil {
   385  		typecheck.Redeclared(pack.Pos(), my, "as imported package name")
   386  	}
   387  	my.Def = pack
   388  	my.Lastlineno = pack.Pos()
   389  	my.Block = 1 // at top level
   390  }
   391  
   392  func (p *noder) varDecl(decl *syntax.VarDecl) []ir.Node {
   393  	names := p.declNames(ir.ONAME, decl.NameList)
   394  	typ := p.typeExprOrNil(decl.Type)
   395  	exprs := p.exprList(decl.Values)
   396  
   397  	if pragma, ok := decl.Pragma.(*pragmas); ok {
   398  		varEmbed(p.makeXPos, names[0], decl, pragma, p.importedEmbed)
   399  		p.checkUnused(pragma)
   400  	}
   401  
   402  	var init []ir.Node
   403  	p.setlineno(decl)
   404  
   405  	if len(names) > 1 && len(exprs) == 1 {
   406  		as2 := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, exprs)
   407  		for _, v := range names {
   408  			as2.Lhs.Append(v)
   409  			typecheck.Declare(v, typecheck.DeclContext)
   410  			v.Ntype = typ
   411  			v.Defn = as2
   412  			if ir.CurFunc != nil {
   413  				init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v))
   414  			}
   415  		}
   416  
   417  		return append(init, as2)
   418  	}
   419  
   420  	for i, v := range names {
   421  		var e ir.Node
   422  		if i < len(exprs) {
   423  			e = exprs[i]
   424  		}
   425  
   426  		typecheck.Declare(v, typecheck.DeclContext)
   427  		v.Ntype = typ
   428  
   429  		if ir.CurFunc != nil {
   430  			init = append(init, ir.NewDecl(base.Pos, ir.ODCL, v))
   431  		}
   432  		as := ir.NewAssignStmt(base.Pos, v, e)
   433  		init = append(init, as)
   434  		if e != nil || ir.CurFunc == nil {
   435  			v.Defn = as
   436  		}
   437  	}
   438  
   439  	if len(exprs) != 0 && len(names) != len(exprs) {
   440  		base.Errorf("assignment mismatch: %d variables but %d values", len(names), len(exprs))
   441  	}
   442  
   443  	return init
   444  }
   445  
   446  // constState tracks state between constant specifiers within a
   447  // declaration group. This state is kept separate from noder so nested
   448  // constant declarations are handled correctly (e.g., issue 15550).
   449  type constState struct {
   450  	group  *syntax.Group
   451  	typ    ir.Ntype
   452  	values []ir.Node
   453  	iota   int64
   454  }
   455  
   456  func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []ir.Node {
   457  	if decl.Group == nil || decl.Group != cs.group {
   458  		*cs = constState{
   459  			group: decl.Group,
   460  		}
   461  	}
   462  
   463  	if pragma, ok := decl.Pragma.(*pragmas); ok {
   464  		p.checkUnused(pragma)
   465  	}
   466  
   467  	names := p.declNames(ir.OLITERAL, decl.NameList)
   468  	typ := p.typeExprOrNil(decl.Type)
   469  
   470  	var values []ir.Node
   471  	if decl.Values != nil {
   472  		values = p.exprList(decl.Values)
   473  		cs.typ, cs.values = typ, values
   474  	} else {
   475  		if typ != nil {
   476  			base.Errorf("const declaration cannot have type without expression")
   477  		}
   478  		typ, values = cs.typ, cs.values
   479  	}
   480  
   481  	nn := make([]ir.Node, 0, len(names))
   482  	for i, n := range names {
   483  		if i >= len(values) {
   484  			base.Errorf("missing value in const declaration")
   485  			break
   486  		}
   487  		v := values[i]
   488  		if decl.Values == nil {
   489  			v = ir.DeepCopy(n.Pos(), v)
   490  		}
   491  		typecheck.Declare(n, typecheck.DeclContext)
   492  
   493  		n.Ntype = typ
   494  		n.Defn = v
   495  		n.SetIota(cs.iota)
   496  
   497  		nn = append(nn, ir.NewDecl(p.pos(decl), ir.ODCLCONST, n))
   498  	}
   499  
   500  	if len(values) > len(names) {
   501  		base.Errorf("extra expression in const declaration")
   502  	}
   503  
   504  	cs.iota++
   505  
   506  	return nn
   507  }
   508  
   509  func (p *noder) typeDecl(decl *syntax.TypeDecl) ir.Node {
   510  	n := p.declName(ir.OTYPE, decl.Name)
   511  	typecheck.Declare(n, typecheck.DeclContext)
   512  
   513  	// decl.Type may be nil but in that case we got a syntax error during parsing
   514  	typ := p.typeExprOrNil(decl.Type)
   515  
   516  	n.Ntype = typ
   517  	n.SetAlias(decl.Alias)
   518  	if pragma, ok := decl.Pragma.(*pragmas); ok {
   519  		if !decl.Alias {
   520  			n.SetPragma(pragma.Flag & typePragmas)
   521  			pragma.Flag &^= typePragmas
   522  		}
   523  		p.checkUnused(pragma)
   524  	}
   525  
   526  	nod := ir.NewDecl(p.pos(decl), ir.ODCLTYPE, n)
   527  	if n.Alias() && !types.AllowsGoVersion(types.LocalPkg, 1, 9) {
   528  		base.ErrorfAt(nod.Pos(), "type aliases only supported as of -lang=go1.9")
   529  	}
   530  	return nod
   531  }
   532  
   533  func (p *noder) declNames(op ir.Op, names []*syntax.Name) []*ir.Name {
   534  	nodes := make([]*ir.Name, 0, len(names))
   535  	for _, name := range names {
   536  		nodes = append(nodes, p.declName(op, name))
   537  	}
   538  	return nodes
   539  }
   540  
   541  func (p *noder) declName(op ir.Op, name *syntax.Name) *ir.Name {
   542  	return ir.NewDeclNameAt(p.pos(name), op, p.name(name))
   543  }
   544  
   545  func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node {
   546  	name := p.name(fun.Name)
   547  	t := p.signature(fun.Recv, fun.Type)
   548  	f := ir.NewFunc(p.pos(fun))
   549  
   550  	if fun.Recv == nil {
   551  		if name.Name == "init" {
   552  			name = renameinit()
   553  			if len(t.Params) > 0 || len(t.Results) > 0 {
   554  				base.ErrorfAt(f.Pos(), "func init must have no arguments and no return values")
   555  			}
   556  			typecheck.Target.Inits = append(typecheck.Target.Inits, f)
   557  		}
   558  
   559  		if types.LocalPkg.Name == "main" && name.Name == "main" {
   560  			if len(t.Params) > 0 || len(t.Results) > 0 {
   561  				base.ErrorfAt(f.Pos(), "func main must have no arguments and no return values")
   562  			}
   563  		}
   564  	} else {
   565  		f.Shortname = name
   566  		name = ir.BlankNode.Sym() // filled in by tcFunc
   567  	}
   568  
   569  	f.Nname = ir.NewNameAt(p.pos(fun.Name), name)
   570  	f.Nname.Func = f
   571  	f.Nname.Defn = f
   572  	f.Nname.Ntype = t
   573  
   574  	if pragma, ok := fun.Pragma.(*pragmas); ok {
   575  		f.Pragma = pragma.Flag & funcPragmas
   576  		if pragma.Flag&ir.Systemstack != 0 && pragma.Flag&ir.Nosplit != 0 {
   577  			base.ErrorfAt(f.Pos(), "go:nosplit and go:systemstack cannot be combined")
   578  		}
   579  		pragma.Flag &^= funcPragmas
   580  		p.checkUnused(pragma)
   581  	}
   582  
   583  	if fun.Recv == nil {
   584  		typecheck.Declare(f.Nname, ir.PFUNC)
   585  	}
   586  
   587  	p.funcBody(f, fun.Body)
   588  
   589  	if fun.Body != nil {
   590  		if f.Pragma&ir.Noescape != 0 {
   591  			base.ErrorfAt(f.Pos(), "can only use //go:noescape with external func implementations")
   592  		}
   593  	} else {
   594  		if base.Flag.Complete || strings.HasPrefix(ir.FuncName(f), "init.") {
   595  			// Linknamed functions are allowed to have no body. Hopefully
   596  			// the linkname target has a body. See issue 23311.
   597  			isLinknamed := false
   598  			for _, n := range p.linknames {
   599  				if ir.FuncName(f) == n.local {
   600  					isLinknamed = true
   601  					break
   602  				}
   603  			}
   604  			if !isLinknamed {
   605  				base.ErrorfAt(f.Pos(), "missing function body")
   606  			}
   607  		}
   608  	}
   609  
   610  	return f
   611  }
   612  
   613  func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *ir.FuncType {
   614  	var rcvr *ir.Field
   615  	if recv != nil {
   616  		rcvr = p.param(recv, false, false)
   617  	}
   618  	return ir.NewFuncType(p.pos(typ), rcvr,
   619  		p.params(typ.ParamList, true),
   620  		p.params(typ.ResultList, false))
   621  }
   622  
   623  func (p *noder) params(params []*syntax.Field, dddOk bool) []*ir.Field {
   624  	nodes := make([]*ir.Field, 0, len(params))
   625  	for i, param := range params {
   626  		p.setlineno(param)
   627  		nodes = append(nodes, p.param(param, dddOk, i+1 == len(params)))
   628  	}
   629  	return nodes
   630  }
   631  
   632  func (p *noder) param(param *syntax.Field, dddOk, final bool) *ir.Field {
   633  	var name *types.Sym
   634  	if param.Name != nil {
   635  		name = p.name(param.Name)
   636  	}
   637  
   638  	typ := p.typeExpr(param.Type)
   639  	n := ir.NewField(p.pos(param), name, typ, nil)
   640  
   641  	// rewrite ...T parameter
   642  	if typ, ok := typ.(*ir.SliceType); ok && typ.DDD {
   643  		if !dddOk {
   644  			// We mark these as syntax errors to get automatic elimination
   645  			// of multiple such errors per line (see ErrorfAt in subr.go).
   646  			base.Errorf("syntax error: cannot use ... in receiver or result parameter list")
   647  		} else if !final {
   648  			if param.Name == nil {
   649  				base.Errorf("syntax error: cannot use ... with non-final parameter")
   650  			} else {
   651  				p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
   652  			}
   653  		}
   654  		typ.DDD = false
   655  		n.IsDDD = true
   656  	}
   657  
   658  	return n
   659  }
   660  
   661  func (p *noder) exprList(expr syntax.Expr) []ir.Node {
   662  	switch expr := expr.(type) {
   663  	case nil:
   664  		return nil
   665  	case *syntax.ListExpr:
   666  		return p.exprs(expr.ElemList)
   667  	default:
   668  		return []ir.Node{p.expr(expr)}
   669  	}
   670  }
   671  
   672  func (p *noder) exprs(exprs []syntax.Expr) []ir.Node {
   673  	nodes := make([]ir.Node, 0, len(exprs))
   674  	for _, expr := range exprs {
   675  		nodes = append(nodes, p.expr(expr))
   676  	}
   677  	return nodes
   678  }
   679  
   680  func (p *noder) expr(expr syntax.Expr) ir.Node {
   681  	p.setlineno(expr)
   682  	switch expr := expr.(type) {
   683  	case nil, *syntax.BadExpr:
   684  		return nil
   685  	case *syntax.Name:
   686  		return p.mkname(expr)
   687  	case *syntax.BasicLit:
   688  		n := ir.NewBasicLit(p.pos(expr), p.basicLit(expr))
   689  		if expr.Kind == syntax.RuneLit {
   690  			n.SetType(types.UntypedRune)
   691  		}
   692  		n.SetDiag(expr.Bad || n.Val().Kind() == constant.Unknown) // avoid follow-on errors if there was a syntax error
   693  		return n
   694  	case *syntax.CompositeLit:
   695  		n := ir.NewCompLitExpr(p.pos(expr), ir.OCOMPLIT, p.typeExpr(expr.Type), nil)
   696  		l := p.exprs(expr.ElemList)
   697  		for i, e := range l {
   698  			l[i] = p.wrapname(expr.ElemList[i], e)
   699  		}
   700  		n.List = l
   701  		base.Pos = p.makeXPos(expr.Rbrace)
   702  		return n
   703  	case *syntax.KeyValueExpr:
   704  		// use position of expr.Key rather than of expr (which has position of ':')
   705  		return ir.NewKeyExpr(p.pos(expr.Key), p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value)))
   706  	case *syntax.FuncLit:
   707  		return p.funcLit(expr)
   708  	case *syntax.ParenExpr:
   709  		return ir.NewParenExpr(p.pos(expr), p.expr(expr.X))
   710  	case *syntax.SelectorExpr:
   711  		// parser.new_dotname
   712  		obj := p.expr(expr.X)
   713  		if obj.Op() == ir.OPACK {
   714  			pack := obj.(*ir.PkgName)
   715  			pack.Used = true
   716  			return importName(pack.Pkg.Lookup(expr.Sel.Value))
   717  		}
   718  		n := ir.NewSelectorExpr(base.Pos, ir.OXDOT, obj, p.name(expr.Sel))
   719  		n.SetPos(p.pos(expr)) // lineno may have been changed by p.expr(expr.X)
   720  		return n
   721  	case *syntax.IndexExpr:
   722  		return ir.NewIndexExpr(p.pos(expr), p.expr(expr.X), p.expr(expr.Index))
   723  	case *syntax.SliceExpr:
   724  		op := ir.OSLICE
   725  		if expr.Full {
   726  			op = ir.OSLICE3
   727  		}
   728  		x := p.expr(expr.X)
   729  		var index [3]ir.Node
   730  		for i, n := range &expr.Index {
   731  			if n != nil {
   732  				index[i] = p.expr(n)
   733  			}
   734  		}
   735  		return ir.NewSliceExpr(p.pos(expr), op, x, index[0], index[1], index[2])
   736  	case *syntax.AssertExpr:
   737  		return ir.NewTypeAssertExpr(p.pos(expr), p.expr(expr.X), p.typeExpr(expr.Type))
   738  	case *syntax.Operation:
   739  		if expr.Op == syntax.Add && expr.Y != nil {
   740  			return p.sum(expr)
   741  		}
   742  		x := p.expr(expr.X)
   743  		if expr.Y == nil {
   744  			pos, op := p.pos(expr), p.unOp(expr.Op)
   745  			switch op {
   746  			case ir.OADDR:
   747  				return typecheck.NodAddrAt(pos, x)
   748  			case ir.ODEREF:
   749  				return ir.NewStarExpr(pos, x)
   750  			}
   751  			return ir.NewUnaryExpr(pos, op, x)
   752  		}
   753  
   754  		pos, op, y := p.pos(expr), p.binOp(expr.Op), p.expr(expr.Y)
   755  		switch op {
   756  		case ir.OANDAND, ir.OOROR:
   757  			return ir.NewLogicalExpr(pos, op, x, y)
   758  		}
   759  		return ir.NewBinaryExpr(pos, op, x, y)
   760  	case *syntax.CallExpr:
   761  		n := ir.NewCallExpr(p.pos(expr), ir.OCALL, p.expr(expr.Fun), p.exprs(expr.ArgList))
   762  		n.IsDDD = expr.HasDots
   763  		return n
   764  
   765  	case *syntax.ArrayType:
   766  		var len ir.Node
   767  		if expr.Len != nil {
   768  			len = p.expr(expr.Len)
   769  		}
   770  		return ir.NewArrayType(p.pos(expr), len, p.typeExpr(expr.Elem))
   771  	case *syntax.SliceType:
   772  		return ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
   773  	case *syntax.DotsType:
   774  		t := ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
   775  		t.DDD = true
   776  		return t
   777  	case *syntax.StructType:
   778  		return p.structType(expr)
   779  	case *syntax.InterfaceType:
   780  		return p.interfaceType(expr)
   781  	case *syntax.FuncType:
   782  		return p.signature(nil, expr)
   783  	case *syntax.MapType:
   784  		return ir.NewMapType(p.pos(expr),
   785  			p.typeExpr(expr.Key), p.typeExpr(expr.Value))
   786  	case *syntax.ChanType:
   787  		return ir.NewChanType(p.pos(expr),
   788  			p.typeExpr(expr.Elem), p.chanDir(expr.Dir))
   789  
   790  	case *syntax.TypeSwitchGuard:
   791  		var tag *ir.Ident
   792  		if expr.Lhs != nil {
   793  			tag = ir.NewIdent(p.pos(expr.Lhs), p.name(expr.Lhs))
   794  			if ir.IsBlank(tag) {
   795  				base.Errorf("invalid variable name %v in type switch", tag)
   796  			}
   797  		}
   798  		return ir.NewTypeSwitchGuard(p.pos(expr), tag, p.expr(expr.X))
   799  	}
   800  	panic("unhandled Expr")
   801  }
   802  
   803  // sum efficiently handles very large summation expressions (such as
   804  // in issue #16394). In particular, it avoids left recursion and
   805  // collapses string literals.
   806  func (p *noder) sum(x syntax.Expr) ir.Node {
   807  	// While we need to handle long sums with asymptotic
   808  	// efficiency, the vast majority of sums are very small: ~95%
   809  	// have only 2 or 3 operands, and ~99% of string literals are
   810  	// never concatenated.
   811  
   812  	adds := make([]*syntax.Operation, 0, 2)
   813  	for {
   814  		add, ok := x.(*syntax.Operation)
   815  		if !ok || add.Op != syntax.Add || add.Y == nil {
   816  			break
   817  		}
   818  		adds = append(adds, add)
   819  		x = add.X
   820  	}
   821  
   822  	// nstr is the current rightmost string literal in the
   823  	// summation (if any), and chunks holds its accumulated
   824  	// substrings.
   825  	//
   826  	// Consider the expression x + "a" + "b" + "c" + y. When we
   827  	// reach the string literal "a", we assign nstr to point to
   828  	// its corresponding Node and initialize chunks to {"a"}.
   829  	// Visiting the subsequent string literals "b" and "c", we
   830  	// simply append their values to chunks. Finally, when we
   831  	// reach the non-constant operand y, we'll join chunks to form
   832  	// "abc" and reassign the "a" string literal's value.
   833  	//
   834  	// N.B., we need to be careful about named string constants
   835  	// (indicated by Sym != nil) because 1) we can't modify their
   836  	// value, as doing so would affect other uses of the string
   837  	// constant, and 2) they may have types, which we need to
   838  	// handle correctly. For now, we avoid these problems by
   839  	// treating named string constants the same as non-constant
   840  	// operands.
   841  	var nstr ir.Node
   842  	chunks := make([]string, 0, 1)
   843  
   844  	n := p.expr(x)
   845  	if ir.IsConst(n, constant.String) && n.Sym() == nil {
   846  		nstr = n
   847  		chunks = append(chunks, ir.StringVal(nstr))
   848  	}
   849  
   850  	for i := len(adds) - 1; i >= 0; i-- {
   851  		add := adds[i]
   852  
   853  		r := p.expr(add.Y)
   854  		if ir.IsConst(r, constant.String) && r.Sym() == nil {
   855  			if nstr != nil {
   856  				// Collapse r into nstr instead of adding to n.
   857  				chunks = append(chunks, ir.StringVal(r))
   858  				continue
   859  			}
   860  
   861  			nstr = r
   862  			chunks = append(chunks, ir.StringVal(nstr))
   863  		} else {
   864  			if len(chunks) > 1 {
   865  				nstr.SetVal(constant.MakeString(strings.Join(chunks, "")))
   866  			}
   867  			nstr = nil
   868  			chunks = chunks[:0]
   869  		}
   870  		n = ir.NewBinaryExpr(p.pos(add), ir.OADD, n, r)
   871  	}
   872  	if len(chunks) > 1 {
   873  		nstr.SetVal(constant.MakeString(strings.Join(chunks, "")))
   874  	}
   875  
   876  	return n
   877  }
   878  
   879  func (p *noder) typeExpr(typ syntax.Expr) ir.Ntype {
   880  	// TODO(mdempsky): Be stricter? typecheck should handle errors anyway.
   881  	n := p.expr(typ)
   882  	if n == nil {
   883  		return nil
   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  		// The max. mantissa precision for untyped numeric values
  1459  		// is 512 bits, or 4048 bits for each of the two integer
  1460  		// parts of a fraction for floating-point numbers that are
  1461  		// represented accurately in the go/constant package.
  1462  		// Constant literals that are longer than this many bits
  1463  		// are not meaningful; and excessively long constants may
  1464  		// consume a lot of space and time for a useless conversion.
  1465  		// Cap constant length with a generous upper limit that also
  1466  		// allows for separators between all digits.
  1467  		const limit = 10000
  1468  		if len(lit.Value) > limit {
  1469  			p.errorAt(lit.Pos(), "excessively long constant: %s... (%d chars)", lit.Value[:10], len(lit.Value))
  1470  			return constant.MakeUnknown()
  1471  		}
  1472  	}
  1473  
  1474  	v := constant.MakeFromLiteral(lit.Value, tokenForLitKind[lit.Kind], 0)
  1475  	if v.Kind() == constant.Unknown {
  1476  		// TODO(mdempsky): Better error message?
  1477  		p.errorAt(lit.Pos(), "malformed constant: %s", lit.Value)
  1478  	}
  1479  
  1480  	return v
  1481  }
  1482  
  1483  var tokenForLitKind = [...]token.Token{
  1484  	syntax.IntLit:    token.INT,
  1485  	syntax.RuneLit:   token.CHAR,
  1486  	syntax.FloatLit:  token.FLOAT,
  1487  	syntax.ImagLit:   token.IMAG,
  1488  	syntax.StringLit: token.STRING,
  1489  }
  1490  
  1491  func (p *noder) name(name *syntax.Name) *types.Sym {
  1492  	return typecheck.Lookup(name.Value)
  1493  }
  1494  
  1495  func (p *noder) mkname(name *syntax.Name) ir.Node {
  1496  	// TODO(mdempsky): Set line number?
  1497  	return mkname(p.name(name))
  1498  }
  1499  
  1500  func (p *noder) wrapname(n syntax.Node, x ir.Node) ir.Node {
  1501  	// These nodes do not carry line numbers.
  1502  	// Introduce a wrapper node to give them the correct line.
  1503  	switch x.Op() {
  1504  	case ir.OTYPE, ir.OLITERAL:
  1505  		if x.Sym() == nil {
  1506  			break
  1507  		}
  1508  		fallthrough
  1509  	case ir.ONAME, ir.ONONAME, ir.OPACK:
  1510  		p := ir.NewParenExpr(p.pos(n), x)
  1511  		p.SetImplicit(true)
  1512  		return p
  1513  	}
  1514  	return x
  1515  }
  1516  
  1517  func (p *noder) setlineno(n syntax.Node) {
  1518  	if n != nil {
  1519  		base.Pos = p.pos(n)
  1520  	}
  1521  }
  1522  
  1523  // error is called concurrently if files are parsed concurrently.
  1524  func (p *noder) error(err error) {
  1525  	p.err <- err.(syntax.Error)
  1526  }
  1527  
  1528  // pragmas that are allowed in the std lib, but don't have
  1529  // a syntax.Pragma value (see lex.go) associated with them.
  1530  var allowedStdPragmas = map[string]bool{
  1531  	"go:cgo_export_static":  true,
  1532  	"go:cgo_export_dynamic": true,
  1533  	"go:cgo_import_static":  true,
  1534  	"go:cgo_import_dynamic": true,
  1535  	"go:cgo_ldflag":         true,
  1536  	"go:cgo_dynamic_linker": true,
  1537  	"go:embed":              true,
  1538  	"go:generate":           true,
  1539  }
  1540  
  1541  // *pragmas is the value stored in a syntax.pragmas during parsing.
  1542  type pragmas struct {
  1543  	Flag   ir.PragmaFlag // collected bits
  1544  	Pos    []pragmaPos   // position of each individual flag
  1545  	Embeds []pragmaEmbed
  1546  }
  1547  
  1548  type pragmaPos struct {
  1549  	Flag ir.PragmaFlag
  1550  	Pos  syntax.Pos
  1551  }
  1552  
  1553  type pragmaEmbed struct {
  1554  	Pos      syntax.Pos
  1555  	Patterns []string
  1556  }
  1557  
  1558  func (p *noder) checkUnused(pragma *pragmas) {
  1559  	for _, pos := range pragma.Pos {
  1560  		if pos.Flag&pragma.Flag != 0 {
  1561  			p.errorAt(pos.Pos, "misplaced compiler directive")
  1562  		}
  1563  	}
  1564  	if len(pragma.Embeds) > 0 {
  1565  		for _, e := range pragma.Embeds {
  1566  			p.errorAt(e.Pos, "misplaced go:embed directive")
  1567  		}
  1568  	}
  1569  }
  1570  
  1571  func (p *noder) checkUnusedDuringParse(pragma *pragmas) {
  1572  	for _, pos := range pragma.Pos {
  1573  		if pos.Flag&pragma.Flag != 0 {
  1574  			p.error(syntax.Error{Pos: pos.Pos, Msg: "misplaced compiler directive"})
  1575  		}
  1576  	}
  1577  	if len(pragma.Embeds) > 0 {
  1578  		for _, e := range pragma.Embeds {
  1579  			p.error(syntax.Error{Pos: e.Pos, Msg: "misplaced go:embed directive"})
  1580  		}
  1581  	}
  1582  }
  1583  
  1584  // pragma is called concurrently if files are parsed concurrently.
  1585  func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.Pragma) syntax.Pragma {
  1586  	pragma, _ := old.(*pragmas)
  1587  	if pragma == nil {
  1588  		pragma = new(pragmas)
  1589  	}
  1590  
  1591  	if text == "" {
  1592  		// unused pragma; only called with old != nil.
  1593  		p.checkUnusedDuringParse(pragma)
  1594  		return nil
  1595  	}
  1596  
  1597  	if strings.HasPrefix(text, "line ") {
  1598  		// line directives are handled by syntax package
  1599  		panic("unreachable")
  1600  	}
  1601  
  1602  	if !blankLine {
  1603  		// directive must be on line by itself
  1604  		p.error(syntax.Error{Pos: pos, Msg: "misplaced compiler directive"})
  1605  		return pragma
  1606  	}
  1607  
  1608  	switch {
  1609  	case strings.HasPrefix(text, "go:linkname "):
  1610  		f := strings.Fields(text)
  1611  		if !(2 <= len(f) && len(f) <= 3) {
  1612  			p.error(syntax.Error{Pos: pos, Msg: "usage: //go:linkname localname [linkname]"})
  1613  			break
  1614  		}
  1615  		// The second argument is optional. If omitted, we use
  1616  		// the default object symbol name for this and
  1617  		// linkname only serves to mark this symbol as
  1618  		// something that may be referenced via the object
  1619  		// symbol name from another package.
  1620  		var target string
  1621  		if len(f) == 3 {
  1622  			target = f[2]
  1623  		} else if base.Ctxt.Pkgpath != "" {
  1624  			// Use the default object symbol name if the
  1625  			// user didn't provide one.
  1626  			target = objabi.PathToPrefix(base.Ctxt.Pkgpath) + "." + f[1]
  1627  		} else {
  1628  			p.error(syntax.Error{Pos: pos, Msg: "//go:linkname requires linkname argument or -p compiler flag"})
  1629  			break
  1630  		}
  1631  		p.linknames = append(p.linknames, linkname{pos, f[1], target})
  1632  
  1633  	case text == "go:embed", strings.HasPrefix(text, "go:embed "):
  1634  		args, err := parseGoEmbed(text[len("go:embed"):])
  1635  		if err != nil {
  1636  			p.error(syntax.Error{Pos: pos, Msg: err.Error()})
  1637  		}
  1638  		if len(args) == 0 {
  1639  			p.error(syntax.Error{Pos: pos, Msg: "usage: //go:embed pattern..."})
  1640  			break
  1641  		}
  1642  		pragma.Embeds = append(pragma.Embeds, pragmaEmbed{pos, args})
  1643  
  1644  	case strings.HasPrefix(text, "go:cgo_import_dynamic "):
  1645  		// This is permitted for general use because Solaris
  1646  		// code relies on it in golang.org/x/sys/unix and others.
  1647  		fields := pragmaFields(text)
  1648  		if len(fields) >= 4 {
  1649  			lib := strings.Trim(fields[3], `"`)
  1650  			if lib != "" && !safeArg(lib) && !isCgoGeneratedFile(pos) {
  1651  				p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("invalid library name %q in cgo_import_dynamic directive", lib)})
  1652  			}
  1653  			p.pragcgo(pos, text)
  1654  			pragma.Flag |= pragmaFlag("go:cgo_import_dynamic")
  1655  			break
  1656  		}
  1657  		fallthrough
  1658  	case strings.HasPrefix(text, "go:cgo_"):
  1659  		// For security, we disallow //go:cgo_* directives other
  1660  		// than cgo_import_dynamic outside cgo-generated files.
  1661  		// Exception: they are allowed in the standard library, for runtime and syscall.
  1662  		if !isCgoGeneratedFile(pos) && !base.Flag.Std {
  1663  			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in cgo-generated code", text)})
  1664  		}
  1665  		p.pragcgo(pos, text)
  1666  		fallthrough // because of //go:cgo_unsafe_args
  1667  	default:
  1668  		verb := text
  1669  		if i := strings.Index(text, " "); i >= 0 {
  1670  			verb = verb[:i]
  1671  		}
  1672  		flag := pragmaFlag(verb)
  1673  		const runtimePragmas = ir.Systemstack | ir.Nowritebarrier | ir.Nowritebarrierrec | ir.Yeswritebarrierrec
  1674  		if !base.Flag.CompilingRuntime && flag&runtimePragmas != 0 {
  1675  			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)})
  1676  		}
  1677  		if flag == 0 && !allowedStdPragmas[verb] && base.Flag.Std {
  1678  			p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s is not allowed in the standard library", verb)})
  1679  		}
  1680  		pragma.Flag |= flag
  1681  		pragma.Pos = append(pragma.Pos, pragmaPos{flag, pos})
  1682  	}
  1683  
  1684  	return pragma
  1685  }
  1686  
  1687  // isCgoGeneratedFile reports whether pos is in a file
  1688  // generated by cgo, which is to say a file with name
  1689  // beginning with "_cgo_". Such files are allowed to
  1690  // contain cgo directives, and for security reasons
  1691  // (primarily misuse of linker flags), other files are not.
  1692  // See golang.org/issue/23672.
  1693  func isCgoGeneratedFile(pos syntax.Pos) bool {
  1694  	return strings.HasPrefix(filepath.Base(filepath.Clean(fileh(pos.Base().Filename()))), "_cgo_")
  1695  }
  1696  
  1697  // safeArg reports whether arg is a "safe" command-line argument,
  1698  // meaning that when it appears in a command-line, it probably
  1699  // doesn't have some special meaning other than its own name.
  1700  // This is copied from SafeArg in cmd/go/internal/load/pkg.go.
  1701  func safeArg(name string) bool {
  1702  	if name == "" {
  1703  		return false
  1704  	}
  1705  	c := name[0]
  1706  	return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
  1707  }
  1708  
  1709  func mkname(sym *types.Sym) ir.Node {
  1710  	n := oldname(sym)
  1711  	if n.Name() != nil && n.Name().PkgName != nil {
  1712  		n.Name().PkgName.Used = true
  1713  	}
  1714  	return n
  1715  }
  1716  
  1717  // parseGoEmbed parses the text following "//go:embed" to extract the glob patterns.
  1718  // It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings.
  1719  // go/build/read.go also processes these strings and contains similar logic.
  1720  func parseGoEmbed(args string) ([]string, error) {
  1721  	var list []string
  1722  	for args = strings.TrimSpace(args); args != ""; args = strings.TrimSpace(args) {
  1723  		var path string
  1724  	Switch:
  1725  		switch args[0] {
  1726  		default:
  1727  			i := len(args)
  1728  			for j, c := range args {
  1729  				if unicode.IsSpace(c) {
  1730  					i = j
  1731  					break
  1732  				}
  1733  			}
  1734  			path = args[:i]
  1735  			args = args[i:]
  1736  
  1737  		case '`':
  1738  			i := strings.Index(args[1:], "`")
  1739  			if i < 0 {
  1740  				return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
  1741  			}
  1742  			path = args[1 : 1+i]
  1743  			args = args[1+i+1:]
  1744  
  1745  		case '"':
  1746  			i := 1
  1747  			for ; i < len(args); i++ {
  1748  				if args[i] == '\\' {
  1749  					i++
  1750  					continue
  1751  				}
  1752  				if args[i] == '"' {
  1753  					q, err := strconv.Unquote(args[:i+1])
  1754  					if err != nil {
  1755  						return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args[:i+1])
  1756  					}
  1757  					path = q
  1758  					args = args[i+1:]
  1759  					break Switch
  1760  				}
  1761  			}
  1762  			if i >= len(args) {
  1763  				return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
  1764  			}
  1765  		}
  1766  
  1767  		if args != "" {
  1768  			r, _ := utf8.DecodeRuneInString(args)
  1769  			if !unicode.IsSpace(r) {
  1770  				return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
  1771  			}
  1772  		}
  1773  		list = append(list, path)
  1774  	}
  1775  	return list, nil
  1776  }
  1777  
  1778  func fakeRecv() *ir.Field {
  1779  	return ir.NewField(base.Pos, nil, nil, types.FakeRecvType())
  1780  }
  1781  
  1782  func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
  1783  	xtype := p.typeExpr(expr.Type)
  1784  
  1785  	fn := ir.NewFunc(p.pos(expr))
  1786  	fn.SetIsHiddenClosure(ir.CurFunc != nil)
  1787  
  1788  	fn.Nname = ir.NewNameAt(p.pos(expr), ir.BlankNode.Sym()) // filled in by tcClosure
  1789  	fn.Nname.Func = fn
  1790  	fn.Nname.Ntype = xtype
  1791  	fn.Nname.Defn = fn
  1792  
  1793  	clo := ir.NewClosureExpr(p.pos(expr), fn)
  1794  	fn.OClosure = clo
  1795  
  1796  	p.funcBody(fn, expr.Body)
  1797  
  1798  	ir.FinishCaptureNames(base.Pos, ir.CurFunc, fn)
  1799  
  1800  	return clo
  1801  }
  1802  
  1803  // A function named init is a special case.
  1804  // It is called by the initialization before main is run.
  1805  // To make it unique within a package and also uncallable,
  1806  // the name, normally "pkg.init", is altered to "pkg.init.0".
  1807  var renameinitgen int
  1808  
  1809  func renameinit() *types.Sym {
  1810  	s := typecheck.LookupNum("init.", renameinitgen)
  1811  	renameinitgen++
  1812  	return s
  1813  }
  1814  
  1815  // oldname returns the Node that declares symbol s in the current scope.
  1816  // If no such Node currently exists, an ONONAME Node is returned instead.
  1817  // Automatically creates a new closure variable if the referenced symbol was
  1818  // declared in a different (containing) function.
  1819  func oldname(s *types.Sym) ir.Node {
  1820  	if s.Pkg != types.LocalPkg {
  1821  		return ir.NewIdent(base.Pos, s)
  1822  	}
  1823  
  1824  	n := ir.AsNode(s.Def)
  1825  	if n == nil {
  1826  		// Maybe a top-level declaration will come along later to
  1827  		// define s. resolve will check s.Def again once all input
  1828  		// source has been processed.
  1829  		return ir.NewIdent(base.Pos, s)
  1830  	}
  1831  
  1832  	if n, ok := n.(*ir.Name); ok {
  1833  		// TODO(rsc): If there is an outer variable x and we
  1834  		// are parsing x := 5 inside the closure, until we get to
  1835  		// the := it looks like a reference to the outer x so we'll
  1836  		// make x a closure variable unnecessarily.
  1837  		return ir.CaptureName(base.Pos, ir.CurFunc, n)
  1838  	}
  1839  
  1840  	return n
  1841  }
  1842  
  1843  func varEmbed(makeXPos func(syntax.Pos) src.XPos, name *ir.Name, decl *syntax.VarDecl, pragma *pragmas, haveEmbed bool) {
  1844  	if pragma.Embeds == nil {
  1845  		return
  1846  	}
  1847  
  1848  	pragmaEmbeds := pragma.Embeds
  1849  	pragma.Embeds = nil
  1850  	pos := makeXPos(pragmaEmbeds[0].Pos)
  1851  
  1852  	if !haveEmbed {
  1853  		base.ErrorfAt(pos, "go:embed only allowed in Go files that import \"embed\"")
  1854  		return
  1855  	}
  1856  	if len(decl.NameList) > 1 {
  1857  		base.ErrorfAt(pos, "go:embed cannot apply to multiple vars")
  1858  		return
  1859  	}
  1860  	if decl.Values != nil {
  1861  		base.ErrorfAt(pos, "go:embed cannot apply to var with initializer")
  1862  		return
  1863  	}
  1864  	if decl.Type == nil {
  1865  		// Should not happen, since Values == nil now.
  1866  		base.ErrorfAt(pos, "go:embed cannot apply to var without type")
  1867  		return
  1868  	}
  1869  	if typecheck.DeclContext != ir.PEXTERN {
  1870  		base.ErrorfAt(pos, "go:embed cannot apply to var inside func")
  1871  		return
  1872  	}
  1873  
  1874  	var embeds []ir.Embed
  1875  	for _, e := range pragmaEmbeds {
  1876  		embeds = append(embeds, ir.Embed{Pos: makeXPos(e.Pos), Patterns: e.Patterns})
  1877  	}
  1878  	typecheck.Target.Embeds = append(typecheck.Target.Embeds, name)
  1879  	name.Embed = &embeds
  1880  }
  1881  

View as plain text