"cmd/compile/internal/ir.Nodes %+v": "",
"cmd/compile/internal/ir.Nodes %.v": "",
"cmd/compile/internal/ir.Nodes %v": "",
+ "cmd/compile/internal/ir.Ntype %v": "",
"cmd/compile/internal/ir.Op %#v": "",
"cmd/compile/internal/ir.Op %v": "",
"cmd/compile/internal/ssa.BranchPrediction %d": "",
dclcontext = ir.PEXTERN
// func sym(p *T, h uintptr) uintptr
- tfn := ir.Nod(ir.OTFUNC, nil, nil)
- tfn.PtrList().Set2(
+ args := []*ir.Field{
namedfield("p", types.NewPtr(t)),
namedfield("h", types.Types[types.TUINTPTR]),
- )
- tfn.PtrRlist().Set1(anonfield(types.Types[types.TUINTPTR]))
+ }
+ results := []*ir.Field{anonfield(types.Types[types.TUINTPTR])}
+ tfn := ir.NewFuncType(base.Pos, nil, args, results)
fn := dclfunc(sym, tfn)
np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
n := NewName(sym)
setNodeNameFunc(n)
- n.SetType(functype(nil, []ir.Node{
+ n.SetType(functype(nil, []*ir.Field{
anonfield(types.NewPtr(t)),
anonfield(types.Types[types.TUINTPTR]),
- }, []ir.Node{
+ }, []*ir.Field{
anonfield(types.Types[types.TUINTPTR]),
}))
return n
dclcontext = ir.PEXTERN
// func sym(p, q *T) bool
- tfn := ir.Nod(ir.OTFUNC, nil, nil)
- tfn.PtrList().Set2(
- namedfield("p", types.NewPtr(t)),
- namedfield("q", types.NewPtr(t)),
- )
- tfn.PtrRlist().Set1(namedfield("r", types.Types[types.TBOOL]))
+ tfn := ir.NewFuncType(base.Pos, nil,
+ []*ir.Field{namedfield("p", types.NewPtr(t)), namedfield("q", types.NewPtr(t))},
+ []*ir.Field{namedfield("r", types.Types[types.TBOOL])})
fn := dclfunc(sym, tfn)
np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
typs[1] = types.NewPtr(typs[0])
typs[2] = types.Types[types.TANY]
typs[3] = types.NewPtr(typs[2])
- typs[4] = functype(nil, []ir.Node{anonfield(typs[1])}, []ir.Node{anonfield(typs[3])})
+ typs[4] = functype(nil, []*ir.Field{anonfield(typs[1])}, []*ir.Field{anonfield(typs[3])})
typs[5] = types.Types[types.TUINTPTR]
typs[6] = types.Types[types.TBOOL]
typs[7] = types.Types[types.TUNSAFEPTR]
- typs[8] = functype(nil, []ir.Node{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []ir.Node{anonfield(typs[7])})
+ typs[8] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []*ir.Field{anonfield(typs[7])})
typs[9] = functype(nil, nil, nil)
typs[10] = types.Types[types.TINTER]
- typs[11] = functype(nil, []ir.Node{anonfield(typs[10])}, nil)
+ typs[11] = functype(nil, []*ir.Field{anonfield(typs[10])}, nil)
typs[12] = types.Types[types.TINT32]
typs[13] = types.NewPtr(typs[12])
- typs[14] = functype(nil, []ir.Node{anonfield(typs[13])}, []ir.Node{anonfield(typs[10])})
+ typs[14] = functype(nil, []*ir.Field{anonfield(typs[13])}, []*ir.Field{anonfield(typs[10])})
typs[15] = types.Types[types.TINT]
- typs[16] = functype(nil, []ir.Node{anonfield(typs[15]), anonfield(typs[15])}, nil)
+ typs[16] = functype(nil, []*ir.Field{anonfield(typs[15]), anonfield(typs[15])}, nil)
typs[17] = types.Types[types.TUINT]
- typs[18] = functype(nil, []ir.Node{anonfield(typs[17]), anonfield(typs[15])}, nil)
- typs[19] = functype(nil, []ir.Node{anonfield(typs[6])}, nil)
+ typs[18] = functype(nil, []*ir.Field{anonfield(typs[17]), anonfield(typs[15])}, nil)
+ typs[19] = functype(nil, []*ir.Field{anonfield(typs[6])}, nil)
typs[20] = types.Types[types.TFLOAT64]
- typs[21] = functype(nil, []ir.Node{anonfield(typs[20])}, nil)
+ typs[21] = functype(nil, []*ir.Field{anonfield(typs[20])}, nil)
typs[22] = types.Types[types.TINT64]
- typs[23] = functype(nil, []ir.Node{anonfield(typs[22])}, nil)
+ typs[23] = functype(nil, []*ir.Field{anonfield(typs[22])}, nil)
typs[24] = types.Types[types.TUINT64]
- typs[25] = functype(nil, []ir.Node{anonfield(typs[24])}, nil)
+ typs[25] = functype(nil, []*ir.Field{anonfield(typs[24])}, nil)
typs[26] = types.Types[types.TCOMPLEX128]
- typs[27] = functype(nil, []ir.Node{anonfield(typs[26])}, nil)
+ typs[27] = functype(nil, []*ir.Field{anonfield(typs[26])}, nil)
typs[28] = types.Types[types.TSTRING]
- typs[29] = functype(nil, []ir.Node{anonfield(typs[28])}, nil)
- typs[30] = functype(nil, []ir.Node{anonfield(typs[2])}, nil)
- typs[31] = functype(nil, []ir.Node{anonfield(typs[5])}, nil)
+ typs[29] = functype(nil, []*ir.Field{anonfield(typs[28])}, nil)
+ typs[30] = functype(nil, []*ir.Field{anonfield(typs[2])}, nil)
+ typs[31] = functype(nil, []*ir.Field{anonfield(typs[5])}, nil)
typs[32] = types.NewArray(typs[0], 32)
typs[33] = types.NewPtr(typs[32])
- typs[34] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[28])})
- typs[35] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[28])})
- typs[36] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[28])})
- typs[37] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[28])})
+ typs[34] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
+ typs[35] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
+ typs[36] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
+ typs[37] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
typs[38] = types.NewSlice(typs[28])
- typs[39] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[38])}, []ir.Node{anonfield(typs[28])})
- typs[40] = functype(nil, []ir.Node{anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[15])})
+ typs[39] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[38])}, []*ir.Field{anonfield(typs[28])})
+ typs[40] = functype(nil, []*ir.Field{anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[15])})
typs[41] = types.NewArray(typs[0], 4)
typs[42] = types.NewPtr(typs[41])
- typs[43] = functype(nil, []ir.Node{anonfield(typs[42]), anonfield(typs[22])}, []ir.Node{anonfield(typs[28])})
- typs[44] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []ir.Node{anonfield(typs[28])})
- typs[45] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15])}, []ir.Node{anonfield(typs[28])})
+ typs[43] = functype(nil, []*ir.Field{anonfield(typs[42]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[28])})
+ typs[44] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[28])})
+ typs[45] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[28])})
typs[46] = types.Runetype
typs[47] = types.NewSlice(typs[46])
- typs[48] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[47])}, []ir.Node{anonfield(typs[28])})
+ typs[48] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[47])}, []*ir.Field{anonfield(typs[28])})
typs[49] = types.NewSlice(typs[0])
- typs[50] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28])}, []ir.Node{anonfield(typs[49])})
+ typs[50] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[49])})
typs[51] = types.NewArray(typs[46], 32)
typs[52] = types.NewPtr(typs[51])
- typs[53] = functype(nil, []ir.Node{anonfield(typs[52]), anonfield(typs[28])}, []ir.Node{anonfield(typs[47])})
- typs[54] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []ir.Node{anonfield(typs[15])})
- typs[55] = functype(nil, []ir.Node{anonfield(typs[28]), anonfield(typs[15])}, []ir.Node{anonfield(typs[46]), anonfield(typs[15])})
- typs[56] = functype(nil, []ir.Node{anonfield(typs[28])}, []ir.Node{anonfield(typs[15])})
- typs[57] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[2])}, []ir.Node{anonfield(typs[2])})
- typs[58] = functype(nil, []ir.Node{anonfield(typs[2])}, []ir.Node{anonfield(typs[7])})
- typs[59] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3])}, []ir.Node{anonfield(typs[2])})
- typs[60] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[2])}, []ir.Node{anonfield(typs[2]), anonfield(typs[6])})
- typs[61] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
- typs[62] = functype(nil, []ir.Node{anonfield(typs[1])}, nil)
+ typs[53] = functype(nil, []*ir.Field{anonfield(typs[52]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[47])})
+ typs[54] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[15])})
+ typs[55] = functype(nil, []*ir.Field{anonfield(typs[28]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[46]), anonfield(typs[15])})
+ typs[56] = functype(nil, []*ir.Field{anonfield(typs[28])}, []*ir.Field{anonfield(typs[15])})
+ typs[57] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[2])})
+ typs[58] = functype(nil, []*ir.Field{anonfield(typs[2])}, []*ir.Field{anonfield(typs[7])})
+ typs[59] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[2])})
+ typs[60] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[2]), anonfield(typs[6])})
+ typs[61] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
+ typs[62] = functype(nil, []*ir.Field{anonfield(typs[1])}, nil)
typs[63] = types.NewPtr(typs[5])
- typs[64] = functype(nil, []ir.Node{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []ir.Node{anonfield(typs[6])})
+ typs[64] = functype(nil, []*ir.Field{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[6])})
typs[65] = types.Types[types.TUINT32]
- typs[66] = functype(nil, nil, []ir.Node{anonfield(typs[65])})
+ typs[66] = functype(nil, nil, []*ir.Field{anonfield(typs[65])})
typs[67] = types.NewMap(typs[2], typs[2])
- typs[68] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []ir.Node{anonfield(typs[67])})
- typs[69] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []ir.Node{anonfield(typs[67])})
- typs[70] = functype(nil, nil, []ir.Node{anonfield(typs[67])})
- typs[71] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []ir.Node{anonfield(typs[3])})
- typs[72] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []ir.Node{anonfield(typs[3])})
- typs[73] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []ir.Node{anonfield(typs[3])})
- typs[74] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []ir.Node{anonfield(typs[3]), anonfield(typs[6])})
- typs[75] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []ir.Node{anonfield(typs[3]), anonfield(typs[6])})
- typs[76] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []ir.Node{anonfield(typs[3]), anonfield(typs[6])})
- typs[77] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
- typs[78] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
- typs[79] = functype(nil, []ir.Node{anonfield(typs[3])}, nil)
- typs[80] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67])}, nil)
+ typs[68] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[67])})
+ typs[69] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[67])})
+ typs[70] = functype(nil, nil, []*ir.Field{anonfield(typs[67])})
+ typs[71] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[3])})
+ typs[72] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[3])})
+ typs[73] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Field{anonfield(typs[3])})
+ typs[74] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])})
+ typs[75] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])})
+ typs[76] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])})
+ typs[77] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
+ typs[78] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
+ typs[79] = functype(nil, []*ir.Field{anonfield(typs[3])}, nil)
+ typs[80] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67])}, nil)
typs[81] = types.NewChan(typs[2], types.Cboth)
- typs[82] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[22])}, []ir.Node{anonfield(typs[81])})
- typs[83] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15])}, []ir.Node{anonfield(typs[81])})
+ typs[82] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[81])})
+ typs[83] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[81])})
typs[84] = types.NewChan(typs[2], types.Crecv)
- typs[85] = functype(nil, []ir.Node{anonfield(typs[84]), anonfield(typs[3])}, nil)
- typs[86] = functype(nil, []ir.Node{anonfield(typs[84]), anonfield(typs[3])}, []ir.Node{anonfield(typs[6])})
+ typs[85] = functype(nil, []*ir.Field{anonfield(typs[84]), anonfield(typs[3])}, nil)
+ typs[86] = functype(nil, []*ir.Field{anonfield(typs[84]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
typs[87] = types.NewChan(typs[2], types.Csend)
- typs[88] = functype(nil, []ir.Node{anonfield(typs[87]), anonfield(typs[3])}, nil)
+ typs[88] = functype(nil, []*ir.Field{anonfield(typs[87]), anonfield(typs[3])}, nil)
typs[89] = types.NewArray(typs[0], 3)
- typs[90] = tostruct([]ir.Node{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])})
- typs[91] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
- typs[92] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
- typs[93] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []ir.Node{anonfield(typs[15])})
- typs[94] = functype(nil, []ir.Node{anonfield(typs[87]), anonfield(typs[3])}, []ir.Node{anonfield(typs[6])})
- typs[95] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[84])}, []ir.Node{anonfield(typs[6])})
+ typs[90] = tostruct([]*ir.Field{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])})
+ typs[91] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
+ typs[92] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3])}, nil)
+ typs[93] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[15])})
+ typs[94] = functype(nil, []*ir.Field{anonfield(typs[87]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
+ typs[95] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[84])}, []*ir.Field{anonfield(typs[6])})
typs[96] = types.NewPtr(typs[6])
- typs[97] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []ir.Node{anonfield(typs[6])})
- typs[98] = functype(nil, []ir.Node{anonfield(typs[63])}, nil)
- typs[99] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []ir.Node{anonfield(typs[15]), anonfield(typs[6])})
- typs[100] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []ir.Node{anonfield(typs[7])})
- typs[101] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []ir.Node{anonfield(typs[7])})
- typs[102] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []ir.Node{anonfield(typs[7])})
+ typs[97] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*ir.Field{anonfield(typs[6])})
+ typs[98] = functype(nil, []*ir.Field{anonfield(typs[63])}, nil)
+ typs[99] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []*ir.Field{anonfield(typs[15]), anonfield(typs[6])})
+ typs[100] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[7])})
+ typs[101] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[7])})
+ typs[102] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[7])})
typs[103] = types.NewSlice(typs[2])
- typs[104] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []ir.Node{anonfield(typs[103])})
- typs[105] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
- typs[106] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
- typs[107] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []ir.Node{anonfield(typs[6])})
- typs[108] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[3])}, []ir.Node{anonfield(typs[6])})
- typs[109] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[7])}, []ir.Node{anonfield(typs[6])})
- typs[110] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []ir.Node{anonfield(typs[5])})
- typs[111] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[5])}, []ir.Node{anonfield(typs[5])})
- typs[112] = functype(nil, []ir.Node{anonfield(typs[22]), anonfield(typs[22])}, []ir.Node{anonfield(typs[22])})
- typs[113] = functype(nil, []ir.Node{anonfield(typs[24]), anonfield(typs[24])}, []ir.Node{anonfield(typs[24])})
- typs[114] = functype(nil, []ir.Node{anonfield(typs[20])}, []ir.Node{anonfield(typs[22])})
- typs[115] = functype(nil, []ir.Node{anonfield(typs[20])}, []ir.Node{anonfield(typs[24])})
- typs[116] = functype(nil, []ir.Node{anonfield(typs[20])}, []ir.Node{anonfield(typs[65])})
- typs[117] = functype(nil, []ir.Node{anonfield(typs[22])}, []ir.Node{anonfield(typs[20])})
- typs[118] = functype(nil, []ir.Node{anonfield(typs[24])}, []ir.Node{anonfield(typs[20])})
- typs[119] = functype(nil, []ir.Node{anonfield(typs[65])}, []ir.Node{anonfield(typs[20])})
- typs[120] = functype(nil, []ir.Node{anonfield(typs[26]), anonfield(typs[26])}, []ir.Node{anonfield(typs[26])})
- typs[121] = functype(nil, []ir.Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
- typs[122] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
+ typs[104] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[103])})
+ typs[105] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
+ typs[106] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5])}, nil)
+ typs[107] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[6])})
+ typs[108] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
+ typs[109] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[6])})
+ typs[110] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[5])})
+ typs[111] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[5])})
+ typs[112] = functype(nil, []*ir.Field{anonfield(typs[22]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[22])})
+ typs[113] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, []*ir.Field{anonfield(typs[24])})
+ typs[114] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[22])})
+ typs[115] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[24])})
+ typs[116] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[65])})
+ typs[117] = functype(nil, []*ir.Field{anonfield(typs[22])}, []*ir.Field{anonfield(typs[20])})
+ typs[118] = functype(nil, []*ir.Field{anonfield(typs[24])}, []*ir.Field{anonfield(typs[20])})
+ typs[119] = functype(nil, []*ir.Field{anonfield(typs[65])}, []*ir.Field{anonfield(typs[20])})
+ typs[120] = functype(nil, []*ir.Field{anonfield(typs[26]), anonfield(typs[26])}, []*ir.Field{anonfield(typs[26])})
+ typs[121] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[5])}, nil)
+ typs[122] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
typs[123] = types.NewSlice(typs[7])
- typs[124] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[123])}, nil)
+ typs[124] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[123])}, nil)
typs[125] = types.Types[types.TUINT8]
- typs[126] = functype(nil, []ir.Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
+ typs[126] = functype(nil, []*ir.Field{anonfield(typs[125]), anonfield(typs[125])}, nil)
typs[127] = types.Types[types.TUINT16]
- typs[128] = functype(nil, []ir.Node{anonfield(typs[127]), anonfield(typs[127])}, nil)
- typs[129] = functype(nil, []ir.Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
- typs[130] = functype(nil, []ir.Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
+ typs[128] = functype(nil, []*ir.Field{anonfield(typs[127]), anonfield(typs[127])}, nil)
+ typs[129] = functype(nil, []*ir.Field{anonfield(typs[65]), anonfield(typs[65])}, nil)
+ typs[130] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, nil)
return typs[:]
}
// The information appears in the binary in the form of type descriptors;
// the struct is unnamed so that closures in multiple packages with the
// same struct type can share the descriptor.
- fields := []ir.Node{
+ fields := []*ir.Field{
namedfield(".F", types.Types[types.TUINTPTR]),
}
for _, v := range clo.Func().ClosureVars {
// number at the use of the method expression in this
// case. See issue 29389.
- tfn := ir.Nod(ir.OTFUNC, nil, nil)
- tfn.PtrList().Set(structargs(t0.Params(), true))
- tfn.PtrRlist().Set(structargs(t0.Results(), false))
+ tfn := ir.NewFuncType(base.Pos, nil,
+ structargs(t0.Params(), true),
+ structargs(t0.Results(), false))
fn := dclfunc(sym, tfn)
fn.SetDupok(true)
// needed in the closure for n (n must be a OCALLPART node).
// The address of a variable of the returned type can be cast to a func.
func partialCallType(n ir.Node) *types.Type {
- t := tostruct([]ir.Node{
+ t := tostruct([]*ir.Field{
namedfield("F", types.Types[types.TUINTPTR]),
namedfield("R", n.Left().Type()),
})
// declare variables from grammar
// new_name_list (type | [type] = expr_list)
-func variter(vl []ir.Node, t ir.Node, el []ir.Node) []ir.Node {
+func variter(vl []ir.Node, t ir.Ntype, el []ir.Node) []ir.Node {
var init []ir.Node
doexpr := len(el) > 0
return n
}
-func anonfield(typ *types.Type) ir.Node {
+func anonfield(typ *types.Type) *ir.Field {
return symfield(nil, typ)
}
-func namedfield(s string, typ *types.Type) ir.Node {
+func namedfield(s string, typ *types.Type) *ir.Field {
return symfield(lookup(s), typ)
}
-func symfield(s *types.Sym, typ *types.Type) ir.Node {
- n := nodSym(ir.ODCLFIELD, nil, s)
- n.SetType(typ)
- return n
+func symfield(s *types.Sym, typ *types.Type) *ir.Field {
+ return ir.NewField(base.Pos, s, nil, typ)
}
// oldname returns the Node that declares symbol s in the current scope.
return n
}
-// importName is like oldname, but it reports an error if sym is from another package and not exported.
+// importName is like oldname,
+// but it reports an error if sym is from another package and not exported.
func importName(sym *types.Sym) ir.Node {
n := oldname(sym)
if !types.IsExported(sym.Name) && sym.Pkg != ir.LocalPkg {
// declare the arguments in an
// interface field declaration.
-func ifacedcl(n ir.Node) {
- if n.Op() != ir.ODCLFIELD || n.Left() == nil {
+func ifacedcl(n *ir.Field) {
+ if n.Sym == nil {
base.Fatalf("ifacedcl")
}
- if n.Sym().IsBlank() {
+ if n.Sym.IsBlank() {
base.Errorf("methods must have a unique non-blank name")
}
}
types.Markdcl()
if fn.Nname != nil && fn.Nname.Ntype != nil {
- funcargs(fn.Nname.Ntype)
+ funcargs(fn.Nname.Ntype.(*ir.FuncType))
} else {
funcargs2(fn.Type())
}
}
-func funcargs(nt ir.Node) {
+func funcargs(nt *ir.FuncType) {
if nt.Op() != ir.OTFUNC {
base.Fatalf("funcargs %v", nt.Op())
}
// 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 = len(nt.Results)
// declare the receiver and in arguments.
- if nt.Left() != nil {
- funcarg(nt.Left(), ir.PPARAM)
+ if nt.Recv != nil {
+ funcarg(nt.Recv, ir.PPARAM)
}
- for _, n := range nt.List().Slice() {
+ for _, n := range nt.Params {
funcarg(n, ir.PPARAM)
}
vargen = 0
// declare the out arguments.
- gen := nt.List().Len()
- for _, n := range nt.Rlist().Slice() {
- if n.Sym() == nil {
+ gen := len(nt.Params)
+ for _, n := range nt.Results {
+ if n.Sym == nil {
// Name so that escape analysis can track it. ~r stands for 'result'.
- n.SetSym(lookupN("~r", gen))
+ n.Sym = 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.SetSym(lookupN("~b", gen))
+ n.Sym = lookupN("~b", gen)
gen++
}
vargen = oldvargen
}
-func funcarg(n ir.Node, ctxt ir.Class) {
- if n.Op() != ir.ODCLFIELD {
- base.Fatalf("funcarg %v", n.Op())
- }
- if n.Sym() == nil {
+func funcarg(n *ir.Field, ctxt ir.Class) {
+ if n.Sym == nil {
return
}
- name := ir.NewNameAt(n.Pos(), n.Sym())
- n.SetRight(name)
- name.Ntype = n.Left()
- name.SetIsDDD(n.IsDDD())
+ name := ir.NewNameAt(n.Pos, n.Sym)
+ n.Decl = name
+ name.Ntype = n.Ntype
+ name.SetIsDDD(n.IsDDD)
declare(name, ctxt)
vargen++
- n.Right().Name().Vargen = int32(vargen)
+ n.Decl.Name().Vargen = int32(vargen)
}
// Same as funcargs, except run over an already constructed TFUNC.
}
}
-func structfield(n ir.Node) *types.Field {
+func structfield(n *ir.Field) *types.Field {
lno := base.Pos
- base.Pos = n.Pos()
-
- if n.Op() != ir.ODCLFIELD {
- base.Fatalf("structfield: oops %v\n", n)
- }
+ base.Pos = n.Pos
- if n.Left() != nil {
- n.SetLeft(typecheck(n.Left(), ctxType))
- n.SetType(n.Left().Type())
- n.SetLeft(nil)
+ if n.Ntype != nil {
+ n.Ntype = typecheckNtype(n.Ntype)
+ n.Type = n.Ntype.Type()
+ n.Ntype = nil
}
- f := types.NewField(n.Pos(), n.Sym(), n.Type())
- if n.Embedded() {
- checkembeddedtype(n.Type())
+ f := types.NewField(n.Pos, n.Sym, n.Type)
+ if n.Embedded {
+ checkembeddedtype(n.Type)
f.Embedded = 1
}
- if n.Opt() != nil {
- f.Note = n.Opt().(string)
- }
+ f.Note = n.Note
base.Pos = lno
return f
// convert a parsed id/type list into
// a type for struct/interface/arglist
-func tostruct(l []ir.Node) *types.Type {
+func tostruct(l []*ir.Field) *types.Type {
t := types.New(types.TSTRUCT)
fields := make([]*types.Field, len(l))
return t
}
-func tofunargs(l []ir.Node, funarg types.Funarg) *types.Type {
+func tofunargs(l []*ir.Field, 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().SetType(f.Type)
- f.Nname = n.Right()
+ f.SetIsDDD(n.IsDDD)
+ if n.Decl != nil {
+ n.Decl.SetType(f.Type)
+ f.Nname = n.Decl
}
if f.Broke() {
t.SetBroke(true)
return t
}
-func interfacefield(n ir.Node) *types.Field {
+func interfacefield(n *ir.Field) *types.Field {
lno := base.Pos
- base.Pos = n.Pos()
-
- if n.Op() != ir.ODCLFIELD {
- base.Fatalf("interfacefield: oops %v\n", n)
- }
+ base.Pos = n.Pos
- if n.Opt() != nil {
+ if n.Note != "" {
base.Errorf("interface method cannot have annotation")
}
// If Sym != nil, then Sym is MethodName and Left is Signature.
// Otherwise, Left is InterfaceTypeName.
- if n.Left() != nil {
- n.SetLeft(typecheck(n.Left(), ctxType))
- n.SetType(n.Left().Type())
- n.SetLeft(nil)
+ if n.Ntype != nil {
+ n.Ntype = typecheckNtype(n.Ntype)
+ n.Type = n.Ntype.Type()
+ n.Ntype = nil
}
- f := types.NewField(n.Pos(), n.Sym(), n.Type())
+ f := types.NewField(n.Pos, n.Sym, n.Type)
base.Pos = lno
return f
}
-func tointerface(l []ir.Node) *types.Type {
+func tointerface(l []*ir.Field) *types.Type {
if len(l) == 0 {
return types.Types[types.TINTER]
}
return t
}
-func fakeRecv() ir.Node {
+func fakeRecv() *ir.Field {
return anonfield(types.FakeRecvType())
}
}
// turn a parsed function declaration into a type
-func functype(this ir.Node, in, out []ir.Node) *types.Type {
+func functype(this *ir.Field, in, out []*ir.Field) *types.Type {
t := types.New(types.TFUNC)
- var rcvr []ir.Node
+ var rcvr []*ir.Field
if this != nil {
- rcvr = []ir.Node{this}
+ rcvr = []*ir.Field{this}
}
t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
t.FuncType().Params = tofunargs(in, types.FunargParams)
n.Sym().SetFunc(true)
}
-func dclfunc(sym *types.Sym, tfn ir.Node) *ir.Func {
+func dclfunc(sym *types.Sym, tfn ir.Ntype) *ir.Func {
if tfn.Op() != ir.OTFUNC {
base.Fatalf("expected OTFUNC node, got %v", tfn)
}
fn.Nname.Ntype = tfn
setNodeNameFunc(fn.Nname)
funchdr(fn)
- fn.Nname.Ntype = typecheck(fn.Nname.Ntype, ctxType)
+ fn.Nname.Ntype = typecheckNtype(fn.Nname.Ntype)
return fn
}
var numLocalEmbed int
-func varEmbed(p *noder, names []ir.Node, typ ir.Node, exprs []ir.Node, embeds []PragmaEmbed) (newExprs []ir.Node) {
+func varEmbed(p *noder, names []ir.Node, typ ir.Ntype, exprs []ir.Node, embeds []PragmaEmbed) (newExprs []ir.Node) {
haveEmbed := false
for _, decl := range p.file.DeclList {
imp, ok := decl.(*syntax.ImportDecl)
if typ.Sym() != nil && typ.Sym().Name == "string" && typ.Sym().Pkg == ir.LocalPkg {
return embedString
}
- if typ.Op() == ir.OTARRAY && typ.Left() == nil && typ.Right().Sym() != nil && typ.Right().Sym().Name == "byte" && typ.Right().Sym().Pkg == ir.LocalPkg {
- return embedBytes
+ if typ, ok := typ.(*ir.SliceType); ok {
+ if sym := typ.Elem.Sym(); sym != nil && sym.Name == "byte" && sym.Pkg == ir.LocalPkg {
+ return embedBytes
+ }
}
return embedUnknown
}
w.localName(n.Left())
w.typ(n.Left().Type())
- // case ODCLFIELD:
- // unimplemented - handled by default case
-
case ir.OAS:
// Don't export "v = <N>" initializing statements, hope they're always
// preceded by the DCL which will be re-parsed and typecheck to reproduce
typ := ir.TypeNode(r.typ())
return npos(pos, liststmt(variter([]ir.Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
- // case ODCLFIELD:
- // unimplemented
-
// case OAS, OASWB:
// unreachable - mapped to OAS case below by exporter
if len(nf) > 0 {
base.Pos = nf[0].Pos() // prolog/epilog gets line number of first init stmt
initializers := lookup("init")
- fn := dclfunc(initializers, ir.Nod(ir.OTFUNC, nil, nil))
+ fn := dclfunc(initializers, ir.NewFuncType(base.Pos, nil, nil, nil))
for _, dcl := range initTodo.Dcl {
dcl.Name().Curfn = fn
}
}
}
}
- return fmt.Sprintf("[]ir.Node{%s}", strings.Join(res, ", "))
+ return fmt.Sprintf("[]*ir.Field{%s}", strings.Join(res, ", "))
}
func intconst(e ast.Expr) int64 {
// constant declarations are handled correctly (e.g., issue 15550).
type constState struct {
group *syntax.Group
- typ ir.Node
+ typ ir.Ntype
values []ir.Node
iota int64
}
return f
}
-func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) ir.Node {
- n := p.nod(typ, ir.OTFUNC, nil, nil)
+func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *ir.FuncType {
+ var rcvr *ir.Field
if recv != nil {
- n.SetLeft(p.param(recv, false, false))
+ rcvr = p.param(recv, false, false)
}
- n.PtrList().Set(p.params(typ.ParamList, true))
- n.PtrRlist().Set(p.params(typ.ResultList, false))
- return n
+ return ir.NewFuncType(p.pos(typ), rcvr,
+ p.params(typ.ParamList, true),
+ p.params(typ.ResultList, false))
}
-func (p *noder) params(params []*syntax.Field, dddOk bool) []ir.Node {
- nodes := make([]ir.Node, 0, len(params))
+func (p *noder) params(params []*syntax.Field, dddOk bool) []*ir.Field {
+ nodes := make([]*ir.Field, 0, len(params))
for i, param := range params {
p.setlineno(param)
nodes = append(nodes, p.param(param, dddOk, i+1 == len(params)))
return nodes
}
-func (p *noder) param(param *syntax.Field, dddOk, final bool) ir.Node {
+func (p *noder) param(param *syntax.Field, dddOk, final bool) *ir.Field {
var name *types.Sym
if param.Name != nil {
name = p.name(param.Name)
}
typ := p.typeExpr(param.Type)
- n := p.nodSym(param, ir.ODCLFIELD, typ, name)
+ n := ir.NewField(p.pos(param), name, typ, nil)
// rewrite ...T parameter
- if typ.Op() == ir.ODDD {
+ if typ, ok := typ.(*ir.SliceType); ok && typ.DDD {
if !dddOk {
// We mark these as syntax errors to get automatic elimination
// of multiple such errors per line (see ErrorfAt in subr.go).
p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
}
}
- typ.SetOp(ir.OTARRAY)
- typ.SetRight(typ.Left())
- typ.SetLeft(nil)
- n.SetIsDDD(true)
- if n.Left() != nil {
- n.Left().SetIsDDD(true)
- }
+ typ.DDD = false
+ n.IsDDD = true
}
return n
var len ir.Node
if expr.Len != nil {
len = p.expr(expr.Len)
- } else {
- len = p.nod(expr, ir.ODDD, nil, nil)
}
- return p.nod(expr, ir.OTARRAY, len, p.typeExpr(expr.Elem))
+ return ir.NewArrayType(p.pos(expr), len, p.typeExpr(expr.Elem))
case *syntax.SliceType:
- return p.nod(expr, ir.OTARRAY, nil, p.typeExpr(expr.Elem))
+ return ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
case *syntax.DotsType:
- return p.nod(expr, ir.ODDD, p.typeExpr(expr.Elem), nil)
+ t := ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
+ t.DDD = true
+ return t
case *syntax.StructType:
return p.structType(expr)
case *syntax.InterfaceType:
case *syntax.FuncType:
return p.signature(nil, expr)
case *syntax.MapType:
- return p.nod(expr, ir.OTMAP, p.typeExpr(expr.Key), p.typeExpr(expr.Value))
+ return ir.NewMapType(p.pos(expr),
+ p.typeExpr(expr.Key), p.typeExpr(expr.Value))
case *syntax.ChanType:
- n := p.nod(expr, ir.OTCHAN, p.typeExpr(expr.Elem), nil)
- n.SetTChanDir(p.chanDir(expr.Dir))
- return n
+ return ir.NewChanType(p.pos(expr),
+ p.typeExpr(expr.Elem), p.chanDir(expr.Dir))
case *syntax.TypeSwitchGuard:
n := p.nod(expr, ir.OTYPESW, nil, p.expr(expr.X))
return n
}
-func (p *noder) typeExpr(typ syntax.Expr) ir.Node {
+func (p *noder) typeExpr(typ syntax.Expr) ir.Ntype {
// TODO(mdempsky): Be stricter? typecheck should handle errors anyway.
- return p.expr(typ)
+ n := p.expr(typ)
+ if n == nil {
+ return nil
+ }
+ if _, ok := n.(ir.Ntype); !ok {
+ ir.Dump("NOT NTYPE", n)
+ }
+ return n.(ir.Ntype)
}
-func (p *noder) typeExprOrNil(typ syntax.Expr) ir.Node {
+func (p *noder) typeExprOrNil(typ syntax.Expr) ir.Ntype {
if typ != nil {
- return p.expr(typ)
+ return p.typeExpr(typ)
}
return nil
}
}
func (p *noder) structType(expr *syntax.StructType) ir.Node {
- l := make([]ir.Node, 0, len(expr.FieldList))
+ l := make([]*ir.Field, 0, len(expr.FieldList))
for i, field := range expr.FieldList {
p.setlineno(field)
- var n ir.Node
+ var n *ir.Field
if field.Name == nil {
n = p.embedded(field.Type)
} else {
- n = p.nodSym(field, ir.ODCLFIELD, p.typeExpr(field.Type), p.name(field.Name))
+ n = ir.NewField(p.pos(field), p.name(field.Name), p.typeExpr(field.Type), nil)
}
if i < len(expr.TagList) && expr.TagList[i] != nil {
- n.SetOpt(constant.StringVal(p.basicLit(expr.TagList[i])))
+ n.Note = constant.StringVal(p.basicLit(expr.TagList[i]))
}
l = append(l, n)
}
p.setlineno(expr)
- n := p.nod(expr, ir.OTSTRUCT, nil, nil)
- n.PtrList().Set(l)
- return n
+ return ir.NewStructType(p.pos(expr), l)
}
func (p *noder) interfaceType(expr *syntax.InterfaceType) ir.Node {
- l := make([]ir.Node, 0, len(expr.MethodList))
+ l := make([]*ir.Field, 0, len(expr.MethodList))
for _, method := range expr.MethodList {
p.setlineno(method)
- var n ir.Node
+ var n *ir.Field
if method.Name == nil {
- n = p.nodSym(method, ir.ODCLFIELD, importName(p.packname(method.Type)), nil)
+ n = ir.NewField(p.pos(method), nil, importName(p.packname(method.Type)).(ir.Ntype), nil)
} else {
mname := p.name(method.Name)
- sig := p.typeExpr(method.Type)
- sig.SetLeft(fakeRecv())
- n = p.nodSym(method, ir.ODCLFIELD, sig, mname)
+ sig := p.typeExpr(method.Type).(*ir.FuncType)
+ sig.Recv = fakeRecv()
+ n = ir.NewField(p.pos(method), mname, sig, nil)
ifacedcl(n)
}
l = append(l, n)
}
- n := p.nod(expr, ir.OTINTER, nil, nil)
- n.PtrList().Set(l)
- return n
+ return ir.NewInterfaceType(p.pos(expr), l)
}
func (p *noder) packname(expr syntax.Expr) *types.Sym {
panic(fmt.Sprintf("unexpected packname: %#v", expr))
}
-func (p *noder) embedded(typ syntax.Expr) ir.Node {
+func (p *noder) embedded(typ syntax.Expr) *ir.Field {
op, isStar := typ.(*syntax.Operation)
if isStar {
if op.Op != syntax.Mul || op.Y != nil {
}
sym := p.packname(typ)
- n := p.nodSym(typ, ir.ODCLFIELD, importName(sym), lookup(sym.Name))
- n.SetEmbedded(true)
+ n := ir.NewField(p.pos(typ), lookup(sym.Name), importName(sym).(ir.Ntype), nil)
+ n.Embedded = true
if isStar {
- n.SetLeft(p.nod(op, ir.ODEREF, n.Left(), nil))
+ n.Ntype = ir.NewStarExpr(p.pos(op), n.Ntype)
}
return n
}
if receiver != nil {
inLen++
}
- in := make([]ir.Node, 0, inLen)
+ in := make([]*ir.Field, 0, inLen)
if receiver != nil {
d := anonfield(receiver)
for _, t := range f.Params().Fields().Slice() {
d := anonfield(t.Type)
- d.SetIsDDD(t.IsDDD())
+ d.IsDDD = t.IsDDD()
in = append(in, d)
}
outLen := f.Results().Fields().Len()
- out := make([]ir.Node, 0, outLen)
+ out := make([]*ir.Field, 0, outLen)
for _, t := range f.Results().Fields().Slice() {
d := anonfield(t.Type)
out = append(out, d)
// The latter is the type of an auto-generated wrapper.
dtypesym(types.NewPtr(types.Errortype))
- dtypesym(functype(nil, []ir.Node{anonfield(types.Errortype)}, []ir.Node{anonfield(types.Types[types.TSTRING])}))
+ dtypesym(functype(nil, []*ir.Field{anonfield(types.Errortype)}, []*ir.Field{anonfield(types.Types[types.TSTRING])}))
// add paths for runtime and main, which 6l imports implicitly.
dimportpath(Runtimepkg)
// Keep in sync with src/runtime/select.go.
func scasetype() *types.Type {
if scase == nil {
- scase = tostruct([]ir.Node{
+ scase = tostruct([]*ir.Field{
namedfield("c", types.Types[types.TUNSAFEPTR]),
namedfield("elem", types.Types[types.TUNSAFEPTR]),
})
t.AllMethods().Set(ms)
}
-// Given funarg struct list, return list of ODCLFIELD Node fn args.
-func structargs(tl *types.Type, mustname bool) []ir.Node {
- var args []ir.Node
+// Given funarg struct list, return list of fn args.
+func structargs(tl *types.Type, mustname bool) []*ir.Field {
+ var args []*ir.Field
gen := 0
for _, t := range tl.Fields().Slice() {
s := t.Sym
gen++
}
a := symfield(s, t.Type)
- a.SetPos(t.Pos)
- a.SetIsDDD(t.IsDDD())
+ a.Pos = t.Pos
+ a.IsDDD = t.IsDDD()
args = append(args, a)
}
base.Pos = autogeneratedPos
dclcontext = ir.PEXTERN
- tfn := ir.Nod(ir.OTFUNC, nil, nil)
- tfn.SetLeft(namedfield(".this", rcvr))
- tfn.PtrList().Set(structargs(method.Type.Params(), true))
- tfn.PtrRlist().Set(structargs(method.Type.Results(), false))
+ tfn := ir.NewFuncType(base.Pos,
+ namedfield(".this", rcvr),
+ structargs(method.Type.Params(), true),
+ structargs(method.Type.Results(), false))
fn := dclfunc(newnam, tfn)
fn.SetDupok(true)
n := NewName(sym)
setNodeNameFunc(n)
- n.SetType(functype(nil, []ir.Node{
+ n.SetType(functype(nil, []*ir.Field{
anonfield(types.NewPtr(t)),
anonfield(types.Types[types.TUINTPTR]),
anonfield(types.Types[types.TUINTPTR]),
- }, []ir.Node{
+ }, []*ir.Field{
anonfield(types.Types[types.TUINTPTR]),
}))
return n
}
}
+func typecheckNtype(n ir.Ntype) ir.Ntype {
+ return typecheck(n, ctxType).(ir.Ntype)
+}
+
// typecheck type checks node n.
// The result of typecheck MUST be assigned back to n, e.g.
// n.Left = typecheck(n.Left, top)
n.SetType(nil)
return n
- case ir.ODDD:
- break
-
// types (ODEREF is with exprs)
case ir.OTYPE:
ok |= ctxType
return n
}
- case ir.OTARRAY:
+ case ir.OTSLICE:
ok |= ctxType
- r := typecheck(n.Right(), ctxType)
- if r.Type() == nil {
- n.SetType(nil)
+ n := n.(*ir.SliceType)
+ n.Elem = typecheck(n.Elem, ctxType)
+ if n.Elem.Type() == nil {
return n
}
+ t := types.NewSlice(n.Elem.Type())
+ n.SetOTYPE(t)
+ checkwidth(t)
- var t *types.Type
- if n.Left() == nil {
- t = types.NewSlice(r.Type())
- } else if n.Left().Op() == ir.ODDD {
+ case ir.OTARRAY:
+ ok |= ctxType
+ n := n.(*ir.ArrayType)
+ n.Elem = typecheck(n.Elem, ctxType)
+ if n.Elem.Type() == nil {
+ return n
+ }
+ if n.Len == nil { // [...]T
if !n.Diag() {
n.SetDiag(true)
base.Errorf("use of [...] array outside of array literal")
}
- n.SetType(nil)
return n
- } else {
- n.SetLeft(indexlit(typecheck(n.Left(), ctxExpr)))
- l := n.Left()
- if ir.ConstType(l) != constant.Int {
- switch {
- case l.Type() == nil:
- // Error already reported elsewhere.
- case l.Type().IsInteger() && l.Op() != ir.OLITERAL:
- base.Errorf("non-constant array bound %v", l)
- default:
- base.Errorf("invalid array bound %v", l)
- }
- n.SetType(nil)
- return n
- }
-
- v := l.Val()
- if doesoverflow(v, types.Types[types.TINT]) {
- base.Errorf("array bound is too large")
- n.SetType(nil)
- return n
+ }
+ n.Len = indexlit(typecheck(n.Len, ctxExpr))
+ size := n.Len
+ if ir.ConstType(size) != constant.Int {
+ switch {
+ case size.Type() == nil:
+ // Error already reported elsewhere.
+ case size.Type().IsInteger() && size.Op() != ir.OLITERAL:
+ base.Errorf("non-constant array bound %v", size)
+ default:
+ base.Errorf("invalid array bound %v", size)
}
+ return n
+ }
- if constant.Sign(v) < 0 {
- base.Errorf("array bound must be non-negative")
- n.SetType(nil)
- return n
- }
+ v := size.Val()
+ if doesoverflow(v, types.Types[types.TINT]) {
+ base.Errorf("array bound is too large")
+ return n
+ }
- bound, _ := constant.Int64Val(v)
- t = types.NewArray(r.Type(), bound)
+ if constant.Sign(v) < 0 {
+ base.Errorf("array bound must be non-negative")
+ return n
}
- setTypeNode(n, t)
- n.SetLeft(nil)
- n.SetRight(nil)
+ bound, _ := constant.Int64Val(v)
+ t := types.NewArray(n.Elem.Type(), bound)
+ n.SetOTYPE(t)
checkwidth(t)
case ir.OTMAP:
ok |= ctxType
- n.SetLeft(typecheck(n.Left(), ctxType))
- n.SetRight(typecheck(n.Right(), ctxType))
- l := n.Left()
- r := n.Right()
+ n := n.(*ir.MapType)
+ n.Key = typecheck(n.Key, ctxType)
+ n.Elem = typecheck(n.Elem, ctxType)
+ l := n.Key
+ r := n.Elem
if l.Type() == nil || r.Type() == nil {
- n.SetType(nil)
return n
}
if l.Type().NotInHeap() {
if r.Type().NotInHeap() {
base.Errorf("incomplete (or unallocatable) map value not allowed")
}
-
- setTypeNode(n, types.NewMap(l.Type(), r.Type()))
+ n.SetOTYPE(types.NewMap(l.Type(), r.Type()))
mapqueue = append(mapqueue, n) // check map keys when all types are settled
- n.SetLeft(nil)
- n.SetRight(nil)
case ir.OTCHAN:
ok |= ctxType
- n.SetLeft(typecheck(n.Left(), ctxType))
- l := n.Left()
+ n := n.(*ir.ChanType)
+ n.Elem = typecheck(n.Elem, ctxType)
+ l := n.Elem
if l.Type() == nil {
- n.SetType(nil)
return n
}
if l.Type().NotInHeap() {
base.Errorf("chan of incomplete (or unallocatable) type not allowed")
}
-
- setTypeNode(n, types.NewChan(l.Type(), n.TChanDir()))
- n.SetLeft(nil)
- n.ResetAux()
+ n.SetOTYPE(types.NewChan(l.Type(), n.Dir))
case ir.OTSTRUCT:
ok |= ctxType
- setTypeNode(n, tostruct(n.List().Slice()))
- n.PtrList().Set(nil)
+ n := n.(*ir.StructType)
+ n.SetOTYPE(tostruct(n.Fields))
case ir.OTINTER:
ok |= ctxType
- setTypeNode(n, tointerface(n.List().Slice()))
+ n := n.(*ir.InterfaceType)
+ n.SetOTYPE(tointerface(n.Methods))
case ir.OTFUNC:
ok |= ctxType
- setTypeNode(n, functype(n.Left(), n.List().Slice(), n.Rlist().Slice()))
- n.SetLeft(nil)
- n.PtrList().Set(nil)
- n.PtrRlist().Set(nil)
+ n := n.(*ir.FuncType)
+ n.SetOTYPE(functype(n.Recv, n.Params, n.Results))
// type or expr
case ir.ODEREF:
- n.SetLeft(typecheck(n.Left(), ctxExpr|ctxType))
- l := n.Left()
+ n := n.(*ir.StarExpr)
+ n.X = typecheck(n.X, ctxExpr|ctxType)
+ l := n.X
t := l.Type()
if t == nil {
n.SetType(nil)
}
if l.Op() == ir.OTYPE {
ok |= ctxType
- setTypeNode(n, types.NewPtr(l.Type()))
- n.SetLeft(nil)
+ n.SetOTYPE(types.NewPtr(l.Type()))
// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
checkwidth(l.Type())
break
setlineno(n.Right())
// Need to handle [...]T arrays specially.
- if n.Right().Op() == ir.OTARRAY && n.Right().Left() != nil && n.Right().Left().Op() == ir.ODDD {
- n.Right().SetRight(typecheck(n.Right().Right(), ctxType))
- if n.Right().Right().Type() == nil {
+ if array, ok := n.Right().(*ir.ArrayType); ok && array.Elem != nil && array.Len == nil {
+ array.Elem = typecheck(array.Elem, ctxType)
+ elemType := array.Elem.Type()
+ if elemType == nil {
n.SetType(nil)
return n
}
- elemType := n.Right().Right().Type()
-
length := typecheckarraylit(elemType, -1, n.List().Slice(), "array literal")
-
n.SetOp(ir.OARRAYLIT)
n.SetType(types.NewArray(elemType, length))
n.SetRight(nil)
return nn
}
-var mapqueue []ir.Node
+var mapqueue []*ir.MapType
func checkMapKeys() {
for _, n := range mapqueue {
}
n.SetTypecheck(1)
- n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
+ n.Name().Ntype = typecheckNtype(n.Name().Ntype)
t := n.Name().Ntype.Type()
if t == nil {
n.SetDiag(true)
case ir.OLITERAL:
if n.Name().Ntype != nil {
- n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
+ n.Name().Ntype = typecheckNtype(n.Name().Ntype)
n.SetType(n.Name().Ntype.Type())
n.Name().Ntype = nil
if n.Type() == nil {
case ir.ONAME:
if n.Name().Ntype != nil {
- n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
+ n.Name().Ntype = typecheckNtype(n.Name().Ntype)
n.SetType(n.Name().Ntype.Type())
if n.Type() == nil {
n.SetDiag(true)
if n.Alias() {
// Type alias declaration: Simply use the rhs type - no need
// to create a new type.
- // If we have a syntax error, p.Ntype may be nil.
+ // If we have a syntax error, name.Ntype may be nil.
if n.Ntype != nil {
- n.Ntype = typecheck(n.Ntype, ctxType)
+ n.Ntype = typecheckNtype(n.Ntype)
n.SetType(n.Ntype.Type())
if n.Type() == nil {
n.SetDiag(true)
// regular type declaration
defercheckwidth()
n.SetWalkdef(1)
- setTypeNode(n, types.New(types.TFORW))
- n.Type().Sym = n.Sym()
+ t := types.New(types.TFORW)
+ t.Nod = n
+ t.Sym = n.Sym()
+ n.SetType(t)
errorsBefore := base.Errors()
typecheckdeftype(n)
if n.Type().Etype == types.TFORW && base.Errors() > errorsBefore {
return n
}
-// setTypeNode sets n to an OTYPE node representing t.
-func setTypeNode(n ir.Node, t *types.Type) {
- n.SetOp(ir.OTYPE)
+func toTypeNode(orig ir.Node, t *types.Type) ir.Node {
+ n := ir.Nod(ir.OTYPE, nil, nil)
+ n.SetPos(orig.Pos())
n.SetType(t)
- n.Type().Nod = n
+ t.Nod = n
+ return n
}
// getIotaValue returns the current value for "iota",
t := types.New(types.TUNSAFEPTR)
types.Types[types.TUNSAFEPTR] = t
t.Sym = unsafepkg.Lookup("Pointer")
- t.Sym.Def = ir.TypeNode(t)
+ n := ir.NewNameAt(src.NoXPos, t.Sym) // NewNameAt to get a package for use tracking
+ n.SetOp(ir.OTYPE)
+ n.SetType(t)
+ t.Sym.Def = n
dowidth(types.Types[types.TUNSAFEPTR])
for et := types.TINT8; et <= types.TUINT64; et++ {
}
value = ir.Nod(ir.OINDEX, staticuint64s, index)
value.SetBounded(true)
- case n.Left().Class() == ir.PEXTERN && n.Left().Name() != nil && n.Left().Name().Readonly():
+ case n.Left().Name() != nil && n.Left().Class() == ir.PEXTERN && n.Left().Name().Readonly():
// n.Left is a readonly global; use it directly.
value = n.Left()
case !fromType.IsInterface() && n.Esc() == EscNone && fromType.Width <= 1024:
sym := typesymprefix(".eq", t)
n := NewName(sym)
setNodeNameFunc(n)
- n.SetType(functype(nil, []ir.Node{
+ n.SetType(functype(nil, []*ir.Field{
anonfield(types.NewPtr(t)),
anonfield(types.NewPtr(t)),
- }, []ir.Node{
+ }, []*ir.Field{
anonfield(types.Types[types.TBOOL]),
}))
return n, false
// origArgs keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion.
origArgs := make([]ir.Node, n.List().Len())
- t := ir.Nod(ir.OTFUNC, nil, nil)
+ var funcArgs []*ir.Field
for i, arg := range n.List().Slice() {
s := lookupN("a", i)
if !isBuiltinCall && arg.Op() == ir.OCONVNOP && arg.Type().IsUintptr() && arg.Left().Type().IsUnsafePtr() {
arg = arg.Left()
n.List().SetIndex(i, arg)
}
- t.PtrList().Append(symfield(s, arg.Type()))
+ funcArgs = append(funcArgs, symfield(s, arg.Type()))
}
+ t := ir.NewFuncType(base.Pos, nil, funcArgs, nil)
wrapCall_prgen++
sym := lookupN("wrap·", wrapCall_prgen)
func (n *CallPartExpr) Right() Node { return n.Method }
func (n *CallPartExpr) SetLeft(x Node) { n.X = x }
func (n *CallPartExpr) SetRight(x Node) { n.Method = x.(*Name) }
+
+// A StarExpr is a dereference expression *X.
+// It may end up being a value or a type.
+type StarExpr struct {
+ miniExpr
+ X Node
+}
+
+func NewStarExpr(pos src.XPos, x Node) *StarExpr {
+ n := &StarExpr{X: x}
+ n.op = ODEREF
+ n.pos = pos
+ return n
+}
+
+func (n *StarExpr) String() string { return fmt.Sprint(n) }
+func (n *StarExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *StarExpr) RawCopy() Node { c := *n; return &c }
+func (n *StarExpr) Left() Node { return n.X }
+func (n *StarExpr) SetLeft(x Node) { n.X = x }
+
+func (*StarExpr) CanBeNtype() {}
+
+// SetOTYPE changes n to be an OTYPE node returning t,
+// like all the type nodes in type.go.
+func (n *StarExpr) SetOTYPE(t *types.Type) {
+ n.op = OTYPE
+ n.X = nil
+ n.typ = t
+ if t.Nod == nil {
+ t.Nod = n
+ }
+}
+
+func (n *StarExpr) DeepCopy(pos src.XPos) Node {
+ if n.op == OTYPE {
+ // Can't change types and no node references left.
+ return n
+ }
+ c := SepCopy(n).(*StarExpr)
+ c.pos = n.posOr(pos)
+ c.X = DeepCopy(pos, n.X)
+ return c
+}
fmt.Fprintf(s, " implicit(%v)", n.Implicit())
}
- if n.Embedded() {
- fmt.Fprintf(s, " embedded")
- }
-
if n.Op() == ONAME {
if n.Name().Addrtaken() {
fmt.Fprint(s, " addrtaken")
case ODCL:
mode.Fprintf(s, "var %v %v", n.Left().Sym(), n.Left().Type())
- case ODCLFIELD:
- if n.Sym() != nil {
- mode.Fprintf(s, "%v %v", n.Sym(), n.Left())
- } else {
- mode.Fprintf(s, "%v", n.Left())
- }
-
// Don't export "v = <N>" initializing statements, hope they're always
// preceded by the DCL which will be re-parsed and typechecked to reproduce
// the "v = <N>" again.
OSTR2RUNES: 8,
OSTRUCTLIT: 8,
OTARRAY: 8,
+ OTSLICE: 8,
OTCHAN: 8,
OTFUNC: 8,
OTINTER: 8,
OCASE: -1,
OCONTINUE: -1,
ODCL: -1,
- ODCLFIELD: -1,
ODEFER: -1,
OEMPTY: -1,
OFALL: -1,
}
mode.Fprintf(s, "%v", n.Type())
+ case OTSLICE:
+ n := n.(*SliceType)
+ if n.DDD {
+ mode.Fprintf(s, "...%v", n.Elem)
+ } else {
+ mode.Fprintf(s, "[]%v", n.Elem) // happens before typecheck
+ }
+
case OTARRAY:
- if n.Left() != nil {
- mode.Fprintf(s, "[%v]%v", n.Left(), n.Right())
- return
+ n := n.(*ArrayType)
+ if n.Len == nil {
+ mode.Fprintf(s, "[...]%v", n.Elem)
+ } else {
+ mode.Fprintf(s, "[%v]%v", n.Len, n.Elem)
}
- mode.Fprintf(s, "[]%v", n.Right()) // happens before typecheck
case OTMAP:
- mode.Fprintf(s, "map[%v]%v", n.Left(), n.Right())
+ n := n.(*MapType)
+ mode.Fprintf(s, "map[%v]%v", n.Key, n.Elem)
case OTCHAN:
- switch n.TChanDir() {
+ n := n.(*ChanType)
+ switch n.Dir {
case types.Crecv:
- mode.Fprintf(s, "<-chan %v", n.Left())
+ mode.Fprintf(s, "<-chan %v", n.Elem)
case types.Csend:
- mode.Fprintf(s, "chan<- %v", n.Left())
+ mode.Fprintf(s, "chan<- %v", n.Elem)
default:
- if n.Left() != nil && n.Left().Op() == OTCHAN && n.Left().Sym() == nil && n.Left().TChanDir() == types.Crecv {
- mode.Fprintf(s, "chan (%v)", n.Left())
+ if n.Elem != nil && n.Elem.Op() == OTCHAN && n.Elem.(*ChanType).Dir == types.Crecv {
+ mode.Fprintf(s, "chan (%v)", n.Elem)
} else {
- mode.Fprintf(s, "chan %v", n.Left())
+ mode.Fprintf(s, "chan %v", n.Elem)
}
}
}
exprFmt(n1, s, nprec, mode)
}
- case ODDD:
- mode.Fprintf(s, "...")
default:
mode.Fprintf(s, "<node %v>", n.Op())
}
esc uint16
}
+// posOr returns pos if known, or else n.pos.
+// For use in DeepCopy.
+func (n *miniNode) posOr(pos src.XPos) src.XPos {
+ if pos.IsKnown() {
+ return pos
+ }
+ return n.pos
+}
+
// op can be read, but not written.
// An embedding implementation can provide a SetOp if desired.
// (The panicking SetOp is with the other panics below.)
Vargen int32
Decldepth int32 // declaration loop depth, increased for every loop or label
- Ntype Node
+ Ntype Ntype
Heapaddr *Name // temp holding heap address of param
// ONAME PAUTOHEAP
func (n *Name) Iota() int64 { return n.offset }
func (n *Name) SetIota(x int64) { n.offset = x }
+func (*Name) CanBeNtype() {}
+
func (n *Name) SetOp(op Op) {
switch op {
default:
func (p *PkgName) RawCopy() Node { c := *p; return &c }
func (p *PkgName) Sym() *types.Sym { return p.sym }
+func (*PkgName) CanBeNtype() {}
+
func NewPkgName(pos src.XPos, sym *types.Sym, pkg *types.Pkg) *PkgName {
p := &PkgName{sym: sym, Pkg: pkg}
p.op = OPACK
SetImplicit(x bool)
IsDDD() bool
SetIsDDD(x bool)
- Embedded() bool
- SetEmbedded(x bool)
IndexMapLValue() bool
SetIndexMapLValue(x bool)
- TChanDir() types.ChanDir
- SetTChanDir(x types.ChanDir)
ResetAux()
HasBreak() bool
SetHasBreak(x bool)
func (n *node) BoolVal() bool { panic("node.BoolVal") }
func (n *node) StringVal() string { panic("node.StringVal") }
+// node can be Ntype only because of OXDOT of undefined name.
+// When that moves into its own syntax, can drop this.
+func (n *node) CanBeNtype() {}
+
func (n *node) SetOp(op Op) {
if !okForNod[op] {
panic("cannot node.SetOp " + op.String())
}
}
-func (n *node) TChanDir() types.ChanDir {
- if n.Op() != OTCHAN {
- base.Fatalf("unexpected op: %v", n.Op())
- }
- return types.ChanDir(n.aux)
-}
-
-func (n *node) SetTChanDir(dir types.ChanDir) {
- if n.Op() != OTCHAN {
- base.Fatalf("unexpected op: %v", n.Op())
- }
- n.aux = uint8(dir)
-}
-
func IsSynthetic(n Node) bool {
name := n.Sym().Name
return name[0] == '.' || name[0] == '~'
_, nodeBounded // bounds check unnecessary
_, nodeHasCall // expression contains a function call
_, nodeLikely // if statement condition likely
- _, nodeEmbedded // ODCLFIELD embedded type
)
func (n *node) Class() Class { return Class(n.flags.get3(nodeClass)) }
func (n *node) Bounded() bool { return n.flags&nodeBounded != 0 }
func (n *node) HasCall() bool { return n.flags&nodeHasCall != 0 }
func (n *node) Likely() bool { return n.flags&nodeLikely != 0 }
-func (n *node) Embedded() bool { return n.flags&nodeEmbedded != 0 }
func (n *node) SetClass(b Class) { n.flags.set3(nodeClass, uint8(b)) }
func (n *node) SetWalkdef(b uint8) { n.flags.set2(nodeWalkdef, b) }
func (n *node) SetTransient(b bool) { n.flags.set(nodeTransient, b) }
func (n *node) SetHasCall(b bool) { n.flags.set(nodeHasCall, b) }
func (n *node) SetLikely(b bool) { n.flags.set(nodeLikely, b) }
-func (n *node) SetEmbedded(b bool) { n.flags.set(nodeEmbedded, b) }
// MarkNonNil marks a pointer n as being guaranteed non-nil,
// on all code paths, at all times.
// Used during parsing but don't last.
ODCLFUNC // func f() or func (r) f()
- ODCLFIELD // struct field, interface field, or func/method argument/return value.
+ ODCLFIELD // UNUSED: TODO(rsc): Delete.
ODCLCONST // const pi = 3.14
ODCLTYPE // type Int int or type Int = int
// OTFUNC: func() - Left is receiver field, List is list of param fields, Rlist is
// list of result fields.
OTFUNC
- OTARRAY // []int, [8]int, [N]int or [...]int
- OTSLICE // to be used in future CL
+ OTARRAY // [8]int or [...]int
+ OTSLICE // []int
// misc
- ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
+ ODDD // UNUSED; TODO(rsc): Delete.
OINLCALL // intermediary representation of an inlined call.
OEFACE // itable and data words of an empty-interface value.
OITAB // itable word of an interface value.
switch op {
case ODCLFUNC:
return NewFunc(pos)
+ case ODEREF:
+ return NewStarExpr(pos, nleft)
case OPACK:
return NewPkgName(pos, nil, nil)
case OEMPTY:
OCOPY: true,
ODCL: true,
ODCLCONST: true,
- ODCLFIELD: true,
ODCLTYPE: true,
- ODDD: true,
ODEFER: true,
ODELETE: true,
- ODEREF: true,
ODIV: true,
ODOT: true,
ODOTINTER: true,
OSTRUCTLIT: true,
OSUB: true,
OSWITCH: true,
- OTARRAY: true,
- OTCHAN: true,
- OTFUNC: true,
- OTINTER: true,
- OTMAP: true,
- OTSTRUCT: true,
- OTYPE: true, // TODO: Remove once setTypeNode is gone.
OTYPESW: true,
OVARDEF: true,
OVARKILL: true,
import (
"cmd/compile/internal/types"
"cmd/internal/src"
+ "fmt"
)
-func TypeNode(t *types.Type) Node {
- return TypeNodeAt(src.NoXPos, t)
+// Nodes that represent the syntax of a type before type-checking.
+// After type-checking, they serve only as shells around a *types.Type.
+// Calling TypeNode converts a *types.Type to a Node shell.
+
+// An Ntype is a Node that syntactically looks like a type.
+// It can be the raw syntax for a type before typechecking,
+// or it can be an OTYPE with Type() set to a *types.Type.
+// Note that syntax doesn't guarantee it's a type: an expression
+// like *fmt is an Ntype (we don't know whether names are types yet),
+// but at least 1+1 is not an Ntype.
+type Ntype interface {
+ Node
+ CanBeNtype()
+}
+
+// A miniType is a minimal type syntax Node implementation,
+// to be embedded as the first field in a larger node implementation.
+type miniType struct {
+ miniNode
+ typ *types.Type
+}
+
+func (*miniType) CanBeNtype() {}
+
+func (n *miniType) Type() *types.Type { return n.typ }
+
+// setOTYPE changes n to be an OTYPE node returning t.
+// Rewriting the node in place this way should not be strictly
+// necessary (we should be able to update the uses with
+// proper OTYPE nodes), but it's mostly harmless and easy
+// to keep doing for now.
+//
+// setOTYPE also records t.Nod = self if t.Nod is not already set.
+// (Some types are shared by multiple OTYPE nodes, so only
+// the first such node is used as t.Nod.)
+func (n *miniType) setOTYPE(t *types.Type, self Node) {
+ if n.typ != nil {
+ panic(n.op.String() + " SetType: type already set")
+ }
+ n.op = OTYPE
+ n.typ = t
+
+ // t.Nod can be non-nil already
+ // in the case of shared *type.Types, like []byte or interface{}.
+ if t.Nod == nil {
+ t.Nod = self
+ }
+}
+
+func (n *miniType) Sym() *types.Sym { return nil } // for Format OTYPE
+func (n *miniType) Implicit() bool { return false } // for Format OTYPE
+
+// A ChanType represents a chan Elem syntax with the direction Dir.
+type ChanType struct {
+ miniType
+ Elem Node
+ Dir types.ChanDir
+}
+
+func NewChanType(pos src.XPos, elem Node, dir types.ChanDir) *ChanType {
+ n := &ChanType{Elem: elem, Dir: dir}
+ n.op = OTCHAN
+ n.pos = pos
+ return n
}
-func TypeNodeAt(pos src.XPos, t *types.Type) 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 = NodAt(pos, OTYPE, nil, nil)
- AsNode(t.Nod).SetType(t)
- AsNode(t.Nod).SetSym(t.Sym)
+func (n *ChanType) String() string { return fmt.Sprint(n) }
+func (n *ChanType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *ChanType) RawCopy() Node { c := *n; return &c }
+func (n *ChanType) SetOTYPE(t *types.Type) {
+ n.setOTYPE(t, n)
+ n.Elem = nil
+}
+
+func (n *ChanType) DeepCopy(pos src.XPos) Node {
+ if n.op == OTYPE {
+ // Can't change types and no node references left.
+ return n
}
+ return NewChanType(n.posOr(pos), DeepCopy(pos, n.Elem), n.Dir)
+}
+
+// A MapType represents a map[Key]Value type syntax.u
+type MapType struct {
+ miniType
+ Key Node
+ Elem Node
+}
+
+func NewMapType(pos src.XPos, key, elem Node) *MapType {
+ n := &MapType{Key: key, Elem: elem}
+ n.op = OTMAP
+ n.pos = pos
+ return n
+}
+
+func (n *MapType) String() string { return fmt.Sprint(n) }
+func (n *MapType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *MapType) RawCopy() Node { c := *n; return &c }
+func (n *MapType) SetOTYPE(t *types.Type) {
+ n.setOTYPE(t, n)
+ n.Key = nil
+ n.Elem = nil
+}
+
+func (n *MapType) DeepCopy(pos src.XPos) Node {
+ if n.op == OTYPE {
+ // Can't change types and no node references left.
+ return n
+ }
+ return NewMapType(n.posOr(pos), DeepCopy(pos, n.Key), DeepCopy(pos, n.Elem))
+}
+
+// A StructType represents a struct { ... } type syntax.
+type StructType struct {
+ miniType
+ Fields []*Field
+}
+
+func NewStructType(pos src.XPos, fields []*Field) *StructType {
+ n := &StructType{Fields: fields}
+ n.op = OTSTRUCT
+ n.pos = pos
+ return n
+}
+
+func (n *StructType) String() string { return fmt.Sprint(n) }
+func (n *StructType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *StructType) RawCopy() Node { c := *n; return &c }
+func (n *StructType) SetOTYPE(t *types.Type) {
+ n.setOTYPE(t, n)
+ n.Fields = nil
+}
+
+func (n *StructType) DeepCopy(pos src.XPos) Node {
+ if n.op == OTYPE {
+ // Can't change types and no node references left.
+ return n
+ }
+ return NewStructType(n.posOr(pos), deepCopyFields(pos, n.Fields))
+}
+
+func deepCopyFields(pos src.XPos, fields []*Field) []*Field {
+ var out []*Field
+ for _, f := range fields {
+ out = append(out, f.deepCopy(pos))
+ }
+ return out
+}
+
+// An InterfaceType represents a struct { ... } type syntax.
+type InterfaceType struct {
+ miniType
+ Methods []*Field
+}
+
+func NewInterfaceType(pos src.XPos, methods []*Field) *InterfaceType {
+ n := &InterfaceType{Methods: methods}
+ n.op = OTINTER
+ n.pos = pos
+ return n
+}
+
+func (n *InterfaceType) String() string { return fmt.Sprint(n) }
+func (n *InterfaceType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *InterfaceType) RawCopy() Node { c := *n; return &c }
+func (n *InterfaceType) SetOTYPE(t *types.Type) {
+ n.setOTYPE(t, n)
+ n.Methods = nil
+}
+
+func (n *InterfaceType) DeepCopy(pos src.XPos) Node {
+ if n.op == OTYPE {
+ // Can't change types and no node references left.
+ return n
+ }
+ return NewInterfaceType(n.posOr(pos), deepCopyFields(pos, n.Methods))
+}
+
+// A FuncType represents a func(Args) Results type syntax.
+type FuncType struct {
+ miniType
+ Recv *Field
+ Params []*Field
+ Results []*Field
+}
- return AsNode(t.Nod)
+func NewFuncType(pos src.XPos, rcvr *Field, args, results []*Field) *FuncType {
+ n := &FuncType{Recv: rcvr, Params: args, Results: results}
+ n.op = OTFUNC
+ n.pos = pos
+ return n
+}
+
+func (n *FuncType) String() string { return fmt.Sprint(n) }
+func (n *FuncType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *FuncType) RawCopy() Node { c := *n; return &c }
+
+func (n *FuncType) SetOTYPE(t *types.Type) {
+ n.setOTYPE(t, n)
+ n.Recv = nil
+ n.Params = nil
+ n.Results = nil
+}
+
+func (n *FuncType) DeepCopy(pos src.XPos) Node {
+ if n.op == OTYPE {
+ // Can't change types and no node references left.
+ return n
+ }
+ return NewFuncType(n.posOr(pos),
+ n.Recv.deepCopy(pos),
+ deepCopyFields(pos, n.Params),
+ deepCopyFields(pos, n.Results))
+}
+
+// A Field is a declared struct field, interface method, or function argument.
+// It is not a Node.
+type Field struct {
+ Pos src.XPos
+ Sym *types.Sym
+ Ntype Ntype
+ Type *types.Type
+ Embedded bool
+ IsDDD bool
+ Note string
+ Decl *Name
+}
+
+func NewField(pos src.XPos, sym *types.Sym, ntyp Ntype, typ *types.Type) *Field {
+ return &Field{Pos: pos, Sym: sym, Ntype: ntyp, Type: typ}
+}
+
+func (f *Field) String() string {
+ var typ string
+ if f.Type != nil {
+ typ = fmt.Sprint(f.Type)
+ } else {
+ typ = fmt.Sprint(f.Ntype)
+ }
+ if f.Sym != nil {
+ return fmt.Sprintf("%v %v", f.Sym, typ)
+ }
+ return typ
+}
+
+func (f *Field) deepCopy(pos src.XPos) *Field {
+ if f == nil {
+ return nil
+ }
+ fpos := pos
+ if !pos.IsKnown() {
+ fpos = f.Pos
+ }
+ decl := f.Decl
+ if decl != nil {
+ decl = DeepCopy(pos, decl).(*Name)
+ }
+ ntype := f.Ntype
+ if ntype != nil {
+ ntype = DeepCopy(pos, ntype).(Ntype)
+ }
+ // No keyed literal here: if a new struct field is added, we want this to stop compiling.
+ return &Field{fpos, f.Sym, ntype, f.Type, f.Embedded, f.IsDDD, f.Note, decl}
+}
+
+// A SliceType represents a []Elem type syntax.
+// If DDD is true, it's the ...Elem at the end of a function list.
+type SliceType struct {
+ miniType
+ Elem Node
+ DDD bool
+}
+
+func NewSliceType(pos src.XPos, elem Node) *SliceType {
+ n := &SliceType{Elem: elem}
+ n.op = OTSLICE
+ n.pos = pos
+ return n
+}
+
+func (n *SliceType) String() string { return fmt.Sprint(n) }
+func (n *SliceType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *SliceType) RawCopy() Node { c := *n; return &c }
+func (n *SliceType) SetOTYPE(t *types.Type) {
+ n.setOTYPE(t, n)
+ n.Elem = nil
+}
+
+func (n *SliceType) DeepCopy(pos src.XPos) Node {
+ if n.op == OTYPE {
+ // Can't change types and no node references left.
+ return n
+ }
+ return NewSliceType(n.posOr(pos), DeepCopy(pos, n.Elem))
+}
+
+// An ArrayType represents a [Len]Elem type syntax.
+// If Len is nil, the type is a [...]Elem in an array literal.
+type ArrayType struct {
+ miniType
+ Len Node
+ Elem Node
+}
+
+func NewArrayType(pos src.XPos, size Node, elem Node) *ArrayType {
+ n := &ArrayType{Len: size, Elem: elem}
+ n.op = OTARRAY
+ n.pos = pos
+ return n
+}
+
+func (n *ArrayType) String() string { return fmt.Sprint(n) }
+func (n *ArrayType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *ArrayType) RawCopy() Node { c := *n; return &c }
+
+func (n *ArrayType) DeepCopy(pos src.XPos) Node {
+ if n.op == OTYPE {
+ // Can't change types and no node references left.
+ return n
+ }
+ return NewArrayType(n.posOr(pos), DeepCopy(pos, n.Len), DeepCopy(pos, n.Elem))
+}
+
+func (n *ArrayType) SetOTYPE(t *types.Type) {
+ n.setOTYPE(t, n)
+ n.Len = nil
+ n.Elem = nil
+}
+
+// A typeNode is a Node wrapper for type t.
+type typeNode struct {
+ miniNode
+ typ *types.Type
+}
+
+func newTypeNode(pos src.XPos, typ *types.Type) *typeNode {
+ n := &typeNode{typ: typ}
+ n.pos = pos
+ n.op = OTYPE
+ return n
+}
+
+func (n *typeNode) String() string { return fmt.Sprint(n) }
+func (n *typeNode) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *typeNode) RawCopy() Node { c := *n; return &c }
+func (n *typeNode) Type() *types.Type { return n.typ }
+func (n *typeNode) Sym() *types.Sym { return n.typ.Sym }
+func (n *typeNode) CanBeNtype() {}
+
+// TypeNode returns the Node representing the type t.
+func TypeNode(t *types.Type) Ntype {
+ return TypeNodeAt(src.NoXPos, t)
+}
+
+// TypeNodeAt returns the Node representing the type t.
+// If the node must be created, TypeNodeAt uses the position pos.
+// TODO(rsc): Does anyone actually use position on these type nodes?
+func TypeNodeAt(pos src.XPos, t *types.Type) Ntype {
+ // If we copied another type with *t = *u,
+ // then t.Nod might be out of date, so check t.Nod.Type() too.
+ n := AsNode(t.Nod)
+ if n == nil || n.Type() != t {
+ n := newTypeNode(pos, t) // t.Sym may be nil
+ t.Nod = n
+ return n
+ }
+ return n.(Ntype)
}