]> Cypherpunks repositories - gostls13.git/commitdiff
go/internal/gccgoimporter: update for gofrontend export data changes
authorIan Lance Taylor <iant@golang.org>
Fri, 7 Jun 2019 00:19:11 +0000 (17:19 -0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 7 Jun 2019 13:39:26 +0000 (13:39 +0000)
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 <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/go/internal/gccgoimporter/parser.go

index 64a4042a451af463bf264225f253bc53019130fd..76f30bb9ca5522c7809acaa3b612383940fb6984 100644 (file)
@@ -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 = "<esc:" int ">" . (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":