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.
14 "cmd/compile/internal/syntax"
19 func parseFiles(filenames []string) uint {
23 for _, filename := range filenames {
24 p := &noder{err: make(chan syntax.Error)}
25 noders = append(noders, p)
27 go func(filename string) {
29 base := src.NewFileBase(filename, absFilename(filename))
31 f, err := os.Open(filename)
33 p.error(syntax.Error{Pos: src.MakePos(base, 0, 0), Msg: err.Error()})
38 p.file, _ = syntax.Parse(base, f, p.error, p.pragma, 0) // errors are tracked via p.error
42 for _, p := range noders {
43 for e := range p.err {
44 yyerrorpos(e.Pos, "%s", e.Msg)
49 p.file = nil // release memory
51 if nsyntaxerrors != 0 {
54 // Always run testdclstack here, even when debug_dclstack is not set, as a sanity measure.
61 func yyerrorpos(pos src.Pos, format string, args ...interface{}) {
62 yyerrorl(Ctxt.PosTable.XPos(pos), format, args...)
67 func absFilename(name string) string {
68 return obj.AbsFile(Ctxt.Pathname, name, pathPrefix)
71 // noder transforms package syntax's AST into a Node tree.
79 // linkname records a //go:linkname directive.
80 type linkname struct {
86 func (p *noder) node() {
89 imported_unsafe = false
91 p.lineno(p.file.PkgName)
92 mkpackage(p.file.PkgName.Value)
94 xtop = append(xtop, p.decls(p.file.DeclList)...)
96 for _, n := range p.linknames {
98 lookup(n.local).Linkname = n.remote
100 yyerrorpos(n.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
104 pragcgobuf += p.pragcgobuf
106 // For compatibility with old code only (comparisons w/ toolstash):
107 // The old line number tracking simply continued incrementing the
108 // virtual line number (lexlineno) and using it also for lineno.
109 // After processing the last function, the lineno was used for the
110 // line number information of the initialization code (fninit).
111 // It would be better to use an explicit "<autogenerated>" filename
112 // for fninit and set lineno to NoPos here.
113 // TODO(gri) fix this once we switched permanently to the new
114 // position information.
115 lineno = MakePos(p.file.Pos().Base(), uint(p.file.Lines), 0)
120 func (p *noder) decls(decls []syntax.Decl) (l []*Node) {
121 var lastConstGroup *syntax.Group
122 var lastConstRHS []*Node
125 for _, decl := range decls {
127 switch decl := decl.(type) {
128 case *syntax.ImportDecl:
131 case *syntax.VarDecl:
132 l = append(l, p.varDecl(decl)...)
134 case *syntax.ConstDecl:
135 // Tricky to handle golang.org/issue/15550 correctly.
139 if decl.Group == nil || decl.Group != lastConstGroup {
145 lastconst = lastConstRHS
147 l = append(l, p.constDecl(decl)...)
149 lastConstRHS = lastconst
155 lastConstGroup = decl.Group
157 case *syntax.TypeDecl:
158 l = append(l, p.typeDecl(decl))
160 case *syntax.FuncDecl:
161 l = append(l, p.funcDecl(decl))
164 panic("unhandled Decl")
171 func (p *noder) importDecl(imp *syntax.ImportDecl) {
172 val := p.basicLit(imp.Path)
173 importfile(&val, nil)
179 Fatalf("phase error in import")
187 if imp.LocalPkgName != nil {
188 my = p.name(imp.LocalPkgName)
190 my = lookup(ipkg.Name)
193 pack := p.nod(imp, OPACK, nil, nil)
198 importdot(ipkg, pack)
201 if my.Name == "init" {
202 yyerrorl(pack.Pos, "cannot import package as init - init must be a func")
210 redeclare(my, "as imported package name")
213 my.Lastlineno = pack.Pos
214 my.Block = 1 // at top level
217 func (p *noder) varDecl(decl *syntax.VarDecl) []*Node {
218 names := p.declNames(decl.NameList)
219 typ := p.typeExprOrNil(decl.Type)
222 if decl.Values != nil {
223 exprs = p.exprList(decl.Values)
227 return variter(names, typ, exprs)
230 func (p *noder) constDecl(decl *syntax.ConstDecl) []*Node {
231 names := p.declNames(decl.NameList)
232 typ := p.typeExprOrNil(decl.Type)
235 if decl.Values != nil {
236 exprs = p.exprList(decl.Values)
239 return constiter(names, typ, exprs)
242 func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node {
243 name := typedcl0(p.name(decl.Name))
245 // decl.Type may be nil but in that case we got a syntax error during parsing
246 typ := p.typeExprOrNil(decl.Type)
248 return typedcl1(name, typ, syntax.Pragma(decl.Pragma), decl.Alias)
251 func (p *noder) declNames(names []*syntax.Name) []*Node {
253 for _, name := range names {
254 nodes = append(nodes, p.declName(name))
259 func (p *noder) declName(name *syntax.Name) *Node {
260 // TODO(mdempsky): Set lineno?
261 return dclname(p.name(name))
264 func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
265 f := p.funcHeader(fun)
272 body = p.stmts(fun.Body)
274 body = []*Node{p.nod(fun, OEMPTY, nil, nil)}
281 f.Noescape = pragma&Noescape != 0
282 if f.Noescape && len(body) != 0 {
283 yyerror("can only use //go:noescape with external func implementations")
285 f.Func.Pragma = pragma
286 lineno = MakePos(fun.Pos().Base(), fun.EndLine, 0)
287 f.Func.Endlineno = lineno
294 func (p *noder) funcHeader(fun *syntax.FuncDecl) *Node {
295 name := p.name(fun.Name)
296 t := p.signature(fun.Recv, fun.Type)
297 f := p.nod(fun, ODCLFUNC, nil, nil)
300 // FunctionName Signature
301 if name.Name == "init" {
303 if t.List.Len() > 0 || t.Rlist.Len() > 0 {
304 yyerror("func init must have no arguments and no return values")
308 if localpkg.Name == "main" && name.Name == "main" {
309 if t.List.Len() > 0 || t.Rlist.Len() > 0 {
310 yyerror("func main must have no arguments and no return values")
314 f.Func.Shortname = name
315 name = nblank.Sym // filled in by typecheckfunc
318 f.Func.Nname = newfuncname(name)
319 f.Func.Nname.Name.Defn = f
320 f.Func.Nname.Name.Param.Ntype = t // TODO: check if nname already has an ntype
323 declare(f.Func.Nname, PFUNC)
330 func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *Node {
331 n := p.nod(typ, OTFUNC, nil, nil)
333 n.Left = p.param(recv, false, false)
335 n.List.Set(p.params(typ.ParamList, true))
336 n.Rlist.Set(p.params(typ.ResultList, false))
340 func (p *noder) params(params []*syntax.Field, dddOk bool) []*Node {
342 for i, param := range params {
344 nodes = append(nodes, p.param(param, dddOk, i+1 == len(params)))
349 func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node {
351 if param.Name != nil {
352 name = p.newname(param.Name)
355 typ := p.typeExpr(param.Type)
356 n := p.nod(param, ODCLFIELD, name, typ)
358 // rewrite ...T parameter
361 yyerror("cannot use ... in receiver or result parameter list")
363 yyerror("can only use ... with final parameter in list")
377 func (p *noder) exprList(expr syntax.Expr) []*Node {
378 if list, ok := expr.(*syntax.ListExpr); ok {
379 return p.exprs(list.ElemList)
381 return []*Node{p.expr(expr)}
384 func (p *noder) exprs(exprs []syntax.Expr) []*Node {
386 for _, expr := range exprs {
387 nodes = append(nodes, p.expr(expr))
392 func (p *noder) expr(expr syntax.Expr) *Node {
394 switch expr := expr.(type) {
398 return p.mkname(expr)
399 case *syntax.BasicLit:
400 return p.setlineno(expr, nodlit(p.basicLit(expr)))
402 case *syntax.CompositeLit:
403 n := p.nod(expr, OCOMPLIT, nil, nil)
404 if expr.Type != nil {
405 n.Right = p.expr(expr.Type)
407 l := p.exprs(expr.ElemList)
408 for i, e := range l {
409 l[i] = p.wrapname(expr.ElemList[i], e)
412 lineno = MakePos(expr.Pos().Base(), expr.EndLine, 0)
414 case *syntax.KeyValueExpr:
415 return p.nod(expr, OKEY, p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value)))
416 case *syntax.FuncLit:
417 closurehdr(p.typeExpr(expr.Type))
418 body := p.stmts(expr.Body)
419 lineno = MakePos(expr.Pos().Base(), expr.EndLine, 0)
420 return p.setlineno(expr, closurebody(body))
421 case *syntax.ParenExpr:
422 return p.nod(expr, OPAREN, p.expr(expr.X), nil)
423 case *syntax.SelectorExpr:
424 // parser.new_dotname
425 obj := p.expr(expr.X)
428 return oldname(restrictlookup(expr.Sel.Value, obj.Name.Pkg))
430 return p.setlineno(expr, nodSym(OXDOT, obj, p.name(expr.Sel)))
431 case *syntax.IndexExpr:
432 return p.nod(expr, OINDEX, p.expr(expr.X), p.expr(expr.Index))
433 case *syntax.SliceExpr:
438 n := p.nod(expr, op, p.expr(expr.X), nil)
440 for i, x := range expr.Index {
445 n.SetSliceBounds(index[0], index[1], index[2])
447 case *syntax.AssertExpr:
448 if expr.Type == nil {
449 panic("unexpected AssertExpr")
451 // TODO(mdempsky): parser.pexpr uses p.expr(), but
452 // seems like the type field should be parsed with
453 // ntype? Shrug, doesn't matter here.
454 return p.nod(expr, ODOTTYPE, p.expr(expr.X), p.expr(expr.Type))
455 case *syntax.Operation:
458 if expr.Op == syntax.And {
459 x = unparen(x) // TODO(mdempsky): Needed?
460 if x.Op == OCOMPLIT {
461 // Special case for &T{...}: turn into (*T){...}.
462 // TODO(mdempsky): Switch back to p.nod after we
463 // get rid of gcCompat.
464 x.Right = nod(OIND, x.Right, nil)
465 x.Right.Implicit = true
469 return p.nod(expr, p.unOp(expr.Op), x, nil)
471 return p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y))
472 case *syntax.CallExpr:
473 n := p.nod(expr, OCALL, p.expr(expr.Fun), nil)
474 n.List.Set(p.exprs(expr.ArgList))
475 n.Isddd = expr.HasDots
478 case *syntax.ArrayType:
481 len = p.expr(expr.Len)
483 len = p.nod(expr, ODDD, nil, nil)
485 return p.nod(expr, OTARRAY, len, p.typeExpr(expr.Elem))
486 case *syntax.SliceType:
487 return p.nod(expr, OTARRAY, nil, p.typeExpr(expr.Elem))
488 case *syntax.DotsType:
489 return p.nod(expr, ODDD, p.typeExpr(expr.Elem), nil)
490 case *syntax.StructType:
491 return p.structType(expr)
492 case *syntax.InterfaceType:
493 return p.interfaceType(expr)
494 case *syntax.FuncType:
495 return p.signature(nil, expr)
496 case *syntax.MapType:
497 return p.nod(expr, OTMAP, p.typeExpr(expr.Key), p.typeExpr(expr.Value))
498 case *syntax.ChanType:
499 n := p.nod(expr, OTCHAN, p.typeExpr(expr.Elem), nil)
500 n.Etype = EType(p.chanDir(expr.Dir))
503 case *syntax.TypeSwitchGuard:
504 n := p.nod(expr, OTYPESW, nil, p.expr(expr.X))
506 n.Left = p.declName(expr.Lhs)
508 yyerror("invalid variable name %v in type switch", n.Left)
513 panic("unhandled Expr")
516 func (p *noder) typeExpr(typ syntax.Expr) *Node {
517 // TODO(mdempsky): Be stricter? typecheck should handle errors anyway.
521 func (p *noder) typeExprOrNil(typ syntax.Expr) *Node {
528 func (p *noder) chanDir(dir syntax.ChanDir) ChanDir {
532 case syntax.SendOnly:
534 case syntax.RecvOnly:
537 panic("unhandled ChanDir")
540 func (p *noder) structType(expr *syntax.StructType) *Node {
542 for i, field := range expr.FieldList {
545 if field.Name == nil {
546 n = p.embedded(field.Type)
548 n = p.nod(field, ODCLFIELD, p.newname(field.Name), p.typeExpr(field.Type))
550 if i < len(expr.TagList) && expr.TagList[i] != nil {
551 n.SetVal(p.basicLit(expr.TagList[i]))
557 n := p.nod(expr, OTSTRUCT, nil, nil)
562 func (p *noder) interfaceType(expr *syntax.InterfaceType) *Node {
564 for _, method := range expr.MethodList {
567 if method.Name == nil {
568 n = p.nod(method, ODCLFIELD, nil, oldname(p.packname(method.Type)))
570 mname := p.newname(method.Name)
571 sig := p.typeExpr(method.Type)
572 sig.Left = fakethis()
573 n = p.nod(method, ODCLFIELD, mname, sig)
579 n := p.nod(expr, OTINTER, nil, nil)
584 func (p *noder) packname(expr syntax.Expr) *Sym {
585 switch expr := expr.(type) {
588 if n := oldname(name); n.Name != nil && n.Name.Pack != nil {
589 n.Name.Pack.Used = true
592 case *syntax.SelectorExpr:
593 name := p.name(expr.X.(*syntax.Name))
595 if name.Def == nil || name.Def.Op != OPACK {
596 yyerror("%v is not a package", name)
600 pkg = name.Def.Name.Pkg
602 return restrictlookup(expr.Sel.Value, pkg)
604 panic(fmt.Sprintf("unexpected packname: %#v", expr))
607 func (p *noder) embedded(typ syntax.Expr) *Node {
608 op, isStar := typ.(*syntax.Operation)
610 if op.Op != syntax.Mul || op.Y != nil {
611 panic("unexpected Operation")
615 n := embedded(p.packname(typ), localpkg)
617 n.Right = p.nod(op, OIND, n.Right, nil)
622 func (p *noder) stmts(stmts []syntax.Stmt) []*Node {
624 for _, stmt := range stmts {
627 } else if s.Op == OBLOCK && s.Ninit.Len() == 0 {
628 nodes = append(nodes, s.List.Slice()...)
630 nodes = append(nodes, s)
636 func (p *noder) stmt(stmt syntax.Stmt) *Node {
638 switch stmt := stmt.(type) {
639 case *syntax.EmptyStmt:
641 case *syntax.LabeledStmt:
642 return p.labeledStmt(stmt)
643 case *syntax.BlockStmt:
644 return p.body(stmt.Body)
645 case *syntax.ExprStmt:
646 return p.wrapname(stmt, p.expr(stmt.X))
647 case *syntax.SendStmt:
648 return p.nod(stmt, OSEND, p.expr(stmt.Chan), p.expr(stmt.Value))
649 case *syntax.DeclStmt:
650 return liststmt(p.decls(stmt.DeclList))
651 case *syntax.AssignStmt:
652 if stmt.Op != 0 && stmt.Op != syntax.Def {
653 n := p.nod(stmt, OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs))
654 n.Implicit = stmt.Rhs == syntax.ImplicitOne
655 n.Etype = EType(p.binOp(stmt.Op))
659 lhs := p.exprList(stmt.Lhs)
660 rhs := p.exprList(stmt.Rhs)
662 n := p.nod(stmt, OAS, nil, nil) // assume common case
664 if stmt.Op == syntax.Def {
666 colasdefn(lhs, n) // modifies lhs, call before using lhs[0] in common case
669 if len(lhs) == 1 && len(rhs) == 1 {
680 case *syntax.BranchStmt:
685 case syntax.Continue:
687 case syntax.Fallthrough:
692 panic("unhandled BranchStmt")
694 n := p.nod(stmt, op, nil, nil)
695 if stmt.Label != nil {
696 n.Left = p.newname(stmt.Label)
699 n.Sym = dclstack // context, for goto restriction
702 n.Xoffset = int64(block)
705 case *syntax.CallStmt:
713 panic("unhandled CallStmt")
715 return p.nod(stmt, op, p.expr(stmt.Call), nil)
716 case *syntax.ReturnStmt:
718 if stmt.Results != nil {
719 results = p.exprList(stmt.Results)
721 n := p.nod(stmt, ORETURN, nil, nil)
723 if n.List.Len() == 0 && Curfn != nil {
724 for _, ln := range Curfn.Func.Dcl {
725 if ln.Class == PPARAM {
728 if ln.Class != PPARAMOUT {
731 if ln.Sym.Def != ln {
732 yyerror("%s is shadowed during return", ln.Sym.Name)
738 return p.ifStmt(stmt)
739 case *syntax.ForStmt:
740 return p.forStmt(stmt)
741 case *syntax.SwitchStmt:
742 return p.switchStmt(stmt)
743 case *syntax.SelectStmt:
744 return p.selectStmt(stmt)
746 panic("unhandled Stmt")
749 func (p *noder) body(body []syntax.Stmt) *Node {
750 l := p.bodyList(body)
752 // TODO(mdempsky): Line number?
753 return nod(OEMPTY, nil, nil)
758 func (p *noder) bodyList(body []syntax.Stmt) []*Node {
760 nodes := p.stmts(body)
765 func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node {
767 n := p.nod(stmt, OIF, nil, nil)
768 if stmt.Init != nil {
769 n.Ninit.Set1(p.stmt(stmt.Init))
771 if stmt.Cond != nil {
772 n.Left = p.expr(stmt.Cond)
774 n.Nbody.Set(p.bodyList(stmt.Then))
775 if stmt.Else != nil {
776 e := p.stmt(stmt.Else)
777 if e.Op == OBLOCK && e.Ninit.Len() == 0 {
778 n.Rlist.Set(e.List.Slice())
787 func (p *noder) forStmt(stmt *syntax.ForStmt) *Node {
790 if r, ok := stmt.Init.(*syntax.RangeClause); ok {
791 if stmt.Cond != nil || stmt.Post != nil {
792 panic("unexpected RangeClause")
795 n = p.nod(r, ORANGE, nil, p.expr(r.X))
797 lhs := p.exprList(r.Lhs)
805 n = p.nod(stmt, OFOR, nil, nil)
806 if stmt.Init != nil {
807 n.Ninit.Set1(p.stmt(stmt.Init))
809 if stmt.Cond != nil {
810 n.Left = p.expr(stmt.Cond)
812 if stmt.Post != nil {
813 n.Right = p.stmt(stmt.Post)
816 n.Nbody.Set(p.bodyList(stmt.Body))
821 func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node {
823 n := p.nod(stmt, OSWITCH, nil, nil)
824 if stmt.Init != nil {
825 n.Ninit.Set1(p.stmt(stmt.Init))
828 n.Left = p.expr(stmt.Tag)
832 if tswitch != nil && (tswitch.Op != OTYPESW || tswitch.Left == nil) {
836 n.List.Set(p.caseClauses(stmt.Body, tswitch))
842 func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node) []*Node {
844 for _, clause := range clauses {
847 n := p.nod(clause, OXCASE, nil, nil)
848 if clause.Cases != nil {
849 n.List.Set(p.exprList(clause.Cases))
852 nn := newname(tswitch.Left.Sym)
853 declare(nn, dclcontext)
855 // keep track of the instances for reporting unused
856 nn.Name.Defn = tswitch
858 n.Xoffset = int64(block)
859 n.Nbody.Set(p.stmts(clause.Body))
861 nodes = append(nodes, n)
866 func (p *noder) selectStmt(stmt *syntax.SelectStmt) *Node {
867 n := p.nod(stmt, OSELECT, nil, nil)
868 n.List.Set(p.commClauses(stmt.Body))
872 func (p *noder) commClauses(clauses []*syntax.CommClause) []*Node {
874 for _, clause := range clauses {
877 n := p.nod(clause, OXCASE, nil, nil)
878 if clause.Comm != nil {
879 n.List.Set1(p.stmt(clause.Comm))
881 n.Xoffset = int64(block)
882 n.Nbody.Set(p.stmts(clause.Body))
884 nodes = append(nodes, n)
889 func (p *noder) labeledStmt(label *syntax.LabeledStmt) *Node {
890 lhs := p.nod(label, OLABEL, p.newname(label.Label), nil)
894 if label.Stmt != nil { // TODO(mdempsky): Should always be present.
895 ls = p.stmt(label.Stmt)
901 if ls.Op == OBLOCK && ls.Ninit.Len() == 0 {
902 l = append(l, ls.List.Slice()...)
921 func (p *noder) unOp(op syntax.Operator) Op {
922 if uint64(op) >= uint64(len(unOps)) || unOps[op] == 0 {
923 panic("invalid Operator")
928 var binOps = [...]Op{
930 syntax.AndAnd: OANDAND,
948 syntax.AndNot: OANDNOT,
953 func (p *noder) binOp(op syntax.Operator) Op {
954 if uint64(op) >= uint64(len(binOps)) || binOps[op] == 0 {
955 panic("invalid Operator")
960 func (p *noder) basicLit(lit *syntax.BasicLit) Val {
961 // TODO: Don't try to convert if we had syntax errors (conversions may fail).
962 // Use dummy values so we can continue to compile. Eventually, use a
963 // form of "unknown" literals that are ignored during type-checking so
964 // we can continue type-checking w/o spurious follow-up errors.
965 switch s := lit.Value; lit.Kind {
971 case syntax.FloatLit:
978 x.Imag.SetString(strings.TrimSuffix(s, "i"))
983 if u, err := strconv.Unquote(s); err == nil && len(u) > 0 {
984 // Package syntax already reported any errors.
985 // Check for them again though because 0 is a
986 // better fallback value for invalid rune
987 // literals than 0xFFFD.
991 r, _ = utf8.DecodeRuneInString(u)
999 case syntax.StringLit:
1000 if len(s) > 0 && s[0] == '`' {
1001 // strip carriage returns from raw string
1002 s = strings.Replace(s, "\r", "", -1)
1004 // Ignore errors because package syntax already reported them.
1005 u, _ := strconv.Unquote(s)
1009 panic("unhandled BasicLit kind")
1013 func (p *noder) name(name *syntax.Name) *Sym {
1014 return lookup(name.Value)
1017 func (p *noder) mkname(name *syntax.Name) *Node {
1018 // TODO(mdempsky): Set line number?
1019 return mkname(p.name(name))
1022 func (p *noder) newname(name *syntax.Name) *Node {
1023 // TODO(mdempsky): Set line number?
1024 return newname(p.name(name))
1027 func (p *noder) wrapname(n syntax.Node, x *Node) *Node {
1028 // These nodes do not carry line numbers.
1029 // Introduce a wrapper node to give them the correct line.
1031 case OTYPE, OLITERAL:
1036 case ONAME, ONONAME, OPACK:
1037 x = p.nod(n, OPAREN, x, nil)
1043 func (p *noder) nod(orig syntax.Node, op Op, left, right *Node) *Node {
1044 return p.setlineno(orig, nod(op, left, right))
1047 func (p *noder) setlineno(src_ syntax.Node, dst *Node) *Node {
1050 // TODO(mdempsky): Shouldn't happen. Fix package syntax.
1053 dst.Pos = Ctxt.PosTable.XPos(pos)
1057 func (p *noder) lineno(n syntax.Node) {
1063 // TODO(mdempsky): Shouldn't happen. Fix package syntax.
1066 lineno = Ctxt.PosTable.XPos(pos)
1069 func (p *noder) error(err error) {
1070 p.err <- err.(syntax.Error)
1073 func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
1075 case strings.HasPrefix(text, "line "):
1076 // line directives are handled by syntax package
1077 panic("unreachable")
1079 case strings.HasPrefix(text, "go:linkname "):
1080 f := strings.Fields(text)
1082 p.error(syntax.Error{Pos: pos, Msg: "usage: //go:linkname localname linkname"})
1085 p.linknames = append(p.linknames, linkname{pos, f[1], f[2]})
1087 case strings.HasPrefix(text, "go:cgo_"):
1088 // TODO(gri): lineno = p.baseline + int32(line) - 1 // pragcgo may call yyerror
1089 p.pragcgobuf += pragcgo(text)
1090 fallthrough // because of //go:cgo_unsafe_args
1093 if i := strings.Index(text, " "); i >= 0 {
1096 prag := pragmaValue(verb)
1097 const runtimePragmas = Systemstack | Nowritebarrier | Nowritebarrierrec | Yeswritebarrierrec
1098 if !compiling_runtime && prag&runtimePragmas != 0 {
1099 p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//go:%s only allowed in runtime", verb)})
1107 func mkname(sym *Sym) *Node {
1109 if n.Name != nil && n.Name.Pack != nil {
1110 n.Name.Pack.Used = true
1115 func unparen(x *Node) *Node {
1116 for x.Op == OPAREN {