From 7647fcd39292b5d36eb0f0be9750eecb03b1874c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 6 Jun 2019 17:19:11 -0700 Subject: [PATCH] go/internal/gccgoimporter: update for gofrontend export data changes This recognizes new features that the gofrontend has started emitting in the export data to support cross-package inlinable functions. This is a port of CL 180677 and 180758 from the gofrontend repo. Change-Id: I48af6e71f9d8b04ba874ea0c204d39d1d461f8ad Reviewed-on: https://go-review.googlesource.com/c/go/+/181118 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Than McIntosh --- src/go/internal/gccgoimporter/parser.go | 69 +++++++++++++++---------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/src/go/internal/gccgoimporter/parser.go b/src/go/internal/gccgoimporter/parser.go index 64a4042a45..76f30bb9ca 100644 --- a/src/go/internal/gccgoimporter/parser.go +++ b/src/go/internal/gccgoimporter/parser.go @@ -268,6 +268,10 @@ func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) { // Param = Name ["..."] Type . func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) { name := p.parseName() + // Ignore names invented for inlinable functions. + if strings.HasPrefix(name, "p.") || strings.HasPrefix(name, "r.") || strings.HasPrefix(name, "$ret") { + name = "" + } if p.tok == '<' && p.scanner.Peek() == 'e' { // EscInfo = "" . (optional and ignored) p.next() @@ -293,7 +297,14 @@ func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bo // Var = Name Type . func (p *parser) parseVar(pkg *types.Package) *types.Var { name := p.parseName() - return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg)) + v := types.NewVar(token.NoPos, pkg, name, p.parseType(pkg)) + if name[0] == '.' || name[0] == '<' { + // This is an unexported variable, + // or a variable defined in a different package. + // We only want to record exported variables. + return nil + } + return v } // Conversion = "convert" "(" Type "," ConstValue ")" . @@ -547,10 +558,12 @@ func (p *parser) parseNamedType(nlist []int) types.Type { for p.tok == scanner.Ident { p.expectKeyword("func") if p.tok == '/' { - // Skip a /*nointerface*/ comment. + // Skip a /*nointerface*/ or /*asm ID */ comment. p.expect('/') p.expect('*') - p.expect(scanner.Ident) + if p.expect(scanner.Ident) == "asm" { + p.parseUnquotedString() + } p.expect('*') p.expect('/') } @@ -736,15 +749,29 @@ func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signa // Func = Name FunctionType [InlineBody] . func (p *parser) parseFunc(pkg *types.Package) *types.Func { - name := p.parseName() - if strings.ContainsRune(name, '$') { - // This is a Type$equal or Type$hash function, which we don't want to parse, - // except for the types. - p.discardDirectiveWhileParsingTypes(pkg) - return nil + if p.tok == '/' { + // Skip an /*asm ID */ comment. + p.expect('/') + p.expect('*') + if p.expect(scanner.Ident) == "asm" { + p.parseUnquotedString() + } + p.expect('*') + p.expect('/') } + + name := p.parseName() f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil)) p.skipInlineBody() + + if name[0] == '.' || name[0] == '<' || strings.ContainsRune(name, '$') { + // This is an unexported function, + // or a function defined in a different package, + // or a type$equal or type$hash function. + // We only want to record exported functions. + return nil + } + return f } @@ -765,7 +792,9 @@ func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type embeddeds = append(embeddeds, p.parseType(pkg)) } else { method := p.parseFunc(pkg) - methods = append(methods, method) + if method != nil { + methods = append(methods, method) + } } p.expect(';') } @@ -1057,22 +1086,6 @@ func (p *parser) parsePackageInit() PackageInit { return PackageInit{Name: name, InitFunc: initfunc, Priority: priority} } -// Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type. -func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) { - for { - switch p.tok { - case '\n', ';': - return - case '<': - p.parseType(pkg) - case scanner.EOF: - p.error("unexpected EOF") - default: - p.next() - } - } -} - // Create the package if we have parsed both the package path and package name. func (p *parser) maybeCreatePackage() { if p.pkgname != "" && p.pkgpath != "" { @@ -1210,7 +1223,9 @@ func (p *parser) parseDirective() { case "var": p.next() v := p.parseVar(p.pkg) - p.pkg.Scope().Insert(v) + if v != nil { + p.pkg.Scope().Insert(v) + } p.expectEOL() case "const": -- 2.50.0