1
0
mirror of https://github.com/golang/go synced 2024-11-11 19:51:37 -07:00

[dev.regabi] cmd/compile: add custom type syntax Node implementations

The type syntax is reused to stand in for the actual type once typechecked,
to avoid updating all the possible references to the original type syntax.
So all these implementations allow changing their Op from the raw syntax
like OTMAP to the finished form OTYPE, even though obviously the
representation does not change.

Passes buildall w/ toolstash -cmp.

Change-Id: I4acca1a5b35fa2f48ee08e8f1e5a330a004c284b
Reviewed-on: https://go-review.googlesource.com/c/go/+/274103
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Russ Cox 2020-11-26 07:02:13 -05:00
parent d40869fced
commit 4e7685ef1a
23 changed files with 790 additions and 430 deletions

View File

@ -95,6 +95,7 @@ var knownFormats = map[string]string{
"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": "",

View File

@ -292,12 +292,12 @@ func genhash(t *types.Type) *obj.LSym {
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)
@ -432,10 +432,10 @@ func hashfor(t *types.Type) ir.Node {
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
@ -521,12 +521,9 @@ func geneq(t *types.Type) *obj.LSym {
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)

View File

@ -210,132 +210,132 @@ func runtimeTypes() []*types.Type {
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[:]
}

View File

@ -363,7 +363,7 @@ func closureType(clo ir.Node) *types.Type {
// 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 {
@ -456,9 +456,9 @@ func makepartialcall(dot ir.Node, t0 *types.Type, meth *types.Sym) *ir.Func {
// 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)
@ -510,7 +510,7 @@ func makepartialcall(dot ir.Node, t0 *types.Type, meth *types.Sym) *ir.Func {
// 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()),
})

View File

@ -134,7 +134,7 @@ func addvar(n *ir.Name, t *types.Type, ctxt ir.Class) {
// 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
@ -221,18 +221,16 @@ func dclname(s *types.Sym) *ir.Name {
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.
@ -279,7 +277,8 @@ func oldname(s *types.Sym) ir.Node {
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 {
@ -348,12 +347,12 @@ func colasdefn(left []ir.Node, defn ir.Node) {
// 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")
}
}
@ -371,13 +370,13 @@ func funchdr(fn *ir.Func) {
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())
}
@ -389,13 +388,13 @@ func funcargs(nt ir.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 = 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)
}
@ -403,21 +402,21 @@ func funcargs(nt ir.Node) {
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++
}
@ -427,22 +426,19 @@ func funcargs(nt ir.Node) {
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.
@ -514,28 +510,22 @@ func checkembeddedtype(t *types.Type) {
}
}
func structfield(n ir.Node) *types.Field {
func structfield(n *ir.Field) *types.Field {
lno := base.Pos
base.Pos = n.Pos()
base.Pos = n.Pos
if n.Op() != ir.ODCLFIELD {
base.Fatalf("structfield: oops %v\n", n)
if n.Ntype != nil {
n.Ntype = typecheckNtype(n.Ntype)
n.Type = n.Ntype.Type()
n.Ntype = nil
}
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())
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
@ -561,7 +551,7 @@ func checkdupfields(what string, fss ...[]*types.Field) {
// 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))
@ -583,17 +573,17 @@ func tostruct(l []ir.Node) *types.Type {
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)
@ -611,15 +601,11 @@ func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
return t
}
func interfacefield(n ir.Node) *types.Field {
func interfacefield(n *ir.Field) *types.Field {
lno := base.Pos
base.Pos = n.Pos()
base.Pos = n.Pos
if n.Op() != ir.ODCLFIELD {
base.Fatalf("interfacefield: oops %v\n", n)
}
if n.Opt() != nil {
if n.Note != "" {
base.Errorf("interface method cannot have annotation")
}
@ -628,19 +614,19 @@ func interfacefield(n ir.Node) *types.Field {
// 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]
}
@ -657,7 +643,7 @@ func tointerface(l []ir.Node) *types.Type {
return t
}
func fakeRecv() ir.Node {
func fakeRecv() *ir.Field {
return anonfield(types.FakeRecvType())
}
@ -673,12 +659,12 @@ func isifacemethod(f *types.Type) bool {
}
// 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)
@ -923,7 +909,7 @@ func setNodeNameFunc(n ir.Node) {
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)
}
@ -934,7 +920,7 @@ func dclfunc(sym *types.Sym, tfn ir.Node) *ir.Func {
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
}

View File

@ -28,7 +28,7 @@ const (
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)
@ -141,8 +141,10 @@ func embedKindApprox(typ ir.Node) int {
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
}

View File

@ -1056,9 +1056,6 @@ func (w *exportWriter) stmt(n ir.Node) {
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

View File

@ -974,9 +974,6 @@ func (r *importReader) node() ir.Node {
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

View File

@ -48,7 +48,7 @@ func fninit(n []ir.Node) {
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
}

View File

@ -207,7 +207,7 @@ func (i *typeInterner) fields(fl *ast.FieldList, keepNames bool) string {
}
}
}
return fmt.Sprintf("[]ir.Node{%s}", strings.Join(res, ", "))
return fmt.Sprintf("[]*ir.Field{%s}", strings.Join(res, ", "))
}
func intconst(e ast.Expr) int64 {

View File

@ -412,7 +412,7 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []ir.Node {
// 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
}
@ -578,18 +578,18 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node {
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)))
@ -597,17 +597,17 @@ func (p *noder) params(params []*syntax.Field, dddOk bool) []ir.Node {
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).
@ -619,13 +619,8 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) ir.Node {
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
@ -727,14 +722,14 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
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:
@ -742,11 +737,11 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
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))
@ -837,14 +832,21 @@ func (p *noder) sum(x syntax.Expr) ir.Node {
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
}
@ -862,47 +864,43 @@ func (p *noder) chanDir(dir syntax.ChanDir) types.ChanDir {
}
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 {
@ -934,7 +932,7 @@ 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 {
@ -944,11 +942,11 @@ func (p *noder) embedded(typ syntax.Expr) ir.Node {
}
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
}

View File

@ -347,7 +347,7 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
if receiver != nil {
inLen++
}
in := make([]ir.Node, 0, inLen)
in := make([]*ir.Field, 0, inLen)
if receiver != nil {
d := anonfield(receiver)
@ -356,12 +356,12 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
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)
@ -1626,7 +1626,7 @@ func dumpbasictypes() {
// 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)

View File

@ -381,7 +381,7 @@ var scase *types.Type
// 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]),
})

View File

@ -1062,9 +1062,9 @@ func expandmeth(t *types.Type) {
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
@ -1074,8 +1074,8 @@ func structargs(tl *types.Type, mustname bool) []ir.Node {
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)
}
@ -1123,10 +1123,10 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
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)
@ -1215,11 +1215,11 @@ func hashmem(t *types.Type) ir.Node {
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

View File

@ -206,6 +206,10 @@ func typecheckFunc(fn *ir.Func) {
}
}
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)
@ -403,9 +407,6 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
n.SetType(nil)
return n
case ir.ODDD:
break
// types (ODEREF is with exprs)
case ir.OTYPE:
ok |= ctxType
@ -414,70 +415,69 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
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
}
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)
}
v := l.Val()
if doesoverflow(v, types.Types[types.TINT]) {
base.Errorf("array bound is too large")
n.SetType(nil)
return n
}
if constant.Sign(v) < 0 {
base.Errorf("array bound must be non-negative")
n.SetType(nil)
return n
}
bound, _ := constant.Int64Val(v)
t = types.NewArray(r.Type(), bound)
return n
}
setTypeNode(n, t)
n.SetLeft(nil)
n.SetRight(nil)
v := size.Val()
if doesoverflow(v, types.Types[types.TINT]) {
base.Errorf("array bound is too large")
return n
}
if constant.Sign(v) < 0 {
base.Errorf("array bound must be non-negative")
return n
}
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() {
@ -486,48 +486,42 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
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)
@ -535,8 +529,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
}
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
@ -2822,16 +2815,14 @@ func typecheckcomplit(n ir.Node) (res ir.Node) {
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)
@ -3464,7 +3455,7 @@ func stringtoruneslit(n ir.Node) ir.Node {
return nn
}
var mapqueue []ir.Node
var mapqueue []*ir.MapType
func checkMapKeys() {
for _, n := range mapqueue {
@ -3531,7 +3522,7 @@ func typecheckdeftype(n ir.Node) {
}
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)
@ -3593,7 +3584,7 @@ func typecheckdef(n ir.Node) {
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 {
@ -3647,7 +3638,7 @@ func typecheckdef(n ir.Node) {
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)
@ -3686,9 +3677,9 @@ func typecheckdef(n ir.Node) {
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)
@ -3706,8 +3697,10 @@ func typecheckdef(n ir.Node) {
// 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 {
@ -3990,11 +3983,12 @@ func deadcodeexpr(n ir.Node) ir.Node {
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",

View File

@ -176,7 +176,10 @@ func typeinit() {
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++ {

View File

@ -853,7 +853,7 @@ opswitch:
}
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:
@ -3183,10 +3183,10 @@ func eqfor(t *types.Type) (n ir.Node, needsize bool) {
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
@ -3914,7 +3914,7 @@ func wrapCall(n ir.Node, init *ir.Nodes) ir.Node {
// 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() {
@ -3922,8 +3922,9 @@ func wrapCall(n ir.Node, init *ir.Nodes) ir.Node {
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)

View File

@ -110,3 +110,47 @@ func (n *CallPartExpr) Left() Node { return n.X }
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
}

View File

@ -403,10 +403,6 @@ func jconvFmt(n Node, s fmt.State, flag FmtFlag) {
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")
@ -921,13 +917,6 @@ func stmtFmt(n Node, s fmt.State, mode FmtMode) {
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.
@ -1115,6 +1104,7 @@ var OpPrec = []int{
OSTR2RUNES: 8,
OSTRUCTLIT: 8,
OTARRAY: 8,
OTSLICE: 8,
OTCHAN: 8,
OTFUNC: 8,
OTINTER: 8,
@ -1176,7 +1166,6 @@ var OpPrec = []int{
OCASE: -1,
OCONTINUE: -1,
ODCL: -1,
ODCLFIELD: -1,
ODEFER: -1,
OEMPTY: -1,
OFALL: -1,
@ -1294,29 +1283,40 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
}
mode.Fprintf(s, "%v", n.Type())
case OTARRAY:
if n.Left() != nil {
mode.Fprintf(s, "[%v]%v", n.Left(), n.Right())
return
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:
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)
}
}
@ -1556,8 +1556,6 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
}
exprFmt(n1, s, nprec, mode)
}
case ODDD:
mode.Fprintf(s, "...")
default:
mode.Fprintf(s, "<node %v>", n.Op())
}

View File

@ -33,6 +33,15 @@ type miniNode struct {
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.)

View File

@ -43,7 +43,7 @@ type Name struct {
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
@ -160,6 +160,8 @@ func (n *Name) SetOffset(x int64) { n.offset = x }
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:
@ -371,6 +373,8 @@ func (p *PkgName) Format(s fmt.State, verb rune) { FmtNode(p, s, verb) }
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

View File

@ -79,12 +79,8 @@ type Node interface {
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)
@ -205,6 +201,10 @@ func (n *node) Uint64Val() uint64 { panic("node.Uint64Val") }
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())
@ -252,20 +252,6 @@ func (n *node) SetIndexMapLValue(b bool) {
}
}
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] == '~'
@ -301,7 +287,6 @@ const (
_, 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)) }
@ -320,7 +305,6 @@ func (n *node) Transient() bool { return n.flags&nodeTransient != 0 }
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) }
@ -336,7 +320,6 @@ func (n *node) SetColas(b bool) { n.flags.set(nodeColas, 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.
@ -474,7 +457,7 @@ const (
// 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
@ -593,11 +576,11 @@ const (
// 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.
@ -1050,6 +1033,8 @@ func NodAt(pos src.XPos, op Op, nleft, nright Node) Node {
switch op {
case ODCLFUNC:
return NewFunc(pos)
case ODEREF:
return NewStarExpr(pos, nleft)
case OPACK:
return NewPkgName(pos, nil, nil)
case OEMPTY:
@ -1112,12 +1097,9 @@ var okForNod = [OEND]bool{
OCOPY: true,
ODCL: true,
ODCLCONST: true,
ODCLFIELD: true,
ODCLTYPE: true,
ODDD: true,
ODEFER: true,
ODELETE: true,
ODEREF: true,
ODIV: true,
ODOT: true,
ODOTINTER: true,
@ -1201,13 +1183,6 @@ var okForNod = [OEND]bool{
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,

View File

@ -7,21 +7,375 @@ package ir
import (
"cmd/compile/internal/types"
"cmd/internal/src"
"fmt"
)
func TypeNode(t *types.Type) Node {
// 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 (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
}
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)
}
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)
// 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 AsNode(t.Nod)
return n.(Ntype)
}