aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/dcl.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/dcl.go')
-rw-r--r--src/cmd/compile/internal/gc/dcl.go662
1 files changed, 303 insertions, 359 deletions
diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go
index 6e90eb4d65..2a7be137c0 100644
--- a/src/cmd/compile/internal/gc/dcl.go
+++ b/src/cmd/compile/internal/gc/dcl.go
@@ -6,23 +6,23 @@ package gc
import (
"bytes"
+ "cmd/compile/internal/base"
+ "cmd/compile/internal/ir"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/src"
"fmt"
+ "go/constant"
"strings"
)
// Declaration stack & operations
-var externdcl []*Node
+var externdcl []ir.Node
func testdclstack() {
if !types.IsDclstackValid() {
- if nerrors != 0 {
- errorexit()
- }
- Fatalf("mark left on the dclstack")
+ base.Fatalf("mark left on the dclstack")
}
}
@@ -33,7 +33,7 @@ func redeclare(pos src.XPos, s *types.Sym, where string) {
if pkg == nil {
pkg = s.Pkg
}
- yyerrorl(pos, "%v redeclared %s\n"+
+ base.ErrorfAt(pos, "%v redeclared %s\n"+
"\tprevious declaration during import %q", s, where, pkg.Path)
} else {
prevPos := s.Lastlineno
@@ -46,8 +46,8 @@ func redeclare(pos src.XPos, s *types.Sym, where string) {
pos, prevPos = prevPos, pos
}
- yyerrorl(pos, "%v redeclared %s\n"+
- "\tprevious declaration at %v", s, where, linestr(prevPos))
+ base.ErrorfAt(pos, "%v redeclared %s\n"+
+ "\tprevious declaration at %v", s, where, base.FmtPos(prevPos))
}
}
@@ -59,103 +59,103 @@ var declare_typegen int
// declare records that Node n declares symbol n.Sym in the specified
// declaration context.
-func declare(n *Node, ctxt Class) {
- if n.isBlank() {
+func declare(n ir.Node, ctxt ir.Class) {
+ if ir.IsBlank(n) {
return
}
- if n.Name == nil {
+ if n.Name() == nil {
// named OLITERAL needs Name; most OLITERALs don't.
- n.Name = new(Name)
+ n.SetName(new(ir.Name))
}
- s := n.Sym
+ s := n.Sym()
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
- if !inimport && !typecheckok && s.Pkg != localpkg {
- yyerrorl(n.Pos, "cannot declare name %v", s)
+ if !inimport && !typecheckok && s.Pkg != ir.LocalPkg {
+ base.ErrorfAt(n.Pos(), "cannot declare name %v", s)
}
gen := 0
- if ctxt == PEXTERN {
+ if ctxt == ir.PEXTERN {
if s.Name == "init" {
- yyerrorl(n.Pos, "cannot declare init - must be func")
+ base.ErrorfAt(n.Pos(), "cannot declare init - must be func")
}
if s.Name == "main" && s.Pkg.Name == "main" {
- yyerrorl(n.Pos, "cannot declare main - must be func")
+ base.ErrorfAt(n.Pos(), "cannot declare main - must be func")
}
externdcl = append(externdcl, n)
} else {
- if Curfn == nil && ctxt == PAUTO {
- lineno = n.Pos
- Fatalf("automatic outside function")
+ if Curfn == nil && ctxt == ir.PAUTO {
+ base.Pos = n.Pos()
+ base.Fatalf("automatic outside function")
}
- if Curfn != nil && ctxt != PFUNC {
- Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
+ if Curfn != nil && ctxt != ir.PFUNC {
+ Curfn.Func().Dcl = append(Curfn.Func().Dcl, n)
}
- if n.Op == OTYPE {
+ if n.Op() == ir.OTYPE {
declare_typegen++
gen = declare_typegen
- } else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") {
+ } else if n.Op() == ir.ONAME && ctxt == ir.PAUTO && !strings.Contains(s.Name, "·") {
vargen++
gen = vargen
}
types.Pushdcl(s)
- n.Name.Curfn = Curfn
+ n.Name().Curfn = Curfn
}
- if ctxt == PAUTO {
- n.Xoffset = 0
+ if ctxt == ir.PAUTO {
+ n.SetOffset(0)
}
if s.Block == types.Block {
// functype will print errors about duplicate function arguments.
// Don't repeat the error here.
- if ctxt != PPARAM && ctxt != PPARAMOUT {
- redeclare(n.Pos, s, "in this block")
+ if ctxt != ir.PPARAM && ctxt != ir.PPARAMOUT {
+ redeclare(n.Pos(), s, "in this block")
}
}
s.Block = types.Block
- s.Lastlineno = lineno
- s.Def = asTypesNode(n)
- n.Name.Vargen = int32(gen)
+ s.Lastlineno = base.Pos
+ s.Def = n
+ n.Name().Vargen = int32(gen)
n.SetClass(ctxt)
- if ctxt == PFUNC {
- n.Sym.SetFunc(true)
+ if ctxt == ir.PFUNC {
+ n.Sym().SetFunc(true)
}
autoexport(n, ctxt)
}
-func addvar(n *Node, t *types.Type, ctxt Class) {
- if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
- Fatalf("addvar: n=%v t=%v nil", n, t)
+func addvar(n ir.Node, t *types.Type, ctxt ir.Class) {
+ if n == nil || n.Sym() == nil || (n.Op() != ir.ONAME && n.Op() != ir.ONONAME) || t == nil {
+ base.Fatalf("addvar: n=%v t=%v nil", n, t)
}
- n.Op = ONAME
+ n.SetOp(ir.ONAME)
declare(n, ctxt)
- n.Type = t
+ n.SetType(t)
}
// declare variables from grammar
// new_name_list (type | [type] = expr_list)
-func variter(vl []*Node, t *Node, el []*Node) []*Node {
- var init []*Node
+func variter(vl []ir.Node, t ir.Node, el []ir.Node) []ir.Node {
+ var init []ir.Node
doexpr := len(el) > 0
if len(el) == 1 && len(vl) > 1 {
e := el[0]
- as2 := nod(OAS2, nil, nil)
- as2.List.Set(vl)
- as2.Rlist.Set1(e)
+ as2 := ir.Nod(ir.OAS2, nil, nil)
+ as2.PtrList().Set(vl)
+ as2.PtrRlist().Set1(e)
for _, v := range vl {
- v.Op = ONAME
+ v.SetOp(ir.ONAME)
declare(v, dclcontext)
- v.Name.Param.Ntype = t
- v.Name.Defn = as2
+ v.Name().Param.Ntype = t
+ v.Name().Defn = as2
if Curfn != nil {
- init = append(init, nod(ODCL, v, nil))
+ init = append(init, ir.Nod(ir.ODCL, v, nil))
}
}
@@ -164,94 +164,96 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
nel := len(el)
for _, v := range vl {
- var e *Node
+ var e ir.Node
if doexpr {
if len(el) == 0 {
- yyerror("assignment mismatch: %d variables but %d values", len(vl), nel)
+ base.Errorf("assignment mismatch: %d variables but %d values", len(vl), nel)
break
}
e = el[0]
el = el[1:]
}
- v.Op = ONAME
+ v.SetOp(ir.ONAME)
declare(v, dclcontext)
- v.Name.Param.Ntype = t
+ v.Name().Param.Ntype = t
- if e != nil || Curfn != nil || v.isBlank() {
+ if e != nil || Curfn != nil || ir.IsBlank(v) {
if Curfn != nil {
- init = append(init, nod(ODCL, v, nil))
+ init = append(init, ir.Nod(ir.ODCL, v, nil))
}
- e = nod(OAS, v, e)
+ e = ir.Nod(ir.OAS, v, e)
init = append(init, e)
- if e.Right != nil {
- v.Name.Defn = e
+ if e.Right() != nil {
+ v.Name().Defn = e
}
}
}
if len(el) != 0 {
- yyerror("assignment mismatch: %d variables but %d values", len(vl), nel)
+ base.Errorf("assignment mismatch: %d variables but %d values", len(vl), nel)
}
return init
}
// newnoname returns a new ONONAME Node associated with symbol s.
-func newnoname(s *types.Sym) *Node {
+func newnoname(s *types.Sym) ir.Node {
if s == nil {
- Fatalf("newnoname nil")
+ base.Fatalf("newnoname nil")
}
- n := nod(ONONAME, nil, nil)
- n.Sym = s
- n.Xoffset = 0
+ n := ir.Nod(ir.ONONAME, nil, nil)
+ n.SetSym(s)
+ n.SetOffset(0)
return n
}
// newfuncnamel generates a new name node for a function or method.
-// TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360.
-func newfuncnamel(pos src.XPos, s *types.Sym) *Node {
- n := newnamel(pos, s)
- n.Func = new(Func)
- n.Func.SetIsHiddenClosure(Curfn != nil)
+func newfuncnamel(pos src.XPos, s *types.Sym, fn *ir.Func) ir.Node {
+ if fn.Nname != nil {
+ base.Fatalf("newfuncnamel - already have name")
+ }
+ n := ir.NewNameAt(pos, s)
+ n.SetFunc(fn)
+ fn.Nname = n
return n
}
// this generates a new name node for a name
// being declared.
-func dclname(s *types.Sym) *Node {
- n := newname(s)
- n.Op = ONONAME // caller will correct it
+func dclname(s *types.Sym) ir.Node {
+ n := NewName(s)
+ n.SetOp(ir.ONONAME) // caller will correct it
return n
}
-func typenod(t *types.Type) *Node {
+func typenod(t *types.Type) ir.Node {
return typenodl(src.NoXPos, t)
}
-func typenodl(pos src.XPos, t *types.Type) *Node {
+func typenodl(pos src.XPos, t *types.Type) ir.Node {
// if we copied another type with *t = *u
// then t->nod might be out of date, so
// check t->nod->type too
- if asNode(t.Nod) == nil || asNode(t.Nod).Type != t {
- t.Nod = asTypesNode(nodl(pos, OTYPE, nil, nil))
- asNode(t.Nod).Type = t
- asNode(t.Nod).Sym = t.Sym
+ if ir.AsNode(t.Nod) == nil || ir.AsNode(t.Nod).Type() != t {
+ t.Nod = ir.NodAt(pos, ir.OTYPE, nil, nil)
+ ir.AsNode(t.Nod).SetType(t)
+ ir.AsNode(t.Nod).SetSym(t.Sym)
}
- return asNode(t.Nod)
+ return ir.AsNode(t.Nod)
}
-func anonfield(typ *types.Type) *Node {
+func anonfield(typ *types.Type) ir.Node {
return symfield(nil, typ)
}
-func namedfield(s string, typ *types.Type) *Node {
+func namedfield(s string, typ *types.Type) ir.Node {
return symfield(lookup(s), typ)
}
-func symfield(s *types.Sym, typ *types.Type) *Node {
- n := nodSym(ODCLFIELD, nil, s)
- n.Type = typ
+func symfield(s *types.Sym, typ *types.Type) ir.Node {
+ n := nodSym(ir.ODCLFIELD, nil, s)
+ n.SetType(typ)
return n
}
@@ -259,8 +261,8 @@ func symfield(s *types.Sym, typ *types.Type) *Node {
// If no such Node currently exists, an ONONAME Node is returned instead.
// Automatically creates a new closure variable if the referenced symbol was
// declared in a different (containing) function.
-func oldname(s *types.Sym) *Node {
- n := asNode(s.Def)
+func oldname(s *types.Sym) ir.Node {
+ n := ir.AsNode(s.Def)
if n == nil {
// Maybe a top-level declaration will come along later to
// define s. resolve will check s.Def again once all input
@@ -268,28 +270,28 @@ func oldname(s *types.Sym) *Node {
return newnoname(s)
}
- if Curfn != nil && n.Op == ONAME && n.Name.Curfn != nil && n.Name.Curfn != Curfn {
+ if Curfn != nil && n.Op() == ir.ONAME && n.Name().Curfn != nil && n.Name().Curfn != Curfn {
// Inner func is referring to var in outer func.
//
// TODO(rsc): If there is an outer variable x and we
// are parsing x := 5 inside the closure, until we get to
// the := it looks like a reference to the outer x so we'll
// make x a closure variable unnecessarily.
- c := n.Name.Param.Innermost
- if c == nil || c.Name.Curfn != Curfn {
+ c := n.Name().Param.Innermost
+ if c == nil || c.Name().Curfn != Curfn {
// Do not have a closure var for the active closure yet; make one.
- c = newname(s)
- c.SetClass(PAUTOHEAP)
- c.Name.SetIsClosureVar(true)
+ c = NewName(s)
+ c.SetClass(ir.PAUTOHEAP)
+ c.Name().SetIsClosureVar(true)
c.SetIsDDD(n.IsDDD())
- c.Name.Defn = n
+ c.Name().Defn = n
// Link into list of active closure variables.
// Popped from list in func funcLit.
- c.Name.Param.Outer = n.Name.Param.Innermost
- n.Name.Param.Innermost = c
+ c.Name().Param.Outer = n.Name().Param.Innermost
+ n.Name().Param.Innermost = c
- Curfn.Func.Cvars.Append(c)
+ Curfn.Func().ClosureVars.Append(c)
}
// return ref to closure var, not original
@@ -300,81 +302,81 @@ func oldname(s *types.Sym) *Node {
}
// importName is like oldname, but it reports an error if sym is from another package and not exported.
-func importName(sym *types.Sym) *Node {
+func importName(sym *types.Sym) ir.Node {
n := oldname(sym)
- if !types.IsExported(sym.Name) && sym.Pkg != localpkg {
+ if !types.IsExported(sym.Name) && sym.Pkg != ir.LocalPkg {
n.SetDiag(true)
- yyerror("cannot refer to unexported name %s.%s", sym.Pkg.Name, sym.Name)
+ base.Errorf("cannot refer to unexported name %s.%s", sym.Pkg.Name, sym.Name)
}
return n
}
// := declarations
-func colasname(n *Node) bool {
- switch n.Op {
- case ONAME,
- ONONAME,
- OPACK,
- OTYPE,
- OLITERAL:
- return n.Sym != nil
+func colasname(n ir.Node) bool {
+ switch n.Op() {
+ case ir.ONAME,
+ ir.ONONAME,
+ ir.OPACK,
+ ir.OTYPE,
+ ir.OLITERAL:
+ return n.Sym() != nil
}
return false
}
-func colasdefn(left []*Node, defn *Node) {
+func colasdefn(left []ir.Node, defn ir.Node) {
for _, n := range left {
- if n.Sym != nil {
- n.Sym.SetUniq(true)
+ if n.Sym() != nil {
+ n.Sym().SetUniq(true)
}
}
var nnew, nerr int
for i, n := range left {
- if n.isBlank() {
+ if ir.IsBlank(n) {
continue
}
if !colasname(n) {
- yyerrorl(defn.Pos, "non-name %v on left side of :=", n)
+ base.ErrorfAt(defn.Pos(), "non-name %v on left side of :=", n)
nerr++
continue
}
- if !n.Sym.Uniq() {
- yyerrorl(defn.Pos, "%v repeated on left side of :=", n.Sym)
+ if !n.Sym().Uniq() {
+ base.ErrorfAt(defn.Pos(), "%v repeated on left side of :=", n.Sym())
n.SetDiag(true)
nerr++
continue
}
- n.Sym.SetUniq(false)
- if n.Sym.Block == types.Block {
+ n.Sym().SetUniq(false)
+ if n.Sym().Block == types.Block {
continue
}
nnew++
- n = newname(n.Sym)
+ n = NewName(n.Sym())
declare(n, dclcontext)
- n.Name.Defn = defn
- defn.Ninit.Append(nod(ODCL, n, nil))
+ n.Name().Defn = defn
+ defn.PtrInit().Append(ir.Nod(ir.ODCL, n, nil))
left[i] = n
}
if nnew == 0 && nerr == 0 {
- yyerrorl(defn.Pos, "no new variables on left side of :=")
+ base.ErrorfAt(defn.Pos(), "no new variables on left side of :=")
}
}
// declare the arguments in an
// interface field declaration.
-func ifacedcl(n *Node) {
- if n.Op != ODCLFIELD || n.Left == nil {
- Fatalf("ifacedcl")
+func ifacedcl(n ir.Node) {
+ if n.Op() != ir.ODCLFIELD || n.Left() == nil {
+ base.Fatalf("ifacedcl")
}
- if n.Sym.IsBlank() {
- yyerror("methods must have a unique non-blank name")
+ if n.Sym().IsBlank() {
+ base.Errorf("methods must have a unique non-blank name")
}
}
@@ -382,26 +384,24 @@ func ifacedcl(n *Node) {
// and declare the arguments.
// called in extern-declaration context
// returns in auto-declaration context.
-func funchdr(n *Node) {
+func funchdr(n ir.Node) {
// change the declaration context from extern to auto
funcStack = append(funcStack, funcStackEnt{Curfn, dclcontext})
Curfn = n
- dclcontext = PAUTO
+ dclcontext = ir.PAUTO
types.Markdcl()
- if n.Func.Nname != nil {
- funcargs(n.Func.Nname.Name.Param.Ntype)
- } else if n.Func.Ntype != nil {
- funcargs(n.Func.Ntype)
+ if n.Func().Nname != nil && n.Func().Nname.Name().Param.Ntype != nil {
+ funcargs(n.Func().Nname.Name().Param.Ntype)
} else {
- funcargs2(n.Type)
+ funcargs2(n.Type())
}
}
-func funcargs(nt *Node) {
- if nt.Op != OTFUNC {
- Fatalf("funcargs %v", nt.Op)
+func funcargs(nt ir.Node) {
+ if nt.Op() != ir.OTFUNC {
+ base.Fatalf("funcargs %v", nt.Op())
}
// re-start the variable generation number
@@ -411,87 +411,87 @@ func funcargs(nt *Node) {
// TODO(mdempsky): This is ugly, and only necessary because
// esc.go uses Vargen to figure out result parameters' index
// within the result tuple.
- vargen = nt.Rlist.Len()
+ vargen = nt.Rlist().Len()
// declare the receiver and in arguments.
- if nt.Left != nil {
- funcarg(nt.Left, PPARAM)
+ if nt.Left() != nil {
+ funcarg(nt.Left(), ir.PPARAM)
}
- for _, n := range nt.List.Slice() {
- funcarg(n, PPARAM)
+ for _, n := range nt.List().Slice() {
+ funcarg(n, ir.PPARAM)
}
oldvargen := vargen
vargen = 0
// declare the out arguments.
- gen := nt.List.Len()
- for _, n := range nt.Rlist.Slice() {
- if n.Sym == nil {
+ gen := nt.List().Len()
+ for _, n := range nt.Rlist().Slice() {
+ if n.Sym() == nil {
// Name so that escape analysis can track it. ~r stands for 'result'.
- n.Sym = lookupN("~r", gen)
+ n.SetSym(lookupN("~r", gen))
gen++
}
- if n.Sym.IsBlank() {
+ if n.Sym().IsBlank() {
// Give it a name so we can assign to it during return. ~b stands for 'blank'.
// The name must be different from ~r above because if you have
// func f() (_ int)
// func g() int
// f is allowed to use a plain 'return' with no arguments, while g is not.
// So the two cases must be distinguished.
- n.Sym = lookupN("~b", gen)
+ n.SetSym(lookupN("~b", gen))
gen++
}
- funcarg(n, PPARAMOUT)
+ funcarg(n, ir.PPARAMOUT)
}
vargen = oldvargen
}
-func funcarg(n *Node, ctxt Class) {
- if n.Op != ODCLFIELD {
- Fatalf("funcarg %v", n.Op)
+func funcarg(n ir.Node, ctxt ir.Class) {
+ if n.Op() != ir.ODCLFIELD {
+ base.Fatalf("funcarg %v", n.Op())
}
- if n.Sym == nil {
+ if n.Sym() == nil {
return
}
- n.Right = newnamel(n.Pos, n.Sym)
- n.Right.Name.Param.Ntype = n.Left
- n.Right.SetIsDDD(n.IsDDD())
- declare(n.Right, ctxt)
+ n.SetRight(ir.NewNameAt(n.Pos(), n.Sym()))
+ n.Right().Name().Param.Ntype = n.Left()
+ n.Right().SetIsDDD(n.IsDDD())
+ declare(n.Right(), ctxt)
vargen++
- n.Right.Name.Vargen = int32(vargen)
+ n.Right().Name().Vargen = int32(vargen)
}
// Same as funcargs, except run over an already constructed TFUNC.
// This happens during import, where the hidden_fndcl rule has
// used functype directly to parse the function's type.
func funcargs2(t *types.Type) {
- if t.Etype != TFUNC {
- Fatalf("funcargs2 %v", t)
+ if t.Etype != types.TFUNC {
+ base.Fatalf("funcargs2 %v", t)
}
for _, f := range t.Recvs().Fields().Slice() {
- funcarg2(f, PPARAM)
+ funcarg2(f, ir.PPARAM)
}
for _, f := range t.Params().Fields().Slice() {
- funcarg2(f, PPARAM)
+ funcarg2(f, ir.PPARAM)
}
for _, f := range t.Results().Fields().Slice() {
- funcarg2(f, PPARAMOUT)
+ funcarg2(f, ir.PPARAMOUT)
}
}
-func funcarg2(f *types.Field, ctxt Class) {
+func funcarg2(f *types.Field, ctxt ir.Class) {
if f.Sym == nil {
return
}
- n := newnamel(f.Pos, f.Sym)
- f.Nname = asTypesNode(n)
- n.Type = f.Type
+ n := ir.NewNameAt(f.Pos, f.Sym)
+ f.Nname = n
+ n.SetType(f.Type)
n.SetIsDDD(f.IsDDD())
declare(n, ctxt)
}
@@ -499,8 +499,8 @@ func funcarg2(f *types.Field, ctxt Class) {
var funcStack []funcStackEnt // stack of previous values of Curfn/dclcontext
type funcStackEnt struct {
- curfn *Node
- dclcontext Class
+ curfn ir.Node
+ dclcontext ir.Class
}
// finish the body.
@@ -524,57 +524,41 @@ func checkembeddedtype(t *types.Type) {
if t.Sym == nil && t.IsPtr() {
t = t.Elem()
if t.IsInterface() {
- yyerror("embedded type cannot be a pointer to interface")
+ base.Errorf("embedded type cannot be a pointer to interface")
}
}
if t.IsPtr() || t.IsUnsafePtr() {
- yyerror("embedded type cannot be a pointer")
- } else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
- t.ForwardType().Embedlineno = lineno
+ base.Errorf("embedded type cannot be a pointer")
+ } else if t.Etype == types.TFORW && !t.ForwardType().Embedlineno.IsKnown() {
+ t.ForwardType().Embedlineno = base.Pos
}
}
-func structfield(n *Node) *types.Field {
- lno := lineno
- lineno = n.Pos
-
- if n.Op != ODCLFIELD {
- Fatalf("structfield: oops %v\n", n)
- }
-
- f := types.NewField()
- f.Pos = n.Pos
- f.Sym = n.Sym
+func structfield(n ir.Node) *types.Field {
+ lno := base.Pos
+ base.Pos = n.Pos()
- if n.Left != nil {
- n.Left = typecheck(n.Left, ctxType)
- n.Type = n.Left.Type
- n.Left = nil
+ if n.Op() != ir.ODCLFIELD {
+ base.Fatalf("structfield: oops %v\n", n)
}
- f.Type = n.Type
- if f.Type == nil {
- f.SetBroke(true)
+ if n.Left() != nil {
+ n.SetLeft(typecheck(n.Left(), ctxType))
+ n.SetType(n.Left().Type())
+ n.SetLeft(nil)
}
+ f := types.NewField(n.Pos(), n.Sym(), n.Type())
if n.Embedded() {
- checkembeddedtype(n.Type)
+ checkembeddedtype(n.Type())
f.Embedded = 1
- } else {
- f.Embedded = 0
}
-
- switch u := n.Val().U.(type) {
- case string:
- f.Note = u
- default:
- yyerror("field tag must be a string")
- case nil:
- // no-op
+ if n.HasVal() {
+ f.Note = constant.StringVal(n.Val())
}
- lineno = lno
+ base.Pos = lno
return f
}
@@ -588,7 +572,7 @@ func checkdupfields(what string, fss ...[]*types.Field) {
continue
}
if seen[f.Sym] {
- yyerrorl(f.Pos, "duplicate %s %s", what, f.Sym.Name)
+ base.ErrorfAt(f.Pos, "duplicate %s %s", what, f.Sym.Name)
continue
}
seen[f.Sym] = true
@@ -598,8 +582,8 @@ func checkdupfields(what string, fss ...[]*types.Field) {
// convert a parsed id/type list into
// a type for struct/interface/arglist
-func tostruct(l []*Node) *types.Type {
- t := types.New(TSTRUCT)
+func tostruct(l []ir.Node) *types.Type {
+ t := types.New(types.TSTRUCT)
fields := make([]*types.Field, len(l))
for i, n := range l {
@@ -620,17 +604,17 @@ func tostruct(l []*Node) *types.Type {
return t
}
-func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
- t := types.New(TSTRUCT)
+func tofunargs(l []ir.Node, funarg types.Funarg) *types.Type {
+ t := types.New(types.TSTRUCT)
t.StructType().Funarg = funarg
fields := make([]*types.Field, len(l))
for i, n := range l {
f := structfield(n)
f.SetIsDDD(n.IsDDD())
- if n.Right != nil {
- n.Right.Type = f.Type
- f.Nname = asTypesNode(n.Right)
+ if n.Right() != nil {
+ n.Right().SetType(f.Type)
+ f.Nname = n.Right()
}
if f.Broke() {
t.SetBroke(true)
@@ -642,22 +626,22 @@ func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
}
func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
- t := types.New(TSTRUCT)
+ t := types.New(types.TSTRUCT)
t.StructType().Funarg = funarg
t.SetFields(fields)
return t
}
-func interfacefield(n *Node) *types.Field {
- lno := lineno
- lineno = n.Pos
+func interfacefield(n ir.Node) *types.Field {
+ lno := base.Pos
+ base.Pos = n.Pos()
- if n.Op != ODCLFIELD {
- Fatalf("interfacefield: oops %v\n", n)
+ if n.Op() != ir.ODCLFIELD {
+ base.Fatalf("interfacefield: oops %v\n", n)
}
- if n.Val().Ctype() != CTxxx {
- yyerror("interface method cannot have annotation")
+ if n.HasVal() {
+ base.Errorf("interface method cannot have annotation")
}
// MethodSpec = MethodName Signature | InterfaceTypeName .
@@ -665,29 +649,23 @@ func interfacefield(n *Node) *types.Field {
// If Sym != nil, then Sym is MethodName and Left is Signature.
// Otherwise, Left is InterfaceTypeName.
- if n.Left != nil {
- n.Left = typecheck(n.Left, ctxType)
- n.Type = n.Left.Type
- n.Left = nil
+ if n.Left() != nil {
+ n.SetLeft(typecheck(n.Left(), ctxType))
+ n.SetType(n.Left().Type())
+ n.SetLeft(nil)
}
- f := types.NewField()
- f.Pos = n.Pos
- f.Sym = n.Sym
- f.Type = n.Type
- if f.Type == nil {
- f.SetBroke(true)
- }
+ f := types.NewField(n.Pos(), n.Sym(), n.Type())
- lineno = lno
+ base.Pos = lno
return f
}
-func tointerface(l []*Node) *types.Type {
+func tointerface(l []ir.Node) *types.Type {
if len(l) == 0 {
- return types.Types[TINTER]
+ return types.Types[types.TINTER]
}
- t := types.New(TINTER)
+ t := types.New(types.TINTER)
var fields []*types.Field
for _, n := range l {
f := interfacefield(n)
@@ -700,14 +678,12 @@ func tointerface(l []*Node) *types.Type {
return t
}
-func fakeRecv() *Node {
+func fakeRecv() ir.Node {
return anonfield(types.FakeRecvType())
}
func fakeRecvField() *types.Field {
- f := types.NewField()
- f.Type = types.FakeRecvType()
- return f
+ return types.NewField(src.NoXPos, nil, types.FakeRecvType())
}
// isifacemethod reports whether (field) m is
@@ -718,12 +694,12 @@ func isifacemethod(f *types.Type) bool {
}
// turn a parsed function declaration into a type
-func functype(this *Node, in, out []*Node) *types.Type {
- t := types.New(TFUNC)
+func functype(this ir.Node, in, out []ir.Node) *types.Type {
+ t := types.New(types.TFUNC)
- var rcvr []*Node
+ var rcvr []ir.Node
if this != nil {
- rcvr = []*Node{this}
+ rcvr = []ir.Node{this}
}
t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
t.FuncType().Params = tofunargs(in, types.FunargParams)
@@ -735,13 +711,13 @@ func functype(this *Node, in, out []*Node) *types.Type {
t.SetBroke(true)
}
- t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil
+ t.FuncType().Outnamed = t.NumResults() > 0 && ir.OrigSym(t.Results().Field(0).Sym) != nil
return t
}
func functypefield(this *types.Field, in, out []*types.Field) *types.Type {
- t := types.New(TFUNC)
+ t := types.New(types.TFUNC)
var rcvr []*types.Field
if this != nil {
@@ -751,36 +727,11 @@ func functypefield(this *types.Field, in, out []*types.Field) *types.Type {
t.FuncType().Params = tofunargsfield(in, types.FunargParams)
t.FuncType().Results = tofunargsfield(out, types.FunargResults)
- t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil
+ t.FuncType().Outnamed = t.NumResults() > 0 && ir.OrigSym(t.Results().Field(0).Sym) != nil
return t
}
-// origSym returns the original symbol written by the user.
-func origSym(s *types.Sym) *types.Sym {
- if s == nil {
- return nil
- }
-
- if len(s.Name) > 1 && s.Name[0] == '~' {
- switch s.Name[1] {
- case 'r': // originally an unnamed result
- return nil
- case 'b': // originally the blank identifier _
- // TODO(mdempsky): Does s.Pkg matter here?
- return nblank.Sym
- }
- return s
- }
-
- if strings.HasPrefix(s.Name, ".anon") {
- // originally an unnamed or _ name (see subr.go: structargs)
- return nil
- }
-
- return s
-}
-
// methodSym returns the method symbol representing a method name
// associated with a specific receiver type.
//
@@ -800,13 +751,13 @@ func methodSym(recv *types.Type, msym *types.Sym) *types.Sym {
// start with a letter, number, or period.
func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
if msym.IsBlank() {
- Fatalf("blank method name")
+ base.Fatalf("blank method name")
}
rsym := recv.Sym
if recv.IsPtr() {
if rsym != nil {
- Fatalf("declared pointer receiver type: %v", recv)
+ base.Fatalf("declared pointer receiver type: %v", recv)
}
rsym = recv.Elem().Sym
}
@@ -848,15 +799,15 @@ func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sy
// - msym is the method symbol
// - t is function type (with receiver)
// Returns a pointer to the existing or added Field; or nil if there's an error.
-func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
+func addmethod(n ir.Node, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
if msym == nil {
- Fatalf("no method symbol")
+ base.Fatalf("no method symbol")
}
// get parent type sym
rf := t.Recv() // ptr to this structure
if rf == nil {
- yyerror("missing receiver")
+ base.Errorf("missing receiver")
return nil
}
@@ -866,7 +817,7 @@ func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.F
t := pa
if t != nil && t.IsPtr() {
if t.Sym != nil {
- yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
+ base.Errorf("invalid receiver type %v (%v is a pointer type)", pa, t)
return nil
}
t = t.Elem()
@@ -876,21 +827,21 @@ func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.F
case t == nil || t.Broke():
// rely on typecheck having complained before
case t.Sym == nil:
- yyerror("invalid receiver type %v (%v is not a defined type)", pa, t)
+ base.Errorf("invalid receiver type %v (%v is not a defined type)", pa, t)
case t.IsPtr():
- yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
+ base.Errorf("invalid receiver type %v (%v is a pointer type)", pa, t)
case t.IsInterface():
- yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
+ base.Errorf("invalid receiver type %v (%v is an interface type)", pa, t)
default:
// Should have picked off all the reasons above,
// but just in case, fall back to generic error.
- yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
+ base.Errorf("invalid receiver type %v (%L / %L)", pa, pa, t)
}
return nil
}
- if local && mt.Sym.Pkg != localpkg {
- yyerror("cannot define new methods on non-local type %v", mt)
+ if local && mt.Sym.Pkg != ir.LocalPkg {
+ base.Errorf("cannot define new methods on non-local type %v", mt)
return nil
}
@@ -901,7 +852,7 @@ func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.F
if mt.IsStruct() {
for _, f := range mt.Fields().Slice() {
if f.Sym == msym {
- yyerror("type %v has both field and method named %v", mt, msym)
+ base.Errorf("type %v has both field and method named %v", mt, msym)
f.SetBroke(true)
return nil
}
@@ -915,15 +866,13 @@ func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.F
// types.Identical only checks that incoming and result parameters match,
// so explicitly check that the receiver parameters match too.
if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) {
- yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
+ base.Errorf("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
}
return f
}
- f := types.NewField()
- f.Pos = lineno
- f.Sym = msym
- f.Type = t
+ f := types.NewField(base.Pos, msym, t)
+ f.Nname = n.Func().Nname
f.SetNointerface(nointerface)
mt.Methods().Append(f)
@@ -951,7 +900,7 @@ func funcsym(s *types.Sym) *types.Sym {
// When dynamically linking, the necessary function
// symbols will be created explicitly with makefuncsym.
// See the makefuncsym comment for details.
- if !Ctxt.Flag_dynlink && !existed {
+ if !base.Ctxt.Flag_dynlink && !existed {
funcsyms = append(funcsyms, s)
}
funcsymsmu.Unlock()
@@ -968,13 +917,13 @@ func funcsym(s *types.Sym) *types.Sym {
// So instead, when dynamic linking, we only create
// the s·f stubs in s's package.
func makefuncsym(s *types.Sym) {
- if !Ctxt.Flag_dynlink {
- Fatalf("makefuncsym dynlink")
+ if !base.Ctxt.Flag_dynlink {
+ base.Fatalf("makefuncsym dynlink")
}
if s.IsBlank() {
return
}
- if compiling_runtime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") {
+ if base.Flag.CompilingRuntime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") {
// runtime.getg(), getclosureptr(), getcallerpc(), and
// getcallersp() are not real functions and so do not
// get funcsyms.
@@ -986,27 +935,27 @@ func makefuncsym(s *types.Sym) {
}
// setNodeNameFunc marks a node as a function.
-func setNodeNameFunc(n *Node) {
- if n.Op != ONAME || n.Class() != Pxxx {
- Fatalf("expected ONAME/Pxxx node, got %v", n)
+func setNodeNameFunc(n ir.Node) {
+ if n.Op() != ir.ONAME || n.Class() != ir.Pxxx {
+ base.Fatalf("expected ONAME/Pxxx node, got %v", n)
}
- n.SetClass(PFUNC)
- n.Sym.SetFunc(true)
+ n.SetClass(ir.PFUNC)
+ n.Sym().SetFunc(true)
}
-func dclfunc(sym *types.Sym, tfn *Node) *Node {
- if tfn.Op != OTFUNC {
- Fatalf("expected OTFUNC node, got %v", tfn)
+func dclfunc(sym *types.Sym, tfn ir.Node) ir.Node {
+ if tfn.Op() != ir.OTFUNC {
+ base.Fatalf("expected OTFUNC node, got %v", tfn)
}
- fn := nod(ODCLFUNC, nil, nil)
- fn.Func.Nname = newfuncnamel(lineno, sym)
- fn.Func.Nname.Name.Defn = fn
- fn.Func.Nname.Name.Param.Ntype = tfn
- setNodeNameFunc(fn.Func.Nname)
+ fn := ir.Nod(ir.ODCLFUNC, nil, nil)
+ fn.Func().Nname = newfuncnamel(base.Pos, sym, fn.Func())
+ fn.Func().Nname.Name().Defn = fn
+ fn.Func().Nname.Name().Param.Ntype = tfn
+ setNodeNameFunc(fn.Func().Nname)
funchdr(fn)
- fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, ctxType)
+ fn.Func().Nname.Name().Param.Ntype = typecheck(fn.Func().Nname.Name().Param.Ntype, ctxType)
return fn
}
@@ -1014,27 +963,22 @@ type nowritebarrierrecChecker struct {
// extraCalls contains extra function calls that may not be
// visible during later analysis. It maps from the ODCLFUNC of
// the caller to a list of callees.
- extraCalls map[*Node][]nowritebarrierrecCall
+ extraCalls map[ir.Node][]nowritebarrierrecCall
// curfn is the current function during AST walks.
- curfn *Node
+ curfn ir.Node
}
type nowritebarrierrecCall struct {
- target *Node // ODCLFUNC of caller or callee
+ target ir.Node // ODCLFUNC of caller or callee
lineno src.XPos // line of call
}
-type nowritebarrierrecCallSym struct {
- target *obj.LSym // LSym of callee
- lineno src.XPos // line of call
-}
-
// newNowritebarrierrecChecker creates a nowritebarrierrecChecker. It
// must be called before transformclosure and walk.
func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
c := &nowritebarrierrecChecker{
- extraCalls: make(map[*Node][]nowritebarrierrecCall),
+ extraCalls: make(map[ir.Node][]nowritebarrierrecCall),
}
// Find all systemstack calls and record their targets. In
@@ -1043,42 +987,42 @@ func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
// directly. This has to happen before transformclosure since
// it's a lot harder to work out the argument after.
for _, n := range xtop {
- if n.Op != ODCLFUNC {
+ if n.Op() != ir.ODCLFUNC {
continue
}
c.curfn = n
- inspect(n, c.findExtraCalls)
+ ir.Inspect(n, c.findExtraCalls)
}
c.curfn = nil
return c
}
-func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool {
- if n.Op != OCALLFUNC {
+func (c *nowritebarrierrecChecker) findExtraCalls(n ir.Node) bool {
+ if n.Op() != ir.OCALLFUNC {
return true
}
- fn := n.Left
- if fn == nil || fn.Op != ONAME || fn.Class() != PFUNC || fn.Name.Defn == nil {
+ fn := n.Left()
+ if fn == nil || fn.Op() != ir.ONAME || fn.Class() != ir.PFUNC || fn.Name().Defn == nil {
return true
}
- if !isRuntimePkg(fn.Sym.Pkg) || fn.Sym.Name != "systemstack" {
+ if !isRuntimePkg(fn.Sym().Pkg) || fn.Sym().Name != "systemstack" {
return true
}
- var callee *Node
- arg := n.List.First()
- switch arg.Op {
- case ONAME:
- callee = arg.Name.Defn
- case OCLOSURE:
- callee = arg.Func.Closure
+ var callee ir.Node
+ arg := n.List().First()
+ switch arg.Op() {
+ case ir.ONAME:
+ callee = arg.Name().Defn
+ case ir.OCLOSURE:
+ callee = arg.Func().Decl
default:
- Fatalf("expected ONAME or OCLOSURE node, got %+v", arg)
+ base.Fatalf("expected ONAME or OCLOSURE node, got %+v", arg)
}
- if callee.Op != ODCLFUNC {
- Fatalf("expected ODCLFUNC node, got %+v", callee)
+ if callee.Op() != ir.ODCLFUNC {
+ base.Fatalf("expected ODCLFUNC node, got %+v", callee)
}
- c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos})
+ c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos()})
return true
}
@@ -1090,17 +1034,17 @@ func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool {
// because that's all we know after we start SSA.
//
// This can be called concurrently for different from Nodes.
-func (c *nowritebarrierrecChecker) recordCall(from *Node, to *obj.LSym, pos src.XPos) {
- if from.Op != ODCLFUNC {
- Fatalf("expected ODCLFUNC, got %v", from)
+func (c *nowritebarrierrecChecker) recordCall(from ir.Node, to *obj.LSym, pos src.XPos) {
+ if from.Op() != ir.ODCLFUNC {
+ base.Fatalf("expected ODCLFUNC, got %v", from)
}
// We record this information on the *Func so this is
// concurrent-safe.
- fn := from.Func
- if fn.nwbrCalls == nil {
- fn.nwbrCalls = new([]nowritebarrierrecCallSym)
+ fn := from.Func()
+ if fn.NWBRCalls == nil {
+ fn.NWBRCalls = new([]ir.SymAndPos)
}
- *fn.nwbrCalls = append(*fn.nwbrCalls, nowritebarrierrecCallSym{to, pos})
+ *fn.NWBRCalls = append(*fn.NWBRCalls, ir.SymAndPos{Sym: to, Pos: pos})
}
func (c *nowritebarrierrecChecker) check() {
@@ -1108,39 +1052,39 @@ func (c *nowritebarrierrecChecker) check() {
// capture all calls created by lowering, but this means we
// only get to see the obj.LSyms of calls. symToFunc lets us
// get back to the ODCLFUNCs.
- symToFunc := make(map[*obj.LSym]*Node)
+ symToFunc := make(map[*obj.LSym]ir.Node)
// funcs records the back-edges of the BFS call graph walk. It
// maps from the ODCLFUNC of each function that must not have
// write barriers to the call that inhibits them. Functions
// that are directly marked go:nowritebarrierrec are in this
// map with a zero-valued nowritebarrierrecCall. This also
// acts as the set of marks for the BFS of the call graph.
- funcs := make(map[*Node]nowritebarrierrecCall)
+ funcs := make(map[ir.Node]nowritebarrierrecCall)
// q is the queue of ODCLFUNC Nodes to visit in BFS order.
- var q nodeQueue
+ var q ir.NodeQueue
for _, n := range xtop {
- if n.Op != ODCLFUNC {
+ if n.Op() != ir.ODCLFUNC {
continue
}
- symToFunc[n.Func.lsym] = n
+ symToFunc[n.Func().LSym] = n
// Make nowritebarrierrec functions BFS roots.
- if n.Func.Pragma&Nowritebarrierrec != 0 {
+ if n.Func().Pragma&ir.Nowritebarrierrec != 0 {
funcs[n] = nowritebarrierrecCall{}
- q.pushRight(n)
+ q.PushRight(n)
}
// Check go:nowritebarrier functions.
- if n.Func.Pragma&Nowritebarrier != 0 && n.Func.WBPos.IsKnown() {
- yyerrorl(n.Func.WBPos, "write barrier prohibited")
+ if n.Func().Pragma&ir.Nowritebarrier != 0 && n.Func().WBPos.IsKnown() {
+ base.ErrorfAt(n.Func().WBPos, "write barrier prohibited")
}
}
// Perform a BFS of the call graph from all
// go:nowritebarrierrec functions.
- enqueue := func(src, target *Node, pos src.XPos) {
- if target.Func.Pragma&Yeswritebarrierrec != 0 {
+ enqueue := func(src, target ir.Node, pos src.XPos) {
+ if target.Func().Pragma&ir.Yeswritebarrierrec != 0 {
// Don't flow into this function.
return
}
@@ -1151,20 +1095,20 @@ func (c *nowritebarrierrecChecker) check() {
// Record the path.
funcs[target] = nowritebarrierrecCall{target: src, lineno: pos}
- q.pushRight(target)
+ q.PushRight(target)
}
- for !q.empty() {
- fn := q.popLeft()
+ for !q.Empty() {
+ fn := q.PopLeft()
// Check fn.
- if fn.Func.WBPos.IsKnown() {
+ if fn.Func().WBPos.IsKnown() {
var err bytes.Buffer
call := funcs[fn]
for call.target != nil {
- fmt.Fprintf(&err, "\n\t%v: called by %v", linestr(call.lineno), call.target.Func.Nname)
+ fmt.Fprintf(&err, "\n\t%v: called by %v", base.FmtPos(call.lineno), call.target.Func().Nname)
call = funcs[call.target]
}
- yyerrorl(fn.Func.WBPos, "write barrier prohibited by caller; %v%s", fn.Func.Nname, err.String())
+ base.ErrorfAt(fn.Func().WBPos, "write barrier prohibited by caller; %v%s", fn.Func().Nname, err.String())
continue
}
@@ -1172,13 +1116,13 @@ func (c *nowritebarrierrecChecker) check() {
for _, callee := range c.extraCalls[fn] {
enqueue(fn, callee.target, callee.lineno)
}
- if fn.Func.nwbrCalls == nil {
+ if fn.Func().NWBRCalls == nil {
continue
}
- for _, callee := range *fn.Func.nwbrCalls {
- target := symToFunc[callee.target]
+ for _, callee := range *fn.Func().NWBRCalls {
+ target := symToFunc[callee.Sym]
if target != nil {
- enqueue(fn, target, callee.lineno)
+ enqueue(fn, target, callee.Pos)
}
}
}