go/internal/gccgoimporter: parse optional escape info in export data

This is a copy of https://go-review.googlesource.com/c/go/+/86977
and brings those changes into the x/tools repo.

It also includes a minor change to parser.go that was done via
https://go-review.googlesource.com/37839 but that wasn't brought
over.

For golang/go#23324.

Change-Id: I84b7cf134fec250ac340e404802158860cb3c630
Reviewed-on: https://go-review.googlesource.com/87295
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/go/internal/gccgoimporter/importer_test.go b/go/internal/gccgoimporter/importer_test.go
index 87b5ff2..2c6f1cb 100644
--- a/go/internal/gccgoimporter/importer_test.go
+++ b/go/internal/gccgoimporter/importer_test.go
@@ -104,6 +104,7 @@
 	{pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"},
 	{pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"},
 	{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
+	{pkgpath: "escapeinfo", name: "NewT", want: "func NewT(data []byte) *T"},
 }
 
 func TestGoxImporter(t *testing.T) {
diff --git a/go/internal/gccgoimporter/parser.go b/go/internal/gccgoimporter/parser.go
index 08e3bb9..9e20df0 100644
--- a/go/internal/gccgoimporter/parser.go
+++ b/go/internal/gccgoimporter/parser.go
@@ -228,6 +228,14 @@
 // Param = Name ["..."] Type .
 func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
 	name := p.parseName()
+	if p.tok == '<' && p.scanner.Peek() == 'e' {
+		// EscInfo = "<esc:" int ">" . (optional and ignored)
+		p.next()
+		p.expectKeyword("esc")
+		p.expect(':')
+		p.expect(scanner.Int)
+		p.expect('>')
+	}
 	if p.tok == '.' {
 		p.next()
 		p.expect('.')
@@ -741,7 +749,7 @@
 		case ';':
 			return
 		case '<':
-			p.parseType(p.pkg)
+			p.parseType(pkg)
 		case scanner.EOF:
 			p.error("unexpected EOF")
 		default:
diff --git a/go/internal/gccgoimporter/testdata/escapeinfo.go b/go/internal/gccgoimporter/testdata/escapeinfo.go
new file mode 100644
index 0000000..103ad95
--- /dev/null
+++ b/go/internal/gccgoimporter/testdata/escapeinfo.go
@@ -0,0 +1,13 @@
+// Test case for escape info in export data. To compile and extract .gox file:
+// gccgo -fgo-optimize-allocs -c escapeinfo.go
+// objcopy -j .go_export escapeinfo.o escapeinfo.gox
+
+package escapeinfo
+
+type T struct{ data []byte }
+
+func NewT(data []byte) *T {
+	return &T{data}
+}
+
+func (*T) Read(p []byte) {}
diff --git a/go/internal/gccgoimporter/testdata/escapeinfo.gox b/go/internal/gccgoimporter/testdata/escapeinfo.gox
new file mode 100644
index 0000000..1db8156
--- /dev/null
+++ b/go/internal/gccgoimporter/testdata/escapeinfo.gox
Binary files differ