]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: add custom type syntax Node implementations
authorRuss Cox <rsc@golang.org>
Thu, 26 Nov 2020 12:02:13 +0000 (07:02 -0500)
committerRuss Cox <rsc@golang.org>
Mon, 30 Nov 2020 19:45:21 +0000 (19:45 +0000)
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>

23 files changed:
src/cmd/compile/fmtmap_test.go
src/cmd/compile/internal/gc/alg.go
src/cmd/compile/internal/gc/builtin.go
src/cmd/compile/internal/gc/closure.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/embed.go
src/cmd/compile/internal/gc/iexport.go
src/cmd/compile/internal/gc/iimport.go
src/cmd/compile/internal/gc/init.go
src/cmd/compile/internal/gc/mkbuiltin.go
src/cmd/compile/internal/gc/noder.go
src/cmd/compile/internal/gc/reflect.go
src/cmd/compile/internal/gc/select.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/universe.go
src/cmd/compile/internal/gc/walk.go
src/cmd/compile/internal/ir/expr.go
src/cmd/compile/internal/ir/fmt.go
src/cmd/compile/internal/ir/mini.go
src/cmd/compile/internal/ir/name.go
src/cmd/compile/internal/ir/node.go
src/cmd/compile/internal/ir/type.go

index e949a89d9331234762c4d79418c604419aa57ed2..32891aea66d55942b27b11d19cd4fae3959688f7 100644 (file)
@@ -95,6 +95,7 @@ var knownFormats = map[string]string{
        "cmd/compile/internal/ir.Nodes %+v":               "",
        "cmd/compile/internal/ir.Nodes %.v":               "",
        "cmd/compile/internal/ir.Nodes %v":                "",
+       "cmd/compile/internal/ir.Ntype %v":                "",
        "cmd/compile/internal/ir.Op %#v":                  "",
        "cmd/compile/internal/ir.Op %v":                   "",
        "cmd/compile/internal/ssa.BranchPrediction %d":    "",
index b40a56fe39ee4a2058ccd25f3081b5345cbeb486..806417d03de31e0e504865a98f65e70f3d7be2b4 100644 (file)
@@ -292,12 +292,12 @@ func genhash(t *types.Type) *obj.LSym {
        dclcontext = ir.PEXTERN
 
        // func sym(p *T, h uintptr) uintptr
-       tfn := ir.Nod(ir.OTFUNC, nil, nil)
-       tfn.PtrList().Set2(
+       args := []*ir.Field{
                namedfield("p", types.NewPtr(t)),
                namedfield("h", types.Types[types.TUINTPTR]),
-       )
-       tfn.PtrRlist().Set1(anonfield(types.Types[types.TUINTPTR]))
+       }
+       results := []*ir.Field{anonfield(types.Types[types.TUINTPTR])}
+       tfn := ir.NewFuncType(base.Pos, nil, args, results)
 
        fn := dclfunc(sym, tfn)
        np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
@@ -432,10 +432,10 @@ func hashfor(t *types.Type) ir.Node {
 
        n := NewName(sym)
        setNodeNameFunc(n)
-       n.SetType(functype(nil, []ir.Node{
+       n.SetType(functype(nil, []*ir.Field{
                anonfield(types.NewPtr(t)),
                anonfield(types.Types[types.TUINTPTR]),
-       }, []ir.Node{
+       }, []*ir.Field{
                anonfield(types.Types[types.TUINTPTR]),
        }))
        return n
@@ -521,12 +521,9 @@ func geneq(t *types.Type) *obj.LSym {
        dclcontext = ir.PEXTERN
 
        // func sym(p, q *T) bool
-       tfn := ir.Nod(ir.OTFUNC, nil, nil)
-       tfn.PtrList().Set2(
-               namedfield("p", types.NewPtr(t)),
-               namedfield("q", types.NewPtr(t)),
-       )
-       tfn.PtrRlist().Set1(namedfield("r", types.Types[types.TBOOL]))
+       tfn := ir.NewFuncType(base.Pos, nil,
+               []*ir.Field{namedfield("p", types.NewPtr(t)), namedfield("q", types.NewPtr(t))},
+               []*ir.Field{namedfield("r", types.Types[types.TBOOL])})
 
        fn := dclfunc(sym, tfn)
        np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
index a57c6115595f03b8c859ef81f1edf0caf5c36246..efca44c66764017d284caf3fcfab3b1d6a80c1b4 100644 (file)
@@ -210,132 +210,132 @@ func runtimeTypes() []*types.Type {
        typs[1] = types.NewPtr(typs[0])
        typs[2] = types.Types[types.TANY]
        typs[3] = types.NewPtr(typs[2])
-       typs[4] = functype(nil, []ir.Node{anonfield(typs[1])}, []ir.Node{anonfield(typs[3])})
+       typs[4] = functype(nil, []*ir.Field{anonfield(typs[1])}, []*ir.Field{anonfield(typs[3])})
        typs[5] = types.Types[types.TUINTPTR]
        typs[6] = types.Types[types.TBOOL]
        typs[7] = types.Types[types.TUNSAFEPTR]
-       typs[8] = functype(nil, []ir.Node{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []ir.Node{anonfield(typs[7])})
+       typs[8] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []*ir.Field{anonfield(typs[7])})
        typs[9] = functype(nil, nil, nil)
        typs[10] = types.Types[types.TINTER]
-       typs[11] = functype(nil, []ir.Node{anonfield(typs[10])}, nil)
+       typs[11] = functype(nil, []*ir.Field{anonfield(typs[10])}, nil)
        typs[12] = types.Types[types.TINT32]
        typs[13] = types.NewPtr(typs[12])
-       typs[14] = functype(nil, []ir.Node{anonfield(typs[13])}, []ir.Node{anonfield(typs[10])})
+       typs[14] = functype(nil, []*ir.Field{anonfield(typs[13])}, []*ir.Field{anonfield(typs[10])})
        typs[15] = types.Types[types.TINT]
-       typs[16] = functype(nil, []ir.Node{anonfield(typs[15]), anonfield(typs[15])}, nil)
+       typs[16] = functype(nil, []*ir.Field{anonfield(typs[15]), anonfield(typs[15])}, nil)
        typs[17] = types.Types[types.TUINT]
-       typs[18] = functype(nil, []ir.Node{anonfield(typs[17]), anonfield(typs[15])}, nil)
-       typs[19] = functype(nil, []ir.Node{anonfield(typs[6])}, nil)
+       typs[18] = functype(nil, []*ir.Field{anonfield(typs[17]), anonfield(typs[15])}, nil)
+       typs[19] = functype(nil, []*ir.Field{anonfield(typs[6])}, nil)
        typs[20] = types.Types[types.TFLOAT64]
-       typs[21] = functype(nil, []ir.Node{anonfield(typs[20])}, nil)
+       typs[21] = functype(nil, []*ir.Field{anonfield(typs[20])}, nil)
        typs[22] = types.Types[types.TINT64]
-       typs[23] = functype(nil, []ir.Node{anonfield(typs[22])}, nil)
+       typs[23] = functype(nil, []*ir.Field{anonfield(typs[22])}, nil)
        typs[24] = types.Types[types.TUINT64]
-       typs[25] = functype(nil, []ir.Node{anonfield(typs[24])}, nil)
+       typs[25] = functype(nil, []*ir.Field{anonfield(typs[24])}, nil)
        typs[26] = types.Types[types.TCOMPLEX128]
-       typs[27] = functype(nil, []ir.Node{anonfield(typs[26])}, nil)
+       typs[27] = functype(nil, []*ir.Field{anonfield(typs[26])}, nil)
        typs[28] = types.Types[types.TSTRING]
-       typs[29] = functype(nil, []ir.Node{anonfield(typs[28])}, nil)
-       typs[30] = functype(nil, []ir.Node{anonfield(typs[2])}, nil)
-       typs[31] = functype(nil, []ir.Node{anonfield(typs[5])}, nil)
+       typs[29] = functype(nil, []*ir.Field{anonfield(typs[28])}, nil)
+       typs[30] = functype(nil, []*ir.Field{anonfield(typs[2])}, nil)
+       typs[31] = functype(nil, []*ir.Field{anonfield(typs[5])}, nil)
        typs[32] = types.NewArray(typs[0], 32)
        typs[33] = types.NewPtr(typs[32])
-       typs[34] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[28])})
-       typs[35] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[28])})
-       typs[36] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[28])})
-       typs[37] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[28])})
+       typs[34] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
+       typs[35] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
+       typs[36] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
+       typs[37] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[28])})
        typs[38] = types.NewSlice(typs[28])
-       typs[39] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[38])}, []ir.Node{anonfield(typs[28])})
-       typs[40] = functype(nil, []ir.Node{anonfield(typs[28]), anonfield(typs[28])}, []ir.Node{anonfield(typs[15])})
+       typs[39] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[38])}, []*ir.Field{anonfield(typs[28])})
+       typs[40] = functype(nil, []*ir.Field{anonfield(typs[28]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[15])})
        typs[41] = types.NewArray(typs[0], 4)
        typs[42] = types.NewPtr(typs[41])
-       typs[43] = functype(nil, []ir.Node{anonfield(typs[42]), anonfield(typs[22])}, []ir.Node{anonfield(typs[28])})
-       typs[44] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []ir.Node{anonfield(typs[28])})
-       typs[45] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15])}, []ir.Node{anonfield(typs[28])})
+       typs[43] = functype(nil, []*ir.Field{anonfield(typs[42]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[28])})
+       typs[44] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[28])})
+       typs[45] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[28])})
        typs[46] = types.Runetype
        typs[47] = types.NewSlice(typs[46])
-       typs[48] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[47])}, []ir.Node{anonfield(typs[28])})
+       typs[48] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[47])}, []*ir.Field{anonfield(typs[28])})
        typs[49] = types.NewSlice(typs[0])
-       typs[50] = functype(nil, []ir.Node{anonfield(typs[33]), anonfield(typs[28])}, []ir.Node{anonfield(typs[49])})
+       typs[50] = functype(nil, []*ir.Field{anonfield(typs[33]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[49])})
        typs[51] = types.NewArray(typs[46], 32)
        typs[52] = types.NewPtr(typs[51])
-       typs[53] = functype(nil, []ir.Node{anonfield(typs[52]), anonfield(typs[28])}, []ir.Node{anonfield(typs[47])})
-       typs[54] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []ir.Node{anonfield(typs[15])})
-       typs[55] = functype(nil, []ir.Node{anonfield(typs[28]), anonfield(typs[15])}, []ir.Node{anonfield(typs[46]), anonfield(typs[15])})
-       typs[56] = functype(nil, []ir.Node{anonfield(typs[28])}, []ir.Node{anonfield(typs[15])})
-       typs[57] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[2])}, []ir.Node{anonfield(typs[2])})
-       typs[58] = functype(nil, []ir.Node{anonfield(typs[2])}, []ir.Node{anonfield(typs[7])})
-       typs[59] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3])}, []ir.Node{anonfield(typs[2])})
-       typs[60] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[2])}, []ir.Node{anonfield(typs[2]), anonfield(typs[6])})
-       typs[61] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
-       typs[62] = functype(nil, []ir.Node{anonfield(typs[1])}, nil)
+       typs[53] = functype(nil, []*ir.Field{anonfield(typs[52]), anonfield(typs[28])}, []*ir.Field{anonfield(typs[47])})
+       typs[54] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[15])})
+       typs[55] = functype(nil, []*ir.Field{anonfield(typs[28]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[46]), anonfield(typs[15])})
+       typs[56] = functype(nil, []*ir.Field{anonfield(typs[28])}, []*ir.Field{anonfield(typs[15])})
+       typs[57] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[2])})
+       typs[58] = functype(nil, []*ir.Field{anonfield(typs[2])}, []*ir.Field{anonfield(typs[7])})
+       typs[59] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[2])})
+       typs[60] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[2]), anonfield(typs[6])})
+       typs[61] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
+       typs[62] = functype(nil, []*ir.Field{anonfield(typs[1])}, nil)
        typs[63] = types.NewPtr(typs[5])
