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:
parent
d40869fced
commit
4e7685ef1a
@ -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": "",
|
||||
|
@ -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)
|
||||
|
@ -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[:]
|
||||
}
|
||||
|
@ -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()),
|
||||
})
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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]),
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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++ {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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.)
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user