1
2
3
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
35 supportsGenerics := base.Flag.G != 0 || buildcfg.Experiment.Unified
36
37 mode := syntax.CheckBranches
38 if supportsGenerics {
39 mode |= syntax.AllowGenerics
40 }
41
42
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)
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
90 check2(noders)
91 return
92 }
93
94 for _, p := range noders {
95 p.node()
96 p.file = nil
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
109 types.LocalPkg.Height = myheight
110 typecheck.DeclareUniverse()
111 typecheck.TypecheckAllowed = true
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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
134
135 if fn, ok := n.(*ir.Func); ok && fn.OClosure != nil {
136 continue
137 }
138
139
140 if op == ir.ODCL {
141 base.FatalfAt(n.Pos(), "unexpected top declaration: %v", op)
142 }
143
144
145
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
155
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
172
173
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
182
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
193
194
195
196
197
198
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
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
227
228 type funcState struct {
229
230
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
278 fs.marker.Unpush()
279 } else {
280 fs.marker.Pop(p.makeXPos(pos))
281 }
282 }
283 }
284
285
286
287
288
289 func (p *noder) closeAnotherScope() {
290 p.closeScope(p.funcState.lastCloseScopePos)
291 }
292
293
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
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
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
473
474
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
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()
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
627
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
676 if typ, ok := typ.(*ir.SliceType); ok && typ.DDD {
677 if !dddOk {
678
679
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)
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
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
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))
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
838
839
840 func (p *noder) sum(x syntax.Expr) ir.Node {
841
842
843
844
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
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
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
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
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
1048
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
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
1315 nn.Defn = tswitch
1316 }
1317
1318
1319
1320
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 {
1374 ls = p.stmtFall(label.Stmt, fallOK)
1375
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
1457
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
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
1487
1488
1489
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
1498
1499
1500
1501
1502
1503
1504
1505
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
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
1536 return mkname(p.name(name))
1537 }
1538
1539 func wrapname(pos src.XPos, x ir.Node) ir.Node {
1540
1541
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
1567 func (p *noder) error(err error) {
1568 p.err <- err.(syntax.Error)
1569 }
1570
1571
1572
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
1585 type pragmas struct {
1586 Flag ir.PragmaFlag
1587 Pos []pragmaPos
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
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
1636 p.checkUnusedDuringParse(pragma)
1637 return nil
1638 }
1639
1640 if strings.HasPrefix(text, "line ") {
1641
1642 panic("unreachable")
1643 }
1644
1645 if !blankLine {
1646
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
1659
1660
1661
1662
1663 var target string
1664 if len(f) == 3 {
1665 target = f[2]
1666 } else if base.Ctxt.Pkgpath != "" {
1667
1668
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
1689
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
1703
1704
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
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
1731
1732
1733
1734
1735
1736 func isCgoGeneratedFile(pos syntax.Pos) bool {
1737 return strings.HasPrefix(filepath.Base(trimFilename(pos.Base())), "_cgo_")
1738 }
1739
1740
1741
1742
1743
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
1761
1762
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
1837
1838
1839
1840 var renameinitgen int
1841
1842 func renameinit() *types.Sym {
1843 s := typecheck.LookupNum("init.", renameinitgen)
1844 renameinitgen++
1845 return s
1846 }
1847
1848
1849
1850
1851
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
1860
1861
1862 return ir.NewIdent(base.Pos, s)
1863 }
1864
1865 if n, ok := n.(*ir.Name); ok {
1866
1867
1868
1869
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
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