github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/go/internal/gccgoimporter/parser.go (about)

     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  }