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

View as plain text