go/internal/gccgoimporter: update package to match std lib version

Import changes from std lib version, specifically

   https://golang.org/cl/194565
   https://golang.org/cl/194440

related to handling of embedded fields in pointer loops.

Change-Id: I7218e39d67ada728accd707b11fced6ed52f5fa2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/195958
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Than McIntosh 2019-09-17 10:09:42 -04:00
parent 11bbd741f5
commit 6c790d6458
4 changed files with 79 additions and 32 deletions

View File

@ -99,6 +99,7 @@ var importerTests = [...]importerTest{
{pkgpath: "issue29198", name: "FooServer", gccgoVersion: 7, want: "type FooServer struct{FooServer *FooServer; user string; ctx context.Context}"},
{pkgpath: "issue30628", name: "Apple", want: "type Apple struct{hey sync.RWMutex; x int; RQ [517]struct{Count uintptr; NumBytes uintptr; Last uintptr}}"},
{pkgpath: "issue31540", name: "S", gccgoVersion: 7, want: "type S struct{b int; map[Y]Z}"},
{pkgpath: "issue34182", name: "T1", want: "type T1 struct{f *T2}"},
}
func TestGoxImporter(t *testing.T) {

View File

@ -258,7 +258,7 @@ func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
case *types.Named:
name = typ.Obj().Name()
default:
p.error("anonymous field expected")
p.error("embedded field expected")
}
}
}
@ -473,31 +473,47 @@ func (p *parser) reserve(n int) {
}
}
// update sets the type map entries for the given type numbers nlist to t.
func (p *parser) update(t types.Type, nlist []int) {
if len(nlist) != 0 {
if t == reserved {
p.errorf("internal error: update(%v) invoked on reserved", nlist)
}
if t == nil {
p.errorf("internal error: update(%v) invoked on nil", nlist)
}
// update sets the type map entries for the entries in nlist to t.
// An entry in nlist can be a type number in p.typeList,
// used to resolve named types, or it can be a *types.Pointer,
// used to resolve pointers to named types in case they are referenced
// by embedded fields.
func (p *parser) update(t types.Type, nlist []interface{}) {
if t == reserved {
p.errorf("internal error: update(%v) invoked on reserved", nlist)
}
if t == nil {
p.errorf("internal error: update(%v) invoked on nil", nlist)
}
for _, n := range nlist {
if p.typeList[n] == t {
continue
switch n := n.(type) {
case int:
if p.typeList[n] == t {
continue
}
if p.typeList[n] != reserved {
p.errorf("internal error: update(%v): %d not reserved", nlist, n)
}
p.typeList[n] = t
case *types.Pointer:
if *n != (types.Pointer{}) {
elem := n.Elem()
if elem == t {
continue
}
p.errorf("internal error: update: pointer already set to %v, expected %v", elem, t)
}
*n = *types.NewPointer(t)
default:
p.errorf("internal error: %T on nlist", n)
}
if p.typeList[n] != reserved {
p.errorf("internal error: update(%v): %d not reserved", nlist, n)
}
p.typeList[n] = t
}
}
// NamedType = TypeName [ "=" ] Type { Method } .
// TypeName = ExportedName .
// Method = "func" "(" Param ")" Name ParamList ResultList [InlineBody] ";" .
func (p *parser) parseNamedType(nlist []int) types.Type {
func (p *parser) parseNamedType(nlist []interface{}) types.Type {
pkg, name := p.parseExportedName()
scope := pkg.Scope()
obj := scope.Lookup(name)
@ -508,7 +524,7 @@ func (p *parser) parseNamedType(nlist []int) types.Type {
// type alias
if p.tok == '=' {
p.next()
p.aliases[nlist[len(nlist)-1]] = name
p.aliases[nlist[len(nlist)-1].(int)] = name
if obj != nil {
// use the previously imported (canonical) type
t := obj.Type()
@ -607,7 +623,7 @@ func (p *parser) parseInt() int {
}
// ArrayOrSliceType = "[" [ int ] "]" Type .
func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []int) types.Type {
func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []interface{}) types.Type {
p.expect('[')
if p.tok == ']' {
p.next()
@ -630,7 +646,7 @@ func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []int) types.Ty
}
// MapType = "map" "[" Type "]" Type .
func (p *parser) parseMapType(pkg *types.Package, nlist []int) types.Type {
func (p *parser) parseMapType(pkg *types.Package, nlist []interface{}) types.Type {
p.expectKeyword("map")
t := new(types.Map)
@ -646,7 +662,7 @@ func (p *parser) parseMapType(pkg *types.Package, nlist []int) types.Type {
}
// ChanType = "chan" ["<-" | "-<"] Type .
func (p *parser) parseChanType(pkg *types.Package, nlist []int) types.Type {
func (p *parser) parseChanType(pkg *types.Package, nlist []interface{}) types.Type {
p.expectKeyword("chan")
t := new(types.Chan)
@ -673,7 +689,7 @@ func (p *parser) parseChanType(pkg *types.Package, nlist []int) types.Type {
}
// StructType = "struct" "{" { Field } "}" .
func (p *parser) parseStructType(pkg *types.Package, nlist []int) types.Type {
func (p *parser) parseStructType(pkg *types.Package, nlist []interface{}) types.Type {
p.expectKeyword("struct")
t := new(types.Struct)
@ -740,7 +756,7 @@ func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
}
// FunctionType = ParamList ResultList .
func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signature {
func (p *parser) parseFunctionType(pkg *types.Package, nlist []interface{}) *types.Signature {
t := new(types.Signature)
p.update(t, nlist)
@ -780,7 +796,7 @@ func (p *parser) parseFunc(pkg *types.Package) *types.Func {
}
// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type {
func (p *parser) parseInterfaceType(pkg *types.Package, nlist []interface{}) types.Type {
p.expectKeyword("interface")
t := new(types.Interface)
@ -809,7 +825,7 @@ func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type
}
// PointerType = "*" ("any" | Type) .
func (p *parser) parsePointerType(pkg *types.Package, nlist []int) types.Type {
func (p *parser) parsePointerType(pkg *types.Package, nlist []interface{}) types.Type {
p.expect('*')
if p.tok == scanner.Ident {
p.expectKeyword("any")
@ -821,13 +837,13 @@ func (p *parser) parsePointerType(pkg *types.Package, nlist []int) types.Type {
t := new(types.Pointer)
p.update(t, nlist)
*t = *types.NewPointer(p.parseType(pkg))
*t = *types.NewPointer(p.parseType(pkg, t))
return t
}
// TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
func (p *parser) parseTypeSpec(pkg *types.Package, nlist []int) types.Type {
func (p *parser) parseTypeSpec(pkg *types.Package, nlist []interface{}) types.Type {
switch p.tok {
case scanner.String:
return p.parseNamedType(nlist)
@ -916,14 +932,14 @@ func lookupBuiltinType(typ int) types.Type {
//
// parseType updates the type map to t for all type numbers n.
//
func (p *parser) parseType(pkg *types.Package, n ...int) types.Type {
func (p *parser) parseType(pkg *types.Package, n ...interface{}) types.Type {
p.expect('<')
t, _ := p.parseTypeAfterAngle(pkg, n...)
return t
}
// (*parser).Type after reading the "<".
func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...int) (t types.Type, n1 int) {
func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
p.expectKeyword("type")
n1 = 0
@ -966,7 +982,7 @@ func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...int) (t types.Type
// parseTypeExtended is identical to parseType, but if the type in
// question is a saved type, returns the index as well as the type
// pointer (index returned is zero if we parsed a builtin).
func (p *parser) parseTypeExtended(pkg *types.Package, n ...int) (t types.Type, n1 int) {
func (p *parser) parseTypeExtended(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
p.expect('<')
t, n1 = p.parseTypeAfterAngle(pkg, n...)
return
@ -1048,12 +1064,12 @@ func (p *parser) parseTypes(pkg *types.Package) {
}
for i := 1; i < int(exportedp1); i++ {
p.parseSavedType(pkg, i, []int{})
p.parseSavedType(pkg, i, nil)
}
}
// parseSavedType parses one saved type definition.
func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []int) {
func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []interface{}) {
defer func(s *scanner.Scanner, tok rune, lit string) {
p.scanner = s
p.tok = tok

View File

@ -0,0 +1,17 @@
// Copyright 2019 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 issue34182
type T1 struct {
f *T2
}
type T2 struct {
f T3
}
type T3 struct {
*T2
}

View File

@ -0,0 +1,13 @@
v3;
package issue34182
pkgpath issue34182
init issue34182 ~go.issue34182
types 8 4 21 21 21 17 30 45 45
type 1 "T1" <type 6>
type 2 "T2" <type 7>
type 3 "T3" <type 5>
type 4 *<type 2>
type 5 struct { ? <type 4>; }
type 6 struct { .go.issue34182.f <type 4>; }
type 7 struct { .go.issue34182.f <type 3>; }
checksum FF02C49BAF44B06C087ED4E573F7CC880C79C208