From 03f546eb60bb8da02ef86264f43d9555e96fcb0b Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Tue, 17 Apr 2018 14:54:42 -0700 Subject: [PATCH] cmd/compile/internal/types: add Pkg and SetPkg methods to Type The go/types API exposes what package objects were declared in, which includes struct fields, interface methods, and function parameters. The compiler implicitly tracks these for non-exported identifiers (through the Sym's associated Pkg), but exported identifiers always use localpkg. To simplify identifying this, add an explicit package field to struct, interface, and function types. Change-Id: I6adc5dc653e78f058714259845fb3077066eec82 Reviewed-on: https://go-review.googlesource.com/107622 Reviewed-by: Robert Griesemer Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/types/sizeof_test.go | 6 +-- src/cmd/compile/internal/types/type.go | 39 ++++++++++++++++++- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/cmd/compile/internal/types/sizeof_test.go b/src/cmd/compile/internal/types/sizeof_test.go index 04e2f01e92..2633ef2ddd 100644 --- a/src/cmd/compile/internal/types/sizeof_test.go +++ b/src/cmd/compile/internal/types/sizeof_test.go @@ -26,9 +26,9 @@ func TestSizeof(t *testing.T) { {Type{}, 52, 88}, {Map{}, 20, 40}, {Forward{}, 20, 32}, - {Func{}, 28, 48}, - {Struct{}, 12, 24}, - {Interface{}, 4, 8}, + {Func{}, 32, 56}, + {Struct{}, 16, 32}, + {Interface{}, 8, 16}, {Chan{}, 8, 16}, {Array{}, 12, 16}, {DDDField{}, 4, 8}, diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go index a8adb77366..8d5f9fedf9 100644 --- a/src/cmd/compile/internal/types/type.go +++ b/src/cmd/compile/internal/types/type.go @@ -132,7 +132,7 @@ type Type struct { // TFORW: *Forward // TFUNC: *Func // TSTRUCT: *Struct - // TINTER: *Inter + // TINTER: *Interface // TDDDFIELD: DDDField // TFUNCARGS: FuncArgs // TCHANARGS: ChanArgs @@ -183,6 +183,40 @@ func (t *Type) SetNoalg(b bool) { t.flags.set(typeNoalg, b) } func (t *Type) SetDeferwidth(b bool) { t.flags.set(typeDeferwidth, b) } func (t *Type) SetRecur(b bool) { t.flags.set(typeRecur, b) } +// Pkg returns the package that t appeared in. +// +// Pkg is only defined for function, struct, and interface types +// (i.e., types with named elements). This information isn't used by +// cmd/compile itself, but we need to track it because it's exposed by +// the go/types API. +func (t *Type) Pkg() *Pkg { + switch t.Etype { + case TFUNC: + return t.Extra.(*Func).pkg + case TSTRUCT: + return t.Extra.(*Struct).pkg + case TINTER: + return t.Extra.(*Interface).pkg + default: + Fatalf("Pkg: unexpected kind: %v", t) + return nil + } +} + +// SetPkg sets the package that t appeared in. +func (t *Type) SetPkg(pkg *Pkg) { + switch t.Etype { + case TFUNC: + t.Extra.(*Func).pkg = pkg + case TSTRUCT: + t.Extra.(*Struct).pkg = pkg + case TINTER: + t.Extra.(*Interface).pkg = pkg + default: + Fatalf("Pkg: unexpected kind: %v", t) + } +} + // Map contains Type fields specific to maps. type Map struct { Key *Type // Key type @@ -218,6 +252,7 @@ type Func struct { Params *Type // function params Nname *Node + pkg *Pkg // Argwid is the total width of the function receiver, params, and results. // It gets calculated via a temporary TFUNCARGS type. @@ -236,6 +271,7 @@ func (t *Type) FuncType() *Func { // StructType contains Type fields specific to struct types. type Struct struct { fields Fields + pkg *Pkg // Maps have three associated internal structs (see struct MapType). // Map links such structs back to their map type. @@ -263,6 +299,7 @@ func (t *Type) StructType() *Struct { // Interface contains Type fields specific to interface types. type Interface struct { Fields Fields + pkg *Pkg } // Ptr contains Type fields specific to pointer types.