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>
diff --git a/go/internal/gccgoimporter/importer_test.go b/go/internal/gccgoimporter/importer_test.go
index ea2f323..6c3644e 100644
--- a/go/internal/gccgoimporter/importer_test.go
+++ b/go/internal/gccgoimporter/importer_test.go
@@ -99,6 +99,7 @@
 	{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) {
diff --git a/go/internal/gccgoimporter/parser.go b/go/internal/gccgoimporter/parser.go
index 891141f..2fcd7ac 100644
--- a/go/internal/gccgoimporter/parser.go
+++ b/go/internal/gccgoimporter/parser.go
@@ -258,7 +258,7 @@
 			case *types.Named:
 				name = typ.Obj().Name()
 			default:
-				p.error("anonymous field expected")
+				p.error("embedded field expected")
 			}
 		}
 	}
@@ -473,31 +473,47 @@
 	}
 }
 
-// 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 @@
 	// 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 @@
 }
 
 // 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 @@
 }
 
 // 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 @@
 }
 
 // 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 @@
 }
 
 // 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 @@
 }
 
 // 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 @@
 }
 
 // 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 @@
 }
 
 // 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 @@
 	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 @@
 //
 // 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 @@
 // 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 @@
 	}
 
 	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
diff --git a/go/internal/gccgoimporter/testdata/issue34182.go b/go/internal/gccgoimporter/testdata/issue34182.go
new file mode 100644
index 0000000..2a5c333
--- /dev/null
+++ b/go/internal/gccgoimporter/testdata/issue34182.go
@@ -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
+}
diff --git a/go/internal/gccgoimporter/testdata/issue34182.gox b/go/internal/gccgoimporter/testdata/issue34182.gox
new file mode 100644
index 0000000..671a7d6
--- /dev/null
+++ b/go/internal/gccgoimporter/testdata/issue34182.gox
@@ -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