Home | History | Annotate | Download | only in gccgoimporter
      1 // Copyright 2013 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package gccgoimporter
      6 
      7 import (
      8 	"bytes"
      9 	"errors"
     10 	"fmt"
     11 	"go/constant"
     12 	"go/token"
     13 	"go/types"
     14 	"io"
     15 	"strconv"
     16 	"strings"
     17 	"text/scanner"
     18 )
     19 
     20 type parser struct {
     21 	scanner  scanner.Scanner
     22 	version  string                    // format version
     23 	tok      rune                      // current token
     24 	lit      string                    // literal string; only valid for Ident, Int, String tokens
     25 	pkgpath  string                    // package path of imported package
     26 	pkgname  string                    // name of imported package
     27 	pkg      *types.Package            // reference to imported package
     28 	imports  map[string]*types.Package // package path -> package object
     29 	typeMap  map[int]types.Type        // type number -> type
     30 	initdata InitData                  // package init priority data
     31 }
     32 
     33 func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
     34 	p.scanner.Init(src)
     35 	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
     36 	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
     37 	p.scanner.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' '
     38 	p.scanner.Filename = filename // for good error messages
     39 	p.next()
     40 	p.imports = imports
     41 	p.typeMap = make(map[int]types.Type)
     42 }
     43 
     44 type importError struct {
     45 	pos scanner.Position
     46 	err error
     47 }
     48 
     49 func (e importError) Error() string {
     50 	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
     51 }
     52 
     53 func (p *parser) error(err interface{}) {
     54 	if s, ok := err.(string); ok {
     55 		err = errors.New(s)
     56 	}
     57 	// panic with a runtime.Error if err is not an error
     58 	panic(importError{p.scanner.Pos(), err.(error)})
     59 }
     60 
     61 func (p *parser) errorf(format string, args ...interface{}) {
     62 	p.error(fmt.Errorf(format, args...))
     63 }
     64 
     65 func (p *parser) expect(tok rune) string {
     66 	lit := p.lit
     67 	if p.tok != tok {
     68 		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
     69 	}
     70 	p.next()
     71 	return lit
     72 }
     73 
     74 func (p *parser) expectKeyword(keyword string) {
     75 	lit := p.expect(scanner.Ident)
     76 	if lit != keyword {
     77 		p.errorf("expected keyword %s, got %q", keyword, lit)
     78 	}
     79 }
     80 
     81 func (p *parser) parseString() string {
     82 	str, err := strconv.Unquote(p.expect(scanner.String))
     83 	if err != nil {
     84 		p.error(err)
     85 	}
     86 	return str
     87 }
     88 
     89 // unquotedString     = { unquotedStringChar } .
     90 // unquotedStringChar = <neither a whitespace nor a ';' char> .
     91 func (p *parser) parseUnquotedString() string {
     92 	if p.tok == scanner.EOF {
     93 		p.error("unexpected EOF")
     94 	}
     95 	var buf bytes.Buffer
     96 	buf.WriteString(p.scanner.TokenText())
     97 	// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
     98 	// we need to let it be consumed by p.next().
     99 	for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
    100 		buf.WriteRune(ch)
    101 		p.scanner.Next()
    102 	}
    103 	p.next()
    104 	return buf.String()
    105 }
    106 
    107 func (p *parser) next() {
    108 	p.tok = p.scanner.Scan()
    109 	switch p.tok {
    110 	case scanner.Ident, scanner.Int, scanner.Float, scanner.String, '':
    111 		p.lit = p.scanner.TokenText()
    112 	default:
    113 		p.lit = ""
    114 	}
    115 }
    116 
    117 func (p *parser) parseQualifiedName() (path, name string) {
    118 	return p.parseQualifiedNameStr(p.parseString())
    119 }
    120 
    121 func (p *parser) parseUnquotedQualifiedName() (path, name string) {
    122 	return p.parseQualifiedNameStr(p.parseUnquotedString())
    123 }
    124 
    125 // qualifiedName = [ ["."] unquotedString "." ] unquotedString .
    126 //
    127 // The above production uses greedy matching.
    128 func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
    129 	parts := strings.Split(unquotedName, ".")
    130 	if parts[0] == "" {
    131 		parts = parts[1:]
    132 	}
    133 
    134 	switch len(parts) {
    135 	case 0:
    136 		p.errorf("malformed qualified name: %q", unquotedName)
    137 	case 1:
    138 		// unqualified name
    139 		pkgpath = p.pkgpath
    140 		name = parts[0]
    141 	default:
    142 		// qualified name, which may contain periods
    143 		pkgpath = strings.Join(parts[0:len(parts)-1], ".")
    144 		name = parts[len(parts)-1]
    145 	}
    146 
    147 	return
    148 }
    149 
    150 // getPkg returns the package for a given path. If the package is
    151 // not found but we have a package name, create the package and
    152 // add it to the p.imports map.
    153 //
    154 func (p *parser) getPkg(pkgpath, name string) *types.Package {
    155 	// package unsafe is not in the imports map - handle explicitly
    156 	if pkgpath == "unsafe" {
    157 		return types.Unsafe
    158 	}
    159 	pkg := p.imports[pkgpath]
    160 	if pkg == nil && name != "" {
    161 		pkg = types.NewPackage(pkgpath, name)
    162 		p.imports[pkgpath] = pkg
    163 	}
    164 	return pkg
    165 }
    166 
    167 // parseExportedName is like parseQualifiedName, but
    168 // the package path is resolved to an imported *types.Package.
    169 //
    170 // ExportedName = string [string] .
    171 func (p *parser) parseExportedName() (pkg *types.Package, name string) {
    172 	path, name := p.parseQualifiedName()
    173 	var pkgname string
    174 	if p.tok == scanner.String {
    175 		pkgname = p.parseString()
    176 	}
    177 	pkg = p.getPkg(path, pkgname)
    178 	if pkg == nil {
    179 		p.errorf("package %s (path = %q) not found", name, path)
    180 	}
    181 	return
    182 }
    183 
    184 // Name = QualifiedName | "?" .
    185 func (p *parser) parseName() string {
    186 	if p.tok == '?' {
    187 		// Anonymous.
    188 		p.next()
    189 		return ""
    190 	}
    191 	// The package path is redundant for us. Don't try to parse it.
    192 	_, name := p.parseUnquotedQualifiedName()
    193 	return name
    194 }
    195 
    196 func deref(typ types.Type) types.Type {
    197 	if p, _ := typ.(*types.Pointer); p != nil {
    198 		typ = p.Elem()
    199 	}
    200 	return typ
    201 }
    202 
    203 // Field = Name Type [string] .
    204 func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
    205 	name := p.parseName()
    206 	typ := p.parseType(pkg)
    207 	anon := false
    208 	if name == "" {
    209 		anon = true
    210 		switch typ := deref(typ).(type) {
    211 		case *types.Basic:
    212 			name = typ.Name()
    213 		case *types.Named:
    214 			name = typ.Obj().Name()
    215 		default:
    216 			p.error("anonymous field expected")
    217 		}
    218 	}
    219 	field = types.NewField(token.NoPos, pkg, name, typ, anon)
    220 	if p.tok == scanner.String {
    221 		tag = p.parseString()
    222 	}
    223 	return
    224 }
    225 
    226 // Param = Name ["..."] Type .
    227 func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
    228 	name := p.parseName()
    229 	if p.tok == '.' {
    230 		p.next()
    231 		p.expect('.')
    232 		p.expect('.')
    233 		isVariadic = true
    234 	}
    235 	typ := p.parseType(pkg)
    236 	if isVariadic {
    237 		typ = types.NewSlice(typ)
    238 	}
    239 	param = types.NewParam(token.NoPos, pkg, name, typ)
    240 	return
    241 }
    242 
    243 // Var = Name Type .
    244 func (p *parser) parseVar(pkg *types.Package) *types.Var {
    245 	name := p.parseName()
    246 	return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
    247 }
    248 
    249 // Conversion = "convert" "(" Type "," ConstValue ")" .
    250 func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
    251 	p.expectKeyword("convert")
    252 	p.expect('(')
    253 	typ = p.parseType(pkg)
    254 	p.expect(',')
    255 	val, _ = p.parseConstValue(pkg)
    256 	p.expect(')')
    257 	return
    258 }
    259 
    260 // ConstValue     = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
    261 // FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
    262 func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
    263 	switch p.tok {
    264 	case scanner.String:
    265 		str := p.parseString()
    266 		val = constant.MakeString(str)
    267 		typ = types.Typ[types.UntypedString]
    268 		return
    269 
    270 	case scanner.Ident:
    271 		b := false
    272 		switch p.lit {
    273 		case "false":
    274 		case "true":
    275 			b = true
    276 
    277 		case "convert":
    278 			return p.parseConversion(pkg)
    279 
    280 		default:
    281 			p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
    282 		}
    283 
    284 		p.next()
    285 		val = constant.MakeBool(b)
    286 		typ = types.Typ[types.UntypedBool]
    287 		return
    288 	}
    289 
    290 	sign := ""
    291 	if p.tok == '-' {
    292 		p.next()
    293 		sign = "-"
    294 	}
    295 
    296 	switch p.tok {
    297 	case scanner.Int:
    298 		val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
    299 		if val == nil {
    300 			p.error("could not parse integer literal")
    301 		}
    302 
    303 		p.next()
    304 		if p.tok == '\'' {
    305 			p.next()
    306 			typ = types.Typ[types.UntypedRune]
    307 		} else {
    308 			typ = types.Typ[types.UntypedInt]
    309 		}
    310 
    311 	case scanner.Float:
    312 		re := sign + p.lit
    313 		p.next()
    314 
    315 		var im string
    316 		switch p.tok {
    317 		case '+':
    318 			p.next()
    319 			im = p.expect(scanner.Float)
    320 
    321 		case '-':
    322 			p.next()
    323 			im = "-" + p.expect(scanner.Float)
    324 
    325 		case scanner.Ident:
    326 			// re is in fact the imaginary component. Expect "i" below.
    327 			im = re
    328 			re = "0"
    329 
    330 		default:
    331 			val = constant.MakeFromLiteral(re, token.FLOAT, 0)
    332 			if val == nil {
    333 				p.error("could not parse float literal")
    334 			}
    335 			typ = types.Typ[types.UntypedFloat]
    336 			return
    337 		}
    338 
    339 		p.expectKeyword("i")
    340 		reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
    341 		if reval == nil {
    342 			p.error("could not parse real component of complex literal")
    343 		}
    344 		imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
    345 		if imval == nil {
    346 			p.error("could not parse imag component of complex literal")
    347 		}
    348 		val = constant.BinaryOp(reval, token.ADD, imval)
    349 		typ = types.Typ[types.UntypedComplex]
    350 
    351 	default:
    352 		p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
    353 	}
    354 
    355 	return
    356 }
    357 
    358 // Const = Name [Type] "=" ConstValue .
    359 func (p *parser) parseConst(pkg *types.Package) *types.Const {
    360 	name := p.parseName()
    361 	var typ types.Type
    362 	if p.tok == '<' {
    363 		typ = p.parseType(pkg)
    364 	}
    365 	p.expect('=')
    366 	val, vtyp := p.parseConstValue(pkg)
    367 	if typ == nil {
    368 		typ = vtyp
    369 	}
    370 	return types.NewConst(token.NoPos, pkg, name, typ, val)
    371 }
    372 
    373 // TypeName = ExportedName .
    374 func (p *parser) parseTypeName() *types.TypeName {
    375 	pkg, name := p.parseExportedName()
    376 	scope := pkg.Scope()
    377 	if obj := scope.Lookup(name); obj != nil {
    378 		return obj.(*types.TypeName)
    379 	}
    380 	obj := types.NewTypeName(token.NoPos, pkg, name, nil)
    381 	// a named type may be referred to before the underlying type
    382 	// is known - set it up
    383 	types.NewNamed(obj, nil, nil)
    384 	scope.Insert(obj)
    385 	return obj
    386 }
    387 
    388 // NamedType = TypeName Type { Method } .
    389 // Method    = "func" "(" Param ")" Name ParamList ResultList ";" .
    390 func (p *parser) parseNamedType(n int) types.Type {
    391 	obj := p.parseTypeName()
    392 
    393 	pkg := obj.Pkg()
    394 	typ := obj.Type()
    395 	p.typeMap[n] = typ
    396 
    397 	nt, ok := typ.(*types.Named)
    398 	if !ok {
    399 		// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
    400 		pt := p.parseType(pkg)
    401 		if pt != typ {
    402 			p.error("unexpected underlying type for non-named TypeName")
    403 		}
    404 		return typ
    405 	}
    406 
    407 	underlying := p.parseType(pkg)
    408 	if nt.Underlying() == nil {
    409 		nt.SetUnderlying(underlying.Underlying())
    410 	}
    411 
    412 	for p.tok == scanner.Ident {
    413 		// collect associated methods
    414 		p.expectKeyword("func")
    415 		p.expect('(')
    416 		receiver, _ := p.parseParam(pkg)
    417 		p.expect(')')
    418 		name := p.parseName()
    419 		params, isVariadic := p.parseParamList(pkg)
    420 		results := p.parseResultList(pkg)
    421 		p.expect(';')
    422 
    423 		sig := types.NewSignature(receiver, params, results, isVariadic)
    424 		nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
    425 	}
    426 
    427 	return nt
    428 }
    429 
    430 func (p *parser) parseInt() int64 {
    431 	lit := p.expect(scanner.Int)
    432 	n, err := strconv.ParseInt(lit, 10, 0)
    433 	if err != nil {
    434 		p.error(err)
    435 	}
    436 	return n
    437 }
    438 
    439 // ArrayOrSliceType = "[" [ int ] "]" Type .
    440 func (p *parser) parseArrayOrSliceType(pkg *types.Package) types.Type {
    441 	p.expect('[')
    442 	if p.tok == ']' {
    443 		p.next()
    444 		return types.NewSlice(p.parseType(pkg))
    445 	}
    446 
    447 	n := p.parseInt()
    448 	p.expect(']')
    449 	return types.NewArray(p.parseType(pkg), n)
    450 }
    451 
    452 // MapType = "map" "[" Type "]" Type .
    453 func (p *parser) parseMapType(pkg *types.Package) types.Type {
    454 	p.expectKeyword("map")
    455 	p.expect('[')
    456 	key := p.parseType(pkg)
    457 	p.expect(']')
    458 	elem := p.parseType(pkg)
    459 	return types.NewMap(key, elem)
    460 }
    461 
    462 // ChanType = "chan" ["<-" | "-<"] Type .
    463 func (p *parser) parseChanType(pkg *types.Package) types.Type {
    464 	p.expectKeyword("chan")
    465 	dir := types.SendRecv
    466 	switch p.tok {
    467 	case '-':
    468 		p.next()
    469 		p.expect('<')
    470 		dir = types.SendOnly
    471 
    472 	case '<':
    473 		// don't consume '<' if it belongs to Type
    474 		if p.scanner.Peek() == '-' {
    475 			p.next()
    476 			p.expect('-')
    477 			dir = types.RecvOnly
    478 		}
    479 	}
    480 
    481 	return types.NewChan(dir, p.parseType(pkg))
    482 }
    483 
    484 // StructType = "struct" "{" { Field } "}" .
    485 func (p *parser) parseStructType(pkg *types.Package) types.Type {
    486 	p.expectKeyword("struct")
    487 
    488 	var fields []*types.Var
    489 	var tags []string
    490 
    491 	p.expect('{')
    492 	for p.tok != '}' && p.tok != scanner.EOF {
    493 		field, tag := p.parseField(pkg)
    494 		p.expect(';')
    495 		fields = append(fields, field)
    496 		tags = append(tags, tag)
    497 	}
    498 	p.expect('}')
    499 
    500 	return types.NewStruct(fields, tags)
    501 }
    502 
    503 // ParamList = "(" [ { Parameter "," } Parameter ] ")" .
    504 func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
    505 	var list []*types.Var
    506 	isVariadic := false
    507 
    508 	p.expect('(')
    509 	for p.tok != ')' && p.tok != scanner.EOF {
    510 		if len(list) > 0 {
    511 			p.expect(',')
    512 		}
    513 		par, variadic := p.parseParam(pkg)
    514 		list = append(list, par)
    515 		if variadic {
    516 			if isVariadic {
    517 				p.error("... not on final argument")
    518 			}
    519 			isVariadic = true
    520 		}
    521 	}
    522 	p.expect(')')
    523 
    524 	return types.NewTuple(list...), isVariadic
    525 }
    526 
    527 // ResultList = Type | ParamList .
    528 func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
    529 	switch p.tok {
    530 	case '<':
    531 		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg)))
    532 
    533 	case '(':
    534 		params, _ := p.parseParamList(pkg)
    535 		return params
    536 
    537 	default:
    538 		return nil
    539 	}
    540 }
    541 
    542 // FunctionType = ParamList ResultList .
    543 func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature {
    544 	params, isVariadic := p.parseParamList(pkg)
    545 	results := p.parseResultList(pkg)
    546 	return types.NewSignature(nil, params, results, isVariadic)
    547 }
    548 
    549 // Func = Name FunctionType .
    550 func (p *parser) parseFunc(pkg *types.Package) *types.Func {
    551 	name := p.parseName()
    552 	if strings.ContainsRune(name, '$') {
    553 		// This is a Type$equal or Type$hash function, which we don't want to parse,
    554 		// except for the types.
    555 		p.discardDirectiveWhileParsingTypes(pkg)
    556 		return nil
    557 	}
    558 	return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg))
    559 }
    560 
    561 // InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
    562 func (p *parser) parseInterfaceType(pkg *types.Package) types.Type {
    563 	p.expectKeyword("interface")
    564 
    565 	var methods []*types.Func
    566 	var typs []*types.Named
    567 
    568 	p.expect('{')
    569 	for p.tok != '}' && p.tok != scanner.EOF {
    570 		if p.tok == '?' {
    571 			p.next()
    572 			typs = append(typs, p.parseType(pkg).(*types.Named))
    573 		} else {
    574 			method := p.parseFunc(pkg)
    575 			methods = append(methods, method)
    576 		}
    577 		p.expect(';')
    578 	}
    579 	p.expect('}')
    580 
    581 	return types.NewInterface(methods, typs)
    582 }
    583 
    584 // PointerType = "*" ("any" | Type) .
    585 func (p *parser) parsePointerType(pkg *types.Package) types.Type {
    586 	p.expect('*')
    587 	if p.tok == scanner.Ident {
    588 		p.expectKeyword("any")
    589 		return types.Typ[types.UnsafePointer]
    590 	}
    591 	return types.NewPointer(p.parseType(pkg))
    592 }
    593 
    594 // TypeDefinition = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
    595 func (p *parser) parseTypeDefinition(pkg *types.Package, n int) types.Type {
    596 	var t types.Type
    597 	switch p.tok {
    598 	case scanner.String:
    599 		t = p.parseNamedType(n)
    600 
    601 	case scanner.Ident:
    602 		switch p.lit {
    603 		case "map":
    604 			t = p.parseMapType(pkg)
    605 
    606 		case "chan":
    607 			t = p.parseChanType(pkg)
    608 
    609 		case "struct":
    610 			t = p.parseStructType(pkg)
    611 
    612 		case "interface":
    613 			t = p.parseInterfaceType(pkg)
    614 		}
    615 
    616 	case '*':
    617 		t = p.parsePointerType(pkg)
    618 
    619 	case '[':
    620 		t = p.parseArrayOrSliceType(pkg)
    621 
    622 	case '(':
    623 		t = p.parseFunctionType(pkg)
    624 	}
    625 
    626 	p.typeMap[n] = t
    627 	return t
    628 }
    629 
    630 const (
    631 	// From gofrontend/go/export.h
    632 	// Note that these values are negative in the gofrontend and have been made positive
    633 	// in the gccgoimporter.
    634 	gccgoBuiltinINT8       = 1
    635 	gccgoBuiltinINT16      = 2
    636 	gccgoBuiltinINT32      = 3
    637 	gccgoBuiltinINT64      = 4
    638 	gccgoBuiltinUINT8      = 5
    639 	gccgoBuiltinUINT16     = 6
    640 	gccgoBuiltinUINT32     = 7
    641 	gccgoBuiltinUINT64     = 8
    642 	gccgoBuiltinFLOAT32    = 9
    643 	gccgoBuiltinFLOAT64    = 10
    644 	gccgoBuiltinINT        = 11
    645 	gccgoBuiltinUINT       = 12
    646 	gccgoBuiltinUINTPTR    = 13
    647 	gccgoBuiltinBOOL       = 15
    648 	gccgoBuiltinSTRING     = 16
    649 	gccgoBuiltinCOMPLEX64  = 17
    650 	gccgoBuiltinCOMPLEX128 = 18
    651 	gccgoBuiltinERROR      = 19
    652 	gccgoBuiltinBYTE       = 20
    653 	gccgoBuiltinRUNE       = 21
    654 )
    655 
    656 func lookupBuiltinType(typ int) types.Type {
    657 	return [...]types.Type{
    658 		gccgoBuiltinINT8:       types.Typ[types.Int8],
    659 		gccgoBuiltinINT16:      types.Typ[types.Int16],
    660 		gccgoBuiltinINT32:      types.Typ[types.Int32],
    661 		gccgoBuiltinINT64:      types.Typ[types.Int64],
    662 		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
    663 		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
    664 		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
    665 		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
    666 		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
    667 		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
    668 		gccgoBuiltinINT:        types.Typ[types.Int],
    669 		gccgoBuiltinUINT:       types.Typ[types.Uint],
    670 		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
    671 		gccgoBuiltinBOOL:       types.Typ[types.Bool],
    672 		gccgoBuiltinSTRING:     types.Typ[types.String],
    673 		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
    674 		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
    675 		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
    676 		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
    677 		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
    678 	}[typ]
    679 }
    680 
    681 // Type = "<" "type" ( "-" int | int [ TypeDefinition ] ) ">" .
    682 func (p *parser) parseType(pkg *types.Package) (t types.Type) {
    683 	p.expect('<')
    684 	p.expectKeyword("type")
    685 
    686 	switch p.tok {
    687 	case scanner.Int:
    688 		n := p.parseInt()
    689 
    690 		if p.tok == '>' {
    691 			t = p.typeMap[int(n)]
    692 		} else {
    693 			t = p.parseTypeDefinition(pkg, int(n))
    694 		}
    695 
    696 	case '-':
    697 		p.next()
    698 		n := p.parseInt()
    699 		t = lookupBuiltinType(int(n))
    700 
    701 	default:
    702 		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
    703 		return nil
    704 	}
    705 
    706 	p.expect('>')
    707 	return
    708 }
    709 
    710 // PackageInit = unquotedString unquotedString int .
    711 func (p *parser) parsePackageInit() PackageInit {
    712 	name := p.parseUnquotedString()
    713 	initfunc := p.parseUnquotedString()
    714 	priority := -1
    715 	if p.version == "v1" {
    716 		priority = int(p.parseInt())
    717 	}
    718 	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
    719 }
    720 
    721 // Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type.
    722 func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) {
    723 	for {
    724 		switch p.tok {
    725 		case ';':
    726 			return
    727 		case '<':
    728 			p.parseType(p.pkg)
    729 		case scanner.EOF:
    730 			p.error("unexpected EOF")
    731 		default:
    732 			p.next()
    733 		}
    734 	}
    735 }
    736 
    737 // Create the package if we have parsed both the package path and package name.
    738 func (p *parser) maybeCreatePackage() {
    739 	if p.pkgname != "" && p.pkgpath != "" {
    740 		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
    741 	}
    742 }
    743 
    744 // InitDataDirective = ( "v1" | "v2" ) ";" |
    745 //                     "priority" int ";" |
    746 //                     "init" { PackageInit } ";" |
    747 //                     "checksum" unquotedString ";" .
    748 func (p *parser) parseInitDataDirective() {
    749 	if p.tok != scanner.Ident {
    750 		// unexpected token kind; panic
    751 		p.expect(scanner.Ident)
    752 	}
    753 
    754 	switch p.lit {
    755 	case "v1", "v2":
    756 		p.version = p.lit
    757 		p.next()
    758 		p.expect(';')
    759 
    760 	case "priority":
    761 		p.next()
    762 		p.initdata.Priority = int(p.parseInt())
    763 		p.expect(';')
    764 
    765 	case "init":
    766 		p.next()
    767 		for p.tok != ';' && p.tok != scanner.EOF {
    768 			p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
    769 		}
    770 		p.expect(';')
    771 
    772 	case "init_graph":
    773 		p.next()
    774 		// The graph data is thrown away for now.
    775 		for p.tok != ';' && p.tok != scanner.EOF {
    776 			p.parseInt()
    777 			p.parseInt()
    778 		}
    779 		p.expect(';')
    780 
    781 	case "checksum":
    782 		// Don't let the scanner try to parse the checksum as a number.
    783 		defer func(mode uint) {
    784 			p.scanner.Mode = mode
    785 		}(p.scanner.Mode)
    786 		p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
    787 		p.next()
    788 		p.parseUnquotedString()
    789 		p.expect(';')
    790 
    791 	default:
    792 		p.errorf("unexpected identifier: %q", p.lit)
    793 	}
    794 }
    795 
    796 // Directive = InitDataDirective |
    797 //             "package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
    798 //             "pkgpath" unquotedString ";" |
    799 //             "prefix" unquotedString ";" |
    800 //             "import" unquotedString unquotedString string ";" |
    801 //             "func" Func ";" |
    802 //             "type" Type ";" |
    803 //             "var" Var ";" |
    804 //             "const" Const ";" .
    805 func (p *parser) parseDirective() {
    806 	if p.tok != scanner.Ident {
    807 		// unexpected token kind; panic
    808 		p.expect(scanner.Ident)
    809 	}
    810 
    811 	switch p.lit {
    812 	case "v1", "v2", "priority", "init", "init_graph", "checksum":
    813 		p.parseInitDataDirective()
    814 
    815 	case "package":
    816 		p.next()
    817 		p.pkgname = p.parseUnquotedString()
    818 		p.maybeCreatePackage()
    819 		if p.version == "v2" && p.tok != ';' {
    820 			p.parseUnquotedString()
    821 			p.parseUnquotedString()
    822 		}
    823 		p.expect(';')
    824 
    825 	case "pkgpath":
    826 		p.next()
    827 		p.pkgpath = p.parseUnquotedString()
    828 		p.maybeCreatePackage()
    829 		p.expect(';')
    830 
    831 	case "prefix":
    832 		p.next()
    833 		p.pkgpath = p.parseUnquotedString()
    834 		p.expect(';')
    835 
    836 	case "import":
    837 		p.next()
    838 		pkgname := p.parseUnquotedString()
    839 		pkgpath := p.parseUnquotedString()
    840 		p.getPkg(pkgpath, pkgname)
    841 		p.parseString()
    842 		p.expect(';')
    843 
    844 	case "func":
    845 		p.next()
    846 		fun := p.parseFunc(p.pkg)
    847 		if fun != nil {
    848 			p.pkg.Scope().Insert(fun)
    849 		}
    850 		p.expect(';')
    851 
    852 	case "type":
    853 		p.next()
    854 		p.parseType(p.pkg)
    855 		p.expect(';')
    856 
    857 	case "var":
    858 		p.next()
    859 		v := p.parseVar(p.pkg)
    860 		p.pkg.Scope().Insert(v)
    861 		p.expect(';')
    862 
    863 	case "const":
    864 		p.next()
    865 		c := p.parseConst(p.pkg)
    866 		p.pkg.Scope().Insert(c)
    867 		p.expect(';')
    868 
    869 	default:
    870 		p.errorf("unexpected identifier: %q", p.lit)
    871 	}
    872 }
    873 
    874 // Package = { Directive } .
    875 func (p *parser) parsePackage() *types.Package {
    876 	for p.tok != scanner.EOF {
    877 		p.parseDirective()
    878 	}
    879 	for _, typ := range p.typeMap {
    880 		if it, ok := typ.(*types.Interface); ok {
    881 			it.Complete()
    882 		}
    883 	}
    884 	p.pkg.MarkComplete()
    885 	return p.pkg
    886 }
    887 
    888 // InitData = { InitDataDirective } .
    889 func (p *parser) parseInitData() {
    890 	for p.tok != scanner.EOF {
    891 		p.parseInitDataDirective()
    892 	}
    893 }
    894