-       typs[64] = functype(nil, []ir.Node{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []ir.Node{anonfield(typs[6])})
+       typs[64] = functype(nil, []*ir.Field{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[6])})
        typs[65] = types.Types[types.TUINT32]
-       typs[66] = functype(nil, nil, []ir.Node{anonfield(typs[65])})
+       typs[66] = functype(nil, nil, []*ir.Field{anonfield(typs[65])})
        typs[67] = types.NewMap(typs[2], typs[2])
-       typs[68] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []ir.Node{anonfield(typs[67])})
-       typs[69] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []ir.Node{anonfield(typs[67])})
-       typs[70] = functype(nil, nil, []ir.Node{anonfield(typs[67])})
-       typs[71] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []ir.Node{anonfield(typs[3])})
-       typs[72] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []ir.Node{anonfield(typs[3])})
-       typs[73] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []ir.Node{anonfield(typs[3])})
-       typs[74] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []ir.Node{anonfield(typs[3]), anonfield(typs[6])})
-       typs[75] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []ir.Node{anonfield(typs[3]), anonfield(typs[6])})
-       typs[76] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []ir.Node{anonfield(typs[3]), anonfield(typs[6])})
-       typs[77] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
-       typs[78] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
-       typs[79] = functype(nil, []ir.Node{anonfield(typs[3])}, nil)
-       typs[80] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[67])}, nil)
+       typs[68] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[67])})
+       typs[69] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[67])})
+       typs[70] = functype(nil, nil, []*ir.Field{anonfield(typs[67])})
+       typs[71] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[3])})
+       typs[72] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[3])})
+       typs[73] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Field{anonfield(typs[3])})
+       typs[74] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])})
+       typs[75] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])})
+       typs[76] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Field{anonfield(typs[3]), anonfield(typs[6])})
+       typs[77] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
+       typs[78] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
+       typs[79] = functype(nil, []*ir.Field{anonfield(typs[3])}, nil)
+       typs[80] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[67])}, nil)
        typs[81] = types.NewChan(typs[2], types.Cboth)
-       typs[82] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[22])}, []ir.Node{anonfield(typs[81])})
-       typs[83] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15])}, []ir.Node{anonfield(typs[81])})
+       typs[82] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[81])})
+       typs[83] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[81])})
        typs[84] = types.NewChan(typs[2], types.Crecv)
-       typs[85] = functype(nil, []ir.Node{anonfield(typs[84]), anonfield(typs[3])}, nil)
-       typs[86] = functype(nil, []ir.Node{anonfield(typs[84]), anonfield(typs[3])}, []ir.Node{anonfield(typs[6])})
+       typs[85] = functype(nil, []*ir.Field{anonfield(typs[84]), anonfield(typs[3])}, nil)
+       typs[86] = functype(nil, []*ir.Field{anonfield(typs[84]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
        typs[87] = types.NewChan(typs[2], types.Csend)
-       typs[88] = functype(nil, []ir.Node{anonfield(typs[87]), anonfield(typs[3])}, nil)
+       typs[88] = functype(nil, []*ir.Field{anonfield(typs[87]), anonfield(typs[3])}, nil)
        typs[89] = types.NewArray(typs[0], 3)
-       typs[90] = tostruct([]ir.Node{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])})
-       typs[91] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
-       typs[92] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
-       typs[93] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []ir.Node{anonfield(typs[15])})
-       typs[94] = functype(nil, []ir.Node{anonfield(typs[87]), anonfield(typs[3])}, []ir.Node{anonfield(typs[6])})
-       typs[95] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[84])}, []ir.Node{anonfield(typs[6])})
+       typs[90] = tostruct([]*ir.Field{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])})
+       typs[91] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
+       typs[92] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3])}, nil)
+       typs[93] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[15])})
+       typs[94] = functype(nil, []*ir.Field{anonfield(typs[87]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
+       typs[95] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[84])}, []*ir.Field{anonfield(typs[6])})
        typs[96] = types.NewPtr(typs[6])
-       typs[97] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []ir.Node{anonfield(typs[6])})
-       typs[98] = functype(nil, []ir.Node{anonfield(typs[63])}, nil)
-       typs[99] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []ir.Node{anonfield(typs[15]), anonfield(typs[6])})
-       typs[100] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []ir.Node{anonfield(typs[7])})
-       typs[101] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []ir.Node{anonfield(typs[7])})
-       typs[102] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []ir.Node{anonfield(typs[7])})
+       typs[97] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*ir.Field{anonfield(typs[6])})
+       typs[98] = functype(nil, []*ir.Field{anonfield(typs[63])}, nil)
+       typs[99] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []*ir.Field{anonfield(typs[15]), anonfield(typs[6])})
+       typs[100] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[7])})
+       typs[101] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[7])})
+       typs[102] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[7])})
        typs[103] = types.NewSlice(typs[2])
-       typs[104] = functype(nil, []ir.Node{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []ir.Node{anonfield(typs[103])})
-       typs[105] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
-       typs[106] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
-       typs[107] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []ir.Node{anonfield(typs[6])})
-       typs[108] = functype(nil, []ir.Node{anonfield(typs[3]), anonfield(typs[3])}, []ir.Node{anonfield(typs[6])})
-       typs[109] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[7])}, []ir.Node{anonfield(typs[6])})
-       typs[110] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []ir.Node{anonfield(typs[5])})
-       typs[111] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[5])}, []ir.Node{anonfield(typs[5])})
-       typs[112] = functype(nil, []ir.Node{anonfield(typs[22]), anonfield(typs[22])}, []ir.Node{anonfield(typs[22])})
-       typs[113] = functype(nil, []ir.Node{anonfield(typs[24]), anonfield(typs[24])}, []ir.Node{anonfield(typs[24])})
-       typs[114] = functype(nil, []ir.Node{anonfield(typs[20])}, []ir.Node{anonfield(typs[22])})
-       typs[115] = functype(nil, []ir.Node{anonfield(typs[20])}, []ir.Node{anonfield(typs[24])})
-       typs[116] = functype(nil, []ir.Node{anonfield(typs[20])}, []ir.Node{anonfield(typs[65])})
-       typs[117] = functype(nil, []ir.Node{anonfield(typs[22])}, []ir.Node{anonfield(typs[20])})
-       typs[118] = functype(nil, []ir.Node{anonfield(typs[24])}, []ir.Node{anonfield(typs[20])})
-       typs[119] = functype(nil, []ir.Node{anonfield(typs[65])}, []ir.Node{anonfield(typs[20])})
-       typs[120] = functype(nil, []ir.Node{anonfield(typs[26]), anonfield(typs[26])}, []ir.Node{anonfield(typs[26])})
-       typs[121] = functype(nil, []ir.Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
-       typs[122] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
+       typs[104] = functype(nil, []*ir.Field{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*ir.Field{anonfield(typs[103])})
+       typs[105] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
+       typs[106] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5])}, nil)
+       typs[107] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[6])})
+       typs[108] = functype(nil, []*ir.Field{anonfield(typs[3]), anonfield(typs[3])}, []*ir.Field{anonfield(typs[6])})
+       typs[109] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[7])}, []*ir.Field{anonfield(typs[6])})
+       typs[110] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[5])})
+       typs[111] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[5])}, []*ir.Field{anonfield(typs[5])})
+       typs[112] = functype(nil, []*ir.Field{anonfield(typs[22]), anonfield(typs[22])}, []*ir.Field{anonfield(typs[22])})
+       typs[113] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, []*ir.Field{anonfield(typs[24])})
+       typs[114] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[22])})
+       typs[115] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[24])})
+       typs[116] = functype(nil, []*ir.Field{anonfield(typs[20])}, []*ir.Field{anonfield(typs[65])})
+       typs[117] = functype(nil, []*ir.Field{anonfield(typs[22])}, []*ir.Field{anonfield(typs[20])})
+       typs[118] = functype(nil, []*ir.Field{anonfield(typs[24])}, []*ir.Field{anonfield(typs[20])})
+       typs[119] = functype(nil, []*ir.Field{anonfield(typs[65])}, []*ir.Field{anonfield(typs[20])})
+       typs[120] = functype(nil, []*ir.Field{anonfield(typs[26]), anonfield(typs[26])}, []*ir.Field{anonfield(typs[26])})
+       typs[121] = functype(nil, []*ir.Field{anonfield(typs[5]), anonfield(typs[5])}, nil)
+       typs[122] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
        typs[123] = types.NewSlice(typs[7])
-       typs[124] = functype(nil, []ir.Node{anonfield(typs[7]), anonfield(typs[123])}, nil)
+       typs[124] = functype(nil, []*ir.Field{anonfield(typs[7]), anonfield(typs[123])}, nil)
        typs[125] = types.Types[types.TUINT8]
