Commit 7647fcd3 authored by Ian Lance Taylor's avatar Ian Lance Taylor

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 <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarThan McIntosh <thanm@google.com>
parent 8969b051
......@@ -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":
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment