aboutsummaryrefslogtreecommitdiff
path: root/libgo/go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go')
-rw-r--r--libgo/go/go/internal/gccgoimporter/parser.go63
1 files changed, 57 insertions, 6 deletions
diff --git a/libgo/go/go/internal/gccgoimporter/parser.go b/libgo/go/go/internal/gccgoimporter/parser.go
index dc61e4c..c23002f 100644
--- a/libgo/go/go/internal/gccgoimporter/parser.go
+++ b/libgo/go/go/internal/gccgoimporter/parser.go
@@ -15,6 +15,7 @@ import (
"strconv"
"strings"
"text/scanner"
+ "unicode/utf8"
)
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) {
p.scanner.Init(src)
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.Filename = filename // for good error messages
p.next()
@@ -393,7 +394,7 @@ func (p *parser) parseConst(pkg *types.Package) *types.Const {
// NamedType = TypeName [ "=" ] Type { Method } .
// TypeName = ExportedName .
-// Method = "func" "(" Param ")" Name ParamList ResultList ";" .
+// Method = "func" "(" Param ")" Name ParamList ResultList [InlineBody] ";" .
func (p *parser) parseNamedType(n int) types.Type {
pkg, name := p.parseExportedName()
scope := pkg.Scope()
@@ -455,6 +456,7 @@ func (p *parser) parseNamedType(n int) types.Type {
name := p.parseName()
params, isVariadic := p.parseParamList(pkg)
results := p.parseResultList(pkg)
+ p.skipInlineBody()
p.expectEOL()
sig := types.NewSignature(receiver, params, results, isVariadic)
@@ -566,7 +568,11 @@ func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
switch p.tok {
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 '(':
params, _ := p.parseParamList(pkg)
@@ -584,7 +590,7 @@ func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature {
return types.NewSignature(nil, params, results, isVariadic)
}
-// Func = Name FunctionType .
+// Func = Name FunctionType [InlineBody] .
func (p *parser) parseFunc(pkg *types.Package) *types.Func {
name := p.parseName()
if strings.ContainsRune(name, '$') {
@@ -593,7 +599,9 @@ func (p *parser) parseFunc(pkg *types.Package) *types.Func {
p.discardDirectiveWhileParsingTypes(pkg)
return nil
}
- return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg))
+ f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg))
+ p.skipInlineBody()
+ return f
}
// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
@@ -717,8 +725,13 @@ func lookupBuiltinType(typ int) types.Type {
}
// Type = "<" "type" ( "-" int | int [ TypeDefinition ] ) ">" .
-func (p *parser) parseType(pkg *types.Package) (t types.Type) {
+func (p *parser) parseType(pkg *types.Package) types.Type {
p.expect('<')
+ return p.parseTypeAfterAngle(pkg)
+}
+
+// (*parser).Type after reading the "<".
+func (p *parser) parseTypeAfterAngle(pkg *types.Package) (t types.Type) {
p.expectKeyword("type")
switch p.tok {
@@ -748,6 +761,39 @@ func (p *parser) parseType(pkg *types.Package) (t types.Type) {
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 := int64(0)
+ for got < want {
+ r := p.scanner.Next()
+ if r == scanner.EOF {
+ p.error("unexpected EOF")
+ }
+ got += int64(utf8.RuneLen(r))
+ }
+}
+
// Types = "types" maxp1 exportedp1 (offset length)* .
func (p *parser) parseTypes(pkg *types.Package) {
maxp1 := p.parseInt()
@@ -766,6 +812,11 @@ func (p *parser) parseTypes(pkg *types.Package) {
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.
// The next runes from the scanner should be the type data.