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

Import changes from std lib version, specifically

  https://golang.org/cl/172603
  https://golang.org/cl/165739

which contain to a fix for reading of import data as
well as a couple of new test cases.

Updates golang/go#31540.

Change-Id: Iecb1a5a5a7bf100b2ebb871196868e96b1a50611
Reviewed-on: https://go-review.googlesource.com/c/tools/+/173037
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 73aa9d1..aa03879 100644
--- a/go/internal/gccgoimporter/importer_test.go
+++ b/go/internal/gccgoimporter/importer_test.go
@@ -94,7 +94,8 @@
 	{pkgpath: "v1reflect", name: "Type", want: "type Type interface{Align() int; AssignableTo(u Type) bool; Bits() int; ChanDir() ChanDir; Elem() Type; Field(i int) StructField; FieldAlign() int; FieldByIndex(index []int) StructField; FieldByName(name string) (StructField, bool); FieldByNameFunc(match func(string) bool) (StructField, bool); Implements(u Type) bool; In(i int) Type; IsVariadic() bool; Key() Type; Kind() Kind; Len() int; Method(int) Method; MethodByName(string) (Method, bool); Name() string; NumField() int; NumIn() int; NumMethod() int; NumOut() int; Out(i int) Type; PkgPath() string; Size() uintptr; String() string; common() *commonType; rawString() string; runtimeType() *runtimeType; uncommon() *uncommonType}"},
 	{pkgpath: "nointerface", name: "I", want: "type I int"},
 	{pkgpath: "issue29198", name: "FooServer", 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", want: "type S struct{b int; map[Y]Z}"}}
 
 func TestGoxImporter(t *testing.T) {
 	testenv.MustHaveExec(t) // this is to skip nacl, js
diff --git a/go/internal/gccgoimporter/parser.go b/go/internal/gccgoimporter/parser.go
index 179c987..ca63b34 100644
--- a/go/internal/gccgoimporter/parser.go
+++ b/go/internal/gccgoimporter/parser.go
@@ -35,6 +35,7 @@
 	typeData []string                  // unparsed type data (v3 and later)
 	fixups   []fixupRecord             // fixups to apply at end of parsing
 	initdata InitData                  // package init priority data
+	aliases  map[int]string            // maps saved type number to alias name
 }
 
 // When reading export data it's possible to encounter a defined type
@@ -61,6 +62,7 @@
 	p.scanner = new(scanner.Scanner)
 	p.initScanner(filename, src)
 	p.imports = imports
+	p.aliases = make(map[int]string)
 	p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
 }
 
@@ -242,17 +244,22 @@
 // Field = Name Type [string] .
 func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
 	name := p.parseName()
-	typ := p.parseType(pkg)
+	typ, n := p.parseTypeExtended(pkg)
 	anon := false
 	if name == "" {
 		anon = true
-		switch typ := deref(typ).(type) {
-		case *types.Basic:
-			name = typ.Name()
-		case *types.Named:
-			name = typ.Obj().Name()
-		default:
-			p.error("anonymous field expected")
+		// Alias?
+		if aname, ok := p.aliases[n]; ok {
+			name = aname
+		} else {
+			switch typ := deref(typ).(type) {
+			case *types.Basic:
+				name = typ.Name()
+			case *types.Named:
+				name = typ.Obj().Name()
+			default:
+				p.error("anonymous field expected")
+			}
 		}
 	}
 	field = types.NewField(token.NoPos, pkg, name, typ, anon)
@@ -499,6 +506,7 @@
 		}
 		t := p.parseType(pkg, nlist...)
 		obj = types.NewTypeName(token.NoPos, pkg, name, t)
+		p.aliases[nlist[len(nlist)-1]] = name
 		scope.Insert(obj)
 		return t
 	}
@@ -706,7 +714,8 @@
 		if p.tok == scanner.Ident && p.lit == "inl" {
 			return nil
 		}
-		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseTypeAfterAngle(pkg)))
+		taa, _ := p.parseTypeAfterAngle(pkg)
+		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", taa))
 
 	case '(':
 		params, _ := p.parseParamList(pkg)
@@ -880,16 +889,18 @@
 //
 func (p *parser) parseType(pkg *types.Package, n ...int) types.Type {
 	p.expect('<')
-	return p.parseTypeAfterAngle(pkg, n...)
+	t, _ := p.parseTypeAfterAngle(pkg, n...)
+	return t
 }
 
 // (*parser).Type after reading the "<".
