const (
gccgov1Magic = "v1;\n"
+ gccgov2Magic = "v2;\n"
goimporterMagic = "\n$$ "
archiveMagic = "!<ar"
)
var elfreader io.ReaderAt
switch string(magic[:]) {
- case gccgov1Magic, goimporterMagic:
+ case gccgov1Magic, gccgov2Magic, goimporterMagic:
// Raw export data.
reader = f
return
}
switch string(magic[:]) {
- case gccgov1Magic:
+ case gccgov1Magic, gccgov2Magic:
var p parser
p.init(fpath, reader, imports)
pkg = p.parsePackage()
{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"}},
}
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
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()
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)
}
typ = p.parseType(pkg)
}
p.expect('=')
- val, vtyp := p.parseConstValue()
+ val, vtyp := p.parseConstValue(pkg)
if typ == nil {
typ = vtyp
}
}
}
-// InitDataDirective = "v1" ";" |
+// InitDataDirective = ( "v1" | "v2" ) ";" |
// "priority" int ";" |
// "init" { PackageInit } ";" |
// "checksum" unquotedString ";" .
}
switch p.lit {
- case "v1":
+ case "v1", "v2":
+ p.version = p.lit
p.next()
p.expect(';')
}
// Directive = InitDataDirective |
-// "package" unquotedString ";" |
+// "package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
// "pkgpath" unquotedString ";" |
+// "prefix" unquotedString ";" |
// "import" unquotedString unquotedString string ";" |
// "func" Func ";" |
// "type" Type ";" |
}
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":
p.maybeCreatePackage()
p.expect(';')
+ case "prefix":
+ p.next()
+ p.pkgpath = p.parseUnquotedString()
+ p.expect(';')
+
case "import":
p.next()
pkgname := p.parseUnquotedString()