-       typs[126] = functype(nil, []ir.Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
+       typs[126] = functype(nil, []*ir.Field{anonfield(typs[125]), anonfield(typs[125])}, nil)
        typs[127] = types.Types[types.TUINT16]
-       typs[128] = functype(nil, []ir.Node{anonfield(typs[127]), anonfield(typs[127])}, nil)
-       typs[129] = functype(nil, []ir.Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
-       typs[130] = functype(nil, []ir.Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
+       typs[128] = functype(nil, []*ir.Field{anonfield(typs[127]), anonfield(typs[127])}, nil)
+       typs[129] = functype(nil, []*ir.Field{anonfield(typs[65]), anonfield(typs[65])}, nil)
+       typs[130] = functype(nil, []*ir.Field{anonfield(typs[24]), anonfield(typs[24])}, nil)
        return typs[:]
 }
index ee09e7876eed873c45e471ddbd6df725c0761603..0ba2858b8b4e8df10e6ea0fbcaa2f9d38d179008 100644 (file)
@@ -363,7 +363,7 @@ func closureType(clo ir.Node) *types.Type {
        // The information appears in the binary in the form of type descriptors;
        // the struct is unnamed so that closures in multiple packages with the
        // same struct type can share the descriptor.
-       fields := []ir.Node{
+       fields := []*ir.Field{
                namedfield(".F", types.Types[types.TUINTPTR]),
        }
        for _, v := range clo.Func().ClosureVars {
@@ -456,9 +456,9 @@ func makepartialcall(dot ir.Node, t0 *types.Type, meth *types.Sym) *ir.Func {
        // number at the use of the method expression in this
        // case. See issue 29389.
 
-       tfn := ir.Nod(ir.OTFUNC, nil, nil)
-       tfn.PtrList().Set(structargs(t0.Params(), true))
-       tfn.PtrRlist().Set(structargs(t0.Results(), false))
+       tfn := ir.NewFuncType(base.Pos, nil,
+               structargs(t0.Params(), true),
+               structargs(t0.Results(), false))
 
        fn := dclfunc(sym, tfn)
        fn.SetDupok(true)
@@ -510,7 +510,7 @@ func makepartialcall(dot ir.Node, t0 *types.Type, meth *types.Sym) *ir.Func {
 // needed in the closure for n (n must be a OCALLPART node).
 // The address of a variable of the returned type can be cast to a func.
 func partialCallType(n ir.Node) *types.Type {
-       t := tostruct([]ir.Node{
+       t := tostruct([]*ir.Field{
                namedfield("F", types.Types[types.TUINTPTR]),
                namedfield("R", n.Left().Type()),
        })
index 3d8f97d93dd515461161da59c9817d7e5c0cb49d..637587392aa448ab66706b6ee8d865279c3bb3cd 100644 (file)
@@ -134,7 +134,7 @@ func addvar(n *ir.Name, t *types.Type, ctxt ir.Class) {
 
 // declare variables from grammar
 // new_name_list (type | [type] = expr_list)
-func variter(vl []ir.Node, t ir.Node, el []ir.Node) []ir.Node {
+func variter(vl []ir.Node, t ir.Ntype, el []ir.Node) []ir.Node {
        var init []ir.Node
        doexpr := len(el) > 0
 
@@ -221,18 +221,16 @@ func dclname(s *types.Sym) *ir.Name {
        return n
 }
 
-func anonfield(typ *types.Type) ir.Node {
+func anonfield(typ *types.Type) *ir.Field {
        return symfield(nil, typ)
 }
 
-func namedfield(s string, typ *types.Type) ir.Node {
+func namedfield(s string, typ *types.Type) *ir.Field {
        return symfield(lookup(s), typ)
 }
 
-func symfield(s *types.Sym, typ *types.Type) ir.Node {
-       n := nodSym(ir.ODCLFIELD, nil, s)
-       n.SetType(typ)
-       return n
+func symfield(s *types.Sym, typ *types.Type) *ir.Field {
+       return ir.NewField(base.Pos, s, nil, typ)
 }
 
 // oldname returns the Node that declares symbol s in the current scope.
@@ -279,7 +277,8 @@ func oldname(s *types.Sym) ir.Node {
        return n
 }
 
-// importName is like oldname, but it reports an error if sym is from another package and not exported.
+// importName is like oldname,
+// but it reports an error if sym is from another package and not exported.
 func importName(sym *types.Sym) ir.Node {
        n := oldname(sym)
        if !types.IsExported(sym.Name) && sym.Pkg != ir.LocalPkg {
@@ -348,12 +347,12 @@ func colasdefn(left []ir.Node, defn ir.Node) {
 
 // declare the arguments in an
 // interface field declaration.
-func ifacedcl(n ir.Node) {
-       if n.Op() != ir.ODCLFIELD || n.Left() == nil {
+func ifacedcl(n *ir.Field) {
+       if n.Sym == nil {
                base.Fatalf("ifacedcl")
        }
 
-       if n.Sym().IsBlank() {
+       if n.Sym.IsBlank() {
                base.Errorf("methods must have a unique non-blank name")
        }
 }
@@ -371,13 +370,13 @@ func funchdr(fn *ir.Func) {
        types.Markdcl()
 
        if fn.Nname != nil && fn.Nname.Ntype != nil {
-               funcargs(fn.Nname.Ntype)
+               funcargs(fn.Nname.Ntype.(*ir.FuncType))
        } else {
                funcargs2(fn.Type())
        }
 }
 
-func funcargs(nt ir.Node) {
+func funcargs(nt *ir.FuncType) {
        if nt.Op() != ir.OTFUNC {
                base.Fatalf("funcargs %v", nt.Op())
        }
@@ -389,13 +388,13 @@ func funcargs(nt ir.Node) {
        // TODO(mdempsky): This is ugly, and only necessary because
        // esc.go uses Vargen to figure out result parameters' index
        // within the result tuple.
-       vargen = nt.Rlist().Len()
+       vargen = len(nt.Results)
 
        // declare the receiver and in arguments.
-       if nt.Left() != nil {
-               funcarg(nt.Left(), ir.PPARAM)
+       if nt.Recv != nil {
+               funcarg(nt.Recv, ir.PPARAM)
        }
-       for _, n := range nt.List().Slice() {
+       for _, n := range nt.Params {
                funcarg(n, ir.PPARAM)
        }
 
@@ -403,21 +402,21 @@ func funcargs(nt ir.Node) {
        vargen = 0
 
        // declare the out arguments.
-       gen := nt.List().Len()
-       for _, n := range nt.Rlist().Slice() {
-               if n.Sym() == nil {
+       gen := len(nt.Params)
+       for _, n := range nt.Results {
+               if n.Sym == nil {
                        // Name so that escape analysis can track it. ~r stands for 'result'.
-                       n.SetSym(lookupN("~r", gen))
+                       n.Sym = lookupN("~r", gen)
                        gen++
                }
-               if n.Sym().IsBlank() {
+               if n.Sym.IsBlank() {
                        // Give it a name so we can assign to it during return. ~b stands for 'blank'.
                        // The name must be different from ~r above because if you have
                        //      func f() (_ int)
                        //      func g() int
                        // f is allowed to use a plain 'return' with no arguments, while g is not.
                        // So the two cases must be distinguished.
-                       n.SetSym(lookupN("~b", gen))
+                       n.Sym = lookupN("~b", gen)
                        gen++
                }
 
@@ -427,22 +426,19 @@ func funcargs(nt ir.Node) {
        vargen = oldvargen
 }
 
-func funcarg(n ir.Node, ctxt ir.Class) {
-       if n.Op() != ir.ODCLFIELD {
-               base.Fatalf("funcarg %v", n.Op())
-       }
-       if n.Sym() == nil {
+func funcarg(n *ir.Field, ctxt ir.Class) {
+       if n.Sym == nil {
                return
        }
 
-       name := ir.NewNameAt(n.Pos(), n.Sym())
-       n.SetRight(name)
-       name.Ntype = n.Left()
-       name.SetIsDDD(n.IsDDD())
+       name := ir.NewNameAt(n.Pos, n.Sym)
+       n.Decl = name
+       name.Ntype = n.Ntype
+       name.SetIsDDD(n.IsDDD)
        declare(name, ctxt)
 
        vargen++
-       n.Right().Name().Vargen = int32(vargen)
+       n.Decl.Name().Vargen = int32(vargen)
 }
 
 // Same as funcargs, except run over an already constructed TFUNC.
@@ -514,28 +510,22 @@ func checkembeddedtype(t *types.Type) {
        }
 }
 
-func structfield(n ir.Node) *types.Field {
+func structfield(n *ir.Field) *types.Field {
        lno := base.Pos
-       base.Pos = n.Pos()
-
-       if n.Op() != ir.ODCLFIELD {
-               base.Fatalf("structfield: oops %v\n", n)
-       }
+       base.Pos = n.Pos
 
-       if n.Left() != nil {
-               n.SetLeft(typecheck(n.Left(), ctxType))
-               n.SetType(n.Left().Type())
-               n.SetLeft(nil)
+       if n.Ntype != nil {
+               n.Ntype = typecheckNtype(n.Ntype)
+               n.Type = n.Ntype.Type()
+               n.Ntype = nil
        }
 
-       f := types.NewField(n.Pos(), n.Sym(), n.Type())
-       if n.Embedded() {
-               checkembeddedtype(n.Type())
+       f := types.NewField(n.Pos, n.Sym, n.Type)
+       if n.Embedded {
+               checkembeddedtype(n.Type)
                f.Embedded = 1
        }
-       if n.Opt() != nil {
-               f.Note = n.Opt().(string)
-       }
+       f.Note = n.Note
 
        base.Pos = lno
        return f
@@ -561,7 +551,7 @@ func checkdupfields(what string, fss ...[]*types.Field) {
 
 // convert a parsed id/type list into
 // a type for struct/interface/arglist
-func tostruct(l []ir.Node) *types.Type {
+func tostruct(l []*ir.Field) *types.Type {
        t := types.New(types.TSTRUCT)
 
        fields := make([]*types.Field, len(l))
@@ -583,17 +573,17 @@ func tostruct(l []ir.Node) *types.Type {
        return t
 }
 
-func tofunargs(l []ir.Node, funarg types.Funarg) *types.Type {
+func tofunargs(l []*ir.Field, funarg types.Funarg) *types.Type {
        t := types.New(types.TSTRUCT)
        t.StructType().Funarg = funarg
 
        fields := make([]*types.Field, len(l))
        for i, n := range l {
                f := structfield(n)
-               f.SetIsDDD(n.IsDDD())
-               if n.Right() != nil {
-                       n.Right().SetType(f.Type)
-                       f.Nname = n.Right()
+               f.SetIsDDD(n.IsDDD)
+               if n.Decl != nil {
+                       n.Decl.SetType(f.Type)
+                       f.Nname = n.Decl
                }
                if f.Broke() {
                        t.SetBroke(true)
@@ -611,15 +601,11 @@ func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
        return t
 }
 
-func interfacefield(n ir.Node) *types.Field {
+func interfacefield(n *ir.Field) *types.Field {
        lno := base.Pos
-       base.Pos = n.Pos()
-
-       if n.Op() != ir.ODCLFIELD {
-               base.Fatalf("interfacefield: oops %v\n", n)
-       }
+       base.Pos = n.Pos
 
-       if n.Opt() != nil {
+       if n.Note != "" {
                base.Errorf("interface method cannot have annotation")
        }
 
@@ -628,19 +614,19 @@ func interfacefield(n ir.Node) *types.Field {
        // If Sym != nil, then Sym is MethodName and Left is Signature.
        // Otherwise, Left is InterfaceTypeName.
 
-       if n.Left() != nil {
-               n.SetLeft(typecheck(n.Left(), ctxType))
-               n.SetType(n.Left().Type())
-               n.SetLeft(nil)
+       if n.Ntype != nil {
+               n.Ntype = typecheckNtype(n.Ntype)
+               n.Type = n.Ntype.Type()
+               n.Ntype = nil
        }
 
-       f := types.NewField(n.Pos(), n.Sym(), n.Type())
+       f := types.NewField(n.Pos, n.Sym, n.Type)
 
        base.Pos = lno
        return f
 }
 
-func tointerface(l []ir.Node) *types.Type {
+func tointerface(l []*ir.Field) *types.Type {
        if len(l) == 0 {
                return types.Types[types.TINTER]
        }
@@ -657,7 +643,7 @@ func tointerface(l []ir.Node) *types.Type {
        return t
 }
 
-func fakeRecv() ir.Node {
+func fakeRecv() *ir.Field {
        return anonfield(types.FakeRecvType())
 }
 
@@ -673,12 +659,12 @@ func isifacemethod(f *types.Type) bool {
 }
 
 // turn a parsed function declaration into a type
-func functype(this ir.Node, in, out []ir.Node) *types.Type {
+func functype(this *ir.Field, in, out []*ir.Field) *types.Type {
        t := types.New(types.TFUNC)
 
-       var rcvr []ir.Node
+       var rcvr []*ir.Field
        if this != nil {
-               rcvr = []ir.Node{this}
+               rcvr = []*ir.Field{this}
        }
        t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
        t.FuncType().Params = tofunargs(in, types.FunargParams)
@@ -923,7 +909,7 @@ func setNodeNameFunc(n ir.Node) {
        n.Sym().SetFunc(true)
 }
 
-func dclfunc(sym *types.Sym, tfn ir.Node) *ir.Func {
+func dclfunc(sym *types.Sym, tfn ir.Ntype) *ir.Func {
        if tfn.Op() != ir.OTFUNC {
                base.Fatalf("expected OTFUNC node, got %v", tfn)
        }
@@ -934,7 +920,7 @@ func dclfunc(sym *types.Sym, tfn ir.Node) *ir.Func {
        fn.Nname.Ntype = tfn
        setNodeNameFunc(fn.Nname)
        funchdr(fn)
-       fn.Nname.Ntype = typecheck(fn.Nname.Ntype, ctxType)
+       fn.Nname.Ntype = typecheckNtype(fn.Nname.Ntype)
        return fn
 }
 
index 1c8ccdadefeb5b8ffeaef92f1ab3300477b5afc3..d9bfd6f5edebef5df514f0458e9f4d7dd8c4ff0e 100644 (file)
@@ -28,7 +28,7 @@ const (
 
 var numLocalEmbed int
 
-func varEmbed(p *noder, names []ir.Node, typ ir.Node, exprs []ir.Node, embeds []PragmaEmbed) (newExprs []ir.Node) {
+func varEmbed(p *noder, names []ir.Node, typ ir.Ntype, exprs []ir.Node, embeds []PragmaEmbed) (newExprs []ir.Node) {
        haveEmbed := false
        for _, decl := range p.file.DeclList {
                imp, ok := decl.(*syntax.ImportDecl)
@@ -141,8 +141,10 @@ func embedKindApprox(typ ir.Node) int {
        if typ.Sym() != nil && typ.Sym().Name == "string" && typ.Sym().Pkg == ir.LocalPkg {
                return embedString
        }
-       if typ.Op() == ir.OTARRAY && typ.Left() == nil && typ.Right().Sym() != nil && typ.Right().Sym().Name == "byte" && typ.Right().Sym().Pkg == ir.LocalPkg {
-               return embedBytes
+       if typ, ok := typ.(*ir.SliceType); ok {
+               if sym := typ.Elem.Sym(); sym != nil && sym.Name == "byte" && sym.Pkg == ir.LocalPkg {
+                       return embedBytes
+               }
        }
        return embedUnknown
 }
index 3f0f381974ea3de9fc76e0c4cb9d1b75add6972b..c9f5d0c85c401f1fd88482962f1fca417b8bc654 100644 (file)
@@ -1056,9 +1056,6 @@ func (w *exportWriter) stmt(n ir.Node) {
                w.localName(n.Left())
                w.typ(n.Left().Type())
 
-       // case ODCLFIELD:
-       //      unimplemented - handled by default case
-
        case ir.OAS:
                // Don't export "v = <N>" initializing statements, hope they're always
                // preceded by the DCL which will be re-parsed and typecheck to reproduce
index 88f6e36e0735f1459160d27c99a33fa6748205ed..c219b70e0fc4b23cd083e039e4df5ae19977e35f 100644 (file)
@@ -974,9 +974,6 @@ func (r *importReader) node() ir.Node {
                typ := ir.TypeNode(r.typ())
                return npos(pos, liststmt(variter([]ir.Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
 
-       // case ODCLFIELD:
-       //      unimplemented
-
        // case OAS, OASWB:
        //      unreachable - mapped to OAS case below by exporter
 
index 7f2a39ff464ff332804d93f9eff95e8ed3cfbe7a..ed0218c0e2363730ea5b9d7fe017d2d564aab567 100644 (file)
@@ -48,7 +48,7 @@ func fninit(n []ir.Node) {
        if len(nf) > 0 {
                base.Pos = nf[0].Pos() // prolog/epilog gets line number of first init stmt
                initializers := lookup("init")
-               fn := dclfunc(initializers, ir.Nod(ir.OTFUNC, nil, nil))
+               fn := dclfunc(initializers, ir.NewFuncType(base.Pos, nil, nil, nil))
                for _, dcl := range initTodo.Dcl {
                        dcl.Name().Curfn = fn
                }
index d763f1ebee8e99ba843364cc652679ab5bf95ec4..5317484de9ec6ac8ca89818b18760bdca2f54aab 100644 (file)
@@ -207,7 +207,7 @@ func (i *typeInterner) fields(fl *ast.FieldList, keepNames bool) string {
                        }
                }
        }
-       return fmt.Sprintf("[]ir.Node{%s}", strings.Join(res, ", "))
+       return fmt.Sprintf("[]*ir.Field{%s}", strings.Join(res, ", "))
 }
 
 func intconst(e ast.Expr) int64 {
index 1c433b5d30085d4da9577b05b56ba3ebc31b0491..e6c78d1afb5d9d4cbfb86c60dda1baf0142c5f03 100644 (file)
@@ -412,7 +412,7 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []ir.Node {
 // constant declarations are handled correctly (e.g., issue 15550).
 type constState struct {
        group  *syntax.Group
-       typ    ir.Node
+       typ    ir.Ntype
        values []ir.Node
        iota   int64
 }
@@ -578,18 +578,18 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node {
        return f
 }
 
-func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) ir.Node {
-       n := p.nod(typ, ir.OTFUNC, nil, nil)
+func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *ir.FuncType {
+       var rcvr *ir.Field
        if recv != nil {
-               n.SetLeft(p.param(recv, false, false))
+               rcvr = p.param(recv, false, false)
        }
-       n.PtrList().Set(p.params(typ.ParamList, true))
-       n.PtrRlist().Set(p.params(typ.ResultList, false))
-       return n
+       return ir.NewFuncType(p.pos(typ), rcvr,
+               p.params(typ.ParamList, true),
+               p.params(typ.ResultList, false))
 }
 
-func (p *noder) params(params []*syntax.Field, dddOk bool) []ir.Node {
-       nodes := make([]ir.Node, 0, len(params))
+func (p *noder) params(params []*syntax.Field, dddOk bool) []*ir.Field {
+       nodes := make([]*ir.Field, 0, len(params))
        for i, param := range params {
                p.setlineno(param)
                nodes = append(nodes, p.param(param, dddOk, i+1 == len(params)))
@@ -597,17 +597,17 @@ func (p *noder) params(params []*syntax.Field, dddOk bool) []ir.Node {
        return nodes
 }
 
-func (p *noder) param(param *syntax.Field, dddOk, final bool) ir.Node {
+func (p *noder) param(param *syntax.Field, dddOk, final bool) *ir.Field {
        var name *types.Sym
        if param.Name != nil {
                name = p.name(param.Name)
        }
 
        typ := p.typeExpr(param.Type)
-       n := p.nodSym(param, ir.ODCLFIELD, typ, name)
+       n := ir.NewField(p.pos(param), name, typ, nil)
 
        // rewrite ...T parameter
-       if typ.Op() == ir.ODDD {
+       if typ, ok := typ.(*ir.SliceType); ok && typ.DDD {
                if !dddOk {
                        // We mark these as syntax errors to get automatic elimination
                        // of multiple such errors per line (see ErrorfAt in subr.go).
@@ -619,13 +619,8 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) ir.Node {
                                p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
                        }
                }
-               typ.SetOp(ir.OTARRAY)
-               typ.SetRight(typ.Left())
-               typ.SetLeft(nil)
-               n.SetIsDDD(true)
-               if n.Left() != nil {
-                       n.Left().SetIsDDD(true)
-               }
+               typ.DDD = false
+               n.IsDDD = true
        }
 
        return n
@@ -727,14 +722,14 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
                var len ir.Node
                if expr.Len != nil {
                        len = p.expr(expr.Len)
-               } else {
-                       len = p.nod(expr, ir.ODDD, nil, nil)
                }
-               return p.nod(expr, ir.OTARRAY, len, p.typeExpr(expr.Elem))
+               return ir.NewArrayType(p.pos(expr), len, p.typeExpr(expr.Elem))
        case *syntax.SliceType:
-               return p.nod(expr, ir.OTARRAY, nil, p.typeExpr(expr.Elem))
+               return ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
        case *syntax.DotsType:
-               return p.nod(expr, ir.ODDD, p.typeExpr(expr.Elem), nil)
+               t := ir.NewSliceType(p.pos(expr), p.typeExpr(expr.Elem))
+               t.DDD = true
+               return t
        case *syntax.StructType:
                return p.structType(expr)
        case *syntax.InterfaceType:
@@ -742,11 +737,11 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
        case *syntax.FuncType:
                return p.signature(nil, expr)
        case *syntax.MapType:
-               return p.nod(expr, ir.OTMAP, p.typeExpr(expr.Key), p.typeExpr(expr.Value))
+               return ir.NewMapType(p.pos(expr),
+                       p.typeExpr(expr.Key), p.typeExpr(expr.Value))
        case *syntax.ChanType:
-               n := p.nod(expr, ir.OTCHAN, p.typeExpr(expr.Elem), nil)
-               n.SetTChanDir(p.chanDir(expr.Dir))
-               return n
+               return ir.NewChanType(p.pos(expr),
+                       p.typeExpr(expr.Elem), p.chanDir(expr.Dir))
 
        case *syntax.TypeSwitchGuard:
                n := p.nod(expr, ir.OTYPESW, nil, p.expr(expr.X))
@@ -837,14 +832,21 @@ func (p *noder) sum(x syntax.Expr) ir.Node {
        return n
 }
 
-func (p *noder) typeExpr(typ syntax.Expr) ir.Node {
+func (p *noder) typeExpr(typ syntax.Expr) ir.Ntype {
        // TODO(mdempsky): Be stricter? typecheck should handle errors anyway.
-       return p.expr(typ)
+       n := p.expr(typ)
+       if n == nil {
+               return nil
+       }
+       if _, ok := n.(ir.Ntype); !ok {
+               ir.Dump("NOT NTYPE", n)
+       }
+       return n.(ir.Ntype)
 }
 
-func (p *noder) typeExprOrNil(typ syntax.Expr) ir.Node {
+func (p *noder) typeExprOrNil(typ syntax.Expr) ir.Ntype {
        if typ != nil {
-               return p.expr(typ)
+               return p.typeExpr(typ)
        }
        return nil
 }
@@ -862,47 +864,43 @@ func (p *noder) chanDir(dir syntax.ChanDir) types.ChanDir {
 }
 
 func (p *noder) structType(expr *syntax.StructType) ir.Node {
-       l := make([]ir.Node, 0, len(expr.FieldList))
+       l := make([]*ir.Field, 0, len(expr.FieldList))
        for i, field := range expr.FieldList {
                p.setlineno(field)
-               var n ir.Node
+               var n *ir.Field
                if field.Name == nil {
                        n = p.embedded(field.Type)
                } else {
-                       n = p.nodSym(field, ir.ODCLFIELD, p.typeExpr(field.Type), p.name(field.Name))
+                       n = ir.NewField(p.pos(field), p.name(field.Name), p.typeExpr(field.Type), nil)
                }
                if i < len(expr.TagList) && expr.TagList[i] != nil {
-                       n.SetOpt(constant.StringVal(p.basicLit(expr.TagList[i])))
+                       n.Note = constant.StringVal(p.basicLit(expr.TagList[i]))
                }
                l = append(l, n)
        }
 
        p.setlineno(expr)
-       n := p.nod(expr, ir.OTSTRUCT, nil, nil)
-       n.PtrList().Set(l)
-       return n
+       return ir.NewStructType(p.pos(expr), l)
 }
 
 func (p *noder) interfaceType(expr *syntax.InterfaceType) ir.Node {
-       l := make([]ir.Node, 0, len(expr.MethodList))
+       l := make([]*ir.Field, 0, len(expr.MethodList))
        for _, method := range expr.MethodList {
                p.setlineno(method)
-               var n ir.Node
+               var n *ir.Field
                if method.Name == nil {
-                       n = p.nodSym(method, ir.ODCLFIELD, importName(p.packname(method.Type)), nil)
+                       n = ir.NewField(p.pos(method), nil, importName(p.packname(method.Type)).(ir.Ntype), nil)
                } else {
                        mname := p.name(method.Name)
-                       sig := p.typeExpr(method.Type)
-                       sig.SetLeft(fakeRecv())
-                       n = p.nodSym(method, ir.ODCLFIELD, sig, mname)
+                       sig := p.typeExpr(method.Type).(*ir.FuncType)
+                       sig.Recv = fakeRecv()
+                       n = ir.NewField(p.pos(method), mname, sig, nil)
                        ifacedcl(n)
                }
                l = append(l, n)
        }
 
-       n := p.nod(expr, ir.OTINTER, nil, nil)
-       n.PtrList().Set(l)
-       return n
+       return ir.NewInterfaceType(p.pos(expr), l)
 }
 
 func (p *noder) packname(expr syntax.Expr) *types.Sym {
@@ -934,7 +932,7 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym {
        panic(fmt.Sprintf("unexpected packname: %#v", expr))
 }
 
-func (p *noder) embedded(typ syntax.Expr) ir.Node {
+func (p *noder) embedded(typ syntax.Expr) *ir.Field {
        op, isStar := typ.(*syntax.Operation)
        if isStar {
                if op.Op != syntax.Mul || op.Y != nil {
@@ -944,11 +942,11 @@ func (p *noder) embedded(typ syntax.Expr) ir.Node {
        }
 
        sym := p.packname(typ)
-       n := p.nodSym(typ, ir.ODCLFIELD, importName(sym), lookup(sym.Name))
-       n.SetEmbedded(true)
+       n := ir.NewField(p.pos(typ), lookup(sym.Name), importName(sym).(ir.Ntype), nil)
+       n.Embedded = true
 
        if isStar {
-               n.SetLeft(p.nod(op, ir.ODEREF, n.Left(), nil))
+               n.Ntype = ir.NewStarExpr(p.pos(op), n.Ntype)
        }
        return n
 }
index dc9efc07fef0abd203908e25f48af86f58700f62..73d369f413b42d1ed3fea58fb943207d84ca1756 100644 (file)
@@ -347,7 +347,7 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
        if receiver != nil {
                inLen++
        }
-       in := make([]ir.Node, 0, inLen)
+       in := make([]*ir.Field, 0, inLen)
 
        if receiver != nil {
                d := anonfield(receiver)
@@ -356,12 +356,12 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
 
        for _, t := range f.Params().Fields().Slice() {
                d := anonfield(t.Type)
-               d.SetIsDDD(t.IsDDD())
+               d.IsDDD = t.IsDDD()
                in = append(in, d)
        }
 
        outLen := f.Results().Fields().Len()
-       out := make([]ir.Node, 0, outLen)
+       out := make([]*ir.Field, 0, outLen)
        for _, t := range f.Results().Fields().Slice() {
                d := anonfield(t.Type)
                out = append(out, d)
@@ -1626,7 +1626,7 @@ func dumpbasictypes() {
                // The latter is the type of an auto-generated wrapper.
                dtypesym(types.NewPtr(types.Errortype))
 
-               dtypesym(functype(nil, []ir.Node{anonfield(types.Errortype)}, []ir.Node{anonfield(types.Types[types.TSTRING])}))
+               dtypesym(functype(nil, []*ir.Field{anonfield(types.Errortype)}, []*ir.Field{anonfield(types.Types[types.TSTRING])}))
 
                // add paths for runtime and main, which 6l imports implicitly.
                dimportpath(Runtimepkg)
index 116b6f5b6e657675ebf96f0c35b71d6312f0eac1..9668df082a7538c48924c0aa1aabfb36062bedc7 100644 (file)
@@ -381,7 +381,7 @@ var scase *types.Type
 // Keep in sync with src/runtime/select.go.
 func scasetype() *types.Type {
        if scase == nil {
-               scase = tostruct([]ir.Node{
+               scase = tostruct([]*ir.Field{
                        namedfield("c", types.Types[types.TUNSAFEPTR]),
                        namedfield("elem", types.Types[types.TUNSAFEPTR]),
                })
index 25490246e6d0b937e8cf5478df1c81a43719ec3c..b1c9d24d991f2596e6ea1d4c302c3b311b81d443 100644 (file)
@@ -1062,9 +1062,9 @@ func expandmeth(t *types.Type) {
        t.AllMethods().Set(ms)
 }
 
-// Given funarg struct list, return list of ODCLFIELD Node fn args.
-func structargs(tl *types.Type, mustname bool) []ir.Node {
-       var args []ir.Node
+// Given funarg struct list, return list of fn args.
+func structargs(tl *types.Type, mustname bool) []*ir.Field {
+       var args []*ir.Field
        gen := 0
        for _, t := range tl.Fields().Slice() {
                s := t.Sym
@@ -1074,8 +1074,8 @@ func structargs(tl *types.Type, mustname bool) []ir.Node {
                        gen++
                }
                a := symfield(s, t.Type)
-               a.SetPos(t.Pos)
-               a.SetIsDDD(t.IsDDD())
+               a.Pos = t.Pos
+               a.IsDDD = t.IsDDD()
                args = append(args, a)
        }
 
@@ -1123,10 +1123,10 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
        base.Pos = autogeneratedPos
        dclcontext = ir.PEXTERN
 
-       tfn := ir.Nod(ir.OTFUNC, nil, nil)
-       tfn.SetLeft(namedfield(".this", rcvr))
-       tfn.PtrList().Set(structargs(method.Type.Params(), true))
-       tfn.PtrRlist().Set(structargs(method.Type.Results(), false))
+       tfn := ir.NewFuncType(base.Pos,
+               namedfield(".this", rcvr),
+               structargs(method.Type.Params(), true),
+               structargs(method.Type.Results(), false))
 
        fn := dclfunc(newnam, tfn)
        fn.SetDupok(true)
@@ -1215,11 +1215,11 @@ func hashmem(t *types.Type) ir.Node {
 
        n := NewName(sym)
        setNodeNameFunc(n)
-       n.SetType(functype(nil, []ir.Node{
+       n.SetType(functype(nil, []*ir.Field{
                anonfield(types.NewPtr(t)),
                anonfield(types.Types[types.TUINTPTR]),
                anonfield(types.Types[types.TUINTPTR]),
-       }, []ir.Node{
+       }, []*ir.Field{
                anonfield(types.Types[types.TUINTPTR]),
        }))
        return n
index a1b18097906db7e959f584a896ba5d64da4c3712..19146e2a9e795a91f075743aaf8086bb12b4beb2 100644 (file)
@@ -206,6 +206,10 @@ func typecheckFunc(fn *ir.Func) {
        }
 }
 
+func typecheckNtype(n ir.Ntype) ir.Ntype {
+       return typecheck(n, ctxType).(ir.Ntype)
+}
+
 // typecheck type checks node n.
 // The result of typecheck MUST be assigned back to n, e.g.
 //     n.Left = typecheck(n.Left, top)
@@ -403,9 +407,6 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                n.SetType(nil)
                return n
 
-       case ir.ODDD:
-               break
-
        // types (ODEREF is with exprs)
        case ir.OTYPE:
                ok |= ctxType
@@ -414,70 +415,69 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                        return n
                }
 
-       case ir.OTARRAY:
+       case ir.OTSLICE:
                ok |= ctxType
-               r := typecheck(n.Right(), ctxType)
-               if r.Type() == nil {
-                       n.SetType(nil)
+               n := n.(*ir.SliceType)
+               n.Elem = typecheck(n.Elem, ctxType)
+               if n.Elem.Type() == nil {
                        return n
                }
+               t := types.NewSlice(n.Elem.Type())
+               n.SetOTYPE(t)
+               checkwidth(t)
 
-               var t *types.Type
-               if n.Left() == nil {
-                       t = types.NewSlice(r.Type())
-               } else if n.Left().Op() == ir.ODDD {
+       case ir.OTARRAY:
+               ok |= ctxType
+               n := n.(*ir.ArrayType)
+               n.Elem = typecheck(n.Elem, ctxType)
+               if n.Elem.Type() == nil {
+                       return n
+               }
+               if n.Len == nil { // [...]T
                        if !n.Diag() {
                                n.SetDiag(true)
                                base.Errorf("use of [...] array outside of array literal")
                        }
-                       n.SetType(nil)
                        return n
-               } else {
-                       n.SetLeft(indexlit(typecheck(n.Left(), ctxExpr)))
-                       l := n.Left()
-                       if ir.ConstType(l) != constant.Int {
-                               switch {
-                               case l.Type() == nil:
-                                       // Error already reported elsewhere.
-                               case l.Type().IsInteger() && l.Op() != ir.OLITERAL:
-                                       base.Errorf("non-constant array bound %v", l)
-                               default:
-                                       base.Errorf("invalid array bound %v", l)
-                               }
-                               n.SetType(nil)
-                               return n
-                       }
-
-                       v := l.Val()
-                       if doesoverflow(v, types.Types[types.TINT]) {
-                               base.Errorf("array bound is too large")
-                               n.SetType(nil)
-                               return n
+               }
+               n.Len = indexlit(typecheck(n.Len, ctxExpr))
+               size := n.Len
+               if ir.ConstType(size) != constant.Int {
+                       switch {
+                       case size.Type() == nil:
+                               // Error already reported elsewhere.
+                       case size.Type().IsInteger() && size.Op() != ir.OLITERAL:
+                               base.Errorf("non-constant array bound %v", size)
+                       default:
+                               base.Errorf("invalid array bound %v", size)
                        }
+                       return n
+               }
 
-                       if constant.Sign(v) < 0 {
-                               base.Errorf("array bound must be non-negative")
-                               n.SetType(nil)
-                               return n
-                       }
+               v := size.Val()
+               if doesoverflow(v, types.Types[types.TINT]) {
+                       base.Errorf("array bound is too large")
+                       return n
+               }
 
-                       bound, _ := constant.Int64Val(v)
-                       t = types.NewArray(r.Type(), bound)
+               if constant.Sign(v) < 0 {
+                       base.Errorf("array bound must be non-negative")
+                       return n
                }
 
-               setTypeNode(n, t)
-               n.SetLeft(nil)
-               n.SetRight(nil)
+               bound, _ := constant.Int64Val(v)
+               t := types.NewArray(n.Elem.Type(), bound)
+               n.SetOTYPE(t)
                checkwidth(t)
 
        case ir.OTMAP:
                ok |= ctxType
-               n.SetLeft(typecheck(n.Left(), ctxType))
-               n.SetRight(typecheck(n.Right(), ctxType))
-               l := n.Left()
-               r := n.Right()
+               n := n.(*ir.MapType)
+               n.Key = typecheck(n.Key, ctxType)
+               n.Elem = typecheck(n.Elem, ctxType)
+               l := n.Key
+               r := n.Elem
                if l.Type() == nil || r.Type() == nil {
-                       n.SetType(nil)
                        return n
                }
                if l.Type().NotInHeap() {
@@ -486,48 +486,42 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                if r.Type().NotInHeap() {
                        base.Errorf("incomplete (or unallocatable) map value not allowed")
                }
-
-               setTypeNode(n, types.NewMap(l.Type(), r.Type()))
+               n.SetOTYPE(types.NewMap(l.Type(), r.Type()))
                mapqueue = append(mapqueue, n) // check map keys when all types are settled
-               n.SetLeft(nil)
-               n.SetRight(nil)
 
        case ir.OTCHAN:
                ok |= ctxType
-               n.SetLeft(typecheck(n.Left(), ctxType))
-               l := n.Left()
+               n := n.(*ir.ChanType)
+               n.Elem = typecheck(n.Elem, ctxType)
+               l := n.Elem
                if l.Type() == nil {
-                       n.SetType(nil)
                        return n
                }
                if l.Type().NotInHeap() {
                        base.Errorf("chan of incomplete (or unallocatable) type not allowed")
                }
-
-               setTypeNode(n, types.NewChan(l.Type(), n.TChanDir()))
-               n.SetLeft(nil)
-               n.ResetAux()
+               n.SetOTYPE(types.NewChan(l.Type(), n.Dir))
 
        case ir.OTSTRUCT:
                ok |= ctxType
-               setTypeNode(n, tostruct(n.List().Slice()))
-               n.PtrList().Set(nil)
+               n := n.(*ir.StructType)
+               n.SetOTYPE(tostruct(n.Fields))
 
        case ir.OTINTER:
                ok |= ctxType
-               setTypeNode(n, tointerface(n.List().Slice()))
+               n := n.(*ir.InterfaceType)
+               n.SetOTYPE(tointerface(n.Methods))
 
        case ir.OTFUNC:
                ok |= ctxType
-               setTypeNode(n, functype(n.Left(), n.List().Slice(), n.Rlist().Slice()))
-               n.SetLeft(nil)
-               n.PtrList().Set(nil)
-               n.PtrRlist().Set(nil)
+               n := n.(*ir.FuncType)
+               n.SetOTYPE(functype(n.Recv, n.Params, n.Results))
 
        // type or expr
        case ir.ODEREF:
-               n.SetLeft(typecheck(n.Left(), ctxExpr|ctxType))
-               l := n.Left()
+               n := n.(*ir.StarExpr)
+               n.X = typecheck(n.X, ctxExpr|ctxType)
+               l := n.X
                t := l.Type()
                if t == nil {
                        n.SetType(nil)
@@ -535,8 +529,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
                }
                if l.Op() == ir.OTYPE {
                        ok |= ctxType
-                       setTypeNode(n, types.NewPtr(l.Type()))
-                       n.SetLeft(nil)
+                       n.SetOTYPE(types.NewPtr(l.Type()))
                        // Ensure l.Type gets dowidth'd for the backend. Issue 20174.
                        checkwidth(l.Type())
                        break
@@ -2822,16 +2815,14 @@ func typecheckcomplit(n ir.Node) (res ir.Node) {
        setlineno(n.Right())
 
        // Need to handle [...]T arrays specially.
-       if n.Right().Op() == ir.OTARRAY && n.Right().Left() != nil && n.Right().Left().Op() == ir.ODDD {
-               n.Right().SetRight(typecheck(n.Right().Right(), ctxType))
-               if n.Right().Right().Type() == nil {
+       if array, ok := n.Right().(*ir.ArrayType); ok && array.Elem != nil && array.Len == nil {
+               array.Elem = typecheck(array.Elem, ctxType)
+               elemType := array.Elem.Type()
+               if elemType == nil {
                        n.SetType(nil)
                        return n
                }
-               elemType := n.Right().Right().Type()
-
                length := typecheckarraylit(elemType, -1, n.List().Slice(), "array literal")
-
                n.SetOp(ir.OARRAYLIT)
                n.SetType(types.NewArray(elemType, length))
                n.SetRight(nil)
@@ -3464,7 +3455,7 @@ func stringtoruneslit(n ir.Node) ir.Node {
        return nn
 }
 
-var mapqueue []ir.Node
+var mapqueue []*ir.MapType
 
 func checkMapKeys() {
        for _, n := range mapqueue {
@@ -3531,7 +3522,7 @@ func typecheckdeftype(n ir.Node) {
        }
 
        n.SetTypecheck(1)
-       n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
+       n.Name().Ntype = typecheckNtype(n.Name().Ntype)
        t := n.Name().Ntype.Type()
        if t == nil {
                n.SetDiag(true)
@@ -3593,7 +3584,7 @@ func typecheckdef(n ir.Node) {
 
        case ir.OLITERAL:
                if n.Name().Ntype != nil {
-                       n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
+                       n.Name().Ntype = typecheckNtype(n.Name().Ntype)
                        n.SetType(n.Name().Ntype.Type())
                        n.Name().Ntype = nil
                        if n.Type() == nil {
@@ -3647,7 +3638,7 @@ func typecheckdef(n ir.Node) {
 
        case ir.ONAME:
                if n.Name().Ntype != nil {
-                       n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
+                       n.Name().Ntype = typecheckNtype(n.Name().Ntype)
                        n.SetType(n.Name().Ntype.Type())
                        if n.Type() == nil {
                                n.SetDiag(true)
@@ -3686,9 +3677,9 @@ func typecheckdef(n ir.Node) {
                if n.Alias() {
                        // Type alias declaration: Simply use the rhs type - no need
                        // to create a new type.
-                       // If we have a syntax error, p.Ntype may be nil.
+                       // If we have a syntax error, name.Ntype may be nil.
                        if n.Ntype != nil {
-                               n.Ntype = typecheck(n.Ntype, ctxType)
+                               n.Ntype = typecheckNtype(n.Ntype)
                                n.SetType(n.Ntype.Type())
                                if n.Type() == nil {
                                        n.SetDiag(true)
@@ -3706,8 +3697,10 @@ func typecheckdef(n ir.Node) {
                // regular type declaration
                defercheckwidth()
                n.SetWalkdef(1)
-               setTypeNode(n, types.New(types.TFORW))
-               n.Type().Sym = n.Sym()
+               t := types.New(types.TFORW)
+               t.Nod = n
+               t.Sym = n.Sym()
+               n.SetType(t)
                errorsBefore := base.Errors()
                typecheckdeftype(n)
                if n.Type().Etype == types.TFORW && base.Errors() > errorsBefore {
@@ -3990,11 +3983,12 @@ func deadcodeexpr(n ir.Node) ir.Node {
        return n
 }
 
-// setTypeNode sets n to an OTYPE node representing t.
-func setTypeNode(n ir.Node, t *types.Type) {
-       n.SetOp(ir.OTYPE)
+func toTypeNode(orig ir.Node, t *types.Type) ir.Node {
+       n := ir.Nod(ir.OTYPE, nil, nil)
+       n.SetPos(orig.Pos())
        n.SetType(t)
-       n.Type().Nod = n
+       t.Nod = n
+       return n
 }
 
 // getIotaValue returns the current value for "iota",
index 931135759ac84c6db08d07d90ed69613448912b1..d43545391cfc727263de47ba46276afd1df0010a 100644 (file)
@@ -176,7 +176,10 @@ func typeinit() {
        t := types.New(types.TUNSAFEPTR)
        types.Types[types.TUNSAFEPTR] = t
        t.Sym = unsafepkg.Lookup("Pointer")
-       t.Sym.Def = ir.TypeNode(t)
+       n := ir.NewNameAt(src.NoXPos, t.Sym) // NewNameAt to get a package for use tracking
+       n.SetOp(ir.OTYPE)
+       n.SetType(t)
+       t.Sym.Def = n
        dowidth(types.Types[types.TUNSAFEPTR])
 
        for et := types.TINT8; et <= types.TUINT64; et++ {
index 2376bfc0935033be03fa55ffc5edd4061bd301a5..e7c88bd3296109bdead7d17f7e55fdf46a6565bb 100644 (file)
@@ -853,7 +853,7 @@ opswitch:
                        }
                        value = ir.Nod(ir.OINDEX, staticuint64s, index)
                        value.SetBounded(true)
-               case n.Left().Class() == ir.PEXTERN && n.Left().Name() != nil && n.Left().Name().Readonly():
+               case n.Left().Name() != nil && n.Left().Class() == ir.PEXTERN && n.Left().Name().Readonly():
                        // n.Left is a readonly global; use it directly.
                        value = n.Left()
                case !fromType.IsInterface() && n.Esc() == EscNone && fromType.Width <= 1024:
@@ -3183,10 +3183,10 @@ func eqfor(t *types.Type) (n ir.Node, needsize bool) {
                sym := typesymprefix(".eq", t)
                n := NewName(sym)
                setNodeNameFunc(n)
-               n.SetType(functype(nil, []ir.Node{
+               n.SetType(functype(nil, []*ir.Field{
                        anonfield(types.NewPtr(t)),
                        anonfield(types.NewPtr(t)),
-               }, []ir.Node{
+               }, []*ir.Field{
                        anonfield(types.Types[types.TBOOL]),
                }))
                return n, false
@@ -3914,7 +3914,7 @@ func wrapCall(n ir.Node, init *ir.Nodes) ir.Node {
 
        // origArgs keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion.
        origArgs := make([]ir.Node, n.List().Len())
-       t := ir.Nod(ir.OTFUNC, nil, nil)
+       var funcArgs []*ir.Field
        for i, arg := range n.List().Slice() {
                s := lookupN("a", i)
                if !isBuiltinCall && arg.Op() == ir.OCONVNOP && arg.Type().IsUintptr() && arg.Left().Type().IsUnsafePtr() {
@@ -3922,8 +3922,9 @@ func wrapCall(n ir.Node, init *ir.Nodes) ir.Node {
                        arg = arg.Left()
                        n.List().SetIndex(i, arg)
                }
-               t.PtrList().Append(symfield(s, arg.Type()))
+               funcArgs = append(funcArgs, symfield(s, arg.Type()))
        }
+       t := ir.NewFuncType(base.Pos, nil, funcArgs, nil)
 
        wrapCall_prgen++
        sym := lookupN("wrap·", wrapCall_prgen)
index 2c1391859972e5150be680ef49f410f5fd3fa3d5..f8e5f7641ca154a8e00f416347f7a1e205c701af 100644 (file)
@@ -110,3 +110,47 @@ func (n *CallPartExpr) Left() Node                    { return n.X }
 func (n *CallPartExpr) Right() Node                   { return n.Method }
 func (n *CallPartExpr) SetLeft(x Node)                { n.X = x }
 func (n *CallPartExpr) SetRight(x Node)               { n.Method = x.(*Name) }
+
+// A StarExpr is a dereference expression *X.
+// It may end up being a value or a type.
+type StarExpr struct {
+       miniExpr
+       X Node
+}
+
+func NewStarExpr(pos src.XPos, x Node) *StarExpr {
+       n := &StarExpr{X: x}
+       n.op = ODEREF
+       n.pos = pos
+       return n
+}
+
+func (n *StarExpr) String() string                { return fmt.Sprint(n) }
+func (n *StarExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *StarExpr) RawCopy() Node                 { c := *n; return &c }
+func (n *StarExpr) Left() Node                    { return n.X }
+func (n *StarExpr) SetLeft(x Node)                { n.X = x }
+
+func (*StarExpr) CanBeNtype() {}
+
+// SetOTYPE changes n to be an OTYPE node returning t,
+// like all the type nodes in type.go.
+func (n *StarExpr) SetOTYPE(t *types.Type) {
+       n.op = OTYPE
+       n.X = nil
+       n.typ = t
+       if t.Nod == nil {
+               t.Nod = n
+       }
+}
+
+func (n *StarExpr) DeepCopy(pos src.XPos) Node {
+       if n.op == OTYPE {
+               // Can't change types and no node references left.
+               return n
+       }
+       c := SepCopy(n).(*StarExpr)
+       c.pos = n.posOr(pos)
+       c.X = DeepCopy(pos, n.X)
+       return c
+}
index a3999b6da038073b0338863239dfaf643c707a7a..c723bad4c9332fc4138112a7e9b7cea7572646ec 100644 (file)
@@ -403,10 +403,6 @@ func jconvFmt(n Node, s fmt.State, flag FmtFlag) {
                fmt.Fprintf(s, " implicit(%v)", n.Implicit())
        }
 
-       if n.Embedded() {
-               fmt.Fprintf(s, " embedded")
-       }
-
        if n.Op() == ONAME {
                if n.Name().Addrtaken() {
                        fmt.Fprint(s, " addrtaken")
@@ -921,13 +917,6 @@ func stmtFmt(n Node, s fmt.State, mode FmtMode) {
        case ODCL:
                mode.Fprintf(s, "var %v %v", n.Left().Sym(), n.Left().Type())
 
-       case ODCLFIELD:
-               if n.Sym() != nil {
-                       mode.Fprintf(s, "%v %v", n.Sym(), n.Left())
-               } else {
-                       mode.Fprintf(s, "%v", n.Left())
-               }
-
        // Don't export "v = <N>" initializing statements, hope they're always
        // preceded by the DCL which will be re-parsed and typechecked to reproduce
        // the "v = <N>" again.
@@ -1115,6 +1104,7 @@ var OpPrec = []int{
        OSTR2RUNES:     8,
        OSTRUCTLIT:     8,
        OTARRAY:        8,
+       OTSLICE:        8,
        OTCHAN:         8,
        OTFUNC:         8,
        OTINTER:        8,
@@ -1176,7 +1166,6 @@ var OpPrec = []int{
        OCASE:       -1,
        OCONTINUE:   -1,
        ODCL:        -1,
-       ODCLFIELD:   -1,
        ODEFER:      -1,
        OEMPTY:      -1,
        OFALL:       -1,
@@ -1294,29 +1283,40 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
                }
                mode.Fprintf(s, "%v", n.Type())
 
+       case OTSLICE:
+               n := n.(*SliceType)
+               if n.DDD {
+                       mode.Fprintf(s, "...%v", n.Elem)
+               } else {
+                       mode.Fprintf(s, "[]%v", n.Elem) // happens before typecheck
+               }
+
        case OTARRAY:
-               if n.Left() != nil {
-                       mode.Fprintf(s, "[%v]%v", n.Left(), n.Right())
-                       return
+               n := n.(*ArrayType)
+               if n.Len == nil {
+                       mode.Fprintf(s, "[...]%v", n.Elem)
+               } else {
+                       mode.Fprintf(s, "[%v]%v", n.Len, n.Elem)
                }
-               mode.Fprintf(s, "[]%v", n.Right()) // happens before typecheck
 
        case OTMAP:
-               mode.Fprintf(s, "map[%v]%v", n.Left(), n.Right())
+               n := n.(*MapType)
+               mode.Fprintf(s, "map[%v]%v", n.Key, n.Elem)
 
        case OTCHAN:
-               switch n.TChanDir() {
+               n := n.(*ChanType)
+               switch n.Dir {
                case types.Crecv:
-                       mode.Fprintf(s, "<-chan %v", n.Left())
+                       mode.Fprintf(s, "<-chan %v", n.Elem)
 
                case types.Csend:
-                       mode.Fprintf(s, "chan<- %v", n.Left())
+                       mode.Fprintf(s, "chan<- %v", n.Elem)
 
                default:
-                       if n.Left() != nil && n.Left().Op() == OTCHAN && n.Left().Sym() == nil && n.Left().TChanDir() == types.Crecv {
-                               mode.Fprintf(s, "chan (%v)", n.Left())
+                       if n.Elem != nil && n.Elem.Op() == OTCHAN && n.Elem.(*ChanType).Dir == types.Crecv {
+                               mode.Fprintf(s, "chan (%v)", n.Elem)
                        } else {
-                               mode.Fprintf(s, "chan %v", n.Left())
+                               mode.Fprintf(s, "chan %v", n.Elem)
                        }
                }
 
@@ -1556,8 +1556,6 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
                        }
                        exprFmt(n1, s, nprec, mode)
                }
-       case ODDD:
-               mode.Fprintf(s, "...")
        default:
                mode.Fprintf(s, "<node %v>", n.Op())
        }
index 338ded3308f3218851a2fdc4978dbd7e84b43a5f..d73ec4ecd5ec0d2bc2e5de30d9036811d701a50f 100644 (file)
@@ -33,6 +33,15 @@ type miniNode struct {
        esc  uint16
 }
 
+// posOr returns pos if known, or else n.pos.
+// For use in DeepCopy.
+func (n *miniNode) posOr(pos src.XPos) src.XPos {
+       if pos.IsKnown() {
+               return pos
+       }
+       return n.pos
+}
+
 // op can be read, but not written.
 // An embedding implementation can provide a SetOp if desired.
 // (The panicking SetOp is with the other panics below.)
index 5546488fa7f168010217b0dad1d00795308a7202..1bc6bea3b670b37c9289633cddf064a739039cf4 100644 (file)
@@ -43,7 +43,7 @@ type Name struct {
        Vargen    int32
        Decldepth int32 // declaration loop depth, increased for every loop or label
 
-       Ntype    Node
+       Ntype    Ntype
        Heapaddr *Name // temp holding heap address of param
 
        // ONAME PAUTOHEAP
@@ -160,6 +160,8 @@ func (n *Name) SetOffset(x int64)             { n.offset = x }
 func (n *Name) Iota() int64                   { return n.offset }
 func (n *Name) SetIota(x int64)               { n.offset = x }
 
+func (*Name) CanBeNtype() {}
+
 func (n *Name) SetOp(op Op) {
        switch op {
        default:
@@ -371,6 +373,8 @@ func (p *PkgName) Format(s fmt.State, verb rune) { FmtNode(p, s, verb) }
 func (p *PkgName) RawCopy() Node                 { c := *p; return &c }
 func (p *PkgName) Sym() *types.Sym               { return p.sym }
 
+func (*PkgName) CanBeNtype() {}
+
 func NewPkgName(pos src.XPos, sym *types.Sym, pkg *types.Pkg) *PkgName {
        p := &PkgName{sym: sym, Pkg: pkg}
        p.op = OPACK
index 653410d175be947ec1b282103965158b3f5db833..74557236ccb1d001e10d5bc5b5c0e96d60139622 100644 (file)
@@ -79,12 +79,8 @@ type Node interface {
        SetImplicit(x bool)
        IsDDD() bool
        SetIsDDD(x bool)
-       Embedded() bool
-       SetEmbedded(x bool)
        IndexMapLValue() bool
        SetIndexMapLValue(x bool)
-       TChanDir() types.ChanDir
-       SetTChanDir(x types.ChanDir)
        ResetAux()
        HasBreak() bool
        SetHasBreak(x bool)
@@ -205,6 +201,10 @@ func (n *node) Uint64Val() uint64     { panic("node.Uint64Val") }
 func (n *node) BoolVal() bool         { panic("node.BoolVal") }
 func (n *node) StringVal() string     { panic("node.StringVal") }
 
+// node can be Ntype only because of OXDOT of undefined name.
+// When that moves into its own syntax, can drop this.
+func (n *node) CanBeNtype() {}
+
 func (n *node) SetOp(op Op) {
        if !okForNod[op] {
                panic("cannot node.SetOp " + op.String())
@@ -252,20 +252,6 @@ func (n *node) SetIndexMapLValue(b bool) {
        }
 }
 
-func (n *node) TChanDir() types.ChanDir {
-       if n.Op() != OTCHAN {
-               base.Fatalf("unexpected op: %v", n.Op())
-       }
-       return types.ChanDir(n.aux)
-}
-
-func (n *node) SetTChanDir(dir types.ChanDir) {
-       if n.Op() != OTCHAN {
-               base.Fatalf("unexpected op: %v", n.Op())
-       }
-       n.aux = uint8(dir)
-}
-
 func IsSynthetic(n Node) bool {
        name := n.Sym().Name
        return name[0] == '.' || name[0] == '~'
@@ -301,7 +287,6 @@ const (
        _, nodeBounded   // bounds check unnecessary
        _, nodeHasCall   // expression contains a function call
        _, nodeLikely    // if statement condition likely
-       _, nodeEmbedded  // ODCLFIELD embedded type
 )
 
 func (n *node) Class() Class     { return Class(n.flags.get3(nodeClass)) }
@@ -320,7 +305,6 @@ func (n *node) Transient() bool { return n.flags&nodeTransient != 0 }
 func (n *node) Bounded() bool   { return n.flags&nodeBounded != 0 }
 func (n *node) HasCall() bool   { return n.flags&nodeHasCall != 0 }
 func (n *node) Likely() bool    { return n.flags&nodeLikely != 0 }
-func (n *node) Embedded() bool  { return n.flags&nodeEmbedded != 0 }
 
 func (n *node) SetClass(b Class)     { n.flags.set3(nodeClass, uint8(b)) }
 func (n *node) SetWalkdef(b uint8)   { n.flags.set2(nodeWalkdef, b) }
@@ -336,7 +320,6 @@ func (n *node) SetColas(b bool)     { n.flags.set(nodeColas, b) }
 func (n *node) SetTransient(b bool) { n.flags.set(nodeTransient, b) }
 func (n *node) SetHasCall(b bool)   { n.flags.set(nodeHasCall, b) }
 func (n *node) SetLikely(b bool)    { n.flags.set(nodeLikely, b) }
-func (n *node) SetEmbedded(b bool)  { n.flags.set(nodeEmbedded, b) }
 
 // MarkNonNil marks a pointer n as being guaranteed non-nil,
 // on all code paths, at all times.
@@ -474,7 +457,7 @@ const (
 
        // Used during parsing but don't last.
        ODCLFUNC  // func f() or func (r) f()
-       ODCLFIELD // struct field, interface field, or func/method argument/return value.
+       ODCLFIELD // UNUSED: TODO(rsc): Delete.
        ODCLCONST // const pi = 3.14
        ODCLTYPE  // type Int int or type Int = int
 
@@ -593,11 +576,11 @@ const (
        // OTFUNC: func() - Left is receiver field, List is list of param fields, Rlist is
        // list of result fields.
        OTFUNC
-       OTARRAY // []int, [8]int, [N]int or [...]int
-       OTSLICE // to be used in future CL
+       OTARRAY // [8]int or [...]int
+       OTSLICE // []int
 
        // misc
-       ODDD         // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
+       ODDD         // UNUSED; TODO(rsc): Delete.
        OINLCALL     // intermediary representation of an inlined call.
        OEFACE       // itable and data words of an empty-interface value.
        OITAB        // itable word of an interface value.
@@ -1050,6 +1033,8 @@ func NodAt(pos src.XPos, op Op, nleft, nright Node) Node {
        switch op {
        case ODCLFUNC:
                return NewFunc(pos)
+       case ODEREF:
+               return NewStarExpr(pos, nleft)
        case OPACK:
                return NewPkgName(pos, nil, nil)
        case OEMPTY:
@@ -1112,12 +1097,9 @@ var okForNod = [OEND]bool{
        OCOPY:          true,
        ODCL:           true,
        ODCLCONST:      true,
-       ODCLFIELD:      true,
        ODCLTYPE:       true,
-       ODDD:           true,
        ODEFER:         true,
        ODELETE:        true,
-       ODEREF:         true,
        ODIV:           true,
        ODOT:           true,
        ODOTINTER:      true,
@@ -1201,13 +1183,6 @@ var okForNod = [OEND]bool{
        OSTRUCTLIT:     true,
        OSUB:           true,
        OSWITCH:        true,
-       OTARRAY:        true,
-       OTCHAN:         true,
-       OTFUNC:         true,
-       OTINTER:        true,
-       OTMAP:          true,
-       OTSTRUCT:       true,
-       OTYPE:          true, // TODO: Remove once setTypeNode is gone.
        OTYPESW:        true,
        OVARDEF:        true,
        OVARKILL:       true,
index 3409424fed2e8d25f5bbdcfe57b0a596d7691a32..39411ed43197658ead487a91029b32ce5c008da3 100644 (file)
@@ -7,21 +7,375 @@ package ir
 import (
        "cmd/compile/internal/types"
        "cmd/internal/src"
+       "fmt"
 )
 
-func TypeNode(t *types.Type) Node {
-       return TypeNodeAt(src.NoXPos, t)
+// Nodes that represent the syntax of a type before type-checking.
+// After type-checking, they serve only as shells around a *types.Type.
+// Calling TypeNode converts a *types.Type to a Node shell.
+
+// An Ntype is a Node that syntactically looks like a type.
+// It can be the raw syntax for a type before typechecking,
+// or it can be an OTYPE with Type() set to a *types.Type.
+// Note that syntax doesn't guarantee it's a type: an expression
+// like *fmt is an Ntype (we don't know whether names are types yet),
+// but at least 1+1 is not an Ntype.
+type Ntype interface {
+       Node
+       CanBeNtype()
+}
+
+// A miniType is a minimal type syntax Node implementation,
+// to be embedded as the first field in a larger node implementation.
+type miniType struct {
+       miniNode
+       typ *types.Type
+}
+
+func (*miniType) CanBeNtype() {}
+
+func (n *miniType) Type() *types.Type { return n.typ }
+
+// setOTYPE changes n to be an OTYPE node returning t.
+// Rewriting the node in place this way should not be strictly
+// necessary (we should be able to update the uses with
+// proper OTYPE nodes), but it's mostly harmless and easy
+// to keep doing for now.
+//
+// setOTYPE also records t.Nod = self if t.Nod is not already set.
+// (Some types are shared by multiple OTYPE nodes, so only
+// the first such node is used as t.Nod.)
+func (n *miniType) setOTYPE(t *types.Type, self Node) {
+       if n.typ != nil {
+               panic(n.op.String() + " SetType: type already set")
+       }
+       n.op = OTYPE
+       n.typ = t
+
+       // t.Nod can be non-nil already
+       // in the case of shared *type.Types, like []byte or interface{}.
+       if t.Nod == nil {
+               t.Nod = self
+       }
+}
+
+func (n *miniType) Sym() *types.Sym { return nil }   // for Format OTYPE
+func (n *miniType) Implicit() bool  { return false } // for Format OTYPE
+
+// A ChanType represents a chan Elem syntax with the direction Dir.
+type ChanType struct {
+       miniType
+       Elem Node
+       Dir  types.ChanDir
+}
+
+func NewChanType(pos src.XPos, elem Node, dir types.ChanDir) *ChanType {
+       n := &ChanType{Elem: elem, Dir: dir}
+       n.op = OTCHAN
+       n.pos = pos
+       return n
 }
 
-func TypeNodeAt(pos src.XPos, t *types.Type) Node {
-       // if we copied another type with *t = *u
-       // then t->nod might be out of date, so
-       // check t->nod->type too
-       if AsNode(t.Nod) == nil || AsNode(t.Nod).Type() != t {
-               t.Nod = NodAt(pos, OTYPE, nil, nil)
-               AsNode(t.Nod).SetType(t)
-               AsNode(t.Nod).SetSym(t.Sym)
+func (n *ChanType) String() string                { return fmt.Sprint(n) }
+func (n *ChanType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *ChanType) RawCopy() Node                 { c := *n; return &c }
+func (n *ChanType) SetOTYPE(t *types.Type) {
+       n.setOTYPE(t, n)
+       n.Elem = nil
+}
+
+func (n *ChanType) DeepCopy(pos src.XPos) Node {
+       if n.op == OTYPE {
+               // Can't change types and no node references left.
+               return n
        }
+       return NewChanType(n.posOr(pos), DeepCopy(pos, n.Elem), n.Dir)
+}
+
+// A MapType represents a map[Key]Value type syntax.u
+type MapType struct {
+       miniType
+       Key  Node
+       Elem Node
+}
+
+func NewMapType(pos src.XPos, key, elem Node) *MapType {
+       n := &MapType{Key: key, Elem: elem}
+       n.op = OTMAP
+       n.pos = pos
+       return n
+}
+
+func (n *MapType) String() string                { return fmt.Sprint(n) }
+func (n *MapType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *MapType) RawCopy() Node                 { c := *n; return &c }
+func (n *MapType) SetOTYPE(t *types.Type) {
+       n.setOTYPE(t, n)
+       n.Key = nil
+       n.Elem = nil
+}
+
+func (n *MapType) DeepCopy(pos src.XPos) Node {
+       if n.op == OTYPE {
+               // Can't change types and no node references left.
+               return n
+       }
+       return NewMapType(n.posOr(pos), DeepCopy(pos, n.Key), DeepCopy(pos, n.Elem))
+}
+
+// A StructType represents a struct { ... } type syntax.
+type StructType struct {
+       miniType
+       Fields []*Field
+}
+
+func NewStructType(pos src.XPos, fields []*Field) *StructType {
+       n := &StructType{Fields: fields}
+       n.op = OTSTRUCT
+       n.pos = pos
+       return n
+}
+
+func (n *StructType) String() string                { return fmt.Sprint(n) }
+func (n *StructType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *StructType) RawCopy() Node                 { c := *n; return &c }
+func (n *StructType) SetOTYPE(t *types.Type) {
+       n.setOTYPE(t, n)
+       n.Fields = nil
+}
+
+func (n *StructType) DeepCopy(pos src.XPos) Node {
+       if n.op == OTYPE {
+               // Can't change types and no node references left.
+               return n
+       }
+       return NewStructType(n.posOr(pos), deepCopyFields(pos, n.Fields))
+}
+
+func deepCopyFields(pos src.XPos, fields []*Field) []*Field {
+       var out []*Field
+       for _, f := range fields {
+               out = append(out, f.deepCopy(pos))
+       }
+       return out
+}
+
+// An InterfaceType represents a struct { ... } type syntax.
+type InterfaceType struct {
+       miniType
+       Methods []*Field
+}
+
+func NewInterfaceType(pos src.XPos, methods []*Field) *InterfaceType {
+       n := &InterfaceType{Methods: methods}
+       n.op = OTINTER
+       n.pos = pos
+       return n
+}
+
+func (n *InterfaceType) String() string                { return fmt.Sprint(n) }
+func (n *InterfaceType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *InterfaceType) RawCopy() Node                 { c := *n; return &c }
+func (n *InterfaceType) SetOTYPE(t *types.Type) {
+       n.setOTYPE(t, n)
+       n.Methods = nil
+}
+
+func (n *InterfaceType) DeepCopy(pos src.XPos) Node {
+       if n.op == OTYPE {
+               // Can't change types and no node references left.
+               return n
+       }
+       return NewInterfaceType(n.posOr(pos), deepCopyFields(pos, n.Methods))
+}
+
+// A FuncType represents a func(Args) Results type syntax.
+type FuncType struct {
+       miniType
+       Recv    *Field
+       Params  []*Field
+       Results []*Field
+}
 
-       return AsNode(t.Nod)
+func NewFuncType(pos src.XPos, rcvr *Field, args, results []*Field) *FuncType {
+       n := &FuncType{Recv: rcvr, Params: args, Results: results}
+       n.op = OTFUNC
+       n.pos = pos
+       return n
+}
+
+func (n *FuncType) String() string                { return fmt.Sprint(n) }
+func (n *FuncType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *FuncType) RawCopy() Node                 { c := *n; return &c }
+
+func (n *FuncType) SetOTYPE(t *types.Type) {
+       n.setOTYPE(t, n)
+       n.Recv = nil
+       n.Params = nil
+       n.Results = nil
+}
+
+func (n *FuncType) DeepCopy(pos src.XPos) Node {
+       if n.op == OTYPE {
+               // Can't change types and no node references left.
+               return n
+       }
+       return NewFuncType(n.posOr(pos),
+               n.Recv.deepCopy(pos),
+               deepCopyFields(pos, n.Params),
+               deepCopyFields(pos, n.Results))
+}
+
+// A Field is a declared struct field, interface method, or function argument.
+// It is not a Node.
+type Field struct {
+       Pos      src.XPos
+       Sym      *types.Sym
+       Ntype    Ntype
+       Type     *types.Type
+       Embedded bool
+       IsDDD    bool
+       Note     string
+       Decl     *Name
+}
+
+func NewField(pos src.XPos, sym *types.Sym, ntyp Ntype, typ *types.Type) *Field {
+       return &Field{Pos: pos, Sym: sym, Ntype: ntyp, Type: typ}
+}
+
+func (f *Field) String() string {
+       var typ string
+       if f.Type != nil {
+               typ = fmt.Sprint(f.Type)
+       } else {
+               typ = fmt.Sprint(f.Ntype)
+       }
+       if f.Sym != nil {
+               return fmt.Sprintf("%v %v", f.Sym, typ)
+       }
+       return typ
+}
+
+func (f *Field) deepCopy(pos src.XPos) *Field {
+       if f == nil {
+               return nil
+       }
+       fpos := pos
+       if !pos.IsKnown() {
+               fpos = f.Pos
+       }
+       decl := f.Decl
+       if decl != nil {
+               decl = DeepCopy(pos, decl).(*Name)
+       }
+       ntype := f.Ntype
+       if ntype != nil {
+               ntype = DeepCopy(pos, ntype).(Ntype)
+       }
+       // No keyed literal here: if a new struct field is added, we want this to stop compiling.
+       return &Field{fpos, f.Sym, ntype, f.Type, f.Embedded, f.IsDDD, f.Note, decl}
+}
+
+// A SliceType represents a []Elem type syntax.
+// If DDD is true, it's the ...Elem at the end of a function list.
+type SliceType struct {
+       miniType
+       Elem Node
+       DDD  bool
+}
+
+func NewSliceType(pos src.XPos, elem Node) *SliceType {
+       n := &SliceType{Elem: elem}
+       n.op = OTSLICE
+       n.pos = pos
+       return n
+}
+
+func (n *SliceType) String() string                { return fmt.Sprint(n) }
+func (n *SliceType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *SliceType) RawCopy() Node                 { c := *n; return &c }
+func (n *SliceType) SetOTYPE(t *types.Type) {
+       n.setOTYPE(t, n)
+       n.Elem = nil
+}
+
+func (n *SliceType) DeepCopy(pos src.XPos) Node {
+       if n.op == OTYPE {
+               // Can't change types and no node references left.
+               return n
+       }
+       return NewSliceType(n.posOr(pos), DeepCopy(pos, n.Elem))
+}
+
+// An ArrayType represents a [Len]Elem type syntax.
+// If Len is nil, the type is a [...]Elem in an array literal.
+type ArrayType struct {
+       miniType
+       Len  Node
+       Elem Node
+}
+
+func NewArrayType(pos src.XPos, size Node, elem Node) *ArrayType {
+       n := &ArrayType{Len: size, Elem: elem}
+       n.op = OTARRAY
+       n.pos = pos
+       return n
+}
+
+func (n *ArrayType) String() string                { return fmt.Sprint(n) }
+func (n *ArrayType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *ArrayType) RawCopy() Node                 { c := *n; return &c }
+
+func (n *ArrayType) DeepCopy(pos src.XPos) Node {
+       if n.op == OTYPE {
+               // Can't change types and no node references left.
+               return n
+       }
+       return NewArrayType(n.posOr(pos), DeepCopy(pos, n.Len), DeepCopy(pos, n.Elem))
+}
+
+func (n *ArrayType) SetOTYPE(t *types.Type) {
+       n.setOTYPE(t, n)
+       n.Len = nil
+       n.Elem = nil
+}
+
+// A typeNode is a Node wrapper for type t.
+type typeNode struct {
+       miniNode
+       typ *types.Type
+}
+
+func newTypeNode(pos src.XPos, typ *types.Type) *typeNode {
+       n := &typeNode{typ: typ}
+       n.pos = pos
+       n.op = OTYPE
+       return n
+}
+
+func (n *typeNode) String() string                { return fmt.Sprint(n) }
+func (n *typeNode) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *typeNode) RawCopy() Node                 { c := *n; return &c }
+func (n *typeNode) Type() *types.Type             { return n.typ }
+func (n *typeNode) Sym() *types.Sym               { return n.typ.Sym }
+func (n *typeNode) CanBeNtype()                   {}
+
+// TypeNode returns the Node representing the type t.
+func TypeNode(t *types.Type) Ntype {
+       return TypeNodeAt(src.NoXPos, t)
+}
+
+// TypeNodeAt returns the Node representing the type t.
+// If the node must be created, TypeNodeAt uses the position pos.
+// TODO(rsc): Does anyone actually use position on these type nodes?
+func TypeNodeAt(pos src.XPos, t *types.Type) Ntype {
+       // If we copied another type with *t = *u,
+       // then t.Nod might be out of date, so check t.Nod.Type() too.
+       n := AsNode(t.Nod)
+       if n == nil || n.Type() != t {
+               n := newTypeNode(pos, t) // t.Sym may be nil
+               t.Nod = n
+               return n
+       }
+       return n.(Ntype)
 }