Skip to content

Commit

Permalink
go/internal/gccgoimporter: handle conversions in exported const values
Browse files Browse the repository at this point in the history
Same as https://go-review.googlesource.com/c/33412/ in the standard library.

Fixes #17981.

Change-Id: Iaf47872840a4456d824ed5d7b3eda205c043e4cf
Reviewed-on: https://go-review.googlesource.com/34110
Reviewed-by: Robert Griesemer <gri@golang.org>
  • Loading branch information
adonovan committed Dec 7, 2016
1 parent 99be5a0 commit 3d92dd6
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 9 deletions.
5 changes: 3 additions & 2 deletions go/internal/gccgoimporter/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func findExportFile(searchpaths []string, pkgpath string) (string, error) {

const (
gccgov1Magic = "v1;\n"
gccgov2Magic = "v2;\n"
goimporterMagic = "\n$$ "
archiveMagic = "!<ar"
)
Expand Down Expand Up @@ -93,7 +94,7 @@ func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err e

var elfreader io.ReaderAt
switch string(magic[:]) {
case gccgov1Magic, goimporterMagic:
case gccgov1Magic, gccgov2Magic, goimporterMagic:
// Raw export data.
reader = f
return
Expand Down Expand Up @@ -170,7 +171,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo
}

switch string(magic[:]) {
case gccgov1Magic:
case gccgov1Magic, gccgov2Magic:
var p parser
p.init(fpath, reader, imports)
pkg = p.parsePackage()
Expand Down
1 change: 1 addition & 0 deletions go/internal/gccgoimporter/importer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ var importerTests = [...]importerTest{
{pkgpath: "complexnums", name: "NP", want: "const NP untyped complex", wantval: "(-1 + 1i)"},
{pkgpath: "complexnums", name: "PN", want: "const PN untyped complex", wantval: "(1 + -1i)"},
{pkgpath: "complexnums", name: "PP", want: "const PP untyped complex", wantval: "(1 + 1i)"},
{pkgpath: "conversions", name: "Bits", want: "const Bits Units", wantval: `"bits"`},
// TODO: enable this entry once bug has been tracked down
//{pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}},
}
Expand Down
40 changes: 33 additions & 7 deletions go/internal/gccgoimporter/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

type parser struct {
scanner scanner.Scanner
version string // format version
tok rune // current token
lit string // literal string; only valid for Ident, Int, String tokens
pkgpath string // package path of imported package
Expand Down Expand Up @@ -247,9 +248,20 @@ func (p *parser) parseVar(pkg *types.Package) *types.Var {
return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
}

// ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) .
// Conversion = "convert" "(" Type "," ConstValue ")" .
func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
p.expectKeyword("convert")
p.expect('(')
typ = p.parseType(pkg)
p.expect(',')
val, _ = p.parseConstValue(pkg)
p.expect(')')
return
}

// ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
// FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
func (p *parser) parseConstValue() (val constant.Value, typ types.Type) {
func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
switch p.tok {
case scanner.String:
str := p.parseString()
Expand All @@ -264,6 +276,9 @@ func (p *parser) parseConstValue() (val constant.Value, typ types.Type) {
case "true":
b = true

case "convert":
return p.parseConversion(pkg)

default:
p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
}
Expand Down Expand Up @@ -350,7 +365,7 @@ func (p *parser) parseConst(pkg *types.Package) *types.Const {
typ = p.parseType(pkg)
}
p.expect('=')
val, vtyp := p.parseConstValue()
val, vtyp := p.parseConstValue(pkg)
if typ == nil {
typ = vtyp
}
Expand Down Expand Up @@ -725,7 +740,7 @@ func (p *parser) maybeCreatePackage() {
}
}

// InitDataDirective = "v1" ";" |
// InitDataDirective = ( "v1" | "v2" ) ";" |
// "priority" int ";" |
// "init" { PackageInit } ";" |
// "checksum" unquotedString ";" .
Expand All @@ -736,7 +751,8 @@ func (p *parser) parseInitDataDirective() {
}

switch p.lit {
case "v1":
case "v1", "v2":
p.version = p.lit
p.next()
p.expect(';')

Expand Down Expand Up @@ -768,8 +784,9 @@ func (p *parser) parseInitDataDirective() {
}

// Directive = InitDataDirective |
// "package" unquotedString ";" |
// "package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
// "pkgpath" unquotedString ";" |
// "prefix" unquotedString ";" |
// "import" unquotedString unquotedString string ";" |
// "func" Func ";" |
// "type" Type ";" |
Expand All @@ -782,13 +799,17 @@ func (p *parser) parseDirective() {
}

switch p.lit {
case "v1", "priority", "init", "checksum":
case "v1", "v2", "priority", "init", "checksum":
p.parseInitDataDirective()

case "package":
p.next()
p.pkgname = p.parseUnquotedString()
p.maybeCreatePackage()
if p.version == "v2" && p.tok != ';' {
p.parseUnquotedString()
p.parseUnquotedString()
}
p.expect(';')

case "pkgpath":
Expand All @@ -797,6 +818,11 @@ func (p *parser) parseDirective() {
p.maybeCreatePackage()
p.expect(';')

case "prefix":
p.next()
p.pkgpath = p.parseUnquotedString()
p.expect(';')

case "import":
p.next()
pkgname := p.parseUnquotedString()
Expand Down
5 changes: 5 additions & 0 deletions go/internal/gccgoimporter/testdata/conversions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package conversions

type Units string

const Bits = Units("bits")
6 changes: 6 additions & 0 deletions go/internal/gccgoimporter/testdata/conversions.gox
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
v2;
package conversions;
prefix go;
package conversions go.conversions go.conversions;
const Bits <type 1 "Units" <type -16>> = convert(<type 1>, "bits");
type <type 1>;

0 comments on commit 3d92dd6

Please sign in to comment.