From f68f292820a3dc545aba0ee64a372635a64d5040 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 4 Apr 2017 17:54:02 -0700 Subject: [PATCH] cmd/compile: factor out Pkg, Sym, and Type into package types - created new package cmd/compile/internal/types - moved Pkg, Sym, Type to new package - to break cycles, for now we need the (ugly) types/utils.go file which contains a handful of functions that must be installed early by the gc frontend - to break cycles, for now we need two functions to convert between *gc.Node and *types.Node (the latter is a dummy type) - adjusted the gc's code to use the new package and the conversion functions as needed - made several Pkg, Sym, and Type methods functions as needed - renamed constructors typ, typPtr, typArray, etc. to types.New, types.NewPtr, types.NewArray, etc. Passes toolstash-check -all. Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72 Reviewed-on: https://go-review.googlesource.com/39855 Reviewed-by: Matthew Dempsky --- src/cmd/compile/fmt_test.go | 38 +- src/cmd/compile/internal/gc/alg.go | 67 +- src/cmd/compile/internal/gc/align.go | 45 +- src/cmd/compile/internal/gc/bexport.go | 155 ++--- src/cmd/compile/internal/gc/bimport.go | 115 ++-- src/cmd/compile/internal/gc/builtin.go | 76 +-- src/cmd/compile/internal/gc/checkcfg.go | 9 +- src/cmd/compile/internal/gc/closure.go | 45 +- src/cmd/compile/internal/gc/const.go | 93 +-- src/cmd/compile/internal/gc/dcl.go | 191 +++--- src/cmd/compile/internal/gc/esc.go | 55 +- src/cmd/compile/internal/gc/export.go | 51 +- src/cmd/compile/internal/gc/fmt.go | 289 ++++----- src/cmd/compile/internal/gc/gen.go | 20 +- src/cmd/compile/internal/gc/go.go | 99 +-- src/cmd/compile/internal/gc/gsubr.go | 25 +- src/cmd/compile/internal/gc/init.go | 14 +- src/cmd/compile/internal/gc/inl.go | 47 +- src/cmd/compile/internal/gc/lex.go | 11 - src/cmd/compile/internal/gc/main.go | 52 +- src/cmd/compile/internal/gc/mkbuiltin.go | 32 +- src/cmd/compile/internal/gc/noder.go | 33 +- src/cmd/compile/internal/gc/obj.go | 29 +- src/cmd/compile/internal/gc/order.go | 33 +- src/cmd/compile/internal/gc/pgen.go | 17 +- src/cmd/compile/internal/gc/pgen_test.go | 101 +-- src/cmd/compile/internal/gc/plive.go | 11 +- src/cmd/compile/internal/gc/racewalk.go | 11 +- src/cmd/compile/internal/gc/range.go | 45 +- src/cmd/compile/internal/gc/reflect.go | 273 ++++---- src/cmd/compile/internal/gc/reflect_test.go | 17 +- src/cmd/compile/internal/gc/select.go | 42 +- src/cmd/compile/internal/gc/sinit.go | 27 +- src/cmd/compile/internal/gc/sizeof_test.go | 30 +- src/cmd/compile/internal/gc/ssa.go | 581 +++++++++--------- src/cmd/compile/internal/gc/subr.go | 214 +++---- src/cmd/compile/internal/gc/swt.go | 19 +- src/cmd/compile/internal/gc/syntax.go | 35 +- src/cmd/compile/internal/gc/typecheck.go | 227 +++---- src/cmd/compile/internal/gc/types.go | 249 ++++++++ src/cmd/compile/internal/gc/types_acc.go | 16 + src/cmd/compile/internal/gc/universe.go | 182 +++--- src/cmd/compile/internal/gc/walk.go | 231 +++---- src/cmd/compile/internal/types/pkg.go | 70 +++ src/cmd/compile/internal/types/sym.go | 62 ++ .../compile/internal/{gc => types}/type.go | 229 ++++--- src/cmd/compile/internal/types/utils.go | 126 ++++ src/cmd/dist/buildtool.go | 1 + 48 files changed, 2434 insertions(+), 2006 deletions(-) create mode 100644 src/cmd/compile/internal/gc/types.go create mode 100644 src/cmd/compile/internal/gc/types_acc.go create mode 100644 src/cmd/compile/internal/types/pkg.go create mode 100644 src/cmd/compile/internal/types/sym.go rename src/cmd/compile/internal/{gc => types}/type.go (86%) create mode 100644 src/cmd/compile/internal/types/utils.go diff --git a/src/cmd/compile/fmt_test.go b/src/cmd/compile/fmt_test.go index e9b78df2fb..204e611e9e 100644 --- a/src/cmd/compile/fmt_test.go +++ b/src/cmd/compile/fmt_test.go @@ -557,8 +557,6 @@ func init() { // To print out a new table, run: go test -run Formats -v. var knownFormats = map[string]string{ "*bytes.Buffer %s": "", - "*cmd/compile/internal/gc.Field %p": "", - "*cmd/compile/internal/gc.Field %v": "", "*cmd/compile/internal/gc.Mpflt %v": "", "*cmd/compile/internal/gc.Mpint %v": "", "*cmd/compile/internal/gc.Node %#v": "", @@ -570,20 +568,6 @@ var knownFormats = map[string]string{ "*cmd/compile/internal/gc.Node %j": "", "*cmd/compile/internal/gc.Node %p": "", "*cmd/compile/internal/gc.Node %v": "", - "*cmd/compile/internal/gc.Sym %+v": "", - "*cmd/compile/internal/gc.Sym %-v": "", - "*cmd/compile/internal/gc.Sym %0S": "", - "*cmd/compile/internal/gc.Sym %S": "", - "*cmd/compile/internal/gc.Sym %p": "", - "*cmd/compile/internal/gc.Sym %v": "", - "*cmd/compile/internal/gc.Type %#v": "", - "*cmd/compile/internal/gc.Type %+v": "", - "*cmd/compile/internal/gc.Type %-S": "", - "*cmd/compile/internal/gc.Type %0S": "", - "*cmd/compile/internal/gc.Type %L": "", - "*cmd/compile/internal/gc.Type %S": "", - "*cmd/compile/internal/gc.Type %p": "", - "*cmd/compile/internal/gc.Type %v": "", "*cmd/compile/internal/ssa.Block %s": "", "*cmd/compile/internal/ssa.Block %v": "", "*cmd/compile/internal/ssa.Func %s": "", @@ -591,6 +575,22 @@ var knownFormats = map[string]string{ "*cmd/compile/internal/ssa.Value %s": "", "*cmd/compile/internal/ssa.Value %v": "", "*cmd/compile/internal/ssa.sparseTreeMapEntry %v": "", + "*cmd/compile/internal/types.Field %p": "", + "*cmd/compile/internal/types.Field %v": "", + "*cmd/compile/internal/types.Sym %+v": "", + "*cmd/compile/internal/types.Sym %-v": "", + "*cmd/compile/internal/types.Sym %0S": "", + "*cmd/compile/internal/types.Sym %S": "", + "*cmd/compile/internal/types.Sym %p": "", + "*cmd/compile/internal/types.Sym %v": "", + "*cmd/compile/internal/types.Type %#v": "", + "*cmd/compile/internal/types.Type %+v": "", + "*cmd/compile/internal/types.Type %-S": "", + "*cmd/compile/internal/types.Type %0S": "", + "*cmd/compile/internal/types.Type %L": "", + "*cmd/compile/internal/types.Type %S": "", + "*cmd/compile/internal/types.Type %p": "", + "*cmd/compile/internal/types.Type %v": "", "*cmd/internal/obj.Addr %v": "", "*cmd/internal/obj.LSym %v": "", "*cmd/internal/obj.Prog %s": "", @@ -613,9 +613,6 @@ var knownFormats = map[string]string{ "cmd/compile/internal/gc.Class %d": "", "cmd/compile/internal/gc.Ctype %d": "", "cmd/compile/internal/gc.Ctype %v": "", - "cmd/compile/internal/gc.EType %d": "", - "cmd/compile/internal/gc.EType %s": "", - "cmd/compile/internal/gc.EType %v": "", "cmd/compile/internal/gc.Level %d": "", "cmd/compile/internal/gc.Level %v": "", "cmd/compile/internal/gc.Node %#v": "", @@ -652,6 +649,9 @@ var knownFormats = map[string]string{ "cmd/compile/internal/syntax.token %d": "", "cmd/compile/internal/syntax.token %q": "", "cmd/compile/internal/syntax.token %s": "", + "cmd/compile/internal/types.EType %d": "", + "cmd/compile/internal/types.EType %s": "", + "cmd/compile/internal/types.EType %v": "", "cmd/internal/src.Pos %s": "", "cmd/internal/src.Pos %v": "", "cmd/internal/src.XPos %v": "", diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go index a2ec81569d..8ee158c5f7 100644 --- a/src/cmd/compile/internal/gc/alg.go +++ b/src/cmd/compile/internal/gc/alg.go @@ -4,7 +4,10 @@ package gc -import "fmt" +import ( + "cmd/compile/internal/types" + "fmt" +) // AlgKind describes the kind of algorithms used for comparing and // hashing a Type. @@ -35,21 +38,21 @@ const ( ) // IsComparable reports whether t is a comparable type. -func (t *Type) IsComparable() bool { +func IsComparable(t *types.Type) bool { a, _ := algtype1(t) return a != ANOEQ } // IsRegularMemory reports whether t can be compared/hashed as regular memory. -func (t *Type) IsRegularMemory() bool { +func IsRegularMemory(t *types.Type) bool { a, _ := algtype1(t) return a == AMEM } // IncomparableField returns an incomparable Field of struct Type t, if any. -func (t *Type) IncomparableField() *Field { +func IncomparableField(t *types.Type) *types.Field { for _, f := range t.FieldSlice() { - if !f.Type.IsComparable() { + if !IsComparable(f.Type) { return f } } @@ -58,7 +61,7 @@ func (t *Type) IncomparableField() *Field { // algtype is like algtype1, except it returns the fixed-width AMEMxx variants // instead of the general AMEM kind when possible. -func algtype(t *Type) AlgKind { +func algtype(t *types.Type) AlgKind { a, _ := algtype1(t) if a == AMEM { switch t.Width { @@ -83,7 +86,7 @@ func algtype(t *Type) AlgKind { // algtype1 returns the AlgKind used for comparing and hashing Type t. // If it returns ANOEQ, it also returns the component type of t that // makes it incomparable. -func algtype1(t *Type) (AlgKind, *Type) { +func algtype1(t *types.Type) (AlgKind, *types.Type) { if t.Broke() { return AMEM, nil } @@ -181,7 +184,7 @@ func algtype1(t *Type) (AlgKind, *Type) { } // Generate a helper function to compute the hash of a value of type t. -func genhash(sym *Sym, t *Type) { +func genhash(sym *types.Sym, t *types.Type) { if Debug['r'] != 0 { fmt.Printf("genhash %v %v\n", sym, t) } @@ -198,13 +201,13 @@ func genhash(sym *Sym, t *Type) { tfn := nod(OTFUNC, nil, nil) fn.Func.Nname.Name.Param.Ntype = tfn - n := namedfield("p", typPtr(t)) + n := namedfield("p", types.NewPtr(t)) tfn.List.Append(n) np := n.Left - n = namedfield("h", Types[TUINTPTR]) + n = namedfield("h", types.Types[TUINTPTR]) tfn.List.Append(n) nh := n.Left - n = anonfield(Types[TUINTPTR]) // return value + n = anonfield(types.Types[TUINTPTR]) // return value tfn.Rlist.Append(n) funchdr(fn) @@ -217,7 +220,7 @@ func genhash(sym *Sym, t *Type) { default: Fatalf("genhash %v", t) - case TARRAY: + case types.TARRAY: // An array of pure memory would be handled by the // standard algorithm, so the element type must not be // pure memory. @@ -225,7 +228,7 @@ func genhash(sym *Sym, t *Type) { n := nod(ORANGE, nil, nod(OIND, np, nil)) ni := newname(lookup("i")) - ni.Type = Types[TINT] + ni.Type = types.Types[TINT] n.List.Set1(ni) n.SetColas(true) colasdefn(n.List.Slice(), n) @@ -244,7 +247,7 @@ func genhash(sym *Sym, t *Type) { fn.Nbody.Append(n) - case TSTRUCT: + case types.TSTRUCT: // Walk the struct using memhash for runs of AMEM // and calling specific hash functions for the others. for i, fields := 0, t.FieldSlice(); i < len(fields); { @@ -257,7 +260,7 @@ func genhash(sym *Sym, t *Type) { } // Hash non-memory fields with appropriate hash function. - if !f.Type.IsRegularMemory() { + if !IsRegularMemory(f.Type) { hashel := hashfor(f.Type) call := nod(OCALL, hashel, nil) nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages? @@ -322,8 +325,8 @@ func genhash(sym *Sym, t *Type) { safemode = old_safemode } -func hashfor(t *Type) *Node { - var sym *Sym +func hashfor(t *types.Type) *Node { + var sym *types.Sym switch a, _ := algtype1(t); a { case AMEM: @@ -349,9 +352,9 @@ func hashfor(t *Type) *Node { n := newname(sym) n.Class = PFUNC tfn := nod(OTFUNC, nil, nil) - tfn.List.Append(anonfield(typPtr(t))) - tfn.List.Append(anonfield(Types[TUINTPTR])) - tfn.Rlist.Append(anonfield(Types[TUINTPTR])) + tfn.List.Append(anonfield(types.NewPtr(t))) + tfn.List.Append(anonfield(types.Types[TUINTPTR])) + tfn.Rlist.Append(anonfield(types.Types[TUINTPTR])) tfn = typecheck(tfn, Etype) n.Type = tfn.Type return n @@ -359,7 +362,7 @@ func hashfor(t *Type) *Node { // geneq generates a helper function to // check equality of two values of type t. -func geneq(sym *Sym, t *Type) { +func geneq(sym *types.Sym, t *types.Type) { if Debug['r'] != 0 { fmt.Printf("geneq %v %v\n", sym, t) } @@ -376,13 +379,13 @@ func geneq(sym *Sym, t *Type) { tfn := nod(OTFUNC, nil, nil) fn.Func.Nname.Name.Param.Ntype = tfn - n := namedfield("p", typPtr(t)) + n := namedfield("p", types.NewPtr(t)) tfn.List.Append(n) np := n.Left - n = namedfield("q", typPtr(t)) + n = namedfield("q", types.NewPtr(t)) tfn.List.Append(n) nq := n.Left - n = anonfield(Types[TBOOL]) + n = anonfield(types.Types[TBOOL]) tfn.Rlist.Append(n) funchdr(fn) @@ -404,7 +407,7 @@ func geneq(sym *Sym, t *Type) { nrange := nod(ORANGE, nil, nod(OIND, np, nil)) ni := newname(lookup("i")) - ni.Type = Types[TINT] + ni.Type = types.Types[TINT] nrange.List.Set1(ni) nrange.SetColas(true) colasdefn(nrange.List.Slice(), nrange) @@ -452,7 +455,7 @@ func geneq(sym *Sym, t *Type) { } // Compare non-memory fields with field equality. - if !f.Type.IsRegularMemory() { + if !IsRegularMemory(f.Type) { and(eqfield(np, nq, f.Sym)) i++ continue @@ -521,7 +524,7 @@ func geneq(sym *Sym, t *Type) { // eqfield returns the node // p.field == q.field -func eqfield(p *Node, q *Node, field *Sym) *Node { +func eqfield(p *Node, q *Node, field *types.Sym) *Node { nx := nodSym(OXDOT, p, field) ny := nodSym(OXDOT, q, field) ne := nod(OEQ, nx, ny) @@ -530,7 +533,7 @@ func eqfield(p *Node, q *Node, field *Sym) *Node { // eqmem returns the node // memequal(&p.field, &q.field [, size]) -func eqmem(p *Node, q *Node, field *Sym, size int64) *Node { +func eqmem(p *Node, q *Node, field *types.Sym, size int64) *Node { nx := nod(OADDR, nodSym(OXDOT, p, field), nil) nx.Etype = 1 // does not escape ny := nod(OADDR, nodSym(OXDOT, q, field), nil) @@ -549,7 +552,7 @@ func eqmem(p *Node, q *Node, field *Sym, size int64) *Node { return call } -func eqmemfunc(size int64, t *Type) (fn *Node, needsize bool) { +func eqmemfunc(size int64, t *types.Type) (fn *Node, needsize bool) { switch size { default: fn = syslook("memequal") @@ -567,7 +570,7 @@ func eqmemfunc(size int64, t *Type) (fn *Node, needsize bool) { // t is the parent struct type, and start is the field index at which to start the run. // size is the length in bytes of the memory included in the run. // next is the index just after the end of the memory run. -func memrun(t *Type, start int) (size int64, next int) { +func memrun(t *types.Type, start int) (size int64, next int) { next = start for { next++ @@ -579,7 +582,7 @@ func memrun(t *Type, start int) (size int64, next int) { break } // Also, stop before a blank or non-memory field. - if f := t.Field(next); isblanksym(f.Sym) || !f.Type.IsRegularMemory() { + if f := t.Field(next); isblanksym(f.Sym) || !IsRegularMemory(f.Type) { break } } @@ -588,7 +591,7 @@ func memrun(t *Type, start int) (size int64, next int) { // ispaddedfield reports whether the i'th field of struct type t is followed // by padding. -func ispaddedfield(t *Type, i int) bool { +func ispaddedfield(t *types.Type, i int) bool { if !t.IsStruct() { Fatalf("ispaddedfield called non-struct %v", t) } diff --git a/src/cmd/compile/internal/gc/align.go b/src/cmd/compile/internal/gc/align.go index 935e012194..3f0ff2c545 100644 --- a/src/cmd/compile/internal/gc/align.go +++ b/src/cmd/compile/internal/gc/align.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "sort" ) @@ -21,8 +22,8 @@ func Rnd(o int64, r int64) int64 { // expandiface computes the method set for interface type t by // expanding embedded interfaces. -func expandiface(t *Type) { - var fields []*Field +func expandiface(t *types.Type) { + var fields []*types.Field for _, m := range t.Methods().Slice() { if m.Sym != nil { fields = append(fields, m) @@ -30,7 +31,7 @@ func expandiface(t *Type) { } if !m.Type.IsInterface() { - yyerrorl(m.Nname.Pos, "interface contains embedded non-interface %v", m.Type) + yyerrorl(asNode(m.Nname).Pos, "interface contains embedded non-interface %v", m.Type) m.SetBroke(true) t.SetBroke(true) // Add to fields so that error messages @@ -45,7 +46,7 @@ func expandiface(t *Type) { // (including broken ones, if any) and add to t's // method set. for _, t1 := range m.Type.Fields().Slice() { - f := newField() + f := types.NewField() f.Type = t1.Type f.SetBroke(t1.Broke()) f.Sym = t1.Sym @@ -57,10 +58,10 @@ func expandiface(t *Type) { // Access fields directly to avoid recursively calling dowidth // within Type.Fields(). - t.Extra.(*InterType).fields.Set(fields) + t.Extra.(*types.InterType).Fields.Set(fields) } -func offmod(t *Type) { +func offmod(t *types.Type) { o := int32(0) for _, f := range t.Fields().Slice() { f.Offset = int64(o) @@ -72,7 +73,7 @@ func offmod(t *Type) { } } -func widstruct(errtype *Type, t *Type, o int64, flag int) int64 { +func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 { starto := o maxalign := int32(flag) if maxalign < 1 { @@ -94,7 +95,7 @@ func widstruct(errtype *Type, t *Type, o int64, flag int) int64 { o = Rnd(o, int64(f.Type.Align)) } f.Offset = o - if f.Nname != nil { + if asNode(f.Nname) != nil { // addrescapes has similar code to update these offsets. // Usually addrescapes runs after widstruct, // in which case we could drop this, @@ -102,11 +103,11 @@ func widstruct(errtype *Type, t *Type, o int64, flag int) int64 { // NOTE(rsc): This comment may be stale. // It's possible the ordering has changed and this is // now the common case. I'm not sure. - if f.Nname.Name.Param.Stackcopy != nil { - f.Nname.Name.Param.Stackcopy.Xoffset = o - f.Nname.Xoffset = 0 + if asNode(f.Nname).Name.Param.Stackcopy != nil { + asNode(f.Nname).Name.Param.Stackcopy.Xoffset = o + asNode(f.Nname).Xoffset = 0 } else { - f.Nname.Xoffset = o + asNode(f.Nname).Xoffset = o } } @@ -150,7 +151,7 @@ func widstruct(errtype *Type, t *Type, o int64, flag int) int64 { return o } -func dowidth(t *Type) { +func dowidth(t *types.Type) { if Widthptr == 0 { Fatalf("dowidth without betypeinit") } @@ -162,7 +163,7 @@ func dowidth(t *Type) { if t.Width == -2 { if !t.Broke() { t.SetBroke(true) - yyerrorl(t.nod.Pos, "invalid recursive type %v", t) + yyerrorl(asNode(t.Nod).Pos, "invalid recursive type %v", t) } t.Width = 0 @@ -183,8 +184,8 @@ func dowidth(t *Type) { defercalc++ lno := lineno - if t.nod != nil { - lineno = t.nod.Pos + if asNode(t.Nod) != nil { + lineno = asNode(t.Nod).Pos } t.Width = -2 @@ -253,7 +254,7 @@ func dowidth(t *Type) { // make fake type to check later to // trigger channel argument check. - t1 := typChanArgs(t) + t1 := types.NewChanArgs(t) checkwidth(t1) case TCHANARGS: @@ -290,7 +291,7 @@ func dowidth(t *Type) { if t.Elem() == nil { break } - if t.isDDDArray() { + if t.IsDDDArray() { if !t.Broke() { yyerror("use of [...] array outside of array literal") t.SetBroke(true) @@ -325,7 +326,7 @@ func dowidth(t *Type) { // make fake type to check later to // trigger function argument computation. case TFUNC: - t1 := typFuncArgs(t) + t1 := types.NewFuncArgs(t) checkwidth(t1) w = int64(Widthptr) // width of func type is pointer @@ -336,7 +337,7 @@ func dowidth(t *Type) { w = widstruct(t1, t1.Recvs(), 0, 0) w = widstruct(t1, t1.Params(), w, Widthreg) w = widstruct(t1, t1.Results(), w, Widthreg) - t1.Extra.(*FuncType).Argwid = w + t1.Extra.(*types.FuncType).Argwid = w if w%int64(Widthreg) != 0 { Warn("bad type %v %d\n", t1, w) } @@ -388,9 +389,9 @@ func dowidth(t *Type) { // is needed immediately. checkwidth makes sure the // size is evaluated eventually. -var deferredTypeStack []*Type +var deferredTypeStack []*types.Type -func checkwidth(t *Type) { +func checkwidth(t *types.Type) { if t == nil { return } diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go index 3555505bbf..5d0feea313 100644 --- a/src/cmd/compile/internal/gc/bexport.go +++ b/src/cmd/compile/internal/gc/bexport.go @@ -114,6 +114,7 @@ package gc import ( "bufio" "bytes" + "cmd/compile/internal/types" "encoding/binary" "fmt" "math/big" @@ -164,8 +165,8 @@ type exporter struct { // object -> index maps, indexed in order of serialization strIndex map[string]int - pkgIndex map[*Pkg]int - typIndex map[*Type]int + pkgIndex map[*types.Pkg]int + typIndex map[*types.Type]int funcList []*Func // position encoding @@ -184,8 +185,8 @@ func export(out *bufio.Writer, trace bool) int { p := exporter{ out: out, strIndex: map[string]int{"": 0}, // empty string is mapped to 0 - pkgIndex: make(map[*Pkg]int), - typIndex: make(map[*Type]int), + pkgIndex: make(map[*types.Pkg]int), + typIndex: make(map[*types.Type]int), posInfoFormat: true, trace: trace, } @@ -333,7 +334,7 @@ func export(out *bufio.Writer, trace bool) int { p.tracef("\n") } - if sym.isAlias() { + if IsAlias(sym) { Fatalf("exporter: unexpected type alias %v in inlined function body", sym) } @@ -395,7 +396,7 @@ func export(out *bufio.Writer, trace bool) int { return p.written } -func (p *exporter) pkg(pkg *Pkg) { +func (p *exporter) pkg(pkg *types.Pkg) { if pkg == nil { Fatalf("exporter: unexpected nil pkg") } @@ -418,7 +419,7 @@ func (p *exporter) pkg(pkg *Pkg) { p.string(pkg.Path) } -func unidealType(typ *Type, val Val) *Type { +func unidealType(typ *types.Type, val Val) *types.Type { // Untyped (ideal) constants get their own type. This decouples // the constant type from the encoding of the constant value. if typ == nil || typ.IsUntyped() { @@ -427,7 +428,7 @@ func unidealType(typ *Type, val Val) *Type { return typ } -func (p *exporter) obj(sym *Sym) { +func (p *exporter) obj(sym *types.Sym) { // Exported objects may be from different packages because they // may be re-exported via an exported alias or as dependencies in // exported inlined function bodies. Thus, exported object names @@ -440,7 +441,7 @@ func (p *exporter) obj(sym *Sym) { // pulled in via inlined function bodies. In that case the package // qualifier is not needed. Possible space optimization.) - n := sym.Def + n := asNode(sym.Def) switch n.Op { case OLITERAL: // constant @@ -467,7 +468,7 @@ func (p *exporter) obj(sym *Sym) { Fatalf("exporter: export of incomplete type %v", sym) } - if sym.isAlias() { + if IsAlias(sym) { p.tag(aliasTag) p.pos(n) p.qualifiedName(sym) @@ -489,15 +490,15 @@ func (p *exporter) obj(sym *Sym) { p.pos(n) p.qualifiedName(sym) - sig := sym.Def.Type - inlineable := isInlineable(sym.Def) + sig := asNode(sym.Def).Type + inlineable := isInlineable(asNode(sym.Def)) p.paramList(sig.Params(), inlineable) p.paramList(sig.Results(), inlineable) var f *Func if inlineable { - f = sym.Def.Func + f = asNode(sym.Def).Func reexportdeplist(f.Inl) } p.funcList = append(p.funcList, f) @@ -506,7 +507,7 @@ func (p *exporter) obj(sym *Sym) { p.tag(varTag) p.pos(n) p.qualifiedName(sym) - p.typ(sym.Def.Type) + p.typ(asNode(sym.Def).Type) } default: @@ -579,9 +580,9 @@ func isInlineable(n *Node) bool { return false } -var errorInterface *Type // lazily initialized +var errorInterface *types.Type // lazily initialized -func (p *exporter) typ(t *Type) { +func (p *exporter) typ(t *types.Type) { if t == nil { Fatalf("exporter: nil type") } @@ -633,7 +634,7 @@ func (p *exporter) typ(t *Type) { // write underlying type orig := t.Orig - if orig == errortype { + if orig == types.Errortype { // The error type is the only predeclared type which has // a composite underlying type. When we encode that type, // make sure to encode the underlying interface rather than @@ -654,7 +655,7 @@ func (p *exporter) typ(t *Type) { // sort methods for reproducible export format // TODO(gri) Determine if they are already sorted // in which case we can drop this step. - var methods []*Field + var methods []*types.Field for _, m := range t.Methods().Slice() { methods = append(methods, m) } @@ -673,11 +674,11 @@ func (p *exporter) typ(t *Type) { Fatalf("invalid symbol name: %s (%v)", m.Sym.Name, m.Sym) } - p.pos(m.Nname) + p.pos(asNode(m.Nname)) p.fieldSym(m.Sym, false) sig := m.Type - mfn := sig.Nname() + mfn := asNode(sig.FuncType().Nname) inlineable := isInlineable(mfn) p.paramList(sig.Recvs(), inlineable) @@ -703,7 +704,7 @@ func (p *exporter) typ(t *Type) { // otherwise we have a type literal switch t.Etype { case TARRAY: - if t.isDDDArray() { + if t.IsDDDArray() { Fatalf("array bounds should be known at export time: %v", t) } p.tag(arrayTag) @@ -751,12 +752,12 @@ func (p *exporter) typ(t *Type) { } } -func (p *exporter) qualifiedName(sym *Sym) { +func (p *exporter) qualifiedName(sym *types.Sym) { p.string(sym.Name) p.pkg(sym.Pkg) } -func (p *exporter) fieldList(t *Type) { +func (p *exporter) fieldList(t *types.Type) { if p.trace && t.NumFields() > 0 { p.tracef("fields {>") defer p.tracef("<\n} ") @@ -771,15 +772,15 @@ func (p *exporter) fieldList(t *Type) { } } -func (p *exporter) field(f *Field) { - p.pos(f.Nname) +func (p *exporter) field(f *types.Field) { + p.pos(asNode(f.Nname)) p.fieldName(f) p.typ(f.Type) p.string(f.Note) } -func (p *exporter) methodList(t *Type) { - var embeddeds, methods []*Field +func (p *exporter) methodList(t *types.Type) { + var embeddeds, methods []*types.Field for _, m := range t.Methods().Slice() { if m.Sym != nil { @@ -797,7 +798,7 @@ func (p *exporter) methodList(t *Type) { if p.trace { p.tracef("\n") } - p.pos(m.Nname) + p.pos(asNode(m.Nname)) p.typ(m.Type) } if p.trace && len(embeddeds) > 0 { @@ -819,14 +820,14 @@ func (p *exporter) methodList(t *Type) { } } -func (p *exporter) method(m *Field) { - p.pos(m.Nname) +func (p *exporter) method(m *types.Field) { + p.pos(asNode(m.Nname)) p.methodName(m.Sym) p.paramList(m.Type.Params(), false) p.paramList(m.Type.Results(), false) } -func (p *exporter) fieldName(t *Field) { +func (p *exporter) fieldName(t *types.Field) { name := t.Sym.Name if t.Embedded != 0 { // anonymous field - we distinguish between 3 cases: @@ -853,14 +854,14 @@ func (p *exporter) fieldName(t *Field) { } // methodName is like qualifiedName but it doesn't record the package for exported names. -func (p *exporter) methodName(sym *Sym) { +func (p *exporter) methodName(sym *types.Sym) { p.string(sym.Name) if !exportname(sym.Name) { p.pkg(sym.Pkg) } } -func basetypeName(t *Type) string { +func basetypeName(t *types.Type) string { s := t.Sym if s == nil && t.IsPtr() { s = t.Elem().Sym // deref @@ -871,7 +872,7 @@ func basetypeName(t *Type) string { return "" // unnamed type } -func (p *exporter) paramList(params *Type, numbered bool) { +func (p *exporter) paramList(params *types.Type, numbered bool) { if !params.IsFuncArgStruct() { Fatalf("exporter: parameter list expected") } @@ -894,11 +895,11 @@ func (p *exporter) paramList(params *Type, numbered bool) { } } -func (p *exporter) param(q *Field, n int, numbered bool) { +func (p *exporter) param(q *types.Field, n int, numbered bool) { t := q.Type if q.Isddd() { // create a fake type to encode ... just for the p.typ call - t = typDDDField(t.Elem()) + t = types.NewDDDField(t.Elem()) } p.typ(t) if n > 0 { @@ -937,7 +938,7 @@ func (p *exporter) param(q *Field, n int, numbered bool) { p.string(q.Note) } -func parName(f *Field, numbered bool) string { +func parName(f *types.Field, numbered bool) string { s := f.Sym if s == nil { return "" @@ -945,9 +946,9 @@ func parName(f *Field, numbered bool) string { // Take the name from the original, lest we substituted it with ~r%d or ~b%d. // ~r%d is a (formerly) unnamed result. - if f.Nname != nil { - if f.Nname.Orig != nil { - s = f.Nname.Orig.Sym + if asNode(f.Nname) != nil { + if asNode(f.Nname).Orig != nil { + s = asNode(f.Nname).Orig.Sym if s != nil && s.Name[0] == '~' { if s.Name[1] == 'r' { // originally an unnamed result return "" // s = nil @@ -974,8 +975,8 @@ func parName(f *Field, numbered bool) string { // from other names in their context after inlining (i.e., the parameter numbering // is a form of parameter rewriting). See issue 4326 for an example and test case. if numbered { - if !strings.Contains(name, "·") && f.Nname != nil && f.Nname.Name != nil && f.Nname.Name.Vargen > 0 { - name = fmt.Sprintf("%s·%d", name, f.Nname.Name.Vargen) // append Vargen + if !strings.Contains(name, "·") && asNode(f.Nname) != nil && asNode(f.Nname).Name != nil && asNode(f.Nname).Name.Vargen > 0 { + name = fmt.Sprintf("%s·%d", name, asNode(f.Nname).Name.Vargen) // append Vargen } } else { if i := strings.Index(name, "·"); i > 0 { @@ -1551,7 +1552,7 @@ func (p *exporter) exprsOrNil(a, b *Node) { } } -func (p *exporter) fieldSym(s *Sym, short bool) { +func (p *exporter) fieldSym(s *types.Sym, short bool) { name := s.Name // remove leading "type." in method names ("(T).m" -> "m") @@ -1858,59 +1859,59 @@ var tagString = [...]string{ // untype returns the "pseudo" untyped type for a Ctype (import/export use only). // (we can't use an pre-initialized array because we must be sure all types are // set up) -func untype(ctype Ctype) *Type { +func untype(ctype Ctype) *types.Type { switch ctype { case CTINT: - return idealint + return types.Idealint case CTRUNE: - return idealrune + return types.Idealrune case CTFLT: - return idealfloat + return types.Idealfloat case CTCPLX: - return idealcomplex + return types.Idealcomplex case CTSTR: - return idealstring + return types.Idealstring case CTBOOL: - return idealbool + return types.Idealbool case CTNIL: - return Types[TNIL] + return types.Types[TNIL] } Fatalf("exporter: unknown Ctype") return nil } -var predecl []*Type // initialized lazily +var predecl []*types.Type // initialized lazily -func predeclared() []*Type { +func predeclared() []*types.Type { if predecl == nil { // initialize lazily to be sure that all // elements have been initialized before - predecl = []*Type{ + predecl = []*types.Type{ // basic types - Types[TBOOL], - Types[TINT], - Types[TINT8], - Types[TINT16], - Types[TINT32], - Types[TINT64], - Types[TUINT], - Types[TUINT8], - Types[TUINT16], - Types[TUINT32], - Types[TUINT64], - Types[TUINTPTR], - Types[TFLOAT32], - Types[TFLOAT64], - Types[TCOMPLEX64], - Types[TCOMPLEX128], - Types[TSTRING], + types.Types[TBOOL], + types.Types[TINT], + types.Types[TINT8], + types.Types[TINT16], + types.Types[TINT32], + types.Types[TINT64], + types.Types[TUINT], + types.Types[TUINT8], + types.Types[TUINT16], + types.Types[TUINT32], + types.Types[TUINT64], + types.Types[TUINTPTR], + types.Types[TFLOAT32], + types.Types[TFLOAT64], + types.Types[TCOMPLEX64], + types.Types[TCOMPLEX128], + types.Types[TSTRING], // basic type aliases - bytetype, - runetype, + types.Bytetype, + types.Runetype, // error - errortype, + types.Errortype, // untyped types untype(CTBOOL), @@ -1922,13 +1923,13 @@ func predeclared() []*Type { untype(CTNIL), // package unsafe - Types[TUNSAFEPTR], + types.Types[TUNSAFEPTR], // invalid type (package contains errors) - Types[Txxx], + types.Types[Txxx], // any type, for builtin export data - Types[TANY], + types.Types[TANY], } } return predecl diff --git a/src/cmd/compile/internal/gc/bimport.go b/src/cmd/compile/internal/gc/bimport.go index 10cae7c165..8b3669f19c 100644 --- a/src/cmd/compile/internal/gc/bimport.go +++ b/src/cmd/compile/internal/gc/bimport.go @@ -10,6 +10,7 @@ package gc import ( "bufio" + "cmd/compile/internal/types" "cmd/internal/src" "encoding/binary" "fmt" @@ -25,19 +26,19 @@ import ( type importer struct { in *bufio.Reader - imp *Pkg // imported package - buf []byte // reused for reading strings - version int // export format version + imp *types.Pkg // imported package + buf []byte // reused for reading strings + version int // export format version // object lists, in order of deserialization strList []string - pkgList []*Pkg - typList []*Type + pkgList []*types.Pkg + typList []*types.Type funcList []*Node // nil entry means already declared trackAllTypes bool // for delayed type verification - cmpList []struct{ pt, t *Type } + cmpList []struct{ pt, t *types.Type } // position encoding posInfoFormat bool @@ -51,7 +52,7 @@ type importer struct { } // Import populates imp from the serialized package data read from in. -func Import(imp *Pkg, in *bufio.Reader) { +func Import(imp *types.Pkg, in *bufio.Reader) { inimport = true defer func() { inimport = false }() @@ -255,7 +256,7 @@ func (p *importer) verifyTypes() { // the same name appears in an error message. var numImport = make(map[string]int) -func (p *importer) pkg() *Pkg { +func (p *importer) pkg() *types.Pkg { // if the package was seen before, i is its index (>= 0) i := p.tagOrIndex() if i >= 0 { @@ -307,10 +308,10 @@ func (p *importer) pkg() *Pkg { return pkg } -func idealType(typ *Type) *Type { +func idealType(typ *types.Type) *types.Type { if typ.IsUntyped() { // canonicalize ideal types - typ = Types[TIDEAL] + typ = types.Types[TIDEAL] } return typ } @@ -347,10 +348,10 @@ func (p *importer) obj(tag int) { sig := functypefield(nil, params, result) importsym(p.imp, sym, ONAME) - if sym.Def != nil && sym.Def.Op == ONAME { + if asNode(sym.Def) != nil && asNode(sym.Def).Op == ONAME { // function was imported before (via another import) - if !eqtype(sig, sym.Def.Type) { - p.formatErrorf("inconsistent definition for func %v during import\n\t%v\n\t%v", sym, sym.Def.Type, sig) + if !eqtype(sig, asNode(sym.Def).Type) { + p.formatErrorf("inconsistent definition for func %v during import\n\t%v\n\t%v", sym, asNode(sym.Def).Type, sig) } p.funcList = append(p.funcList, nil) break @@ -398,8 +399,8 @@ func (p *importer) pos() src.XPos { return xpos } -func (p *importer) newtyp(etype EType) *Type { - t := typ(etype) +func (p *importer) newtyp(etype types.EType) *types.Type { + t := types.New(etype) if p.trackAllTypes { p.typList = append(p.typList, t) } @@ -407,19 +408,19 @@ func (p *importer) newtyp(etype EType) *Type { } // importtype declares that pt, an imported named type, has underlying type t. -func (p *importer) importtype(pt, t *Type) { +func (p *importer) importtype(pt, t *types.Type) { if pt.Etype == TFORW { - copytype(pt.nod, t) + copytype(asNode(pt.Nod), t) pt.Sym.Importdef = p.imp pt.Sym.Lastlineno = lineno - declare(pt.nod, PEXTERN) + declare(asNode(pt.Nod), PEXTERN) checkwidth(pt) } else { // pt.Orig and t must be identical. if p.trackAllTypes { // If we track all types, t may not be fully set up yet. // Collect the types and verify identity later. - p.cmpList = append(p.cmpList, struct{ pt, t *Type }{pt, t}) + p.cmpList = append(p.cmpList, struct{ pt, t *types.Type }{pt, t}) } else if !eqtype(pt.Orig, t) { yyerror("inconsistent definition for type %v during import\n\t%L (in %q)\n\t%L (in %q)", pt.Sym, pt, pt.Sym.Importdef.Path, t, p.imp.Path) } @@ -430,7 +431,7 @@ func (p *importer) importtype(pt, t *Type) { } } -func (p *importer) typ() *Type { +func (p *importer) typ() *types.Type { // if the type was seen before, i is its index (>= 0) i := p.tagOrIndex() if i >= 0 { @@ -438,7 +439,7 @@ func (p *importer) typ() *Type { } // otherwise, i is the type tag (< 0) - var t *Type + var t *types.Type switch i { case namedTag: p.pos() @@ -488,7 +489,7 @@ func (p *importer) typ() *Type { // (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled // out by typecheck's lookdot as this $$.ttype. So by providing // this back link here we avoid special casing there. - n.Type.SetNname(n) + n.Type.FuncType().Nname = asTypesNode(n) if Debug['E'] > 0 { fmt.Printf("import [%q] meth %v \n", p.imp.Path, n) @@ -504,16 +505,16 @@ func (p *importer) typ() *Type { t = p.newtyp(TARRAY) bound := p.int64() elem := p.typ() - t.Extra = &ArrayType{Elem: elem, Bound: bound} + t.Extra = &types.ArrayType{Elem: elem, Bound: bound} case sliceTag: t = p.newtyp(TSLICE) elem := p.typ() - t.Extra = SliceType{Elem: elem} + t.Extra = types.SliceType{Elem: elem} case dddTag: t = p.newtyp(TDDDFIELD) - t.Extra = DDDFieldType{T: p.typ()} + t.Extra = types.DDDFieldType{T: p.typ()} case structTag: t = p.newtyp(TSTRUCT) @@ -521,8 +522,8 @@ func (p *importer) typ() *Type { checkwidth(t) case pointerTag: - t = p.newtyp(Tptr) - t.Extra = PtrType{Elem: p.typ()} + t = p.newtyp(types.Tptr) + t.Extra = types.PtrType{Elem: p.typ()} case signatureTag: t = p.newtyp(TFUNC) @@ -532,7 +533,7 @@ func (p *importer) typ() *Type { case interfaceTag: if ml := p.methodList(); len(ml) == 0 { - t = Types[TINTER] + t = types.Types[TINTER] } else { t = p.newtyp(TINTER) t.SetInterface(ml) @@ -547,7 +548,7 @@ func (p *importer) typ() *Type { case chanTag: t = p.newtyp(TCHAN) ct := t.ChanType() - ct.Dir = ChanDir(p.int()) + ct.Dir = types.ChanDir(p.int()) ct.Elem = p.typ() default: @@ -561,15 +562,15 @@ func (p *importer) typ() *Type { return t } -func (p *importer) qualifiedName() *Sym { +func (p *importer) qualifiedName() *types.Sym { name := p.string() pkg := p.pkg() return pkg.Lookup(name) } -func (p *importer) fieldList() (fields []*Field) { +func (p *importer) fieldList() (fields []*types.Field) { if n := p.int(); n > 0 { - fields = make([]*Field, n) + fields = make([]*types.Field, n) for i := range fields { fields[i] = p.field() } @@ -577,13 +578,13 @@ func (p *importer) fieldList() (fields []*Field) { return } -func (p *importer) field() *Field { +func (p *importer) field() *types.Field { p.pos() sym, alias := p.fieldName() typ := p.typ() note := p.string() - f := newField() + f := types.NewField() if sym.Name == "" { // anonymous field: typ must be T or *T and T must be a type name s := typ.Sym @@ -598,18 +599,18 @@ func (p *importer) field() *Field { } f.Sym = sym - f.Nname = newname(sym) + f.Nname = asTypesNode(newname(sym)) f.Type = typ f.Note = note return f } -func (p *importer) methodList() (methods []*Field) { +func (p *importer) methodList() (methods []*types.Field) { for n := p.int(); n > 0; n-- { - f := newField() - f.Nname = newname(nblank.Sym) - f.Nname.Pos = p.pos() + f := types.NewField() + f.Nname = asTypesNode(newname(nblank.Sym)) + asNode(f.Nname).Pos = p.pos() f.Type = p.typ() methods = append(methods, f) } @@ -621,20 +622,20 @@ func (p *importer) methodList() (methods []*Field) { return } -func (p *importer) method() *Field { +func (p *importer) method() *types.Field { p.pos() sym := p.methodName() params := p.paramList() result := p.paramList() - f := newField() + f := types.NewField() f.Sym = sym - f.Nname = newname(sym) + f.Nname = asTypesNode(newname(sym)) f.Type = functypefield(fakethisfield(), params, result) return f } -func (p *importer) fieldName() (*Sym, bool) { +func (p *importer) fieldName() (*types.Sym, bool) { name := p.string() if p.version == 0 && name == "_" { // version 0 didn't export a package for _ field names @@ -663,7 +664,7 @@ func (p *importer) fieldName() (*Sym, bool) { return pkg.Lookup(name), alias } -func (p *importer) methodName() *Sym { +func (p *importer) methodName() *types.Sym { name := p.string() if p.version == 0 && name == "_" { // version 0 didn't export a package for _ method names @@ -677,7 +678,7 @@ func (p *importer) methodName() *Sym { return pkg.Lookup(name) } -func (p *importer) paramList() []*Field { +func (p *importer) paramList() []*types.Field { i := p.int() if i == 0 { return nil @@ -689,19 +690,19 @@ func (p *importer) paramList() []*Field { named = false } // i > 0 - fs := make([]*Field, i) + fs := make([]*types.Field, i) for i := range fs { fs[i] = p.param(named) } return fs } -func (p *importer) param(named bool) *Field { - f := newField() +func (p *importer) param(named bool) *types.Field { + f := types.NewField() f.Type = p.typ() if f.Type.Etype == TDDDFIELD { // TDDDFIELD indicates wrapped ... slice type - f.Type = typSlice(f.Type.DDDField()) + f.Type = types.NewSlice(f.Type.DDDField()) f.SetIsddd(true) } @@ -717,7 +718,7 @@ func (p *importer) param(named bool) *Field { pkg = p.pkg() } f.Sym = pkg.Lookup(name) - f.Nname = newname(f.Sym) + f.Nname = asTypesNode(newname(f.Sym)) } // TODO(gri) This is compiler-specific (escape info). @@ -727,7 +728,7 @@ func (p *importer) param(named bool) *Field { return f } -func (p *importer) value(typ *Type) (x Val) { +func (p *importer) value(typ *types.Type) (x Val) { switch tag := p.tagOrIndex(); tag { case falseTag: x.U = false @@ -738,13 +739,13 @@ func (p *importer) value(typ *Type) (x Val) { case int64Tag: u := new(Mpint) u.SetInt64(p.int64()) - u.Rune = typ == idealrune + u.Rune = typ == types.Idealrune x.U = u case floatTag: f := newMpflt() p.float(f) - if typ == idealint || typ.IsInteger() { + if typ == types.Idealint || typ.IsInteger() { // uncommon case: large int encoded as float u := new(Mpint) u.SetFloat(f) @@ -885,7 +886,7 @@ func (p *importer) node() *Node { // (issue 16317). if typ.IsUnsafePtr() { n = nod(OCONV, n, nil) - n.Type = Types[TUINTPTR] + n.Type = types.Types[TUINTPTR] } n = nod(OCONV, n, nil) n.Type = typ @@ -1059,7 +1060,7 @@ func (p *importer) node() *Node { case OASOP: n := nodl(p.pos(), OASOP, nil, nil) - n.Etype = EType(p.int()) + n.Etype = types.EType(p.int()) n.Left = p.expr() if !p.bool() { n.Right = nodintconst(1) @@ -1189,7 +1190,7 @@ func (p *importer) exprsOrNil() (a, b *Node) { return } -func (p *importer) fieldSym() *Sym { +func (p *importer) fieldSym() *types.Sym { name := p.string() pkg := localpkg if !exportname(name) { @@ -1198,7 +1199,7 @@ func (p *importer) fieldSym() *Sym { return pkg.Lookup(name) } -func (p *importer) sym() *Sym { +func (p *importer) sym() *types.Sym { name := p.string() pkg := localpkg if name != "_" { diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go index eae6f20d80..f21a4da491 100644 --- a/src/cmd/compile/internal/gc/builtin.go +++ b/src/cmd/compile/internal/gc/builtin.go @@ -2,6 +2,8 @@ package gc +import "cmd/compile/internal/types" + var runtimeDecls = [...]struct { name string tag int @@ -145,58 +147,58 @@ var runtimeDecls = [...]struct { {"support_popcnt", varTag, 11}, } -func runtimeTypes() []*Type { - var typs [112]*Type - typs[0] = bytetype - typs[1] = typPtr(typs[0]) - typs[2] = Types[TANY] - typs[3] = typPtr(typs[2]) +func runtimeTypes() []*types.Type { + var typs [112]*types.Type + typs[0] = types.Bytetype + typs[1] = types.NewPtr(typs[0]) + typs[2] = types.Types[TANY] + typs[3] = types.NewPtr(typs[2]) typs[4] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[3])}) typs[5] = functype(nil, nil, nil) - typs[6] = Types[TINTER] + typs[6] = types.Types[TINTER] typs[7] = functype(nil, []*Node{anonfield(typs[6])}, nil) - typs[8] = Types[TINT32] - typs[9] = typPtr(typs[8]) + typs[8] = types.Types[TINT32] + typs[9] = types.NewPtr(typs[8]) typs[10] = functype(nil, []*Node{anonfield(typs[9])}, []*Node{anonfield(typs[6])}) - typs[11] = Types[TBOOL] + typs[11] = types.Types[TBOOL] typs[12] = functype(nil, []*Node{anonfield(typs[11])}, nil) - typs[13] = Types[TFLOAT64] + typs[13] = types.Types[TFLOAT64] typs[14] = functype(nil, []*Node{anonfield(typs[13])}, nil) - typs[15] = Types[TINT64] + typs[15] = types.Types[TINT64] typs[16] = functype(nil, []*Node{anonfield(typs[15])}, nil) - typs[17] = Types[TUINT64] + typs[17] = types.Types[TUINT64] typs[18] = functype(nil, []*Node{anonfield(typs[17])}, nil) - typs[19] = Types[TCOMPLEX128] + typs[19] = types.Types[TCOMPLEX128] typs[20] = functype(nil, []*Node{anonfield(typs[19])}, nil) - typs[21] = Types[TSTRING] + typs[21] = types.Types[TSTRING] typs[22] = functype(nil, []*Node{anonfield(typs[21])}, nil) typs[23] = functype(nil, []*Node{anonfield(typs[2])}, nil) - typs[24] = typArray(typs[0], 32) - typs[25] = typPtr(typs[24]) + typs[24] = types.NewArray(typs[0], 32) + typs[25] = types.NewPtr(typs[24]) typs[26] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])}) typs[27] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])}) typs[28] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])}) typs[29] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])}) - typs[30] = typSlice(typs[21]) + typs[30] = types.NewSlice(typs[21]) typs[31] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[30])}, []*Node{anonfield(typs[21])}) - typs[32] = Types[TINT] + typs[32] = types.Types[TINT] typs[33] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[32])}) typs[34] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[11])}) - typs[35] = typArray(typs[0], 4) - typs[36] = typPtr(typs[35]) + typs[35] = types.NewArray(typs[0], 4) + typs[36] = types.NewPtr(typs[35]) typs[37] = functype(nil, []*Node{anonfield(typs[36]), anonfield(typs[15])}, []*Node{anonfield(typs[21])}) - typs[38] = typSlice(typs[0]) + typs[38] = types.NewSlice(typs[0]) typs[39] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[38])}, []*Node{anonfield(typs[21])}) typs[40] = functype(nil, []*Node{anonfield(typs[38])}, []*Node{anonfield(typs[21])}) - typs[41] = runetype - typs[42] = typSlice(typs[41]) + typs[41] = types.Runetype + typs[42] = types.NewSlice(typs[41]) typs[43] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[42])}, []*Node{anonfield(typs[21])}) typs[44] = functype(nil, []*Node{anonfield(typs[25]), anonfield(typs[21])}, []*Node{anonfield(typs[38])}) - typs[45] = typArray(typs[41], 32) - typs[46] = typPtr(typs[45]) + typs[45] = types.NewArray(typs[41], 32) + typs[46] = types.NewPtr(typs[45]) typs[47] = functype(nil, []*Node{anonfield(typs[46]), anonfield(typs[21])}, []*Node{anonfield(typs[42])}) typs[48] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[32])}, []*Node{anonfield(typs[41]), anonfield(typs[32])}) - typs[49] = Types[TUINTPTR] + typs[49] = types.Types[TUINTPTR] typs[50] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2]), anonfield(typs[49])}, []*Node{anonfield(typs[32])}) typs[51] = functype(nil, []*Node{anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])}) typs[52] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])}) @@ -204,10 +206,10 @@ func runtimeTypes() []*Type { typs[54] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[11])}) typs[55] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil) typs[56] = functype(nil, []*Node{anonfield(typs[1])}, nil) - typs[57] = typPtr(typs[49]) - typs[58] = Types[TUNSAFEPTR] + typs[57] = types.NewPtr(typs[49]) + typs[58] = types.Types[TUNSAFEPTR] typs[59] = functype(nil, []*Node{anonfield(typs[57]), anonfield(typs[58]), anonfield(typs[58])}, []*Node{anonfield(typs[11])}) - typs[60] = typMap(typs[2], typs[2]) + typs[60] = types.NewMap(typs[2], typs[2]) typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[60])}) typs[62] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3])}, []*Node{anonfield(typs[3])}) typs[63] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[2])}, []*Node{anonfield(typs[3])}) @@ -218,14 +220,14 @@ func runtimeTypes() []*Type { typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[3])}, nil) typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[60]), anonfield(typs[2])}, nil) typs[70] = functype(nil, []*Node{anonfield(typs[3])}, nil) - typs[71] = typChan(typs[2], Cboth) + typs[71] = types.NewChan(typs[2], types.Cboth) typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[71])}) - typs[73] = typChan(typs[2], Crecv) + typs[73] = types.NewChan(typs[2], types.Crecv) typs[74] = functype(nil, []*Node{anonfield(typs[73]), anonfield(typs[3])}, nil) typs[75] = functype(nil, []*Node{anonfield(typs[73]), anonfield(typs[3])}, []*Node{anonfield(typs[11])}) - typs[76] = typChan(typs[2], Csend) + typs[76] = types.NewChan(typs[2], types.Csend) typs[77] = functype(nil, []*Node{anonfield(typs[76]), anonfield(typs[3])}, nil) - typs[78] = typArray(typs[0], 3) + typs[78] = types.NewArray(typs[0], 3) typs[79] = tostruct([]*Node{namedfield("enabled", typs[11]), namedfield("pad", typs[78]), namedfield("needed", typs[11]), namedfield("cgo", typs[11]), namedfield("alignme", typs[17])}) typs[80] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[2])}, nil) typs[81] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil) @@ -233,13 +235,13 @@ func runtimeTypes() []*Type { typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2]), anonfield(typs[2])}, []*Node{anonfield(typs[32])}) typs[84] = functype(nil, []*Node{anonfield(typs[76]), anonfield(typs[3])}, []*Node{anonfield(typs[11])}) typs[85] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[73])}, []*Node{anonfield(typs[11])}) - typs[86] = typPtr(typs[11]) + typs[86] = types.NewPtr(typs[11]) typs[87] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[86]), anonfield(typs[73])}, []*Node{anonfield(typs[11])}) typs[88] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[8])}, nil) typs[89] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[76]), anonfield(typs[3])}, nil) typs[90] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[73]), anonfield(typs[3]), anonfield(typs[86])}, nil) typs[91] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[32])}) - typs[92] = typSlice(typs[2]) + typs[92] = types.NewSlice(typs[2]) typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[32]), anonfield(typs[32])}, []*Node{anonfield(typs[92])}) typs[94] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[92])}) typs[95] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[92]), anonfield(typs[32])}, []*Node{anonfield(typs[92])}) @@ -251,7 +253,7 @@ func runtimeTypes() []*Type { typs[101] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[17])}, []*Node{anonfield(typs[17])}) typs[102] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[15])}) typs[103] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[17])}) - typs[104] = Types[TUINT32] + typs[104] = types.Types[TUINT32] typs[105] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[104])}) typs[106] = functype(nil, []*Node{anonfield(typs[15])}, []*Node{anonfield(typs[13])}) typs[107] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[13])}) diff --git a/src/cmd/compile/internal/gc/checkcfg.go b/src/cmd/compile/internal/gc/checkcfg.go index bbb93a60c3..1b2fa65645 100644 --- a/src/cmd/compile/internal/gc/checkcfg.go +++ b/src/cmd/compile/internal/gc/checkcfg.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/src" ) @@ -76,7 +77,7 @@ func (l *cfLabel) defined() bool { return l.defNode != nil } func (l *cfLabel) used() bool { return l.useNode != nil } // label returns the label associated with sym, creating it if necessary. -func (c *controlflow) label(sym *Sym) *cfLabel { +func (c *controlflow) label(sym *types.Sym) *cfLabel { lab := c.labels[sym.Name] if lab == nil { lab = new(cfLabel) @@ -253,8 +254,8 @@ func (c *controlflow) checkgoto(from *Node, to *Node) { // Decide what to complain about. Unwind to.Sym until where it // forked from from.Sym, and keep track of the innermost block // and declaration we jumped into/over. - var block *Sym - var dcl *Sym + var block *types.Sym + var dcl *types.Sym // If to.Sym is longer, unwind until it's the same length. ts := to.Sym @@ -290,7 +291,7 @@ func (c *controlflow) checkgoto(from *Node, to *Node) { // dcldepth returns the declaration depth for a dclstack Sym; that is, // the sum of the block nesting level and the number of declarations // in scope. -func dcldepth(s *Sym) int { +func dcldepth(s *types.Sym) int { n := 0 for ; s != nil; s = s.Link { n++ diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index 99b2678f50..cc6f8eb6a6 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "fmt" ) @@ -155,7 +156,7 @@ func typecheckclosure(func_ *Node, top int) { var closurename_closgen int -func closurename(n *Node) *Sym { +func closurename(n *Node) *types.Sym { if n.Sym != nil { return n.Sym } @@ -282,7 +283,7 @@ func capturevars(xfunc *Node) { } if Debug['m'] > 1 { - var name *Sym + var name *types.Sym if v.Name.Curfn != nil && v.Name.Curfn.Func.Nname != nil { name = v.Name.Curfn.Func.Nname.Sym } @@ -327,35 +328,35 @@ func transformclosure(xfunc *Node) { f := xfunc.Func.Nname // We are going to insert captured variables before input args. - var params []*Field + var params []*types.Field var decls []*Node for _, v := range func_.Func.Cvars.Slice() { if v.Op == OXXX { continue } - fld := newField() - fld.Funarg = FunargParams + fld := types.NewField() + fld.Funarg = types.FunargParams if v.Name.Byval() { // If v is captured by value, we merely downgrade it to PPARAM. v.Class = PPARAM - fld.Nname = v + fld.Nname = asTypesNode(v) } else { // If v of type T is captured by reference, // we introduce function param &v *T // and v remains PAUTOHEAP with &v heapaddr // (accesses will implicitly deref &v). addr := newname(lookup("&" + v.Sym.Name)) - addr.Type = typPtr(v.Type) + addr.Type = types.NewPtr(v.Type) addr.Class = PPARAM v.Name.Param.Heapaddr = addr - fld.Nname = addr + fld.Nname = asTypesNode(addr) } - fld.Type = fld.Nname.Type - fld.Sym = fld.Nname.Sym + fld.Type = asNode(fld.Nname).Type + fld.Sym = asNode(fld.Nname).Sym params = append(params, fld) - decls = append(decls, fld.Nname) + decls = append(decls, asNode(fld.Nname)) } if len(params) > 0 { @@ -380,7 +381,7 @@ func transformclosure(xfunc *Node) { cv.Type = v.Type if !v.Name.Byval() { - cv.Type = typPtr(v.Type) + cv.Type = types.NewPtr(v.Type) } offset = Rnd(offset, int64(cv.Type.Align)) cv.Xoffset = offset @@ -395,7 +396,7 @@ func transformclosure(xfunc *Node) { // Declare variable holding addresses taken from closure // and initialize in entry prologue. addr := newname(lookup("&" + v.Sym.Name)) - addr.Type = typPtr(v.Type) + addr.Type = types.NewPtr(v.Type) addr.Class = PAUTO addr.SetUsed(true) addr.Name.Curfn = xfunc @@ -473,7 +474,7 @@ func walkclosure(func_ *Node, init *Nodes) *Node { typ := nod(OTSTRUCT, nil, nil) - typ.List.Set1(namedfield(".F", Types[TUINTPTR])) + typ.List.Set1(namedfield(".F", types.Types[TUINTPTR])) for _, v := range func_.Func.Cvars.Slice() { if v.Op == OXXX { continue @@ -513,7 +514,7 @@ func walkclosure(func_ *Node, init *Nodes) *Node { return walkexpr(clos, init) } -func typecheckpartialcall(fn *Node, sym *Sym) { +func typecheckpartialcall(fn *Node, sym *types.Sym) { switch fn.Op { case ODOTINTER, ODOTMETH: break @@ -530,9 +531,9 @@ func typecheckpartialcall(fn *Node, sym *Sym) { fn.Type = xfunc.Type } -var makepartialcall_gopkg *Pkg +var makepartialcall_gopkg *types.Pkg -func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { +func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node { var p string rcvrtype := fn.Left.Type @@ -549,7 +550,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { Fatalf("missing base type for %v", rcvrtype) } - var spkg *Pkg + var spkg *types.Pkg if basetype.Sym != nil { spkg = basetype.Sym.Pkg } @@ -563,7 +564,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { sym := spkg.Lookup(p) if sym.Uniq() { - return sym.Def + return asNode(sym.Def) } sym.SetUniq(true) @@ -629,7 +630,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { ptr.Type = rcvrtype body = append(body, nod(OAS, ptr, cv)) } else { - ptr.Type = typPtr(rcvrtype) + ptr.Type = types.NewPtr(rcvrtype) body = append(body, nod(OAS, ptr, nod(OADDR, cv, nil))) } @@ -650,7 +651,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { xfunc.Nbody.Set(body) xfunc = typecheck(xfunc, Etop) - sym.Def = xfunc + sym.Def = asTypesNode(xfunc) xtop = append(xtop, xfunc) Curfn = savecurfn @@ -674,7 +675,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node { } typ := nod(OTSTRUCT, nil, nil) - typ.List.Set1(namedfield("F", Types[TUINTPTR])) + typ.List.Set1(namedfield("F", types.Types[TUINTPTR])) typ.List.Append(namedfield("R", n.Left.Type)) clos := nod(OCOMPLIT, nil, nod(OIND, typ, nil)) diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go index 24c0fba523..68d83bb962 100644 --- a/src/cmd/compile/internal/gc/const.go +++ b/src/cmd/compile/internal/gc/const.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/src" "math/big" "strings" @@ -132,7 +133,7 @@ func (n *Node) Bool() bool { // truncate float literal fv to 32-bit or 64-bit precision // according to type; return truncated value. -func truncfltlit(oldv *Mpflt, t *Type) *Mpflt { +func truncfltlit(oldv *Mpflt, t *types.Type) *Mpflt { if t == nil { return oldv } @@ -147,7 +148,7 @@ func truncfltlit(oldv *Mpflt, t *Type) *Mpflt { // convert large precision literal floating // into limited precision (float64 or float32) switch t.Etype { - case TFLOAT64: + case types.TFLOAT64: d := fv.Float64() fv.SetFloat64(d) @@ -172,7 +173,7 @@ const ( // implicit conversion. // The result of convlit MUST be assigned back to n, e.g. // n.Left = convlit(n.Left, t) -func convlit(n *Node, t *Type) *Node { +func convlit(n *Node, t *types.Type) *Node { return convlit1(n, t, false, noReuse) } @@ -180,7 +181,7 @@ func convlit(n *Node, t *Type) *Node { // It returns a new node if necessary. // The result of convlit1 MUST be assigned back to n, e.g. // n.Left = convlit1(n.Left, t, explicit, reuse) -func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node { +func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node { if n == nil || t == nil || n.Type == nil || t.IsUntyped() || n.Type == t { return n } @@ -198,11 +199,11 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node { switch n.Op { default: - if n.Type == idealbool { + if n.Type == types.Idealbool { if t.IsBoolean() { n.Type = t } else { - n.Type = Types[TBOOL] + n.Type = types.Types[TBOOL] } } @@ -240,17 +241,17 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node { default: // If trying to convert to non-complex type, // leave as complex128 and let typechecker complain. - t = Types[TCOMPLEX128] + t = types.Types[TCOMPLEX128] fallthrough - case TCOMPLEX128: + case types.TCOMPLEX128: n.Type = t - n.Left = convlit(n.Left, Types[TFLOAT64]) - n.Right = convlit(n.Right, Types[TFLOAT64]) + n.Left = convlit(n.Left, types.Types[TFLOAT64]) + n.Right = convlit(n.Right, types.Types[TFLOAT64]) case TCOMPLEX64: n.Type = t - n.Left = convlit(n.Left, Types[TFLOAT32]) - n.Right = convlit(n.Right, Types[TFLOAT32]) + n.Left = convlit(n.Left, types.Types[TFLOAT32]) + n.Right = convlit(n.Right, types.Types[TFLOAT32]) } } @@ -263,14 +264,14 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node { } ct := consttype(n) - var et EType + var et types.EType if ct < 0 { goto bad } et = t.Etype if et == TINTER { - if ct == CTNIL && n.Type == Types[TNIL] { + if ct == CTNIL && n.Type == types.Types[TNIL] { n.Type = t return n } @@ -361,7 +362,7 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node { case CTCPLX: overflow(n.Val(), t) } - } else if et == TSTRING && (ct == CTINT || ct == CTRUNE) && explicit { + } else if et == types.TSTRING && (ct == CTINT || ct == CTRUNE) && explicit { n.SetVal(tostr(n.Val())) } else { goto bad @@ -492,7 +493,7 @@ func toint(v Val) Val { return v } -func doesoverflow(v Val, t *Type) bool { +func doesoverflow(v Val, t *types.Type) bool { switch u := v.U.(type) { case *Mpint: if !t.IsInteger() { @@ -517,7 +518,7 @@ func doesoverflow(v Val, t *Type) bool { return false } -func overflow(v Val, t *Type) { +func overflow(v Val, t *types.Type) { // v has already been converted // to appropriate form for t. if t == nil || t.Etype == TIDEAL { @@ -702,7 +703,7 @@ func evconst(n *Node) { nr := n.Right var rv Val var lno src.XPos - var wr EType + var wr types.EType var v Val var norig *Node var nn *Node @@ -750,7 +751,7 @@ func evconst(n *Node) { case OCOM_ | CTINT_, OCOM_ | CTRUNE_: - var et EType = Txxx + var et types.EType = Txxx if nl.Type != nil { et = nl.Type.Etype } @@ -836,7 +837,7 @@ func evconst(n *Node) { // right must be unsigned. // left can be ideal. case OLSH, ORSH: - nr = defaultlit(nr, Types[TUINT]) + nr = defaultlit(nr, types.Types[TUINT]) n.Right = nr if nr.Type != nil && (nr.Type.IsSigned() || !nr.Type.IsInteger()) { @@ -1219,16 +1220,16 @@ func nodlit(v Val) *Node { Fatalf("nodlit ctype %d", v.Ctype()) case CTSTR: - n.Type = idealstring + n.Type = types.Idealstring case CTBOOL: - n.Type = idealbool + n.Type = types.Idealbool case CTINT, CTRUNE, CTFLT, CTCPLX: - n.Type = Types[TIDEAL] + n.Type = types.Types[TIDEAL] case CTNIL: - n.Type = Types[TNIL] + n.Type = types.Types[TNIL] } return n @@ -1240,7 +1241,7 @@ func nodcplxlit(r Val, i Val) *Node { c := new(Mpcplx) n := nod(OLITERAL, nil, nil) - n.Type = Types[TIDEAL] + n.Type = types.Types[TIDEAL] n.SetVal(Val{c}) if r.Ctype() != CTFLT || i.Ctype() != CTFLT { @@ -1318,13 +1319,13 @@ func idealkind(n *Node) Ctype { // The result of defaultlit MUST be assigned back to n, e.g. // n.Left = defaultlit(n.Left, t) -func defaultlit(n *Node, t *Type) *Node { +func defaultlit(n *Node, t *types.Type) *Node { return defaultlitreuse(n, t, noReuse) } // The result of defaultlitreuse MUST be assigned back to n, e.g. // n.Left = defaultlitreuse(n.Left, t, reuse) -func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node { +func defaultlitreuse(n *Node, t *types.Type, reuse canReuseNode) *Node { if n == nil || !n.Type.IsUntyped() { return n } @@ -1337,7 +1338,7 @@ func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node { lno := setlineno(n) ctype := idealkind(n) - var t1 *Type + var t1 *types.Type switch ctype { default: if t != nil { @@ -1356,7 +1357,7 @@ func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node { } if n.Val().Ctype() == CTSTR { - t1 := Types[TSTRING] + t1 := types.Types[TSTRING] n = convlit1(n, t1, false, reuse) break } @@ -1367,26 +1368,26 @@ func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node { Fatalf("defaultlit: idealkind is CTxxx: %+v", n) case CTBOOL: - t1 := Types[TBOOL] + t1 := types.Types[TBOOL] if t != nil && t.IsBoolean() { t1 = t } n = convlit1(n, t1, false, reuse) case CTINT: - t1 = Types[TINT] + t1 = types.Types[TINT] goto num case CTRUNE: - t1 = runetype + t1 = types.Runetype goto num case CTFLT: - t1 = Types[TFLOAT64] + t1 = types.Types[TFLOAT64] goto num case CTCPLX: - t1 = Types[TCOMPLEX128] + t1 = types.Types[TCOMPLEX128] goto num } @@ -1446,32 +1447,32 @@ func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) { } if l.Type.IsBoolean() { - l = convlit(l, Types[TBOOL]) - r = convlit(r, Types[TBOOL]) + l = convlit(l, types.Types[TBOOL]) + r = convlit(r, types.Types[TBOOL]) } lkind := idealkind(l) rkind := idealkind(r) if lkind == CTCPLX || rkind == CTCPLX { - l = convlit(l, Types[TCOMPLEX128]) - r = convlit(r, Types[TCOMPLEX128]) + l = convlit(l, types.Types[TCOMPLEX128]) + r = convlit(r, types.Types[TCOMPLEX128]) return l, r } if lkind == CTFLT || rkind == CTFLT { - l = convlit(l, Types[TFLOAT64]) - r = convlit(r, Types[TFLOAT64]) + l = convlit(l, types.Types[TFLOAT64]) + r = convlit(r, types.Types[TFLOAT64]) return l, r } if lkind == CTRUNE || rkind == CTRUNE { - l = convlit(l, runetype) - r = convlit(r, runetype) + l = convlit(l, types.Runetype) + r = convlit(r, types.Runetype) return l, r } - l = convlit(l, Types[TINT]) - r = convlit(r, Types[TINT]) + l = convlit(l, types.Types[TINT]) + r = convlit(r, types.Types[TINT]) return l, r } @@ -1673,13 +1674,13 @@ func isgoconst(n *Node) bool { } case ONAME: - l := n.Sym.Def + l := asNode(n.Sym.Def) if l != nil && l.Op == OLITERAL && n.Val().Ctype() != CTNIL { return true } case ONONAME: - if n.Sym.Def != nil && n.Sym.Def.Op == OIOTA { + if asNode(n.Sym.Def) != nil && asNode(n.Sym.Def).Op == OIOTA { return true } diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index 8f548895d4..0704d6ef5d 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/src" "fmt" "strings" @@ -30,9 +31,9 @@ var block int32 // current block number // Finally, the Syms in this list are not "real" Syms as they don't actually // represent object names. Sym is just a convenient type for saving shadowed // Sym definitions, and only a subset of its fields are actually used. -var dclstack *Sym +var dclstack *types.Sym -func dcopy(a, b *Sym) { +func dcopy(a, b *types.Sym) { a.Pkg = b.Pkg a.Name = b.Name a.Def = b.Def @@ -40,8 +41,8 @@ func dcopy(a, b *Sym) { a.Lastlineno = b.Lastlineno } -func push() *Sym { - d := new(Sym) +func push() *types.Sym { + d := new(types.Sym) d.Lastlineno = lineno d.Link = dclstack dclstack = d @@ -50,7 +51,7 @@ func push() *Sym { // pushdcl pushes the current declaration for symbol s (if any) so that // it can be shadowed by a new declaration within a nested block scope. -func pushdcl(s *Sym) *Sym { +func pushdcl(s *types.Sym) *types.Sym { d := push() dcopy(d, s) return d @@ -111,7 +112,7 @@ func testdclstack() { } // redeclare emits a diagnostic about symbol s being redeclared somewhere. -func redeclare(s *Sym, where string) { +func redeclare(s *types.Sym, where string) { if !s.Lastlineno.IsKnown() { var tmp string if s.Origpkg != nil { @@ -208,7 +209,7 @@ func declare(n *Node, ctxt Class) { s.Block = block s.Lastlineno = lineno - s.Def = n + s.Def = asTypesNode(n) n.Name.Vargen = int32(gen) n.Name.Funcdepth = funcdepth n.Class = ctxt @@ -216,7 +217,7 @@ func declare(n *Node, ctxt Class) { autoexport(n, ctxt) } -func addvar(n *Node, t *Type, ctxt Class) { +func addvar(n *Node, t *types.Type, ctxt Class) { if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil { Fatalf("addvar: n=%v t=%v nil", n, t) } @@ -284,7 +285,7 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node { } // newnoname returns a new ONONAME Node associated with symbol s. -func newnoname(s *Sym) *Node { +func newnoname(s *types.Sym) *Node { if s == nil { Fatalf("newnoname nil") } @@ -297,7 +298,7 @@ func newnoname(s *Sym) *Node { // newfuncname generates a new name node for a function or method. // TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360. -func newfuncname(s *Sym) *Node { +func newfuncname(s *types.Sym) *Node { n := newname(s) n.Func = new(Func) n.Func.SetIsHiddenClosure(Curfn != nil) @@ -306,37 +307,37 @@ func newfuncname(s *Sym) *Node { // this generates a new name node for a name // being declared. -func dclname(s *Sym) *Node { +func dclname(s *types.Sym) *Node { n := newname(s) n.Op = ONONAME // caller will correct it return n } -func typenod(t *Type) *Node { +func typenod(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 t.nod == nil || t.nod.Type != t { - t.nod = nod(OTYPE, nil, nil) - t.nod.Type = t - t.nod.Sym = t.Sym + if asNode(t.Nod) == nil || asNode(t.Nod).Type != t { + t.Nod = asTypesNode(nod(OTYPE, nil, nil)) + asNode(t.Nod).Type = t + asNode(t.Nod).Sym = t.Sym } - return t.nod + return asNode(t.Nod) } -func anonfield(typ *Type) *Node { +func anonfield(typ *types.Type) *Node { return nod(ODCLFIELD, nil, typenod(typ)) } -func namedfield(s string, typ *Type) *Node { +func namedfield(s string, typ *types.Type) *Node { return nod(ODCLFIELD, newname(lookup(s)), typenod(typ)) } // oldname returns the Node that declares symbol s in the current scope. // If no such Node currently exists, an ONONAME Node is returned instead. -func oldname(s *Sym) *Node { - n := s.Def +func oldname(s *types.Sym) *Node { + n := asNode(s.Def) if n == nil { // Maybe a top-level declaration will come along later to // define s. resolve will check s.Def again once all input @@ -557,34 +558,34 @@ func funcargs(nt *Node) { // Same as funcargs, except run over an already constructed TFUNC. // This happens during import, where the hidden_fndcl rule has // used functype directly to parse the function's type. -func funcargs2(t *Type) { +func funcargs2(t *types.Type) { if t.Etype != TFUNC { Fatalf("funcargs2 %v", t) } for _, ft := range t.Recvs().Fields().Slice() { - if ft.Nname == nil || ft.Nname.Sym == nil { + if asNode(ft.Nname) == nil || asNode(ft.Nname).Sym == nil { continue } - n := ft.Nname // no need for newname(ft->nname->sym) + n := asNode(ft.Nname) // no need for newname(ft->nname->sym) n.Type = ft.Type declare(n, PPARAM) } for _, ft := range t.Params().Fields().Slice() { - if ft.Nname == nil || ft.Nname.Sym == nil { + if asNode(ft.Nname) == nil || asNode(ft.Nname).Sym == nil { continue } - n := ft.Nname + n := asNode(ft.Nname) n.Type = ft.Type declare(n, PPARAM) } for _, ft := range t.Results().Fields().Slice() { - if ft.Nname == nil || ft.Nname.Sym == nil { + if asNode(ft.Nname) == nil || asNode(ft.Nname).Sym == nil { continue } - n := ft.Nname + n := asNode(ft.Nname) n.Type = ft.Type declare(n, PPARAMOUT) } @@ -620,7 +621,7 @@ func funcbody(n *Node) { // structs, functions, and methods. // they don't belong here, but where do they belong? -func checkembeddedtype(t *Type) { +func checkembeddedtype(t *types.Type) { if t == nil { return } @@ -639,7 +640,7 @@ func checkembeddedtype(t *Type) { } } -func structfield(n *Node) *Field { +func structfield(n *Node) *types.Field { lno := lineno lineno = n.Pos @@ -647,7 +648,7 @@ func structfield(n *Node) *Field { Fatalf("structfield: oops %v\n", n) } - f := newField() + f := types.NewField() f.SetIsddd(n.Isddd()) if n.Right != nil { @@ -678,9 +679,9 @@ func structfield(n *Node) *Field { } if n.Left != nil && n.Left.Op == ONAME { - f.Nname = n.Left + f.Nname = asTypesNode(n.Left) f.Embedded = n.Embedded - f.Sym = f.Nname.Sym + f.Sym = asNode(f.Nname).Sym } lineno = lno @@ -689,15 +690,15 @@ func structfield(n *Node) *Field { // checkdupfields emits errors for duplicately named fields or methods in // a list of struct or interface types. -func checkdupfields(what string, ts ...*Type) { - seen := make(map[*Sym]bool) +func checkdupfields(what string, ts ...*types.Type) { + seen := make(map[*types.Sym]bool) for _, t := range ts { for _, f := range t.Fields().Slice() { - if f.Sym == nil || isblanksym(f.Sym) || f.Nname == nil { + if f.Sym == nil || isblanksym(f.Sym) || asNode(f.Nname) == nil { continue } if seen[f.Sym] { - yyerrorl(f.Nname.Pos, "duplicate %s %s", what, f.Sym.Name) + yyerrorl(asNode(f.Nname).Pos, "duplicate %s %s", what, f.Sym.Name) continue } seen[f.Sym] = true @@ -707,18 +708,18 @@ func checkdupfields(what string, ts ...*Type) { // convert a parsed id/type list into // a type for struct/interface/arglist -func tostruct(l []*Node) *Type { - t := typ(TSTRUCT) +func tostruct(l []*Node) *types.Type { + t := types.New(TSTRUCT) tostruct0(t, l) return t } -func tostruct0(t *Type, l []*Node) { +func tostruct0(t *types.Type, l []*Node) { if t == nil || !t.IsStruct() { Fatalf("struct expected") } - fields := make([]*Field, len(l)) + fields := make([]*types.Field, len(l)) for i, n := range l { f := structfield(n) if f.Broke() { @@ -735,11 +736,11 @@ func tostruct0(t *Type, l []*Node) { } } -func tofunargs(l []*Node, funarg Funarg) *Type { - t := typ(TSTRUCT) +func tofunargs(l []*Node, funarg types.Funarg) *types.Type { + t := types.New(TSTRUCT) t.StructType().Funarg = funarg - fields := make([]*Field, len(l)) + fields := make([]*types.Field, len(l)) for i, n := range l { f := structfield(n) f.Funarg = funarg @@ -757,23 +758,23 @@ func tofunargs(l []*Node, funarg Funarg) *Type { return t } -func tofunargsfield(fields []*Field, funarg Funarg) *Type { - t := typ(TSTRUCT) +func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type { + t := types.New(TSTRUCT) t.StructType().Funarg = funarg for _, f := range fields { f.Funarg = funarg // esc.go needs to find f given a PPARAM to add the tag. - if f.Nname != nil && f.Nname.Class == PPARAM { - f.Nname.Name.Param.Field = f + if asNode(f.Nname) != nil && asNode(f.Nname).Class == PPARAM { + asNode(f.Nname).Name.Param.Field = f } } t.SetFields(fields) return t } -func interfacefield(n *Node) *Field { +func interfacefield(n *Node) *types.Field { lno := lineno lineno = n.Pos @@ -796,14 +797,14 @@ func interfacefield(n *Node) *Field { n.Right = nil } - f := newField() + f := types.NewField() if n.Left != nil { - f.Nname = n.Left - f.Sym = f.Nname.Sym + f.Nname = asTypesNode(n.Left) + f.Sym = asNode(f.Nname).Sym } else { // Placeholder ONAME just to hold Pos. // TODO(mdempsky): Add Pos directly to Field instead. - f.Nname = newname(nblank.Sym) + f.Nname = asTypesNode(newname(nblank.Sym)) } f.Type = n.Type @@ -815,21 +816,21 @@ func interfacefield(n *Node) *Field { return f } -func tointerface(l []*Node) *Type { +func tointerface(l []*Node) *types.Type { if len(l) == 0 { - return Types[TINTER] + return types.Types[TINTER] } - t := typ(TINTER) + t := types.New(TINTER) tointerface0(t, l) return t } -func tointerface0(t *Type, l []*Node) *Type { +func tointerface0(t *types.Type, l []*Node) *types.Type { if t == nil || !t.IsInterface() { Fatalf("interface expected") } - var fields []*Field + var fields []*types.Field for _, n := range l { f := interfacefield(n) if f.Broke() { @@ -842,7 +843,7 @@ func tointerface0(t *Type, l []*Node) *Type { return t } -func embedded(s *Sym, pkg *Pkg) *Node { +func embedded(s *types.Sym, pkg *types.Pkg) *Node { const ( CenterDot = 0xB7 ) @@ -870,20 +871,20 @@ func embedded(s *Sym, pkg *Pkg) *Node { } // thisT is the singleton type used for interface method receivers. -var thisT *Type +var thisT *types.Type func fakethis() *Node { if thisT == nil { - thisT = typPtr(typ(TSTRUCT)) + thisT = types.NewPtr(types.New(TSTRUCT)) } return anonfield(thisT) } -func fakethisfield() *Field { +func fakethisfield() *types.Field { if thisT == nil { - thisT = typPtr(typ(TSTRUCT)) + thisT = types.NewPtr(types.New(TSTRUCT)) } - f := newField() + f := types.NewField() f.Type = thisT return f } @@ -891,18 +892,18 @@ func fakethisfield() *Field { // Is this field a method on an interface? // Those methods have thisT as the receiver. // (See fakethis above.) -func isifacemethod(f *Type) bool { +func isifacemethod(f *types.Type) bool { return f.Recv().Type == thisT } // turn a parsed function declaration into a type -func functype(this *Node, in, out []*Node) *Type { - t := typ(TFUNC) +func functype(this *Node, in, out []*Node) *types.Type { + t := types.New(TFUNC) functype0(t, this, in, out) return t } -func functype0(t *Type, this *Node, in, out []*Node) { +func functype0(t *types.Type, this *Node, in, out []*Node) { if t == nil || t.Etype != TFUNC { Fatalf("function type expected") } @@ -911,9 +912,9 @@ func functype0(t *Type, this *Node, in, out []*Node) { if this != nil { rcvr = []*Node{this} } - t.FuncType().Receiver = tofunargs(rcvr, FunargRcvr) - t.FuncType().Results = tofunargs(out, FunargResults) - t.FuncType().Params = tofunargs(in, FunargParams) + t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr) + t.FuncType().Results = tofunargs(out, types.FunargResults) + t.FuncType().Params = tofunargs(in, types.FunargParams) checkdupfields("argument", t.Recvs(), t.Results(), t.Params()) @@ -930,33 +931,33 @@ func functype0(t *Type, this *Node, in, out []*Node) { } } -func functypefield(this *Field, in, out []*Field) *Type { - t := typ(TFUNC) +func functypefield(this *types.Field, in, out []*types.Field) *types.Type { + t := types.New(TFUNC) functypefield0(t, this, in, out) return t } -func functypefield0(t *Type, this *Field, in, out []*Field) { - var rcvr []*Field +func functypefield0(t *types.Type, this *types.Field, in, out []*types.Field) { + var rcvr []*types.Field if this != nil { - rcvr = []*Field{this} + rcvr = []*types.Field{this} } - t.FuncType().Receiver = tofunargsfield(rcvr, FunargRcvr) - t.FuncType().Results = tofunargsfield(out, FunargRcvr) - t.FuncType().Params = tofunargsfield(in, FunargRcvr) + t.FuncType().Receiver = tofunargsfield(rcvr, types.FunargRcvr) + t.FuncType().Results = tofunargsfield(out, types.FunargRcvr) + t.FuncType().Params = tofunargsfield(in, types.FunargRcvr) t.FuncType().Outnamed = false - if len(out) > 0 && out[0].Nname != nil && out[0].Nname.Orig != nil { - s := out[0].Nname.Orig.Sym + if len(out) > 0 && asNode(out[0].Nname) != nil && asNode(out[0].Nname).Orig != nil { + s := asNode(out[0].Nname).Orig.Sym if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result t.FuncType().Outnamed = true } } } -var methodsym_toppkg *Pkg +var methodsym_toppkg *types.Pkg -func methodsym(nsym *Sym, t0 *Type, iface bool) *Sym { +func methodsym(nsym *types.Sym, t0 *types.Type, iface bool) *types.Sym { if t0 == nil { Fatalf("methodsym: nil receiver type") } @@ -974,7 +975,7 @@ func methodsym(nsym *Sym, t0 *Type, iface bool) *Sym { // if t0 == *t and t0 has a sym, // we want to see *t, not t0, in the method name. if t != t0 && t0.Sym != nil { - t0 = typPtr(t) + t0 = types.NewPtr(t) } suffix := "" @@ -985,7 +986,7 @@ func methodsym(nsym *Sym, t0 *Type, iface bool) *Sym { } } - var spkg *Pkg + var spkg *types.Pkg if s != nil { spkg = s.Pkg } @@ -1013,7 +1014,7 @@ func methodsym(nsym *Sym, t0 *Type, iface bool) *Sym { // methodname is a misnomer because this now returns a Sym, rather // than an ONAME. // TODO(mdempsky): Reconcile with methodsym. -func methodname(s *Sym, recv *Type) *Sym { +func methodname(s *types.Sym, recv *types.Type) *types.Sym { star := false if recv.IsPtr() { star = true @@ -1040,7 +1041,7 @@ func methodname(s *Sym, recv *Type) *Sym { // Add a method, declared as a function. // - msym is the method symbol // - t is function type (with receiver) -func addmethod(msym *Sym, t *Type, local, nointerface bool) { +func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) { if msym == nil { Fatalf("no method symbol") } @@ -1111,9 +1112,9 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) { return } - f := newField() + f := types.NewField() f.Sym = msym - f.Nname = newname(msym) + f.Nname = asTypesNode(newname(msym)) f.Type = t f.SetNointerface(nointerface) @@ -1143,13 +1144,13 @@ func funccompile(n *Node) { dclcontext = PEXTERN } -func (s *Sym) funcsymname() string { +func funcsymname(s *types.Sym) string { return s.Name + "·f" } // funcsym returns s·f. -func funcsym(s *Sym) *Sym { - sf, existed := s.Pkg.LookupOK(s.funcsymname()) +func funcsym(s *types.Sym) *types.Sym { + sf, existed := s.Pkg.LookupOK(funcsymname(s)) // Don't export s·f when compiling for dynamic linking. // When dynamically linking, the necessary function // symbols will be created explicitly with makefuncsym. @@ -1169,7 +1170,7 @@ func funcsym(s *Sym) *Sym { // but DUPOK doesn't work across shared library boundaries. // So instead, when dynamic linking, we only create // the s·f stubs in s's package. -func makefuncsym(s *Sym) { +func makefuncsym(s *types.Sym) { if !Ctxt.Flag_dynlink { Fatalf("makefuncsym dynlink") } @@ -1181,7 +1182,7 @@ func makefuncsym(s *Sym) { // not get a funcsym. return } - if _, existed := s.Pkg.LookupOK(s.funcsymname()); !existed { + if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed { funcsyms = append(funcsyms, s) } } @@ -1289,7 +1290,7 @@ func (c *nowritebarrierrecChecker) visitcode(n *Node) { func (c *nowritebarrierrecChecker) visitcall(n *Node) { fn := n.Left if n.Op == OCALLMETH { - fn = n.Left.Sym.Def + fn = asNode(n.Left.Sym.Def) } if fn == nil || fn.Op != ONAME || fn.Class != PFUNC || fn.Name.Defn == nil { return diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index 272c83d9d5..75adb8eecb 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "fmt" "strconv" "strings" @@ -131,7 +132,7 @@ func (v *bottomUpVisitor) visitcode(n *Node, min uint32) uint32 { if n.Op == OCALLFUNC || n.Op == OCALLMETH { fn := n.Left if n.Op == OCALLMETH { - fn = n.Left.Sym.Def + fn = asNode(n.Left.Sym.Def) } if fn != nil && fn.Op == ONAME && fn.Class == PFUNC && fn.Name.Defn != nil { m := v.visit(fn.Name.Defn) @@ -458,7 +459,7 @@ func (e *EscState) stepAssignWhere(dst, src *Node, why string, where *Node) *Esc } // funcSym returns fn.Func.Nname.Sym if no nils are encountered along the way. -func funcSym(fn *Node) *Sym { +func funcSym(fn *Node) *types.Sym { if fn == nil || fn.Func.Nname == nil { return nil } @@ -466,7 +467,7 @@ func funcSym(fn *Node) *Sym { } // curfnSym returns n.Curfn.Nname.Sym if no nils are encountered along the way. -func (e *EscState) curfnSym(n *Node) *Sym { +func (e *EscState) curfnSym(n *Node) *types.Sym { nE := e.nodeEscState(n) return funcSym(nE.Curfn) } @@ -563,7 +564,7 @@ func (e *EscState) escfunc(fn *Node) { case PPARAM: lnE.Loopdepth = 1 - if ln.Type != nil && !haspointers(ln.Type) { + if ln.Type != nil && !types.Haspointers(ln.Type) { break } if Curfn.Nbody.Len() == 0 && !Curfn.Noescape() { @@ -621,7 +622,7 @@ func (e *EscState) escloopdepth(n *Node) { // after escape analysis. in the future, maybe pull label & goto analysis out of walk and put before esc // if(n.Left.Sym.Label != nil) // fatal("escape analysis messed up analyzing label: %+N", n); - n.Left.Sym.Label = &nonlooping + n.Left.Sym.Label = asTypesNode(&nonlooping) case OGOTO: if n.Left == nil || n.Left.Sym == nil { @@ -630,8 +631,8 @@ func (e *EscState) escloopdepth(n *Node) { // If we come past one that's uninitialized, this must be a (harmless) forward jump // but if it's set to nonlooping the label must have preceded this goto. - if n.Left.Sym.Label == &nonlooping { - n.Left.Sym.Label = &looping + if asNode(n.Left.Sym.Label) == &nonlooping { + n.Left.Sym.Label = asTypesNode(&looping) } } @@ -720,11 +721,11 @@ func (e *EscState) esc(n *Node, parent *Node) { } case OLABEL: - if n.Left.Sym.Label == &nonlooping { + if asNode(n.Left.Sym.Label) == &nonlooping { if Debug['m'] > 2 { fmt.Printf("%v:%v non-looping label\n", linestr(lineno), n) } - } else if n.Left.Sym.Label == &looping { + } else if asNode(n.Left.Sym.Label) == &looping { if Debug['m'] > 2 { fmt.Printf("%v: %v looping label\n", linestr(lineno), n) } @@ -1158,7 +1159,7 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) { a := nod(OADDR, src, nil) a.Pos = src.Pos e.nodeEscState(a).Loopdepth = e.nodeEscState(src).Loopdepth - a.Type = typPtr(src.Type) + a.Type = types.NewPtr(src.Type) e.escflows(dst, a, e.stepAssign(nil, originalDst, src, dstwhy)) // Flowing multiple returns to a single dst happens when @@ -1170,7 +1171,7 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) { // A non-pointer escaping from a struct does not concern us. case ODOT: - if src.Type != nil && !haspointers(src.Type) { + if src.Type != nil && !types.Haspointers(src.Type) { break } fallthrough @@ -1191,7 +1192,7 @@ func (e *EscState) escassign(dst, src *Node, step *EscStep) { case ODOTTYPE, ODOTTYPE2: - if src.Type != nil && !haspointers(src.Type) { + if src.Type != nil && !types.Haspointers(src.Type) { break } e.escassign(dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy)) @@ -1396,7 +1397,7 @@ func (e *EscState) addDereference(n *Node) *Node { e.nodeEscState(ind).Loopdepth = e.nodeEscState(n).Loopdepth ind.Pos = n.Pos t := n.Type - if t.IsKind(Tptr) { + if t.IsKind(types.Tptr) { // This should model our own sloppy use of OIND to encode // decreasing levels of indirection; i.e., "indirecting" an array // might yield the type of an element. To be enhanced... @@ -1440,7 +1441,7 @@ func escNoteOutputParamFlow(e uint16, vargen int32, level Level) uint16 { return (e &^ (bitsMaskForTag << shift)) | encodedFlow } -func (e *EscState) initEscRetval(call *Node, fntype *Type) { +func (e *EscState) initEscRetval(call *Node, fntype *types.Type) { cE := e.nodeEscState(call) cE.Retval.Set(nil) // Suspect this is not nil for indirect calls. for i, f := range fntype.Results().Fields().Slice() { @@ -1464,7 +1465,7 @@ func (e *EscState) initEscRetval(call *Node, fntype *Type) { // different for methods vs plain functions and for imported vs // this-package func (e *EscState) esccall(call *Node, parent *Node) { - var fntype *Type + var fntype *types.Type var indirect bool var fn *Node switch call.Op { @@ -1477,7 +1478,7 @@ func (e *EscState) esccall(call *Node, parent *Node) { indirect = fn.Op != ONAME || fn.Class != PFUNC case OCALLMETH: - fn = call.Left.Sym.Def + fn = asNode(call.Left.Sym.Def) if fn != nil { fntype = fn.Type } else { @@ -1514,7 +1515,7 @@ func (e *EscState) esccall(call *Node, parent *Node) { if call.Op != OCALLFUNC { rf := fntype.Recv() r := call.Left.Left - if haspointers(rf.Type) { + if types.Haspointers(rf.Type) { e.escassignSinkWhy(call, r, "receiver in indirect call") } } else { // indirect and OCALLFUNC = could be captured variables, too. (#14409) @@ -1555,8 +1556,8 @@ func (e *EscState) esccall(call *Node, parent *Node) { if n.Isddd() && !call.Isddd() { // Introduce ODDDARG node to represent ... allocation. arg = nod(ODDDARG, nil, nil) - arr := typArray(n.Type.Elem(), int64(len(args))) - arg.Type = typPtr(arr) // make pointer so it will be tracked + arr := types.NewArray(n.Type.Elem(), int64(len(args))) + arg.Type = types.NewPtr(arr) // make pointer so it will be tracked arg.Pos = call.Pos e.track(arg) call.Right = arg @@ -1603,7 +1604,7 @@ func (e *EscState) esccall(call *Node, parent *Node) { if call.Op != OCALLFUNC { rf := fntype.Recv() r := call.Left.Left - if haspointers(rf.Type) { + if types.Haspointers(rf.Type) { e.escassignfromtag(rf.Note, cE.Retval, r, call) } } @@ -1620,8 +1621,8 @@ func (e *EscState) esccall(call *Node, parent *Node) { // Introduce ODDDARG node to represent ... allocation. arg = nod(ODDDARG, nil, nil) arg.Pos = call.Pos - arr := typArray(param.Type.Elem(), int64(len(rest))) - arg.Type = typPtr(arr) // make pointer so it will be tracked + arr := types.NewArray(param.Type.Elem(), int64(len(rest))) + arg.Type = types.NewPtr(arr) // make pointer so it will be tracked e.track(arg) call.Right = arg @@ -1643,7 +1644,7 @@ func (e *EscState) esccall(call *Node, parent *Node) { } } - if haspointers(param.Type) && e.escassignfromtag(note, cE.Retval, arg, call)&EscMask == EscNone && parent.Op != ODEFER && parent.Op != OPROC { + if types.Haspointers(param.Type) && e.escassignfromtag(note, cE.Retval, arg, call)&EscMask == EscNone && parent.Op != ODEFER && parent.Op != OPROC { a := arg for a.Op == OCONVNOP { a = a.Left @@ -1673,7 +1674,7 @@ func (e *EscState) escflows(dst, src *Node, why *EscStep) { } // Don't bother building a graph for scalars. - if src.Type != nil && !haspointers(src.Type) && !isReflectHeaderDataField(src) { + if src.Type != nil && !types.Haspointers(src.Type) && !isReflectHeaderDataField(src) { if Debug['m'] > 3 { fmt.Printf("%v::NOT flows:: %S <- %S\n", linestr(lineno), dst, src) } @@ -2036,7 +2037,7 @@ const uintptrEscapesTag = "uintptr-escapes" func (e *EscState) esctag(fn *Node) { fn.Esc = EscFuncTagged - name := func(s *Sym, narg int) string { + name := func(s *types.Sym, narg int) string { if s != nil { return s.Name } @@ -2048,7 +2049,7 @@ func (e *EscState) esctag(fn *Node) { if fn.Nbody.Len() == 0 { if fn.Noescape() { for _, f := range fn.Type.Params().Fields().Slice() { - if haspointers(f.Type) { + if types.Haspointers(f.Type) { f.Note = mktag(EscNone) } } @@ -2103,7 +2104,7 @@ func (e *EscState) esctag(fn *Node) { switch ln.Esc & EscMask { case EscNone, // not touched by escflood EscReturn: - if haspointers(ln.Type) { // don't bother tagging for scalars + if types.Haspointers(ln.Type) { // don't bother tagging for scalars if ln.Name.Param.Field.Note != uintptrEscapesTag { ln.Name.Param.Field.Note = mktag(int(ln.Esc)) } diff --git a/src/cmd/compile/internal/gc/export.go b/src/cmd/compile/internal/gc/export.go index 10e21838f5..1c6b90905f 100644 --- a/src/cmd/compile/internal/gc/export.go +++ b/src/cmd/compile/internal/gc/export.go @@ -7,6 +7,7 @@ package gc import ( "bufio" "bytes" + "cmd/compile/internal/types" "cmd/internal/bio" "fmt" "unicode" @@ -44,8 +45,8 @@ func exportsym(n *Node) { } // Ensure original types are on exportlist before type aliases. - if n.Sym.isAlias() { - exportlist = append(exportlist, n.Sym.Def) + if IsAlias(n.Sym) { + exportlist = append(exportlist, asNode(n.Sym.Def)) } exportlist = append(exportlist, n) @@ -65,7 +66,7 @@ func initname(s string) bool { // exportedsym reports whether a symbol will be visible // to files that import our package. -func exportedsym(sym *Sym) bool { +func exportedsym(sym *types.Sym) bool { // Builtins are visible everywhere. if sym.Pkg == builtinpkg || sym.Origpkg == builtinpkg { return true @@ -141,7 +142,7 @@ func reexportdep(n *Node) { } // methodbyname sorts types by symbol name. -type methodbyname []*Field +type methodbyname []*types.Field func (x methodbyname) Len() int { return len(x) } func (x methodbyname) Swap(i, j int) { x[i], x[j] = x[j], x[i] } @@ -174,7 +175,7 @@ func dumpexport() { // (use empty package map to avoid collisions) savedPkgMap := pkgMap savedPkgs := pkgs - pkgMap = make(map[string]*Pkg) + pkgMap = make(map[string]*types.Pkg) pkgs = nil Import(mkpkg(""), bufio.NewReader(©)) // must not die pkgs = savedPkgs @@ -191,14 +192,14 @@ func dumpexport() { // importsym declares symbol s as an imported object representable by op. // pkg is the package being imported -func importsym(pkg *Pkg, s *Sym, op Op) { - if s.Def != nil && s.Def.Op != op { +func importsym(pkg *types.Pkg, s *types.Sym, op Op) { + if asNode(s.Def) != nil && asNode(s.Def).Op != op { pkgstr := fmt.Sprintf("during import %q", pkg.Path) redeclare(s, pkgstr) } // mark the symbol so it is not reexported - if s.Def == nil { + if asNode(s.Def) == nil { if exportname(s.Name) || initname(s.Name) { s.SetExport(true) } else { @@ -210,28 +211,28 @@ func importsym(pkg *Pkg, s *Sym, op Op) { // pkgtype returns the named type declared by symbol s. // If no such type has been declared yet, a forward declaration is returned. // pkg is the package being imported -func pkgtype(pkg *Pkg, s *Sym) *Type { +func pkgtype(pkg *types.Pkg, s *types.Sym) *types.Type { importsym(pkg, s, OTYPE) - if s.Def == nil || s.Def.Op != OTYPE { - t := typ(TFORW) + if asNode(s.Def) == nil || asNode(s.Def).Op != OTYPE { + t := types.New(TFORW) t.Sym = s - s.Def = typenod(t) - s.Def.Name = new(Name) + s.Def = asTypesNode(typenod(t)) + asNode(s.Def).Name = new(Name) } - if s.Def.Type == nil { + if asNode(s.Def).Type == nil { Fatalf("pkgtype %v", s) } - return s.Def.Type + return asNode(s.Def).Type } // importconst declares symbol s as an imported constant with type t and value n. // pkg is the package being imported -func importconst(pkg *Pkg, s *Sym, t *Type, n *Node) { +func importconst(pkg *types.Pkg, s *types.Sym, t *types.Type, n *Node) { importsym(pkg, s, OLITERAL) n = convlit(n, t) - if s.Def != nil { // TODO: check if already the same. + if asNode(s.Def) != nil { // TODO: check if already the same. return } @@ -256,13 +257,13 @@ func importconst(pkg *Pkg, s *Sym, t *Type, n *Node) { // importvar declares symbol s as an imported variable with type t. // pkg is the package being imported -func importvar(pkg *Pkg, s *Sym, t *Type) { +func importvar(pkg *types.Pkg, s *types.Sym, t *types.Type) { importsym(pkg, s, ONAME) - if s.Def != nil && s.Def.Op == ONAME { - if eqtype(t, s.Def.Type) { + if asNode(s.Def) != nil && asNode(s.Def).Op == ONAME { + if eqtype(t, asNode(s.Def).Type) { return } - yyerror("inconsistent definition for var %v during import\n\t%v (in %q)\n\t%v (in %q)", s, s.Def.Type, s.Importdef.Path, t, pkg.Path) + yyerror("inconsistent definition for var %v during import\n\t%v (in %q)\n\t%v (in %q)", s, asNode(s.Def).Type, s.Importdef.Path, t, pkg.Path) } n := newname(s) @@ -277,13 +278,13 @@ func importvar(pkg *Pkg, s *Sym, t *Type) { // importalias declares symbol s as an imported type alias with type t. // pkg is the package being imported -func importalias(pkg *Pkg, s *Sym, t *Type) { +func importalias(pkg *types.Pkg, s *types.Sym, t *types.Type) { importsym(pkg, s, OTYPE) - if s.Def != nil && s.Def.Op == OTYPE { - if eqtype(t, s.Def.Type) { + if asNode(s.Def) != nil && asNode(s.Def).Op == OTYPE { + if eqtype(t, asNode(s.Def).Type) { return } - yyerror("inconsistent definition for type alias %v during import\n\t%v (in %q)\n\t%v (in %q)", s, s.Def.Type, s.Importdef.Path, t, pkg.Path) + yyerror("inconsistent definition for type alias %v during import\n\t%v (in %q)\n\t%v (in %q)", s, asNode(s.Def).Type, s.Importdef.Path, t, pkg.Path) } n := newname(s) diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go index ca32ebf050..f712c706eb 100644 --- a/src/cmd/compile/internal/gc/fmt.go +++ b/src/cmd/compile/internal/gc/fmt.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "fmt" "strconv" "strings" @@ -69,12 +70,12 @@ func fmtFlag(s fmt.State, verb rune) FmtFlag { // // %v *Val Constant values // -// %v *Sym Symbols +// %v *types.Sym Symbols // %S unqualified identifier in any mode // Flags: +,- #: mode (see below) // 0: in export mode: unqualified identifier if exported, qualified if not // -// %v *Type Types +// %v *types.Type Types // %S omit "func" and receiver in function types // %L definition instead of name. // Flags: +,- #: mode (see below) @@ -89,7 +90,7 @@ func fmtFlag(s fmt.State, verb rune) FmtFlag { // Flags: those of *Node // .: separate items with ',' instead of ';' -// *Sym, *Type, and *Node types use the flags below to set the format mode +// *types.Sym, *types.Type, and *Node types use the flags below to set the format mode const ( FErr = iota FDbg @@ -98,10 +99,10 @@ const ( ) // The mode flags '+', '-', and '#' are sticky; they persist through -// recursions of *Node, *Type, and *Sym values. The ' ' flag is -// sticky only on *Type recursions and only used in %-/*Sym mode. +// recursions of *Node, *types.Type, and *types.Sym values. The ' ' flag is +// sticky only on *types.Type recursions and only used in %-/*types.Sym mode. // -// Example: given a *Sym: %+v %#v %-v print an identifier properly qualified for debug/export/internal mode +// Example: given a *types.Sym: %+v %#v %-v print an identifier properly qualified for debug/export/internal mode // Useful format combinations: // TODO(gri): verify these @@ -114,7 +115,7 @@ const ( // %#v Go format // %L "foo (type Bar)" for error messages // -// *Type: +// *types.Type: // %#v Go format // %#L type definition instead of name // %#S omit"func" and receiver in function signature @@ -263,15 +264,15 @@ type ( fmtOpTypeId Op fmtOpTypeIdName Op - fmtTypeErr Type - fmtTypeDbg Type - fmtTypeTypeId Type - fmtTypeTypeIdName Type + fmtTypeErr types.Type + fmtTypeDbg types.Type + fmtTypeTypeId types.Type + fmtTypeTypeIdName types.Type - fmtSymErr Sym - fmtSymDbg Sym - fmtSymTypeId Sym - fmtSymTypeIdName Sym + fmtSymErr types.Sym + fmtSymDbg types.Sym + fmtSymTypeId types.Sym + fmtSymTypeIdName types.Sym fmtNodesErr Nodes fmtNodesDbg Nodes @@ -291,17 +292,23 @@ func (o fmtOpTypeId) Format(s fmt.State, verb rune) { Op(o).format(s, verb, func (o fmtOpTypeIdName) Format(s fmt.State, verb rune) { Op(o).format(s, verb, FTypeIdName) } func (o Op) Format(s fmt.State, verb rune) { o.format(s, verb, FErr) } -func (t *fmtTypeErr) Format(s fmt.State, verb rune) { (*Type)(t).format(s, verb, FErr) } -func (t *fmtTypeDbg) Format(s fmt.State, verb rune) { (*Type)(t).format(s, verb, FDbg) } -func (t *fmtTypeTypeId) Format(s fmt.State, verb rune) { (*Type)(t).format(s, verb, FTypeId) } -func (t *fmtTypeTypeIdName) Format(s fmt.State, verb rune) { (*Type)(t).format(s, verb, FTypeIdName) } -func (t *Type) Format(s fmt.State, verb rune) { t.format(s, verb, FErr) } +func (t *fmtTypeErr) Format(s fmt.State, verb rune) { typeFormat((*types.Type)(t), s, verb, FErr) } +func (t *fmtTypeDbg) Format(s fmt.State, verb rune) { typeFormat((*types.Type)(t), s, verb, FDbg) } +func (t *fmtTypeTypeId) Format(s fmt.State, verb rune) { typeFormat((*types.Type)(t), s, verb, FTypeId) } +func (t *fmtTypeTypeIdName) Format(s fmt.State, verb rune) { + typeFormat((*types.Type)(t), s, verb, FTypeIdName) +} + +// func (t *types.Type) Format(s fmt.State, verb rune) // in package types + +func (y *fmtSymErr) Format(s fmt.State, verb rune) { symFormat((*types.Sym)(y), s, verb, FErr) } +func (y *fmtSymDbg) Format(s fmt.State, verb rune) { symFormat((*types.Sym)(y), s, verb, FDbg) } +func (y *fmtSymTypeId) Format(s fmt.State, verb rune) { symFormat((*types.Sym)(y), s, verb, FTypeId) } +func (y *fmtSymTypeIdName) Format(s fmt.State, verb rune) { + symFormat((*types.Sym)(y), s, verb, FTypeIdName) +} -func (y *fmtSymErr) Format(s fmt.State, verb rune) { (*Sym)(y).format(s, verb, FErr) } -func (y *fmtSymDbg) Format(s fmt.State, verb rune) { (*Sym)(y).format(s, verb, FDbg) } -func (y *fmtSymTypeId) Format(s fmt.State, verb rune) { (*Sym)(y).format(s, verb, FTypeId) } -func (y *fmtSymTypeIdName) Format(s fmt.State, verb rune) { (*Sym)(y).format(s, verb, FTypeIdName) } -func (y *Sym) Format(s fmt.State, verb rune) { y.format(s, verb, FErr) } +// func (y *types.Sym) Format(s fmt.State, verb rune) // in package types { y.format(s, verb, FErr) } func (n fmtNodesErr) Format(s fmt.State, verb rune) { (Nodes)(n).format(s, verb, FErr) } func (n fmtNodesDbg) Format(s fmt.State, verb rune) { (Nodes)(n).format(s, verb, FDbg) } @@ -333,13 +340,13 @@ func (m fmtMode) prepareArgs(args []interface{}) { args[i] = fmtOpErr(arg) case *Node: args[i] = (*fmtNodeErr)(arg) - case *Type: + case *types.Type: args[i] = (*fmtTypeErr)(arg) - case *Sym: + case *types.Sym: args[i] = (*fmtSymErr)(arg) case Nodes: args[i] = fmtNodesErr(arg) - case Val, int32, int64, string, EType: + case Val, int32, int64, string, types.EType: // OK: printing these types doesn't depend on mode default: Fatalf("mode.prepareArgs type %T", arg) @@ -352,13 +359,13 @@ func (m fmtMode) prepareArgs(args []interface{}) { args[i] = fmtOpDbg(arg) case *Node: args[i] = (*fmtNodeDbg)(arg) - case *Type: + case *types.Type: args[i] = (*fmtTypeDbg)(arg) - case *Sym: + case *types.Sym: args[i] = (*fmtSymDbg)(arg) case Nodes: args[i] = fmtNodesDbg(arg) - case Val, int32, int64, string, EType: + case Val, int32, int64, string, types.EType: // OK: printing these types doesn't depend on mode default: Fatalf("mode.prepareArgs type %T", arg) @@ -371,13 +378,13 @@ func (m fmtMode) prepareArgs(args []interface{}) { args[i] = fmtOpTypeId(arg) case *Node: args[i] = (*fmtNodeTypeId)(arg) - case *Type: + case *types.Type: args[i] = (*fmtTypeTypeId)(arg) - case *Sym: + case *types.Sym: args[i] = (*fmtSymTypeId)(arg) case Nodes: args[i] = fmtNodesTypeId(arg) - case Val, int32, int64, string, EType: + case Val, int32, int64, string, types.EType: // OK: printing these types doesn't depend on mode default: Fatalf("mode.prepareArgs type %T", arg) @@ -390,13 +397,13 @@ func (m fmtMode) prepareArgs(args []interface{}) { args[i] = fmtOpTypeIdName(arg) case *Node: args[i] = (*fmtNodeTypeIdName)(arg) - case *Type: + case *types.Type: args[i] = (*fmtTypeTypeIdName)(arg) - case *Sym: + case *types.Sym: args[i] = (*fmtSymTypeIdName)(arg) case Nodes: args[i] = fmtNodesTypeIdName(arg) - case Val, int32, int64, string, EType: + case Val, int32, int64, string, types.EType: // OK: printing these types doesn't depend on mode default: Fatalf("mode.prepareArgs type %T", arg) @@ -606,53 +613,8 @@ s%.+% [T&] = "&",%g s%^ ........*\]%&~%g s%~ %%g */ -var etnames = []string{ - Txxx: "Txxx", - TINT: "INT", - TUINT: "UINT", - TINT8: "INT8", - TUINT8: "UINT8", - TINT16: "INT16", - TUINT16: "UINT16", - TINT32: "INT32", - TUINT32: "UINT32", - TINT64: "INT64", - TUINT64: "UINT64", - TUINTPTR: "UINTPTR", - TFLOAT32: "FLOAT32", - TFLOAT64: "FLOAT64", - TCOMPLEX64: "COMPLEX64", - TCOMPLEX128: "COMPLEX128", - TBOOL: "BOOL", - TPTR32: "PTR32", - TPTR64: "PTR64", - TFUNC: "FUNC", - TARRAY: "ARRAY", - TSLICE: "SLICE", - TSTRUCT: "STRUCT", - TCHAN: "CHAN", - TMAP: "MAP", - TINTER: "INTER", - TFORW: "FORW", - TSTRING: "STRING", - TUNSAFEPTR: "TUNSAFEPTR", - TANY: "ANY", - TIDEAL: "TIDEAL", - TNIL: "TNIL", - TBLANK: "TBLANK", - TFUNCARGS: "TFUNCARGS", - TCHANARGS: "TCHANARGS", - TDDDFIELD: "TDDDFIELD", -} - -func (et EType) String() string { - if int(et) < len(etnames) && etnames[et] != "" { - return etnames[et] - } - return fmt.Sprintf("E-%d", et) -} -func (s *Sym) symfmt(flag FmtFlag, mode fmtMode) string { +func symfmt(s *types.Sym, flag FmtFlag, mode fmtMode) string { if s.Pkg != nil && flag&FmtShort == 0 { switch mode { case FErr: // This is for the user @@ -719,38 +681,38 @@ var basicnames = []string{ TBLANK: "blank", } -func (t *Type) typefmt(flag FmtFlag, mode fmtMode, depth int) string { +func typefmt(t *types.Type, flag FmtFlag, mode fmtMode, depth int) string { if t == nil { return "" } - if t == bytetype || t == runetype { + if t == types.Bytetype || t == types.Runetype { // in %-T mode collapse rune and byte with their originals. switch mode { case FTypeIdName, FTypeId: - t = Types[t.Etype] + t = types.Types[t.Etype] default: - return t.Sym.sconv(FmtShort, mode) + return sconv(t.Sym, FmtShort, mode) } } - if t == errortype { + if t == types.Errortype { return "error" } // Unless the 'l' flag was specified, if the type has a name, just print that name. - if flag&FmtLong == 0 && t.Sym != nil && t != Types[t.Etype] { + if flag&FmtLong == 0 && t.Sym != nil && t != types.Types[t.Etype] { switch mode { case FTypeId, FTypeIdName: if flag&FmtShort != 0 { if t.Vargen != 0 { - return mode.Sprintf("%v·%d", t.Sym.sconv(FmtShort, mode), t.Vargen) + return mode.Sprintf("%v·%d", sconv(t.Sym, FmtShort, mode), t.Vargen) } - return t.Sym.sconv(FmtShort, mode) + return sconv(t.Sym, FmtShort, mode) } if mode == FTypeIdName { - return t.Sym.sconv(FmtUnsigned, mode) + return sconv(t.Sym, FmtUnsigned, mode) } if t.Sym.Pkg == localpkg && t.Vargen != 0 { @@ -758,19 +720,19 @@ func (t *Type) typefmt(flag FmtFlag, mode fmtMode, depth int) string { } } - return t.Sym.modeString(mode) + return smodeString(t.Sym, mode) } if int(t.Etype) < len(basicnames) && basicnames[t.Etype] != "" { prefix := "" - if mode == FErr && (t == idealbool || t == idealstring) { + if mode == FErr && (t == types.Idealbool || t == types.Idealstring) { prefix = "untyped " } return prefix + basicnames[t.Etype] } if mode == FDbg { - return t.Etype.String() + "-" + t.typefmt(flag, 0, depth) + return t.Etype.String() + "-" + typefmt(t, flag, 0, depth) } switch t.Etype { @@ -778,36 +740,36 @@ func (t *Type) typefmt(flag FmtFlag, mode fmtMode, depth int) string { switch mode { case FTypeId, FTypeIdName: if flag&FmtShort != 0 { - return "*" + t.Elem().tconv(FmtShort, mode, depth) + return "*" + tconv(t.Elem(), FmtShort, mode, depth) } } - return "*" + t.Elem().modeString(mode, depth) + return "*" + tmodeString(t.Elem(), mode, depth) case TARRAY: - if t.isDDDArray() { - return "[...]" + t.Elem().modeString(mode, depth) + if t.IsDDDArray() { + return "[...]" + tmodeString(t.Elem(), mode, depth) } - return "[" + strconv.FormatInt(t.NumElem(), 10) + "]" + t.Elem().modeString(mode, depth) + return "[" + strconv.FormatInt(t.NumElem(), 10) + "]" + tmodeString(t.Elem(), mode, depth) case TSLICE: - return "[]" + t.Elem().modeString(mode, depth) + return "[]" + tmodeString(t.Elem(), mode, depth) case TCHAN: switch t.ChanDir() { - case Crecv: - return "<-chan " + t.Elem().modeString(mode, depth) + case types.Crecv: + return "<-chan " + tmodeString(t.Elem(), mode, depth) - case Csend: - return "chan<- " + t.Elem().modeString(mode, depth) + case types.Csend: + return "chan<- " + tmodeString(t.Elem(), mode, depth) } - if t.Elem() != nil && t.Elem().IsChan() && t.Elem().Sym == nil && t.Elem().ChanDir() == Crecv { - return "chan (" + t.Elem().modeString(mode, depth) + ")" + if t.Elem() != nil && t.Elem().IsChan() && t.Elem().Sym == nil && t.Elem().ChanDir() == types.Crecv { + return "chan (" + tmodeString(t.Elem(), mode, depth) + ")" } - return "chan " + t.Elem().modeString(mode, depth) + return "chan " + tmodeString(t.Elem(), mode, depth) case TMAP: - return "map[" + t.Key().modeString(mode, depth) + "]" + t.Val().modeString(mode, depth) + return "map[" + tmodeString(t.Key(), mode, depth) + "]" + tmodeString(t.Val(), mode, depth) case TINTER: if t.IsEmptyInterface() { @@ -826,11 +788,11 @@ func (t *Type) typefmt(flag FmtFlag, mode fmtMode, depth int) string { // Wrong interface definitions may have types lacking a symbol. break case exportname(f.Sym.Name): - buf = append(buf, f.Sym.sconv(FmtShort, mode)...) + buf = append(buf, sconv(f.Sym, FmtShort, mode)...) default: - buf = append(buf, f.Sym.sconv(FmtUnsigned, mode)...) + buf = append(buf, sconv(f.Sym, FmtUnsigned, mode)...) } - buf = append(buf, f.Type.tconv(FmtShort, mode, depth)...) + buf = append(buf, tconv(f.Type, FmtShort, mode, depth)...) } if t.NumFields() != 0 { buf = append(buf, ' ') @@ -845,12 +807,12 @@ func (t *Type) typefmt(flag FmtFlag, mode fmtMode, depth int) string { } else { if t.Recv() != nil { buf = append(buf, "method"...) - buf = append(buf, t.Recvs().modeString(mode, depth)...) + buf = append(buf, tmodeString(t.Recvs(), mode, depth)...) buf = append(buf, ' ') } buf = append(buf, "func"...) } - buf = append(buf, t.Params().modeString(mode, depth)...) + buf = append(buf, tmodeString(t.Params(), mode, depth)...) switch t.Results().NumFields() { case 0: @@ -858,11 +820,11 @@ func (t *Type) typefmt(flag FmtFlag, mode fmtMode, depth int) string { case 1: buf = append(buf, ' ') - buf = append(buf, t.Results().Field(0).Type.modeString(mode, depth)...) // struct->field->field's type + buf = append(buf, tmodeString(t.Results().Field(0).Type, mode, depth)...) // struct->field->field's type default: buf = append(buf, ' ') - buf = append(buf, t.Results().modeString(mode, depth)...) + buf = append(buf, tmodeString(t.Results(), mode, depth)...) } return string(buf) @@ -872,15 +834,15 @@ func (t *Type) typefmt(flag FmtFlag, mode fmtMode, depth int) string { // Format the bucket struct for map[x]y as map.bucket[x]y. // This avoids a recursive print that generates very long names. if mt.Bucket == t { - return "map.bucket[" + m.Key().modeString(mode, depth) + "]" + m.Val().modeString(mode, depth) + return "map.bucket[" + tmodeString(m.Key(), mode, depth) + "]" + tmodeString(m.Val(), mode, depth) } if mt.Hmap == t { - return "map.hdr[" + m.Key().modeString(mode, depth) + "]" + m.Val().modeString(mode, depth) + return "map.hdr[" + tmodeString(m.Key(), mode, depth) + "]" + tmodeString(m.Val(), mode, depth) } if mt.Hiter == t { - return "map.iter[" + m.Key().modeString(mode, depth) + "]" + m.Val().modeString(mode, depth) + return "map.iter[" + tmodeString(m.Key(), mode, depth) + "]" + tmodeString(m.Val(), mode, depth) } Fatalf("unknown internal map type") @@ -920,7 +882,7 @@ func (t *Type) typefmt(flag FmtFlag, mode fmtMode, depth int) string { case TFORW: if t.Sym != nil { - return "undefined " + t.Sym.modeString(mode) + return "undefined " + smodeString(t.Sym, mode) } return "undefined" @@ -1296,7 +1258,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) { return } if n.Sym != nil { - fmt.Fprint(s, n.Sym.modeString(mode)) + fmt.Fprint(s, smodeString(n.Sym, mode)) return } } @@ -1304,10 +1266,10 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) { n.Orig.exprfmt(s, prec, mode) return } - if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != idealbool && n.Type != idealstring { + if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != types.Idealbool && n.Type != types.Idealstring { // Need parens when type begins with what might // be misinterpreted as a unary operator: * or <-. - if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == Crecv) { + if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == types.Crecv) { mode.Fprintf(s, "(%v)(%v)", n.Type, n.Val()) return } else { @@ -1327,11 +1289,11 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) { } fallthrough case OPACK, ONONAME: - fmt.Fprint(s, n.Sym.modeString(mode)) + fmt.Fprint(s, smodeString(n.Sym, mode)) case OTYPE: if n.Type == nil && n.Sym != nil { - fmt.Fprint(s, n.Sym.modeString(mode)) + fmt.Fprint(s, smodeString(n.Sym, mode)) return } mode.Fprintf(s, "%v", n.Type) @@ -1347,15 +1309,15 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) { mode.Fprintf(s, "map[%v]%v", n.Left, n.Right) case OTCHAN: - switch ChanDir(n.Etype) { - case Crecv: + switch types.ChanDir(n.Etype) { + case types.Crecv: mode.Fprintf(s, "<-chan %v", n.Left) - case Csend: + case types.Csend: mode.Fprintf(s, "chan<- %v", n.Left) default: - if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && ChanDir(n.Left.Etype) == Crecv { + if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && types.ChanDir(n.Left.Etype) == types.Crecv { mode.Fprintf(s, "chan (%v)", n.Left) } else { mode.Fprintf(s, "chan %v", n.Left) @@ -1717,21 +1679,20 @@ func (n *Node) nodedump(s fmt.State, flag FmtFlag, mode fmtMode) { } // "%S" suppresses qualifying with package -func (s *Sym) format(f fmt.State, verb rune, mode fmtMode) { +func symFormat(s *types.Sym, f fmt.State, verb rune, mode fmtMode) { switch verb { case 'v', 'S': - fmt.Fprint(f, s.sconv(fmtFlag(f, verb), mode)) + fmt.Fprint(f, sconv(s, fmtFlag(f, verb), mode)) default: - fmt.Fprintf(f, "%%!%c(*Sym=%p)", verb, s) + fmt.Fprintf(f, "%%!%c(*types.Sym=%p)", verb, s) } } -func (s *Sym) String() string { return s.sconv(0, FErr) } -func (s *Sym) modeString(mode fmtMode) string { return s.sconv(0, mode) } +func smodeString(s *types.Sym, mode fmtMode) string { return sconv(s, 0, mode) } // See #16897 before changing the implementation of sconv. -func (s *Sym) sconv(flag FmtFlag, mode fmtMode) string { +func sconv(s *types.Sym, flag FmtFlag, mode fmtMode) string { if flag&FmtLong != 0 { panic("linksymfmt") } @@ -1745,36 +1706,14 @@ func (s *Sym) sconv(flag FmtFlag, mode fmtMode) string { } flag, mode = flag.update(mode) - return s.symfmt(flag, mode) -} - -func (t *Type) String() string { - // This is an external entry point, so we pass depth 0 to tconv. - // The implementation of tconv (including typefmt and fldconv) - // must take care not to use a type in a formatting string - // to avoid resetting the recursion counter. - return t.tconv(0, FErr, 0) -} - -func (t *Type) modeString(mode fmtMode, depth int) string { - return t.tconv(0, mode, depth) -} - -// ShortString generates a short description of t. -// It is used in autogenerated method names, reflection, -// and itab names. -func (t *Type) ShortString() string { - return t.tconv(FmtLeft, FErr, 0) + return symfmt(s, flag, mode) } -// LongString generates a complete description of t. -// It is useful for reflection, -// or when a unique fingerprint or hash of a type is required. -func (t *Type) LongString() string { - return t.tconv(FmtLeft|FmtUnsigned, FErr, 0) +func tmodeString(t *types.Type, mode fmtMode, depth int) string { + return tconv(t, 0, mode, depth) } -func fldconv(f *Field, flag FmtFlag, mode fmtMode, depth int) string { +func fldconv(f *types.Field, flag FmtFlag, mode fmtMode, depth int) string { if f == nil { return "" } @@ -1790,9 +1729,9 @@ func fldconv(f *Field, flag FmtFlag, mode fmtMode, depth int) string { // Take the name from the original, lest we substituted it with ~r%d or ~b%d. // ~r%d is a (formerly) unnamed result. - if mode == FErr && f.Nname != nil { - if f.Nname.Orig != nil { - s = f.Nname.Orig.Sym + if mode == FErr && asNode(f.Nname) != nil { + if asNode(f.Nname).Orig != nil { + s = asNode(f.Nname).Orig.Sym if s != nil && s.Name[0] == '~' { if s.Name[1] == 'r' { // originally an unnamed result s = nil @@ -1806,24 +1745,24 @@ func fldconv(f *Field, flag FmtFlag, mode fmtMode, depth int) string { } if s != nil && f.Embedded == 0 { - if f.Funarg != FunargNone { - name = f.Nname.modeString(mode) + if f.Funarg != types.FunargNone { + name = asNode(f.Nname).modeString(mode) } else if flag&FmtLong != 0 { name = mode.Sprintf("%0S", s) if !exportname(name) && flag&FmtUnsigned == 0 { - name = s.modeString(mode) // qualify non-exported names (used on structs, not on funarg) + name = smodeString(s, mode) // qualify non-exported names (used on structs, not on funarg) } } else { - name = s.modeString(mode) + name = smodeString(s, mode) } } } var typ string if f.Isddd() { - typ = "..." + f.Type.Elem().modeString(mode, depth) + typ = "..." + tmodeString(f.Type.Elem(), mode, depth) } else { - typ = f.Type.modeString(mode, depth) + typ = tmodeString(f.Type, mode, depth) } str := typ @@ -1831,7 +1770,7 @@ func fldconv(f *Field, flag FmtFlag, mode fmtMode, depth int) string { str = name + " " + typ } - if flag&FmtShort == 0 && f.Funarg == FunargNone && f.Note != "" { + if flag&FmtShort == 0 && f.Funarg == types.FunargNone && f.Note != "" { str += " " + strconv.Quote(f.Note) } @@ -1840,12 +1779,12 @@ func fldconv(f *Field, flag FmtFlag, mode fmtMode, depth int) string { // "%L" print definition, not name // "%S" omit 'func' and receiver from function types, short type names -func (t *Type) format(s fmt.State, verb rune, mode fmtMode) { +func typeFormat(t *types.Type, s fmt.State, verb rune, mode fmtMode) { switch verb { case 'v', 'S', 'L': // This is an external entry point, so we pass depth 0 to tconv. // See comments in Type.String. - fmt.Fprint(s, t.tconv(fmtFlag(s, verb), mode, 0)) + fmt.Fprint(s, tconv(t, fmtFlag(s, verb), mode, 0)) default: fmt.Fprintf(s, "%%!%c(*Type=%p)", verb, t) @@ -1853,7 +1792,7 @@ func (t *Type) format(s fmt.State, verb rune, mode fmtMode) { } // See #16897 before changing the implementation of tconv. -func (t *Type) tconv(flag FmtFlag, mode fmtMode, depth int) string { +func tconv(t *types.Type, flag FmtFlag, mode fmtMode, depth int) string { if t == nil { return "" } @@ -1867,7 +1806,7 @@ func (t *Type) tconv(flag FmtFlag, mode fmtMode, depth int) string { flag |= FmtUnsigned } - str := t.typefmt(flag, mode, depth+1) + str := typefmt(t, flag, mode, depth+1) return str } diff --git a/src/cmd/compile/internal/gc/gen.go b/src/cmd/compile/internal/gc/gen.go index b0689b22ca..ef4c8537f3 100644 --- a/src/cmd/compile/internal/gc/gen.go +++ b/src/cmd/compile/internal/gc/gen.go @@ -7,6 +7,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/src" "fmt" @@ -114,7 +115,7 @@ func moveToHeap(n *Node) { // Allocate a local stack variable to hold the pointer to the heap copy. // temp will add it to the function declaration list automatically. - heapaddr := temp(typPtr(n.Type)) + heapaddr := temp(types.NewPtr(n.Type)) heapaddr.Sym = lookup("&" + n.Sym.Name) heapaddr.Orig.Sym = heapaddr.Sym @@ -191,11 +192,12 @@ func autotmpname(n int) string { // Start with a buffer big enough to hold a large n. b := []byte(prefix + " ")[:len(prefix)] b = strconv.AppendInt(b, int64(n), 10) - return internString(b) + _ = b + return types.InternString(b) } // make a new Node off the books -func tempnamel(pos src.XPos, curfn *Node, nn *Node, t *Type) { +func tempnamel(pos src.XPos, curfn *Node, nn *Node, t *types.Type) { if curfn == nil { Fatalf("no curfn for tempname") } @@ -207,12 +209,12 @@ func tempnamel(pos src.XPos, curfn *Node, nn *Node, t *Type) { Fatalf("tempname called with nil type") } - s := &Sym{ + s := &types.Sym{ Name: autotmpname(len(curfn.Func.Dcl)), Pkg: localpkg, } n := newnamel(pos, s) - s.Def = n + s.Def = asTypesNode(n) n.Type = t n.Class = PAUTO n.Esc = EscNever @@ -224,16 +226,16 @@ func tempnamel(pos src.XPos, curfn *Node, nn *Node, t *Type) { *nn = *n } -func temp(t *Type) *Node { +func temp(t *types.Type) *Node { var n Node tempnamel(lineno, Curfn, &n, t) - n.Sym.Def.SetUsed(true) + asNode(n.Sym.Def).SetUsed(true) return n.Orig } -func tempAt(pos src.XPos, curfn *Node, t *Type) *Node { +func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node { var n Node tempnamel(pos, curfn, &n, t) - n.Sym.Def.SetUsed(true) + asNode(n.Sym.Def).SetUsed(true) return n.Orig } diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go index c98001239e..272b6c5b2c 100644 --- a/src/cmd/compile/internal/gc/go.go +++ b/src/cmd/compile/internal/gc/go.go @@ -6,90 +6,25 @@ package gc import ( "cmd/compile/internal/ssa" + "cmd/compile/internal/types" "cmd/internal/bio" "cmd/internal/obj" "cmd/internal/src" ) const ( - BADWIDTH = -1000000000 + BADWIDTH = types.BADWIDTH MaxStackVarSize = 10 * 1024 * 1024 ) -type Pkg struct { - Name string // package name, e.g. "sys" - Path string // string literal used in import statement, e.g. "runtime/internal/sys" - Pathsym *obj.LSym - Prefix string // escaped path for use in symbol table - Imported bool // export data of this package was parsed - Direct bool // imported directly - Syms map[string]*Sym -} - -// isRuntime reports whether p is package runtime. -func (p *Pkg) isRuntime() bool { +// isRuntimePkg reports whether p is package runtime. +func isRuntimePkg(p *types.Pkg) bool { if compiling_runtime && p == localpkg { return true } return p.Path == "runtime" } -// Sym represents an object name. Most commonly, this is a Go identifier naming -// an object declared within a package, but Syms are also used to name internal -// synthesized objects. -// -// As an exception, field and method names that are exported use the Sym -// associated with localpkg instead of the package that declared them. This -// allows using Sym pointer equality to test for Go identifier uniqueness when -// handling selector expressions. -type Sym struct { - Link *Sym - Importdef *Pkg // where imported definition was found - Linkname string // link name - - // saved and restored by dcopy - Pkg *Pkg - Name string // object name - Def *Node // definition: ONAME OTYPE OPACK or OLITERAL - Lastlineno src.XPos // last declaration for diagnostic - Block int32 // blocknumber to catch redeclaration - - flags bitset8 - Label *Node // corresponding label (ephemeral) - Origpkg *Pkg // original package for . import - Lsym *obj.LSym -} - -const ( - symExport = 1 << iota // added to exportlist (no need to add again) - symPackage - symExported // already written out by export - symUniq - symSiggen - symAsm - symAlgGen -) - -func (sym *Sym) Export() bool { return sym.flags&symExport != 0 } -func (sym *Sym) Package() bool { return sym.flags&symPackage != 0 } -func (sym *Sym) Exported() bool { return sym.flags&symExported != 0 } -func (sym *Sym) Uniq() bool { return sym.flags&symUniq != 0 } -func (sym *Sym) Siggen() bool { return sym.flags&symSiggen != 0 } -func (sym *Sym) Asm() bool { return sym.flags&symAsm != 0 } -func (sym *Sym) AlgGen() bool { return sym.flags&symAlgGen != 0 } - -func (sym *Sym) SetExport(b bool) { sym.flags.set(symExport, b) } -func (sym *Sym) SetPackage(b bool) { sym.flags.set(symPackage, b) } -func (sym *Sym) SetExported(b bool) { sym.flags.set(symExported, b) } -func (sym *Sym) SetUniq(b bool) { sym.flags.set(symUniq, b) } -func (sym *Sym) SetSiggen(b bool) { sym.flags.set(symSiggen, b) } -func (sym *Sym) SetAsm(b bool) { sym.flags.set(symAsm, b) } -func (sym *Sym) SetAlgGen(b bool) { sym.flags.set(symAlgGen, b) } - -func (sym *Sym) isAlias() bool { - return sym.Def != nil && sym.Def.Sym != sym -} - // The Class of a variable/function describes the "storage class" // of a variable or function. During parsing, storage classes are // called declaration contexts. @@ -165,38 +100,36 @@ var debugstr string var Debug_checknil int var Debug_typeassert int -var localpkg *Pkg // package being compiled +var localpkg *types.Pkg // package being compiled var inimport bool // set during import -var itabpkg *Pkg // fake pkg for itab entries +var itabpkg *types.Pkg // fake pkg for itab entries -var itablinkpkg *Pkg // fake package for runtime itab entries +var itablinkpkg *types.Pkg // fake package for runtime itab entries -var Runtimepkg *Pkg // fake package runtime +var Runtimepkg *types.Pkg // fake package runtime -var racepkg *Pkg // package runtime/race +var racepkg *types.Pkg // package runtime/race -var msanpkg *Pkg // package runtime/msan +var msanpkg *types.Pkg // package runtime/msan -var typepkg *Pkg // fake package for runtime type info (headers) +var typepkg *types.Pkg // fake package for runtime type info (headers) -var unsafepkg *Pkg // package unsafe +var unsafepkg *types.Pkg // package unsafe -var trackpkg *Pkg // fake package for field tracking +var trackpkg *types.Pkg // fake package for field tracking -var mappkg *Pkg // fake package for map zero value +var mappkg *types.Pkg // fake package for map zero value var zerosize int64 -var Tptr EType // either TPTR32 or TPTR64 - var myimportpath string var localimport string var asmhdr string -var simtype [NTYPE]EType +var simtype [NTYPE]types.EType var ( isforw [NTYPE]bool @@ -238,7 +171,7 @@ var exportlist []*Node var importlist []*Node // imported functions and methods with inlinable bodies -var funcsyms []*Sym +var funcsyms []*types.Sym var dclcontext Class // PEXTERN/PAUTO diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go index b3ef556029..b22828f2e5 100644 --- a/src/cmd/compile/internal/gc/gsubr.go +++ b/src/cmd/compile/internal/gc/gsubr.go @@ -31,6 +31,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/src" ) @@ -194,13 +195,13 @@ func ggloblnod(nam *Node) { if nam.Name.Readonly() { flags = obj.RODATA } - if nam.Type != nil && !haspointers(nam.Type) { + if nam.Type != nil && !types.Haspointers(nam.Type) { flags |= obj.NOPTR } Ctxt.Globl(s, nam.Type.Width, flags) } -func ggloblsym(s *Sym, width int32, flags int16) { +func ggloblsym(s *types.Sym, width int32, flags int16) { ggloblLSym(Linksym(s), width, flags) } @@ -212,7 +213,7 @@ func ggloblLSym(s *obj.LSym, width int32, flags int16) { Ctxt.Globl(s, int64(width), int(flags)) } -func isfat(t *Type) bool { +func isfat(t *types.Type) bool { if t != nil { switch t.Etype { case TSTRUCT, TARRAY, TSLICE, TSTRING, @@ -231,8 +232,8 @@ func Addrconst(a *obj.Addr, v int64) { } // nodarg returns a Node for the function argument denoted by t, -// which is either the entire function argument or result struct (t is a struct *Type) -// or a specific argument (t is a *Field within a struct *Type). +// which is either the entire function argument or result struct (t is a struct *types.Type) +// or a specific argument (t is a *types.Field within a struct *types.Type). // // If fp is 0, the node is for use by a caller invoking the given // function, preparing the arguments before the call @@ -247,12 +248,12 @@ func Addrconst(a *obj.Addr, v int64) { func nodarg(t interface{}, fp int) *Node { var n *Node - var funarg Funarg + var funarg types.Funarg switch t := t.(type) { default: Fatalf("bad nodarg %T(%v)", t, t) - case *Type: + case *types.Type: // Entire argument struct, not just one arg if !t.IsFuncArgStruct() { Fatalf("nodarg: bad type %v", t) @@ -271,7 +272,7 @@ func nodarg(t interface{}, fp int) *Node { } n.Xoffset = first.Offset - case *Field: + case *types.Field: funarg = t.Funarg if fp == 1 { // NOTE(rsc): This should be using t.Nname directly, @@ -285,7 +286,7 @@ func nodarg(t interface{}, fp int) *Node { // toward time for the Go 1.7 beta). // At some quieter time (assuming we've never seen these Fatalfs happen) // we could change this code to use "expect" directly. - expect := t.Nname + expect := asNode(t.Nname) if expect.isParamHeapCopy() { expect = expect.Name.Param.Stackcopy } @@ -293,7 +294,7 @@ func nodarg(t interface{}, fp int) *Node { for _, n := range Curfn.Func.Dcl { if (n.Class == PPARAM || n.Class == PPARAMOUT) && !isblanksym(t.Sym) && n.Sym == t.Sym { if n != expect { - Fatalf("nodarg: unexpected node: %v (%p %v) vs %v (%p %v)", n, n, n.Op, t.Nname, t.Nname, t.Nname.Op) + Fatalf("nodarg: unexpected node: %v (%p %v) vs %v (%p %v)", n, n, n.Op, asNode(t.Nname), asNode(t.Nname), asNode(t.Nname).Op) } return n } @@ -313,7 +314,7 @@ func nodarg(t interface{}, fp int) *Node { Fatalf("nodarg: offset not computed for %v", t) } n.Xoffset = t.Offset - n.Orig = t.Nname + n.Orig = asNode(t.Nname) } // Rewrite argument named _ to __, @@ -333,7 +334,7 @@ func nodarg(t interface{}, fp int) *Node { case 1: // reading arguments inside call n.Class = PPARAM - if funarg == FunargResults { + if funarg == types.FunargResults { n.Class = PPARAMOUT } } diff --git a/src/cmd/compile/internal/gc/init.go b/src/cmd/compile/internal/gc/init.go index 7ce8383dbc..e26718dfdc 100644 --- a/src/cmd/compile/internal/gc/init.go +++ b/src/cmd/compile/internal/gc/init.go @@ -4,6 +4,8 @@ package gc +import "cmd/compile/internal/types" + // a function named init is a special case. // it is called by the initialization before // main is run. to make it unique within a @@ -12,7 +14,7 @@ package gc var renameinit_initgen int -func renameinit() *Sym { +func renameinit() *types.Sym { renameinit_initgen++ return lookupN("init.", renameinit_initgen) } @@ -42,7 +44,7 @@ func anyinit(n []*Node) bool { } // are there any imported init functions - for _, s := range initSyms { + for _, s := range types.InitSyms { if s.Def != nil { return true } @@ -81,7 +83,7 @@ func fninit(n []*Node) { // (1) gatevar := newname(lookup("initdone·")) - addvar(gatevar, Types[TUINT8], PEXTERN) + addvar(gatevar, types.Types[TUINT8], PEXTERN) // (2) fn := nod(ODCLFUNC, nil, nil) @@ -116,10 +118,10 @@ func fninit(n []*Node) { r = append(r, a) // (6) - for _, s := range initSyms { + for _, s := range types.InitSyms { if s.Def != nil && s != initsym { // could check that it is fn of no args/returns - a = nod(OCALL, s.Def, nil) + a = nod(OCALL, asNode(s.Def), nil) r = append(r, a) } } @@ -134,7 +136,7 @@ func fninit(n []*Node) { if s.Def == nil { break } - a = nod(OCALL, s.Def, nil) + a = nod(OCALL, asNode(s.Def), nil) r = append(r, a) } diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index 5faf494876..7478ee2c7d 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -28,13 +28,14 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/src" "fmt" ) // Get the function's package. For ordinary functions it's on the ->sym, but for imported methods // the ->sym can be re-used in the local package, so peel it off the receiver's type. -func fnpkg(fn *Node) *Pkg { +func fnpkg(fn *Node) *types.Pkg { if fn.IsMethod() { // method rcvr := fn.Type.Recv().Type @@ -171,7 +172,7 @@ func caninl(fn *Node) { // hack, TODO, check for better way to link method nodes back to the thing with the ->inl // this is so export can find the body of a method - fn.Type.SetNname(n) + fn.Type.FuncType().Nname = asTypesNode(n) if Debug['m'] > 1 { fmt.Printf("%v: can inline %#v as: %#v { %#v }\n", fn.Line(), n, fn.Type, n.Func.Inl) @@ -210,7 +211,7 @@ func ishairy(n *Node, budget *int32, reason *string) bool { } if n.isMethodCalledAsFunction() { - if d := n.Left.Sym.Def; d != nil && d.Func.Inl.Len() != 0 { + if d := asNode(n.Left.Sym.Def); d != nil && d.Func.Inl.Len() != 0 { *budget -= d.Func.InlCost break } @@ -229,7 +230,7 @@ func ishairy(n *Node, budget *int32, reason *string) bool { if t.Nname() == nil { Fatalf("no function definition for [%p] %+v\n", t, t) } - if inlfn := t.Nname().Func; inlfn.Inl.Len() != 0 { + if inlfn := asNode(t.FuncType().Nname).Func; inlfn.Inl.Len() != 0 { *budget -= inlfn.InlCost break } @@ -507,8 +508,8 @@ func inlnode(n *Node) *Node { } if n.Left.Func != nil && n.Left.Func.Inl.Len() != 0 && !isIntrinsicCall(n) { // normal case n = mkinlcall(n, n.Left, n.Isddd()) - } else if n.isMethodCalledAsFunction() && n.Left.Sym.Def != nil { - n = mkinlcall(n, n.Left.Sym.Def, n.Isddd()) + } else if n.isMethodCalledAsFunction() && asNode(n.Left.Sym.Def) != nil { + n = mkinlcall(n, asNode(n.Left.Sym.Def), n.Isddd()) } case OCALLMETH: @@ -525,7 +526,7 @@ func inlnode(n *Node) *Node { Fatalf("no function definition for [%p] %+v\n", n.Left.Type, n.Left.Type) } - n = mkinlcall(n, n.Left.Type.Nname(), n.Isddd()) + n = mkinlcall(n, asNode(n.Left.Type.FuncType().Nname), n.Isddd()) } lineno = lno @@ -549,11 +550,11 @@ func mkinlcall(n *Node, fn *Node, isddd bool) *Node { return n } -func tinlvar(t *Field, inlvars map[*Node]*Node) *Node { - if t.Nname != nil && !isblank(t.Nname) { - inlvar := inlvars[t.Nname] +func tinlvar(t *types.Field, inlvars map[*Node]*Node) *Node { + if asNode(t.Nname) != nil && !isblank(asNode(t.Nname)) { + inlvar := inlvars[asNode(t.Nname)] if inlvar == nil { - Fatalf("missing inlvar for %v\n", t.Nname) + Fatalf("missing inlvar for %v\n", asNode(t.Nname)) } return inlvar } @@ -631,10 +632,10 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { // temporaries for return values. var m *Node for _, t := range fn.Type.Results().Fields().Slice() { - if t != nil && t.Nname != nil && !isblank(t.Nname) { - m = inlvar(t.Nname) + if t != nil && asNode(t.Nname) != nil && !isblank(asNode(t.Nname)) { + m = inlvar(asNode(t.Nname)) m = typecheck(m, Erv) - inlvars[t.Nname] = m + inlvars[asNode(t.Nname)] = m } else { // anonymous return values, synthesize names for use in assignment that replaces return m = retvar(t, i) @@ -650,8 +651,8 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { // method call with a receiver. t := fn.Type.Recv() - if t != nil && t.Nname != nil && !isblank(t.Nname) && inlvars[t.Nname] == nil { - Fatalf("missing inlvar for %v\n", t.Nname) + if t != nil && t.Nname != nil && !isblank(asNode(t.Nname)) && inlvars[asNode(t.Nname)] == nil { + Fatalf("missing inlvar for %v\n", asNode(t.Nname)) } if n.Left.Left == nil { Fatalf("method call without receiver: %+v", n) @@ -669,7 +670,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { // check if inlined function is variadic. variadic := false - var varargtype *Type + var varargtype *types.Type varargcount := 0 for _, t := range fn.Type.Params().Fields().Slice() { if t.Isddd() { @@ -719,8 +720,8 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { // append receiver inlvar to LHS. t := fn.Type.Recv() - if t != nil && t.Nname != nil && !isblank(t.Nname) && inlvars[t.Nname] == nil { - Fatalf("missing inlvar for %v\n", t.Nname) + if t != nil && t.Nname != nil && !isblank(asNode(t.Nname)) && inlvars[asNode(t.Nname)] == nil { + Fatalf("missing inlvar for %v\n", asNode(t.Nname)) } if t == nil { Fatalf("method call unknown receiver type: %+v", n) @@ -753,7 +754,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { } } else { // match arguments except final variadic (unless the call is dotted itself) - t, it := iterFields(fn.Type.Params()) + t, it := types.IterFields(fn.Type.Params()) for t != nil { if li >= n.List.Len() { break @@ -799,7 +800,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { as.Right = nodnil() as.Right.Type = varargtype } else { - varslicetype := typSlice(varargtype.Elem()) + varslicetype := types.NewSlice(varargtype.Elem()) as.Right = nod(OCOMPLIT, nil, typenod(varslicetype)) as.Right.List.Set(varargs) } @@ -911,7 +912,7 @@ func inlvar(var_ *Node) *Node { } // Synthesize a variable to store the inlined function's results in. -func retvar(t *Field, i int) *Node { +func retvar(t *types.Field, i int) *Node { n := newname(lookupN("~r", i)) n.Type = t.Type n.Class = PAUTO @@ -923,7 +924,7 @@ func retvar(t *Field, i int) *Node { // Synthesize a variable to store the inlined function's arguments // when they come from a multiple return call. -func argvar(t *Type, i int) *Node { +func argvar(t *types.Type, i int) *Node { n := newname(lookupN("~arg", i)) n.Type = t.Elem() n.Class = PAUTO diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go index 7bd534d71d..7d68431dc0 100644 --- a/src/cmd/compile/internal/gc/lex.go +++ b/src/cmd/compile/internal/gc/lex.go @@ -104,17 +104,6 @@ func pragmaValue(verb string) syntax.Pragma { return 0 } -var internedStrings = map[string]string{} - -func internString(b []byte) string { - s, ok := internedStrings[string(b)] // string(b) here doesn't allocate - if !ok { - s = string(b) - internedStrings[s] = s - } - return s -} - // pragcgo is called concurrently if files are parsed concurrently. func (p *noder) pragcgo(pos src.Pos, text string) string { f := pragmaFields(text) diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index e850bef2b6..d6872126f1 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -10,6 +10,7 @@ import ( "bufio" "bytes" "cmd/compile/internal/ssa" + "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/src" "cmd/internal/sys" @@ -347,6 +348,35 @@ func Main(archInit func(*Arch)) { Widthptr = thearch.LinkArch.PtrSize Widthreg = thearch.LinkArch.RegSize + // initialize types package + // (we need to do this to break dependencies that otherwise + // would lead to import cycles) + types.Widthptr = Widthptr + types.Dowidth = dowidth + types.Fatalf = Fatalf + types.Sconv = func(s *types.Sym, flag, mode int) string { + return sconv(s, FmtFlag(flag), fmtMode(mode)) + } + types.Tconv = func(t *types.Type, flag, mode, depth int) string { + return tconv(t, FmtFlag(flag), fmtMode(mode), depth) + } + types.FormatSym = func(sym *types.Sym, s fmt.State, verb rune, mode int) { + symFormat(sym, s, verb, fmtMode(mode)) + } + types.FormatType = func(t *types.Type, s fmt.State, verb rune, mode int) { + typeFormat(t, s, verb, fmtMode(mode)) + } + types.Cmptyp = cmptyp + types.FieldName = func(f *types.Field) string { + return f.Sym.Name + } + types.TypeLinkSym = func(t *types.Type) *obj.LSym { + return Linksym(typenamesym(t)) + } + types.FmtLeft = int(FmtLeft) + types.FmtUnsigned = int(FmtUnsigned) + types.FErr = FErr + initUniverse() blockgen = 1 @@ -752,7 +782,7 @@ func loadsys() { inimport = false } -func importfile(f *Val) *Pkg { +func importfile(f *Val) *types.Pkg { path_, ok := f.U.(string) if !ok { yyerror("import path must be a string") @@ -964,28 +994,28 @@ func mkpackage(pkgname string) { func clearImports() { for _, s := range localpkg.Syms { - if s.Def == nil { + if asNode(s.Def) == nil { continue } - if s.Def.Op == OPACK { + if asNode(s.Def).Op == OPACK { // throw away top-level package name leftover // from previous file. // leave s->block set to cause redeclaration // errors if a conflicting top-level name is // introduced by a different file. - if !s.Def.Used() && nsyntaxerrors == 0 { - pkgnotused(s.Def.Pos, s.Def.Name.Pkg.Path, s.Name) + if !asNode(s.Def).Used() && nsyntaxerrors == 0 { + pkgnotused(asNode(s.Def).Pos, asNode(s.Def).Name.Pkg.Path, s.Name) } s.Def = nil continue } - if s.isAlias() { + if IsAlias(s) { // throw away top-level name left over // from previous import . "x" - if s.Def.Name != nil && s.Def.Name.Pack != nil && !s.Def.Name.Pack.Used() && nsyntaxerrors == 0 { - pkgnotused(s.Def.Name.Pack.Pos, s.Def.Name.Pack.Name.Pkg.Path, "") - s.Def.Name.Pack.SetUsed(true) + if asNode(s.Def).Name != nil && asNode(s.Def).Name.Pack != nil && !asNode(s.Def).Name.Pack.Used() && nsyntaxerrors == 0 { + pkgnotused(asNode(s.Def).Name.Pack.Pos, asNode(s.Def).Name.Pack.Name.Pkg.Path, "") + asNode(s.Def).Name.Pack.SetUsed(true) } s.Def = nil @@ -993,3 +1023,7 @@ func clearImports() { } } } + +func IsAlias(sym *types.Sym) bool { + return sym.Def != nil && asNode(sym.Def).Sym != sym +} diff --git a/src/cmd/compile/internal/gc/mkbuiltin.go b/src/cmd/compile/internal/gc/mkbuiltin.go index 38fb5f700c..63d2a12c07 100644 --- a/src/cmd/compile/internal/gc/mkbuiltin.go +++ b/src/cmd/compile/internal/gc/mkbuiltin.go @@ -34,6 +34,8 @@ func main() { fmt.Fprintln(&b, "// Code generated by mkbuiltin.go. DO NOT EDIT.") fmt.Fprintln(&b) fmt.Fprintln(&b, "package gc") + fmt.Fprintln(&b) + fmt.Fprintln(&b, `import "cmd/compile/internal/types"`) mkbuiltin(&b, "runtime") @@ -98,8 +100,8 @@ func mkbuiltin(w io.Writer, name string) { fmt.Fprintln(w, "}") fmt.Fprintln(w) - fmt.Fprintf(w, "func %sTypes() []*Type {\n", name) - fmt.Fprintf(w, "var typs [%d]*Type\n", len(interner.typs)) + fmt.Fprintf(w, "func %sTypes() []*types.Type {\n", name) + fmt.Fprintf(w, "var typs [%d]*types.Type\n", len(interner.typs)) for i, typ := range interner.typs { fmt.Fprintf(w, "typs[%d] = %s\n", i, typ) } @@ -138,42 +140,42 @@ func (i *typeInterner) mktype(t ast.Expr) string { case *ast.Ident: switch t.Name { case "byte": - return "bytetype" + return "types.Bytetype" case "rune": - return "runetype" + return "types.Runetype" } - return fmt.Sprintf("Types[T%s]", strings.ToUpper(t.Name)) + return fmt.Sprintf("types.Types[T%s]", strings.ToUpper(t.Name)) case *ast.SelectorExpr: if t.X.(*ast.Ident).Name != "unsafe" || t.Sel.Name != "Pointer" { log.Fatalf("unhandled type: %#v", t) } - return "Types[TUNSAFEPTR]" + return "types.Types[TUNSAFEPTR]" case *ast.ArrayType: if t.Len == nil { - return fmt.Sprintf("typSlice(%s)", i.subtype(t.Elt)) + return fmt.Sprintf("types.NewSlice(%s)", i.subtype(t.Elt)) } - return fmt.Sprintf("typArray(%s, %d)", i.subtype(t.Elt), intconst(t.Len)) + return fmt.Sprintf("types.NewArray(%s, %d)", i.subtype(t.Elt), intconst(t.Len)) case *ast.ChanType: - dir := "Cboth" + dir := "types.Cboth" switch t.Dir { case ast.SEND: - dir = "Csend" + dir = "types.Csend" case ast.RECV: - dir = "Crecv" + dir = "types.Crecv" } - return fmt.Sprintf("typChan(%s, %s)", i.subtype(t.Value), dir) + return fmt.Sprintf("types.NewChan(%s, %s)", i.subtype(t.Value), dir) case *ast.FuncType: return fmt.Sprintf("functype(nil, %s, %s)", i.fields(t.Params, false), i.fields(t.Results, false)) case *ast.InterfaceType: if len(t.Methods.List) != 0 { log.Fatal("non-empty interfaces unsupported") } - return "Types[TINTER]" + return "types.Types[TINTER]" case *ast.MapType: - return fmt.Sprintf("typMap(%s, %s)", i.subtype(t.Key), i.subtype(t.Value)) + return fmt.Sprintf("types.NewMap(%s, %s)", i.subtype(t.Key), i.subtype(t.Value)) case *ast.StarExpr: - return fmt.Sprintf("typPtr(%s)", i.subtype(t.X)) + return fmt.Sprintf("types.NewPtr(%s)", i.subtype(t.X)) case *ast.StructType: return fmt.Sprintf("tostruct(%s)", i.fields(t.Fields, true)) diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index cb22d7608a..bd769b6126 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -12,6 +12,7 @@ import ( "unicode/utf8" "cmd/compile/internal/syntax" + "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/src" ) @@ -147,7 +148,7 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) { ipkg.Direct = true - var my *Sym + var my *types.Sym if imp.LocalPkgName != nil { my = p.name(imp.LocalPkgName) } else { @@ -173,7 +174,7 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) { lineno = pack.Pos redeclare(my, "as imported package name") } - my.Def = pack + my.Def = asTypesNode(pack) my.Lastlineno = pack.Pos my.Block = 1 // at top level } @@ -521,7 +522,7 @@ func (p *noder) expr(expr syntax.Expr) *Node { return p.nod(expr, OTMAP, p.typeExpr(expr.Key), p.typeExpr(expr.Value)) case *syntax.ChanType: n := p.nod(expr, OTCHAN, p.typeExpr(expr.Elem), nil) - n.Etype = EType(p.chanDir(expr.Dir)) + n.Etype = types.EType(p.chanDir(expr.Dir)) return n case *syntax.TypeSwitchGuard: @@ -549,14 +550,14 @@ func (p *noder) typeExprOrNil(typ syntax.Expr) *Node { return nil } -func (p *noder) chanDir(dir syntax.ChanDir) ChanDir { +func (p *noder) chanDir(dir syntax.ChanDir) types.ChanDir { switch dir { case 0: - return Cboth + return types.Cboth case syntax.SendOnly: - return Csend + return types.Csend case syntax.RecvOnly: - return Crecv + return types.Crecv } panic("unhandled ChanDir") } @@ -605,7 +606,7 @@ func (p *noder) interfaceType(expr *syntax.InterfaceType) *Node { return n } -func (p *noder) packname(expr syntax.Expr) *Sym { +func (p *noder) packname(expr syntax.Expr) *types.Sym { switch expr := expr.(type) { case *syntax.Name: name := p.name(expr) @@ -615,13 +616,13 @@ func (p *noder) packname(expr syntax.Expr) *Sym { return name case *syntax.SelectorExpr: name := p.name(expr.X.(*syntax.Name)) - var pkg *Pkg - if name.Def == nil || name.Def.Op != OPACK { + var pkg *types.Pkg + if asNode(name.Def) == nil || asNode(name.Def).Op != OPACK { yyerror("%v is not a package", name) pkg = localpkg } else { - name.Def.SetUsed(true) - pkg = name.Def.Name.Pkg + asNode(name.Def).SetUsed(true) + pkg = asNode(name.Def).Name.Pkg } return restrictlookup(expr.Sel.Value, pkg) } @@ -681,7 +682,7 @@ func (p *noder) stmt(stmt syntax.Stmt) *Node { if stmt.Op != 0 && stmt.Op != syntax.Def { n := p.nod(stmt, OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs)) n.SetImplicit(stmt.Rhs == syntax.ImplicitOne) - n.Etype = EType(p.binOp(stmt.Op)) + n.Etype = types.EType(p.binOp(stmt.Op)) return n } @@ -757,7 +758,7 @@ func (p *noder) stmt(stmt syntax.Stmt) *Node { if ln.Class != PPARAMOUT { break } - if ln.Sym.Def != ln { + if asNode(ln.Sym.Def) != ln { yyerror("%s is shadowed during return", ln.Sym.Name) } } @@ -1030,7 +1031,7 @@ func (p *noder) basicLit(lit *syntax.BasicLit) Val { } } -func (p *noder) name(name *syntax.Name) *Sym { +func (p *noder) name(name *syntax.Name) *types.Sym { return lookup(name.Value) } @@ -1125,7 +1126,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma { return 0 } -func mkname(sym *Sym) *Node { +func mkname(sym *types.Sym) *Node { n := oldname(sym) if n.Name != nil && n.Name.Pack != nil { n.Name.Pack.SetUsed(true) diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go index 1971fb7d16..ef5ce3191e 100644 --- a/src/cmd/compile/internal/gc/obj.go +++ b/src/cmd/compile/internal/gc/obj.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/bio" "cmd/internal/obj" "crypto/sha256" @@ -173,7 +174,7 @@ func dumpptabs() { } for _, exportn := range exportlist { s := exportn.Sym - n := s.Def + n := asNode(s.Def) if n == nil { continue } @@ -188,10 +189,10 @@ func dumpptabs() { } if n.Type.Etype == TFUNC && n.Class == PFUNC { // function - ptabs = append(ptabs, ptabEntry{s: s, t: s.Def.Type}) + ptabs = append(ptabs, ptabEntry{s: s, t: asNode(s.Def).Type}) } else { // variable - ptabs = append(ptabs, ptabEntry{s: s, t: typPtr(s.Def.Type)}) + ptabs = append(ptabs, ptabEntry{s: s, t: types.NewPtr(asNode(s.Def).Type)}) } } } @@ -217,7 +218,7 @@ func dumpglobls() { } for _, s := range funcsyms { - sf := s.Pkg.Lookup(s.funcsymname()) + sf := s.Pkg.Lookup(funcsymname(s)) dsymptr(sf, 0, s, 0) ggloblsym(sf, int32(Widthptr), obj.DUPOK|obj.RODATA) } @@ -226,7 +227,7 @@ func dumpglobls() { funcsyms = nil } -func Linksym(s *Sym) *obj.LSym { +func Linksym(s *types.Sym) *obj.LSym { if s == nil { return nil } @@ -247,7 +248,7 @@ func Linksym(s *Sym) *obj.LSym { return ls } -func duintxx(s *Sym, off int, v uint64, wid int) int { +func duintxx(s *types.Sym, off int, v uint64, wid int) int { return duintxxLSym(Linksym(s), off, v, wid) } @@ -260,23 +261,23 @@ func duintxxLSym(s *obj.LSym, off int, v uint64, wid int) int { return int(obj.Setuintxx(Ctxt, s, int64(off), v, int64(wid))) } -func duint8(s *Sym, off int, v uint8) int { +func duint8(s *types.Sym, off int, v uint8) int { return duintxx(s, off, uint64(v), 1) } -func duint16(s *Sym, off int, v uint16) int { +func duint16(s *types.Sym, off int, v uint16) int { return duintxx(s, off, uint64(v), 2) } -func duint32(s *Sym, off int, v uint32) int { +func duint32(s *types.Sym, off int, v uint32) int { return duintxx(s, off, uint64(v), 4) } -func duintptr(s *Sym, off int, v uint64) int { +func duintptr(s *types.Sym, off int, v uint64) int { return duintxx(s, off, v, Widthptr) } -func dbvec(s *Sym, off int, bv bvec) int { +func dbvec(s *types.Sym, off int, bv bvec) int { // Runtime reads the bitmaps as byte arrays. Oblige. for j := 0; int32(j) < bv.n; j += 8 { word := bv.b[j/32] @@ -319,7 +320,7 @@ func slicebytes(nam *Node, s string, len int) { slicebytes_gen++ symname := fmt.Sprintf(".gobytes.%d", slicebytes_gen) sym := localpkg.Lookup(symname) - sym.Def = newname(sym) + sym.Def = asTypesNode(newname(sym)) off := dsname(sym, 0, s) ggloblsym(sym, int32(off), obj.NOPTR|obj.LOCAL) @@ -333,7 +334,7 @@ func slicebytes(nam *Node, s string, len int) { duintxx(nam.Sym, off, uint64(len), Widthint) } -func dsname(s *Sym, off int, t string) int { +func dsname(s *types.Sym, off int, t string) int { return dsnameLSym(Linksym(s), off, t) } @@ -342,7 +343,7 @@ func dsnameLSym(s *obj.LSym, off int, t string) int { return off + len(t) } -func dsymptr(s *Sym, off int, x *Sym, xoff int) int { +func dsymptr(s *types.Sym, off int, x *types.Sym, xoff int) int { return dsymptrLSym(Linksym(s), off, Linksym(x), xoff) } diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go index c3e6d59700..48bd25f7ea 100644 --- a/src/cmd/compile/internal/gc/order.go +++ b/src/cmd/compile/internal/gc/order.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/src" "fmt" ) @@ -59,7 +60,7 @@ func order(fn *Node) { // Ordertemp allocates a new temporary with the given type, // pushes it onto the temp stack, and returns it. // If clear is true, ordertemp emits code to zero the temporary. -func ordertemp(t *Type, order *Order, clear bool) *Node { +func ordertemp(t *types.Type, order *Order, clear bool) *Node { var_ := temp(t) if clear { a := nod(OAS, var_, nil) @@ -83,7 +84,7 @@ func ordertemp(t *Type, order *Order, clear bool) *Node { // (The other candidate would be map access, but map access // returns a pointer to the result data instead of taking a pointer // to be filled in.) -func ordercopyexpr(n *Node, t *Type, order *Order, clear int) *Node { +func ordercopyexpr(n *Node, t *types.Type, order *Order, clear int) *Node { var_ := ordertemp(t, order, clear != 0) a := nod(OAS, var_, n) a = typecheck(a, Etop) @@ -208,7 +209,7 @@ func orderaddrtemp(n *Node, order *Order) *Node { // ordermapkeytemp prepares n to be a key in a map runtime call and returns n. // It should only be used for map runtime calls which have *_fast* versions. -func ordermapkeytemp(t *Type, n *Node, order *Order) *Node { +func ordermapkeytemp(t *types.Type, n *Node, order *Order) *Node { // Most map calls need to take the address of the key. // Exception: map*_fast* calls. See golang.org/issue/19015. if mapfast(t) == mapslow { @@ -595,8 +596,8 @@ func orderstmt(n *Node, order *Order) { orderexprlist(n.List, order) n.Rlist.First().Left = orderexpr(n.Rlist.First().Left, order, nil) // arg to recv ch := n.Rlist.First().Left.Type - tmp1 := ordertemp(ch.Elem(), order, haspointers(ch.Elem())) - tmp2 := ordertemp(Types[TBOOL], order, false) + tmp1 := ordertemp(ch.Elem(), order, types.Haspointers(ch.Elem())) + tmp2 := ordertemp(types.Types[TBOOL], order, false) order.out = append(order.out, n) r := nod(OAS, n.List.First(), tmp1) r = typecheck(r, Etop) @@ -745,9 +746,9 @@ func orderstmt(n *Node, order *Order) { // make copy. r := n.Right - if r.Type.IsString() && r.Type != Types[TSTRING] { + if r.Type.IsString() && r.Type != types.Types[TSTRING] { r = nod(OCONV, r, nil) - r.Type = Types[TSTRING] + r.Type = types.Types[TSTRING] r = typecheck(r, Erv) } @@ -761,7 +762,7 @@ func orderstmt(n *Node, order *Order) { n.Right = ordercopyexpr(r, r.Type, order, 0) // n->alloc is the temp for the iterator. - prealloc[n] = ordertemp(Types[TUINT8], order, true) + prealloc[n] = ordertemp(types.Types[TUINT8], order, true) } for i := range n.List.Slice() { n.List.SetIndex(i, orderexprinplace(n.List.Index(i), order)) @@ -862,7 +863,7 @@ func orderstmt(n *Node, order *Order) { n2.Ninit.Append(tmp2) } - r.Left = ordertemp(r.Right.Left.Type.Elem(), order, haspointers(r.Right.Left.Type.Elem())) + r.Left = ordertemp(r.Right.Left.Type.Elem(), order, types.Haspointers(r.Right.Left.Type.Elem())) tmp2 = nod(OAS, tmp1, r.Left) tmp2 = typecheck(tmp2, Etop) n2.Ninit.Append(tmp2) @@ -879,7 +880,7 @@ func orderstmt(n *Node, order *Order) { n2.Ninit.Append(tmp2) } - r.List.Set1(ordertemp(Types[TBOOL], order, false)) + r.List.Set1(ordertemp(types.Types[TBOOL], order, false)) tmp2 = okas(tmp1, r.List.First()) tmp2 = typecheck(tmp2, Etop) n2.Ninit.Append(tmp2) @@ -1012,7 +1013,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node { orderexprlist(n.List, order) if n.List.Len() > 5 { - t := typArray(Types[TSTRING], int64(n.List.Len())) + t := types.NewArray(types.Types[TSTRING], int64(n.List.Len())) prealloc[n] = ordertemp(t, order, false) } @@ -1165,7 +1166,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node { case OCLOSURE: if n.Noescape() && n.Func.Cvars.Len() > 0 { - prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type + prealloc[n] = ordertemp(types.Types[TUINT8], order, false) // walk will fill in correct type } case OARRAYLIT, OSLICELIT, OCALLPART: @@ -1174,7 +1175,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node { orderexprlist(n.List, order) orderexprlist(n.Rlist, order) if n.Noescape() { - prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type + prealloc[n] = ordertemp(types.Types[TUINT8], order, false) // walk will fill in correct type } case ODDDARG: @@ -1237,7 +1238,7 @@ func orderas2(n *Node, order *Order) { left := []*Node{} for _, l := range n.List.Slice() { if !isblank(l) { - tmp := ordertemp(l.Type, order, haspointers(l.Type)) + tmp := ordertemp(l.Type, order, types.Haspointers(l.Type)) tmplist = append(tmplist, tmp) left = append(left, l) } @@ -1266,11 +1267,11 @@ func orderokas2(n *Node, order *Order) { var tmp1, tmp2 *Node if !isblank(n.List.First()) { typ := n.Rlist.First().Type - tmp1 = ordertemp(typ, order, haspointers(typ)) + tmp1 = ordertemp(typ, order, types.Haspointers(typ)) } if !isblank(n.List.Second()) { - tmp2 = ordertemp(Types[TBOOL], order, false) + tmp2 = ordertemp(types.Types[TBOOL], order, false) } order.out = append(order.out, n) diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index 2f62528766..ec6483fe8e 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -6,6 +6,7 @@ package gc import ( "cmd/compile/internal/ssa" + "cmd/compile/internal/types" "cmd/internal/dwarf" "cmd/internal/obj" "cmd/internal/src" @@ -16,7 +17,7 @@ import ( // "Portable" code generation. -func makefuncdatasym(pp *Progs, nameprefix string, funcdatakind int64, curfn *Node) *Sym { +func makefuncdatasym(pp *Progs, nameprefix string, funcdatakind int64, curfn *Node) *types.Sym { // This symbol requires a unique, reproducible name; // unique to avoid duplicate symbols, // and reproducible for reproducible builds and toolstash. @@ -165,8 +166,8 @@ func cmpstackvarlt(a, b *Node) bool { return a.Used() } - ap := haspointers(a.Type) - bp := haspointers(b.Type) + ap := types.Haspointers(a.Type) + bp := types.Haspointers(b.Type) if ap != bp { return ap } @@ -230,7 +231,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { } if f.Config.NeedsFpScratch && scratchUsed { - s.scratchFpMem = tempAt(src.NoXPos, s.curfn, Types[TUINT64]) + s.scratchFpMem = tempAt(src.NoXPos, s.curfn, types.Types[TUINT64]) } sort.Sort(byStackVar(fn.Dcl)) @@ -252,7 +253,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { } s.stksize += w s.stksize = Rnd(s.stksize, int64(n.Type.Align)) - if haspointers(n.Type) { + if types.Haspointers(n.Type) { s.stkptrsize = s.stksize } if thearch.LinkArch.InFamily(sys.MIPS, sys.MIPS64, sys.ARM, sys.ARM64, sys.PPC64, sys.S390X) { @@ -379,7 +380,7 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []*dwarf.Var { // fieldtrack adds R_USEFIELD relocations to fnsym to record any // struct fields that it used. -func fieldtrack(fnsym *obj.LSym, tracked map[*Sym]struct{}) { +func fieldtrack(fnsym *obj.LSym, tracked map[*types.Sym]struct{}) { if fnsym == nil { return } @@ -387,7 +388,7 @@ func fieldtrack(fnsym *obj.LSym, tracked map[*Sym]struct{}) { return } - trackSyms := make([]*Sym, 0, len(tracked)) + trackSyms := make([]*types.Sym, 0, len(tracked)) for sym := range tracked { trackSyms = append(trackSyms, sym) } @@ -399,7 +400,7 @@ func fieldtrack(fnsym *obj.LSym, tracked map[*Sym]struct{}) { } } -type symByName []*Sym +type symByName []*types.Sym func (a symByName) Len() int { return len(a) } func (a symByName) Less(i, j int) bool { return a[i].Name < a[j].Name } diff --git a/src/cmd/compile/internal/gc/pgen_test.go b/src/cmd/compile/internal/gc/pgen_test.go index 0a95e69c34..35ca114211 100644 --- a/src/cmd/compile/internal/gc/pgen_test.go +++ b/src/cmd/compile/internal/gc/pgen_test.go @@ -5,22 +5,23 @@ package gc import ( + "cmd/compile/internal/types" "reflect" "sort" "testing" ) -func typeWithoutPointers() *Type { - t := typ(TSTRUCT) - f := &Field{Type: typ(TINT)} - t.SetFields([]*Field{f}) +func typeWithoutPointers() *types.Type { + t := types.New(TSTRUCT) + f := &types.Field{Type: types.New(TINT)} + t.SetFields([]*types.Field{f}) return t } -func typeWithPointers() *Type { - t := typ(TSTRUCT) - f := &Field{Type: typ(TPTR64)} - t.SetFields([]*Field{f}) +func typeWithPointers() *types.Type { + t := types.New(TSTRUCT) + f := &types.Field{Type: types.New(TPTR64)} + t.SetFields([]*types.Field{f}) return t } @@ -86,38 +87,38 @@ func TestCmpstackvar(t *testing.T) { true, }, { - Node{Class: PAUTO, Type: &Type{}, Name: &Name{flags: nameNeedzero}}, - Node{Class: PAUTO, Type: &Type{}, Name: &Name{}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{flags: nameNeedzero}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}}, true, }, { - Node{Class: PAUTO, Type: &Type{}, Name: &Name{}}, - Node{Class: PAUTO, Type: &Type{}, Name: &Name{flags: nameNeedzero}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{flags: nameNeedzero}}, false, }, { - Node{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}}, - Node{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}}, + Node{Class: PAUTO, Type: &types.Type{Width: 1}, Name: &Name{}}, + Node{Class: PAUTO, Type: &types.Type{Width: 2}, Name: &Name{}}, false, }, { - Node{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}}, - Node{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}}, + Node{Class: PAUTO, Type: &types.Type{Width: 2}, Name: &Name{}}, + Node{Class: PAUTO, Type: &types.Type{Width: 1}, Name: &Name{}}, true, }, { - Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}}, - Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, true, }, { - Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}}, - Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, false, }, { - Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}}, - Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, + Node{Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, false, }, } @@ -135,41 +136,41 @@ func TestCmpstackvar(t *testing.T) { func TestStackvarSort(t *testing.T) { inp := []*Node{ - {Class: PFUNC, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, flags: nodeUsed, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{flags: nameNeedzero}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}}, + {Class: PFUNC, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PFUNC, Xoffset: 0, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PFUNC, Xoffset: 10, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PFUNC, Xoffset: 20, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, flags: nodeUsed, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{flags: nameNeedzero}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{Width: 1}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{Width: 2}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, } want := []*Node{ - {Class: PFUNC, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, flags: nodeUsed, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{flags: nameNeedzero}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}}, - {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}}, - {Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &Sym{}}, + {Class: PFUNC, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PFUNC, Xoffset: 0, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PFUNC, Xoffset: 10, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PFUNC, Xoffset: 20, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, flags: nodeUsed, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{flags: nameNeedzero}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{Width: 2}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{Width: 1}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, + {Class: PAUTO, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, + {Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &types.Sym{}}, } // haspointers updates Type.Haspointers as a side effect, so // exercise this function on all inputs so that reflect.DeepEqual // doesn't produce false positives. for i := range want { - haspointers(want[i].Type) - haspointers(inp[i].Type) + types.Haspointers(want[i].Type) + types.Haspointers(inp[i].Type) } sort.Sort(byStackVar(inp)) diff --git a/src/cmd/compile/internal/gc/plive.go b/src/cmd/compile/internal/gc/plive.go index 51cb3fa588..7d5387eb84 100644 --- a/src/cmd/compile/internal/gc/plive.go +++ b/src/cmd/compile/internal/gc/plive.go @@ -16,6 +16,7 @@ package gc import ( "cmd/compile/internal/ssa" + "cmd/compile/internal/types" "cmd/internal/obj" "crypto/md5" "fmt" @@ -84,7 +85,7 @@ type progeffectscache struct { // nor do we care about empty structs (handled by the pointer check), // nor do we care about the fake PAUTOHEAP variables. func livenessShouldTrack(n *Node) bool { - return n.Op == ONAME && (n.Class == PAUTO || n.Class == PPARAM || n.Class == PPARAMOUT) && haspointers(n.Type) + return n.Op == ONAME && (n.Class == PAUTO || n.Class == PPARAM || n.Class == PPARAMOUT) && types.Haspointers(n.Type) } // getvariables returns the list of on-stack variables that we need to track. @@ -320,7 +321,7 @@ func (lv *Liveness) blockEffects(b *ssa.Block) *BlockEffects { // and then simply copied into bv at the correct offset on future calls with // the same type t. On https://rsc.googlecode.com/hg/testdata/slow.go, onebitwalktype1 // accounts for 40% of the 6g execution time. -func onebitwalktype1(t *Type, xoffset *int64, bv bvec) { +func onebitwalktype1(t *types.Type, xoffset *int64, bv bvec) { if t.Align > 0 && *xoffset&int64(t.Align-1) != 0 { Fatalf("onebitwalktype1: invalid initial alignment, %v", t) } @@ -1050,7 +1051,7 @@ func livenessprintdebug(lv *Liveness) { fmt.Printf("\n") } -func finishgclocals(sym *Sym) { +func finishgclocals(sym *types.Sym) { ls := Linksym(sym) ls.Name = fmt.Sprintf("gclocals·%x", md5.Sum(ls.P)) ls.Set(obj.AttrDuplicateOK, true) @@ -1068,7 +1069,7 @@ func finishgclocals(sym *Sym) { // first word dumped is the total number of bitmaps. The second word is the // length of the bitmaps. All bitmaps are assumed to be of equal length. The // remaining bytes are the raw bitmaps. -func livenessemit(lv *Liveness, argssym, livesym *Sym) { +func livenessemit(lv *Liveness, argssym, livesym *types.Sym) { args := bvalloc(argswords(lv)) aoff := duint32(argssym, 0, uint32(len(lv.livevars))) // number of bitmaps aoff = duint32(argssym, aoff, uint32(args.n)) // number of bits in each bitmap @@ -1095,7 +1096,7 @@ func livenessemit(lv *Liveness, argssym, livesym *Sym) { // pointer variables in the function and emits a runtime data // structure read by the garbage collector. // Returns a map from GC safe points to their corresponding stack map index. -func liveness(e *ssafn, f *ssa.Func, argssym, livesym *Sym) map[*ssa.Value]int { +func liveness(e *ssafn, f *ssa.Func, argssym, livesym *types.Sym) map[*ssa.Value]int { // Construct the global liveness state. vars := getvariables(e.curfn) lv := newliveness(e.curfn, f, vars, e.stkptrsize) diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go index 2cc1461af7..8ba830e551 100644 --- a/src/cmd/compile/internal/gc/racewalk.go +++ b/src/cmd/compile/internal/gc/racewalk.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/src" "fmt" "strings" @@ -67,7 +68,7 @@ func instrument(fn *Node) { // getcallerpc. We use -widthptr(FP) for x86. // BUG: this will not work on arm. nodpc := *nodfp - nodpc.Type = Types[TUINTPTR] + nodpc.Type = types.Types[TUINTPTR] nodpc.Xoffset = int64(-Widthptr) nd := mkcall("racefuncenter", nil, nil, &nodpc) fn.Func.Enter.Prepend(nd) @@ -216,7 +217,7 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) { instrumentnode(&n.Left, init, 0, 0) if n.Left.Type.IsMap() { n1 := nod(OCONVNOP, n.Left, nil) - n1.Type = typPtr(Types[TUINT8]) + n1.Type = types.NewPtr(types.Types[TUINT8]) n1 = nod(OIND, n1, nil) n1 = typecheck(n1, Erv) callinstr(&n1, init, 0, skip) @@ -561,14 +562,14 @@ func makeaddable(n *Node) { func uintptraddr(n *Node) *Node { r := nod(OADDR, n, nil) r.SetBounded(true) - r = conv(r, Types[TUNSAFEPTR]) - r = conv(r, Types[TUINTPTR]) + r = conv(r, types.Types[TUNSAFEPTR]) + r = conv(r, types.Types[TUINTPTR]) return r } func detachexpr(n *Node, init *Nodes) *Node { addr := nod(OADDR, n, nil) - l := temp(typPtr(n.Type)) + l := temp(types.NewPtr(n.Type)) as := nod(OAS, l, addr) as = typecheck(as, Etop) as = walkexpr(as, init) diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go index 99fa66334d..3570c2a582 100644 --- a/src/cmd/compile/internal/gc/range.go +++ b/src/cmd/compile/internal/gc/range.go @@ -4,14 +4,17 @@ package gc -import "unicode/utf8" +import ( + "cmd/compile/internal/types" + "unicode/utf8" +) // range func typecheckrange(n *Node) { var toomany int var why string - var t1 *Type - var t2 *Type + var t1 *types.Type + var t2 *types.Type var v1 *Node var v2 *Node var ls []*Node @@ -52,7 +55,7 @@ func typecheckrange(n *Node) { goto out case TARRAY, TSLICE: - t1 = Types[TINT] + t1 = types.Types[TINT] t2 = t.Elem() case TMAP: @@ -72,8 +75,8 @@ func typecheckrange(n *Node) { } case TSTRING: - t1 = Types[TINT] - t2 = runetype + t1 = types.Types[TINT] + t2 = types.Runetype } if n.List.Len() > 2 || toomany != 0 { @@ -187,15 +190,15 @@ func walkrange(n *Node) *Node { // orderstmt arranged for a copy of the array/slice variable if needed. ha := a - hv1 := temp(Types[TINT]) - hn := temp(Types[TINT]) + hv1 := temp(types.Types[TINT]) + hn := temp(types.Types[TINT]) var hp *Node init = append(init, nod(OAS, hv1, nil)) init = append(init, nod(OAS, hn, nod(OLEN, ha, nil))) if v2 != nil { - hp = temp(typPtr(n.Type.Elem())) + hp = temp(types.NewPtr(n.Type.Elem())) tmp := nod(OINDEX, ha, nodintconst(0)) tmp.SetBounded(true) init = append(init, nod(OAS, hp, nod(OADDR, tmp, nil))) @@ -229,7 +232,7 @@ func walkrange(n *Node) *Node { tmp.Type = hp.Type tmp.Typecheck = 1 - tmp.Right.Type = Types[Tptr] + tmp.Right.Type = types.Types[types.Tptr] tmp.Right.Typecheck = 1 a = nod(OAS, hp, tmp) a = typecheck(a, Etop) @@ -281,10 +284,10 @@ func walkrange(n *Node) *Node { hv1 := temp(t.Elem()) hv1.Typecheck = 1 - if haspointers(t.Elem()) { + if types.Haspointers(t.Elem()) { init = append(init, nod(OAS, hv1, nil)) } - hb := temp(Types[TBOOL]) + hb := temp(types.Types[TBOOL]) n.Left = nod(ONE, hb, nodbool(false)) a := nod(OAS2RECV, nil, nil) @@ -321,9 +324,9 @@ func walkrange(n *Node) *Node { // orderstmt arranged for a copy of the string variable. ha := a - hv1 := temp(Types[TINT]) - hv1t := temp(Types[TINT]) - hv2 := temp(runetype) + hv1 := temp(types.Types[TINT]) + hv1t := temp(types.Types[TINT]) + hv2 := temp(types.Runetype) // hv1 := 0 init = append(init, nod(OAS, hv1, nil)) @@ -339,7 +342,7 @@ func walkrange(n *Node) *Node { // hv2 := rune(ha[hv1]) nind := nod(OINDEX, ha, hv1) nind.SetBounded(true) - body = append(body, nod(OAS, hv2, conv(nind, runetype))) + body = append(body, nod(OAS, hv2, conv(nind, types.Runetype))) // if hv2 < utf8.RuneSelf nif := nod(OIF, nil, nil) @@ -448,25 +451,25 @@ func memclrrange(n, v1, v2, a *Node) bool { n.Left = nod(ONE, nod(OLEN, a, nil), nodintconst(0)) // hp = &a[0] - hp := temp(Types[TUNSAFEPTR]) + hp := temp(types.Types[TUNSAFEPTR]) tmp := nod(OINDEX, a, nodintconst(0)) tmp.SetBounded(true) tmp = nod(OADDR, tmp, nil) tmp = nod(OCONVNOP, tmp, nil) - tmp.Type = Types[TUNSAFEPTR] + tmp.Type = types.Types[TUNSAFEPTR] n.Nbody.Append(nod(OAS, hp, tmp)) // hn = len(a) * sizeof(elem(a)) - hn := temp(Types[TUINTPTR]) + hn := temp(types.Types[TUINTPTR]) tmp = nod(OLEN, a, nil) tmp = nod(OMUL, tmp, nodintconst(elemsize)) - tmp = conv(tmp, Types[TUINTPTR]) + tmp = conv(tmp, types.Types[TUINTPTR]) n.Nbody.Append(nod(OAS, hn, tmp)) var fn *Node - if haspointers(a.Type.Elem()) { + if types.Haspointers(a.Type.Elem()) { // memclrHasPointers(hp, hn) fn = mkcall("memclrHasPointers", nil, nil, hp, hn) } else { diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go index 639a460572..3b39b6b128 100644 --- a/src/cmd/compile/internal/gc/reflect.go +++ b/src/cmd/compile/internal/gc/reflect.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/gcprog" "cmd/internal/obj" "cmd/internal/src" @@ -15,8 +16,8 @@ import ( ) type itabEntry struct { - t, itype *Type - sym *Sym + t, itype *types.Type + sym *types.Sym // symbol of the itab itself; // filled in lazily after typecheck @@ -29,22 +30,22 @@ type itabEntry struct { } type ptabEntry struct { - s *Sym - t *Type + s *types.Sym + t *types.Type } // runtime interface and reflection data structures -var signatlist []*Type +var signatlist []*types.Type var itabs []itabEntry var ptabs []ptabEntry type Sig struct { name string - pkg *Pkg - isym *Sym - tsym *Sym - type_ *Type - mtype *Type + pkg *types.Pkg + isym *types.Sym + tsym *types.Sym + type_ *types.Type + mtype *types.Type offset int32 } @@ -85,50 +86,50 @@ const ( MAXVALSIZE = 128 ) -func structfieldSize() int { return 3 * Widthptr } // Sizeof(runtime.structfield{}) -func imethodSize() int { return 4 + 4 } // Sizeof(runtime.imethod{}) -func uncommonSize(t *Type) int { // Sizeof(runtime.uncommontype{}) +func structfieldSize() int { return 3 * Widthptr } // Sizeof(runtime.structfield{}) +func imethodSize() int { return 4 + 4 } // Sizeof(runtime.imethod{}) +func uncommonSize(t *types.Type) int { // Sizeof(runtime.uncommontype{}) if t.Sym == nil && len(methods(t)) == 0 { return 0 } return 4 + 2 + 2 + 4 + 4 } -func makefield(name string, t *Type) *Field { - f := newField() +func makefield(name string, t *types.Type) *types.Field { + f := types.NewField() f.Type = t - f.Sym = nopkg.Lookup(name) + f.Sym = types.Nopkg.Lookup(name) return f } -func mapbucket(t *Type) *Type { +func mapbucket(t *types.Type) *types.Type { if t.MapType().Bucket != nil { return t.MapType().Bucket } - bucket := typ(TSTRUCT) + bucket := types.New(TSTRUCT) keytype := t.Key() valtype := t.Val() dowidth(keytype) dowidth(valtype) if keytype.Width > MAXKEYSIZE { - keytype = typPtr(keytype) + keytype = types.NewPtr(keytype) } if valtype.Width > MAXVALSIZE { - valtype = typPtr(valtype) + valtype = types.NewPtr(valtype) } - field := make([]*Field, 0, 5) + field := make([]*types.Field, 0, 5) // The first field is: uint8 topbits[BUCKETSIZE]. - arr := typArray(Types[TUINT8], BUCKETSIZE) + arr := types.NewArray(types.Types[TUINT8], BUCKETSIZE) field = append(field, makefield("topbits", arr)) - arr = typArray(keytype, BUCKETSIZE) + arr = types.NewArray(keytype, BUCKETSIZE) arr.SetNoalg(true) field = append(field, makefield("keys", arr)) - arr = typArray(valtype, BUCKETSIZE) + arr = types.NewArray(valtype, BUCKETSIZE) arr.SetNoalg(true) field = append(field, makefield("values", arr)) @@ -150,7 +151,7 @@ func mapbucket(t *Type) *Type { // then it would end with an extra 32-bit padding field. // Preempt that by emitting the padding here. if int(t.Val().Align) > Widthptr || int(t.Key().Align) > Widthptr { - field = append(field, makefield("pad", Types[TUINTPTR])) + field = append(field, makefield("pad", types.Types[TUINTPTR])) } // If keys and values have no pointers, the map implementation @@ -159,9 +160,9 @@ func mapbucket(t *Type) *Type { // Arrange for the bucket to have no pointers by changing // the type of the overflow field to uintptr in this case. // See comment on hmap.overflow in ../../../../runtime/hashmap.go. - otyp := typPtr(bucket) - if !haspointers(t.Val()) && !haspointers(t.Key()) && t.Val().Width <= MAXVALSIZE && t.Key().Width <= MAXKEYSIZE { - otyp = Types[TUINTPTR] + otyp := types.NewPtr(bucket) + if !types.Haspointers(t.Val()) && !types.Haspointers(t.Key()) && t.Val().Width <= MAXVALSIZE && t.Key().Width <= MAXKEYSIZE { + otyp = types.Types[TUINTPTR] } ovf := makefield("overflow", otyp) field = append(field, ovf) @@ -186,25 +187,25 @@ func mapbucket(t *Type) *Type { // Builds a type representing a Hmap structure for the given map type. // Make sure this stays in sync with ../../../../runtime/hashmap.go! -func hmap(t *Type) *Type { +func hmap(t *types.Type) *types.Type { if t.MapType().Hmap != nil { return t.MapType().Hmap } bucket := mapbucket(t) - fields := []*Field{ - makefield("count", Types[TINT]), - makefield("flags", Types[TUINT8]), - makefield("B", Types[TUINT8]), - makefield("noverflow", Types[TUINT16]), - makefield("hash0", Types[TUINT32]), - makefield("buckets", typPtr(bucket)), - makefield("oldbuckets", typPtr(bucket)), - makefield("nevacuate", Types[TUINTPTR]), - makefield("overflow", Types[TUNSAFEPTR]), - } - - h := typ(TSTRUCT) + fields := []*types.Field{ + makefield("count", types.Types[TINT]), + makefield("flags", types.Types[TUINT8]), + makefield("B", types.Types[TUINT8]), + makefield("noverflow", types.Types[TUINT16]), + makefield("hash0", types.Types[TUINT32]), + makefield("buckets", types.NewPtr(bucket)), + makefield("oldbuckets", types.NewPtr(bucket)), + makefield("nevacuate", types.Types[TUINTPTR]), + makefield("overflow", types.Types[TUNSAFEPTR]), + } + + h := types.New(TSTRUCT) h.SetNoalg(true) h.SetLocal(t.Local()) h.SetFields(fields) @@ -214,7 +215,7 @@ func hmap(t *Type) *Type { return h } -func hiter(t *Type) *Type { +func hiter(t *types.Type) *types.Type { if t.MapType().Hiter != nil { return t.MapType().Hiter } @@ -235,22 +236,22 @@ func hiter(t *Type) *Type { // checkBucket uintptr // } // must match ../../../../runtime/hashmap.go:hiter. - var field [12]*Field - field[0] = makefield("key", typPtr(t.Key())) - field[1] = makefield("val", typPtr(t.Val())) - field[2] = makefield("t", typPtr(Types[TUINT8])) - field[3] = makefield("h", typPtr(hmap(t))) - field[4] = makefield("buckets", typPtr(mapbucket(t))) - field[5] = makefield("bptr", typPtr(mapbucket(t))) - field[6] = makefield("overflow0", Types[TUNSAFEPTR]) - field[7] = makefield("overflow1", Types[TUNSAFEPTR]) - field[8] = makefield("startBucket", Types[TUINTPTR]) - field[9] = makefield("stuff", Types[TUINTPTR]) // offset+wrapped+B+I - field[10] = makefield("bucket", Types[TUINTPTR]) - field[11] = makefield("checkBucket", Types[TUINTPTR]) + var field [12]*types.Field + field[0] = makefield("key", types.NewPtr(t.Key())) + field[1] = makefield("val", types.NewPtr(t.Val())) + field[2] = makefield("t", types.NewPtr(types.Types[TUINT8])) + field[3] = makefield("h", types.NewPtr(hmap(t))) + field[4] = makefield("buckets", types.NewPtr(mapbucket(t))) + field[5] = makefield("bptr", types.NewPtr(mapbucket(t))) + field[6] = makefield("overflow0", types.Types[TUNSAFEPTR]) + field[7] = makefield("overflow1", types.Types[TUNSAFEPTR]) + field[8] = makefield("startBucket", types.Types[TUINTPTR]) + field[9] = makefield("stuff", types.Types[TUINTPTR]) // offset+wrapped+B+I + field[10] = makefield("bucket", types.Types[TUINTPTR]) + field[11] = makefield("checkBucket", types.Types[TUINTPTR]) // build iterator struct holding the above fields - i := typ(TSTRUCT) + i := types.New(TSTRUCT) i.SetNoalg(true) i.SetFields(field[:]) dowidth(i) @@ -264,7 +265,7 @@ func hiter(t *Type) *Type { // f is method type, with receiver. // return function type, receiver as first argument (or not). -func methodfunc(f *Type, receiver *Type) *Type { +func methodfunc(f *types.Type, receiver *types.Type) *types.Type { var in []*Node if receiver != nil { d := nod(ODCLFIELD, nil, nil) @@ -298,7 +299,7 @@ func methodfunc(f *Type, receiver *Type) *Type { // methods returns the methods of the non-interface type t, sorted by name. // Generates stub functions as needed. -func methods(t *Type) []*Sig { +func methods(t *types.Type) []*Sig { // method type mt := methtype(t) @@ -311,7 +312,7 @@ func methods(t *Type) []*Sig { it := t if !isdirectiface(it) { - it = typPtr(t) + it = types.NewPtr(t) } // make list of methods for t, @@ -386,7 +387,7 @@ func methods(t *Type) []*Sig { } // imethods returns the methods of the interface type t, sorted by name. -func imethods(t *Type) []*Sig { +func imethods(t *types.Type) []*Sig { var methods []*Sig for _, f := range t.Fields().Slice() { if f.Type.Etype != TFUNC || f.Sym == nil { @@ -434,7 +435,7 @@ func imethods(t *Type) []*Sig { return methods } -func dimportpath(p *Pkg) { +func dimportpath(p *types.Pkg) { if p.Pathsym != nil { return } @@ -460,11 +461,11 @@ func dimportpath(p *Pkg) { p.Pathsym = s } -func dgopkgpath(s *Sym, ot int, pkg *Pkg) int { +func dgopkgpath(s *types.Sym, ot int, pkg *types.Pkg) int { return dgopkgpathLSym(Linksym(s), ot, pkg) } -func dgopkgpathLSym(s *obj.LSym, ot int, pkg *Pkg) int { +func dgopkgpathLSym(s *obj.LSym, ot int, pkg *types.Pkg) int { if pkg == nil { return duintxxLSym(s, ot, 0, Widthptr) } @@ -484,7 +485,7 @@ func dgopkgpathLSym(s *obj.LSym, ot int, pkg *Pkg) int { } // dgopkgpathOffLSym writes an offset relocation in s at offset ot to the pkg path symbol. -func dgopkgpathOffLSym(s *obj.LSym, ot int, pkg *Pkg) int { +func dgopkgpathOffLSym(s *obj.LSym, ot int, pkg *types.Pkg) int { if pkg == nil { return duintxxLSym(s, ot, 0, 4) } @@ -504,7 +505,7 @@ func dgopkgpathOffLSym(s *obj.LSym, ot int, pkg *Pkg) int { // isExportedField reports whether a struct field is exported. // It also returns the package to use for PkgPath for an unexported field. -func isExportedField(ft *Field) (bool, *Pkg) { +func isExportedField(ft *types.Field) (bool, *types.Pkg) { if ft.Sym != nil && ft.Embedded == 0 { return exportname(ft.Sym.Name), ft.Sym.Pkg } else { @@ -518,7 +519,7 @@ func isExportedField(ft *Field) (bool, *Pkg) { } // dnameField dumps a reflect.name for a struct field. -func dnameField(s *Sym, ot int, spkg *Pkg, ft *Field) int { +func dnameField(s *types.Sym, ot int, spkg *types.Pkg, ft *types.Field) int { var name string if ft.Sym != nil { name = ft.Sym.Name @@ -532,7 +533,7 @@ func dnameField(s *Sym, ot int, spkg *Pkg, ft *Field) int { } // dnameData writes the contents of a reflect.name into s at offset ot. -func dnameData(s *obj.LSym, ot int, name, tag string, pkg *Pkg, exported bool) int { +func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported bool) int { if len(name) > 1<<16-1 { Fatalf("name too long: %s", name) } @@ -577,7 +578,7 @@ func dnameData(s *obj.LSym, ot int, name, tag string, pkg *Pkg, exported bool) i var dnameCount int // dname creates a reflect.name for a struct field or method. -func dname(name, tag string, pkg *Pkg, exported bool) *obj.LSym { +func dname(name, tag string, pkg *types.Pkg, exported bool) *obj.LSym { // Write out data as "type.." to signal two things to the // linker, first that when dynamically linking, the symbol // should be moved to a relro section, and second that the @@ -610,7 +611,7 @@ func dname(name, tag string, pkg *Pkg, exported bool) *obj.LSym { // dextratype dumps the fields of a runtime.uncommontype. // dataAdd is the offset in bytes after the header where the // backing array of the []method field is written (by dextratypeData). -func dextratype(s *Sym, ot int, t *Type, dataAdd int) int { +func dextratype(s *types.Sym, ot int, t *types.Type, dataAdd int) int { m := methods(t) if t.Sym == nil && len(m) == 0 { return ot @@ -642,7 +643,7 @@ func dextratype(s *Sym, ot int, t *Type, dataAdd int) int { return ot } -func typePkg(t *Type) *Pkg { +func typePkg(t *types.Type) *types.Pkg { tsym := t.Sym if tsym == nil { switch t.Etype { @@ -652,7 +653,7 @@ func typePkg(t *Type) *Pkg { } } } - if tsym != nil && t != Types[t.Etype] && t != errortype { + if tsym != nil && t != types.Types[t.Etype] && t != types.Errortype { return tsym.Pkg } return nil @@ -660,12 +661,12 @@ func typePkg(t *Type) *Pkg { // dextratypeData dumps the backing array for the []method field of // runtime.uncommontype. -func dextratypeData(s *Sym, ot int, t *Type) int { +func dextratypeData(s *types.Sym, ot int, t *types.Type) int { lsym := Linksym(s) for _, a := range methods(t) { // ../../../../runtime/type.go:/method exported := exportname(a.name) - var pkg *Pkg + var pkg *types.Pkg if !exported && a.pkg != typePkg(t) { pkg = a.pkg } @@ -721,8 +722,8 @@ var kinds = []int{ // typeptrdata returns the length in bytes of the prefix of t // containing pointer data. Anything after this offset is scalar data. -func typeptrdata(t *Type) int64 { - if !haspointers(t) { +func typeptrdata(t *types.Type) int64 { + if !types.Haspointers(t) { return 0 } @@ -754,9 +755,9 @@ func typeptrdata(t *Type) int64 { case TSTRUCT: // Find the last field that has pointers. - var lastPtrField *Field + var lastPtrField *types.Field for _, t1 := range t.Fields().Slice() { - if haspointers(t1.Type) { + if types.Haspointers(t1.Type) { lastPtrField = t1 } } @@ -781,10 +782,10 @@ const ( tflagNamed = 1 << 2 ) -var dcommontype_algarray *Sym +var dcommontype_algarray *types.Sym // dcommontype dumps the contents of a reflect.rtype (runtime._type). -func dcommontype(s *Sym, ot int, t *Type) int { +func dcommontype(s *types.Sym, ot int, t *types.Type) int { if ot != 0 { Fatalf("dcommontype %d", ot) } @@ -795,15 +796,15 @@ func dcommontype(s *Sym, ot int, t *Type) int { } dowidth(t) alg := algtype(t) - var algsym *Sym + var algsym *types.Sym if alg == ASPECIAL || alg == AMEM { algsym = dalgsym(t) } sptrWeak := true - var sptr *Sym - if !t.IsPtr() || t.ptrTo != nil { - tptr := typPtr(t) + var sptr *types.Sym + if !t.IsPtr() || t.PtrBase != nil { + tptr := types.NewPtr(t) if t.Sym != nil || methods(tptr) != nil { sptrWeak = false } @@ -874,7 +875,7 @@ func dcommontype(s *Sym, ot int, t *Type) int { ot = duint8(s, ot, t.Align) // fieldAlign i = kinds[t.Etype] - if !haspointers(t) { + if !types.Haspointers(t) { i |= obj.KindNoPointers } if isdirectiface(t) { @@ -905,7 +906,7 @@ func dcommontype(s *Sym, ot int, t *Type) int { return ot } -func typesym(t *Type) *Sym { +func typesym(t *types.Type) *types.Sym { name := t.ShortString() // Use a separate symbol name for Noalg types for #17752. @@ -918,11 +919,11 @@ func typesym(t *Type) *Sym { // tracksym returns the symbol for tracking use of field/method f, assumed // to be a member of struct/interface type t. -func tracksym(t *Type, f *Field) *Sym { +func tracksym(t *types.Type, f *types.Field) *types.Sym { return trackpkg.Lookup(t.ShortString() + "." + f.Sym.Name) } -func typesymprefix(prefix string, t *Type) *Sym { +func typesymprefix(prefix string, t *types.Type) *types.Sym { p := prefix + "." + t.ShortString() s := typepkg.Lookup(p) @@ -931,50 +932,50 @@ func typesymprefix(prefix string, t *Type) *Sym { return s } -func typenamesym(t *Type) *Sym { +func typenamesym(t *types.Type) *types.Sym { if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() { Fatalf("typename %v", t) } s := typesym(t) if s.Def == nil { n := newnamel(src.NoXPos, s) - n.Type = Types[TUINT8] + n.Type = types.Types[TUINT8] n.Class = PEXTERN n.Typecheck = 1 - s.Def = n + s.Def = asTypesNode(n) signatlist = append(signatlist, t) } - return s.Def.Sym + return asNode(s.Def).Sym } -func typename(t *Type) *Node { +func typename(t *types.Type) *Node { s := typenamesym(t) - n := nod(OADDR, s.Def, nil) - n.Type = typPtr(s.Def.Type) + n := nod(OADDR, asNode(s.Def), nil) + n.Type = types.NewPtr(asNode(s.Def).Type) n.SetAddable(true) n.Typecheck = 1 return n } -func itabname(t, itype *Type) *Node { +func itabname(t, itype *types.Type) *Node { if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() || !itype.IsInterface() || itype.IsEmptyInterface() { Fatalf("itabname(%v, %v)", t, itype) } s := itabpkg.Lookup(t.ShortString() + "," + itype.ShortString()) if s.Def == nil { n := newname(s) - n.Type = Types[TUINT8] + n.Type = types.Types[TUINT8] n.Class = PEXTERN n.Typecheck = 1 - s.Def = n + s.Def = asTypesNode(n) itabs = append(itabs, itabEntry{t: t, itype: itype, sym: s}) } - n := nod(OADDR, s.Def, nil) - n.Type = typPtr(s.Def.Type) + n := nod(OADDR, asNode(s.Def), nil) + n.Type = types.NewPtr(asNode(s.Def).Type) n.SetAddable(true) n.Typecheck = 1 return n @@ -982,7 +983,7 @@ func itabname(t, itype *Type) *Node { // isreflexive reports whether t has a reflexive equality operator. // That is, if x==x for all x of type t. -func isreflexive(t *Type) bool { +func isreflexive(t *types.Type) bool { switch t.Etype { case TBOOL, TINT, @@ -1029,7 +1030,7 @@ func isreflexive(t *Type) bool { // needkeyupdate reports whether map updates with t as a key // need the key to be updated. -func needkeyupdate(t *Type) bool { +func needkeyupdate(t *types.Type) bool { switch t.Etype { case TBOOL, TINT, @@ -1074,12 +1075,12 @@ func needkeyupdate(t *Type) bool { } } -func dtypesym(t *Type) *Sym { +func dtypesym(t *types.Type) *types.Sym { // Replace byte, rune aliases with real type. // They've been separate internally to make error messages // better, but we have to merge them in the reflect tables. - if t == bytetype || t == runetype { - t = Types[t.Etype] + if t == types.Bytetype || t == types.Runetype { + t = types.Types[t.Etype] } if t.IsUntyped() { @@ -1105,7 +1106,7 @@ func dtypesym(t *Type) *Sym { dupok = obj.DUPOK } - if myimportpath == "runtime" && (tbase == Types[tbase.Etype] || tbase == bytetype || tbase == runetype || tbase == errortype) { // int, float, etc + if myimportpath == "runtime" && (tbase == types.Types[tbase.Etype] || tbase == types.Bytetype || tbase == types.Runetype || tbase == types.Errortype) { // int, float, etc goto ok } @@ -1127,7 +1128,7 @@ ok: case TARRAY: // ../../../../runtime/type.go:/arrayType s1 := dtypesym(t.Elem()) - t2 := typSlice(t.Elem()) + t2 := types.NewSlice(t.Elem()) s2 := dtypesym(t2) ot = dcommontype(s, ot, t) ot = dsymptr(s, ot, s1, 0) @@ -1199,8 +1200,8 @@ ok: // ../../../../runtime/type.go:/interfaceType ot = dcommontype(s, ot, t) - var tpkg *Pkg - if t.Sym != nil && t != Types[t.Etype] && t != errortype { + var tpkg *types.Pkg + if t.Sym != nil && t != types.Types[t.Etype] && t != types.Errortype { tpkg = t.Sym.Pkg } ot = dgopkgpath(s, ot, tpkg) @@ -1215,7 +1216,7 @@ ok: for _, a := range m { // ../../../../runtime/type.go:/imethod exported := exportname(a.name) - var pkg *Pkg + var pkg *types.Pkg if !exported && a.pkg != tpkg { pkg = a.pkg } @@ -1362,7 +1363,7 @@ func peekitabs() { // for the given concrete type and interface // type, return the (sorted) set of methods // on the concrete type that implement the interface -func genfun(t, it *Type) []*obj.LSym { +func genfun(t, it *types.Type) []*obj.LSym { if t == nil || it == nil { return nil } @@ -1431,7 +1432,7 @@ func dumptypestructs() { t := signatlist[i] dtypesym(t) if t.Sym != nil { - dtypesym(typPtr(t)) + dtypesym(types.NewPtr(t)) } } @@ -1502,17 +1503,17 @@ func dumptypestructs() { // another possible choice would be package main, // but using runtime means fewer copies in .6 files. if myimportpath == "runtime" { - for i := EType(1); i <= TBOOL; i++ { - dtypesym(typPtr(Types[i])) + for i := types.EType(1); i <= TBOOL; i++ { + dtypesym(types.NewPtr(types.Types[i])) } - dtypesym(typPtr(Types[TSTRING])) - dtypesym(typPtr(Types[TUNSAFEPTR])) + dtypesym(types.NewPtr(types.Types[TSTRING])) + dtypesym(types.NewPtr(types.Types[TUNSAFEPTR])) // emit type structs for error and func(error) string. // The latter is the type of an auto-generated wrapper. - dtypesym(typPtr(errortype)) + dtypesym(types.NewPtr(types.Errortype)) - dtypesym(functype(nil, []*Node{anonfield(errortype)}, []*Node{anonfield(Types[TSTRING])})) + dtypesym(functype(nil, []*Node{anonfield(types.Errortype)}, []*Node{anonfield(types.Types[TSTRING])})) // add paths for runtime and main, which 6l imports implicitly. dimportpath(Runtimepkg) @@ -1527,16 +1528,16 @@ func dumptypestructs() { } } -type pkgByPath []*Pkg +type pkgByPath []*types.Pkg func (a pkgByPath) Len() int { return len(a) } func (a pkgByPath) Less(i, j int) bool { return a[i].Path < a[j].Path } func (a pkgByPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func dalgsym(t *Type) *Sym { - var s *Sym - var hashfunc *Sym - var eqfunc *Sym +func dalgsym(t *types.Type) *types.Sym { + var s *types.Sym + var hashfunc *types.Sym + var eqfunc *types.Sym // dalgsym is only called for a type that needs an algorithm table, // which implies that the type is comparable (or else it would use ANOEQ). @@ -1637,7 +1638,7 @@ const maxPtrmaskBytes = 2048 // dgcsym emits and returns a data symbol containing GC information for type t, // along with a boolean reporting whether the UseGCProg bit should be set in // the type kind, and the ptrdata field to record in the reflect type information. -func dgcsym(t *Type) (sym *Sym, useGCProg bool, ptrdata int64) { +func dgcsym(t *types.Type) (sym *types.Sym, useGCProg bool, ptrdata int64) { ptrdata = typeptrdata(t) if ptrdata/int64(Widthptr) <= maxPtrmaskBytes*8 { sym = dgcptrmask(t) @@ -1650,7 +1651,7 @@ func dgcsym(t *Type) (sym *Sym, useGCProg bool, ptrdata int64) { } // dgcptrmask emits and returns the symbol containing a pointer mask for type t. -func dgcptrmask(t *Type) *Sym { +func dgcptrmask(t *types.Type) *types.Sym { ptrmask := make([]byte, (typeptrdata(t)/int64(Widthptr)+7)/8) fillptrmask(t, ptrmask) p := fmt.Sprintf("gcbits.%x", ptrmask) @@ -1669,11 +1670,11 @@ func dgcptrmask(t *Type) *Sym { // fillptrmask fills in ptrmask with 1s corresponding to the // word offsets in t that hold pointers. // ptrmask is assumed to fit at least typeptrdata(t)/Widthptr bits. -func fillptrmask(t *Type, ptrmask []byte) { +func fillptrmask(t *types.Type, ptrmask []byte) { for i := range ptrmask { ptrmask[i] = 0 } - if !haspointers(t) { + if !types.Haspointers(t) { return } @@ -1693,7 +1694,7 @@ func fillptrmask(t *Type, ptrmask []byte) { // along with the size of the data described by the program (in the range [typeptrdata(t), t.Width]). // In practice, the size is typeptrdata(t) except for non-trivial arrays. // For non-trivial arrays, the program describes the full t.Width size. -func dgcprog(t *Type) (*Sym, int64) { +func dgcprog(t *types.Type) (*types.Sym, int64) { dowidth(t) if t.Width == BADWIDTH { Fatalf("dgcprog: %v badwidth", t) @@ -1711,14 +1712,14 @@ func dgcprog(t *Type) (*Sym, int64) { } type GCProg struct { - sym *Sym + sym *types.Sym symoff int w gcprog.Writer } var Debug_gcprog int // set by -d gcprog -func (p *GCProg) init(sym *Sym) { +func (p *GCProg) init(sym *types.Sym) { p.sym = sym p.symoff = 4 // first 4 bytes hold program length p.w.Init(p.writeByte) @@ -1741,9 +1742,9 @@ func (p *GCProg) end() { } } -func (p *GCProg) emit(t *Type, offset int64) { +func (p *GCProg) emit(t *types.Type, offset int64) { dowidth(t) - if !haspointers(t) { + if !types.Haspointers(t) { return } if t.Width == int64(Widthptr) { @@ -1808,13 +1809,13 @@ func zeroaddr(size int64) *Node { s := mappkg.Lookup("zero") if s.Def == nil { x := newname(s) - x.Type = Types[TUINT8] + x.Type = types.Types[TUINT8] x.Class = PEXTERN x.Typecheck = 1 - s.Def = x + s.Def = asTypesNode(x) } - z := nod(OADDR, s.Def, nil) - z.Type = typPtr(Types[TUINT8]) + z := nod(OADDR, asNode(s.Def), nil) + z.Type = types.NewPtr(types.Types[TUINT8]) z.SetAddable(true) z.Typecheck = 1 return z diff --git a/src/cmd/compile/internal/gc/reflect_test.go b/src/cmd/compile/internal/gc/reflect_test.go index 9e39933238..ad3cad73c0 100644 --- a/src/cmd/compile/internal/gc/reflect_test.go +++ b/src/cmd/compile/internal/gc/reflect_test.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "reflect" "sort" "testing" @@ -12,24 +13,24 @@ import ( func TestSortingByMethodNameAndPackagePath(t *testing.T) { data := []*Sig{ - &Sig{name: "b", pkg: &Pkg{Path: "abc"}}, + &Sig{name: "b", pkg: &types.Pkg{Path: "abc"}}, &Sig{name: "b", pkg: nil}, &Sig{name: "c", pkg: nil}, - &Sig{name: "c", pkg: &Pkg{Path: "uvw"}}, + &Sig{name: "c", pkg: &types.Pkg{Path: "uvw"}}, &Sig{name: "c", pkg: nil}, - &Sig{name: "b", pkg: &Pkg{Path: "xyz"}}, - &Sig{name: "a", pkg: &Pkg{Path: "abc"}}, + &Sig{name: "b", pkg: &types.Pkg{Path: "xyz"}}, + &Sig{name: "a", pkg: &types.Pkg{Path: "abc"}}, &Sig{name: "b", pkg: nil}, } want := []*Sig{ - &Sig{name: "a", pkg: &Pkg{Path: "abc"}}, + &Sig{name: "a", pkg: &types.Pkg{Path: "abc"}}, &Sig{name: "b", pkg: nil}, &Sig{name: "b", pkg: nil}, - &Sig{name: "b", pkg: &Pkg{Path: "abc"}}, - &Sig{name: "b", pkg: &Pkg{Path: "xyz"}}, + &Sig{name: "b", pkg: &types.Pkg{Path: "abc"}}, + &Sig{name: "b", pkg: &types.Pkg{Path: "xyz"}}, &Sig{name: "c", pkg: nil}, &Sig{name: "c", pkg: nil}, - &Sig{name: "c", pkg: &Pkg{Path: "uvw"}}, + &Sig{name: "c", pkg: &types.Pkg{Path: "uvw"}}, } if len(data) != len(want) { t.Fatal("want and data must match") diff --git a/src/cmd/compile/internal/gc/select.go b/src/cmd/compile/internal/gc/select.go index 92debecca5..5a65a759e5 100644 --- a/src/cmd/compile/internal/gc/select.go +++ b/src/cmd/compile/internal/gc/select.go @@ -4,6 +4,8 @@ package gc +import "cmd/compile/internal/types" + // select func typecheckselect(sel *Node) { var ncase *Node @@ -225,21 +227,21 @@ func walkselect(sel *Node) { case OSEND: // if selectnbsend(c, v) { body } else { default body } ch := n.Left - r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), Types[TBOOL], &r.Ninit, ch, n.Right) + r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), types.Types[TBOOL], &r.Ninit, ch, n.Right) case OSELRECV: // if c != nil && selectnbrecv(&v, c) { body } else { default body } r = nod(OIF, nil, nil) r.Ninit.Set(cas.Ninit.Slice()) ch := n.Right.Left - r.Left = mkcall1(chanfn("selectnbrecv", 2, ch.Type), Types[TBOOL], &r.Ninit, n.Left, ch) + r.Left = mkcall1(chanfn("selectnbrecv", 2, ch.Type), types.Types[TBOOL], &r.Ninit, n.Left, ch) case OSELRECV2: // if c != nil && selectnbrecv2(&v, c) { body } else { default body } r = nod(OIF, nil, nil) r.Ninit.Set(cas.Ninit.Slice()) ch := n.Right.Left - r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), Types[TBOOL], &r.Ninit, n.Left, n.List.First(), ch) + r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), types.Types[TBOOL], &r.Ninit, n.Left, n.List.First(), ch) } r.Left = typecheck(r.Left, Erv) @@ -258,7 +260,7 @@ func walkselect(sel *Node) { r = nod(OAS, selv, nil) r = typecheck(r, Etop) init = append(init, r) - var_ = conv(conv(nod(OADDR, selv, nil), Types[TUNSAFEPTR]), typPtr(Types[TUINT8])) + var_ = conv(conv(nod(OADDR, selv, nil), types.Types[TUNSAFEPTR]), types.NewPtr(types.Types[TUINT8])) r = mkcall("newselect", nil, nil, var_, nodintconst(selv.Type.Width), nodintconst(sel.Xoffset)) r = typecheck(r, Etop) init = append(init, r) @@ -297,8 +299,8 @@ func walkselect(sel *Node) { // run the select setlineno(sel) - chosen = temp(Types[TINT]) - r = nod(OAS, chosen, mkcall("selectgo", Types[TINT], nil, var_)) + chosen = temp(types.Types[TINT]) + r = nod(OAS, chosen, mkcall("selectgo", types.Types[TINT], nil, var_)) r = typecheck(r, Etop) init = append(init, r) @@ -327,29 +329,29 @@ out: } // Keep in sync with src/runtime/select.go. -func selecttype(size int64) *Type { +func selecttype(size int64) *types.Type { // TODO(dvyukov): it's possible to generate Scase only once // and then cache; and also cache Select per size. scase := tostruct([]*Node{ - namedfield("elem", typPtr(Types[TUINT8])), - namedfield("chan", typPtr(Types[TUINT8])), - namedfield("pc", Types[TUINTPTR]), - namedfield("kind", Types[TUINT16]), - namedfield("receivedp", typPtr(Types[TUINT8])), - namedfield("releasetime", Types[TUINT64]), + namedfield("elem", types.NewPtr(types.Types[TUINT8])), + namedfield("chan", types.NewPtr(types.Types[TUINT8])), + namedfield("pc", types.Types[TUINTPTR]), + namedfield("kind", types.Types[TUINT16]), + namedfield("receivedp", types.NewPtr(types.Types[TUINT8])), + namedfield("releasetime", types.Types[TUINT64]), }) scase.SetNoalg(true) scase.SetLocal(true) sel := tostruct([]*Node{ - namedfield("tcase", Types[TUINT16]), - namedfield("ncase", Types[TUINT16]), - namedfield("pollorder", typPtr(Types[TUINT8])), - namedfield("lockorder", typPtr(Types[TUINT8])), - namedfield("scase", typArray(scase, size)), - namedfield("lockorderarr", typArray(Types[TUINT16], size)), - namedfield("pollorderarr", typArray(Types[TUINT16], size)), + namedfield("tcase", types.Types[TUINT16]), + namedfield("ncase", types.Types[TUINT16]), + namedfield("pollorder", types.NewPtr(types.Types[TUINT8])), + namedfield("lockorder", types.NewPtr(types.Types[TUINT8])), + namedfield("scase", types.NewArray(scase, size)), + namedfield("lockorderarr", types.NewArray(types.Types[TUINT16], size)), + namedfield("pollorderarr", types.NewArray(types.Types[TUINT16], size)), }) sel.SetNoalg(true) sel.SetLocal(true) diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go index da0dbeef6b..47aee51c17 100644 --- a/src/cmd/compile/internal/gc/sinit.go +++ b/src/cmd/compile/internal/gc/sinit.go @@ -4,7 +4,10 @@ package gc -import "fmt" +import ( + "cmd/compile/internal/types" + "fmt" +) // static initialization const ( @@ -43,7 +46,7 @@ func init1(n *Node, out *[]*Node) { if n.Left != nil && n.Type != nil && n.Left.Op == OTYPE && n.Class == PFUNC { // Methods called as Type.Method(receiver, ...). // Definitions for method expressions are stored in type->nname. - init1(n.Type.Nname(), out) + init1(asNode(n.Type.FuncType().Nname), out) } if n.Op != ONAME { @@ -214,7 +217,7 @@ func init2(n *Node, out *[]*Node) { init2list(n.Func.Closure.Nbody, out) } if n.Op == ODOTMETH || n.Op == OCALLPART { - init2(n.Type.Nname(), out) + init2(asNode(n.Type.FuncType().Nname), out) } } @@ -424,7 +427,7 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool { initplan(r) // Init slice. bound := r.Right.Int64() - ta := typArray(r.Type.Elem(), bound) + ta := types.NewArray(r.Type.Elem(), bound) a := staticname(ta) inittemps[r] = a n := *l @@ -535,7 +538,7 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool { *out = append(*out, nod(OAS, a, val)) } ptr := nod(OADDR, a, nil) - n.Type = typPtr(val.Type) + n.Type = types.NewPtr(val.Type) gdata(&n, ptr, Widthptr) } @@ -574,7 +577,7 @@ var statuniqgen int // name generator for static temps // staticname returns a name backed by a static data symbol. // Callers should call n.Name.SetReadonly(true) on the // returned node for readonly nodes. -func staticname(t *Type) *Node { +func staticname(t *types.Type) *Node { // Don't use lookupN; it interns the resulting string, but these are all unique. n := newname(lookup(fmt.Sprintf("statictmp_%d", statuniqgen))) statuniqgen++ @@ -768,7 +771,7 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes) func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) { // make an array type corresponding the number of elements we have - t := typArray(n.Type.Elem(), n.Right.Int64()) + t := types.NewArray(n.Type.Elem(), n.Right.Int64()) dowidth(t) if ctxt == inNonInitFunction { @@ -786,7 +789,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) { } var v Node - nodconst(&v, Types[TINT], t.NumElem()) + nodconst(&v, types.Types[TINT], t.NumElem()) nam.Xoffset += int64(array_array) gdata(&nam, nod(OADDR, vstat, nil), Widthptr) @@ -831,7 +834,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) { } // make new auto *array (3 declare) - vauto := temp(typPtr(t)) + vauto := temp(types.NewPtr(t)) // set auto to point at new temp or heap (3 assign) var a *Node @@ -946,8 +949,8 @@ func maplit(n *Node, m *Node, init *Nodes) { // For a large number of static entries, put them in an array and loop. // build types [count]Tindex and [count]Tvalue - tk := typArray(n.Type.Key(), int64(len(stat))) - tv := typArray(n.Type.Val(), int64(len(stat))) + tk := types.NewArray(n.Type.Key(), int64(len(stat))) + tv := types.NewArray(n.Type.Val(), int64(len(stat))) // TODO(josharian): suppress alg generation for these types? dowidth(tk) @@ -982,7 +985,7 @@ func maplit(n *Node, m *Node, init *Nodes) { // for i = 0; i < len(vstatk); i++ { // map[vstatk[i]] = vstatv[i] // } - i := temp(Types[TINT]) + i := temp(types.Types[TINT]) rhs := nod(OINDEX, vstatv, i) rhs.SetBounded(true) diff --git a/src/cmd/compile/internal/gc/sizeof_test.go b/src/cmd/compile/internal/gc/sizeof_test.go index 2c6fecac67..c8b1789669 100644 --- a/src/cmd/compile/internal/gc/sizeof_test.go +++ b/src/cmd/compile/internal/gc/sizeof_test.go @@ -7,6 +7,7 @@ package gc import ( + "cmd/compile/internal/types" "reflect" "testing" "unsafe" @@ -26,20 +27,21 @@ func TestSizeof(t *testing.T) { {Name{}, 36, 56}, {Param{}, 28, 56}, {Node{}, 84, 136}, - {Sym{}, 60, 104}, - {Type{}, 52, 88}, - {MapType{}, 20, 40}, - {ForwardType{}, 20, 32}, - {FuncType{}, 28, 48}, - {StructType{}, 12, 24}, - {InterType{}, 4, 8}, - {ChanType{}, 8, 16}, - {ArrayType{}, 12, 16}, - {DDDFieldType{}, 4, 8}, - {FuncArgsType{}, 4, 8}, - {ChanArgsType{}, 4, 8}, - {PtrType{}, 4, 8}, - {SliceType{}, 4, 8}, + // TODO(gri) test the ones below in the types package + {types.Sym{}, 60, 104}, + {types.Type{}, 52, 88}, + {types.MapType{}, 20, 40}, + {types.ForwardType{}, 20, 32}, + {types.FuncType{}, 28, 48}, + {types.StructType{}, 12, 24}, + {types.InterType{}, 4, 8}, + {types.ChanType{}, 8, 16}, + {types.ArrayType{}, 12, 16}, + {types.DDDFieldType{}, 4, 8}, + {types.FuncArgsType{}, 4, 8}, + {types.ChanArgsType{}, 4, 8}, + {types.PtrType{}, 4, 8}, + {types.SliceType{}, 4, 8}, } for _, tt := range tests { diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index a0cc83d82f..75acaa3ebc 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -13,6 +13,7 @@ import ( "sort" "cmd/compile/internal/ssa" + "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/src" "cmd/internal/sys" @@ -22,46 +23,46 @@ var ssaConfig *ssa.Config var ssaCache *ssa.Cache func initssaconfig() { - types := ssa.Types{ - Bool: Types[TBOOL], - Int8: Types[TINT8], - Int16: Types[TINT16], - Int32: Types[TINT32], - Int64: Types[TINT64], - UInt8: Types[TUINT8], - UInt16: Types[TUINT16], - UInt32: Types[TUINT32], - UInt64: Types[TUINT64], - Float32: Types[TFLOAT32], - Float64: Types[TFLOAT64], - Int: Types[TINT], - Uintptr: Types[TUINTPTR], - String: Types[TSTRING], - BytePtr: typPtr(Types[TUINT8]), - Int32Ptr: typPtr(Types[TINT32]), - UInt32Ptr: typPtr(Types[TUINT32]), - IntPtr: typPtr(Types[TINT]), - UintptrPtr: typPtr(Types[TUINTPTR]), - Float32Ptr: typPtr(Types[TFLOAT32]), - Float64Ptr: typPtr(Types[TFLOAT64]), - BytePtrPtr: typPtr(typPtr(Types[TUINT8])), + types_ := ssa.Types{ + Bool: types.Types[TBOOL], + Int8: types.Types[TINT8], + Int16: types.Types[TINT16], + Int32: types.Types[TINT32], + Int64: types.Types[TINT64], + UInt8: types.Types[TUINT8], + UInt16: types.Types[TUINT16], + UInt32: types.Types[TUINT32], + UInt64: types.Types[TUINT64], + Float32: types.Types[TFLOAT32], + Float64: types.Types[TFLOAT64], + Int: types.Types[TINT], + Uintptr: types.Types[TUINTPTR], + String: types.Types[TSTRING], + BytePtr: types.NewPtr(types.Types[TUINT8]), + Int32Ptr: types.NewPtr(types.Types[TINT32]), + UInt32Ptr: types.NewPtr(types.Types[TUINT32]), + IntPtr: types.NewPtr(types.Types[TINT]), + UintptrPtr: types.NewPtr(types.Types[TUINTPTR]), + Float32Ptr: types.NewPtr(types.Types[TFLOAT32]), + Float64Ptr: types.NewPtr(types.Types[TFLOAT64]), + BytePtrPtr: types.NewPtr(types.NewPtr(types.Types[TUINT8])), } // Generate a few pointer types that are uncommon in the frontend but common in the backend. // Caching is disabled in the backend, so generating these here avoids allocations. - _ = typPtr(Types[TINTER]) // *interface{} - _ = typPtr(typPtr(Types[TSTRING])) // **string - _ = typPtr(typPtr(idealstring)) // **string - _ = typPtr(typSlice(Types[TINTER])) // *[]interface{} - _ = typPtr(typPtr(bytetype)) // **byte - _ = typPtr(typSlice(bytetype)) // *[]byte - _ = typPtr(typSlice(Types[TSTRING])) // *[]string - _ = typPtr(typSlice(idealstring)) // *[]string - _ = typPtr(typPtr(typPtr(Types[TUINT8]))) // ***uint8 - _ = typPtr(Types[TINT16]) // *int16 - _ = typPtr(Types[TINT64]) // *int64 - _ = typPtr(errortype) // *error - typPtrCacheEnabled = false - ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, types, Ctxt, Debug['N'] == 0) + _ = types.NewPtr(types.Types[TINTER]) // *interface{} + _ = types.NewPtr(types.NewPtr(types.Types[TSTRING])) // **string + _ = types.NewPtr(types.NewPtr(types.Idealstring)) // **string + _ = types.NewPtr(types.NewSlice(types.Types[TINTER])) // *[]interface{} + _ = types.NewPtr(types.NewPtr(types.Bytetype)) // **byte + _ = types.NewPtr(types.NewSlice(types.Bytetype)) // *[]byte + _ = types.NewPtr(types.NewSlice(types.Types[TSTRING])) // *[]string + _ = types.NewPtr(types.NewSlice(types.Idealstring)) // *[]string + _ = types.NewPtr(types.NewPtr(types.NewPtr(types.Types[TUINT8]))) // ***uint8 + _ = types.NewPtr(types.Types[TINT16]) // *int16 + _ = types.NewPtr(types.Types[TINT64]) // *int64 + _ = types.NewPtr(types.Errortype) // *error + types.NewPtrCacheEnabled = false + ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, types_, Ctxt, Debug['N'] == 0) if thearch.LinkArch.Name == "386" { ssaConfig.Set387(thearch.Use387) } @@ -143,8 +144,8 @@ func buildssa(fn *Node) *ssa.Func { s.labeledNodes = map[*Node]*ssaLabel{} s.fwdVars = map[*Node]*ssa.Value{} s.startmem = s.entryNewValue0(ssa.OpInitMem, ssa.TypeMem) - s.sp = s.entryNewValue0(ssa.OpSP, Types[TUINTPTR]) // TODO: use generic pointer type (unsafe.Pointer?) instead - s.sb = s.entryNewValue0(ssa.OpSB, Types[TUINTPTR]) + s.sp = s.entryNewValue0(ssa.OpSP, types.Types[TUINTPTR]) // TODO: use generic pointer type (unsafe.Pointer?) instead + s.sb = s.entryNewValue0(ssa.OpSB, types.Types[TUINTPTR]) s.startBlock(s.f.Entry) s.vars[&memVar] = s.startmem @@ -157,7 +158,7 @@ func buildssa(fn *Node) *ssa.Func { switch n.Class { case PPARAM, PPARAMOUT: aux := s.lookupSymbol(n, &ssa.ArgSymbol{Typ: n.Type, Node: n}) - s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, typPtr(n.Type), aux, s.sp) + s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), aux, s.sp) if n.Class == PPARAMOUT && s.canSSA(n) { // Save ssa-able PPARAMOUT variables so we can // store them back to the stack at the end of @@ -279,7 +280,7 @@ type ssaLabel struct { } // label returns the label associated with sym, creating it if necessary. -func (s *state) label(sym *Sym) *ssaLabel { +func (s *state) label(sym *types.Sym) *ssaLabel { lab := s.labels[sym.Name] if lab == nil { lab = new(ssaLabel) @@ -298,15 +299,15 @@ func (s *state) Debug_checknil() bool { return s. var ( // dummy node for the memory variable - memVar = Node{Op: ONAME, Class: Pxxx, Sym: &Sym{Name: "mem"}} + memVar = Node{Op: ONAME, Class: Pxxx, Sym: &types.Sym{Name: "mem"}} // dummy nodes for temporary variables - ptrVar = Node{Op: ONAME, Class: Pxxx, Sym: &Sym{Name: "ptr"}} - lenVar = Node{Op: ONAME, Class: Pxxx, Sym: &Sym{Name: "len"}} - newlenVar = Node{Op: ONAME, Class: Pxxx, Sym: &Sym{Name: "newlen"}} - capVar = Node{Op: ONAME, Class: Pxxx, Sym: &Sym{Name: "cap"}} - typVar = Node{Op: ONAME, Class: Pxxx, Sym: &Sym{Name: "typ"}} - okVar = Node{Op: ONAME, Class: Pxxx, Sym: &Sym{Name: "ok"}} + ptrVar = Node{Op: ONAME, Class: Pxxx, Sym: &types.Sym{Name: "ptr"}} + lenVar = Node{Op: ONAME, Class: Pxxx, Sym: &types.Sym{Name: "len"}} + newlenVar = Node{Op: ONAME, Class: Pxxx, Sym: &types.Sym{Name: "newlen"}} + capVar = Node{Op: ONAME, Class: Pxxx, Sym: &types.Sym{Name: "cap"}} + typVar = Node{Op: ONAME, Class: Pxxx, Sym: &types.Sym{Name: "typ"}} + okVar = Node{Op: ONAME, Class: Pxxx, Sym: &types.Sym{Name: "ok"}} ) // startBlock sets the current block we're generating code in to b. @@ -463,7 +464,7 @@ func (s *state) constInterface(t ssa.Type) *ssa.Value { return s.f.ConstInterf func (s *state) constNil(t ssa.Type) *ssa.Value { return s.f.ConstNil(s.peekPos(), t) } func (s *state) constEmptyString(t ssa.Type) *ssa.Value { return s.f.ConstEmptyString(s.peekPos(), t) } func (s *state) constBool(c bool) *ssa.Value { - return s.f.ConstBool(s.peekPos(), Types[TBOOL], c) + return s.f.ConstBool(s.peekPos(), types.Types[TBOOL], c) } func (s *state) constInt8(t ssa.Type, c int8) *ssa.Value { return s.f.ConstInt8(s.peekPos(), t, c) @@ -633,7 +634,7 @@ func (s *state) stmt(n *Node) { return } - var t *Type + var t *types.Type if n.Right != nil { t = n.Right.Type } else { @@ -949,7 +950,7 @@ func (s *state) exit() *ssa.Block { type opAndType struct { op Op - etype EType + etype types.EType } var opToSSA = map[opAndType]ssa.Op{ @@ -1150,7 +1151,7 @@ var opToSSA = map[opAndType]ssa.Op{ opAndType{OGE, TFLOAT32}: ssa.OpGeq32F, } -func (s *state) concreteEtype(t *Type) EType { +func (s *state) concreteEtype(t *types.Type) types.EType { e := t.Etype switch e { default: @@ -1173,7 +1174,7 @@ func (s *state) concreteEtype(t *Type) EType { } } -func (s *state) ssaOp(op Op, t *Type) ssa.Op { +func (s *state) ssaOp(op Op, t *types.Type) ssa.Op { etype := s.concreteEtype(t) x, ok := opToSSA[opAndType{op, etype}] if !ok { @@ -1182,29 +1183,29 @@ func (s *state) ssaOp(op Op, t *Type) ssa.Op { return x } -func floatForComplex(t *Type) *Type { +func floatForComplex(t *types.Type) *types.Type { if t.Size() == 8 { - return Types[TFLOAT32] + return types.Types[TFLOAT32] } else { - return Types[TFLOAT64] + return types.Types[TFLOAT64] } } type opAndTwoTypes struct { op Op - etype1 EType - etype2 EType + etype1 types.EType + etype2 types.EType } type twoTypes struct { - etype1 EType - etype2 EType + etype1 types.EType + etype2 types.EType } type twoOpsAndType struct { op1 ssa.Op op2 ssa.Op - intermediateType EType + intermediateType types.EType } var fpConvOpToSSA = map[twoTypes]twoOpsAndType{ @@ -1347,7 +1348,7 @@ var shiftOpToSSA = map[opAndTwoTypes]ssa.Op{ opAndTwoTypes{ORSH, TUINT64, TUINT64}: ssa.OpRsh64Ux64, } -func (s *state) ssaShiftOp(op Op, t *Type, u *Type) ssa.Op { +func (s *state) ssaShiftOp(op Op, t *types.Type, u *types.Type) ssa.Op { etype1 := s.concreteEtype(t) etype2 := s.concreteEtype(u) x, ok := shiftOpToSSA[opAndTwoTypes{op, etype1, etype2}] @@ -1371,12 +1372,12 @@ func (s *state) expr(n *Node) *ssa.Value { case OARRAYBYTESTRTMP: slice := s.expr(n.Left) ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, slice) - len := s.newValue1(ssa.OpSliceLen, Types[TINT], slice) + len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], slice) return s.newValue2(ssa.OpStringMake, n.Type, ptr, len) case OSTRARRAYBYTETMP: str := s.expr(n.Left) ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, str) - len := s.newValue1(ssa.OpStringLen, Types[TINT], str) + len := s.newValue1(ssa.OpStringLen, types.Types[TINT], str) return s.newValue3(ssa.OpSliceMake, n.Type, ptr, len, len) case OCFUNC: aux := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: n.Type, Sym: Linksym(n.Left.Sym)}) @@ -1386,7 +1387,7 @@ func (s *state) expr(n *Node) *ssa.Value { // "value" of a function is the address of the function's closure sym := Linksym(funcsym(n.Sym)) aux := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: n.Type, Sym: sym}) - return s.entryNewValue1A(ssa.OpAddr, typPtr(n.Type), aux, s.sb) + return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), aux, s.sb) } if s.canSSA(n) { return s.variable(n, n.Type) @@ -1445,12 +1446,12 @@ func (s *state) expr(n *Node) *ssa.Value { i := &u.Imag switch n.Type.Size() { case 8: - pt := Types[TFLOAT32] + pt := types.Types[TFLOAT32] return s.newValue2(ssa.OpComplexMake, n.Type, s.constFloat32(pt, r.Float32()), s.constFloat32(pt, i.Float32())) case 16: - pt := Types[TFLOAT64] + pt := types.Types[TFLOAT64] return s.newValue2(ssa.OpComplexMake, n.Type, s.constFloat64(pt, r.Float64()), s.constFloat64(pt, i.Float64())) @@ -1641,7 +1642,7 @@ func (s *state) expr(n *Node) *ssa.Value { if op2 == ssa.OpCopy { return s.newValue1(op1, n.Type, x) } - return s.newValue1(op2, n.Type, s.newValue1(op1, Types[it], x)) + return s.newValue1(op2, n.Type, s.newValue1(op1, types.Types[it], x)) } // Tricky 64-bit unsigned cases. if ft.IsInteger() { @@ -1704,19 +1705,19 @@ func (s *state) expr(n *Node) *ssa.Value { if n.Left.Type.IsComplex() { pt := floatForComplex(n.Left.Type) op := s.ssaOp(OEQ, pt) - r := s.newValue2(op, Types[TBOOL], s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b)) - i := s.newValue2(op, Types[TBOOL], s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b)) - c := s.newValue2(ssa.OpAndB, Types[TBOOL], r, i) + r := s.newValue2(op, types.Types[TBOOL], s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b)) + i := s.newValue2(op, types.Types[TBOOL], s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b)) + c := s.newValue2(ssa.OpAndB, types.Types[TBOOL], r, i) switch n.Op { case OEQ: return c case ONE: - return s.newValue1(ssa.OpNot, Types[TBOOL], c) + return s.newValue1(ssa.OpNot, types.Types[TBOOL], c) default: s.Fatalf("ordered complex compare %v", n.Op) } } - return s.newValue2(s.ssaOp(n.Op, n.Left.Type), Types[TBOOL], a, b) + return s.newValue2(s.ssaOp(n.Op, n.Left.Type), types.Types[TBOOL], a, b) case OMUL: a := s.expr(n.Left) b := s.expr(n.Right) @@ -1725,7 +1726,7 @@ func (s *state) expr(n *Node) *ssa.Value { addop := ssa.OpAdd64F subop := ssa.OpSub64F pt := floatForComplex(n.Type) // Could be Float32 or Float64 - wt := Types[TFLOAT64] // Compute in Float64 to minimize cancelation error + wt := types.Types[TFLOAT64] // Compute in Float64 to minimize cancelation error areal := s.newValue1(ssa.OpComplexReal, pt, a) breal := s.newValue1(ssa.OpComplexReal, pt, b) @@ -1763,7 +1764,7 @@ func (s *state) expr(n *Node) *ssa.Value { subop := ssa.OpSub64F divop := ssa.OpDiv64F pt := floatForComplex(n.Type) // Could be Float32 or Float64 - wt := Types[TFLOAT64] // Compute in Float64 to minimize cancelation error + wt := types.Types[TFLOAT64] // Compute in Float64 to minimize cancelation error areal := s.newValue1(ssa.OpComplexReal, pt, a) breal := s.newValue1(ssa.OpComplexReal, pt, b) @@ -1864,7 +1865,7 @@ func (s *state) expr(n *Node) *ssa.Value { b.AddEdgeTo(bResult) s.startBlock(bResult) - return s.variable(n, Types[TBOOL]) + return s.variable(n, types.Types[TBOOL]) case OCOMPLEX: r := s.expr(n.Left) i := s.expr(n.Right) @@ -1894,7 +1895,7 @@ func (s *state) expr(n *Node) *ssa.Value { return s.addr(n.Left, n.Bounded()) case OINDREGSP: - addr := s.constOffPtrSP(typPtr(n.Type), n.Xoffset) + addr := s.constOffPtrSP(types.NewPtr(n.Type), n.Xoffset) return s.newValue2(ssa.OpLoad, n.Type, addr, s.mem()) case OIND: @@ -1921,7 +1922,7 @@ func (s *state) expr(n *Node) *ssa.Value { case ODOTPTR: p := s.exprPtr(n.Left, false, n.Pos) - p = s.newValue1I(ssa.OpOffPtr, typPtr(n.Type), n.Xoffset, p) + p = s.newValue1I(ssa.OpOffPtr, types.NewPtr(n.Type), n.Xoffset, p) return s.newValue2(ssa.OpLoad, n.Type, p, s.mem()) case OINDEX: @@ -1931,13 +1932,13 @@ func (s *state) expr(n *Node) *ssa.Value { // Replace "abc"[1] with 'b'. // Delayed until now because "abc"[1] is not an ideal constant. // See test/fixedbugs/issue11370.go. - return s.newValue0I(ssa.OpConst8, Types[TUINT8], int64(int8(n.Left.Val().U.(string)[n.Right.Int64()]))) + return s.newValue0I(ssa.OpConst8, types.Types[TUINT8], int64(int8(n.Left.Val().U.(string)[n.Right.Int64()]))) } a := s.expr(n.Left) i := s.expr(n.Right) i = s.extendIndex(i, panicindex) if !n.Bounded() { - len := s.newValue1(ssa.OpStringLen, Types[TINT], a) + len := s.newValue1(ssa.OpStringLen, types.Types[TINT], a) s.boundsCheck(i, len) } ptrtyp := s.f.Config.Types.BytePtr @@ -1947,7 +1948,7 @@ func (s *state) expr(n *Node) *ssa.Value { } else { ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i) } - return s.newValue2(ssa.OpLoad, Types[TUINT8], ptr, s.mem()) + return s.newValue2(ssa.OpLoad, types.Types[TUINT8], ptr, s.mem()) case n.Left.Type.IsSlice(): p := s.addr(n, false) return s.newValue2(ssa.OpLoad, n.Left.Type.Elem(), p, s.mem()) @@ -1959,14 +1960,14 @@ func (s *state) expr(n *Node) *ssa.Value { if bound == 0 { // Bounds check will never succeed. Might as well // use constants for the bounds check. - z := s.constInt(Types[TINT], 0) + z := s.constInt(types.Types[TINT], 0) s.boundsCheck(z, z) // The return value won't be live, return junk. return s.newValue0(ssa.OpUnknown, n.Type) } i = s.extendIndex(i, panicindex) if !n.Bounded() { - s.boundsCheck(i, s.constInt(Types[TINT], bound)) + s.boundsCheck(i, s.constInt(types.Types[TINT], bound)) } return s.newValue1I(ssa.OpArraySelect, n.Type, 0, a) } @@ -1984,13 +1985,13 @@ func (s *state) expr(n *Node) *ssa.Value { if n.Op == OCAP { op = ssa.OpSliceCap } - return s.newValue1(op, Types[TINT], s.expr(n.Left)) + return s.newValue1(op, types.Types[TINT], s.expr(n.Left)) case n.Left.Type.IsString(): // string; not reachable for OCAP - return s.newValue1(ssa.OpStringLen, Types[TINT], s.expr(n.Left)) + return s.newValue1(ssa.OpStringLen, types.Types[TINT], s.expr(n.Left)) case n.Left.Type.IsMap(), n.Left.Type.IsChan(): return s.referenceTypeBuiltin(n, s.expr(n.Left)) default: // array - return s.constInt(Types[TINT], n.Left.Type.NumElem()) + return s.constInt(types.Types[TINT], n.Left.Type.NumElem()) } case OSPTR: @@ -2115,7 +2116,7 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value { // *(ptr+len+2) = e3 et := n.Type.Elem() - pt := typPtr(et) + pt := types.NewPtr(et) // Evaluate slice sn := n.List.First() // the slice node is the first in the list @@ -2135,11 +2136,11 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value { // Decide if we need to grow nargs := int64(n.List.Len() - 1) p := s.newValue1(ssa.OpSlicePtr, pt, slice) - l := s.newValue1(ssa.OpSliceLen, Types[TINT], slice) - c := s.newValue1(ssa.OpSliceCap, Types[TINT], slice) - nl := s.newValue2(s.ssaOp(OADD, Types[TINT]), Types[TINT], l, s.constInt(Types[TINT], nargs)) + l := s.newValue1(ssa.OpSliceLen, types.Types[TINT], slice) + c := s.newValue1(ssa.OpSliceCap, types.Types[TINT], slice) + nl := s.newValue2(s.ssaOp(OADD, types.Types[TINT]), types.Types[TINT], l, s.constInt(types.Types[TINT], nargs)) - cmp := s.newValue2(s.ssaOp(OGT, Types[TINT]), Types[TBOOL], nl, c) + cmp := s.newValue2(s.ssaOp(OGT, types.Types[TINT]), types.Types[TBOOL], nl, c) s.vars[&ptrVar] = p if !inplace { @@ -2159,7 +2160,7 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value { // Call growslice s.startBlock(grow) taddr := s.expr(n.Left) - r := s.rtcall(growslice, true, []*Type{pt, Types[TINT], Types[TINT]}, taddr, p, l, c, nl) + r := s.rtcall(growslice, true, []*types.Type{pt, types.Types[TINT], types.Types[TINT]}, taddr, p, l, c, nl) if inplace { if sn.Op == ONAME { @@ -2167,14 +2168,14 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value { s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, sn, s.mem()) } capaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, int64(array_cap), addr) - s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], capaddr, r[2], s.mem()) + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, types.Types[TINT], capaddr, r[2], s.mem()) s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, pt, addr, r[0], s.mem()) // load the value we just stored to avoid having to spill it s.vars[&ptrVar] = s.newValue2(ssa.OpLoad, pt, addr, s.mem()) s.vars[&lenVar] = r[1] // avoid a spill in the fast path } else { s.vars[&ptrVar] = r[0] - s.vars[&newlenVar] = s.newValue2(s.ssaOp(OADD, Types[TINT]), Types[TINT], r[1], s.constInt(Types[TINT], nargs)) + s.vars[&newlenVar] = s.newValue2(s.ssaOp(OADD, types.Types[TINT]), types.Types[TINT], r[1], s.constInt(types.Types[TINT], nargs)) s.vars[&capVar] = r[2] } @@ -2185,10 +2186,10 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value { s.startBlock(assign) if inplace { - l = s.variable(&lenVar, Types[TINT]) // generates phi for len - nl = s.newValue2(s.ssaOp(OADD, Types[TINT]), Types[TINT], l, s.constInt(Types[TINT], nargs)) + l = s.variable(&lenVar, types.Types[TINT]) // generates phi for len + nl = s.newValue2(s.ssaOp(OADD, types.Types[TINT]), types.Types[TINT], l, s.constInt(types.Types[TINT], nargs)) lenaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, int64(array_nel), addr) - s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], lenaddr, nl, s.mem()) + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, types.Types[TINT], lenaddr, nl, s.mem()) } // Evaluate args @@ -2210,12 +2211,12 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value { p = s.variable(&ptrVar, pt) // generates phi for ptr if !inplace { - nl = s.variable(&newlenVar, Types[TINT]) // generates phi for nl - c = s.variable(&capVar, Types[TINT]) // generates phi for cap + nl = s.variable(&newlenVar, types.Types[TINT]) // generates phi for nl + c = s.variable(&capVar, types.Types[TINT]) // generates phi for cap } p2 := s.newValue2(ssa.OpPtrIndex, pt, p, l) for i, arg := range args { - addr := s.newValue2(ssa.OpPtrIndex, pt, p2, s.constInt(Types[TINT], int64(i))) + addr := s.newValue2(ssa.OpPtrIndex, pt, p2, s.constInt(types.Types[TINT], int64(i))) if arg.store { s.storeType(et, addr, arg.v, 0) } else { @@ -2348,7 +2349,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask) if n == 0 { // The bounds check must fail. Might as well // ignore the actual index and just use zeros. - z := s.constInt(Types[TINT], 0) + z := s.constInt(types.Types[TINT], 0) s.boundsCheck(z, z) return } @@ -2357,7 +2358,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask) } // Rewrite to a = [1]{v} i = s.extendIndex(i, panicindex) - s.boundsCheck(i, s.constInt(Types[TINT], 1)) + s.boundsCheck(i, s.constInt(types.Types[TINT], 1)) v := s.newValue1(ssa.OpArrayMake1, t, right) s.assign(left.Left, v, false, 0) return @@ -2378,7 +2379,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask) // is valid, even though they have type uintptr (#19168). // Mark it pointer type to signal the writebarrier pass to // insert a write barrier. - t = Types[TUNSAFEPTR] + t = types.Types[TUNSAFEPTR] } if deref { // Treat as a mem->mem move. @@ -2397,7 +2398,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask) } // zeroVal returns the zero value for type t. -func (s *state) zeroVal(t *Type) *ssa.Value { +func (s *state) zeroVal(t *types.Type) *ssa.Value { switch { case t.IsInteger(): switch t.Size() { @@ -2424,10 +2425,10 @@ func (s *state) zeroVal(t *Type) *ssa.Value { case t.IsComplex(): switch t.Size() { case 8: - z := s.constFloat32(Types[TFLOAT32], 0) + z := s.constFloat32(types.Types[TFLOAT32], 0) return s.entryNewValue2(ssa.OpComplexMake, t, z, z) case 16: - z := s.constFloat64(Types[TFLOAT64], 0) + z := s.constFloat64(types.Types[TFLOAT64], 0) return s.entryNewValue2(ssa.OpComplexMake, t, z, z) default: s.Fatalf("bad sized complex type %v", t) @@ -2447,7 +2448,7 @@ func (s *state) zeroVal(t *Type) *ssa.Value { n := t.NumFields() v := s.entryNewValue0(ssa.StructMakeOp(t.NumFields()), t) for i := 0; i < n; i++ { - v.AddArg(s.zeroVal(t.FieldType(i).(*Type))) + v.AddArg(s.zeroVal(t.FieldType(i).(*types.Type))) } return v case t.IsArray(): @@ -2543,7 +2544,7 @@ func init() { // when not instrumenting. slice := args[0] ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, slice) - len := s.newValue1(ssa.OpSliceLen, Types[TINT], slice) + len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], slice) return s.newValue2(ssa.OpStringMake, n.Type, ptr, len) }, all...) @@ -2559,39 +2560,39 @@ func init() { /******** runtime/internal/sys ********/ addF("runtime/internal/sys", "Ctz32", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpCtz32, Types[TINT], args[0]) + return s.newValue1(ssa.OpCtz32, types.Types[TINT], args[0]) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS) addF("runtime/internal/sys", "Ctz64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpCtz64, Types[TINT], args[0]) + return s.newValue1(ssa.OpCtz64, types.Types[TINT], args[0]) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS) addF("runtime/internal/sys", "Bswap32", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpBswap32, Types[TUINT32], args[0]) + return s.newValue1(ssa.OpBswap32, types.Types[TUINT32], args[0]) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X) addF("runtime/internal/sys", "Bswap64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpBswap64, Types[TUINT64], args[0]) + return s.newValue1(ssa.OpBswap64, types.Types[TUINT64], args[0]) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X) /******** runtime/internal/atomic ********/ addF("runtime/internal/atomic", "Load", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue2(ssa.OpAtomicLoad32, ssa.MakeTuple(Types[TUINT32], ssa.TypeMem), args[0], s.mem()) + v := s.newValue2(ssa.OpAtomicLoad32, ssa.MakeTuple(types.Types[TUINT32], ssa.TypeMem), args[0], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v) - return s.newValue1(ssa.OpSelect0, Types[TUINT32], v) + return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v) }, sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64) addF("runtime/internal/atomic", "Load64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue2(ssa.OpAtomicLoad64, ssa.MakeTuple(Types[TUINT64], ssa.TypeMem), args[0], s.mem()) + v := s.newValue2(ssa.OpAtomicLoad64, ssa.MakeTuple(types.Types[TUINT64], ssa.TypeMem), args[0], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v) - return s.newValue1(ssa.OpSelect0, Types[TUINT64], v) + return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v) }, sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64) addF("runtime/internal/atomic", "Loadp", @@ -2623,46 +2624,46 @@ func init() { addF("runtime/internal/atomic", "Xchg", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue3(ssa.OpAtomicExchange32, ssa.MakeTuple(Types[TUINT32], ssa.TypeMem), args[0], args[1], s.mem()) + v := s.newValue3(ssa.OpAtomicExchange32, ssa.MakeTuple(types.Types[TUINT32], ssa.TypeMem), args[0], args[1], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v) - return s.newValue1(ssa.OpSelect0, Types[TUINT32], v) + return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v) }, sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64) addF("runtime/internal/atomic", "Xchg64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue3(ssa.OpAtomicExchange64, ssa.MakeTuple(Types[TUINT64], ssa.TypeMem), args[0], args[1], s.mem()) + v := s.newValue3(ssa.OpAtomicExchange64, ssa.MakeTuple(types.Types[TUINT64], ssa.TypeMem), args[0], args[1], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v) - return s.newValue1(ssa.OpSelect0, Types[TUINT64], v) + return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v) }, sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64) addF("runtime/internal/atomic", "Xadd", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue3(ssa.OpAtomicAdd32, ssa.MakeTuple(Types[TUINT32], ssa.TypeMem), args[0], args[1], s.mem()) + v := s.newValue3(ssa.OpAtomicAdd32, ssa.MakeTuple(types.Types[TUINT32], ssa.TypeMem), args[0], args[1], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v) - return s.newValue1(ssa.OpSelect0, Types[TUINT32], v) + return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v) }, sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64) addF("runtime/internal/atomic", "Xadd64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue3(ssa.OpAtomicAdd64, ssa.MakeTuple(Types[TUINT64], ssa.TypeMem), args[0], args[1], s.mem()) + v := s.newValue3(ssa.OpAtomicAdd64, ssa.MakeTuple(types.Types[TUINT64], ssa.TypeMem), args[0], args[1], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v) - return s.newValue1(ssa.OpSelect0, Types[TUINT64], v) + return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v) }, sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64) addF("runtime/internal/atomic", "Cas", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue4(ssa.OpAtomicCompareAndSwap32, ssa.MakeTuple(Types[TBOOL], ssa.TypeMem), args[0], args[1], args[2], s.mem()) + v := s.newValue4(ssa.OpAtomicCompareAndSwap32, ssa.MakeTuple(types.Types[TBOOL], ssa.TypeMem), args[0], args[1], args[2], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v) - return s.newValue1(ssa.OpSelect0, Types[TBOOL], v) + return s.newValue1(ssa.OpSelect0, types.Types[TBOOL], v) }, sys.AMD64, sys.ARM64, sys.S390X, sys.MIPS, sys.PPC64) addF("runtime/internal/atomic", "Cas64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - v := s.newValue4(ssa.OpAtomicCompareAndSwap64, ssa.MakeTuple(Types[TBOOL], ssa.TypeMem), args[0], args[1], args[2], s.mem()) + v := s.newValue4(ssa.OpAtomicCompareAndSwap64, ssa.MakeTuple(types.Types[TBOOL], ssa.TypeMem), args[0], args[1], args[2], s.mem()) s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v) - return s.newValue1(ssa.OpSelect0, Types[TBOOL], v) + return s.newValue1(ssa.OpSelect0, types.Types[TBOOL], v) }, sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64) @@ -2699,51 +2700,51 @@ func init() { /******** math ********/ addF("math", "Sqrt", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpSqrt, Types[TFLOAT64], args[0]) + return s.newValue1(ssa.OpSqrt, types.Types[TFLOAT64], args[0]) }, sys.AMD64, sys.ARM, sys.ARM64, sys.MIPS, sys.PPC64, sys.S390X) /******** math/bits ********/ addF("math/bits", "TrailingZeros64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpCtz64, Types[TINT], args[0]) + return s.newValue1(ssa.OpCtz64, types.Types[TINT], args[0]) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS) addF("math/bits", "TrailingZeros32", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpCtz32, Types[TINT], args[0]) + return s.newValue1(ssa.OpCtz32, types.Types[TINT], args[0]) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS) addF("math/bits", "TrailingZeros16", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - x := s.newValue1(ssa.OpZeroExt16to32, Types[TUINT32], args[0]) - c := s.constInt32(Types[TUINT32], 1<<16) - y := s.newValue2(ssa.OpOr32, Types[TUINT32], x, c) - return s.newValue1(ssa.OpCtz32, Types[TINT], y) + x := s.newValue1(ssa.OpZeroExt16to32, types.Types[TUINT32], args[0]) + c := s.constInt32(types.Types[TUINT32], 1<<16) + y := s.newValue2(ssa.OpOr32, types.Types[TUINT32], x, c) + return s.newValue1(ssa.OpCtz32, types.Types[TINT], y) }, sys.ARM, sys.MIPS) addF("math/bits", "TrailingZeros16", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - x := s.newValue1(ssa.OpZeroExt16to64, Types[TUINT64], args[0]) - c := s.constInt64(Types[TUINT64], 1<<16) - y := s.newValue2(ssa.OpOr64, Types[TUINT64], x, c) - return s.newValue1(ssa.OpCtz64, Types[TINT], y) + x := s.newValue1(ssa.OpZeroExt16to64, types.Types[TUINT64], args[0]) + c := s.constInt64(types.Types[TUINT64], 1<<16) + y := s.newValue2(ssa.OpOr64, types.Types[TUINT64], x, c) + return s.newValue1(ssa.OpCtz64, types.Types[TINT], y) }, sys.AMD64, sys.ARM64, sys.S390X) addF("math/bits", "TrailingZeros8", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - x := s.newValue1(ssa.OpZeroExt8to32, Types[TUINT32], args[0]) - c := s.constInt32(Types[TUINT32], 1<<8) - y := s.newValue2(ssa.OpOr32, Types[TUINT32], x, c) - return s.newValue1(ssa.OpCtz32, Types[TINT], y) + x := s.newValue1(ssa.OpZeroExt8to32, types.Types[TUINT32], args[0]) + c := s.constInt32(types.Types[TUINT32], 1<<8) + y := s.newValue2(ssa.OpOr32, types.Types[TUINT32], x, c) + return s.newValue1(ssa.OpCtz32, types.Types[TINT], y) }, sys.ARM, sys.MIPS) addF("math/bits", "TrailingZeros8", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - x := s.newValue1(ssa.OpZeroExt8to64, Types[TUINT64], args[0]) - c := s.constInt64(Types[TUINT64], 1<<8) - y := s.newValue2(ssa.OpOr64, Types[TUINT64], x, c) - return s.newValue1(ssa.OpCtz64, Types[TINT], y) + x := s.newValue1(ssa.OpZeroExt8to64, types.Types[TUINT64], args[0]) + c := s.constInt64(types.Types[TUINT64], 1<<8) + y := s.newValue2(ssa.OpOr64, types.Types[TUINT64], x, c) + return s.newValue1(ssa.OpCtz64, types.Types[TINT], y) }, sys.AMD64, sys.ARM64, sys.S390X) alias("math/bits", "ReverseBytes64", "runtime/internal/sys", "Bswap64", all...) @@ -2752,82 +2753,82 @@ func init() { // ReverseBytes16 lowers to a rotate, no need for anything special here. addF("math/bits", "Len64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpBitLen64, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitLen64, types.Types[TINT], args[0]) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS) addF("math/bits", "Len32", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { if s.config.IntSize == 4 { - return s.newValue1(ssa.OpBitLen32, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitLen32, types.Types[TINT], args[0]) } - x := s.newValue1(ssa.OpZeroExt32to64, Types[TUINT64], args[0]) - return s.newValue1(ssa.OpBitLen64, Types[TINT], x) + x := s.newValue1(ssa.OpZeroExt32to64, types.Types[TUINT64], args[0]) + return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS) addF("math/bits", "Len16", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { if s.config.IntSize == 4 { - x := s.newValue1(ssa.OpZeroExt16to32, Types[TUINT32], args[0]) - return s.newValue1(ssa.OpBitLen32, Types[TINT], x) + x := s.newValue1(ssa.OpZeroExt16to32, types.Types[TUINT32], args[0]) + return s.newValue1(ssa.OpBitLen32, types.Types[TINT], x) } - x := s.newValue1(ssa.OpZeroExt16to64, Types[TUINT64], args[0]) - return s.newValue1(ssa.OpBitLen64, Types[TINT], x) + x := s.newValue1(ssa.OpZeroExt16to64, types.Types[TUINT64], args[0]) + return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS) // Note: disabled on AMD64 because the Go code is faster! addF("math/bits", "Len8", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { if s.config.IntSize == 4 { - x := s.newValue1(ssa.OpZeroExt8to32, Types[TUINT32], args[0]) - return s.newValue1(ssa.OpBitLen32, Types[TINT], x) + x := s.newValue1(ssa.OpZeroExt8to32, types.Types[TUINT32], args[0]) + return s.newValue1(ssa.OpBitLen32, types.Types[TINT], x) } - x := s.newValue1(ssa.OpZeroExt8to64, Types[TUINT64], args[0]) - return s.newValue1(ssa.OpBitLen64, Types[TINT], x) + x := s.newValue1(ssa.OpZeroExt8to64, types.Types[TUINT64], args[0]) + return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x) }, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS) addF("math/bits", "Len", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { if s.config.IntSize == 4 { - return s.newValue1(ssa.OpBitLen32, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitLen32, types.Types[TINT], args[0]) } - return s.newValue1(ssa.OpBitLen64, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitLen64, types.Types[TINT], args[0]) }, sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS) // LeadingZeros is handled because it trivially calls Len. addF("math/bits", "Reverse64", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpBitRev64, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitRev64, types.Types[TINT], args[0]) }, sys.ARM64) addF("math/bits", "Reverse32", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpBitRev32, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitRev32, types.Types[TINT], args[0]) }, sys.ARM64) addF("math/bits", "Reverse16", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpBitRev16, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitRev16, types.Types[TINT], args[0]) }, sys.ARM64) addF("math/bits", "Reverse8", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue1(ssa.OpBitRev8, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitRev8, types.Types[TINT], args[0]) }, sys.ARM64) addF("math/bits", "Reverse", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { if s.config.IntSize == 4 { - return s.newValue1(ssa.OpBitRev32, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitRev32, types.Types[TINT], args[0]) } - return s.newValue1(ssa.OpBitRev64, Types[TINT], args[0]) + return s.newValue1(ssa.OpBitRev64, types.Types[TINT], args[0]) }, sys.ARM64) makeOnesCount := func(op64 ssa.Op, op32 ssa.Op) func(s *state, n *Node, args []*ssa.Value) *ssa.Value { return func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - aux := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: Types[TBOOL], Sym: Linksym(syslook("support_popcnt").Sym)}) - addr := s.entryNewValue1A(ssa.OpAddr, Types[TBOOL].PtrTo(), aux, s.sb) - v := s.newValue2(ssa.OpLoad, Types[TBOOL], addr, s.mem()) + aux := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: types.Types[TBOOL], Sym: Linksym(syslook("support_popcnt").Sym)}) + addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), aux, s.sb) + v := s.newValue2(ssa.OpLoad, types.Types[TBOOL], addr, s.mem()) b := s.endBlock() b.Kind = ssa.BlockIf b.SetControl(v) @@ -2844,18 +2845,18 @@ func init() { if s.config.IntSize == 4 { op = op32 } - s.vars[n] = s.newValue1(op, Types[TINT], args[0]) + s.vars[n] = s.newValue1(op, types.Types[TINT], args[0]) s.endBlock().AddEdgeTo(bEnd) // Call the pure Go version. s.startBlock(bFalse) a := s.call(n, callNormal) - s.vars[n] = s.newValue2(ssa.OpLoad, Types[TINT], a, s.mem()) + s.vars[n] = s.newValue2(ssa.OpLoad, types.Types[TINT], a, s.mem()) s.endBlock().AddEdgeTo(bEnd) // Merge results. s.startBlock(bEnd) - return s.variable(n, Types[TINT]) + return s.variable(n, types.Types[TINT]) } } addF("math/bits", "OnesCount64", @@ -2915,19 +2916,19 @@ func init() { /******** math/big ********/ add("math/big", "mulWW", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue2(ssa.OpMul64uhilo, ssa.MakeTuple(Types[TUINT64], Types[TUINT64]), args[0], args[1]) + return s.newValue2(ssa.OpMul64uhilo, ssa.MakeTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1]) }, sys.ArchAMD64) add("math/big", "divWW", func(s *state, n *Node, args []*ssa.Value) *ssa.Value { - return s.newValue3(ssa.OpDiv128u, ssa.MakeTuple(Types[TUINT64], Types[TUINT64]), args[0], args[1], args[2]) + return s.newValue3(ssa.OpDiv128u, ssa.MakeTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2]) }, sys.ArchAMD64) } // findIntrinsic returns a function which builds the SSA equivalent of the // function identified by the symbol sym. If sym is not an intrinsic call, returns nil. -func findIntrinsic(sym *Sym) intrinsicBuilder { +func findIntrinsic(sym *types.Sym) intrinsicBuilder { if ssa.IntrinsicsDisable { return nil } @@ -3028,7 +3029,7 @@ func (s *state) intrinsicArgs(n *Node) []*ssa.Value { // Calls the function n using the specified call type. // Returns the address of the return value (or nil if none). func (s *state) call(n *Node, k callKind) *ssa.Value { - var sym *Sym // target symbol (if static) + var sym *types.Sym // target symbol (if static) var closure *ssa.Value // ptr to closure to run (if dynamic) var codeptr *ssa.Value // ptr to target code (if dynamic) var rcvr *ssa.Value // receiver to set @@ -3057,7 +3058,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { n2.Name.Curfn = s.curfn n2.Class = PFUNC n2.Pos = fn.Pos - n2.Type = Types[TUINT8] // dummy type for a static closure. Could use runtime.funcval if we had it. + n2.Type = types.Types[TUINT8] // dummy type for a static closure. Could use runtime.funcval if we had it. closure = s.expr(n2) // Note: receiver is already assigned in n.List, so we don't // want to set it here. @@ -3066,18 +3067,18 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op) } i := s.expr(fn.Left) - itab := s.newValue1(ssa.OpITab, Types[TUINTPTR], i) + itab := s.newValue1(ssa.OpITab, types.Types[TUINTPTR], i) if k != callNormal { s.nilCheck(itab) } itabidx := fn.Xoffset + 3*int64(Widthptr) + 8 // offset of fun field in runtime.itab itab = s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.UintptrPtr, itabidx, itab) if k == callNormal { - codeptr = s.newValue2(ssa.OpLoad, Types[TUINTPTR], itab, s.mem()) + codeptr = s.newValue2(ssa.OpLoad, types.Types[TUINTPTR], itab, s.mem()) } else { closure = itab } - rcvr = s.newValue1(ssa.OpIData, Types[TUINTPTR], i) + rcvr = s.newValue1(ssa.OpIData, types.Types[TUINTPTR], i) } dowidth(fn.Type) stksize := fn.Type.ArgWidth() // includes receiver @@ -3095,18 +3096,18 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { argStart += int64(2 * Widthptr) } addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart) - s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TUINTPTR], addr, rcvr, s.mem()) + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, types.Types[TUINTPTR], addr, rcvr, s.mem()) } // Defer/go args if k != callNormal { // Write argsize and closure (args to Newproc/Deferproc). argStart := Ctxt.FixedFrameSize() - argsize := s.constInt32(Types[TUINT32], int32(stksize)) + argsize := s.constInt32(types.Types[TUINT32], int32(stksize)) addr := s.constOffPtrSP(s.f.Config.Types.UInt32Ptr, argStart) - s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TUINT32], addr, argsize, s.mem()) + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, types.Types[TUINT32], addr, argsize, s.mem()) addr = s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart+int64(Widthptr)) - s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TUINTPTR], addr, closure, s.mem()) + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, types.Types[TUINTPTR], addr, closure, s.mem()) stksize += 2 * int64(Widthptr) } @@ -3118,7 +3119,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { case k == callGo: call = s.newValue1A(ssa.OpStaticCall, ssa.TypeMem, Newproc, s.mem()) case closure != nil: - codeptr = s.newValue2(ssa.OpLoad, Types[TUINTPTR], closure, s.mem()) + codeptr = s.newValue2(ssa.OpLoad, types.Types[TUINTPTR], closure, s.mem()) call = s.newValue3(ssa.OpClosureCall, ssa.TypeMem, codeptr, closure, s.mem()) case codeptr != nil: call = s.newValue2(ssa.OpInterCall, ssa.TypeMem, codeptr, s.mem()) @@ -3152,12 +3153,12 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { return nil } fp := res.Field(0) - return s.constOffPtrSP(typPtr(fp.Type), fp.Offset+Ctxt.FixedFrameSize()) + return s.constOffPtrSP(types.NewPtr(fp.Type), fp.Offset+Ctxt.FixedFrameSize()) } // etypesign returns the signed-ness of e, for integer/pointer etypes. // -1 means signed, +1 means unsigned, 0 means non-integer/non-pointer. -func etypesign(e EType) int8 { +func etypesign(e types.EType) int8 { switch e { case TINT8, TINT16, TINT32, TINT64, TINT: return -1 @@ -3190,7 +3191,7 @@ func (s *state) lookupSymbol(n *Node, sym interface{}) interface{} { // If bounded is true then this address does not require a nil check for its operand // even if that would otherwise be implied. func (s *state) addr(n *Node, bounded bool) *ssa.Value { - t := typPtr(n.Type) + t := types.NewPtr(n.Type) switch n.Op { case ONAME: switch n.Class { @@ -3237,7 +3238,7 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value { a := s.expr(n.Left) i := s.expr(n.Right) i = s.extendIndex(i, panicindex) - len := s.newValue1(ssa.OpSliceLen, Types[TINT], a) + len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], a) if !n.Bounded() { s.boundsCheck(i, len) } @@ -3247,11 +3248,11 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value { a := s.addr(n.Left, bounded) i := s.expr(n.Right) i = s.extendIndex(i, panicindex) - len := s.constInt(Types[TINT], n.Left.Type.NumElem()) + len := s.constInt(types.Types[TINT], n.Left.Type.NumElem()) if !n.Bounded() { s.boundsCheck(i, len) } - return s.newValue2(ssa.OpPtrIndex, typPtr(n.Left.Type.Elem()), a, i) + return s.newValue2(ssa.OpPtrIndex, types.NewPtr(n.Left.Type.Elem()), a, i) } case OIND: return s.exprPtr(n.Left, bounded, n.Pos) @@ -3334,7 +3335,7 @@ func (s *state) canSSA(n *Node) bool { } // canSSA reports whether variables of type t are SSA-able. -func canSSAType(t *Type) bool { +func canSSAType(t *types.Type) bool { dowidth(t) if t.Width > int64(4*Widthptr) { // 4*Widthptr is an arbitrary constant. We want it @@ -3398,7 +3399,7 @@ func (s *state) boundsCheck(idx, len *ssa.Value) { } // bounds check - cmp := s.newValue2(ssa.OpIsInBounds, Types[TBOOL], idx, len) + cmp := s.newValue2(ssa.OpIsInBounds, types.Types[TBOOL], idx, len) s.check(cmp, panicindex) } @@ -3411,7 +3412,7 @@ func (s *state) sliceBoundsCheck(idx, len *ssa.Value) { } // bounds check - cmp := s.newValue2(ssa.OpIsSliceInBounds, Types[TBOOL], idx, len) + cmp := s.newValue2(ssa.OpIsSliceInBounds, types.Types[TBOOL], idx, len) s.check(cmp, panicslice) } @@ -3447,7 +3448,7 @@ func (s *state) intDivide(n *Node, a, b *ssa.Value) *ssa.Value { } if needcheck { // do a size-appropriate check for zero - cmp := s.newValue2(s.ssaOp(ONE, n.Type), Types[TBOOL], b, s.zeroVal(n.Type)) + cmp := s.newValue2(s.ssaOp(ONE, n.Type), types.Types[TBOOL], b, s.zeroVal(n.Type)) s.check(cmp, panicdivide) } return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b) @@ -3457,7 +3458,7 @@ func (s *state) intDivide(n *Node, a, b *ssa.Value) *ssa.Value { // Returns a slice of results of the given result types. // The call is added to the end of the current block. // If returns is false, the block is marked as an exit block. -func (s *state) rtcall(fn *obj.LSym, returns bool, results []*Type, args ...*ssa.Value) []*ssa.Value { +func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args ...*ssa.Value) []*ssa.Value { // Write args to the stack off := Ctxt.FixedFrameSize() for _, arg := range args { @@ -3494,7 +3495,7 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*Type, args ...*ssa res := make([]*ssa.Value, len(results)) for i, t := range results { off = Rnd(off, t.Alignment()) - ptr := s.constOffPtrSP(typPtr(t), off) + ptr := s.constOffPtrSP(types.NewPtr(t), off) res[i] = s.newValue2(ssa.OpLoad, t, ptr, s.mem()) off += t.Size() } @@ -3507,8 +3508,8 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*Type, args ...*ssa } // do *left = right for type t. -func (s *state) storeType(t *Type, left, right *ssa.Value, skip skipMask) { - if skip == 0 && (!haspointers(t) || ssa.IsStackAddr(left)) { +func (s *state) storeType(t *types.Type, left, right *ssa.Value, skip skipMask) { + if skip == 0 && (!types.Haspointers(t) || ssa.IsStackAddr(left)) { // Known to not have write barrier. Store the whole type. s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, t, left, right, s.mem()) return @@ -3520,13 +3521,13 @@ func (s *state) storeType(t *Type, left, right *ssa.Value, skip skipMask) { // TODO: if the writebarrier pass knows how to reorder stores, // we can do a single store here as long as skip==0. s.storeTypeScalars(t, left, right, skip) - if skip&skipPtr == 0 && haspointers(t) { + if skip&skipPtr == 0 && types.Haspointers(t) { s.storeTypePtrs(t, left, right) } } // do *left = right for all scalar (non-pointer) parts of t. -func (s *state) storeTypeScalars(t *Type, left, right *ssa.Value, skip skipMask) { +func (s *state) storeTypeScalars(t *types.Type, left, right *ssa.Value, skip skipMask) { switch { case t.IsBoolean() || t.IsInteger() || t.IsFloat() || t.IsComplex(): s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, t, left, right, s.mem()) @@ -3536,31 +3537,31 @@ func (s *state) storeTypeScalars(t *Type, left, right *ssa.Value, skip skipMask) if skip&skipLen != 0 { return } - len := s.newValue1(ssa.OpStringLen, Types[TINT], right) + len := s.newValue1(ssa.OpStringLen, types.Types[TINT], right) lenAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, s.config.IntSize, left) - s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], lenAddr, len, s.mem()) + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, types.Types[TINT], lenAddr, len, s.mem()) case t.IsSlice(): if skip&skipLen == 0 { - len := s.newValue1(ssa.OpSliceLen, Types[TINT], right) + len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], right) lenAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, s.config.IntSize, left) - s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], lenAddr, len, s.mem()) + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, types.Types[TINT], lenAddr, len, s.mem()) } if skip&skipCap == 0 { - cap := s.newValue1(ssa.OpSliceCap, Types[TINT], right) + cap := s.newValue1(ssa.OpSliceCap, types.Types[TINT], right) capAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, 2*s.config.IntSize, left) - s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], capAddr, cap, s.mem()) + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, types.Types[TINT], capAddr, cap, s.mem()) } case t.IsInterface(): // itab field doesn't need a write barrier (even though it is a pointer). itab := s.newValue1(ssa.OpITab, s.f.Config.Types.BytePtr, right) - s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TUINTPTR], left, itab, s.mem()) + s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, types.Types[TUINTPTR], left, itab, s.mem()) case t.IsStruct(): n := t.NumFields() for i := 0; i < n; i++ { ft := t.FieldType(i) addr := s.newValue1I(ssa.OpOffPtr, ft.PtrTo(), t.FieldOff(i), left) val := s.newValue1I(ssa.OpStructSelect, ft, int64(i), right) - s.storeTypeScalars(ft.(*Type), addr, val, 0) + s.storeTypeScalars(ft.(*types.Type), addr, val, 0) } case t.IsArray() && t.NumElem() == 0: // nothing @@ -3572,7 +3573,7 @@ func (s *state) storeTypeScalars(t *Type, left, right *ssa.Value, skip skipMask) } // do *left = right for all pointer parts of t. -func (s *state) storeTypePtrs(t *Type, left, right *ssa.Value) { +func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) { switch { case t.IsPtrShaped(): s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, t, left, right, s.mem()) @@ -3591,12 +3592,12 @@ func (s *state) storeTypePtrs(t *Type, left, right *ssa.Value) { n := t.NumFields() for i := 0; i < n; i++ { ft := t.FieldType(i) - if !haspointers(ft.(*Type)) { + if !types.Haspointers(ft.(*types.Type)) { continue } addr := s.newValue1I(ssa.OpOffPtr, ft.PtrTo(), t.FieldOff(i), left) val := s.newValue1I(ssa.OpStructSelect, ft, int64(i), right) - s.storeTypePtrs(ft.(*Type), addr, val) + s.storeTypePtrs(ft.(*types.Type), addr, val) } case t.IsArray() && t.NumElem() == 0: // nothing @@ -3610,35 +3611,35 @@ func (s *state) storeTypePtrs(t *Type, left, right *ssa.Value) { // slice computes the slice v[i:j:k] and returns ptr, len, and cap of result. // i,j,k may be nil, in which case they are set to their default value. // t is a slice, ptr to array, or string type. -func (s *state) slice(t *Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value) { - var elemtype *Type - var ptrtype *Type +func (s *state) slice(t *types.Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value) { + var elemtype *types.Type + var ptrtype *types.Type var ptr *ssa.Value var len *ssa.Value var cap *ssa.Value - zero := s.constInt(Types[TINT], 0) + zero := s.constInt(types.Types[TINT], 0) switch { case t.IsSlice(): elemtype = t.Elem() - ptrtype = typPtr(elemtype) + ptrtype = types.NewPtr(elemtype) ptr = s.newValue1(ssa.OpSlicePtr, ptrtype, v) - len = s.newValue1(ssa.OpSliceLen, Types[TINT], v) - cap = s.newValue1(ssa.OpSliceCap, Types[TINT], v) + len = s.newValue1(ssa.OpSliceLen, types.Types[TINT], v) + cap = s.newValue1(ssa.OpSliceCap, types.Types[TINT], v) case t.IsString(): - elemtype = Types[TUINT8] - ptrtype = typPtr(elemtype) + elemtype = types.Types[TUINT8] + ptrtype = types.NewPtr(elemtype) ptr = s.newValue1(ssa.OpStringPtr, ptrtype, v) - len = s.newValue1(ssa.OpStringLen, Types[TINT], v) + len = s.newValue1(ssa.OpStringLen, types.Types[TINT], v) cap = len case t.IsPtr(): if !t.Elem().IsArray() { s.Fatalf("bad ptr to array in slice %v\n", t) } elemtype = t.Elem().Elem() - ptrtype = typPtr(elemtype) + ptrtype = types.NewPtr(elemtype) s.nilCheck(v) ptr = v - len = s.constInt(Types[TINT], t.Elem().NumElem()) + len = s.constInt(types.Types[TINT], t.Elem().NumElem()) cap = len default: s.Fatalf("bad type in slice %v\n", t) @@ -3673,10 +3674,10 @@ func (s *state) slice(t *Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value) { // rptr = p + delta&mask(rcap) // result = (SliceMake rptr rlen rcap) // where mask(x) is 0 if x==0 and -1 if x>0. - subOp := s.ssaOp(OSUB, Types[TINT]) - mulOp := s.ssaOp(OMUL, Types[TINT]) - andOp := s.ssaOp(OAND, Types[TINT]) - rlen := s.newValue2(subOp, Types[TINT], j, i) + subOp := s.ssaOp(OSUB, types.Types[TINT]) + mulOp := s.ssaOp(OMUL, types.Types[TINT]) + andOp := s.ssaOp(OAND, types.Types[TINT]) + rlen := s.newValue2(subOp, types.Types[TINT], j, i) var rcap *ssa.Value switch { case t.IsString(): @@ -3687,7 +3688,7 @@ func (s *state) slice(t *Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value) { case j == k: rcap = rlen default: - rcap = s.newValue2(subOp, Types[TINT], k, i) + rcap = s.newValue2(subOp, types.Types[TINT], k, i) } var rptr *ssa.Value @@ -3696,11 +3697,11 @@ func (s *state) slice(t *Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value) { rptr = ptr } else { // delta = # of bytes to offset pointer by. - delta := s.newValue2(mulOp, Types[TINT], i, s.constInt(Types[TINT], elemtype.Width)) + delta := s.newValue2(mulOp, types.Types[TINT], i, s.constInt(types.Types[TINT], elemtype.Width)) // If we're slicing to the point where the capacity is zero, // zero out the delta. - mask := s.newValue1(ssa.OpSlicemask, Types[TINT], rcap) - delta = s.newValue2(andOp, Types[TINT], delta, mask) + mask := s.newValue1(ssa.OpSlicemask, types.Types[TINT], rcap) + delta = s.newValue2(andOp, types.Types[TINT], delta, mask) // Compute rptr = ptr + delta rptr = s.newValue2(ssa.OpAddPtr, ptrtype, ptr, delta) } @@ -3733,15 +3734,15 @@ var u64_f32 u642fcvtTab = u642fcvtTab{ one: (*state).constInt64, } -func (s *state) uint64Tofloat64(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) uint64Tofloat64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { return s.uint64Tofloat(&u64_f64, n, x, ft, tt) } -func (s *state) uint64Tofloat32(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) uint64Tofloat32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { return s.uint64Tofloat(&u64_f32, n, x, ft, tt) } -func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { // if x >= 0 { // result = (floatY) x // } else { @@ -3767,7 +3768,7 @@ func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n *Node, x *ssa.Value, ft, tt // equal to 10000000001; that rounds up, and the 1 cannot // be lost else it would round down if the LSB of the // candidate mantissa is 0. - cmp := s.newValue2(cvttab.geq, Types[TBOOL], x, s.zeroVal(ft)) + cmp := s.newValue2(cvttab.geq, types.Types[TBOOL], x, s.zeroVal(ft)) b := s.endBlock() b.Kind = ssa.BlockIf b.SetControl(cmp) @@ -3814,21 +3815,21 @@ var u32_f32 u322fcvtTab = u322fcvtTab{ cvtF2F: ssa.OpCvt64Fto32F, } -func (s *state) uint32Tofloat64(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) uint32Tofloat64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { return s.uint32Tofloat(&u32_f64, n, x, ft, tt) } -func (s *state) uint32Tofloat32(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) uint32Tofloat32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { return s.uint32Tofloat(&u32_f32, n, x, ft, tt) } -func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { // if x >= 0 { // result = floatY(x) // } else { // result = floatY(float64(x) + (1<<32)) // } - cmp := s.newValue2(ssa.OpGeq32, Types[TBOOL], x, s.zeroVal(ft)) + cmp := s.newValue2(ssa.OpGeq32, types.Types[TBOOL], x, s.zeroVal(ft)) b := s.endBlock() b.Kind = ssa.BlockIf b.SetControl(cmp) @@ -3847,9 +3848,9 @@ func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n *Node, x *ssa.Value, ft, tt b.AddEdgeTo(bElse) s.startBlock(bElse) - a1 := s.newValue1(ssa.OpCvt32to64F, Types[TFLOAT64], x) - twoToThe32 := s.constFloat64(Types[TFLOAT64], float64(1<<32)) - a2 := s.newValue2(ssa.OpAdd64F, Types[TFLOAT64], a1, twoToThe32) + a1 := s.newValue1(ssa.OpCvt32to64F, types.Types[TFLOAT64], x) + twoToThe32 := s.constFloat64(types.Types[TFLOAT64], float64(1<<32)) + a2 := s.newValue2(ssa.OpAdd64F, types.Types[TFLOAT64], a1, twoToThe32) a3 := s.newValue1(cvttab.cvtF2F, tt, a2) s.vars[n] = a3 @@ -3874,8 +3875,8 @@ func (s *state) referenceTypeBuiltin(n *Node, x *ssa.Value) *ssa.Value { // return *(((*int)n)+1) // } lenType := n.Type - nilValue := s.constNil(Types[TUINTPTR]) - cmp := s.newValue2(ssa.OpEqPtr, Types[TBOOL], x, nilValue) + nilValue := s.constNil(types.Types[TUINTPTR]) + cmp := s.newValue2(ssa.OpEqPtr, types.Types[TBOOL], x, nilValue) b := s.endBlock() b.Kind = ssa.BlockIf b.SetControl(cmp) @@ -3958,22 +3959,22 @@ var f64_u32 f2uCvtTab = f2uCvtTab{ cutoff: 2147483648, } -func (s *state) float32ToUint64(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) float32ToUint64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { return s.floatToUint(&f32_u64, n, x, ft, tt) } -func (s *state) float64ToUint64(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) float64ToUint64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { return s.floatToUint(&f64_u64, n, x, ft, tt) } -func (s *state) float32ToUint32(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) float32ToUint32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { return s.floatToUint(&f32_u32, n, x, ft, tt) } -func (s *state) float64ToUint32(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) float64ToUint32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { return s.floatToUint(&f64_u32, n, x, ft, tt) } -func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value { +func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value { // cutoff:=1<<(intY_Size-1) // if x < floatX(cutoff) { // result = uintY(x) @@ -3983,7 +3984,7 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *Ty // result = z | -(cutoff) // } cutoff := cvttab.floatValue(s, ft, float64(cvttab.cutoff)) - cmp := s.newValue2(cvttab.ltf, Types[TBOOL], x, cutoff) + cmp := s.newValue2(cvttab.ltf, types.Types[TBOOL], x, cutoff) b := s.endBlock() b.Kind = ssa.BlockIf b.SetControl(cmp) @@ -4033,7 +4034,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) { // Get itab/type field from input. itab := s.newValue1(ssa.OpITab, byteptr, iface) // Conversion succeeds iff that field is not nil. - cond := s.newValue2(ssa.OpNeqPtr, Types[TBOOL], itab, s.constNil(byteptr)) + cond := s.newValue2(ssa.OpNeqPtr, types.Types[TBOOL], itab, s.constNil(byteptr)) if n.Left.Type.IsEmptyInterface() && commaok { // Converting empty interface to empty interface with ,ok is just a nil check. @@ -4098,16 +4099,16 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) { } if n.Left.Type.IsEmptyInterface() { if commaok { - call := s.rtcall(assertE2I2, true, []*Type{n.Type, Types[TBOOL]}, target, iface) + call := s.rtcall(assertE2I2, true, []*types.Type{n.Type, types.Types[TBOOL]}, target, iface) return call[0], call[1] } - return s.rtcall(assertE2I, true, []*Type{n.Type}, target, iface)[0], nil + return s.rtcall(assertE2I, true, []*types.Type{n.Type}, target, iface)[0], nil } if commaok { - call := s.rtcall(assertI2I2, true, []*Type{n.Type, Types[TBOOL]}, target, iface) + call := s.rtcall(assertI2I2, true, []*types.Type{n.Type, types.Types[TBOOL]}, target, iface) return call[0], call[1] } - return s.rtcall(assertI2I, true, []*Type{n.Type}, target, iface)[0], nil + return s.rtcall(assertI2I, true, []*types.Type{n.Type}, target, iface)[0], nil } if Debug_typeassert > 0 { @@ -4139,7 +4140,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) { s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, tmp, s.mem()) } - cond := s.newValue2(ssa.OpEqPtr, Types[TBOOL], itab, targetITab) + cond := s.newValue2(ssa.OpEqPtr, types.Types[TBOOL], itab, targetITab) b := s.endBlock() b.Kind = ssa.BlockIf b.SetControl(cond) @@ -4165,7 +4166,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) { if direct { return s.newValue1(ssa.OpIData, n.Type, iface), nil } - p := s.newValue1(ssa.OpIData, typPtr(n.Type), iface) + p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type), iface) return s.newValue2(ssa.OpLoad, n.Type, p, s.mem()), nil } @@ -4174,7 +4175,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) { bEnd := s.f.NewBlock(ssa.BlockPlain) // Note that we need a new valVar each time (unlike okVar where we can // reuse the variable) because it might have a different type every time. - valVar := &Node{Op: ONAME, Class: Pxxx, Sym: &Sym{Name: "val"}} + valVar := &Node{Op: ONAME, Class: Pxxx, Sym: &types.Sym{Name: "val"}} // type assertion succeeded s.startBlock(bOk) @@ -4182,11 +4183,11 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) { if direct { s.vars[valVar] = s.newValue1(ssa.OpIData, n.Type, iface) } else { - p := s.newValue1(ssa.OpIData, typPtr(n.Type), iface) + p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type), iface) s.vars[valVar] = s.newValue2(ssa.OpLoad, n.Type, p, s.mem()) } } else { - p := s.newValue1(ssa.OpIData, typPtr(n.Type), iface) + p := s.newValue1(ssa.OpIData, types.NewPtr(n.Type), iface) store := s.newValue3I(ssa.OpMove, ssa.TypeMem, n.Type.Size(), addr, p, s.mem()) store.Aux = n.Type s.vars[&memVar] = store @@ -4217,7 +4218,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) { res = s.newValue2(ssa.OpLoad, n.Type, addr, s.mem()) s.vars[&memVar] = s.newValue1A(ssa.OpVarKill, ssa.TypeMem, tmp, s.mem()) } - resok = s.variable(&okVar, Types[TBOOL]) + resok = s.variable(&okVar, types.Types[TBOOL]) delete(s.vars, &okVar) return res, resok } @@ -4548,11 +4549,11 @@ func (s *state) extendIndex(v *ssa.Value, panicfn *obj.LSym) *ssa.Value { // truncate 64-bit indexes on 32-bit pointer archs. Test the // high word and branch to out-of-bounds failure if it is not 0. if Debug['B'] == 0 { - hi := s.newValue1(ssa.OpInt64Hi, Types[TUINT32], v) - cmp := s.newValue2(ssa.OpEq32, Types[TBOOL], hi, s.constInt32(Types[TUINT32], 0)) + hi := s.newValue1(ssa.OpInt64Hi, types.Types[TUINT32], v) + cmp := s.newValue2(ssa.OpEq32, types.Types[TBOOL], hi, s.constInt32(types.Types[TUINT32], 0)) s.check(cmp, panicfn) } - return s.newValue1(ssa.OpTrunc64to32, Types[TINT], v) + return s.newValue1(ssa.OpTrunc64to32, types.Types[TINT], v) } // Extend value to the required size @@ -4588,7 +4589,7 @@ func (s *state) extendIndex(v *ssa.Value, panicfn *obj.LSym) *ssa.Value { s.Fatalf("bad unsigned index extension %s", v.Type) } } - return s.newValue1(op, Types[TINT], v) + return s.newValue1(op, types.Types[TINT], v) } // CheckLoweredPhi checks that regalloc and stackalloc correctly handled phi values. @@ -4733,7 +4734,7 @@ type ssafn struct { log bool } -// StringData returns a symbol (a *Sym wrapped in an interface) which +// StringData returns a symbol (a *types.Sym wrapped in an interface) which // is the data component of a global string constant containing s. func (e *ssafn) StringData(s string) interface{} { if aux, ok := e.strings[s]; ok { @@ -4743,20 +4744,20 @@ func (e *ssafn) StringData(s string) interface{} { e.strings = make(map[string]interface{}) } data := stringsym(s) - aux := &ssa.ExternSymbol{Typ: idealstring, Sym: data} + aux := &ssa.ExternSymbol{Typ: types.Idealstring, Sym: data} e.strings[s] = aux return aux } func (e *ssafn) Auto(pos src.XPos, t ssa.Type) ssa.GCNode { - n := tempAt(pos, e.curfn, t.(*Type)) // Note: adds new auto to e.curfn.Func.Dcl list + n := tempAt(pos, e.curfn, t.(*types.Type)) // Note: adds new auto to e.curfn.Func.Dcl list return n } func (e *ssafn) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { n := name.N.(*Node) - ptrType := typPtr(Types[TUINT8]) - lenType := Types[TINT] + ptrType := types.NewPtr(types.Types[TUINT8]) + lenType := types.Types[TINT] if n.Class == PAUTO && !n.Addrtaken() { // Split this string up into two separate variables. p := e.namedAuto(n.Sym.Name+".ptr", ptrType, n.Pos) @@ -4769,7 +4770,7 @@ func (e *ssafn) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { n := name.N.(*Node) - t := typPtr(Types[TUINT8]) + t := types.NewPtr(types.Types[TUINT8]) if n.Class == PAUTO && !n.Addrtaken() { // Split this interface up into two separate variables. f := ".itab" @@ -4786,8 +4787,8 @@ func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot func (e *ssafn) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ssa.LocalSlot) { n := name.N.(*Node) - ptrType := typPtr(name.Type.ElemType().(*Type)) - lenType := Types[TINT] + ptrType := types.NewPtr(name.Type.ElemType().(*types.Type)) + lenType := types.Types[TINT] if n.Class == PAUTO && !n.Addrtaken() { // Split this slice up into three separate variables. p := e.namedAuto(n.Sym.Name+".ptr", ptrType, n.Pos) @@ -4804,11 +4805,11 @@ func (e *ssafn) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ss func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { n := name.N.(*Node) s := name.Type.Size() / 2 - var t *Type + var t *types.Type if s == 8 { - t = Types[TFLOAT64] + t = types.Types[TFLOAT64] } else { - t = Types[TFLOAT32] + t = types.Types[TFLOAT32] } if n.Class == PAUTO && !n.Addrtaken() { // Split this complex up into two separate variables. @@ -4822,23 +4823,23 @@ func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) func (e *ssafn) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { n := name.N.(*Node) - var t *Type + var t *types.Type if name.Type.IsSigned() { - t = Types[TINT32] + t = types.Types[TINT32] } else { - t = Types[TUINT32] + t = types.Types[TUINT32] } if n.Class == PAUTO && !n.Addrtaken() { // Split this int64 up into two separate variables. h := e.namedAuto(n.Sym.Name+".hi", t, n.Pos) - l := e.namedAuto(n.Sym.Name+".lo", Types[TUINT32], n.Pos) - return ssa.LocalSlot{N: h, Type: t, Off: 0}, ssa.LocalSlot{N: l, Type: Types[TUINT32], Off: 0} + l := e.namedAuto(n.Sym.Name+".lo", types.Types[TUINT32], n.Pos) + return ssa.LocalSlot{N: h, Type: t, Off: 0}, ssa.LocalSlot{N: l, Type: types.Types[TUINT32], Off: 0} } // Return the two parts of the larger variable. if thearch.LinkArch.ByteOrder == binary.BigEndian { - return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: Types[TUINT32], Off: name.Off + 4} + return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: types.Types[TUINT32], Off: name.Off + 4} } - return ssa.LocalSlot{N: n, Type: t, Off: name.Off + 4}, ssa.LocalSlot{N: n, Type: Types[TUINT32], Off: name.Off} + return ssa.LocalSlot{N: n, Type: t, Off: name.Off + 4}, ssa.LocalSlot{N: n, Type: types.Types[TUINT32], Off: name.Off} } func (e *ssafn) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot { @@ -4876,8 +4877,8 @@ func (e *ssafn) DerefItab(it *obj.LSym, offset int64) *obj.LSym { // namedAuto returns a new AUTO variable with the given name and type. // These are exposed to the debugger. func (e *ssafn) namedAuto(name string, typ ssa.Type, pos src.XPos) ssa.GCNode { - t := typ.(*Type) - s := &Sym{Name: name, Pkg: localpkg} + t := typ.(*types.Type) + s := &types.Sym{Name: name, Pkg: localpkg} n := new(Node) n.Name = new(Name) @@ -4885,8 +4886,8 @@ func (e *ssafn) namedAuto(name string, typ ssa.Type, pos src.XPos) ssa.GCNode { n.Pos = pos n.Orig = n - s.Def = n - s.Def.SetUsed(true) + s.Def = asTypesNode(n) + asNode(s.Def).SetUsed(true) n.Sym = s n.Type = t n.Class = PAUTO @@ -4900,7 +4901,7 @@ func (e *ssafn) namedAuto(name string, typ ssa.Type, pos src.XPos) ssa.GCNode { } func (e *ssafn) CanSSA(t ssa.Type) bool { - return canSSAType(t.(*Type)) + return canSSAType(t.(*types.Type)) } func (e *ssafn) Line(pos src.XPos) string { diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go index 23ba48303b..ddf6f77c07 100644 --- a/src/cmd/compile/internal/gc/subr.go +++ b/src/cmd/compile/internal/gc/subr.go @@ -6,6 +6,7 @@ package gc import ( "bytes" + "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/src" "crypto/md5" @@ -209,13 +210,13 @@ func setlineno(n *Node) src.XPos { return lno } -func lookup(name string) *Sym { +func lookup(name string) *types.Sym { return localpkg.Lookup(name) } // lookupN looks up the symbol starting with prefix and ending with // the decimal n. If prefix is too long, lookupN panics. -func lookupN(prefix string, n int) *Sym { +func lookupN(prefix string, n int) *types.Sym { var buf [20]byte // plenty long enough for all current users copy(buf[:], prefix) b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10) @@ -241,49 +242,7 @@ func autolabel(prefix string) *Node { return newname(lookupN(prefix, int(n))) } -var initSyms []*Sym - -var nopkg = &Pkg{ - Syms: make(map[string]*Sym), -} - -func (pkg *Pkg) Lookup(name string) *Sym { - s, _ := pkg.LookupOK(name) - return s -} - -// LookupOK looks up name in pkg and reports whether it previously existed. -func (pkg *Pkg) LookupOK(name string) (s *Sym, existed bool) { - if pkg == nil { - pkg = nopkg - } - if s := pkg.Syms[name]; s != nil { - return s, true - } - - s = &Sym{ - Name: name, - Pkg: pkg, - } - if name == "init" { - initSyms = append(initSyms, s) - } - pkg.Syms[name] = s - return s, false -} - -func (pkg *Pkg) LookupBytes(name []byte) *Sym { - if pkg == nil { - pkg = nopkg - } - if s := pkg.Syms[string(name)]; s != nil { - return s - } - str := internString(name) - return pkg.Lookup(str) -} - -func restrictlookup(name string, pkg *Pkg) *Sym { +func restrictlookup(name string, pkg *types.Pkg) *types.Sym { if !exportname(name) && pkg != localpkg { yyerror("cannot refer to unexported name %s.%s", pkg.Name, name) } @@ -292,8 +251,8 @@ func restrictlookup(name string, pkg *Pkg) *Sym { // find all the exported symbols in package opkg // and make them available in the current package -func importdot(opkg *Pkg, pack *Node) { - var s1 *Sym +func importdot(opkg *types.Pkg, pack *Node) { + var s1 *types.Sym var pkgerror string n := 0 @@ -313,11 +272,11 @@ func importdot(opkg *Pkg, pack *Node) { s1.Def = s.Def s1.Block = s.Block - if s1.Def.Name == nil { - Dump("s1def", s1.Def) + if asNode(s1.Def).Name == nil { + Dump("s1def", asNode(s1.Def)) Fatalf("missing Name") } - s1.Def.Name.Pack = pack + asNode(s1.Def).Name.Pack = pack s1.Origpkg = opkg n++ } @@ -364,7 +323,7 @@ func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node { } // newname returns a new ONAME Node associated with symbol s. -func newname(s *Sym) *Node { +func newname(s *types.Sym) *Node { n := newnamel(lineno, s) n.Name.Curfn = Curfn return n @@ -372,7 +331,7 @@ func newname(s *Sym) *Node { // newname returns a new ONAME Node associated with symbol s at position pos. // The caller is responsible for setting n.Name.Curfn. -func newnamel(pos src.XPos, s *Sym) *Node { +func newnamel(pos src.XPos, s *types.Sym) *Node { if s == nil { Fatalf("newnamel nil") } @@ -397,7 +356,7 @@ func newnamel(pos src.XPos, s *Sym) *Node { // nodSym makes a Node with Op op and with the Left field set to left // and the Sym field set to sym. This is for ODOT and friends. -func nodSym(op Op, left *Node, sym *Sym) *Node { +func nodSym(op Op, left *Node, sym *types.Sym) *Node { n := nod(op, left, nil) n.Sym = sym return n @@ -413,7 +372,7 @@ func saveorignode(n *Node) { } // methcmp sorts by symbol, then by package path for unexported symbols. -type methcmp []*Field +type methcmp []*types.Field func (x methcmp) Len() int { return len(x) } func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } @@ -446,7 +405,7 @@ func nodintconst(v int64) *Node { c.SetAddable(true) c.SetVal(Val{new(Mpint)}) c.Val().U.(*Mpint).SetInt64(v) - c.Type = Types[TIDEAL] + c.Type = types.Types[TIDEAL] return c } @@ -455,11 +414,11 @@ func nodfltconst(v *Mpflt) *Node { c.SetAddable(true) c.SetVal(Val{newMpflt()}) c.Val().U.(*Mpflt).Set(v) - c.Type = Types[TIDEAL] + c.Type = types.Types[TIDEAL] return c } -func nodconst(n *Node, t *Type, v int64) { +func nodconst(n *Node, t *types.Type, v int64) { *n = Node{} n.Op = OLITERAL n.SetAddable(true) @@ -475,14 +434,14 @@ func nodconst(n *Node, t *Type, v int64) { func nodnil() *Node { c := nodintconst(0) c.SetVal(Val{new(NilVal)}) - c.Type = Types[TNIL] + c.Type = types.Types[TNIL] return c } func nodbool(b bool) *Node { c := nodintconst(0) c.SetVal(Val{b}) - c.Type = idealbool + c.Type = types.Idealbool return c } @@ -531,7 +490,7 @@ func isnil(n *Node) bool { return Isconst(n.Orig, CTNIL) } -func isptrto(t *Type, et EType) bool { +func isptrto(t *types.Type, et types.EType) bool { if t == nil { return false } @@ -555,14 +514,14 @@ func isblank(n *Node) bool { return isblanksym(n.Sym) } -func isblanksym(s *Sym) bool { +func isblanksym(s *types.Sym) bool { return s != nil && s.Name == "_" } // methtype returns the underlying type, if any, // that owns methods with receiver parameter t. // The result is either a named type or an anonymous struct. -func methtype(t *Type) *Type { +func methtype(t *types.Type) *types.Type { if t == nil { return nil } @@ -594,7 +553,7 @@ func methtype(t *Type) *Type { return nil } -func cplxsubtype(et EType) EType { +func cplxsubtype(et types.EType) types.EType { switch et { case TCOMPLEX64: return TFLOAT32 @@ -613,21 +572,21 @@ func cplxsubtype(et EType) EType { // named, it is only identical to the other if they are the same // pointer (t1 == t2), so there's no chance of chasing cycles // ad infinitum, so no need for a depth counter. -func eqtype(t1, t2 *Type) bool { +func eqtype(t1, t2 *types.Type) bool { return eqtype1(t1, t2, true, nil) } // eqtypeIgnoreTags is like eqtype but it ignores struct tags for struct identity. -func eqtypeIgnoreTags(t1, t2 *Type) bool { +func eqtypeIgnoreTags(t1, t2 *types.Type) bool { return eqtype1(t1, t2, false, nil) } type typePair struct { - t1 *Type - t2 *Type + t1 *types.Type + t2 *types.Type } -func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) bool { +func eqtype1(t1, t2 *types.Type, cmpTags bool, assumedEqual map[typePair]struct{}) bool { if t1 == t2 { return true } @@ -639,9 +598,9 @@ func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) boo // separate for error messages. Treat them as equal. switch t1.Etype { case TUINT8: - return (t1 == Types[TUINT8] || t1 == bytetype) && (t2 == Types[TUINT8] || t2 == bytetype) + return (t1 == types.Types[TUINT8] || t1 == types.Bytetype) && (t2 == types.Types[TUINT8] || t2 == types.Bytetype) case TINT32: - return (t1 == Types[TINT32] || t1 == runetype) && (t2 == Types[TINT32] || t2 == runetype) + return (t1 == types.Types[TINT32] || t1 == types.Runetype) && (t2 == types.Types[TINT32] || t2 == types.Runetype) default: return false } @@ -686,7 +645,7 @@ func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) boo // Check parameters and result parameters for type equality. // We intentionally ignore receiver parameters for type // equality, because they're never relevant. - for _, f := range paramsResults { + for _, f := range types.ParamsResults { // Loop over fields in structs, ignoring argument names. fs1, fs2 := f(t1).FieldSlice(), f(t2).FieldSlice() if len(fs1) != len(fs2) { @@ -724,7 +683,7 @@ func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) boo // Are t1 and t2 equal struct types when field names are ignored? // For deciding whether the result struct from g can be copied // directly when compiling f(g()). -func eqtypenoname(t1 *Type, t2 *Type) bool { +func eqtypenoname(t1 *types.Type, t2 *types.Type) bool { if t1 == nil || t2 == nil || !t1.IsStruct() || !t2.IsStruct() { return false } @@ -744,7 +703,7 @@ func eqtypenoname(t1 *Type, t2 *Type) bool { // Is type src assignment compatible to type dst? // If so, return op code to use in conversion. // If not, return 0. -func assignop(src *Type, dst *Type, why *string) Op { +func assignop(src *types.Type, dst *types.Type, why *string) Op { if why != nil { *why = "" } @@ -791,7 +750,7 @@ func assignop(src *Type, dst *Type, why *string) Op { // 3. dst is an interface type and src implements dst. if dst.IsInterface() && src.Etype != TNIL { - var missing, have *Field + var missing, have *types.Field var ptr int if implements(src, dst, &missing, &have, &ptr) { return OCONVIFACE @@ -831,7 +790,7 @@ func assignop(src *Type, dst *Type, why *string) Op { } if src.IsInterface() && dst.Etype != TBLANK { - var missing, have *Field + var missing, have *types.Field var ptr int if why != nil && implements(dst, src, &missing, &have, &ptr) { *why = ": need type assertion" @@ -842,7 +801,7 @@ func assignop(src *Type, dst *Type, why *string) Op { // 4. src is a bidirectional channel value, dst is a channel type, // src and dst have identical element types, and // either src or dst is not a named type. - if src.IsChan() && src.ChanDir() == Cboth && dst.IsChan() { + if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() { if eqtype(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) { return OCONVNOP } @@ -875,7 +834,7 @@ func assignop(src *Type, dst *Type, why *string) Op { // Can we convert a value of type src to a value of type dst? // If so, return op code to use in conversion (maybe OCONVNOP). // If not, return 0. -func convertop(src *Type, dst *Type, why *string) Op { +func convertop(src *types.Type, dst *types.Type, why *string) Op { if why != nil { *why = "" } @@ -950,10 +909,10 @@ func convertop(src *Type, dst *Type, why *string) Op { } if src.IsSlice() && dst.IsString() { - if src.Elem().Etype == bytetype.Etype { + if src.Elem().Etype == types.Bytetype.Etype { return OARRAYBYTESTR } - if src.Elem().Etype == runetype.Etype { + if src.Elem().Etype == types.Runetype.Etype { return OARRAYRUNESTR } } @@ -961,10 +920,10 @@ func convertop(src *Type, dst *Type, why *string) Op { // 7. src is a string and dst is []byte or []rune. // String to slice. if src.IsString() && dst.IsSlice() { - if dst.Elem().Etype == bytetype.Etype { + if dst.Elem().Etype == types.Bytetype.Etype { return OSTRARRAYBYTE } - if dst.Elem().Etype == runetype.Etype { + if dst.Elem().Etype == types.Runetype.Etype { return OSTRARRAYRUNE } } @@ -982,12 +941,12 @@ func convertop(src *Type, dst *Type, why *string) Op { return 0 } -func assignconv(n *Node, t *Type, context string) *Node { +func assignconv(n *Node, t *types.Type, context string) *Node { return assignconvfn(n, t, func() string { return context }) } // Convert node n for assignment to type t. -func assignconvfn(n *Node, t *Type, context func() string) *Node { +func assignconvfn(n *Node, t *types.Type, context func() string) *Node { if n == nil || n.Type == nil || n.Type.Broke() { return n } @@ -1007,10 +966,10 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node { // Convert ideal bool from comparison to plain bool // if the next step is non-bool (like interface{}). - if n.Type == idealbool && !t.IsBoolean() { + if n.Type == types.Idealbool && !t.IsBoolean() { if n.Op == ONAME || n.Op == OLITERAL { r := nod(OCONVNOP, n, nil) - r.Type = Types[TBOOL] + r.Type = types.Types[TBOOL] r.Typecheck = 1 r.SetImplicit(true) n = r @@ -1132,11 +1091,11 @@ func syslook(name string) *Node { if s == nil || s.Def == nil { Fatalf("syslook: can't find runtime.%s", name) } - return s.Def + return asNode(s.Def) } // typehash computes a hash value for type t to use in type switch statements. -func typehash(t *Type) uint32 { +func typehash(t *types.Type) uint32 { p := t.LongString() // Using MD5 is overkill, but reduces accidental collisions. @@ -1229,7 +1188,7 @@ out: n.SetHasCall(b) } -func badtype(op Op, tl *Type, tr *Type) { +func badtype(op Op, tl *types.Type, tr *types.Type) { fmt_ := "" if tl != nil { fmt_ += fmt.Sprintf("\n\t%v", tl) @@ -1358,7 +1317,7 @@ func safeexpr(n *Node, init *Nodes) *Node { return cheapexpr(n, init) } -func copyexpr(n *Node, t *Type, init *Nodes) *Node { +func copyexpr(n *Node, t *types.Type, init *Nodes) *Node { l := temp(t) a := nod(OAS, l, n) a = typecheck(a, Etop) @@ -1383,7 +1342,7 @@ func cheapexpr(n *Node, init *Nodes) *Node { // A Dlist stores a pointer to a TFIELD Type embedded within // a TSTRUCT or TINTER Type. type Dlist struct { - field *Field + field *types.Field } // dotlist is used by adddot1 to record the path of embedded fields @@ -1394,7 +1353,7 @@ var dotlist = make([]Dlist, 10) // lookdot0 returns the number of fields or methods named s associated // with Type t. If exactly one exists, it will be returned in *save // (if save is not nil). -func lookdot0(s *Sym, t *Type, save **Field, ignorecase bool) int { +func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) int { u := t if u.IsPtr() { u = u.Elem() @@ -1433,13 +1392,13 @@ func lookdot0(s *Sym, t *Type, save **Field, ignorecase bool) int { // in reverse order. If none exist, more will indicate whether t contains any // embedded fields at depth d, so callers can decide whether to retry at // a greater depth. -func adddot1(s *Sym, t *Type, d int, save **Field, ignorecase bool) (c int, more bool) { +func adddot1(s *types.Sym, t *types.Type, d int, save **types.Field, ignorecase bool) (c int, more bool) { if t.Recur() { return } t.SetRecur(true) - var u *Type + var u *types.Type d-- if d < 0 { // We've reached our target depth. If t has any fields/methods @@ -1487,7 +1446,7 @@ out: // a selection expression x.f, where x is of type t and f is the symbol s. // If no such path exists, dotpath returns nil. // If there are multiple shortest paths to the same depth, ambig is true. -func dotpath(s *Sym, t *Type, save **Field, ignorecase bool) (path []Dlist, ambig bool) { +func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (path []Dlist, ambig bool) { // The embedding of types within structs imposes a tree structure onto // types: structs parent the types they embed, and types parent their // fields or methods. Our goal here is to find the shortest path to @@ -1555,13 +1514,13 @@ func adddot(n *Node) *Node { // with unique tasks and they return // the actual methods. type Symlink struct { - field *Field + field *types.Field followptr bool } var slist []Symlink -func expand0(t *Type, followptr bool) { +func expand0(t *types.Type, followptr bool) { u := t if u.IsPtr() { followptr = true @@ -1592,7 +1551,7 @@ func expand0(t *Type, followptr bool) { } } -func expand1(t *Type, top, followptr bool) { +func expand1(t *types.Type, top, followptr bool) { if t.Recur() { return } @@ -1626,7 +1585,7 @@ out: t.SetRecur(false) } -func expandmeth(t *Type) { +func expandmeth(t *types.Type) { if t == nil || t.AllMethods().Len() != 0 { return } @@ -1642,12 +1601,12 @@ func expandmeth(t *Type) { expand1(t, true, false) // check each method to be uniquely reachable - var ms []*Field + var ms []*types.Field for i, sl := range slist { slist[i].field = nil sl.field.Sym.SetUniq(false) - var f *Field + var f *types.Field if path, _ := dotpath(sl.field.Sym, t, &f, false); path == nil { continue } @@ -1675,7 +1634,7 @@ func expandmeth(t *Type) { } // Given funarg struct list, return list of ODCLFIELD Node fn args. -func structargs(tl *Type, mustname bool) []*Node { +func structargs(tl *types.Type, mustname bool) []*Node { var args []*Node gen := 0 for _, t := range tl.Fields().Slice() { @@ -1720,7 +1679,7 @@ func structargs(tl *Type, mustname bool) []*Node { // rcvr - U // method - M func (t T)(), a TFIELD type struct // newnam - the eventual mangled name of this function -func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) { +func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym, iface int) { if false && Debug['r'] != 0 { fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam) } @@ -1743,7 +1702,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) { // that the interface call will pass in. // Add a dummy padding argument after the // receiver to make up the difference. - tpad := typArray(Types[TUINT8], int64(Widthptr)-rcvr.Width) + tpad := types.NewArray(types.Types[TUINT8], int64(Widthptr)-rcvr.Width) pad := namedfield(".pad", tpad) l = append(l, pad) } @@ -1844,29 +1803,29 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) { funccompile(fn) } -func hashmem(t *Type) *Node { +func hashmem(t *types.Type) *Node { sym := Runtimepkg.Lookup("memhash") n := newname(sym) n.Class = PFUNC tfn := nod(OTFUNC, nil, nil) - tfn.List.Append(anonfield(typPtr(t))) - tfn.List.Append(anonfield(Types[TUINTPTR])) - tfn.List.Append(anonfield(Types[TUINTPTR])) - tfn.Rlist.Append(anonfield(Types[TUINTPTR])) + tfn.List.Append(anonfield(types.NewPtr(t))) + tfn.List.Append(anonfield(types.Types[TUINTPTR])) + tfn.List.Append(anonfield(types.Types[TUINTPTR])) + tfn.Rlist.Append(anonfield(types.Types[TUINTPTR])) tfn = typecheck(tfn, Etype) n.Type = tfn.Type return n } -func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase bool) *Field { +func ifacelookdot(s *types.Sym, t *types.Type, followptr *bool, ignorecase bool) *types.Field { *followptr = false if t == nil { return nil } - var m *Field + var m *types.Field path, ambig := dotpath(s, t, &m, ignorecase) if path == nil { if ambig { @@ -1890,7 +1849,7 @@ func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase bool) *Field { return m } -func implements(t, iface *Type, m, samename **Field, ptr *int) bool { +func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool { t0 := t if t == nil { return false @@ -1997,7 +1956,7 @@ func (l Nodes) asblock() *Node { return n } -func ngotype(n *Node) *Sym { +func ngotype(n *Node) *types.Sym { if n.Type != nil { return typenamesym(n.Type) } @@ -2031,18 +1990,18 @@ func pathtoprefix(s string) string { return s } -var pkgMap = make(map[string]*Pkg) -var pkgs []*Pkg +var pkgMap = make(map[string]*types.Pkg) +var pkgs []*types.Pkg -func mkpkg(path string) *Pkg { +func mkpkg(path string) *types.Pkg { if p := pkgMap[path]; p != nil { return p } - p := new(Pkg) + p := new(types.Pkg) p.Path = path p.Prefix = pathtoprefix(path) - p.Syms = make(map[string]*Sym) + p.Syms = make(map[string]*types.Sym) pkgMap[path] = p pkgs = append(pkgs, p) return p @@ -2128,7 +2087,7 @@ func checknil(x *Node, init *Nodes) { // Can this type be stored directly in an interface word? // Yes, if the representation is a single pointer. -func isdirectiface(t *Type) bool { +func isdirectiface(t *types.Type) bool { switch t.Etype { case TPTR32, TPTR64, @@ -2153,7 +2112,7 @@ func isdirectiface(t *Type) bool { // itabType loads the _type field from a runtime.itab struct. func itabType(itab *Node) *Node { typ := nodSym(ODOTPTR, itab, nil) - typ.Type = typPtr(Types[TUINT8]) + typ.Type = types.NewPtr(types.Types[TUINT8]) typ.Typecheck = 1 typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab typ.SetBounded(true) // guaranteed not to fault @@ -2163,14 +2122,14 @@ func itabType(itab *Node) *Node { // ifaceData loads the data field from an interface. // The concrete type must be known to have type t. // It follows the pointer if !isdirectiface(t). -func ifaceData(n *Node, t *Type) *Node { +func ifaceData(n *Node, t *types.Type) *Node { ptr := nodSym(OIDATA, n, nil) if isdirectiface(t) { ptr.Type = t ptr.Typecheck = 1 return ptr } - ptr.Type = typPtr(t) + ptr.Type = types.NewPtr(t) ptr.SetBounded(true) ptr.Typecheck = 1 ind := nod(OIND, ptr, nil) @@ -2178,16 +2137,3 @@ func ifaceData(n *Node, t *Type) *Node { ind.Typecheck = 1 return ind } - -// iet returns 'T' if t is a concrete type, -// 'I' if t is an interface type, and 'E' if t is an empty interface type. -// It is used to build calls to the conv* and assert* runtime routines. -func (t *Type) iet() byte { - if t.IsEmptyInterface() { - return 'E' - } - if t.IsInterface() { - return 'I' - } - return 'T' -} diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go index 455957bec1..d18d209098 100644 --- a/src/cmd/compile/internal/gc/swt.go +++ b/src/cmd/compile/internal/gc/swt.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "sort" ) @@ -58,7 +59,7 @@ func typecheckswitch(n *Node) { var nilonly string var top int - var t *Type + var t *types.Type if n.Left != nil && n.Left.Op == OTYPESW { // type switch @@ -76,7 +77,7 @@ func typecheckswitch(n *Node) { n.Left = defaultlit(n.Left, nil) t = n.Left.Type } else { - t = Types[TBOOL] + t = types.Types[TBOOL] } if t != nil { switch { @@ -84,10 +85,10 @@ func typecheckswitch(n *Node) { yyerrorl(n.Pos, "cannot switch on %L", n.Left) case t.IsSlice(): nilonly = "slice" - case t.IsArray() && !t.IsComparable(): + case t.IsArray() && !IsComparable(t): yyerrorl(n.Pos, "cannot switch on %L", n.Left) case t.IsStruct(): - if f := t.IncomparableField(); f != nil { + if f := IncomparableField(t); f != nil { yyerrorl(n.Pos, "cannot switch on %L (struct containing %v cannot be compared)", n.Left, f.Type) } case t.Etype == TFUNC: @@ -137,13 +138,13 @@ func typecheckswitch(n *Node) { } case nilonly != "" && !isnil(n1): yyerrorl(ncase.Pos, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left) - case t.IsInterface() && !n1.Type.IsInterface() && !n1.Type.IsComparable(): + case t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type): yyerrorl(ncase.Pos, "invalid case %L in switch (incomparable type)", n1) } // type switch case Etype: - var missing, have *Field + var missing, have *types.Field var ptr int switch { case n1.Op == OLITERAL && n1.Type.IsKind(TNIL): @@ -705,10 +706,10 @@ func (s *typeSwitch) walk(sw *Node) { a = typecheck(a, Etop) cas = append(cas, a) - s.okname = temp(Types[TBOOL]) + s.okname = temp(types.Types[TBOOL]) s.okname = typecheck(s.okname, Erv) - s.hashname = temp(Types[TUINT32]) + s.hashname = temp(types.Types[TUINT32]) s.hashname = typecheck(s.hashname, Erv) // set up labels and jumps @@ -750,7 +751,7 @@ func (s *typeSwitch) walk(sw *Node) { // Load hash from type or itab. h := nodSym(ODOTPTR, itab, nil) - h.Type = Types[TUINT32] + h.Type = types.Types[TUINT32] h.Typecheck = 1 if cond.Right.Type.IsEmptyInterface() { h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go index c009c0ce65..ef70e4b1f7 100644 --- a/src/cmd/compile/internal/gc/syntax.go +++ b/src/cmd/compile/internal/gc/syntax.go @@ -8,6 +8,7 @@ package gc import ( "cmd/compile/internal/syntax" + "cmd/compile/internal/types" "cmd/internal/src" ) @@ -26,7 +27,7 @@ type Node struct { Rlist Nodes // most nodes - Type *Type + Type *types.Type Orig *Node // original form, for printing, and tracking copies of ONAMEs // func @@ -35,7 +36,7 @@ type Node struct { // ONAME, OTYPE, OPACK, OLABEL, some OLITERAL Name *Name - Sym *Sym // various + Sym *types.Sym // various E interface{} // Opt or Val, see methods below // Various. Usually an offset into a struct. For example: @@ -54,11 +55,11 @@ type Node struct { Esc uint16 // EscXXX Op Op - Etype EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg, ChanDir for OTCHAN, for OINDEXMAP 1=LHS,0=RHS - Class Class // PPARAM, PAUTO, PEXTERN, etc - Embedded uint8 // ODCLFIELD embedded type - Walkdef uint8 // tracks state during typecheckdef; 2 == loop detected - Typecheck uint8 // tracks state during typechecking; 2 == loop detected + Etype types.EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg, ChanDir for OTCHAN, for OINDEXMAP 1=LHS,0=RHS + Class Class // PPARAM, PAUTO, PEXTERN, etc + Embedded uint8 // ODCLFIELD embedded type + Walkdef uint8 // tracks state during typecheckdef; 2 == loop detected + Typecheck uint8 // tracks state during typechecking; 2 == loop detected Initorder uint8 Likely int8 // likeliness of if statement hasVal int8 // +1 for Val, -1 for Opt, 0 for not yet set @@ -191,13 +192,13 @@ func (n *Node) mayBeShared() bool { // Name holds Node fields used only by named nodes (ONAME, OTYPE, OPACK, OLABEL, some OLITERAL). type Name struct { - Pack *Node // real package for import . names - Pkg *Pkg // pkg for OPACK nodes - Defn *Node // initializing assignment - Curfn *Node // function for local variables - Param *Param // additional fields for ONAME, OTYPE - Decldepth int32 // declaration loop depth, increased for every loop or label - Vargen int32 // unique name for ONAME within a function. Function outputs are numbered starting at one. + Pack *Node // real package for import . names + Pkg *types.Pkg // pkg for OPACK nodes + Defn *Node // initializing assignment + Curfn *Node // function for local variables + Param *Param // additional fields for ONAME, OTYPE + Decldepth int32 // declaration loop depth, increased for every loop or label + Vargen int32 // unique name for ONAME within a function. Function outputs are numbered starting at one. Funcdepth int32 flags bitset8 @@ -234,7 +235,7 @@ type Param struct { Stackcopy *Node // the PPARAM/PPARAMOUT on-stack slot (moved func params only) // ONAME PPARAM - Field *Field // TFIELD in arg struct + Field *types.Field // TFIELD in arg struct // ONAME closure linkage // Consider: @@ -317,7 +318,7 @@ type Param struct { // Func holds Node fields used only with function-like nodes. type Func struct { - Shortname *Sym + Shortname *types.Sym Enter Nodes // for example, allocate and initialize memory for escaping parameters Exit Nodes Cvars Nodes // closure params @@ -325,7 +326,7 @@ type Func struct { Inldcl Nodes // copy of dcl for use in inlining Closgen int Outerfunc *Node // outer function (for closure) - FieldTrack map[*Sym]struct{} + FieldTrack map[*types.Sym]struct{} Ntype *Node // signature Top int // top context (Ecall, Eproc, etc) Closure *Node // OCLOSURE <-> ODCLFUNC diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index f6776994dd..e447b0b618 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/src" "fmt" @@ -32,7 +33,7 @@ var typecheckdefstack []*Node // resolve ONONAME to definition, if any. func resolve(n *Node) *Node { if n != nil && n.Op == ONONAME && n.Sym != nil { - r := n.Sym.Def + r := asNode(n.Sym.Def) if r != nil { if r.Op != OIOTA { n = r @@ -86,7 +87,7 @@ var _typekind = []string{ TIDEAL: "untyped number", } -func typekind(t *Type) string { +func typekind(t *types.Type) string { if t.IsSlice() { return "slice" } @@ -253,7 +254,7 @@ func indexlit(n *Node) *Node { } switch consttype(n) { case CTINT, CTRUNE, CTFLT, CTCPLX: - n = defaultlit(n, Types[TINT]) + n = defaultlit(n, types.Types[TINT]) } n = defaultlit(n, nil) @@ -296,7 +297,7 @@ OpSwitch: ok |= Erv if n.Type == nil && n.Val().Ctype() == CTSTR { - n.Type = idealstring + n.Type = types.Idealstring } break OpSwitch @@ -351,9 +352,9 @@ OpSwitch: return n } - var t *Type + var t *types.Type if n.Left == nil { - t = typSlice(r.Type) + t = types.NewSlice(r.Type) } else if n.Left.Op == ODDD { if top&Ecomplit == 0 { if !n.Diag() { @@ -363,7 +364,7 @@ OpSwitch: n.Type = nil return n } - t = typDDDArray(r.Type) + t = types.NewDDDArray(r.Type) } else { n.Left = indexlit(typecheck(n.Left, Erv)) l := n.Left @@ -378,7 +379,7 @@ OpSwitch: } v := l.Val() - if doesoverflow(v, Types[TINT]) { + if doesoverflow(v, types.Types[TINT]) { yyerror("array bound is too large") n.Type = nil return n @@ -390,14 +391,14 @@ OpSwitch: n.Type = nil return n } - t = typArray(r.Type, bound) + t = types.NewArray(r.Type, bound) } n.Op = OTYPE n.Type = t n.Left = nil n.Right = nil - if !t.isDDDArray() { + if !t.IsDDDArray() { checkwidth(t) } @@ -418,7 +419,7 @@ OpSwitch: yyerror("go:notinheap map value not allowed") } n.Op = OTYPE - n.Type = typMap(l.Type, r.Type) + n.Type = types.NewMap(l.Type, r.Type) // map key validation alg, bad := algtype1(l.Type) @@ -445,7 +446,7 @@ OpSwitch: if l.Type.NotInHeap() { yyerror("chan of go:notinheap type not allowed") } - t := typChan(l.Type, ChanDir(n.Etype)) // TODO(marvin): Fix Node.EType type union. + t := types.NewChan(l.Type, types.ChanDir(n.Etype)) // TODO(marvin): Fix Node.EType type union. n.Op = OTYPE n.Type = t n.Left = nil @@ -492,7 +493,7 @@ OpSwitch: if l.Op == OTYPE { ok |= Etype n.Op = OTYPE - n.Type = typPtr(l.Type) + n.Type = types.NewPtr(l.Type) n.Left = nil break OpSwitch } @@ -566,7 +567,7 @@ OpSwitch: op = n.Op } if op == OLSH || op == ORSH { - r = defaultlit(r, Types[TUINT]) + r = defaultlit(r, types.Types[TUINT]) n.Right = r t := r.Type if !t.IsInteger() || t.IsSigned() { @@ -618,7 +619,7 @@ OpSwitch: if r.Type.Etype != TBLANK { aop = assignop(l.Type, r.Type, nil) if aop != 0 { - if r.Type.IsInterface() && !l.Type.IsInterface() && !l.Type.IsComparable() { + if r.Type.IsInterface() && !l.Type.IsInterface() && !IsComparable(l.Type) { yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type)) n.Type = nil return n @@ -640,7 +641,7 @@ OpSwitch: if l.Type.Etype != TBLANK { aop = assignop(r.Type, l.Type, nil) if aop != 0 { - if l.Type.IsInterface() && !r.Type.IsInterface() && !r.Type.IsComparable() { + if l.Type.IsInterface() && !r.Type.IsInterface() && !IsComparable(r.Type) { yyerror("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type)) n.Type = nil return n @@ -679,7 +680,7 @@ OpSwitch: // okfor allows any array == array, map == map, func == func. // restrict to slice/map/func == nil and nil == slice/map/func. - if l.Type.IsArray() && !l.Type.IsComparable() { + if l.Type.IsArray() && !IsComparable(l.Type) { yyerror("invalid operation: %v (%v cannot be compared)", n, l.Type) n.Type = nil return n @@ -704,7 +705,7 @@ OpSwitch: } if l.Type.IsStruct() { - if f := l.Type.IncomparableField(); f != nil { + if f := IncomparableField(l.Type); f != nil { yyerror("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type) n.Type = nil return n @@ -714,7 +715,7 @@ OpSwitch: t = l.Type if iscmp[n.Op] { evconst(n) - t = idealbool + t = types.Idealbool if n.Op != OLITERAL { l, r = defaultlit2(l, r, true) n.Left = l @@ -725,7 +726,7 @@ OpSwitch: if et == TSTRING { if iscmp[n.Op] { // TODO(marvin): Fix Node.EType type union. - n.Etype = EType(n.Op) + n.Etype = types.EType(n.Op) n.Op = OCMPSTR } else if n.Op == OADD { // create OADDSTR node with list of strings in x + y + z + (w + v) + ... @@ -756,7 +757,7 @@ OpSwitch: } else // leave alone for back end if r.Type.IsInterface() == l.Type.IsInterface() { // TODO(marvin): Fix Node.EType type union. - n.Etype = EType(n.Op) + n.Etype = types.EType(n.Op) n.Op = OCMPIFACE } } @@ -823,7 +824,7 @@ OpSwitch: n.Type = nil return n } - n.Type = typPtr(t) + n.Type = types.NewPtr(t) break OpSwitch case OCOMPLIT: @@ -968,7 +969,7 @@ OpSwitch: } if n.Type != nil && !n.Type.IsInterface() { - var missing, have *Field + var missing, have *types.Field var ptr int if !implements(n.Type, t, &missing, &have, &ptr) { if have != nil && have.Sym == missing.Sym { @@ -1011,7 +1012,7 @@ OpSwitch: case TSTRING, TARRAY, TSLICE: n.Right = indexlit(n.Right) if t.IsString() { - n.Type = bytetype + n.Type = types.Bytetype } else { n.Type = t.Elem() } @@ -1146,7 +1147,7 @@ OpSwitch: l = n.Left } t := l.Type - var tp *Type + var tp *types.Type if t.IsString() { if hasmax { yyerror("invalid operation %v (3-index slice of string)", n) @@ -1157,7 +1158,7 @@ OpSwitch: n.Op = OSLICESTR } else if t.IsPtr() && t.Elem().IsArray() { tp = t.Elem() - n.Type = typSlice(tp.Elem()) + n.Type = types.NewSlice(tp.Elem()) dowidth(n.Type) if hasmax { n.Op = OSLICE3ARR @@ -1217,7 +1218,7 @@ OpSwitch: n.Left = defaultlit(n.Left, nil) l = n.Left if l.Op == OTYPE { - if n.Isddd() || l.Type.isDDDArray() { + if n.Isddd() || l.Type.IsDDDArray() { if !l.Type.Broke() { yyerror("invalid use of ... in type conversion to %v", l.Type) } @@ -1287,7 +1288,7 @@ OpSwitch: if t.Results().NumFields() == 1 { n.Type = l.Type.Results().Field(0).Type - if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Sym.Pkg.isRuntime() && n.Left.Sym.Name == "getg" { + if n.Op == OCALLFUNC && n.Left.Op == ONAME && isRuntimePkg(n.Left.Sym.Pkg) && n.Left.Sym.Name == "getg" { // Emit code for runtime.getg() directly instead of calling function. // Most such rewrites (for example the similar one for math.Sqrt) should be done in walk, // so that the ordering pass can make sure to preserve the semantics of the original code @@ -1319,7 +1320,7 @@ OpSwitch: // any side effects disappear; ignore init var r Node - nodconst(&r, Types[TUINTPTR], evalunsafe(n)) + nodconst(&r, types.Types[TUINTPTR], evalunsafe(n)) r.Orig = n n = &r @@ -1365,7 +1366,7 @@ OpSwitch: n.Orig = r } - n.Type = Types[cplxsubtype(t.Etype)] + n.Type = types.Types[cplxsubtype(t.Etype)] break OpSwitch } @@ -1374,7 +1375,7 @@ OpSwitch: case TSTRING: if Isconst(l, CTSTR) { var r Node - nodconst(&r, Types[TINT], int64(len(l.Val().U.(string)))) + nodconst(&r, types.Types[TINT], int64(len(l.Val().U.(string)))) r.Orig = n n = &r } @@ -1384,12 +1385,12 @@ OpSwitch: break } var r Node - nodconst(&r, Types[TINT], t.NumElem()) + nodconst(&r, types.Types[TINT], t.NumElem()) r.Orig = n n = &r } - n.Type = Types[TINT] + n.Type = types.Types[TINT] break OpSwitch badcall1: @@ -1421,8 +1422,8 @@ OpSwitch: } t = n.List.First().Type - l = t.Field(0).Nname - r = t.Field(1).Nname + l = asNode(t.Field(0).Nname) + r = asNode(t.Field(1).Nname) } else { if !twoarg(n) { n.Type = nil @@ -1451,7 +1452,7 @@ OpSwitch: return n } - var t *Type + var t *types.Type switch l.Type.Etype { default: yyerror("invalid operation: %v (arguments have type %v, expected floating-point)", n, l.Type) @@ -1459,13 +1460,13 @@ OpSwitch: return n case TIDEAL: - t = Types[TIDEAL] + t = types.Types[TIDEAL] case TFLOAT32: - t = Types[TCOMPLEX64] + t = types.Types[TCOMPLEX64] case TFLOAT64: - t = Types[TCOMPLEX128] + t = types.Types[TCOMPLEX128] } if l.Op == OLITERAL && r.Op == OLITERAL { @@ -1562,7 +1563,7 @@ OpSwitch: } // Unpack multiple-return result before type-checking. - var funarg *Type + var funarg *types.Type if t.IsFuncArgStruct() { funarg = t t = t.Field(0).Type @@ -1595,7 +1596,7 @@ OpSwitch: } if t.Elem().IsKind(TUINT8) && args.Second().Type.IsString() { - args.SetSecond(defaultlit(args.Second(), Types[TSTRING])) + args.SetSecond(defaultlit(args.Second(), types.Types[TSTRING])) break OpSwitch } @@ -1639,7 +1640,7 @@ OpSwitch: n.Left = args.First() n.Right = args.Second() n.List.Set(nil) - n.Type = Types[TINT] + n.Type = types.Types[TINT] n.Left = typecheck(n.Left, Erv) n.Right = typecheck(n.Right, Erv) if n.Left.Type == nil || n.Right.Type == nil { @@ -1655,7 +1656,7 @@ OpSwitch: // copy([]byte, string) if n.Left.Type.IsSlice() && n.Right.Type.IsString() { - if eqtype(n.Left.Type.Elem(), bytetype) { + if eqtype(n.Left.Type.Elem(), types.Bytetype) { break OpSwitch } yyerror("arguments to copy have different element types: %L and string", n.Left.Type) @@ -1800,7 +1801,7 @@ OpSwitch: l = args[i] i++ l = typecheck(l, Erv) - l = defaultlit(l, Types[TINT]) + l = defaultlit(l, types.Types[TINT]) if l.Type == nil { n.Type = nil return n @@ -1821,7 +1822,7 @@ OpSwitch: l = args[i] i++ l = typecheck(l, Erv) - l = defaultlit(l, Types[TINT]) + l = defaultlit(l, types.Types[TINT]) if l.Type == nil { n.Type = nil return n @@ -1870,7 +1871,7 @@ OpSwitch: } n.Left = l - n.Type = typPtr(t) + n.Type = types.NewPtr(t) break OpSwitch case OPRINT, OPRINTN: @@ -1880,7 +1881,7 @@ OpSwitch: for i1, n1 := range ls { // Special case for print: int constant is int64, not int. if Isconst(n1, CTINT) { - ls[i1] = defaultlit(ls[i1], Types[TINT64]) + ls[i1] = defaultlit(ls[i1], types.Types[TINT64]) } else { ls[i1] = defaultlit(ls[i1], nil) } @@ -1895,7 +1896,7 @@ OpSwitch: return n } n.Left = typecheck(n.Left, Erv) - n.Left = defaultlit(n.Left, Types[TINTER]) + n.Left = defaultlit(n.Left, types.Types[TINTER]) if n.Left.Type == nil { n.Type = nil return n @@ -1910,7 +1911,7 @@ OpSwitch: return n } - n.Type = Types[TINTER] + n.Type = types.Types[TINTER] break OpSwitch case OCLOSURE: @@ -1932,7 +1933,7 @@ OpSwitch: if !t.IsInterface() { Fatalf("OITAB of %v", t) } - n.Type = typPtr(Types[TUINTPTR]) + n.Type = types.NewPtr(types.Types[TUINTPTR]) break OpSwitch case OIDATA: @@ -1953,9 +1954,9 @@ OpSwitch: Fatalf("OSPTR of %v", t) } if t.IsString() { - n.Type = typPtr(Types[TUINT8]) + n.Type = types.NewPtr(types.Types[TUINT8]) } else { - n.Type = typPtr(t.Elem()) + n.Type = types.NewPtr(t.Elem()) } break OpSwitch @@ -1966,7 +1967,7 @@ OpSwitch: case OCFUNC: ok |= Erv n.Left = typecheck(n.Left, Erv) - n.Type = Types[TUINTPTR] + n.Type = types.Types[TUINTPTR] break OpSwitch case OCONVNOP: @@ -2183,7 +2184,7 @@ OpSwitch: return n } -func checksliceindex(l *Node, r *Node, tp *Type) bool { +func checksliceindex(l *Node, r *Node, tp *types.Type) bool { t := r.Type if t == nil { return false @@ -2345,8 +2346,8 @@ func twoarg(n *Node) bool { return true } -func lookdot1(errnode *Node, s *Sym, t *Type, fs *Fields, dostrcmp int) *Field { - var r *Field +func lookdot1(errnode *Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field { + var r *types.Field for _, f := range fs.Slice() { if dostrcmp != 0 && f.Sym.Name == s.Name { return f @@ -2374,7 +2375,7 @@ func lookdot1(errnode *Node, s *Sym, t *Type, fs *Fields, dostrcmp int) *Field { return r } -func looktypedot(n *Node, t *Type, dostrcmp int) bool { +func looktypedot(n *Node, t *types.Type, dostrcmp int) bool { s := n.Sym if t.IsInterface() { @@ -2416,32 +2417,32 @@ func looktypedot(n *Node, t *Type, dostrcmp int) bool { return true } -func derefall(t *Type) *Type { - for t != nil && t.Etype == Tptr { +func derefall(t *types.Type) *types.Type { + for t != nil && t.Etype == types.Tptr { t = t.Elem() } return t } -type typeSym struct { - t *Type - s *Sym +type typeSymKey struct { + t *types.Type + s *types.Sym } -// dotField maps (*Type, *Sym) pairs to the corresponding struct field (*Type with Etype==TFIELD). +// dotField maps (*types.Type, *types.Sym) pairs to the corresponding struct field (*types.Type with Etype==TFIELD). // It is a cache for use during usefield in walk.go, only enabled when field tracking. -var dotField = map[typeSym]*Field{} +var dotField = map[typeSymKey]*types.Field{} -func lookdot(n *Node, t *Type, dostrcmp int) *Field { +func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field { s := n.Sym dowidth(t) - var f1 *Field + var f1 *types.Field if t.IsStruct() || t.IsInterface() { f1 = lookdot1(n, s, t, t.Fields(), dostrcmp) } - var f2 *Field + var f2 *types.Field if n.Left.Type == t || n.Left.Type.Sym == nil { mt := methtype(t) if mt != nil { @@ -2465,7 +2466,7 @@ func lookdot(n *Node, t *Type, dostrcmp int) *Field { n.Xoffset = f1.Offset n.Type = f1.Type if obj.Fieldtrack_enabled > 0 { - dotField[typeSym{t.Orig, s}] = f1 + dotField[typeSymKey{t.Orig, s}] = f1 } if t.IsInterface() { if n.Left.Type.IsPtr() { @@ -2489,20 +2490,20 @@ func lookdot(n *Node, t *Type, dostrcmp int) *Field { dowidth(tt) rcvr := f2.Type.Recv().Type if !eqtype(rcvr, tt) { - if rcvr.Etype == Tptr && eqtype(rcvr.Elem(), tt) { + if rcvr.Etype == types.Tptr && eqtype(rcvr.Elem(), tt) { checklvalue(n.Left, "call pointer method on") n.Left = nod(OADDR, n.Left, nil) n.Left.SetImplicit(true) n.Left = typecheck(n.Left, Etype|Erv) - } else if tt.Etype == Tptr && rcvr.Etype != Tptr && eqtype(tt.Elem(), rcvr) { + } else if tt.Etype == types.Tptr && rcvr.Etype != types.Tptr && eqtype(tt.Elem(), rcvr) { n.Left = nod(OIND, n.Left, nil) n.Left.SetImplicit(true) n.Left = typecheck(n.Left, Etype|Erv) - } else if tt.Etype == Tptr && tt.Elem().Etype == Tptr && eqtype(derefall(tt), derefall(rcvr)) { + } else if tt.Etype == types.Tptr && tt.Elem().Etype == types.Tptr && eqtype(derefall(tt), derefall(rcvr)) { yyerror("calling method %v with receiver %L requires explicit dereference", n.Sym, n.Left) - for tt.Etype == Tptr { + for tt.Etype == types.Tptr { // Stop one level early for method with pointer receiver. - if rcvr.Etype == Tptr && tt.Elem().Etype != Tptr { + if rcvr.Etype == types.Tptr && tt.Elem().Etype != types.Tptr { break } n.Left = nod(OIND, n.Left, nil) @@ -2521,7 +2522,7 @@ func lookdot(n *Node, t *Type, dostrcmp int) *Field { pll = ll ll = ll.Left } - if pll.Implicit() && ll.Type.IsPtr() && ll.Type.Sym != nil && ll.Type.Sym.Def != nil && ll.Type.Sym.Def.Op == OTYPE { + if pll.Implicit() && ll.Type.IsPtr() && ll.Type.Sym != nil && asNode(ll.Type.Sym.Def) != nil && asNode(ll.Type.Sym.Def).Op == OTYPE { // It is invalid to automatically dereference a named pointer type when selecting a method. // Make n->left == ll to clarify error message. n.Left = ll @@ -2550,7 +2551,7 @@ func nokeys(l Nodes) bool { return true } -func hasddd(t *Type) bool { +func hasddd(t *types.Type) bool { for _, tl := range t.Fields().Slice() { if tl.Isddd() { return true @@ -2561,8 +2562,8 @@ func hasddd(t *Type) bool { } // typecheck assignment: type list = expression list -func typecheckaste(op Op, call *Node, isddd bool, tstruct *Type, nl Nodes, desc func() string) { - var t *Type +func typecheckaste(op Op, call *Node, isddd bool, tstruct *types.Type, nl Nodes, desc func() string) { + var t *types.Type var n *Node var n1 int var n2 int @@ -2740,7 +2741,7 @@ toomany: goto out } -func errorDetails(nl Nodes, tstruct *Type, isddd bool) string { +func errorDetails(nl Nodes, tstruct *types.Type, isddd bool) string { // If we don't know any type at a call site, let's suppress any return // message signatures. See Issue https://golang.org/issues/19012. if tstruct == nil { @@ -2758,20 +2759,20 @@ func errorDetails(nl Nodes, tstruct *Type, isddd bool) string { // sigrepr is a type's representation to the outside world, // in string representations of return signatures // e.g in error messages about wrong arguments to return. -func (t *Type) sigrepr() string { +func sigrepr(t *types.Type) string { switch t { default: return t.String() - case Types[TIDEAL]: + case types.Types[TIDEAL]: // "untyped number" is not commonly used // outside of the compiler, so let's use "number". return "number" - case idealstring: + case types.Idealstring: return "string" - case idealbool: + case types.Idealbool: return "bool" } } @@ -2786,11 +2787,11 @@ func (nl Nodes) retsigerr(isddd bool) string { var typeStrings []string if nl.Len() == 1 && nl.First().Type != nil && nl.First().Type.IsFuncArgStruct() { for _, f := range nl.First().Type.Fields().Slice() { - typeStrings = append(typeStrings, f.Type.sigrepr()) + typeStrings = append(typeStrings, sigrepr(f.Type)) } } else { for _, n := range nl.Slice() { - typeStrings = append(typeStrings, n.Type.sigrepr()) + typeStrings = append(typeStrings, sigrepr(n.Type)) } } @@ -2870,7 +2871,7 @@ func keydup(n *Node, hash map[uint32][]*Node) { // iscomptype reports whether type t is a composite literal type // or a pointer to one. -func iscomptype(t *Type) bool { +func iscomptype(t *types.Type) bool { if t.IsPtr() { t = t.Elem() } @@ -2883,7 +2884,7 @@ func iscomptype(t *Type) bool { } } -func pushtype(n *Node, t *Type) { +func pushtype(n *Node, t *types.Type) { if n == nil || n.Op != OCOMPLIT || !iscomptype(t) { return } @@ -2966,7 +2967,7 @@ func typecheckcomplit(n *Node) *Node { } var length, i int64 - checkBounds := t.IsArray() && !t.isDDDArray() + checkBounds := t.IsArray() && !t.IsDDDArray() nl := n.List.Slice() for i2, l := range nl { setlineno(l) @@ -3008,7 +3009,7 @@ func typecheckcomplit(n *Node) *Node { } } - if t.isDDDArray() { + if t.IsDDDArray() { t.SetNumElem(length) } if t.IsSlice() { @@ -3311,7 +3312,7 @@ func typecheckas(n *Node) { } } -func checkassignto(src *Type, dst *Node) { +func checkassignto(src *types.Type, dst *Node) { var why string if assignop(src, dst.Type, &why) == 0 { @@ -3419,10 +3420,10 @@ func typecheckas2(n *Node) { } l := n.List.Second() if l.Type != nil && !l.Type.IsBoolean() { - checkassignto(Types[TBOOL], l) + checkassignto(types.Types[TBOOL], l) } if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil { - l.Type = Types[TBOOL] + l.Type = types.Types[TBOOL] } goto out } @@ -3456,7 +3457,7 @@ func typecheckfunc(n *Node) { return } n.Type = t - t.SetNname(n.Func.Nname) + t.FuncType().Nname = asTypesNode(n.Func.Nname) rcvr := t.Recv() if rcvr != nil && n.Func.Shortname != nil { n.Func.Nname.Sym = methodname(n.Func.Shortname, rcvr.Type) @@ -3504,13 +3505,13 @@ var ntypecheckdeftype int var methodqueue []*Node func domethod(n *Node) { - nt := n.Type.Nname() + nt := asNode(n.Type.FuncType().Nname) nt = typecheck(nt, Etype) if nt.Type == nil { // type check failed; leave empty func // TODO(mdempsky): Fix Type rekinding. n.Type.Etype = TFUNC - n.Type.nod = nil + n.Type.Nod = nil return } @@ -3530,7 +3531,7 @@ func domethod(n *Node) { // TODO(mdempsky): Fix Type rekinding. *n.Type = *nt.Type - n.Type.nod = nil + n.Type.Nod = nil checkwidth(n.Type) } @@ -3542,18 +3543,18 @@ type mapqueueval struct { // tracks the line numbers at which forward types are first used as map keys var mapqueue []mapqueueval -func copytype(n *Node, t *Type) { +func copytype(n *Node, t *types.Type) { if t.Etype == TFORW { // This type isn't computed yet; when it is, update n. - t.ForwardType().Copyto = append(t.ForwardType().Copyto, n) + t.ForwardType().Copyto = append(t.ForwardType().Copyto, asTypesNode(n)) return } embedlineno := n.Type.ForwardType().Embedlineno l := n.Type.ForwardType().Copyto - ptrTo := n.Type.ptrTo - sliceOf := n.Type.sliceOf + ptrBase := n.Type.PtrBase + sliceOf := n.Type.SliceOf // TODO(mdempsky): Fix Type rekinding. *n.Type = *t @@ -3569,14 +3570,14 @@ func copytype(n *Node, t *Type) { // to the existing type, but the method set of an interface // type [...] remains unchanged." if !t.IsInterface() { - t.methods = Fields{} - t.allMethods = Fields{} + *t.Methods() = types.Fields{} + *t.AllMethods() = types.Fields{} } - t.nod = n + t.Nod = asTypesNode(n) t.SetDeferwidth(false) - t.ptrTo = ptrTo - t.sliceOf = sliceOf + t.PtrBase = ptrBase + t.SliceOf = sliceOf // Propagate go:notinheap pragma from the Name to the Type. if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma&NotInHeap != 0 { @@ -3585,7 +3586,7 @@ func copytype(n *Node, t *Type) { // Update nodes waiting on this type. for _, n := range l { - copytype(n, t) + copytype(asNode(n), t) } // Double-check use of type as embedded type. @@ -3643,7 +3644,7 @@ ret: } for _, e := range mapqueue { lineno = e.lno - if !e.n.Type.IsComparable() { + if !IsComparable(e.n.Type) { yyerror("invalid map key type %v", e.n.Type) } } @@ -3811,7 +3812,7 @@ func typecheckdef(n *Node) *Node { n.SetDiag(true) goto ret } - n.Sym.Def = p.Ntype + n.Sym.Def = asTypesNode(p.Ntype) } break } @@ -3821,8 +3822,8 @@ func typecheckdef(n *Node) *Node { defercheckwidth() } n.Walkdef = 1 - n.Type = typ(TFORW) - n.Type.nod = n + n.Type = types.New(TFORW) + n.Type.Nod = asTypesNode(n) n.Type.Sym = n.Sym // TODO(gri) this also happens in typecheckdeftype(n) - where should it happen? nerrors0 := nerrors typecheckdeftype(n) @@ -3852,7 +3853,7 @@ ret: return n } -func checkmake(t *Type, arg string, n *Node) bool { +func checkmake(t *types.Type, arg string, n *Node) bool { if !n.Type.IsInteger() && n.Type.Etype != TIDEAL { yyerror("non-integer %s argument in make(%v) - %v", arg, t, n.Type) return false @@ -3874,7 +3875,7 @@ func checkmake(t *Type, arg string, n *Node) bool { } // defaultlit is necessary for non-constants too: n might be 1.1<x, for an arbitrary +// and optimizer-centric notion of comparison. +func cmptyp(t, x *types.Type) ssa.Cmp { + // This follows the structure of eqtype in subr.go + // with two exceptions. + // 1. Symbols are compared more carefully because a <,=,> result is desired. + // 2. Maps are treated specially to avoid endless recursion -- maps + // contain an internal data type not expressible in Go source code. + if t == x { + return ssa.CMPeq + } + if t == nil { + return ssa.CMPlt + } + if x == nil { + return ssa.CMPgt + } + + if t.Etype != x.Etype { + return cmpForNe(t.Etype < x.Etype) + } + + if t.Sym != nil || x.Sym != nil { + // Special case: we keep byte and uint8 separate + // for error messages. Treat them as equal. + switch t.Etype { + case TUINT8: + if (t == types.Types[TUINT8] || t == types.Bytetype) && (x == types.Types[TUINT8] || x == types.Bytetype) { + return ssa.CMPeq + } + + case TINT32: + if (t == types.Types[types.Runetype.Etype] || t == types.Runetype) && (x == types.Types[types.Runetype.Etype] || x == types.Runetype) { + return ssa.CMPeq + } + } + } + + if c := cmpsym(t.Sym, x.Sym); c != ssa.CMPeq { + return c + } + + if x.Sym != nil { + // Syms non-nil, if vargens match then equal. + if t.Vargen != x.Vargen { + return cmpForNe(t.Vargen < x.Vargen) + } + return ssa.CMPeq + } + // both syms nil, look at structure below. + + switch t.Etype { + case TBOOL, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TUNSAFEPTR, TUINTPTR, + TINT8, TINT16, TINT32, TINT64, TINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINT: + return ssa.CMPeq + } + + switch t.Etype { + case TMAP: + if c := cmptyp(t.Key(), x.Key()); c != ssa.CMPeq { + return c + } + return cmptyp(t.Val(), x.Val()) + + case TPTR32, TPTR64, TSLICE: + // No special cases for these, they are handled + // by the general code after the switch. + + case TSTRUCT: + if t.StructType().Map == nil { + if x.StructType().Map != nil { + return ssa.CMPlt // nil < non-nil + } + // to the fallthrough + } else if x.StructType().Map == nil { + return ssa.CMPgt // nil > non-nil + } else if t.StructType().Map.MapType().Bucket == t { + // Both have non-nil Map + // Special case for Maps which include a recursive type where the recursion is not broken with a named type + if x.StructType().Map.MapType().Bucket != x { + return ssa.CMPlt // bucket maps are least + } + return cmptyp(t.StructType().Map, x.StructType().Map) + } else if x.StructType().Map.MapType().Bucket == x { + return ssa.CMPgt // bucket maps are least + } // If t != t.Map.Bucket, fall through to general case + + fallthrough + case TINTER: + t1, ti := types.IterFields(t) + x1, xi := types.IterFields(x) + for ; t1 != nil && x1 != nil; t1, x1 = ti.Next(), xi.Next() { + if t1.Embedded != x1.Embedded { + return cmpForNe(t1.Embedded < x1.Embedded) + } + if t1.Note != x1.Note { + return cmpForNe(t1.Note < x1.Note) + } + if c := cmpsym(t1.Sym, x1.Sym); c != ssa.CMPeq { + return c + } + if c := cmptyp(t1.Type, x1.Type); c != ssa.CMPeq { + return c + } + } + if t1 != x1 { + return cmpForNe(t1 == nil) + } + return ssa.CMPeq + + case TFUNC: + for _, f := range types.RecvsParamsResults { + // Loop over fields in structs, ignoring argument names. + ta, ia := types.IterFields(f(t)) + tb, ib := types.IterFields(f(x)) + for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() { + if ta.Isddd() != tb.Isddd() { + return cmpForNe(!ta.Isddd()) + } + if c := cmptyp(ta.Type, tb.Type); c != ssa.CMPeq { + return c + } + } + if ta != tb { + return cmpForNe(ta == nil) + } + } + return ssa.CMPeq + + case TARRAY: + if t.NumElem() != x.NumElem() { + return cmpForNe(t.NumElem() < x.NumElem()) + } + + case TCHAN: + if t.ChanDir() != x.ChanDir() { + return cmpForNe(t.ChanDir() < x.ChanDir()) + } + + default: + e := fmt.Sprintf("Do not know how to compare %v with %v", t, x) + panic(e) + } + + // Common element type comparison for TARRAY, TCHAN, TPTR32, TPTR64, and TSLICE. + return cmptyp(t.Elem(), x.Elem()) +} diff --git a/src/cmd/compile/internal/gc/types_acc.go b/src/cmd/compile/internal/gc/types_acc.go new file mode 100644 index 0000000000..7240f726f6 --- /dev/null +++ b/src/cmd/compile/internal/gc/types_acc.go @@ -0,0 +1,16 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements convertions between *types.Node and *Node. +// TODO(gri) try to eliminate these soon + +package gc + +import ( + "cmd/compile/internal/types" + "unsafe" +) + +func asNode(n *types.Node) *Node { return (*Node)(unsafe.Pointer(n)) } +func asTypesNode(n *Node) *types.Node { return (*types.Node)(unsafe.Pointer(n)) } diff --git a/src/cmd/compile/internal/gc/universe.go b/src/cmd/compile/internal/gc/universe.go index 50f7335cd0..f15d84b3a5 100644 --- a/src/cmd/compile/internal/gc/universe.go +++ b/src/cmd/compile/internal/gc/universe.go @@ -2,16 +2,20 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// TODO(gri) This file should probably become part of package types. + package gc +import "cmd/compile/internal/types" + // builtinpkg is a fake package that declares the universe block. -var builtinpkg *Pkg +var builtinpkg *types.Pkg -var itable *Type // distinguished *byte +var itable *types.Type // distinguished *byte var basicTypes = [...]struct { name string - etype EType + etype types.EType }{ {"int8", TINT8}, {"int16", TINT16}, @@ -31,10 +35,10 @@ var basicTypes = [...]struct { var typedefs = [...]struct { name string - etype EType + etype types.EType width *int - sameas32 EType - sameas64 EType + sameas32 types.EType + sameas64 types.EType }{ {"int", TINT, &Widthint, TINT32, TINT64}, {"uint", TUINT, &Widthint, TUINT32, TUINT64}, @@ -82,77 +86,77 @@ func initUniverse() { func lexinit() { for _, s := range basicTypes { etype := s.etype - if int(etype) >= len(Types) { + if int(etype) >= len(types.Types) { Fatalf("lexinit: %s bad etype", s.name) } s2 := builtinpkg.Lookup(s.name) - t := Types[etype] + t := types.Types[etype] if t == nil { - t = typ(etype) + t = types.New(etype) t.Sym = s2 if etype != TANY && etype != TSTRING { dowidth(t) } - Types[etype] = t + types.Types[etype] = t } - s2.Def = typenod(t) - s2.Def.Name = new(Name) + s2.Def = asTypesNode(typenod(t)) + asNode(s2.Def).Name = new(Name) } for _, s := range builtinFuncs { // TODO(marvin): Fix Node.EType type union. s2 := builtinpkg.Lookup(s.name) - s2.Def = newname(s2) - s2.Def.Etype = EType(s.op) + s2.Def = asTypesNode(newname(s2)) + asNode(s2.Def).Etype = types.EType(s.op) } for _, s := range unsafeFuncs { s2 := unsafepkg.Lookup(s.name) - s2.Def = newname(s2) - s2.Def.Etype = EType(s.op) + s2.Def = asTypesNode(newname(s2)) + asNode(s2.Def).Etype = types.EType(s.op) } - idealstring = typ(TSTRING) - idealbool = typ(TBOOL) - Types[TANY] = typ(TANY) + types.Idealstring = types.New(TSTRING) + types.Idealbool = types.New(TBOOL) + types.Types[TANY] = types.New(TANY) s := builtinpkg.Lookup("true") - s.Def = nodbool(true) - s.Def.Sym = lookup("true") - s.Def.Name = new(Name) - s.Def.Type = idealbool + s.Def = asTypesNode(nodbool(true)) + asNode(s.Def).Sym = lookup("true") + asNode(s.Def).Name = new(Name) + asNode(s.Def).Type = types.Idealbool s = builtinpkg.Lookup("false") - s.Def = nodbool(false) - s.Def.Sym = lookup("false") - s.Def.Name = new(Name) - s.Def.Type = idealbool + s.Def = asTypesNode(nodbool(false)) + asNode(s.Def).Sym = lookup("false") + asNode(s.Def).Name = new(Name) + asNode(s.Def).Type = types.Idealbool s = lookup("_") s.Block = -100 - s.Def = newname(s) - Types[TBLANK] = typ(TBLANK) - s.Def.Type = Types[TBLANK] - nblank = s.Def + s.Def = asTypesNode(newname(s)) + types.Types[TBLANK] = types.New(TBLANK) + asNode(s.Def).Type = types.Types[TBLANK] + nblank = asNode(s.Def) s = builtinpkg.Lookup("_") s.Block = -100 - s.Def = newname(s) - Types[TBLANK] = typ(TBLANK) - s.Def.Type = Types[TBLANK] + s.Def = asTypesNode(newname(s)) + types.Types[TBLANK] = types.New(TBLANK) + asNode(s.Def).Type = types.Types[TBLANK] - Types[TNIL] = typ(TNIL) + types.Types[TNIL] = types.New(TNIL) s = builtinpkg.Lookup("nil") var v Val v.U = new(NilVal) - s.Def = nodlit(v) - s.Def.Sym = s - s.Def.Name = new(Name) + s.Def = asTypesNode(nodlit(v)) + asNode(s.Def).Sym = s + asNode(s.Def).Name = new(Name) s = builtinpkg.Lookup("iota") - s.Def = nod(OIOTA, nil, nil) - s.Def.Sym = s - s.Def.Name = new(Name) + s.Def = asTypesNode(nod(OIOTA, nil, nil)) + asNode(s.Def).Sym = s + asNode(s.Def).Name = new(Name) } func typeinit() { @@ -160,26 +164,26 @@ func typeinit() { Fatalf("typeinit before betypeinit") } - for et := EType(0); et < NTYPE; et++ { + for et := types.EType(0); et < NTYPE; et++ { simtype[et] = et } - Types[TPTR32] = typ(TPTR32) - dowidth(Types[TPTR32]) + types.Types[TPTR32] = types.New(TPTR32) + dowidth(types.Types[TPTR32]) - Types[TPTR64] = typ(TPTR64) - dowidth(Types[TPTR64]) + types.Types[TPTR64] = types.New(TPTR64) + dowidth(types.Types[TPTR64]) - t := typ(TUNSAFEPTR) - Types[TUNSAFEPTR] = t + t := types.New(TUNSAFEPTR) + types.Types[TUNSAFEPTR] = t t.Sym = unsafepkg.Lookup("Pointer") - t.Sym.Def = typenod(t) - t.Sym.Def.Name = new(Name) - dowidth(Types[TUNSAFEPTR]) + t.Sym.Def = asTypesNode(typenod(t)) + asNode(t.Sym.Def).Name = new(Name) + dowidth(types.Types[TUNSAFEPTR]) - Tptr = TPTR32 + types.Tptr = TPTR32 if Widthptr == 8 { - Tptr = TPTR64 + types.Tptr = TPTR64 } for et := TINT8; et <= TUINT64; et++ { @@ -198,7 +202,7 @@ func typeinit() { isforw[TFORW] = true // initialize okfor - for et := EType(0); et < NTYPE; et++ { + for et := types.EType(0); et < NTYPE; et++ { if isInt[et] || et == TIDEAL { okforeq[et] = true okforcmp[et] = true @@ -339,20 +343,20 @@ func typeinit() { minfltval[TCOMPLEX128] = minfltval[TFLOAT64] // for walk to use in error messages - Types[TFUNC] = functype(nil, nil, nil) + types.Types[TFUNC] = functype(nil, nil, nil) // types used in front end - // types[TNIL] got set early in lexinit - Types[TIDEAL] = typ(TIDEAL) + // types.Types[TNIL] got set early in lexinit + types.Types[TIDEAL] = types.New(TIDEAL) - Types[TINTER] = typ(TINTER) + types.Types[TINTER] = types.New(TINTER) // simple aliases - simtype[TMAP] = Tptr + simtype[TMAP] = types.Tptr - simtype[TCHAN] = Tptr - simtype[TFUNC] = Tptr - simtype[TUNSAFEPTR] = Tptr + simtype[TCHAN] = types.Tptr + simtype[TFUNC] = types.Tptr + simtype[TUNSAFEPTR] = types.Tptr array_array = int(Rnd(0, int64(Widthptr))) array_nel = int(Rnd(int64(array_array)+int64(Widthptr), int64(Widthint))) @@ -362,39 +366,39 @@ func typeinit() { // string is same as slice wo the cap sizeof_String = int(Rnd(int64(array_nel)+int64(Widthint), int64(Widthptr))) - dowidth(Types[TSTRING]) - dowidth(idealstring) + dowidth(types.Types[TSTRING]) + dowidth(types.Idealstring) - itable = typPtr(Types[TUINT8]) + itable = types.NewPtr(types.Types[TUINT8]) } -func makeErrorInterface() *Type { - field := newField() - field.Type = Types[TSTRING] - f := functypefield(fakethisfield(), nil, []*Field{field}) +func makeErrorInterface() *types.Type { + field := types.NewField() + field.Type = types.Types[TSTRING] + f := functypefield(fakethisfield(), nil, []*types.Field{field}) - field = newField() + field = types.NewField() field.Sym = lookup("Error") field.Type = f - t := typ(TINTER) - t.SetInterface([]*Field{field}) + t := types.New(TINTER) + t.SetInterface([]*types.Field{field}) return t } func lexinit1() { // error type s := builtinpkg.Lookup("error") - errortype = makeErrorInterface() - errortype.Sym = s + types.Errortype = makeErrorInterface() + types.Errortype.Sym = s // TODO: If we can prove that it's safe to set errortype.Orig here // than we don't need the special errortype/errorInterface case in // bexport.go. See also issue #15920. // errortype.Orig = makeErrorInterface() - s.Def = typenod(errortype) + s.Def = asTypesNode(typenod(types.Errortype)) // We create separate byte and rune types for better error messages - // rather than just creating type alias *Sym's for the uint8 and + // rather than just creating type alias *types.Sym's for the uint8 and // int32 types. Hence, (bytetype|runtype).Sym.isAlias() is false. // TODO(gri) Should we get rid of this special case (at the cost // of less informative error messages involving bytes and runes)? @@ -403,17 +407,17 @@ func lexinit1() { // byte alias s = builtinpkg.Lookup("byte") - bytetype = typ(TUINT8) - bytetype.Sym = s - s.Def = typenod(bytetype) - s.Def.Name = new(Name) + types.Bytetype = types.New(TUINT8) + types.Bytetype.Sym = s + s.Def = asTypesNode(typenod(types.Bytetype)) + asNode(s.Def).Name = new(Name) // rune alias s = builtinpkg.Lookup("rune") - runetype = typ(TINT32) - runetype.Sym = s - s.Def = typenod(runetype) - s.Def.Name = new(Name) + types.Runetype = types.New(TINT32) + types.Runetype.Sym = s + s.Def = asTypesNode(typenod(types.Runetype)) + asNode(s.Def).Name = new(Name) // backend-dependent builtin types (e.g. int). for _, s := range typedefs { @@ -430,11 +434,11 @@ func lexinit1() { minintval[s.etype] = minintval[sameas] maxintval[s.etype] = maxintval[sameas] - t := typ(s.etype) + t := types.New(s.etype) t.Sym = s1 - Types[s.etype] = t - s1.Def = typenod(t) - s1.Def.Name = new(Name) + types.Types[s.etype] = t + s1.Def = asTypesNode(typenod(t)) + asNode(s1.Def).Name = new(Name) s1.Origpkg = builtinpkg dowidth(t) @@ -461,7 +465,7 @@ func finishUniverse() { } nodfp = newname(lookup(".fp")) - nodfp.Type = Types[TINT32] + nodfp.Type = types.Types[TINT32] nodfp.Class = PPARAM nodfp.SetUsed(true) } diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 45360f4890..f1d1f573c7 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -5,6 +5,7 @@ package gc import ( + "cmd/compile/internal/types" "cmd/internal/obj" "cmd/internal/sys" "fmt" @@ -405,9 +406,9 @@ func walkexprlistcheap(s []*Node, init *Nodes) { // Build name of function for interface conversion. // Not all names are possible // (e.g., we'll never generate convE2E or convE2I or convI2E). -func convFuncName(from, to *Type) string { - tkind := to.iet() - switch from.iet() { +func convFuncName(from, to *types.Type) string { + tkind := to.Tie() + switch from.Tie() { case 'I': switch tkind { case 'I': @@ -419,15 +420,15 @@ func convFuncName(from, to *Type) string { switch { case from.Size() == 2 && from.Align == 2: return "convT2E16" - case from.Size() == 4 && from.Align == 4 && !haspointers(from): + case from.Size() == 4 && from.Align == 4 && !types.Haspointers(from): return "convT2E32" - case from.Size() == 8 && from.Align == Types[TUINT64].Align && !haspointers(from): + case from.Size() == 8 && from.Align == types.Types[TUINT64].Align && !types.Haspointers(from): return "convT2E64" case from.IsString(): return "convT2Estring" case from.IsSlice(): return "convT2Eslice" - case !haspointers(from): + case !types.Haspointers(from): return "convT2Enoptr" } return "convT2E" @@ -435,21 +436,21 @@ func convFuncName(from, to *Type) string { switch { case from.Size() == 2 && from.Align == 2: return "convT2I16" - case from.Size() == 4 && from.Align == 4 && !haspointers(from): + case from.Size() == 4 && from.Align == 4 && !types.Haspointers(from): return "convT2I32" - case from.Size() == 8 && from.Align == Types[TUINT64].Align && !haspointers(from): + case from.Size() == 8 && from.Align == types.Types[TUINT64].Align && !types.Haspointers(from): return "convT2I64" case from.IsString(): return "convT2Istring" case from.IsSlice(): return "convT2Islice" - case !haspointers(from): + case !types.Haspointers(from): return "convT2Inoptr" } return "convT2I" } } - Fatalf("unknown conv func %c2%c", from.iet(), to.iet()) + Fatalf("unknown conv func %c2%c", from.Tie(), to.Tie()) panic("unreachable") } @@ -822,7 +823,7 @@ opswitch: // don't generate a = *var if a is _ if !isblank(a) { - var_ := temp(typPtr(t.Val())) + var_ := temp(types.NewPtr(t.Val())) var_.Typecheck = 1 var_.SetNonNil(true) // mapaccess always returns a non-nil pointer n.List.SetFirst(var_) @@ -874,10 +875,10 @@ opswitch: if staticbytes == nil { staticbytes = newname(Runtimepkg.Lookup("staticbytes")) staticbytes.Class = PEXTERN - staticbytes.Type = typArray(Types[TUINT8], 256) + staticbytes.Type = types.NewArray(types.Types[TUINT8], 256) zerobase = newname(Runtimepkg.Lookup("zerobase")) zerobase.Class = PEXTERN - zerobase.Type = Types[TUINTPTR] + zerobase.Type = types.Types[TUINTPTR] } // Optimize convT2{E,I} for many cases in which T is not pointer-shaped, @@ -931,7 +932,7 @@ opswitch: init.Append(nod(OAS, c, n.Left)) // Get the itab out of the interface. - tmp := temp(typPtr(Types[TUINT8])) + tmp := temp(types.NewPtr(types.Types[TUINT8])) init.Append(nod(OAS, tmp, typecheck(nod(OITAB, c, nil), Erv))) // Get the type out of the itab. @@ -940,7 +941,7 @@ opswitch: init.Append(nif) // Build the result. - e := nod(OEFACE, tmp, ifaceData(c, typPtr(Types[TUINT8]))) + e := nod(OEFACE, tmp, ifaceData(c, types.NewPtr(types.Types[TUINT8]))) e.Type = n.Type // assign type manually, typecheck doesn't understand OEFACE. e.Typecheck = 1 n = e @@ -989,24 +990,24 @@ opswitch: if thearch.LinkArch.Family == sys.ARM || thearch.LinkArch.Family == sys.MIPS { if n.Left.Type.IsFloat() { if n.Type.Etype == TINT64 { - n = mkcall("float64toint64", n.Type, init, conv(n.Left, Types[TFLOAT64])) + n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) break } if n.Type.Etype == TUINT64 { - n = mkcall("float64touint64", n.Type, init, conv(n.Left, Types[TFLOAT64])) + n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) break } } if n.Type.IsFloat() { if n.Left.Type.Etype == TINT64 { - n = conv(mkcall("int64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TINT64])), n.Type) + n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type) break } if n.Left.Type.Etype == TUINT64 { - n = conv(mkcall("uint64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TUINT64])), n.Type) + n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type) break } } @@ -1015,31 +1016,31 @@ opswitch: if thearch.LinkArch.Family == sys.I386 { if n.Left.Type.IsFloat() { if n.Type.Etype == TINT64 { - n = mkcall("float64toint64", n.Type, init, conv(n.Left, Types[TFLOAT64])) + n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) break } if n.Type.Etype == TUINT64 { - n = mkcall("float64touint64", n.Type, init, conv(n.Left, Types[TFLOAT64])) + n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) break } if n.Type.Etype == TUINT32 || n.Type.Etype == TUINT || n.Type.Etype == TUINTPTR { - n = mkcall("float64touint32", n.Type, init, conv(n.Left, Types[TFLOAT64])) + n = mkcall("float64touint32", n.Type, init, conv(n.Left, types.Types[TFLOAT64])) break } } if n.Type.IsFloat() { if n.Left.Type.Etype == TINT64 { - n = conv(mkcall("int64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TINT64])), n.Type) + n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type) break } if n.Left.Type.Etype == TUINT64 { - n = conv(mkcall("uint64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TUINT64])), n.Type) + n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type) break } if n.Left.Type.Etype == TUINT32 || n.Left.Type.Etype == TUINT || n.Left.Type.Etype == TUINTPTR { - n = conv(mkcall("uint32tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TUINT32])), n.Type) + n = conv(mkcall("uint32tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT32])), n.Type) break } } @@ -1063,7 +1064,7 @@ opswitch: if isComplex[et] && n.Op == ODIV { t := n.Type - n = mkcall("complex128div", Types[TCOMPLEX128], init, conv(n.Left, Types[TCOMPLEX128]), conv(n.Right, Types[TCOMPLEX128])) + n = mkcall("complex128div", types.Types[TCOMPLEX128], init, conv(n.Left, types.Types[TCOMPLEX128]), conv(n.Right, types.Types[TCOMPLEX128])) n = conv(n, t) break } @@ -1107,7 +1108,7 @@ opswitch: } else { fn += "mod" } - n = mkcall(fn, n.Type, init, conv(n.Left, Types[et]), conv(n.Right, Types[et])) + n = mkcall(fn, n.Type, init, conv(n.Left, types.Types[et]), conv(n.Right, types.Types[et])) } case OINDEX: @@ -1178,13 +1179,13 @@ opswitch: } if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/hashmap.go:maxZero - n = mkcall1(mapfn(mapaccess1[fast], t), typPtr(t.Val()), init, typename(t), map_, key) + n = mkcall1(mapfn(mapaccess1[fast], t), types.NewPtr(t.Val()), init, typename(t), map_, key) } else { z := zeroaddr(w) - n = mkcall1(mapfn("mapaccess1_fat", t), typPtr(t.Val()), init, typename(t), map_, key, z) + n = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Val()), init, typename(t), map_, key, z) } } - n.Type = typPtr(t.Val()) + n.Type = types.NewPtr(t.Val()) n.SetNonNil(true) // mapaccess1* and mapassign always return non-nil pointers. n = nod(OIND, n, nil) n.Type = t.Val() @@ -1303,7 +1304,7 @@ opswitch: n.Left = cheapexpr(n.Left, init) n.Right = cheapexpr(n.Right, init) - r = mkcall("eqstring", Types[TBOOL], init, conv(n.Left, Types[TSTRING]), conv(n.Right, Types[TSTRING])) + r = mkcall("eqstring", types.Types[TBOOL], init, conv(n.Left, types.Types[TSTRING]), conv(n.Right, types.Types[TSTRING])) // quick check of len before full compare for == or != // eqstring assumes that the lengths are equal @@ -1321,7 +1322,7 @@ opswitch: r = walkexpr(r, nil) } else { // sys_cmpstring(s1, s2) :: 0 - r = mkcall("cmpstring", Types[TINT], init, conv(n.Left, Types[TSTRING]), conv(n.Right, Types[TSTRING])) + r = mkcall("cmpstring", types.Types[TINT], init, conv(n.Left, types.Types[TSTRING]), conv(n.Right, types.Types[TSTRING])) // TODO(marvin): Fix Node.EType type union. r = nod(Op(n.Etype), r, nodintconst(0)) } @@ -1351,7 +1352,7 @@ opswitch: n = mkcall1(fn, nil, init, n.Left) case OMAKECHAN: - n = mkcall1(chanfn("makechan", 1, n.Type), n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64])) + n = mkcall1(chanfn("makechan", 1, n.Type), n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64])) case OMAKEMAP: t := n.Type @@ -1380,7 +1381,7 @@ opswitch: fn := syslook("makemap") fn = substArgTypes(fn, hmap(t), mapbucket(t), t.Key(), t.Val()) - n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]), a, r) + n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]), a, r) case OMAKESLICE: l := n.Left @@ -1396,7 +1397,7 @@ opswitch: } // var arr [r]T // n = arr[:l] - t = typArray(t.Elem(), nonnegintconst(r)) // [r]T + t = types.NewArray(t.Elem(), nonnegintconst(r)) // [r]T var_ := temp(t) a := nod(OAS, var_, nil) // zero temp a = typecheck(a, Etop) @@ -1419,7 +1420,7 @@ opswitch: len, cap := l, r fnname := "makeslice64" - argtype := Types[TINT64] + argtype := types.Types[TINT64] // typechecking guarantees that TIDEAL len/cap are positive and fit in an int. // The case of len or cap overflow when converting TUINT or TUINTPTR to TINT @@ -1427,7 +1428,7 @@ opswitch: if (len.Type.IsKind(TIDEAL) || maxintval[len.Type.Etype].Cmp(maxintval[TUINT]) <= 0) && (cap.Type.IsKind(TIDEAL) || maxintval[cap.Type.Etype].Cmp(maxintval[TUINT]) <= 0) { fnname = "makeslice" - argtype = Types[TINT] + argtype = types.Types[TINT] } fn := syslook(fnname) @@ -1438,19 +1439,19 @@ opswitch: case ORUNESTR: a := nodnil() if n.Esc == EscNone { - t := typArray(Types[TUINT8], 4) + t := types.NewArray(types.Types[TUINT8], 4) var_ := temp(t) a = nod(OADDR, var_, nil) } // intstring(*[4]byte, rune) - n = mkcall("intstring", n.Type, init, a, conv(n.Left, Types[TINT64])) + n = mkcall("intstring", n.Type, init, a, conv(n.Left, types.Types[TINT64])) case OARRAYBYTESTR: a := nodnil() if n.Esc == EscNone { // Create temporary buffer for string on stack. - t := typArray(Types[TUINT8], tmpstringbufsize) + t := types.NewArray(types.Types[TUINT8], tmpstringbufsize) a = nod(OADDR, temp(t), nil) } @@ -1476,7 +1477,7 @@ opswitch: if n.Esc == EscNone { // Create temporary buffer for string on stack. - t := typArray(Types[TUINT8], tmpstringbufsize) + t := types.NewArray(types.Types[TUINT8], tmpstringbufsize) a = nod(OADDR, temp(t), nil) } @@ -1489,12 +1490,12 @@ opswitch: if n.Esc == EscNone { // Create temporary buffer for slice on stack. - t := typArray(Types[TUINT8], tmpstringbufsize) + t := types.NewArray(types.Types[TUINT8], tmpstringbufsize) a = nod(OADDR, temp(t), nil) } - n = mkcall("stringtoslicebyte", n.Type, init, a, conv(n.Left, Types[TSTRING])) + n = mkcall("stringtoslicebyte", n.Type, init, a, conv(n.Left, types.Types[TSTRING])) case OSTRARRAYBYTETMP: // []byte(string) conversion that creates a slice @@ -1512,7 +1513,7 @@ opswitch: if n.Esc == EscNone { // Create temporary buffer for slice on stack. - t := typArray(Types[TINT32], tmpstringbufsize) + t := types.NewArray(types.Types[TINT32], tmpstringbufsize) a = nod(OADDR, temp(t), nil) } @@ -1537,8 +1538,8 @@ opswitch: rt := nod(OITAB, n.Right, nil) ld := nod(OIDATA, n.Left, nil) rd := nod(OIDATA, n.Right, nil) - ld.Type = Types[TUNSAFEPTR] - rd.Type = Types[TUNSAFEPTR] + ld.Type = types.Types[TUNSAFEPTR] + rd.Type = types.Types[TUNSAFEPTR] ld.Typecheck = 1 rd.Typecheck = 1 call := mkcall1(fn, n.Type, init, lt, ld, rd) @@ -1680,7 +1681,7 @@ func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node { // return 1 if this implies a function call // evaluating the lv or a function call // in the conversion of the types -func fncall(l *Node, rt *Type) bool { +func fncall(l *Node, rt *types.Type) bool { if l.HasCall() || l.Op == OINDEXMAP { return true } @@ -1696,7 +1697,7 @@ func fncall(l *Node, rt *Type) bool { // check assign type list to // a expression list. called in // expr-list = func() -func ascompatet(op Op, nl Nodes, nr *Type) []*Node { +func ascompatet(op Op, nl Nodes, nr *types.Type) []*Node { if nl.Len() != nr.NumFields() { Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields()) } @@ -1734,7 +1735,7 @@ func ascompatet(op Op, nl Nodes, nr *Type) []*Node { } // package all the arguments that match a ... T parameter into a []T. -func mkdotargslice(typ *Type, args []*Node, init *Nodes, ddd *Node) *Node { +func mkdotargslice(typ *types.Type, args []*Node, init *Nodes, ddd *Node) *Node { esc := uint16(EscUnknown) if ddd != nil { esc = ddd.Esc @@ -1764,7 +1765,7 @@ func mkdotargslice(typ *Type, args []*Node, init *Nodes, ddd *Node) *Node { // a type list. called in // return expr-list // func(expr-list) -func ascompatte(call *Node, isddd bool, lhs *Type, rhs []*Node, fp int, init *Nodes) []*Node { +func ascompatte(call *Node, isddd bool, lhs *types.Type, rhs []*Node, fp int, init *Nodes) []*Node { var nn []*Node // f(g()) where g has multiple return values @@ -1824,8 +1825,8 @@ func walkprint(nn *Node, init *Nodes) *Node { var r *Node var n *Node var on *Node - var t *Type - var et EType + var t *types.Type + var et types.EType op := nn.Op all := nn.List @@ -1847,18 +1848,18 @@ func walkprint(nn *Node, init *Nodes) *Node { if n.Op == OLITERAL { switch n.Val().Ctype() { case CTRUNE: - n = defaultlit(n, runetype) + n = defaultlit(n, types.Runetype) case CTINT: - n = defaultlit(n, Types[TINT64]) + n = defaultlit(n, types.Types[TINT64]) case CTFLT: - n = defaultlit(n, Types[TFLOAT64]) + n = defaultlit(n, types.Types[TFLOAT64]) } } if n.Op != OLITERAL && n.Type != nil && n.Type.Etype == TIDEAL { - n = defaultlit(n, Types[TINT64]) + n = defaultlit(n, types.Types[TINT64]) } n = defaultlit(n, nil) all.SetIndex(i1, n) @@ -1883,7 +1884,7 @@ func walkprint(nn *Node, init *Nodes) *Node { on = substArgTypes(on, n.Type) // any-1 } else if isInt[et] { if et == TUINT64 { - if t.Sym.Pkg.isRuntime() && t.Sym.Name == "hex" { + if isRuntimePkg(t.Sym.Pkg) && t.Sym.Name == "hex" { on = syslook("printhex") } else { on = syslook("printuint") @@ -1932,14 +1933,14 @@ func walkprint(nn *Node, init *Nodes) *Node { return r } -func callnew(t *Type) *Node { +func callnew(t *types.Type) *Node { if t.NotInHeap() { yyerror("%v is go:notinheap; heap allocation disallowed", t) } dowidth(t) fn := syslook("newobject") fn = substArgTypes(fn, t) - v := mkcall1(fn, typPtr(t), nil, typename(t)) + v := mkcall1(fn, types.NewPtr(t), nil, typename(t)) v.SetNonNil(true) return v } @@ -1978,11 +1979,11 @@ func isstack(n *Node) bool { // isReflectHeaderDataField reports whether l is an expression p.Data // where p has type reflect.SliceHeader or reflect.StringHeader. func isReflectHeaderDataField(l *Node) bool { - if l.Type != Types[TUINTPTR] { + if l.Type != types.Types[TUINTPTR] { return false } - var tsym *Sym + var tsym *types.Sym switch l.Op { case ODOT: tsym = l.Left.Type.Sym @@ -2022,7 +2023,7 @@ func needwritebarrier(l *Node) bool { // No write barrier for write of non-pointers. dowidth(l.Type) - if !haspointers(l.Type) { + if !types.Haspointers(l.Type) { return false } @@ -2051,8 +2052,8 @@ func convas(n *Node, init *Nodes) *Node { n.Typecheck = 1 - var lt *Type - var rt *Type + var lt *types.Type + var rt *types.Type if n.Left == nil || n.Right == nil { goto out } @@ -2436,10 +2437,10 @@ func vmatch1(l *Node, r *Node) bool { // paramstoheap returns code to allocate memory for heap-escaped parameters // and to copy non-result prameters' values from the stack. -func paramstoheap(params *Type) []*Node { +func paramstoheap(params *types.Type) []*Node { var nn []*Node for _, t := range params.Fields().Slice() { - v := t.Nname + v := asNode(t.Nname) if v != nil && v.Sym != nil && strings.HasPrefix(v.Sym.Name, "~r") { // unnamed result v = nil } @@ -2469,7 +2470,7 @@ func zeroResults() { lno := lineno lineno = Curfn.Pos for _, f := range Curfn.Type.Results().Fields().Slice() { - if v := f.Nname; v != nil && v.Name.Param.Heapaddr != nil { + if v := asNode(f.Nname); v != nil && v.Name.Param.Heapaddr != nil { // The local which points to the return value is the // thing that needs zeroing. This is already handled // by a Needzero annotation in plive.go:livenessepilogue. @@ -2483,10 +2484,10 @@ func zeroResults() { // returnsfromheap returns code to copy values for heap-escaped parameters // back to the stack. -func returnsfromheap(params *Type) []*Node { +func returnsfromheap(params *types.Type) []*Node { var nn []*Node for _, t := range params.Fields().Slice() { - v := t.Nname + v := asNode(t.Nname) if v == nil { continue } @@ -2513,7 +2514,7 @@ func heapmoves() { lineno = lno } -func vmkcall(fn *Node, t *Type, init *Nodes, va []*Node) *Node { +func vmkcall(fn *Node, t *types.Type, init *Nodes, va []*Node) *Node { if fn.Type == nil || fn.Type.Etype != TFUNC { Fatalf("mkcall %v %v", fn, fn.Type) } @@ -2532,15 +2533,15 @@ func vmkcall(fn *Node, t *Type, init *Nodes, va []*Node) *Node { return r } -func mkcall(name string, t *Type, init *Nodes, args ...*Node) *Node { +func mkcall(name string, t *types.Type, init *Nodes, args ...*Node) *Node { return vmkcall(syslook(name), t, init, args) } -func mkcall1(fn *Node, t *Type, init *Nodes, args ...*Node) *Node { +func mkcall1(fn *Node, t *types.Type, init *Nodes, args ...*Node) *Node { return vmkcall(fn, t, init, args) } -func conv(n *Node, t *Type) *Node { +func conv(n *Node, t *types.Type) *Node { if eqtype(n.Type, t) { return n } @@ -2554,16 +2555,16 @@ func conv(n *Node, t *Type) *Node { // We cannot use conv, because we allow converting bool to uint8 here, // which is forbidden in user code. func byteindex(n *Node) *Node { - if eqtype(n.Type, Types[TUINT8]) { + if eqtype(n.Type, types.Types[TUINT8]) { return n } n = nod(OCONV, n, nil) - n.Type = Types[TUINT8] + n.Type = types.Types[TUINT8] n.Typecheck = 1 return n } -func chanfn(name string, n int, t *Type) *Node { +func chanfn(name string, n int, t *types.Type) *Node { if !t.IsChan() { Fatalf("chanfn %v", t) } @@ -2579,7 +2580,7 @@ func chanfn(name string, n int, t *Type) *Node { return fn } -func mapfn(name string, t *Type) *Node { +func mapfn(name string, t *types.Type) *Node { if !t.IsMap() { Fatalf("mapfn %v", t) } @@ -2588,7 +2589,7 @@ func mapfn(name string, t *Type) *Node { return fn } -func mapfndel(name string, t *Type) *Node { +func mapfndel(name string, t *types.Type) *Node { if !t.IsMap() { Fatalf("mapfn %v", t) } @@ -2616,7 +2617,7 @@ var mapaccess2 mapnames = mkmapnames("mapaccess2") var mapassign mapnames = mkmapnames("mapassign") var mapdelete mapnames = mkmapnames("mapdelete") -func mapfast(t *Type) int { +func mapfast(t *types.Type) int { // Check ../../runtime/hashmap.go:maxValueSize before changing. if t.Val().Width > 128 { return mapslow @@ -2632,7 +2633,7 @@ func mapfast(t *Type) int { return mapslow } -func writebarrierfn(name string, l *Type, r *Type) *Node { +func writebarrierfn(name string, l *types.Type, r *types.Type) *Node { fn := syslook(name) fn = substArgTypes(fn, l, r) return fn @@ -2658,7 +2659,7 @@ func addstr(n *Node, init *Nodes) *Node { // Don't allocate the buffer if the result won't fit. if sz < tmpstringbufsize { // Create temporary buffer for result string on stack. - t := typArray(Types[TUINT8], tmpstringbufsize) + t := types.NewArray(types.Types[TUINT8], tmpstringbufsize) buf = nod(OADDR, temp(t), nil) } @@ -2667,7 +2668,7 @@ func addstr(n *Node, init *Nodes) *Node { // build list of string arguments args := []*Node{buf} for _, n2 := range n.List.Slice() { - args = append(args, conv(n2, Types[TSTRING])) + args = append(args, conv(n2, types.Types[TSTRING])) } var fn string @@ -2679,7 +2680,7 @@ func addstr(n *Node, init *Nodes) *Node { // large numbers of strings are passed to the runtime as a slice. fn = "concatstrings" - t := typSlice(Types[TSTRING]) + t := types.NewSlice(types.Types[TSTRING]) slice := nod(OCOMPLIT, nil, typenod(t)) if prealloc[n] != nil { prealloc[slice] = prealloc[n] @@ -2734,14 +2735,14 @@ func appendslice(n *Node, init *Nodes) *Node { l = append(l, nod(OAS, s, l1)) // s = l1 // n := len(s) + len(l2) - nn := temp(Types[TINT]) + nn := temp(types.Types[TINT]) l = append(l, nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil)))) // if uint(n) > uint(cap(s)) nif := nod(OIF, nil, nil) nif.Left = nod(OGT, nod(OCONV, nn, nil), nod(OCONV, nod(OCAP, s, nil), nil)) - nif.Left.Left.Type = Types[TUINT] - nif.Left.Right.Type = Types[TUINT] + nif.Left.Left.Type = types.Types[TUINT] + nif.Left.Right.Type = types.Types[TUINT] // instantiate growslice(Type*, []any, int) []any fn := syslook("growslice") @@ -2757,7 +2758,7 @@ func appendslice(n *Node, init *Nodes) *Node { nt.Etype = 1 l = append(l, nod(OAS, s, nt)) - if haspointers(l1.Type.Elem()) { + if types.Haspointers(l1.Type.Elem()) { // copy(s[len(l1):], l2) nptr1 := nod(OSLICE, s, nil) nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil) @@ -2767,7 +2768,7 @@ func appendslice(n *Node, init *Nodes) *Node { fn = substArgTypes(fn, l1.Type, l2.Type) var ln Nodes ln.Set(l) - nt := mkcall1(fn, Types[TINT], &ln, typename(l1.Type.Elem()), nptr1, nptr2) + nt := mkcall1(fn, types.Types[TINT], &ln, typename(l1.Type.Elem()), nptr1, nptr2) l = append(ln.Slice(), nt) } else if instrumenting && !compiling_runtime { // rely on runtime to instrument copy. @@ -2785,7 +2786,7 @@ func appendslice(n *Node, init *Nodes) *Node { fn = substArgTypes(fn, l1.Type, l2.Type) var ln Nodes ln.Set(l) - nt := mkcall1(fn, Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width)) + nt := mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width)) l = append(ln.Slice(), nt) } else { // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T)) @@ -2801,7 +2802,7 @@ func appendslice(n *Node, init *Nodes) *Node { var ln Nodes ln.Set(l) - nwid := cheapexpr(conv(nod(OLEN, l2, nil), Types[TUINTPTR]), &ln) + nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &ln) nwid = nod(OMUL, nwid, nodintconst(s.Type.Elem().Width)) nt := mkcall1(fn, nil, &ln, nptr1, nptr2, nwid) @@ -2884,7 +2885,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node { l = append(l, nx) - nn := temp(Types[TINT]) + nn := temp(types.Types[TINT]) l = append(l, nod(OAS, nn, nod(OLEN, ns, nil))) // n = len(s) nx = nod(OSLICE, ns, nil) // ...s[:n+argc] @@ -2920,7 +2921,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node { // Also works if b is a string. // func copyany(n *Node, init *Nodes, runtimecall bool) *Node { - if haspointers(n.Left.Type.Elem()) { + if types.Haspointers(n.Left.Type.Elem()) { fn := writebarrierfn("typedslicecopy", n.Left.Type, n.Right.Type) return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), n.Left, n.Right) } @@ -2947,7 +2948,7 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node { nfrm := nod(OSPTR, nr, nil) nto := nod(OSPTR, nl, nil) - nlen := temp(Types[TINT]) + nlen := temp(types.Types[TINT]) // n = len(to) l = append(l, nod(OAS, nlen, nod(OLEN, nl, nil))) @@ -2963,8 +2964,8 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node { fn := syslook("memmove") fn = substArgTypes(fn, nl.Type.Elem(), nl.Type.Elem()) - nwid := temp(Types[TUINTPTR]) - l = append(l, nod(OAS, nwid, conv(nlen, Types[TUINTPTR]))) + nwid := temp(types.Types[TUINTPTR]) + l = append(l, nod(OAS, nwid, conv(nlen, types.Types[TUINTPTR]))) nwid = nod(OMUL, nwid, nodintconst(nl.Type.Elem().Width)) l = append(l, mkcall1(fn, nil, init, nto, nfrm, nwid)) @@ -2974,7 +2975,7 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node { return nlen } -func eqfor(t *Type, needsize *int) *Node { +func eqfor(t *types.Type, needsize *int) *Node { // Should only arrive here with large memory or // a struct/array containing a non-memory field/element. // Small memory is handled inline, and single non-memory @@ -2990,9 +2991,9 @@ func eqfor(t *Type, needsize *int) *Node { n := newname(sym) n.Class = PFUNC ntype := nod(OTFUNC, nil, nil) - ntype.List.Append(anonfield(typPtr(t))) - ntype.List.Append(anonfield(typPtr(t))) - ntype.Rlist.Append(anonfield(Types[TBOOL])) + ntype.List.Append(anonfield(types.NewPtr(t))) + ntype.List.Append(anonfield(types.NewPtr(t))) + ntype.Rlist.Append(anonfield(types.Types[TBOOL])) ntype = typecheck(ntype, Etype) n.Type = ntype.Type *needsize = 0 @@ -3036,7 +3037,7 @@ func walkcompare(n *Node, init *Nodes) *Node { tab := nod(OITAB, l, nil) rtyp := typename(r.Type) if l.Type.IsEmptyInterface() { - tab.Type = typPtr(Types[TUINT8]) + tab.Type = types.NewPtr(types.Types[TUINT8]) tab.Typecheck = 1 eqtype = nod(eq, tab, rtyp) } else { @@ -3093,13 +3094,13 @@ func walkcompare(n *Node, init *Nodes) *Node { } // eq algs take pointers - pl := temp(typPtr(t)) + pl := temp(types.NewPtr(t)) al := nod(OAS, pl, nod(OADDR, cmpl, nil)) al.Right.Etype = 1 // addr does not escape al = typecheck(al, Etop) init.Append(al) - pr := temp(typPtr(t)) + pr := temp(types.NewPtr(t)) ar := nod(OAS, pr, nod(OADDR, cmpr, nil)) ar.Right.Etype = 1 // addr does not escape ar = typecheck(ar, Etop) @@ -3291,7 +3292,7 @@ func walkinrange(n *Node, init *Nodes) *Node { // This is equivalent to (a-a) ≤ (b-a) && (b-a) < (c-a), // which is equivalent to 0 ≤ (b-a) && (b-a) < (c-a), // which is equivalent to uint(b-a) < uint(c-a). - ut := b.Type.toUnsigned() + ut := b.Type.ToUnsigned() lhs := conv(nod(OSUB, b, a), ut) rhs := nodintconst(bound) if negateResult { @@ -3389,7 +3390,7 @@ func usemethod(n *Node) { } p0 := t.Params().Field(0) res0 := t.Results().Field(0) - var res1 *Field + var res1 *types.Field if t.Results().NumFields() == 2 { res1 = t.Results().Field(1) } @@ -3435,7 +3436,7 @@ func usefield(n *Node) { if t.IsPtr() { t = t.Elem() } - field := dotField[typeSym{t.Orig, n.Sym}] + field := dotField[typeSymKey{t.Orig, n.Sym}] if field == nil { Fatalf("usefield %v %v without paramfld", n.Left.Type, n.Sym) } @@ -3456,7 +3457,7 @@ func usefield(n *Node) { sym := tracksym(outer, field) if Curfn.Func.FieldTrack == nil { - Curfn.Func.FieldTrack = make(map[*Sym]struct{}) + Curfn.Func.FieldTrack = make(map[*types.Sym]struct{}) } Curfn.Func.FieldTrack[sym] = struct{}{} } @@ -3629,3 +3630,21 @@ func walkprintfunc(n *Node, init *Nodes) *Node { a = walkexpr(a, init) return a } + +// substArgTypes substitutes the given list of types for +// successive occurrences of the "any" placeholder in the +// type syntax expression n.Type. +// The result of substArgTypes MUST be assigned back to old, e.g. +// n.Left = substArgTypes(n.Left, t1, t2) +func substArgTypes(old *Node, types_ ...*types.Type) *Node { + n := *old // make shallow copy + + for _, t := range types_ { + dowidth(t) + } + n.Type = types.SubstAny(n.Type, &types_) + if len(types_) > 0 { + Fatalf("substArgTypes: too many argument types") + } + return &n +} diff --git a/src/cmd/compile/internal/types/pkg.go b/src/cmd/compile/internal/types/pkg.go new file mode 100644 index 0000000000..9885734bc2 --- /dev/null +++ b/src/cmd/compile/internal/types/pkg.go @@ -0,0 +1,70 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import "cmd/internal/obj" + +type Pkg struct { + Name string // package name, e.g. "sys" + Path string // string literal used in import statement, e.g. "runtime/internal/sys" + Pathsym *obj.LSym + Prefix string // escaped path for use in symbol table + Imported bool // export data of this package was parsed + Direct bool // imported directly + Syms map[string]*Sym +} + +var Nopkg = &Pkg{ + Syms: make(map[string]*Sym), +} + +func (pkg *Pkg) Lookup(name string) *Sym { + s, _ := pkg.LookupOK(name) + return s +} + +var InitSyms []*Sym + +// LookupOK looks up name in pkg and reports whether it previously existed. +func (pkg *Pkg) LookupOK(name string) (s *Sym, existed bool) { + if pkg == nil { + pkg = Nopkg + } + if s := pkg.Syms[name]; s != nil { + return s, true + } + + s = &Sym{ + Name: name, + Pkg: pkg, + } + if name == "init" { + InitSyms = append(InitSyms, s) + } + pkg.Syms[name] = s + return s, false +} + +func (pkg *Pkg) LookupBytes(name []byte) *Sym { + if pkg == nil { + pkg = Nopkg + } + if s := pkg.Syms[string(name)]; s != nil { + return s + } + str := InternString(name) + return pkg.Lookup(str) +} + +var internedStrings = map[string]string{} + +func InternString(b []byte) string { + s, ok := internedStrings[string(b)] // string(b) here doesn't allocate + if !ok { + s = string(b) + internedStrings[s] = s + } + return s +} diff --git a/src/cmd/compile/internal/types/sym.go b/src/cmd/compile/internal/types/sym.go new file mode 100644 index 0000000000..1086b99fdd --- /dev/null +++ b/src/cmd/compile/internal/types/sym.go @@ -0,0 +1,62 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import ( + "cmd/internal/obj" + "cmd/internal/src" +) + +// Sym represents an object name. Most commonly, this is a Go identifier naming +// an object declared within a package, but Syms are also used to name internal +// synthesized objects. +// +// As an exception, field and method names that are exported use the Sym +// associated with localpkg instead of the package that declared them. This +// allows using Sym pointer equality to test for Go identifier uniqueness when +// handling selector expressions. +type Sym struct { + Link *Sym + Importdef *Pkg // where imported definition was found + Linkname string // link name + + // saved and restored by dcopy + Pkg *Pkg + Name string // object name + Def *Node // definition: ONAME OTYPE OPACK or OLITERAL + Lastlineno src.XPos // last declaration for diagnostic + Block int32 // blocknumber to catch redeclaration + + flags bitset8 + Label *Node // corresponding label (ephemeral) + Origpkg *Pkg // original package for . import + Lsym *obj.LSym +} + +const ( + symExport = 1 << iota // added to exportlist (no need to add again) + symPackage + symExported // already written out by export + symUniq + symSiggen + symAsm + symAlgGen +) + +func (sym *Sym) Export() bool { return sym.flags&symExport != 0 } +func (sym *Sym) Package() bool { return sym.flags&symPackage != 0 } +func (sym *Sym) Exported() bool { return sym.flags&symExported != 0 } +func (sym *Sym) Uniq() bool { return sym.flags&symUniq != 0 } +func (sym *Sym) Siggen() bool { return sym.flags&symSiggen != 0 } +func (sym *Sym) Asm() bool { return sym.flags&symAsm != 0 } +func (sym *Sym) AlgGen() bool { return sym.flags&symAlgGen != 0 } + +func (sym *Sym) SetExport(b bool) { sym.flags.set(symExport, b) } +func (sym *Sym) SetPackage(b bool) { sym.flags.set(symPackage, b) } +func (sym *Sym) SetExported(b bool) { sym.flags.set(symExported, b) } +func (sym *Sym) SetUniq(b bool) { sym.flags.set(symUniq, b) } +func (sym *Sym) SetSiggen(b bool) { sym.flags.set(symSiggen, b) } +func (sym *Sym) SetAsm(b bool) { sym.flags.set(symAsm, b) } +func (sym *Sym) SetAlgGen(b bool) { sym.flags.set(symAlgGen, b) } diff --git a/src/cmd/compile/internal/gc/type.go b/src/cmd/compile/internal/types/type.go similarity index 86% rename from src/cmd/compile/internal/gc/type.go rename to src/cmd/compile/internal/types/type.go index cbf9b06afb..89bf90700f 100644 --- a/src/cmd/compile/internal/gc/type.go +++ b/src/cmd/compile/internal/types/type.go @@ -1,13 +1,8 @@ -// Copyright 2015 The Go Authors. All rights reserved. +// Copyright 2017 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// This file provides methods that let us export a Type as an ../ssa:Type. -// We don't export this package's Type directly because it would lead -// to an import cycle with this package and ../ssa. -// TODO: move Type to its own package, then we don't need to dance around import cycles. - -package gc +package types import ( "cmd/compile/internal/ssa" @@ -16,6 +11,11 @@ import ( "fmt" ) +// Dummy Node so we can refer to *Node without actually +// having a gc.Node. Necessary to break import cycles. +// TODO(gri) try to eliminate soon +type Node struct{ _ int } + // EType describes a kind of type. type EType uint8 @@ -98,23 +98,23 @@ var Types [NTYPE]*Type var ( // Predeclared alias types. Kept separate for better error messages. - bytetype *Type - runetype *Type + Bytetype *Type + Runetype *Type // Predeclared error interface type. - errortype *Type + Errortype *Type // Types to represent untyped string and boolean constants. - idealstring *Type - idealbool *Type + Idealstring *Type + Idealbool *Type // Types to represent untyped numeric constants. // Note: Currently these are only used within the binary export // data format. The rest of the compiler only uses Types[TIDEAL]. - idealint = typ(TIDEAL) - idealrune = typ(TIDEAL) - idealfloat = typ(TIDEAL) - idealcomplex = typ(TIDEAL) + Idealint = New(TIDEAL) + Idealrune = New(TIDEAL) + Idealfloat = New(TIDEAL) + Idealcomplex = New(TIDEAL) ) // A Type represents a Go type. @@ -143,11 +143,11 @@ type Type struct { methods Fields allMethods Fields - nod *Node // canonical OTYPE node + Nod *Node // canonical OTYPE node Orig *Type // original type (type literal or predefined type) - sliceOf *Type - ptrTo *Type + SliceOf *Type + PtrBase *Type Sym *Sym // symbol containing name, for named types Vargen int32 // unique name for OTYPE/ONAME @@ -260,7 +260,7 @@ func (t *Type) StructType() *StructType { // InterType contains Type fields specific to interface types. type InterType struct { - fields Fields + Fields Fields } // PtrType contains Type fields specific to pointer types. @@ -396,8 +396,8 @@ func (f *Fields) Append(s ...*Field) { *f.s = append(*f.s, s...) } -// typ returns a new Type of the specified kind. -func typ(et EType) *Type { +// New returns a new Type of the specified kind. +func New(et EType) *Type { t := &Type{ Etype: et, Width: BADWIDTH, @@ -429,138 +429,120 @@ func typ(et EType) *Type { return t } -// typArray returns a new fixed-length array Type. -func typArray(elem *Type, bound int64) *Type { +// NewArray returns a new fixed-length array Type. +func NewArray(elem *Type, bound int64) *Type { if bound < 0 { - Fatalf("typArray: invalid bound %v", bound) + Fatalf("NewArray: invalid bound %v", bound) } - t := typ(TARRAY) + t := New(TARRAY) t.Extra = &ArrayType{Elem: elem, Bound: bound} t.SetNotInHeap(elem.NotInHeap()) return t } -// typSlice returns the slice Type with element type elem. -func typSlice(elem *Type) *Type { - if t := elem.sliceOf; t != nil { +// NewSlice returns the slice Type with element type elem. +func NewSlice(elem *Type) *Type { + if t := elem.SliceOf; t != nil { if t.Elem() != elem { Fatalf("elem mismatch") } return t } - t := typ(TSLICE) + t := New(TSLICE) t.Extra = SliceType{Elem: elem} - elem.sliceOf = t + elem.SliceOf = t return t } -// typDDDArray returns a new [...]T array Type. -func typDDDArray(elem *Type) *Type { - t := typ(TARRAY) +// NewDDDArray returns a new [...]T array Type. +func NewDDDArray(elem *Type) *Type { + t := New(TARRAY) t.Extra = &ArrayType{Elem: elem, Bound: -1} t.SetNotInHeap(elem.NotInHeap()) return t } -// typChan returns a new chan Type with direction dir. -func typChan(elem *Type, dir ChanDir) *Type { - t := typ(TCHAN) +// NewChan returns a new chan Type with direction dir. +func NewChan(elem *Type, dir ChanDir) *Type { + t := New(TCHAN) ct := t.ChanType() ct.Elem = elem ct.Dir = dir return t } -// typMap returns a new map Type with key type k and element (aka value) type v. -func typMap(k, v *Type) *Type { - t := typ(TMAP) +// NewMap returns a new map Type with key type k and element (aka value) type v. +func NewMap(k, v *Type) *Type { + t := New(TMAP) mt := t.MapType() mt.Key = k mt.Val = v return t } -// typPtrCacheEnabled controls whether *T Types are cached in T. +// NewPtrCacheEnabled controls whether *T Types are cached in T. // Caching is disabled just before starting the backend. // This allows the backend to run concurrently. -var typPtrCacheEnabled = true +var NewPtrCacheEnabled = true -// typPtr returns the pointer type pointing to t. -func typPtr(elem *Type) *Type { +// NewPtr returns the pointer type pointing to t. +func NewPtr(elem *Type) *Type { if elem == nil { - Fatalf("typPtr: pointer to elem Type is nil") + Fatalf("NewPtr: pointer to elem Type is nil") } - if t := elem.ptrTo; t != nil { + if t := elem.PtrBase; t != nil { if t.Elem() != elem { - Fatalf("typPtr: elem mismatch") + Fatalf("NewPtr: elem mismatch") } return t } if Tptr == 0 { - Fatalf("typPtr: Tptr not initialized") + Fatalf("NewPtr: Tptr not initialized") } - t := typ(Tptr) + t := New(Tptr) t.Extra = PtrType{Elem: elem} t.Width = int64(Widthptr) t.Align = uint8(Widthptr) - if typPtrCacheEnabled { - elem.ptrTo = t + if NewPtrCacheEnabled { + elem.PtrBase = t } return t } -// typDDDField returns a new TDDDFIELD type for slice type s. -func typDDDField(s *Type) *Type { - t := typ(TDDDFIELD) +// NewDDDField returns a new TDDDFIELD type for slice type s. +func NewDDDField(s *Type) *Type { + t := New(TDDDFIELD) t.Extra = DDDFieldType{T: s} return t } -// typChanArgs returns a new TCHANARGS type for channel type c. -func typChanArgs(c *Type) *Type { - t := typ(TCHANARGS) +// NewChanArgs returns a new TCHANARGS type for channel type c. +func NewChanArgs(c *Type) *Type { + t := New(TCHANARGS) t.Extra = ChanArgsType{T: c} return t } -// typFuncArgs returns a new TFUNCARGS type for func type f. -func typFuncArgs(f *Type) *Type { - t := typ(TFUNCARGS) +// NewFuncArgs returns a new TFUNCARGS type for func type f. +func NewFuncArgs(f *Type) *Type { + t := New(TFUNCARGS) t.Extra = FuncArgsType{T: f} return t } -func newField() *Field { +func NewField() *Field { return &Field{ Offset: BADWIDTH, } } -// substArgTypes substitutes the given list of types for -// successive occurrences of the "any" placeholder in the -// type syntax expression n.Type. -// The result of substArgTypes MUST be assigned back to old, e.g. -// n.Left = substArgTypes(n.Left, t1, t2) -func substArgTypes(old *Node, types ...*Type) *Node { - n := *old // make shallow copy - - for _, t := range types { - dowidth(t) - } - n.Type = substAny(n.Type, &types) - if len(types) > 0 { - Fatalf("substArgTypes: too many argument types") - } - return &n -} - -// substAny walks t, replacing instances of "any" with successive +// SubstAny walks t, replacing instances of "any" with successive // elements removed from types. It returns the substituted type. -func substAny(t *Type, types *[]*Type) *Type { +func SubstAny(t *Type, types *[]*Type) *Type { if t == nil { return nil } @@ -577,36 +559,36 @@ func substAny(t *Type, types *[]*Type) *Type { *types = (*types)[1:] case TPTR32, TPTR64: - elem := substAny(t.Elem(), types) + elem := SubstAny(t.Elem(), types) if elem != t.Elem() { t = t.Copy() t.Extra = PtrType{Elem: elem} } case TARRAY: - elem := substAny(t.Elem(), types) + elem := SubstAny(t.Elem(), types) if elem != t.Elem() { t = t.Copy() t.Extra.(*ArrayType).Elem = elem } case TSLICE: - elem := substAny(t.Elem(), types) + elem := SubstAny(t.Elem(), types) if elem != t.Elem() { t = t.Copy() t.Extra = SliceType{Elem: elem} } case TCHAN: - elem := substAny(t.Elem(), types) + elem := SubstAny(t.Elem(), types) if elem != t.Elem() { t = t.Copy() t.Extra.(*ChanType).Elem = elem } case TMAP: - key := substAny(t.Key(), types) - val := substAny(t.Val(), types) + key := SubstAny(t.Key(), types) + val := SubstAny(t.Val(), types) if key != t.Key() || val != t.Val() { t = t.Copy() t.Extra.(*MapType).Key = key @@ -614,9 +596,9 @@ func substAny(t *Type, types *[]*Type) *Type { } case TFUNC: - recvs := substAny(t.Recvs(), types) - params := substAny(t.Params(), types) - results := substAny(t.Results(), types) + recvs := SubstAny(t.Recvs(), types) + params := SubstAny(t.Params(), types) + results := SubstAny(t.Results(), types) if recvs != t.Recvs() || params != t.Params() || results != t.Results() { t = t.Copy() t.FuncType().Receiver = recvs @@ -628,7 +610,7 @@ func substAny(t *Type, types *[]*Type) *Type { fields := t.FieldSlice() var nfs []*Field for i, f := range fields { - nft := substAny(f.Type, types) + nft := SubstAny(f.Type, types) if nft == f.Type { continue } @@ -695,9 +677,9 @@ type Iter struct { s []*Field } -// iterFields returns the first field or method in struct or interface type t +// IterFields returns the first field or method in struct or interface type t // and an Iter value to continue iterating across the rest. -func iterFields(t *Type) (*Field, Iter) { +func IterFields(t *Type) (*Field, Iter) { return t.Fields().Iter() } @@ -739,15 +721,15 @@ func (t *Type) Recv() *Field { return s.Field(0) } -// recvsParamsResults stores the accessor functions for a function Type's +// RecvsParamsResults stores the accessor functions for a function Type's // receiver, parameters, and result parameters, in that order. // It can be used to iterate over all of a function's parameter lists. -var recvsParamsResults = [3]func(*Type) *Type{ +var RecvsParamsResults = [3]func(*Type) *Type{ (*Type).Recvs, (*Type).Params, (*Type).Results, } -// paramsResults is like recvsParamsResults, but omits receiver parameters. -var paramsResults = [2]func(*Type) *Type{ +// ParamsResults is like RecvsParamsResults, but omits receiver parameters. +var ParamsResults = [2]func(*Type) *Type{ (*Type).Params, (*Type).Results, } @@ -838,8 +820,8 @@ func (t *Type) Fields() *Fields { case TSTRUCT: return &t.Extra.(*StructType).fields case TINTER: - dowidth(t) - return &t.Extra.(*InterType).fields + Dowidth(t) + return &t.Extra.(*InterType).Fields } Fatalf("Fields: type %v does not have fields", t) return nil @@ -887,7 +869,7 @@ func (t *Type) SetInterface(methods []*Field) { t.Methods().Set(methods) } -func (t *Type) isDDDArray() bool { +func (t *Type) IsDDDArray() bool { if t.Etype != TARRAY { return false } @@ -906,12 +888,12 @@ func (t *Type) ArgWidth() int64 { } func (t *Type) Size() int64 { - dowidth(t) + Dowidth(t) return t.Width } func (t *Type) Alignment() int64 { - dowidth(t) + Dowidth(t) return int64(t.Align) } @@ -1001,12 +983,12 @@ func (t *Type) cmp(x *Type) ssa.Cmp { // for error messages. Treat them as equal. switch t.Etype { case TUINT8: - if (t == Types[TUINT8] || t == bytetype) && (x == Types[TUINT8] || x == bytetype) { + if (t == Types[TUINT8] || t == Bytetype) && (x == Types[TUINT8] || x == Bytetype) { return ssa.CMPeq } case TINT32: - if (t == Types[runetype.Etype] || t == runetype) && (x == Types[runetype.Etype] || x == runetype) { + if (t == Types[Runetype.Etype] || t == Runetype) && (x == Types[Runetype.Etype] || x == Runetype) { return ssa.CMPeq } } @@ -1101,7 +1083,7 @@ func (t *Type) cmp(x *Type) ssa.Cmp { return ssa.CMPeq case TFUNC: - for _, f := range recvsParamsResults { + for _, f := range RecvsParamsResults { // Loop over fields in structs, ignoring argument names. tfs := f(t).FieldSlice() xfs := f(x).FieldSlice() @@ -1163,8 +1145,8 @@ var unsignedEType = [...]EType{ TUINTPTR: TUINTPTR, } -// toUnsigned returns the unsigned equivalent of integer type t. -func (t *Type) toUnsigned() *Type { +// ToUnsigned returns the unsigned equivalent of integer type t. +func (t *Type) ToUnsigned() *Type { if !t.IsInteger() { Fatalf("unsignedType(%v)", t) } @@ -1255,7 +1237,7 @@ func (t *Type) ElemType() ssa.Type { return t.Elem() } func (t *Type) PtrTo() ssa.Type { - return typPtr(t) + return NewPtr(t) } func (t *Type) NumFields() int { @@ -1268,7 +1250,7 @@ func (t *Type) FieldOff(i int) int64 { return t.Field(i).Offset } func (t *Type) FieldName(i int) string { - return t.Field(i).Sym.Name + return FieldName(t.Field(i)) } func (t *Type) NumElem() int64 { @@ -1281,8 +1263,8 @@ func (t *Type) NumElem() int64 { } // SetNumElem sets the number of elements in an array type. -// The only allowed use is on array types created with typDDDArray. -// For other uses, create a new array with typArray instead. +// The only allowed use is on array types created with NewDDDArray. +// For other uses, create a new array with NewArray instead. func (t *Type) SetNumElem(n int64) { t.wantEtype(TARRAY) at := t.Extra.(*ArrayType) @@ -1309,7 +1291,7 @@ func (t *Type) IsUntyped() bool { if t == nil { return false } - if t == idealstring || t == idealbool { + if t == Idealstring || t == Idealbool { return true } switch t.Etype { @@ -1319,7 +1301,7 @@ func (t *Type) IsUntyped() bool { return false } -func haspointers(t *Type) bool { +func Haspointers(t *Type) bool { switch t.Etype { case TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64, TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL: @@ -1329,11 +1311,11 @@ func haspointers(t *Type) bool { if t.NumElem() == 0 { // empty array has no pointers return false } - return haspointers(t.Elem()) + return Haspointers(t.Elem()) case TSTRUCT: for _, t1 := range t.Fields().Slice() { - if haspointers(t1.Type) { + if Haspointers(t1.Type) { return true } } @@ -1350,9 +1332,22 @@ func (t *Type) HasPointer() bool { if t.IsPtr() && t.Elem().NotInHeap() { return false } - return haspointers(t) + return Haspointers(t) } func (t *Type) Symbol() *obj.LSym { - return Linksym(typenamesym(t)) + return TypeLinkSym(t) +} + +// Tie returns 'T' if t is a concrete type, +// 'I' if t is an interface type, and 'E' if t is an empty interface type. +// It is used to build calls to the conv* and assert* runtime routines. +func (t *Type) Tie() byte { + if t.IsEmptyInterface() { + return 'E' + } + if t.IsInterface() { + return 'I' + } + return 'T' } diff --git a/src/cmd/compile/internal/types/utils.go b/src/cmd/compile/internal/types/utils.go new file mode 100644 index 0000000000..b0d471f210 --- /dev/null +++ b/src/cmd/compile/internal/types/utils.go @@ -0,0 +1,126 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +import ( + "cmd/compile/internal/ssa" + "cmd/internal/obj" + "fmt" +) + +const BADWIDTH = -1000000000 + +// Initialized by frontend. Exists only here. +var Tptr EType // either TPTR32 or TPTR64 + +// The following variables must be initialized early by the frontend. +// They are here to break import cycles. +// TODO(gri) eliminate these dependencies. +var ( + Widthptr int + Dowidth func(*Type) + Fatalf func(string, ...interface{}) + Sconv func(*Sym, int, int) string // orig: func sconv(s *Sym, flag FmtFlag, mode fmtMode) string + Tconv func(*Type, int, int, int) string // orig: func tconv(t *Type, flag FmtFlag, mode fmtMode, depth int) string + FormatSym func(*Sym, fmt.State, rune, int) // orig: func symFormat(sym *Sym, s fmt.State, verb rune, mode fmtMode) + FormatType func(*Type, fmt.State, rune, int) // orig: func typeFormat(t *Type, s fmt.State, verb rune, mode fmtMode) + Cmptyp func(_, _ *Type) ssa.Cmp + FieldName func(*Field) string + TypeLinkSym func(*Type) *obj.LSym + + FmtLeft int + FmtUnsigned int + FErr int +) + +func (s *Sym) String() string { + return Sconv(s, 0, FErr) +} + +func (sym *Sym) Format(s fmt.State, verb rune) { + FormatSym(sym, s, verb, FErr) +} + +func (t *Type) String() string { + // This is an external entry point, so we pass depth 0 to tconv. + // The implementation of tconv (including typefmt and fldconv) + // must take care not to use a type in a formatting string + // to avoid resetting the recursion counter. + return Tconv(t, 0, FErr, 0) +} + +// ShortString generates a short description of t. +// It is used in autogenerated method names, reflection, +// and itab names. +func (t *Type) ShortString() string { + return Tconv(t, FmtLeft, FErr, 0) +} + +// LongString generates a complete description of t. +// It is useful for reflection, +// or when a unique fingerprint or hash of a type is required. +func (t *Type) LongString() string { + return Tconv(t, FmtLeft|FmtUnsigned, FErr, 0) +} + +func (t *Type) Format(s fmt.State, verb rune) { + FormatType(t, s, verb, FErr) +} + +type bitset8 uint8 + +func (f *bitset8) set(mask uint8, b bool) { + if b { + *(*uint8)(f) |= mask + } else { + *(*uint8)(f) &^= mask + } +} + +var etnames = []string{ + Txxx: "Txxx", + TINT: "INT", + TUINT: "UINT", + TINT8: "INT8", + TUINT8: "UINT8", + TINT16: "INT16", + TUINT16: "UINT16", + TINT32: "INT32", + TUINT32: "UINT32", + TINT64: "INT64", + TUINT64: "UINT64", + TUINTPTR: "UINTPTR", + TFLOAT32: "FLOAT32", + TFLOAT64: "FLOAT64", + TCOMPLEX64: "COMPLEX64", + TCOMPLEX128: "COMPLEX128", + TBOOL: "BOOL", + TPTR32: "PTR32", + TPTR64: "PTR64", + TFUNC: "FUNC", + TARRAY: "ARRAY", + TSLICE: "SLICE", + TSTRUCT: "STRUCT", + TCHAN: "CHAN", + TMAP: "MAP", + TINTER: "INTER", + TFORW: "FORW", + TSTRING: "STRING", + TUNSAFEPTR: "TUNSAFEPTR", + TANY: "ANY", + TIDEAL: "TIDEAL", + TNIL: "TNIL", + TBLANK: "TBLANK", + TFUNCARGS: "TFUNCARGS", + TCHANARGS: "TCHANARGS", + TDDDFIELD: "TDDDFIELD", +} + +func (et EType) String() string { + if int(et) < len(etnames) && etnames[et] != "" { + return etnames[et] + } + return fmt.Sprintf("E-%d", et) +} diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go index f547a5af9e..015ee917b2 100644 --- a/src/cmd/dist/buildtool.go +++ b/src/cmd/dist/buildtool.go @@ -40,6 +40,7 @@ var bootstrapDirs = []string{ "cmd/compile/internal/mips", "cmd/compile/internal/mips64", "cmd/compile/internal/ppc64", + "cmd/compile/internal/types", "cmd/compile/internal/s390x", "cmd/compile/internal/ssa", "cmd/compile/internal/syntax", -- 2.48.1