mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00: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
23 changed files with 790 additions and 430 deletions
|
|
@ -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.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/ir.Op %v": "",
|
"cmd/compile/internal/ir.Op %v": "",
|
||||||
"cmd/compile/internal/ssa.BranchPrediction %d": "",
|
"cmd/compile/internal/ssa.BranchPrediction %d": "",
|
||||||
|
|
|
||||||
|
|
@ -292,12 +292,12 @@ func genhash(t *types.Type) *obj.LSym {
|
||||||
dclcontext = ir.PEXTERN
|
dclcontext = ir.PEXTERN
|
||||||
|
|
||||||
// func sym(p *T, h uintptr) uintptr
|
// func sym(p *T, h uintptr) uintptr
|
||||||
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
args := []*ir.Field{
|
||||||
tfn.PtrList().Set2(
|
|
||||||
namedfield("p", types.NewPtr(t)),
|
namedfield("p", types.NewPtr(t)),
|
||||||
namedfield("h", types.Types[types.TUINTPTR]),
|
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)
|
fn := dclfunc(sym, tfn)
|
||||||
np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
|
np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
|
||||||
|
|
@ -432,10 +432,10 @@ func hashfor(t *types.Type) ir.Node {
|
||||||
|
|
||||||
n := NewName(sym)
|
n := NewName(sym)
|
||||||
setNodeNameFunc(n)
|
setNodeNameFunc(n)
|
||||||
n.SetType(functype(nil, []ir.Node{
|
n.SetType(functype(nil, []*ir.Field{
|
||||||
anonfield(types.NewPtr(t)),
|
anonfield(types.NewPtr(t)),
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
}, []ir.Node{
|
}, []*ir.Field{
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
}))
|
}))
|
||||||
return n
|
return n
|
||||||
|
|
@ -521,12 +521,9 @@ func geneq(t *types.Type) *obj.LSym {
|
||||||
dclcontext = ir.PEXTERN
|
dclcontext = ir.PEXTERN
|
||||||
|
|
||||||
// func sym(p, q *T) bool
|
// func sym(p, q *T) bool
|
||||||
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
tfn := ir.NewFuncType(base.Pos, nil,
|
||||||
tfn.PtrList().Set2(
|
[]*ir.Field{namedfield("p", types.NewPtr(t)), namedfield("q", types.NewPtr(t))},
|
||||||
namedfield("p", types.NewPtr(t)),
|
[]*ir.Field{namedfield("r", types.Types[types.TBOOL])})
|
||||||
namedfield("q", types.NewPtr(t)),
|
|
||||||
)
|
|
||||||
tfn.PtrRlist().Set1(namedfield("r", types.Types[types.TBOOL]))
|
|
||||||
|
|
||||||
fn := dclfunc(sym, tfn)
|
fn := dclfunc(sym, tfn)
|
||||||
np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
|
np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
|
||||||
|
|
|
||||||
|
|
@ -210,132 +210,132 @@ func runtimeTypes() []*types.Type {
|
||||||
typs[1] = types.NewPtr(typs[0])
|
typs[1] = types.NewPtr(typs[0])
|
||||||
typs[2] = types.Types[types.TANY]
|
typs[2] = types.Types[types.TANY]
|
||||||
typs[3] = types.NewPtr(typs[2])
|
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[5] = types.Types[types.TUINTPTR]
|
||||||
typs[6] = types.Types[types.TBOOL]
|
typs[6] = types.Types[types.TBOOL]
|
||||||
typs[7] = types.Types[types.TUNSAFEPTR]
|
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[9] = functype(nil, nil, nil)
|
||||||
typs[10] = types.Types[types.TINTER]
|
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[12] = types.Types[types.TINT32]
|
||||||
typs[13] = types.NewPtr(typs[12])
|
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[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[17] = types.Types[types.TUINT]
|
||||||
typs[18] = functype(nil, []ir.Node{anonfield(typs[17]), anonfield(typs[15])}, nil)
|
typs[18] = functype(nil, []*ir.Field{anonfield(typs[17]), anonfield(typs[15])}, nil)
|
||||||
typs[19] = functype(nil, []ir.Node{anonfield(typs[6])}, nil)
|
typs[19] = functype(nil, []*ir.Field{anonfield(typs[6])}, nil)
|
||||||
typs[20] = types.Types[types.TFLOAT64]
|
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[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[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[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[28] = types.Types[types.TSTRING]
|
||||||
typs[29] = functype(nil, []ir.Node{anonfield(typs[28])}, nil)
|
typs[29] = functype(nil, []*ir.Field{anonfield(typs[28])}, nil)
|
||||||
typs[30] = functype(nil, []ir.Node{anonfield(typs[2])}, nil)
|
typs[30] = functype(nil, []*ir.Field{anonfield(typs[2])}, nil)
|
||||||
typs[31] = functype(nil, []ir.Node{anonfield(typs[5])}, nil)
|
typs[31] = functype(nil, []*ir.Field{anonfield(typs[5])}, nil)
|
||||||
typs[32] = types.NewArray(typs[0], 32)
|
typs[32] = types.NewArray(typs[0], 32)
|
||||||
typs[33] = types.NewPtr(typs[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[34] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{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[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.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{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.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[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[38] = types.NewSlice(typs[28])
|
||||||
typs[39] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[38])}, []ir.Node{anonfield(typs[28])})
|
typs[39] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[38])}, []*ir.Field{anonfield(typs[28])})
|
||||||
typs[40] = functype(nil, []ir.Node{anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[15])})
|
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[41] = types.NewArray(typs[0], 4)
|
||||||
typs[42] = types.NewPtr(typs[41])
|
typs[42] = types.NewPtr(typs[41])
|
||||||
typs[43] = functype(nil, []ir.Node{anonfield(typs[42]), anonfield(typs[22])}, []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.Node{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []ir.Node{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.Node{anonfield(typs[1]), anonfield(typs[15])}, []ir.Node{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[46] = types.Runetype
|
||||||
typs[47] = types.NewSlice(typs[46])
|
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[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[51] = types.NewArray(typs[46], 32)
|
||||||
typs[52] = types.NewPtr(typs[51])
|
typs[52] = types.NewPtr(typs[51])
|
||||||
typs[53] = functype(nil, []ir.Node{anonfield(typs[52]), anonfield(typs[28])}, []ir.Node{anonfield(typs[47])})
|
typs[53] = functype(nil, []*ir.Field{anonfield(typs[52]), anonfield(typs[28])}, []*ir.Field{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[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.Node{anonfield(typs[28]), anonfield(typs[15])}, []ir.Node{anonfield(typs[46]), 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.Node{anonfield(typs[28])}, []ir.Node{anonfield(typs[15])})
|
typs[56] = functype(nil, []*ir.Field{anonfield(typs[28])}, []*ir.Field{anonfield(typs[15])})
|
||||||
typs[57] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[2])}, []ir.Node{anonfield(typs[2])})
|
typs[57] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[2])})
|
||||||
typs[58] = functype(nil, []ir.Node{anonfield(typs[2])}, []ir.Node{anonfield(typs[7])})
|
typs[58] = functype(nil, []*ir.Field{anonfield(typs[2])}, []*ir.Field{anonfield(typs[7])})
|
||||||
typs[59] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3])}, []ir.Node{anonfield(typs[2])})
|
typs[59] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[2])})
|
||||||
typs[60] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[2])}, []ir.Node{anonfield(typs[2]), anonfield(typs[6])})
|
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.Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
|
typs[61] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
|
||||||
typs[62] = functype(nil, []ir.Node{anonfield(typs[1])}, nil)
|
typs[62] = functype(nil, []*ir.Field{anonfield(typs[1])}, nil)
|
||||||
typs[63] = types.NewPtr(typs[5])
|
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[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[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[68] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[67])})
|
||||||
typs[69] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []ir.Node{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.Node{anonfield(typs[67])})
|
typs[70] = functype(nil, nil, []*ir.Field{anonfield(typs[67])})
|
||||||
typs[71] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []ir.Node{anonfield(typs[3])})
|
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.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []ir.Node{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.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []ir.Node{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.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []ir.Node{anonfield(typs[3]), anonfield(typs[6])})
|
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.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []ir.Node{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.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []ir.Node{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.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
|
typs[77] = functype(nil, []*ir.Field{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[78] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
|
||||||
typs[79] = functype(nil, []ir.Node{anonfield(typs[3])}, nil)
|
typs[79] = functype(nil, []*ir.Field{anonfield(typs[3])}, nil)
|
||||||
typs[80] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67])}, nil)
|
typs[80] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67])}, nil)
|
||||||
typs[81] = types.NewChan(typs[2], types.Cboth)
|
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[82] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[81])})
|
||||||
typs[83] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15])}, []ir.Node{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[84] = types.NewChan(typs[2], types.Crecv)
|
||||||
typs[85] = functype(nil, []ir.Node{anonfield(typs[84]), anonfield(typs[3])}, nil)
|
typs[85] = functype(nil, []*ir.Field{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[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[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[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[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.Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
|
typs[91] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
|
||||||
typs[92] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
|
typs[92] = functype(nil, []*ir.Field{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[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.Node{anonfield(typs[87]), anonfield(typs[3])}, []ir.Node{anonfield(typs[6])})
|
typs[94] = functype(nil, []*ir.Field{anonfield(typs[87]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
|
||||||
typs[95] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[84])}, []ir.Node{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[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[97] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*ir.Field{anonfield(typs[6])})
|
||||||
typs[98] = functype(nil, []ir.Node{anonfield(typs[63])}, nil)
|
typs[98] = functype(nil, []*ir.Field{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[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.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []ir.Node{anonfield(typs[7])})
|
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.Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []ir.Node{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.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []ir.Node{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[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[104] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[103])})
|
||||||
typs[105] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
|
typs[105] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
|
||||||
typs[106] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
|
typs[106] = functype(nil, []*ir.Field{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[107] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[6])})
|
||||||
typs[108] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[3])}, []ir.Node{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.Node{anonfield(typs[7]), anonfield(typs[7])}, []ir.Node{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.Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []ir.Node{anonfield(typs[5])})
|
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.Node{anonfield(typs[7]), anonfield(typs[5])}, []ir.Node{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.Node{anonfield(typs[22]), anonfield(typs[22])}, []ir.Node{anonfield(typs[22])})
|
typs[112] = functype(nil, []*ir.Field{anonfield(typs[22]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[22])})
|
||||||
typs[113] = functype(nil, []ir.Node{anonfield(typs[24]), anonfield(typs[24])}, []ir.Node{anonfield(typs[24])})
|
typs[113] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, []*ir.Field{anonfield(typs[24])})
|
||||||
typs[114] = functype(nil, []ir.Node{anonfield(typs[20])}, []ir.Node{anonfield(typs[22])})
|
typs[114] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[22])})
|
||||||
typs[115] = functype(nil, []ir.Node{anonfield(typs[20])}, []ir.Node{anonfield(typs[24])})
|
typs[115] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[24])})
|
||||||
typs[116] = functype(nil, []ir.Node{anonfield(typs[20])}, []ir.Node{anonfield(typs[65])})
|
typs[116] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[65])})
|
||||||
typs[117] = functype(nil, []ir.Node{anonfield(typs[22])}, []ir.Node{anonfield(typs[20])})
|
typs[117] = functype(nil, []*ir.Field{anonfield(typs[22])}, []*ir.Field{anonfield(typs[20])})
|
||||||
typs[118] = functype(nil, []ir.Node{anonfield(typs[24])}, []ir.Node{anonfield(typs[20])})
|
typs[118] = functype(nil, []*ir.Field{anonfield(typs[24])}, []*ir.Field{anonfield(typs[20])})
|
||||||
typs[119] = functype(nil, []ir.Node{anonfield(typs[65])}, []ir.Node{anonfield(typs[20])})
|
typs[119] = functype(nil, []*ir.Field{anonfield(typs[65])}, []*ir.Field{anonfield(typs[20])})
|
||||||
typs[120] = functype(nil, []ir.Node{anonfield(typs[26]), anonfield(typs[26])}, []ir.Node{anonfield(typs[26])})
|
typs[120] = functype(nil, []*ir.Field{anonfield(typs[26]), anonfield(typs[26])}, []*ir.Field{anonfield(typs[26])})
|
||||||
typs[121] = functype(nil, []ir.Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
|
typs[121] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[5])}, nil)
|
||||||
typs[122] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[1]), 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[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[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[127] = types.Types[types.TUINT16]
|
||||||
typs[128] = functype(nil, []ir.Node{anonfield(typs[127]), anonfield(typs[127])}, nil)
|
typs[128] = functype(nil, []*ir.Field{anonfield(typs[127]), anonfield(typs[127])}, nil)
|
||||||
typs[129] = functype(nil, []ir.Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
|
typs[129] = functype(nil, []*ir.Field{anonfield(typs[65]), anonfield(typs[65])}, nil)
|
||||||
typs[130] = functype(nil, []ir.Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
|
typs[130] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, nil)
|
||||||
return typs[:]
|
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 information appears in the binary in the form of type descriptors;
|
||||||
// the struct is unnamed so that closures in multiple packages with the
|
// the struct is unnamed so that closures in multiple packages with the
|
||||||
// same struct type can share the descriptor.
|
// same struct type can share the descriptor.
|
||||||
fields := []ir.Node{
|
fields := []*ir.Field{
|
||||||
namedfield(".F", types.Types[types.TUINTPTR]),
|
namedfield(".F", types.Types[types.TUINTPTR]),
|
||||||
}
|
}
|
||||||
for _, v := range clo.Func().ClosureVars {
|
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
|
// number at the use of the method expression in this
|
||||||
// case. See issue 29389.
|
// case. See issue 29389.
|
||||||
|
|
||||||
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
tfn := ir.NewFuncType(base.Pos, nil,
|
||||||
tfn.PtrList().Set(structargs(t0.Params(), true))
|
structargs(t0.Params(), true),
|
||||||
tfn.PtrRlist().Set(structargs(t0.Results(), false))
|
structargs(t0.Results(), false))
|
||||||
|
|
||||||
fn := dclfunc(sym, tfn)
|
fn := dclfunc(sym, tfn)
|
||||||
fn.SetDupok(true)
|
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).
|
// 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.
|
// The address of a variable of the returned type can be cast to a func.
|
||||||
func partialCallType(n ir.Node) *types.Type {
|
func partialCallType(n ir.Node) *types.Type {
|
||||||
t := tostruct([]ir.Node{
|
t := tostruct([]*ir.Field{
|
||||||
namedfield("F", types.Types[types.TUINTPTR]),
|
namedfield("F", types.Types[types.TUINTPTR]),
|
||||||
namedfield("R", n.Left().Type()),
|
namedfield("R", n.Left().Type()),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ func addvar(n *ir.Name, t *types.Type, ctxt ir.Class) {
|
||||||
|
|
||||||
// declare variables from grammar
|
// declare variables from grammar
|
||||||
// new_name_list (type | [type] = expr_list)
|
// 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
|
var init []ir.Node
|
||||||
doexpr := len(el) > 0
|
doexpr := len(el) > 0
|
||||||
|
|
||||||
|
|
@ -221,18 +221,16 @@ func dclname(s *types.Sym) *ir.Name {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func anonfield(typ *types.Type) ir.Node {
|
func anonfield(typ *types.Type) *ir.Field {
|
||||||
return symfield(nil, typ)
|
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)
|
return symfield(lookup(s), typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
func symfield(s *types.Sym, typ *types.Type) ir.Node {
|
func symfield(s *types.Sym, typ *types.Type) *ir.Field {
|
||||||
n := nodSym(ir.ODCLFIELD, nil, s)
|
return ir.NewField(base.Pos, s, nil, typ)
|
||||||
n.SetType(typ)
|
|
||||||
return n
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// oldname returns the Node that declares symbol s in the current scope.
|
// 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
|
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 {
|
func importName(sym *types.Sym) ir.Node {
|
||||||
n := oldname(sym)
|
n := oldname(sym)
|
||||||
if !types.IsExported(sym.Name) && sym.Pkg != ir.LocalPkg {
|
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
|
// declare the arguments in an
|
||||||
// interface field declaration.
|
// interface field declaration.
|
||||||
func ifacedcl(n ir.Node) {
|
func ifacedcl(n *ir.Field) {
|
||||||
if n.Op() != ir.ODCLFIELD || n.Left() == nil {
|
if n.Sym == nil {
|
||||||
base.Fatalf("ifacedcl")
|
base.Fatalf("ifacedcl")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Sym().IsBlank() {
|
if n.Sym.IsBlank() {
|
||||||
base.Errorf("methods must have a unique non-blank name")
|
base.Errorf("methods must have a unique non-blank name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -371,13 +370,13 @@ func funchdr(fn *ir.Func) {
|
||||||
types.Markdcl()
|
types.Markdcl()
|
||||||
|
|
||||||
if fn.Nname != nil && fn.Nname.Ntype != nil {
|
if fn.Nname != nil && fn.Nname.Ntype != nil {
|
||||||
funcargs(fn.Nname.Ntype)
|
funcargs(fn.Nname.Ntype.(*ir.FuncType))
|
||||||
} else {
|
} else {
|
||||||
funcargs2(fn.Type())
|
funcargs2(fn.Type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcargs(nt ir.Node) {
|
func funcargs(nt *ir.FuncType) {
|
||||||
if nt.Op() != ir.OTFUNC {
|
if nt.Op() != ir.OTFUNC {
|
||||||
base.Fatalf("funcargs %v", nt.Op())
|
base.Fatalf("funcargs %v", nt.Op())
|
||||||
}
|
}
|
||||||
|
|
@ -389,13 +388,13 @@ func funcargs(nt ir.Node) {
|
||||||
// TODO(mdempsky): This is ugly, and only necessary because
|
// TODO(mdempsky): This is ugly, and only necessary because
|
||||||
// esc.go uses Vargen to figure out result parameters' index
|
// esc.go uses Vargen to figure out result parameters' index
|
||||||
// within the result tuple.
|
// within the result tuple.
|
||||||
vargen = nt.Rlist().Len()
|
vargen = len(nt.Results)
|
||||||
|
|
||||||
// declare the receiver and in arguments.
|
// declare the receiver and in arguments.
|
||||||
if nt.Left() != nil {
|
if nt.Recv != nil {
|
||||||
funcarg(nt.Left(), ir.PPARAM)
|
funcarg(nt.Recv, ir.PPARAM)
|
||||||
}
|
}
|
||||||
for _, n := range nt.List().Slice() {
|
for _, n := range nt.Params {
|
||||||
funcarg(n, ir.PPARAM)
|
funcarg(n, ir.PPARAM)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,21 +402,21 @@ func funcargs(nt ir.Node) {
|
||||||
vargen = 0
|
vargen = 0
|
||||||
|
|
||||||
// declare the out arguments.
|
// declare the out arguments.
|
||||||
gen := nt.List().Len()
|
gen := len(nt.Params)
|
||||||
for _, n := range nt.Rlist().Slice() {
|
for _, n := range nt.Results {
|
||||||
if n.Sym() == nil {
|
if n.Sym == nil {
|
||||||
// Name so that escape analysis can track it. ~r stands for 'result'.
|
// Name so that escape analysis can track it. ~r stands for 'result'.
|
||||||
n.SetSym(lookupN("~r", gen))
|
n.Sym = lookupN("~r", gen)
|
||||||
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'.
|
// 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
|
// The name must be different from ~r above because if you have
|
||||||
// func f() (_ int)
|
// func f() (_ int)
|
||||||
// func g() int
|
// func g() int
|
||||||
// f is allowed to use a plain 'return' with no arguments, while g is not.
|
// f is allowed to use a plain 'return' with no arguments, while g is not.
|
||||||
// So the two cases must be distinguished.
|
// So the two cases must be distinguished.
|
||||||
n.SetSym(lookupN("~b", gen))
|
n.Sym = lookupN("~b", gen)
|
||||||
gen++
|
gen++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -427,22 +426,19 @@ func funcargs(nt ir.Node) {
|
||||||
vargen = oldvargen
|
vargen = oldvargen
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcarg(n ir.Node, ctxt ir.Class) {
|
func funcarg(n *ir.Field, ctxt ir.Class) {
|
||||||
if n.Op() != ir.ODCLFIELD {
|
if n.Sym == nil {
|
||||||
base.Fatalf("funcarg %v", n.Op())
|
|
||||||
}
|
|
||||||
if n.Sym() == nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
name := ir.NewNameAt(n.Pos(), n.Sym())
|
name := ir.NewNameAt(n.Pos, n.Sym)
|
||||||
n.SetRight(name)
|
n.Decl = name
|
||||||
name.Ntype = n.Left()
|
name.Ntype = n.Ntype
|
||||||
name.SetIsDDD(n.IsDDD())
|
name.SetIsDDD(n.IsDDD)
|
||||||
declare(name, ctxt)
|
declare(name, ctxt)
|
||||||
|
|
||||||
vargen++
|
vargen++
|
||||||
n.Right().Name().Vargen = int32(vargen)
|
n.Decl.Name().Vargen = int32(vargen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as funcargs, except run over an already constructed TFUNC.
|
// 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
|
lno := base.Pos
|
||||||
base.Pos = n.Pos()
|
base.Pos = n.Pos
|
||||||
|
|
||||||
if n.Op() != ir.ODCLFIELD {
|
if n.Ntype != nil {
|
||||||
base.Fatalf("structfield: oops %v\n", n)
|
n.Ntype = typecheckNtype(n.Ntype)
|
||||||
|
n.Type = n.Ntype.Type()
|
||||||
|
n.Ntype = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left() != nil {
|
f := types.NewField(n.Pos, n.Sym, n.Type)
|
||||||
n.SetLeft(typecheck(n.Left(), ctxType))
|
if n.Embedded {
|
||||||
n.SetType(n.Left().Type())
|
checkembeddedtype(n.Type)
|
||||||
n.SetLeft(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
f := types.NewField(n.Pos(), n.Sym(), n.Type())
|
|
||||||
if n.Embedded() {
|
|
||||||
checkembeddedtype(n.Type())
|
|
||||||
f.Embedded = 1
|
f.Embedded = 1
|
||||||
}
|
}
|
||||||
if n.Opt() != nil {
|
f.Note = n.Note
|
||||||
f.Note = n.Opt().(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
return f
|
return f
|
||||||
|
|
@ -561,7 +551,7 @@ func checkdupfields(what string, fss ...[]*types.Field) {
|
||||||
|
|
||||||
// convert a parsed id/type list into
|
// convert a parsed id/type list into
|
||||||
// a type for struct/interface/arglist
|
// 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)
|
t := types.New(types.TSTRUCT)
|
||||||
|
|
||||||
fields := make([]*types.Field, len(l))
|
fields := make([]*types.Field, len(l))
|
||||||
|
|
@ -583,17 +573,17 @@ func tostruct(l []ir.Node) *types.Type {
|
||||||
return t
|
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 := types.New(types.TSTRUCT)
|
||||||
t.StructType().Funarg = funarg
|
t.StructType().Funarg = funarg
|
||||||
|
|
||||||
fields := make([]*types.Field, len(l))
|
fields := make([]*types.Field, len(l))
|
||||||
for i, n := range l {
|
for i, n := range l {
|
||||||
f := structfield(n)
|
f := structfield(n)
|
||||||
f.SetIsDDD(n.IsDDD())
|
f.SetIsDDD(n.IsDDD)
|
||||||
if n.Right() != nil {
|
if n.Decl != nil {
|
||||||
n.Right().SetType(f.Type)
|
n.Decl.SetType(f.Type)
|
||||||
f.Nname = n.Right()
|
f.Nname = n.Decl
|
||||||
}
|
}
|
||||||
if f.Broke() {
|
if f.Broke() {
|
||||||
t.SetBroke(true)
|
t.SetBroke(true)
|
||||||
|
|
@ -611,15 +601,11 @@ func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func interfacefield(n ir.Node) *types.Field {
|
func interfacefield(n *ir.Field) *types.Field {
|
||||||
lno := base.Pos
|
lno := base.Pos
|
||||||
base.Pos = n.Pos()
|
base.Pos = n.Pos
|
||||||
|
|
||||||
if n.Op() != ir.ODCLFIELD {
|
if n.Note != "" {
|
||||||
base.Fatalf("interfacefield: oops %v\n", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Opt() != nil {
|
|
||||||
base.Errorf("interface method cannot have annotation")
|
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.
|
// If Sym != nil, then Sym is MethodName and Left is Signature.
|
||||||
// Otherwise, Left is InterfaceTypeName.
|
// Otherwise, Left is InterfaceTypeName.
|
||||||
|
|
||||||
if n.Left() != nil {
|
if n.Ntype != nil {
|
||||||
n.SetLeft(typecheck(n.Left(), ctxType))
|
n.Ntype = typecheckNtype(n.Ntype)
|
||||||
n.SetType(n.Left().Type())
|
n.Type = n.Ntype.Type()
|
||||||
n.SetLeft(nil)
|
n.Ntype = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
f := types.NewField(n.Pos(), n.Sym(), n.Type())
|
f := types.NewField(n.Pos, n.Sym, n.Type)
|
||||||
|
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func tointerface(l []ir.Node) *types.Type {
|
func tointerface(l []*ir.Field) *types.Type {
|
||||||
if len(l) == 0 {
|
if len(l) == 0 {
|
||||||
return types.Types[types.TINTER]
|
return types.Types[types.TINTER]
|
||||||
}
|
}
|
||||||
|
|
@ -657,7 +643,7 @@ func tointerface(l []ir.Node) *types.Type {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func fakeRecv() ir.Node {
|
func fakeRecv() *ir.Field {
|
||||||
return anonfield(types.FakeRecvType())
|
return anonfield(types.FakeRecvType())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -673,12 +659,12 @@ func isifacemethod(f *types.Type) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn a parsed function declaration into a type
|
// 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)
|
t := types.New(types.TFUNC)
|
||||||
|
|
||||||
var rcvr []ir.Node
|
var rcvr []*ir.Field
|
||||||
if this != nil {
|
if this != nil {
|
||||||
rcvr = []ir.Node{this}
|
rcvr = []*ir.Field{this}
|
||||||
}
|
}
|
||||||
t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
|
t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
|
||||||
t.FuncType().Params = tofunargs(in, types.FunargParams)
|
t.FuncType().Params = tofunargs(in, types.FunargParams)
|
||||||
|
|
@ -923,7 +909,7 @@ func setNodeNameFunc(n ir.Node) {
|
||||||
n.Sym().SetFunc(true)
|
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 {
|
if tfn.Op() != ir.OTFUNC {
|
||||||
base.Fatalf("expected OTFUNC node, got %v", tfn)
|
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
|
fn.Nname.Ntype = tfn
|
||||||
setNodeNameFunc(fn.Nname)
|
setNodeNameFunc(fn.Nname)
|
||||||
funchdr(fn)
|
funchdr(fn)
|
||||||
fn.Nname.Ntype = typecheck(fn.Nname.Ntype, ctxType)
|
fn.Nname.Ntype = typecheckNtype(fn.Nname.Ntype)
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const (
|
||||||
|
|
||||||
var numLocalEmbed int
|
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
|
haveEmbed := false
|
||||||
for _, decl := range p.file.DeclList {
|
for _, decl := range p.file.DeclList {
|
||||||
imp, ok := decl.(*syntax.ImportDecl)
|
imp, ok := decl.(*syntax.ImportDecl)
|
||||||
|
|
@ -141,9 +141,11 @@ func embedKindApprox(typ ir.Node) int {
|
||||||
if typ.Sym() != nil && typ.Sym().Name == "string" && typ.Sym().Pkg == ir.LocalPkg {
|
if typ.Sym() != nil && typ.Sym().Name == "string" && typ.Sym().Pkg == ir.LocalPkg {
|
||||||
return embedString
|
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 {
|
if typ, ok := typ.(*ir.SliceType); ok {
|
||||||
|
if sym := typ.Elem.Sym(); sym != nil && sym.Name == "byte" && sym.Pkg == ir.LocalPkg {
|
||||||
return embedBytes
|
return embedBytes
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return embedUnknown
|
return embedUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1056,9 +1056,6 @@ func (w *exportWriter) stmt(n ir.Node) {
|
||||||
w.localName(n.Left())
|
w.localName(n.Left())
|
||||||
w.typ(n.Left().Type())
|
w.typ(n.Left().Type())
|
||||||
|
|
||||||
// case ODCLFIELD:
|
|
||||||
// unimplemented - handled by default case
|
|
||||||
|
|
||||||
case ir.OAS:
|
case ir.OAS:
|
||||||
// Don't export "v = <N>" initializing statements, hope they're always
|
// Don't export "v = <N>" initializing statements, hope they're always
|
||||||
// preceded by the DCL which will be re-parsed and typecheck to reproduce
|
// 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())
|
typ := ir.TypeNode(r.typ())
|
||||||
return npos(pos, liststmt(variter([]ir.Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
|
return npos(pos, liststmt(variter([]ir.Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
|
||||||
|
|
||||||
// case ODCLFIELD:
|
|
||||||
// unimplemented
|
|
||||||
|
|
||||||
// case OAS, OASWB:
|
// case OAS, OASWB:
|
||||||
// unreachable - mapped to OAS case below by exporter
|
// unreachable - mapped to OAS case below by exporter
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ func fninit(n []ir.Node) {
|
||||||
if len(nf) > 0 {
|
if len(nf) > 0 {
|
||||||
base.Pos = nf[0].Pos() // prolog/epilog gets line number of first init stmt
|
base.Pos = nf[0].Pos() // prolog/epilog gets line number of first init stmt
|
||||||
initializers := lookup("init")
|
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 {
|
for _, dcl := range initTodo.Dcl {
|
||||||
dcl.Name().Curfn = fn
|
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 {
|
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).
|
// constant declarations are handled correctly (e.g., issue 15550).
|
||||||
type constState struct {
|
type constState struct {
|
||||||
group *syntax.Group
|
group *syntax.Group
|
||||||
typ ir.Node
|
typ ir.Ntype
|
||||||
values []ir.Node
|
values []ir.Node
|
||||||
iota int64
|
iota int64
|
||||||
}
|
}
|
||||||
|
|
@ -578,18 +578,18 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node {
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) ir.Node {
|
func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *ir.FuncType {
|
||||||
n := p.nod(typ, ir.OTFUNC, nil, nil)
|
var rcvr *ir.Field
|
||||||
if recv != nil {
|
if recv != nil {
|
||||||
n.SetLeft(p.param(recv, false, false))
|
rcvr = p.param(recv, false, false)
|
||||||
}
|
}
|
||||||
n.PtrList().Set(p.params(typ.ParamList, true))
|
return ir.NewFuncType(p.pos(typ), rcvr,
|
||||||
n.PtrRlist().Set(p.params(typ.ResultList, false))
|
p.params(typ.ParamList, true),
|
||||||
return n
|
p.params(typ.ResultList, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) params(params []*syntax.Field, dddOk bool) []ir.Node {
|
func (p *noder) params(params []*syntax.Field, dddOk bool) []*ir.Field {
|
||||||
nodes := make([]ir.Node, 0, len(params))
|
nodes := make([]*ir.Field, 0, len(params))
|
||||||
for i, param := range params {
|
for i, param := range params {
|
||||||
p.setlineno(param)
|
p.setlineno(param)
|
||||||
nodes = append(nodes, p.param(param, dddOk, i+1 == len(params)))
|
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
|
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
|
var name *types.Sym
|
||||||
if param.Name != nil {
|
if param.Name != nil {
|
||||||
name = p.name(param.Name)
|
name = p.name(param.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
typ := p.typeExpr(param.Type)
|
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
|
// rewrite ...T parameter
|
||||||
if typ.Op() == ir.ODDD {
|
if typ, ok := typ.(*ir.SliceType); ok && typ.DDD {
|
||||||
if !dddOk {
|
if !dddOk {
|
||||||
// We mark these as syntax errors to get automatic elimination
|
// We mark these as syntax errors to get automatic elimination
|
||||||
// of multiple such errors per line (see ErrorfAt in subr.go).
|
// 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)
|
p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typ.SetOp(ir.OTARRAY)
|
typ.DDD = false
|
||||||
typ.SetRight(typ.Left())
|
n.IsDDD = true
|
||||||
typ.SetLeft(nil)
|
|
||||||
n.SetIsDDD(true)
|
|
||||||
if n.Left() != nil {
|
|
||||||
n.Left().SetIsDDD(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n
|
return n
|
||||||
|
|
@ -727,14 +722,14 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
|
||||||
var len ir.Node
|
var len ir.Node
|
||||||
if expr.Len != nil {
|
if expr.Len != nil {
|
||||||
len = p.expr(expr.Len)
|
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:
|
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:
|
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:
|
case *syntax.StructType:
|
||||||
return p.structType(expr)
|
return p.structType(expr)
|
||||||
case *syntax.InterfaceType:
|
case *syntax.InterfaceType:
|
||||||
|
|
@ -742,11 +737,11 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
|
||||||
case *syntax.FuncType:
|
case *syntax.FuncType:
|
||||||
return p.signature(nil, expr)
|
return p.signature(nil, expr)
|
||||||
case *syntax.MapType:
|
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:
|
case *syntax.ChanType:
|
||||||
n := p.nod(expr, ir.OTCHAN, p.typeExpr(expr.Elem), nil)
|
return ir.NewChanType(p.pos(expr),
|
||||||
n.SetTChanDir(p.chanDir(expr.Dir))
|
p.typeExpr(expr.Elem), p.chanDir(expr.Dir))
|
||||||
return n
|
|
||||||
|
|
||||||
case *syntax.TypeSwitchGuard:
|
case *syntax.TypeSwitchGuard:
|
||||||
n := p.nod(expr, ir.OTYPESW, nil, p.expr(expr.X))
|
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
|
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.
|
// 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 {
|
if typ != nil {
|
||||||
return p.expr(typ)
|
return p.typeExpr(typ)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -862,47 +864,43 @@ func (p *noder) chanDir(dir syntax.ChanDir) types.ChanDir {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) structType(expr *syntax.StructType) ir.Node {
|
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 {
|
for i, field := range expr.FieldList {
|
||||||
p.setlineno(field)
|
p.setlineno(field)
|
||||||
var n ir.Node
|
var n *ir.Field
|
||||||
if field.Name == nil {
|
if field.Name == nil {
|
||||||
n = p.embedded(field.Type)
|
n = p.embedded(field.Type)
|
||||||
} else {
|
} 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 {
|
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)
|
l = append(l, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setlineno(expr)
|
p.setlineno(expr)
|
||||||
n := p.nod(expr, ir.OTSTRUCT, nil, nil)
|
return ir.NewStructType(p.pos(expr), l)
|
||||||
n.PtrList().Set(l)
|
|
||||||
return n
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) interfaceType(expr *syntax.InterfaceType) ir.Node {
|
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 {
|
for _, method := range expr.MethodList {
|
||||||
p.setlineno(method)
|
p.setlineno(method)
|
||||||
var n ir.Node
|
var n *ir.Field
|
||||||
if method.Name == nil {
|
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 {
|
} else {
|
||||||
mname := p.name(method.Name)
|
mname := p.name(method.Name)
|
||||||
sig := p.typeExpr(method.Type)
|
sig := p.typeExpr(method.Type).(*ir.FuncType)
|
||||||
sig.SetLeft(fakeRecv())
|
sig.Recv = fakeRecv()
|
||||||
n = p.nodSym(method, ir.ODCLFIELD, sig, mname)
|
n = ir.NewField(p.pos(method), mname, sig, nil)
|
||||||
ifacedcl(n)
|
ifacedcl(n)
|
||||||
}
|
}
|
||||||
l = append(l, n)
|
l = append(l, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
n := p.nod(expr, ir.OTINTER, nil, nil)
|
return ir.NewInterfaceType(p.pos(expr), l)
|
||||||
n.PtrList().Set(l)
|
|
||||||
return n
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) packname(expr syntax.Expr) *types.Sym {
|
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))
|
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)
|
op, isStar := typ.(*syntax.Operation)
|
||||||
if isStar {
|
if isStar {
|
||||||
if op.Op != syntax.Mul || op.Y != nil {
|
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)
|
sym := p.packname(typ)
|
||||||
n := p.nodSym(typ, ir.ODCLFIELD, importName(sym), lookup(sym.Name))
|
n := ir.NewField(p.pos(typ), lookup(sym.Name), importName(sym).(ir.Ntype), nil)
|
||||||
n.SetEmbedded(true)
|
n.Embedded = true
|
||||||
|
|
||||||
if isStar {
|
if isStar {
|
||||||
n.SetLeft(p.nod(op, ir.ODEREF, n.Left(), nil))
|
n.Ntype = ir.NewStarExpr(p.pos(op), n.Ntype)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,7 +347,7 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
|
||||||
if receiver != nil {
|
if receiver != nil {
|
||||||
inLen++
|
inLen++
|
||||||
}
|
}
|
||||||
in := make([]ir.Node, 0, inLen)
|
in := make([]*ir.Field, 0, inLen)
|
||||||
|
|
||||||
if receiver != nil {
|
if receiver != nil {
|
||||||
d := anonfield(receiver)
|
d := anonfield(receiver)
|
||||||
|
|
@ -356,12 +356,12 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
|
||||||
|
|
||||||
for _, t := range f.Params().Fields().Slice() {
|
for _, t := range f.Params().Fields().Slice() {
|
||||||
d := anonfield(t.Type)
|
d := anonfield(t.Type)
|
||||||
d.SetIsDDD(t.IsDDD())
|
d.IsDDD = t.IsDDD()
|
||||||
in = append(in, d)
|
in = append(in, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
outLen := f.Results().Fields().Len()
|
outLen := f.Results().Fields().Len()
|
||||||
out := make([]ir.Node, 0, outLen)
|
out := make([]*ir.Field, 0, outLen)
|
||||||
for _, t := range f.Results().Fields().Slice() {
|
for _, t := range f.Results().Fields().Slice() {
|
||||||
d := anonfield(t.Type)
|
d := anonfield(t.Type)
|
||||||
out = append(out, d)
|
out = append(out, d)
|
||||||
|
|
@ -1626,7 +1626,7 @@ func dumpbasictypes() {
|
||||||
// The latter is the type of an auto-generated wrapper.
|
// The latter is the type of an auto-generated wrapper.
|
||||||
dtypesym(types.NewPtr(types.Errortype))
|
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.
|
// add paths for runtime and main, which 6l imports implicitly.
|
||||||
dimportpath(Runtimepkg)
|
dimportpath(Runtimepkg)
|
||||||
|
|
|
||||||
|
|
@ -381,7 +381,7 @@ var scase *types.Type
|
||||||
// Keep in sync with src/runtime/select.go.
|
// Keep in sync with src/runtime/select.go.
|
||||||
func scasetype() *types.Type {
|
func scasetype() *types.Type {
|
||||||
if scase == nil {
|
if scase == nil {
|
||||||
scase = tostruct([]ir.Node{
|
scase = tostruct([]*ir.Field{
|
||||||
namedfield("c", types.Types[types.TUNSAFEPTR]),
|
namedfield("c", types.Types[types.TUNSAFEPTR]),
|
||||||
namedfield("elem", types.Types[types.TUNSAFEPTR]),
|
namedfield("elem", types.Types[types.TUNSAFEPTR]),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1062,9 +1062,9 @@ func expandmeth(t *types.Type) {
|
||||||
t.AllMethods().Set(ms)
|
t.AllMethods().Set(ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given funarg struct list, return list of ODCLFIELD Node fn args.
|
// Given funarg struct list, return list of fn args.
|
||||||
func structargs(tl *types.Type, mustname bool) []ir.Node {
|
func structargs(tl *types.Type, mustname bool) []*ir.Field {
|
||||||
var args []ir.Node
|
var args []*ir.Field
|
||||||
gen := 0
|
gen := 0
|
||||||
for _, t := range tl.Fields().Slice() {
|
for _, t := range tl.Fields().Slice() {
|
||||||
s := t.Sym
|
s := t.Sym
|
||||||
|
|
@ -1074,8 +1074,8 @@ func structargs(tl *types.Type, mustname bool) []ir.Node {
|
||||||
gen++
|
gen++
|
||||||
}
|
}
|
||||||
a := symfield(s, t.Type)
|
a := symfield(s, t.Type)
|
||||||
a.SetPos(t.Pos)
|
a.Pos = t.Pos
|
||||||
a.SetIsDDD(t.IsDDD())
|
a.IsDDD = t.IsDDD()
|
||||||
args = append(args, a)
|
args = append(args, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1123,10 +1123,10 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
|
||||||
base.Pos = autogeneratedPos
|
base.Pos = autogeneratedPos
|
||||||
dclcontext = ir.PEXTERN
|
dclcontext = ir.PEXTERN
|
||||||
|
|
||||||
tfn := ir.Nod(ir.OTFUNC, nil, nil)
|
tfn := ir.NewFuncType(base.Pos,
|
||||||
tfn.SetLeft(namedfield(".this", rcvr))
|
namedfield(".this", rcvr),
|
||||||
tfn.PtrList().Set(structargs(method.Type.Params(), true))
|
structargs(method.Type.Params(), true),
|
||||||
tfn.PtrRlist().Set(structargs(method.Type.Results(), false))
|
structargs(method.Type.Results(), false))
|
||||||
|
|
||||||
fn := dclfunc(newnam, tfn)
|
fn := dclfunc(newnam, tfn)
|
||||||
fn.SetDupok(true)
|
fn.SetDupok(true)
|
||||||
|
|
@ -1215,11 +1215,11 @@ func hashmem(t *types.Type) ir.Node {
|
||||||
|
|
||||||
n := NewName(sym)
|
n := NewName(sym)
|
||||||
setNodeNameFunc(n)
|
setNodeNameFunc(n)
|
||||||
n.SetType(functype(nil, []ir.Node{
|
n.SetType(functype(nil, []*ir.Field{
|
||||||
anonfield(types.NewPtr(t)),
|
anonfield(types.NewPtr(t)),
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
}, []ir.Node{
|
}, []*ir.Field{
|
||||||
anonfield(types.Types[types.TUINTPTR]),
|
anonfield(types.Types[types.TUINTPTR]),
|
||||||
}))
|
}))
|
||||||
return n
|
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.
|
// typecheck type checks node n.
|
||||||
// The result of typecheck MUST be assigned back to n, e.g.
|
// The result of typecheck MUST be assigned back to n, e.g.
|
||||||
// n.Left = typecheck(n.Left, top)
|
// n.Left = typecheck(n.Left, top)
|
||||||
|
|
@ -403,9 +407,6 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
|
||||||
n.SetType(nil)
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.ODDD:
|
|
||||||
break
|
|
||||||
|
|
||||||
// types (ODEREF is with exprs)
|
// types (ODEREF is with exprs)
|
||||||
case ir.OTYPE:
|
case ir.OTYPE:
|
||||||
ok |= ctxType
|
ok |= ctxType
|
||||||
|
|
@ -414,70 +415,69 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OTARRAY:
|
case ir.OTSLICE:
|
||||||
ok |= ctxType
|
ok |= ctxType
|
||||||
r := typecheck(n.Right(), ctxType)
|
n := n.(*ir.SliceType)
|
||||||
if r.Type() == nil {
|
n.Elem = typecheck(n.Elem, ctxType)
|
||||||
n.SetType(nil)
|
if n.Elem.Type() == nil {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
t := types.NewSlice(n.Elem.Type())
|
||||||
|
n.SetOTYPE(t)
|
||||||
|
checkwidth(t)
|
||||||
|
|
||||||
var t *types.Type
|
case ir.OTARRAY:
|
||||||
if n.Left() == nil {
|
ok |= ctxType
|
||||||
t = types.NewSlice(r.Type())
|
n := n.(*ir.ArrayType)
|
||||||
} else if n.Left().Op() == ir.ODDD {
|
n.Elem = typecheck(n.Elem, ctxType)
|
||||||
|
if n.Elem.Type() == nil {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
if n.Len == nil { // [...]T
|
||||||
if !n.Diag() {
|
if !n.Diag() {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
base.Errorf("use of [...] array outside of array literal")
|
base.Errorf("use of [...] array outside of array literal")
|
||||||
}
|
}
|
||||||
n.SetType(nil)
|
|
||||||
return n
|
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)
|
n.Len = indexlit(typecheck(n.Len, ctxExpr))
|
||||||
|
size := n.Len
|
||||||
|
if ir.ConstType(size) != constant.Int {
|
||||||
|
switch {
|
||||||
|
case size.Type() == nil:
|
||||||
|
// Error already reported elsewhere.
|
||||||
|
case size.Type().IsInteger() && size.Op() != ir.OLITERAL:
|
||||||
|
base.Errorf("non-constant array bound %v", size)
|
||||||
|
default:
|
||||||
|
base.Errorf("invalid array bound %v", size)
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
v := l.Val()
|
v := size.Val()
|
||||||
if doesoverflow(v, types.Types[types.TINT]) {
|
if doesoverflow(v, types.Types[types.TINT]) {
|
||||||
base.Errorf("array bound is too large")
|
base.Errorf("array bound is too large")
|
||||||
n.SetType(nil)
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
if constant.Sign(v) < 0 {
|
if constant.Sign(v) < 0 {
|
||||||
base.Errorf("array bound must be non-negative")
|
base.Errorf("array bound must be non-negative")
|
||||||
n.SetType(nil)
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
bound, _ := constant.Int64Val(v)
|
bound, _ := constant.Int64Val(v)
|
||||||
t = types.NewArray(r.Type(), bound)
|
t := types.NewArray(n.Elem.Type(), bound)
|
||||||
}
|
n.SetOTYPE(t)
|
||||||
|
|
||||||
setTypeNode(n, t)
|
|
||||||
n.SetLeft(nil)
|
|
||||||
n.SetRight(nil)
|
|
||||||
checkwidth(t)
|
checkwidth(t)
|
||||||
|
|
||||||
case ir.OTMAP:
|
case ir.OTMAP:
|
||||||
ok |= ctxType
|
ok |= ctxType
|
||||||
n.SetLeft(typecheck(n.Left(), ctxType))
|
n := n.(*ir.MapType)
|
||||||
n.SetRight(typecheck(n.Right(), ctxType))
|
n.Key = typecheck(n.Key, ctxType)
|
||||||
l := n.Left()
|
n.Elem = typecheck(n.Elem, ctxType)
|
||||||
r := n.Right()
|
l := n.Key
|
||||||
|
r := n.Elem
|
||||||
if l.Type() == nil || r.Type() == nil {
|
if l.Type() == nil || r.Type() == nil {
|
||||||
n.SetType(nil)
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if l.Type().NotInHeap() {
|
if l.Type().NotInHeap() {
|
||||||
|
|
@ -486,48 +486,42 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
|
||||||
if r.Type().NotInHeap() {
|
if r.Type().NotInHeap() {
|
||||||
base.Errorf("incomplete (or unallocatable) map value not allowed")
|
base.Errorf("incomplete (or unallocatable) map value not allowed")
|
||||||
}
|
}
|
||||||
|
n.SetOTYPE(types.NewMap(l.Type(), r.Type()))
|
||||||
setTypeNode(n, types.NewMap(l.Type(), r.Type()))
|
|
||||||
mapqueue = append(mapqueue, n) // check map keys when all types are settled
|
mapqueue = append(mapqueue, n) // check map keys when all types are settled
|
||||||
n.SetLeft(nil)
|
|
||||||
n.SetRight(nil)
|
|
||||||
|
|
||||||
case ir.OTCHAN:
|
case ir.OTCHAN:
|
||||||
ok |= ctxType
|
ok |= ctxType
|
||||||
n.SetLeft(typecheck(n.Left(), ctxType))
|
n := n.(*ir.ChanType)
|
||||||
l := n.Left()
|
n.Elem = typecheck(n.Elem, ctxType)
|
||||||
|
l := n.Elem
|
||||||
if l.Type() == nil {
|
if l.Type() == nil {
|
||||||
n.SetType(nil)
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if l.Type().NotInHeap() {
|
if l.Type().NotInHeap() {
|
||||||
base.Errorf("chan of incomplete (or unallocatable) type not allowed")
|
base.Errorf("chan of incomplete (or unallocatable) type not allowed")
|
||||||
}
|
}
|
||||||
|
n.SetOTYPE(types.NewChan(l.Type(), n.Dir))
|
||||||
setTypeNode(n, types.NewChan(l.Type(), n.TChanDir()))
|
|
||||||
n.SetLeft(nil)
|
|
||||||
n.ResetAux()
|
|
||||||
|
|
||||||
case ir.OTSTRUCT:
|
case ir.OTSTRUCT:
|
||||||
ok |= ctxType
|
ok |= ctxType
|
||||||
setTypeNode(n, tostruct(n.List().Slice()))
|
n := n.(*ir.StructType)
|
||||||
n.PtrList().Set(nil)
|
n.SetOTYPE(tostruct(n.Fields))
|
||||||
|
|
||||||
case ir.OTINTER:
|
case ir.OTINTER:
|
||||||
ok |= ctxType
|
ok |= ctxType
|
||||||
setTypeNode(n, tointerface(n.List().Slice()))
|
n := n.(*ir.InterfaceType)
|
||||||
|
n.SetOTYPE(tointerface(n.Methods))
|
||||||
|
|
||||||
case ir.OTFUNC:
|
case ir.OTFUNC:
|
||||||
ok |= ctxType
|
ok |= ctxType
|
||||||
setTypeNode(n, functype(n.Left(), n.List().Slice(), n.Rlist().Slice()))
|
n := n.(*ir.FuncType)
|
||||||
n.SetLeft(nil)
|
n.SetOTYPE(functype(n.Recv, n.Params, n.Results))
|
||||||
n.PtrList().Set(nil)
|
|
||||||
n.PtrRlist().Set(nil)
|
|
||||||
|
|
||||||
// type or expr
|
// type or expr
|
||||||
case ir.ODEREF:
|
case ir.ODEREF:
|
||||||
n.SetLeft(typecheck(n.Left(), ctxExpr|ctxType))
|
n := n.(*ir.StarExpr)
|
||||||
l := n.Left()
|
n.X = typecheck(n.X, ctxExpr|ctxType)
|
||||||
|
l := n.X
|
||||||
t := l.Type()
|
t := l.Type()
|
||||||
if t == nil {
|
if t == nil {
|
||||||
n.SetType(nil)
|
n.SetType(nil)
|
||||||
|
|
@ -535,8 +529,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
|
||||||
}
|
}
|
||||||
if l.Op() == ir.OTYPE {
|
if l.Op() == ir.OTYPE {
|
||||||
ok |= ctxType
|
ok |= ctxType
|
||||||
setTypeNode(n, types.NewPtr(l.Type()))
|
n.SetOTYPE(types.NewPtr(l.Type()))
|
||||||
n.SetLeft(nil)
|
|
||||||
// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
|
// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
|
||||||
checkwidth(l.Type())
|
checkwidth(l.Type())
|
||||||
break
|
break
|
||||||
|
|
@ -2822,16 +2815,14 @@ func typecheckcomplit(n ir.Node) (res ir.Node) {
|
||||||
setlineno(n.Right())
|
setlineno(n.Right())
|
||||||
|
|
||||||
// Need to handle [...]T arrays specially.
|
// Need to handle [...]T arrays specially.
|
||||||
if n.Right().Op() == ir.OTARRAY && n.Right().Left() != nil && n.Right().Left().Op() == ir.ODDD {
|
if array, ok := n.Right().(*ir.ArrayType); ok && array.Elem != nil && array.Len == nil {
|
||||||
n.Right().SetRight(typecheck(n.Right().Right(), ctxType))
|
array.Elem = typecheck(array.Elem, ctxType)
|
||||||
if n.Right().Right().Type() == nil {
|
elemType := array.Elem.Type()
|
||||||
|
if elemType == nil {
|
||||||
n.SetType(nil)
|
n.SetType(nil)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
elemType := n.Right().Right().Type()
|
|
||||||
|
|
||||||
length := typecheckarraylit(elemType, -1, n.List().Slice(), "array literal")
|
length := typecheckarraylit(elemType, -1, n.List().Slice(), "array literal")
|
||||||
|
|
||||||
n.SetOp(ir.OARRAYLIT)
|
n.SetOp(ir.OARRAYLIT)
|
||||||
n.SetType(types.NewArray(elemType, length))
|
n.SetType(types.NewArray(elemType, length))
|
||||||
n.SetRight(nil)
|
n.SetRight(nil)
|
||||||
|
|
@ -3464,7 +3455,7 @@ func stringtoruneslit(n ir.Node) ir.Node {
|
||||||
return nn
|
return nn
|
||||||
}
|
}
|
||||||
|
|
||||||
var mapqueue []ir.Node
|
var mapqueue []*ir.MapType
|
||||||
|
|
||||||
func checkMapKeys() {
|
func checkMapKeys() {
|
||||||
for _, n := range mapqueue {
|
for _, n := range mapqueue {
|
||||||
|
|
@ -3531,7 +3522,7 @@ func typecheckdeftype(n ir.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
n.SetTypecheck(1)
|
n.SetTypecheck(1)
|
||||||
n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
|
n.Name().Ntype = typecheckNtype(n.Name().Ntype)
|
||||||
t := n.Name().Ntype.Type()
|
t := n.Name().Ntype.Type()
|
||||||
if t == nil {
|
if t == nil {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
|
|
@ -3593,7 +3584,7 @@ func typecheckdef(n ir.Node) {
|
||||||
|
|
||||||
case ir.OLITERAL:
|
case ir.OLITERAL:
|
||||||
if n.Name().Ntype != nil {
|
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.SetType(n.Name().Ntype.Type())
|
||||||
n.Name().Ntype = nil
|
n.Name().Ntype = nil
|
||||||
if n.Type() == nil {
|
if n.Type() == nil {
|
||||||
|
|
@ -3647,7 +3638,7 @@ func typecheckdef(n ir.Node) {
|
||||||
|
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
if n.Name().Ntype != nil {
|
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.SetType(n.Name().Ntype.Type())
|
||||||
if n.Type() == nil {
|
if n.Type() == nil {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
|
|
@ -3686,9 +3677,9 @@ func typecheckdef(n ir.Node) {
|
||||||
if n.Alias() {
|
if n.Alias() {
|
||||||
// Type alias declaration: Simply use the rhs type - no need
|
// Type alias declaration: Simply use the rhs type - no need
|
||||||
// to create a new type.
|
// 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 {
|
if n.Ntype != nil {
|
||||||
n.Ntype = typecheck(n.Ntype, ctxType)
|
n.Ntype = typecheckNtype(n.Ntype)
|
||||||
n.SetType(n.Ntype.Type())
|
n.SetType(n.Ntype.Type())
|
||||||
if n.Type() == nil {
|
if n.Type() == nil {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
|
|
@ -3706,8 +3697,10 @@ func typecheckdef(n ir.Node) {
|
||||||
// regular type declaration
|
// regular type declaration
|
||||||
defercheckwidth()
|
defercheckwidth()
|
||||||
n.SetWalkdef(1)
|
n.SetWalkdef(1)
|
||||||
setTypeNode(n, types.New(types.TFORW))
|
t := types.New(types.TFORW)
|
||||||
n.Type().Sym = n.Sym()
|
t.Nod = n
|
||||||
|
t.Sym = n.Sym()
|
||||||
|
n.SetType(t)
|
||||||
errorsBefore := base.Errors()
|
errorsBefore := base.Errors()
|
||||||
typecheckdeftype(n)
|
typecheckdeftype(n)
|
||||||
if n.Type().Etype == types.TFORW && base.Errors() > errorsBefore {
|
if n.Type().Etype == types.TFORW && base.Errors() > errorsBefore {
|
||||||
|
|
@ -3990,11 +3983,12 @@ func deadcodeexpr(n ir.Node) ir.Node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// setTypeNode sets n to an OTYPE node representing t.
|
func toTypeNode(orig ir.Node, t *types.Type) ir.Node {
|
||||||
func setTypeNode(n ir.Node, t *types.Type) {
|
n := ir.Nod(ir.OTYPE, nil, nil)
|
||||||
n.SetOp(ir.OTYPE)
|
n.SetPos(orig.Pos())
|
||||||
n.SetType(t)
|
n.SetType(t)
|
||||||
n.Type().Nod = n
|
t.Nod = n
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// getIotaValue returns the current value for "iota",
|
// getIotaValue returns the current value for "iota",
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,10 @@ func typeinit() {
|
||||||
t := types.New(types.TUNSAFEPTR)
|
t := types.New(types.TUNSAFEPTR)
|
||||||
types.Types[types.TUNSAFEPTR] = t
|
types.Types[types.TUNSAFEPTR] = t
|
||||||
t.Sym = unsafepkg.Lookup("Pointer")
|
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])
|
dowidth(types.Types[types.TUNSAFEPTR])
|
||||||
|
|
||||||
for et := types.TINT8; et <= types.TUINT64; et++ {
|
for et := types.TINT8; et <= types.TUINT64; et++ {
|
||||||
|
|
|
||||||
|
|
@ -853,7 +853,7 @@ opswitch:
|
||||||
}
|
}
|
||||||
value = ir.Nod(ir.OINDEX, staticuint64s, index)
|
value = ir.Nod(ir.OINDEX, staticuint64s, index)
|
||||||
value.SetBounded(true)
|
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.
|
// n.Left is a readonly global; use it directly.
|
||||||
value = n.Left()
|
value = n.Left()
|
||||||
case !fromType.IsInterface() && n.Esc() == EscNone && fromType.Width <= 1024:
|
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)
|
sym := typesymprefix(".eq", t)
|
||||||
n := NewName(sym)
|
n := NewName(sym)
|
||||||
setNodeNameFunc(n)
|
setNodeNameFunc(n)
|
||||||
n.SetType(functype(nil, []ir.Node{
|
n.SetType(functype(nil, []*ir.Field{
|
||||||
anonfield(types.NewPtr(t)),
|
anonfield(types.NewPtr(t)),
|
||||||
anonfield(types.NewPtr(t)),
|
anonfield(types.NewPtr(t)),
|
||||||
}, []ir.Node{
|
}, []*ir.Field{
|
||||||
anonfield(types.Types[types.TBOOL]),
|
anonfield(types.Types[types.TBOOL]),
|
||||||
}))
|
}))
|
||||||
return n, false
|
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 keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion.
|
||||||
origArgs := make([]ir.Node, n.List().Len())
|
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() {
|
for i, arg := range n.List().Slice() {
|
||||||
s := lookupN("a", i)
|
s := lookupN("a", i)
|
||||||
if !isBuiltinCall && arg.Op() == ir.OCONVNOP && arg.Type().IsUintptr() && arg.Left().Type().IsUnsafePtr() {
|
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()
|
arg = arg.Left()
|
||||||
n.List().SetIndex(i, arg)
|
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++
|
wrapCall_prgen++
|
||||||
sym := lookupN("wrap·", 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) Right() Node { return n.Method }
|
||||||
func (n *CallPartExpr) SetLeft(x Node) { n.X = x }
|
func (n *CallPartExpr) SetLeft(x Node) { n.X = x }
|
||||||
func (n *CallPartExpr) SetRight(x Node) { n.Method = x.(*Name) }
|
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())
|
fmt.Fprintf(s, " implicit(%v)", n.Implicit())
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Embedded() {
|
|
||||||
fmt.Fprintf(s, " embedded")
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Op() == ONAME {
|
if n.Op() == ONAME {
|
||||||
if n.Name().Addrtaken() {
|
if n.Name().Addrtaken() {
|
||||||
fmt.Fprint(s, " addrtaken")
|
fmt.Fprint(s, " addrtaken")
|
||||||
|
|
@ -921,13 +917,6 @@ func stmtFmt(n Node, s fmt.State, mode FmtMode) {
|
||||||
case ODCL:
|
case ODCL:
|
||||||
mode.Fprintf(s, "var %v %v", n.Left().Sym(), n.Left().Type())
|
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
|
// Don't export "v = <N>" initializing statements, hope they're always
|
||||||
// preceded by the DCL which will be re-parsed and typechecked to reproduce
|
// preceded by the DCL which will be re-parsed and typechecked to reproduce
|
||||||
// the "v = <N>" again.
|
// the "v = <N>" again.
|
||||||
|
|
@ -1115,6 +1104,7 @@ var OpPrec = []int{
|
||||||
OSTR2RUNES: 8,
|
OSTR2RUNES: 8,
|
||||||
OSTRUCTLIT: 8,
|
OSTRUCTLIT: 8,
|
||||||
OTARRAY: 8,
|
OTARRAY: 8,
|
||||||
|
OTSLICE: 8,
|
||||||
OTCHAN: 8,
|
OTCHAN: 8,
|
||||||
OTFUNC: 8,
|
OTFUNC: 8,
|
||||||
OTINTER: 8,
|
OTINTER: 8,
|
||||||
|
|
@ -1176,7 +1166,6 @@ var OpPrec = []int{
|
||||||
OCASE: -1,
|
OCASE: -1,
|
||||||
OCONTINUE: -1,
|
OCONTINUE: -1,
|
||||||
ODCL: -1,
|
ODCL: -1,
|
||||||
ODCLFIELD: -1,
|
|
||||||
ODEFER: -1,
|
ODEFER: -1,
|
||||||
OEMPTY: -1,
|
OEMPTY: -1,
|
||||||
OFALL: -1,
|
OFALL: -1,
|
||||||
|
|
@ -1294,29 +1283,40 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "%v", n.Type())
|
mode.Fprintf(s, "%v", n.Type())
|
||||||
|
|
||||||
case OTARRAY:
|
case OTSLICE:
|
||||||
if n.Left() != nil {
|
n := n.(*SliceType)
|
||||||
mode.Fprintf(s, "[%v]%v", n.Left(), n.Right())
|
if n.DDD {
|
||||||
return
|
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:
|
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:
|
case OTCHAN:
|
||||||
switch n.TChanDir() {
|
n := n.(*ChanType)
|
||||||
|
switch n.Dir {
|
||||||
case types.Crecv:
|
case types.Crecv:
|
||||||
mode.Fprintf(s, "<-chan %v", n.Left())
|
mode.Fprintf(s, "<-chan %v", n.Elem)
|
||||||
|
|
||||||
case types.Csend:
|
case types.Csend:
|
||||||
mode.Fprintf(s, "chan<- %v", n.Left())
|
mode.Fprintf(s, "chan<- %v", n.Elem)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if n.Left() != nil && n.Left().Op() == OTCHAN && n.Left().Sym() == nil && n.Left().TChanDir() == types.Crecv {
|
if n.Elem != nil && n.Elem.Op() == OTCHAN && n.Elem.(*ChanType).Dir == types.Crecv {
|
||||||
mode.Fprintf(s, "chan (%v)", n.Left())
|
mode.Fprintf(s, "chan (%v)", n.Elem)
|
||||||
} else {
|
} 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)
|
exprFmt(n1, s, nprec, mode)
|
||||||
}
|
}
|
||||||
case ODDD:
|
|
||||||
mode.Fprintf(s, "...")
|
|
||||||
default:
|
default:
|
||||||
mode.Fprintf(s, "<node %v>", n.Op())
|
mode.Fprintf(s, "<node %v>", n.Op())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,15 @@ type miniNode struct {
|
||||||
esc uint16
|
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.
|
// op can be read, but not written.
|
||||||
// An embedding implementation can provide a SetOp if desired.
|
// An embedding implementation can provide a SetOp if desired.
|
||||||
// (The panicking SetOp is with the other panics below.)
|
// (The panicking SetOp is with the other panics below.)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ type Name struct {
|
||||||
Vargen int32
|
Vargen int32
|
||||||
Decldepth int32 // declaration loop depth, increased for every loop or label
|
Decldepth int32 // declaration loop depth, increased for every loop or label
|
||||||
|
|
||||||
Ntype Node
|
Ntype Ntype
|
||||||
Heapaddr *Name // temp holding heap address of param
|
Heapaddr *Name // temp holding heap address of param
|
||||||
|
|
||||||
// ONAME PAUTOHEAP
|
// 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) Iota() int64 { return n.offset }
|
||||||
func (n *Name) SetIota(x int64) { n.offset = x }
|
func (n *Name) SetIota(x int64) { n.offset = x }
|
||||||
|
|
||||||
|
func (*Name) CanBeNtype() {}
|
||||||
|
|
||||||
func (n *Name) SetOp(op Op) {
|
func (n *Name) SetOp(op Op) {
|
||||||
switch op {
|
switch op {
|
||||||
default:
|
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) RawCopy() Node { c := *p; return &c }
|
||||||
func (p *PkgName) Sym() *types.Sym { return p.sym }
|
func (p *PkgName) Sym() *types.Sym { return p.sym }
|
||||||
|
|
||||||
|
func (*PkgName) CanBeNtype() {}
|
||||||
|
|
||||||
func NewPkgName(pos src.XPos, sym *types.Sym, pkg *types.Pkg) *PkgName {
|
func NewPkgName(pos src.XPos, sym *types.Sym, pkg *types.Pkg) *PkgName {
|
||||||
p := &PkgName{sym: sym, Pkg: pkg}
|
p := &PkgName{sym: sym, Pkg: pkg}
|
||||||
p.op = OPACK
|
p.op = OPACK
|
||||||
|
|
|
||||||
|
|
@ -79,12 +79,8 @@ type Node interface {
|
||||||
SetImplicit(x bool)
|
SetImplicit(x bool)
|
||||||
IsDDD() bool
|
IsDDD() bool
|
||||||
SetIsDDD(x bool)
|
SetIsDDD(x bool)
|
||||||
Embedded() bool
|
|
||||||
SetEmbedded(x bool)
|
|
||||||
IndexMapLValue() bool
|
IndexMapLValue() bool
|
||||||
SetIndexMapLValue(x bool)
|
SetIndexMapLValue(x bool)
|
||||||
TChanDir() types.ChanDir
|
|
||||||
SetTChanDir(x types.ChanDir)
|
|
||||||
ResetAux()
|
ResetAux()
|
||||||
HasBreak() bool
|
HasBreak() bool
|
||||||
SetHasBreak(x 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) BoolVal() bool { panic("node.BoolVal") }
|
||||||
func (n *node) StringVal() string { panic("node.StringVal") }
|
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) {
|
func (n *node) SetOp(op Op) {
|
||||||
if !okForNod[op] {
|
if !okForNod[op] {
|
||||||
panic("cannot node.SetOp " + op.String())
|
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 {
|
func IsSynthetic(n Node) bool {
|
||||||
name := n.Sym().Name
|
name := n.Sym().Name
|
||||||
return name[0] == '.' || name[0] == '~'
|
return name[0] == '.' || name[0] == '~'
|
||||||
|
|
@ -301,7 +287,6 @@ const (
|
||||||
_, nodeBounded // bounds check unnecessary
|
_, nodeBounded // bounds check unnecessary
|
||||||
_, nodeHasCall // expression contains a function call
|
_, nodeHasCall // expression contains a function call
|
||||||
_, nodeLikely // if statement condition likely
|
_, nodeLikely // if statement condition likely
|
||||||
_, nodeEmbedded // ODCLFIELD embedded type
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *node) Class() Class { return Class(n.flags.get3(nodeClass)) }
|
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) Bounded() bool { return n.flags&nodeBounded != 0 }
|
||||||
func (n *node) HasCall() bool { return n.flags&nodeHasCall != 0 }
|
func (n *node) HasCall() bool { return n.flags&nodeHasCall != 0 }
|
||||||
func (n *node) Likely() bool { return n.flags&nodeLikely != 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) SetClass(b Class) { n.flags.set3(nodeClass, uint8(b)) }
|
||||||
func (n *node) SetWalkdef(b uint8) { n.flags.set2(nodeWalkdef, 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) SetTransient(b bool) { n.flags.set(nodeTransient, b) }
|
||||||
func (n *node) SetHasCall(b bool) { n.flags.set(nodeHasCall, 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) 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,
|
// MarkNonNil marks a pointer n as being guaranteed non-nil,
|
||||||
// on all code paths, at all times.
|
// on all code paths, at all times.
|
||||||
|
|
@ -474,7 +457,7 @@ const (
|
||||||
|
|
||||||
// Used during parsing but don't last.
|
// Used during parsing but don't last.
|
||||||
ODCLFUNC // func f() or func (r) f()
|
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
|
ODCLCONST // const pi = 3.14
|
||||||
ODCLTYPE // type Int int or type Int = int
|
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
|
// OTFUNC: func() - Left is receiver field, List is list of param fields, Rlist is
|
||||||
// list of result fields.
|
// list of result fields.
|
||||||
OTFUNC
|
OTFUNC
|
||||||
OTARRAY // []int, [8]int, [N]int or [...]int
|
OTARRAY // [8]int or [...]int
|
||||||
OTSLICE // to be used in future CL
|
OTSLICE // []int
|
||||||
|
|
||||||
// misc
|
// 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.
|
OINLCALL // intermediary representation of an inlined call.
|
||||||
OEFACE // itable and data words of an empty-interface value.
|
OEFACE // itable and data words of an empty-interface value.
|
||||||
OITAB // itable word of an 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 {
|
switch op {
|
||||||
case ODCLFUNC:
|
case ODCLFUNC:
|
||||||
return NewFunc(pos)
|
return NewFunc(pos)
|
||||||
|
case ODEREF:
|
||||||
|
return NewStarExpr(pos, nleft)
|
||||||
case OPACK:
|
case OPACK:
|
||||||
return NewPkgName(pos, nil, nil)
|
return NewPkgName(pos, nil, nil)
|
||||||
case OEMPTY:
|
case OEMPTY:
|
||||||
|
|
@ -1112,12 +1097,9 @@ var okForNod = [OEND]bool{
|
||||||
OCOPY: true,
|
OCOPY: true,
|
||||||
ODCL: true,
|
ODCL: true,
|
||||||
ODCLCONST: true,
|
ODCLCONST: true,
|
||||||
ODCLFIELD: true,
|
|
||||||
ODCLTYPE: true,
|
ODCLTYPE: true,
|
||||||
ODDD: true,
|
|
||||||
ODEFER: true,
|
ODEFER: true,
|
||||||
ODELETE: true,
|
ODELETE: true,
|
||||||
ODEREF: true,
|
|
||||||
ODIV: true,
|
ODIV: true,
|
||||||
ODOT: true,
|
ODOT: true,
|
||||||
ODOTINTER: true,
|
ODOTINTER: true,
|
||||||
|
|
@ -1201,13 +1183,6 @@ var okForNod = [OEND]bool{
|
||||||
OSTRUCTLIT: true,
|
OSTRUCTLIT: true,
|
||||||
OSUB: true,
|
OSUB: true,
|
||||||
OSWITCH: 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,
|
OTYPESW: true,
|
||||||
OVARDEF: true,
|
OVARDEF: true,
|
||||||
OVARKILL: true,
|
OVARKILL: true,
|
||||||
|
|
|
||||||
|
|
@ -7,21 +7,375 @@ package ir
|
||||||
import (
|
import (
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"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)
|
return TypeNodeAt(src.NoXPos, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TypeNodeAt(pos src.XPos, t *types.Type) Node {
|
// TypeNodeAt returns the Node representing the type t.
|
||||||
// if we copied another type with *t = *u
|
// If the node must be created, TypeNodeAt uses the position pos.
|
||||||
// then t->nod might be out of date, so
|
// TODO(rsc): Does anyone actually use position on these type nodes?
|
||||||
// check t->nod->type too
|
func TypeNodeAt(pos src.XPos, t *types.Type) Ntype {
|
||||||
if AsNode(t.Nod) == nil || AsNode(t.Nod).Type() != t {
|
// If we copied another type with *t = *u,
|
||||||
t.Nod = NodAt(pos, OTYPE, nil, nil)
|
// then t.Nod might be out of date, so check t.Nod.Type() too.
|
||||||
AsNode(t.Nod).SetType(t)
|
n := AsNode(t.Nod)
|
||||||
AsNode(t.Nod).SetSym(t.Sym)
|
if n == nil || n.Type() != t {
|
||||||
|
n := newTypeNode(pos, t) // t.Sym may be nil
|
||||||
|
t.Nod = n
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
|
return n.(Ntype)
|
||||||
return AsNode(t.Nod)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue