aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
Diffstat (limited to 'libgo')
-rw-r--r--libgo/go/go/internal/gccgoimporter/importer.go5
-rw-r--r--libgo/go/go/internal/gccgoimporter/parser.go82
-rw-r--r--libgo/go/go/internal/gccgoimporter/parser_test.go2
3 files changed, 51 insertions, 38 deletions
diff --git a/libgo/go/go/internal/gccgoimporter/importer.go b/libgo/go/go/internal/gccgoimporter/importer.go
index 7bc2afc..d3ce10c 100644
--- a/libgo/go/go/internal/gccgoimporter/importer.go
+++ b/libgo/go/go/internal/gccgoimporter/importer.go
@@ -64,6 +64,7 @@ func findExportFile(searchpaths []string, pkgpath string) (string, error) {
const (
gccgov1Magic = "v1;\n"
gccgov2Magic = "v2;\n"
+ gccgov3Magic = "v3;\n"
goimporterMagic = "\n$$ "
archiveMagic = "!<ar"
aixbigafMagic = "<big"
@@ -93,7 +94,7 @@ func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err e
var objreader io.ReaderAt
switch string(magic[:]) {
- case gccgov1Magic, gccgov2Magic, goimporterMagic:
+ case gccgov1Magic, gccgov2Magic, gccgov3Magic, goimporterMagic:
// Raw export data.
reader = f
return
@@ -208,7 +209,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo
}
switch magics {
- case gccgov1Magic, gccgov2Magic:
+ case gccgov1Magic, gccgov2Magic, gccgov3Magic:
var p parser
p.init(fpath, reader, imports)
pkg = p.parsePackage()
diff --git a/libgo/go/go/internal/gccgoimporter/parser.go b/libgo/go/go/internal/gccgoimporter/parser.go
index 9f8c19b..5988c5d 100644
--- a/libgo/go/go/internal/gccgoimporter/parser.go
+++ b/libgo/go/go/internal/gccgoimporter/parser.go
@@ -34,7 +34,7 @@ func (p *parser) init(filename string, src io.Reader, imports map[string]*types.
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.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' '
+ p.scanner.Whitespace = 1<<'\t' | 1<<' '
p.scanner.Filename = filename // for good error messages
p.next()
p.imports = imports
@@ -71,6 +71,13 @@ func (p *parser) expect(tok rune) string {
return lit
}
+func (p *parser) expectEOL() {
+ if p.version == "v1" || p.version == "v2" {
+ p.expect(';')
+ }
+ p.expect('\n')
+}
+
func (p *parser) expectKeyword(keyword string) {
lit := p.expect(scanner.Ident)
if lit != keyword {
@@ -96,7 +103,7 @@ func (p *parser) parseUnquotedString() string {
buf.WriteString(p.scanner.TokenText())
// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
// we need to let it be consumed by p.next().
- for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
+ for ch := p.scanner.Peek(); ch != '\n' && ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
buf.WriteRune(ch)
p.scanner.Next()
}
@@ -431,19 +438,22 @@ func (p *parser) parseNamedType(n int) types.Type {
nt.SetUnderlying(underlying.Underlying())
}
- // collect associated methods
- for p.tok == scanner.Ident {
- p.expectKeyword("func")
- p.expect('(')
- receiver, _ := p.parseParam(pkg)
- p.expect(')')
- name := p.parseName()
- params, isVariadic := p.parseParamList(pkg)
- results := p.parseResultList(pkg)
- p.expect(';')
-
- sig := types.NewSignature(receiver, params, results, isVariadic)
- nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
+ if p.tok == '\n' {
+ p.next()
+ // collect associated methods
+ for p.tok == scanner.Ident {
+ p.expectKeyword("func")
+ p.expect('(')
+ receiver, _ := p.parseParam(pkg)
+ p.expect(')')
+ name := p.parseName()
+ params, isVariadic := p.parseParamList(pkg)
+ results := p.parseResultList(pkg)
+ p.expectEOL()
+
+ sig := types.NewSignature(receiver, params, results, isVariadic)
+ nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
+ }
}
return nt
@@ -740,11 +750,12 @@ 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.
+// Throw away tokens until we see a newline or ';'.
+// If we see a '<', attempt to parse as a type.
func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) {
for {
switch p.tok {
- case ';':
+ case '\n', ';':
return
case '<':
p.parseType(pkg)
@@ -763,7 +774,7 @@ func (p *parser) maybeCreatePackage() {
}
}
-// InitDataDirective = ( "v1" | "v2" ) ";" |
+// InitDataDirective = ( "v1" | "v2" | "v3" ) ";" |
// "priority" int ";" |
// "init" { PackageInit } ";" |
// "checksum" unquotedString ";" .
@@ -774,31 +785,32 @@ func (p *parser) parseInitDataDirective() {
}
switch p.lit {
- case "v1", "v2":
+ case "v1", "v2", "v3":
p.version = p.lit
p.next()
p.expect(';')
+ p.expect('\n')
case "priority":
p.next()
p.initdata.Priority = int(p.parseInt())
- p.expect(';')
+ p.expectEOL()
case "init":
p.next()
- for p.tok != ';' && p.tok != scanner.EOF {
+ for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
}
- p.expect(';')
+ p.expectEOL()
case "init_graph":
p.next()
// The graph data is thrown away for now.
- for p.tok != ';' && p.tok != scanner.EOF {
+ for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
p.parseInt()
p.parseInt()
}
- p.expect(';')
+ p.expectEOL()
case "checksum":
// Don't let the scanner try to parse the checksum as a number.
@@ -808,7 +820,7 @@ func (p *parser) parseInitDataDirective() {
p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
p.next()
p.parseUnquotedString()
- p.expect(';')
+ p.expectEOL()
default:
p.errorf("unexpected identifier: %q", p.lit)
@@ -831,29 +843,29 @@ func (p *parser) parseDirective() {
}
switch p.lit {
- case "v1", "v2", "priority", "init", "init_graph", "checksum":
+ case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum":
p.parseInitDataDirective()
case "package":
p.next()
p.pkgname = p.parseUnquotedString()
p.maybeCreatePackage()
- if p.version == "v2" && p.tok != ';' {
+ if p.version != "v1" && p.tok != '\n' && p.tok != ';' {
p.parseUnquotedString()
p.parseUnquotedString()
}
- p.expect(';')
+ p.expectEOL()
case "pkgpath":
p.next()
p.pkgpath = p.parseUnquotedString()
p.maybeCreatePackage()
- p.expect(';')
+ p.expectEOL()
case "prefix":
p.next()
p.pkgpath = p.parseUnquotedString()
- p.expect(';')
+ p.expectEOL()
case "import":
p.next()
@@ -861,7 +873,7 @@ func (p *parser) parseDirective() {
pkgpath := p.parseUnquotedString()
p.getPkg(pkgpath, pkgname)
p.parseString()
- p.expect(';')
+ p.expectEOL()
case "func":
p.next()
@@ -869,24 +881,24 @@ func (p *parser) parseDirective() {
if fun != nil {
p.pkg.Scope().Insert(fun)
}
- p.expect(';')
+ p.expectEOL()
case "type":
p.next()
p.parseType(p.pkg)
- p.expect(';')
+ p.expectEOL()
case "var":
p.next()
v := p.parseVar(p.pkg)
p.pkg.Scope().Insert(v)
- p.expect(';')
+ p.expectEOL()
case "const":
p.next()
c := p.parseConst(p.pkg)
p.pkg.Scope().Insert(c)
- p.expect(';')
+ p.expectEOL()
default:
p.errorf("unexpected identifier: %q", p.lit)
diff --git a/libgo/go/go/internal/gccgoimporter/parser_test.go b/libgo/go/go/internal/gccgoimporter/parser_test.go
index 4a103dc4..4d3568a 100644
--- a/libgo/go/go/internal/gccgoimporter/parser_test.go
+++ b/libgo/go/go/internal/gccgoimporter/parser_test.go
@@ -19,7 +19,7 @@ var typeParserTests = []struct {
{id: "foo", typ: "<type 1 *<type -19>>", want: "*error"},
{id: "foo", typ: "<type 1 *any>", want: "unsafe.Pointer"},
{id: "foo", typ: "<type 1 \"Bar\" <type 2 *<type 1>>>", want: "foo.Bar", underlying: "*foo.Bar"},
- {id: "foo", typ: "<type 1 \"bar.Foo\" \"bar\" <type -1> func (? <type 1>) M (); >", want: "bar.Foo", underlying: "int8", methods: "func (bar.Foo).M()"},
+ {id: "foo", typ: "<type 1 \"bar.Foo\" \"bar\" <type -1>\n func (? <type 1>) M ()\n>", want: "bar.Foo", underlying: "int8", methods: "func (bar.Foo).M()"},
{id: "foo", typ: "<type 1 \".bar.foo\" \"bar\" <type -1>>", want: "bar.foo", underlying: "int8"},
{id: "foo", typ: "<type 1 []<type -1>>", want: "[]int8"},
{id: "foo", typ: "<type 1 [42]<type -1>>", want: "[42]int8"},