-func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...int) (t types.Type) {
+func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...int) (t types.Type, n1 int) {
 	p.expectKeyword("type")
 
+	n1 = 0
 	switch p.tok {
 	case scanner.Int:
-		n1 := p.parseInt()
+		n1 = p.parseInt()
 		if p.tok == '>' {
 			if len(p.typeData) > 0 && p.typeList[n1] == nil {
 				p.parseSavedType(pkg, n1, n)
@@ -912,7 +923,7 @@
 
 	default:
 		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
-		return nil
+		return nil, 0
 	}
 
 	if t == nil || t == reserved {
@@ -923,6 +934,15 @@
 	return
 }
 
+// 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) {
+	p.expect('<')
+	t, n1 = p.parseTypeAfterAngle(pkg, n...)
+	return
+}
+
 // InlineBody = "<inl:NN>" .{NN}
 // Reports whether a body was skipped.
 func (p *parser) skipInlineBody() {
diff --git a/go/internal/gccgoimporter/testdata/issue30628.go b/go/internal/gccgoimporter/testdata/issue30628.go
new file mode 100644
index 0000000..8fd7c13
--- /dev/null
+++ b/go/internal/gccgoimporter/testdata/issue30628.go
@@ -0,0 +1,18 @@
+package issue30628
+
+import (
+	"os"
+	"sync"
+)
+
+const numR = int32(os.O_TRUNC + 5)
+
+type Apple struct {
+	hey sync.RWMutex
+	x   int
+	RQ  [numR]struct {
+		Count    uintptr
+		NumBytes uintptr
+		Last     uintptr
+	}
+}
diff --git a/go/internal/gccgoimporter/testdata/issue30628.gox b/go/internal/gccgoimporter/testdata/issue30628.gox
new file mode 100644
index 0000000..0ff6259
--- /dev/null
+++ b/go/internal/gccgoimporter/testdata/issue30628.gox
@@ -0,0 +1,28 @@
+v3;
+package issue30628
+pkgpath issue30628
+import os os "os"
+import sync sync "sync"
+init cpu internal..z2fcpu..import poll internal..z2fpoll..import testlog internal..z2ftestlog..import io io..import os os..import runtime runtime..import sys runtime..z2finternal..z2fsys..import sync sync..import syscall syscall..import time time..import
+init_graph 1 0 1 3 1 5 1 6 1 7 1 8 1 9 3 0 3 5 3 6 3 7 4 0 4 1 4 2 4 3 4 5 4 6 4 7 4 8 4 9 5 0 5 6 7 0 7 5 7 6 8 0 8 5 8 6 8 7 9 0 9 5 9 6 9 7 9 8
+types 13 2 24 84 208 17 30 41 147 86 17 64 25 75
+type 1 "Apple" <type 2>
+type 2 struct { .issue30628.hey <type 3>; .issue30628.x <type -11>; RQ <type 11>; }
+type 3 "sync.RWMutex" <type 7>
+ func (rw <type 4>) Lock ()
+ func (rw <esc:0x12> <type 4>) RLocker () ($ret8 <type 5>)
+ func (rw <type 4>) RUnlock ()
+ func (rw <type 4>) Unlock ()
+ func (rw <type 4>) RLock ()
+type 4 *<type 3>
+type 5 "sync.Locker" <type 6>
+type 6 interface { Lock (); Unlock (); }
+type 7 struct { .sync.w <type 8>; .sync.writerSem <type -7>; .sync.readerSem <type -7>; .sync.readerCount <type -3>; .sync.readerWait <type -3>; }
+type 8 "sync.Mutex" <type 10>
+ func (m <type 9>) Unlock ()
+ func (m <type 9>) Lock ()
+type 9 *<type 8>
+type 10 struct { .sync.state <type -3>; .sync.sema <type -7>; }
+type 11 [517 ] <type 12>
+type 12 struct { Count <type -13>; NumBytes <type -13>; Last <type -13>; }
+checksum 199DCF6D3EE2FCF39F715B4E42B5F87F5B15D3AF
diff --git a/go/internal/gccgoimporter/testdata/issue31540.go b/go/internal/gccgoimporter/testdata/issue31540.go
new file mode 100644
index 0000000..2c6799e
--- /dev/null
+++ b/go/internal/gccgoimporter/testdata/issue31540.go
@@ -0,0 +1,26 @@
+// 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 issue31540
+
+type Y struct {
+	q int
+}
+
+type Z map[int]int
+
+type X = map[Y]Z
+
+type A1 = X
+
+type A2 = A1
+
+type S struct {
+	b int
+	A2
+}
+
+func Hallo() S {
+	return S{}
+}
diff --git a/go/internal/gccgoimporter/testdata/issue31540.gox b/go/internal/gccgoimporter/testdata/issue31540.gox
new file mode 100644
index 0000000..abdc696
--- /dev/null
+++ b/go/internal/gccgoimporter/testdata/issue31540.gox
@@ -0,0 +1,16 @@
+v3;
+package issue31540
+pkgpath issue31540
+types 11 7 23 23 20 22 20 21 57 31 45 36
+type 1 "A1" = <type 4>
+type 2 "A2" = <type 1>
+type 3 "S" <type 7>
+type 4 "X" = <type 8>
+type 5 "Y" <type 9>
+type 6 "Z" <type 10>
+type 7 struct { .go.mapalias.b <type -11>; ? <type 2>; }
+type 8 map [<type 5>] <type 6>
+type 9 struct { .go.mapalias.q <type -11>; }
+type 10 map [<type -11>] <type -11>
+func Hallo () <type 3>
+checksum C3FAF2524A90BC11225EE65D059BF27DFB69134B