mirror of
https://github.com/golang/go
synced 2024-11-12 08:50:22 -07:00
go/internal/gccgoimporter: additional V3 export data changes
This patch merges in support for reading the most recent incarnation of V3 export data (initial inline function bodies), from the importer portions of https://golang.org/cl/150061 and https://golang.org/cl/150067. Updates #28961. Change-Id: I34e837acbf48b8fd1a4896a1a977d2241adfb28d Reviewed-on: https://go-review.googlesource.com/c/151557 Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
2b58ca6e3d
commit
70a684cf44
@ -15,6 +15,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"text/scanner"
|
"text/scanner"
|
||||||
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
type parser struct {
|
type parser struct {
|
||||||
@ -41,7 +42,7 @@ func (p *parser) init(filename string, src io.Reader, imports map[string]*types.
|
|||||||
func (p *parser) initScanner(filename string, src io.Reader) {
|
func (p *parser) initScanner(filename string, src io.Reader) {
|
||||||
p.scanner.Init(src)
|
p.scanner.Init(src)
|
||||||
p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
|
p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
|
||||||
p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
|
p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings
|
||||||
p.scanner.Whitespace = 1<<'\t' | 1<<' '
|
p.scanner.Whitespace = 1<<'\t' | 1<<' '
|
||||||
p.scanner.Filename = filename // for good error messages
|
p.scanner.Filename = filename // for good error messages
|
||||||
p.next()
|
p.next()
|
||||||
@ -281,6 +282,15 @@ func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ ty
|
|||||||
// ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
|
// ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
|
||||||
// FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
|
// FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
|
||||||
func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
|
func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
|
||||||
|
// v3 changed to $false, $true, $convert, to avoid confusion
|
||||||
|
// with variable names in inline function bodies.
|
||||||
|
if p.tok == '$' {
|
||||||
|
p.next()
|
||||||
|
if p.tok != scanner.Ident {
|
||||||
|
p.errorf("expected identifer after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case scanner.String:
|
case scanner.String:
|
||||||
str := p.parseString()
|
str := p.parseString()
|
||||||
@ -443,7 +453,7 @@ func (p *parser) update(t types.Type, nlist []int) {
|
|||||||
|
|
||||||
// NamedType = TypeName [ "=" ] Type { Method } .
|
// NamedType = TypeName [ "=" ] Type { Method } .
|
||||||
// TypeName = ExportedName .
|
// TypeName = ExportedName .
|
||||||
// Method = "func" "(" Param ")" Name ParamList ResultList ";" .
|
// Method = "func" "(" Param ")" Name ParamList ResultList [InlineBody] ";" .
|
||||||
func (p *parser) parseNamedType(nlist []int) types.Type {
|
func (p *parser) parseNamedType(nlist []int) types.Type {
|
||||||
pkg, name := p.parseExportedName()
|
pkg, name := p.parseExportedName()
|
||||||
scope := pkg.Scope()
|
scope := pkg.Scope()
|
||||||
@ -508,6 +518,7 @@ func (p *parser) parseNamedType(nlist []int) types.Type {
|
|||||||
name := p.parseName()
|
name := p.parseName()
|
||||||
params, isVariadic := p.parseParamList(pkg)
|
params, isVariadic := p.parseParamList(pkg)
|
||||||
results := p.parseResultList(pkg)
|
results := p.parseResultList(pkg)
|
||||||
|
p.skipInlineBody()
|
||||||
p.expectEOL()
|
p.expectEOL()
|
||||||
|
|
||||||
sig := types.NewSignature(receiver, params, results, isVariadic)
|
sig := types.NewSignature(receiver, params, results, isVariadic)
|
||||||
@ -653,7 +664,11 @@ func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
|
|||||||
func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
|
func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case '<':
|
case '<':
|
||||||
return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg)))
|
p.next()
|
||||||
|
if p.tok == scanner.Ident && p.lit == "inl" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseTypeAfterAngle(pkg)))
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
params, _ := p.parseParamList(pkg)
|
params, _ := p.parseParamList(pkg)
|
||||||
@ -676,7 +691,7 @@ func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signa
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Func = Name FunctionType .
|
// Func = Name FunctionType [InlineBody] .
|
||||||
func (p *parser) parseFunc(pkg *types.Package) *types.Func {
|
func (p *parser) parseFunc(pkg *types.Package) *types.Func {
|
||||||
name := p.parseName()
|
name := p.parseName()
|
||||||
if strings.ContainsRune(name, '$') {
|
if strings.ContainsRune(name, '$') {
|
||||||
@ -685,7 +700,9 @@ func (p *parser) parseFunc(pkg *types.Package) *types.Func {
|
|||||||
p.discardDirectiveWhileParsingTypes(pkg)
|
p.discardDirectiveWhileParsingTypes(pkg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
|
f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
|
||||||
|
p.skipInlineBody()
|
||||||
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
|
// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
|
||||||
@ -823,8 +840,13 @@ func lookupBuiltinType(typ int) types.Type {
|
|||||||
//
|
//
|
||||||
// parseType updates the type map to t for all type numbers n.
|
// parseType updates the type map to t for all type numbers n.
|
||||||
//
|
//
|
||||||
func (p *parser) parseType(pkg *types.Package, n ...int) (t types.Type) {
|
func (p *parser) parseType(pkg *types.Package, n ...int) types.Type {
|
||||||
p.expect('<')
|
p.expect('<')
|
||||||
|
return p.parseTypeAfterAngle(pkg, n...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// (*parser).Type after reading the "<".
|
||||||
|
func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...int) (t types.Type) {
|
||||||
p.expectKeyword("type")
|
p.expectKeyword("type")
|
||||||
|
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
@ -863,6 +885,39 @@ func (p *parser) parseType(pkg *types.Package, n ...int) (t types.Type) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InlineBody = "<inl:NN>" .{NN}
|
||||||
|
// Reports whether a body was skipped.
|
||||||
|
func (p *parser) skipInlineBody() {
|
||||||
|
// We may or may not have seen the '<' already, depending on
|
||||||
|
// whether the function had a result type or not.
|
||||||
|
if p.tok == '<' {
|
||||||
|
p.next()
|
||||||
|
p.expectKeyword("inl")
|
||||||
|
} else if p.tok != scanner.Ident || p.lit != "inl" {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
p.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
p.expect(':')
|
||||||
|
want := p.parseInt()
|
||||||
|
p.expect('>')
|
||||||
|
|
||||||
|
defer func(w uint64) {
|
||||||
|
p.scanner.Whitespace = w
|
||||||
|
}(p.scanner.Whitespace)
|
||||||
|
p.scanner.Whitespace = 0
|
||||||
|
|
||||||
|
got := 0
|
||||||
|
for got < want {
|
||||||
|
r := p.scanner.Next()
|
||||||
|
if r == scanner.EOF {
|
||||||
|
p.error("unexpected EOF")
|
||||||
|
}
|
||||||
|
got += utf8.RuneLen(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Types = "types" maxp1 exportedp1 (offset length)* .
|
// Types = "types" maxp1 exportedp1 (offset length)* .
|
||||||
func (p *parser) parseTypes(pkg *types.Package) {
|
func (p *parser) parseTypes(pkg *types.Package) {
|
||||||
maxp1 := p.parseInt()
|
maxp1 := p.parseInt()
|
||||||
@ -882,6 +937,11 @@ func (p *parser) parseTypes(pkg *types.Package) {
|
|||||||
total += len
|
total += len
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func(w uint64) {
|
||||||
|
p.scanner.Whitespace = w
|
||||||
|
}(p.scanner.Whitespace)
|
||||||
|
p.scanner.Whitespace = 0
|
||||||
|
|
||||||
// We should now have p.tok pointing to the final newline.
|
// We should now have p.tok pointing to the final newline.
|
||||||
// The next runes from the scanner should be the type data.
|
// The next runes from the scanner should be the type data.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user