github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/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  	typeList []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.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
    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 == '<' && p.scanner.Peek() == 'e' {
   230  		// EscInfo = "<esc:" int ">" . (optional and ignored)
   231  		p.next()
   232  		p.expectKeyword("esc")
   233  		p.expect(':')
   234  		p.expect(scanner.Int)
   235  		p.expect('>')
   236  	}
   237  	if p.tok == '.' {
   238  		p.next()
   239  		p.expect('.')
   240  		p.expect('.')
   241  		isVariadic = true
   242  	}
   243  	typ := p.parseType(pkg)
   244  	if isVariadic {
   245  		typ = types.NewSlice(typ)
   246  	}
   247  	param = types.NewParam(token.NoPos, pkg, name, typ)
   248  	return
   249  }
   250  
   251  // Var = Name Type .
   252  func (p *parser) parseVar(pkg *types.Package) *types.Var {
   253  	name := p.parseName()
   254  	return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
   255  }
   256  
   257  // Conversion = "convert" "(" Type "," ConstValue ")" .
   258  func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
   259  	p.expectKeyword("convert")
   260  	p.expect('(')
   261  	typ = p.parseType(pkg)
   262  	p.expect(',')
   263  	val, _ = p.parseConstValue(pkg)
   264  	p.expect(')')
   265  	return
   266  }
   267  
   268  // ConstValue     = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
   269  // FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
   270  func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
   271  	switch p.tok {
   272  	case scanner.String:
   273  		str := p.parseString()
   274  		val = constant.MakeString(str)
   275  		typ = types.Typ[types.UntypedString]
   276  		return
   277  
   278  	case scanner.Ident:
   279  		b := false
   280  		switch p.lit {
   281  		case "false":
   282  		case "true":
   283  			b = true
   284  
   285  		case "convert":
   286  			return p.parseConversion(pkg)
   287  
   288  		default:
   289  			p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   290  		}
   291  
   292  		p.next()
   293  		val = constant.MakeBool(b)
   294  		typ = types.Typ[types.UntypedBool]
   295  		return
   296  	}
   297  
   298  	sign := ""
   299  	if p.tok == '-' {
   300  		p.next()
   301  		sign = "-"
   302  	}
   303  
   304  	switch p.tok {
   305  	case scanner.Int:
   306  		val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
   307  		if val == nil {
   308  			p.error("could not parse integer literal")
   309  		}
   310  
   311  		p.next()
   312  		if p.tok == '\'' {
   313  			p.next()
   314  			typ = types.Typ[types.UntypedRune]
   315  		} else {
   316  			typ = types.Typ[types.UntypedInt]
   317  		}
   318  
   319  	case scanner.Float:
   320  		re := sign + p.lit
   321  		p.next()
   322  
   323  		var im string
   324  		switch p.tok {
   325  		case '+':
   326  			p.next()
   327  			im = p.expect(scanner.Float)
   328  
   329  		case '-':
   330  			p.next()
   331  			im = "-" + p.expect(scanner.Float)
   332  
   333  		case scanner.Ident:
   334  			// re is in fact the imaginary component. Expect "i" below.
   335  			im = re
   336  			re = "0"
   337  
   338  		default:
   339  			val = constant.MakeFromLiteral(re, token.FLOAT, 0)
   340  			if val == nil {
   341  				p.error("could not parse float literal")
   342  			}
   343  			typ = types.Typ[types.UntypedFloat]
   344  			return
   345  		}
   346  
   347  		p.expectKeyword("i")
   348  		reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
   349  		if reval == nil {
   350  			p.error("could not parse real component of complex literal")
   351  		}
   352  		imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
   353  		if imval == nil {
   354  			p.error("could not parse imag component of complex literal")
   355  		}
   356  		val = constant.BinaryOp(reval, token.ADD, imval)
   357  		typ = types.Typ[types.UntypedComplex]
   358  
   359  	default:
   360  		p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   361  	}
   362  
   363  	return
   364  }
   365  
   366  // Const = Name [Type] "=" ConstValue .
   367  func (p *parser) parseConst(pkg *types.Package) *types.Const {
   368  	name := p.parseName()
   369  	var typ types.Type
   370  	if p.tok == '<' {
   371  		typ = p.parseType(pkg)
   372  	}
   373  	p.expect('=')
   374  	val, vtyp := p.parseConstValue(pkg)
   375  	if typ == nil {
   376  		typ = vtyp
   377  	}
   378  	return types.NewConst(token.NoPos, pkg, name, typ, val)
   379  }
   380  
   381  // reserved is a singleton type used to fill type map slots that have
   382  // been reserved (i.e., for which a type number has been parsed) but
   383  // which don't have their actual type yet. When the type map is updated,
   384  // the actual type must replace a reserved entry (or we have an internal
   385  // error). Used for self-verification only - not required for correctness.
   386  var reserved = new(struct{ types.Type })
   387  
   388  // reserve reserves the type map entry n for future use.
   389  func (p *parser) reserve(n int) {
   390  	if n != len(p.typeList) {
   391  		p.errorf("invalid type number %d (out of sync)", n)
   392  	}
   393  	p.typeList = append(p.typeList, reserved)
   394  }
   395  
   396  // update sets the type map entries for the given type numbers nlist to t.
   397  func (p *parser) update(t types.Type, nlist []int) {
   398  	for _, n := range nlist {
   399  		if p.typeList[n] != reserved {
   400  			p.errorf("typeMap[%d] not reserved", n)
   401  		}
   402  		p.typeList[n] = t
   403  	}
   404  }
   405  
   406  // NamedType = TypeName [ "=" ] Type { Method } .
   407  // TypeName  = ExportedName .
   408  // Method    = "func" "(" Param ")" Name ParamList ResultList ";" .
   409  func (p *parser) parseNamedType(nlist []int) types.Type {
   410  	pkg, name := p.parseExportedName()
   411  	scope := pkg.Scope()
   412  	obj := scope.Lookup(name)
   413  	if obj != nil && obj.Type() == nil {
   414  		p.errorf("%v has nil type", obj)
   415  	}
   416  
   417  	// type alias
   418  	if p.tok == '=' {
   419  		p.next()
   420  		if obj != nil {
   421  			// use the previously imported (canonical) type
   422  			t := obj.Type()
   423  			p.update(t, nlist)
   424  			p.parseType(pkg) // discard
   425  			return t
   426  		}
   427  		t := p.parseType(pkg, nlist...)
   428  		obj = types.NewTypeName(token.NoPos, pkg, name, t)
   429  		scope.Insert(obj)
   430  		return t
   431  	}
   432  
   433  	// defined type
   434  	if obj == nil {
   435  		// A named type may be referred to before the underlying type
   436  		// is known - set it up.
   437  		tname := types.NewTypeName(token.NoPos, pkg, name, nil)
   438  		types.NewNamed(tname, nil, nil)
   439  		scope.Insert(tname)
   440  		obj = tname
   441  	}
   442  
   443  	// use the previously imported (canonical), or newly created type
   444  	t := obj.Type()
   445  	p.update(t, nlist)
   446  
   447  	nt, ok := t.(*types.Named)
   448  	if !ok {
   449  		// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
   450  		pt := p.parseType(pkg)
   451  		if pt != t {
   452  			p.error("unexpected underlying type for non-named TypeName")
   453  		}
   454  		return t
   455  	}
   456  
   457  	underlying := p.parseType(pkg)
   458  	if nt.Underlying() == nil {
   459  		nt.SetUnderlying(underlying.Underlying())
   460  	}
   461  
   462  	// collect associated methods
   463  	for p.tok == scanner.Ident {
   464  		p.expectKeyword("func")
   465  		p.expect('(')
   466  		receiver, _ := p.parseParam(pkg)
   467  		p.expect(')')
   468  		name := p.parseName()
   469  		params, isVariadic := p.parseParamList(pkg)
   470  		results := p.parseResultList(pkg)
   471  		p.expect(';')
   472  
   473  		sig := types.NewSignature(receiver, params, results, isVariadic)
   474  		nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
   475  	}
   476  
   477  	return nt
   478  }
   479  
   480  func (p *parser) parseInt64() int64 {
   481  	lit := p.expect(scanner.Int)
   482  	n, err := strconv.ParseInt(lit, 10, 64)
   483  	if err != nil {
   484  		p.error(err)
   485  	}
   486  	return n
   487  }
   488  
   489  func (p *parser) parseInt() int {
   490  	lit := p.expect(scanner.Int)
   491  	n, err := strconv.ParseInt(lit, 10, 0 /* int */)
   492  	if err != nil {
   493  		p.error(err)
   494  	}
   495  	return int(n)
   496  }
   497  
   498  // ArrayOrSliceType = "[" [ int ] "]" Type .
   499  func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []int) types.Type {
   500  	p.expect('[')
   501  	if p.tok == ']' {
   502  		p.next()
   503  
   504  		t := new(types.Slice)
   505  		p.update(t, nlist)
   506  
   507  		*t = *types.NewSlice(p.parseType(pkg))
   508  		return t
   509  	}
   510  
   511  	t := new(types.Array)
   512  	p.update(t, nlist)
   513  
   514  	len := p.parseInt64()
   515  	p.expect(']')
   516  
   517  	*t = *types.NewArray(p.parseType(pkg), len)
   518  	return t
   519  }
   520  
   521  // MapType = "map" "[" Type "]" Type .
   522  func (p *parser) parseMapType(pkg *types.Package, nlist []int) types.Type {
   523  	p.expectKeyword("map")
   524  
   525  	t := new(types.Map)
   526  	p.update(t, nlist)
   527  
   528  	p.expect('[')
   529  	key := p.parseType(pkg)
   530  	p.expect(']')
   531  	elem := p.parseType(pkg)
   532  
   533  	*t = *types.NewMap(key, elem)
   534  	return t
   535  }
   536  
   537  // ChanType = "chan" ["<-" | "-<"] Type .
   538  func (p *parser) parseChanType(pkg *types.Package, nlist []int) types.Type {
   539  	p.expectKeyword("chan")
   540  
   541  	t := new(types.Chan)
   542  	p.update(t, nlist)
   543  
   544  	dir := types.SendRecv
   545  	switch p.tok {
   546  	case '-':
   547  		p.next()
   548  		p.expect('<')
   549  		dir = types.SendOnly
   550  
   551  	case '<':
   552  		// don't consume '<' if it belongs to Type
   553  		if p.scanner.Peek() == '-' {
   554  			p.next()
   555  			p.expect('-')
   556  			dir = types.RecvOnly
   557  		}
   558  	}
   559  
   560  	*t = *types.NewChan(dir, p.parseType(pkg))
   561  	return t
   562  }
   563  
   564  // StructType = "struct" "{" { Field } "}" .
   565  func (p *parser) parseStructType(pkg *types.Package, nlist []int) types.Type {
   566  	p.expectKeyword("struct")
   567  
   568  	t := new(types.Struct)
   569  	p.update(t, nlist)
   570  
   571  	var fields []*types.Var
   572  	var tags []string
   573  
   574  	p.expect('{')
   575  	for p.tok != '}' && p.tok != scanner.EOF {
   576  		field, tag := p.parseField(pkg)
   577  		p.expect(';')
   578  		fields = append(fields, field)
   579  		tags = append(tags, tag)
   580  	}
   581  	p.expect('}')
   582  
   583  	*t = *types.NewStruct(fields, tags)
   584  	return t
   585  }
   586  
   587  // ParamList = "(" [ { Parameter "," } Parameter ] ")" .
   588  func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
   589  	var list []*types.Var
   590  	isVariadic := false
   591  
   592  	p.expect('(')
   593  	for p.tok != ')' && p.tok != scanner.EOF {
   594  		if len(list) > 0 {
   595  			p.expect(',')
   596  		}
   597  		par, variadic := p.parseParam(pkg)
   598  		list = append(list, par)
   599  		if variadic {
   600  			if isVariadic {
   601  				p.error("... not on final argument")
   602  			}
   603  			isVariadic = true
   604  		}
   605  	}
   606  	p.expect(')')
   607  
   608  	return types.NewTuple(list...), isVariadic
   609  }
   610  
   611  // ResultList = Type | ParamList .
   612  func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
   613  	switch p.tok {
   614  	case '<':
   615  		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg)))
   616  
   617  	case '(':
   618  		params, _ := p.parseParamList(pkg)
   619  		return params
   620  
   621  	default:
   622  		return nil
   623  	}
   624  }
   625  
   626  // FunctionType = ParamList ResultList .
   627  func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signature {
   628  	t := new(types.Signature)
   629  	p.update(t, nlist)
   630  
   631  	params, isVariadic := p.parseParamList(pkg)
   632  	results := p.parseResultList(pkg)
   633  
   634  	*t = *types.NewSignature(nil, params, results, isVariadic)
   635  	return t
   636  }
   637  
   638  // Func = Name FunctionType .
   639  func (p *parser) parseFunc(pkg *types.Package) *types.Func {
   640  	name := p.parseName()
   641  	if strings.ContainsRune(name, '$') {
   642  		// This is a Type$equal or Type$hash function, which we don't want to parse,
   643  		// except for the types.
   644  		p.discardDirectiveWhileParsingTypes(pkg)
   645  		return nil
   646  	}
   647  	return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
   648  }
   649  
   650  // InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
   651  func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type {
   652  	p.expectKeyword("interface")
   653  
   654  	t := new(types.Interface)
   655  	p.update(t, nlist)
   656  
   657  	var methods []*types.Func
   658  	var embeddeds []types.Type
   659  
   660  	p.expect('{')
   661  	for p.tok != '}' && p.tok != scanner.EOF {
   662  		if p.tok == '?' {
   663  			p.next()
   664  			embeddeds = append(embeddeds, p.parseType(pkg))
   665  		} else {
   666  			method := p.parseFunc(pkg)
   667  			methods = append(methods, method)
   668  		}
   669  		p.expect(';')
   670  	}
   671  	p.expect('}')
   672  
   673  	*t = *types.NewInterfaceType(methods, embeddeds)
   674  	return t
   675  }
   676  
   677  // PointerType = "*" ("any" | Type) .
   678  func (p *parser) parsePointerType(pkg *types.Package, nlist []int) types.Type {
   679  	p.expect('*')
   680  	if p.tok == scanner.Ident {
   681  		p.expectKeyword("any")
   682  		t := types.Typ[types.UnsafePointer]
   683  		p.update(t, nlist)
   684  		return t
   685  	}
   686  
   687  	t := new(types.Pointer)
   688  	p.update(t, nlist)
   689  
   690  	*t = *types.NewPointer(p.parseType(pkg))
   691  
   692  	return t
   693  }
   694  
   695  // TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
   696  func (p *parser) parseTypeSpec(pkg *types.Package, nlist []int) types.Type {
   697  	switch p.tok {
   698  	case scanner.String:
   699  		return p.parseNamedType(nlist)
   700  
   701  	case scanner.Ident:
   702  		switch p.lit {
   703  		case "map":
   704  			return p.parseMapType(pkg, nlist)
   705  
   706  		case "chan":
   707  			return p.parseChanType(pkg, nlist)
   708  
   709  		case "struct":
   710  			return p.parseStructType(pkg, nlist)
   711  
   712  		case "interface":
   713  			return p.parseInterfaceType(pkg, nlist)
   714  		}
   715  
   716  	case '*':
   717  		return p.parsePointerType(pkg, nlist)
   718  
   719  	case '[':
   720  		return p.parseArrayOrSliceType(pkg, nlist)
   721  
   722  	case '(':
   723  		return p.parseFunctionType(pkg, nlist)
   724  	}
   725  
   726  	p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
   727  	return nil
   728  }
   729  
   730  const (
   731  	// From gofrontend/go/export.h
   732  	// Note that these values are negative in the gofrontend and have been made positive
   733  	// in the gccgoimporter.
   734  	gccgoBuiltinINT8       = 1
   735  	gccgoBuiltinINT16      = 2
   736  	gccgoBuiltinINT32      = 3
   737  	gccgoBuiltinINT64      = 4
   738  	gccgoBuiltinUINT8      = 5
   739  	gccgoBuiltinUINT16     = 6
   740  	gccgoBuiltinUINT32     = 7
   741  	gccgoBuiltinUINT64     = 8
   742  	gccgoBuiltinFLOAT32    = 9
   743  	gccgoBuiltinFLOAT64    = 10
   744  	gccgoBuiltinINT        = 11
   745  	gccgoBuiltinUINT       = 12
   746  	gccgoBuiltinUINTPTR    = 13
   747  	gccgoBuiltinBOOL       = 15
   748  	gccgoBuiltinSTRING     = 16
   749  	gccgoBuiltinCOMPLEX64  = 17
   750  	gccgoBuiltinCOMPLEX128 = 18
   751  	gccgoBuiltinERROR      = 19
   752  	gccgoBuiltinBYTE       = 20
   753  	gccgoBuiltinRUNE       = 21
   754  )
   755  
   756  func lookupBuiltinType(typ int) types.Type {
   757  	return [...]types.Type{
   758  		gccgoBuiltinINT8:       types.Typ[types.Int8],
   759  		gccgoBuiltinINT16:      types.Typ[types.Int16],
   760  		gccgoBuiltinINT32:      types.Typ[types.Int32],
   761  		gccgoBuiltinINT64:      types.Typ[types.Int64],
   762  		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
   763  		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
   764  		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
   765  		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
   766  		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
   767  		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
   768  		gccgoBuiltinINT:        types.Typ[types.Int],
   769  		gccgoBuiltinUINT:       types.Typ[types.Uint],
   770  		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
   771  		gccgoBuiltinBOOL:       types.Typ[types.Bool],
   772  		gccgoBuiltinSTRING:     types.Typ[types.String],
   773  		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
   774  		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
   775  		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
   776  		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
   777  		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
   778  	}[typ]
   779  }
   780  
   781  // Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
   782  //
   783  // parseType updates the type map to t for all type numbers n.
   784  //
   785  func (p *parser) parseType(pkg *types.Package, n ...int) (t types.Type) {
   786  	p.expect('<')
   787  	p.expectKeyword("type")
   788  
   789  	switch p.tok {
   790  	case scanner.Int:
   791  		n1 := p.parseInt()
   792  		if p.tok == '>' {
   793  			t = p.typeList[n1]
   794  			if t == reserved {
   795  				p.errorf("invalid type cycle, type %d not yet defined", n1)
   796  			}
   797  			p.update(t, n)
   798  		} else {
   799  			p.reserve(n1)
   800  			t = p.parseTypeSpec(pkg, append(n, n1))
   801  		}
   802  
   803  	case '-':
   804  		p.next()
   805  		n1 := p.parseInt()
   806  		t = lookupBuiltinType(n1)
   807  		p.update(t, n)
   808  
   809  	default:
   810  		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   811  	}
   812  
   813  	p.expect('>')
   814  	return
   815  }
   816  
   817  // PackageInit = unquotedString unquotedString int .
   818  func (p *parser) parsePackageInit() PackageInit {
   819  	name := p.parseUnquotedString()
   820  	initfunc := p.parseUnquotedString()
   821  	priority := -1
   822  	if p.version == "v1" {
   823  		priority = p.parseInt()
   824  	}
   825  	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
   826  }
   827  
   828  // Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type.
   829  func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) {
   830  	for {
   831  		switch p.tok {
   832  		case ';':
   833  			return
   834  		case '<':
   835  			p.parseType(pkg)
   836  		case scanner.EOF:
   837  			p.error("unexpected EOF")
   838  		default:
   839  			p.next()
   840  		}
   841  	}
   842  }
   843  
   844  // Create the package if we have parsed both the package path and package name.
   845  func (p *parser) maybeCreatePackage() {
   846  	if p.pkgname != "" && p.pkgpath != "" {
   847  		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
   848  	}
   849  }
   850  
   851  // InitDataDirective = ( "v1" | "v2" ) ";" |
   852  //                     "priority" int ";" |
   853  //                     "init" { PackageInit } ";" |
   854  //                     "checksum" unquotedString ";" .
   855  func (p *parser) parseInitDataDirective() {
   856  	if p.tok != scanner.Ident {
   857  		// unexpected token kind; panic
   858  		p.expect(scanner.Ident)
   859  	}
   860  
   861  	switch p.lit {
   862  	case "v1", "v2":
   863  		p.version = p.lit
   864  		p.next()
   865  		p.expect(';')
   866  
   867  	case "priority":
   868  		p.next()
   869  		p.initdata.Priority = p.parseInt()
   870  		p.expect(';')
   871  
   872  	case "init":
   873  		p.next()
   874  		for p.tok != ';' && p.tok != scanner.EOF {
   875  			p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
   876  		}
   877  		p.expect(';')
   878  
   879  	case "init_graph":
   880  		p.next()
   881  		// The graph data is thrown away for now.
   882  		for p.tok != ';' && p.tok != scanner.EOF {
   883  			p.parseInt64()
   884  			p.parseInt64()
   885  		}
   886  		p.expect(';')
   887  
   888  	case "checksum":
   889  		// Don't let the scanner try to parse the checksum as a number.
   890  		defer func(mode uint) {
   891  			p.scanner.Mode = mode
   892  		}(p.scanner.Mode)
   893  		p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
   894  		p.next()
   895  		p.parseUnquotedString()
   896  		p.expect(';')
   897  
   898  	default:
   899  		p.errorf("unexpected identifier: %q", p.lit)
   900  	}
   901  }
   902  
   903  // Directive = InitDataDirective |
   904  //             "package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
   905  //             "pkgpath" unquotedString ";" |
   906  //             "prefix" unquotedString ";" |
   907  //             "import" unquotedString unquotedString string ";" |
   908  //             "func" Func ";" |
   909  //             "type" Type ";" |
   910  //             "var" Var ";" |
   911  //             "const" Const ";" .
   912  func (p *parser) parseDirective() {
   913  	if p.tok != scanner.Ident {
   914  		// unexpected token kind; panic
   915  		p.expect(scanner.Ident)
   916  	}
   917  
   918  	switch p.lit {
   919  	case "v1", "v2", "priority", "init", "init_graph", "checksum":
   920  		p.parseInitDataDirective()
   921  
   922  	case "package":
   923  		p.next()
   924  		p.pkgname = p.parseUnquotedString()
   925  		p.maybeCreatePackage()
   926  		if p.version == "v2" && p.tok != ';' {
   927  			p.parseUnquotedString()
   928  			p.parseUnquotedString()
   929  		}
   930  		p.expect(';')
   931  
   932  	case "pkgpath":
   933  		p.next()
   934  		p.pkgpath = p.parseUnquotedString()
   935  		p.maybeCreatePackage()
   936  		p.expect(';')
   937  
   938  	case "prefix":
   939  		p.next()
   940  		p.pkgpath = p.parseUnquotedString()
   941  		p.expect(';')
   942  
   943  	case "import":
   944  		p.next()
   945  		pkgname := p.parseUnquotedString()
   946  		pkgpath := p.parseUnquotedString()
   947  		p.getPkg(pkgpath, pkgname)
   948  		p.parseString()
   949  		p.expect(';')
   950  
   951  	case "func":
   952  		p.next()
   953  		fun := p.parseFunc(p.pkg)
   954  		if fun != nil {
   955  			p.pkg.Scope().Insert(fun)
   956  		}
   957  		p.expect(';')
   958  
   959  	case "type":
   960  		p.next()
   961  		p.parseType(p.pkg)
   962  		p.expect(';')
   963  
   964  	case "var":
   965  		p.next()
   966  		v := p.parseVar(p.pkg)
   967  		p.pkg.Scope().Insert(v)
   968  		p.expect(';')
   969  
   970  	case "const":
   971  		p.next()
   972  		c := p.parseConst(p.pkg)
   973  		p.pkg.Scope().Insert(c)
   974  		p.expect(';')
   975  
   976  	default:
   977  		p.errorf("unexpected identifier: %q", p.lit)
   978  	}
   979  }
   980  
   981  // Package = { Directive } .
   982  func (p *parser) parsePackage() *types.Package {
   983  	for p.tok != scanner.EOF {
   984  		p.parseDirective()
   985  	}
   986  	for _, typ := range p.typeList {
   987  		if it, ok := typ.(*types.Interface); ok {
   988  			it.Complete()
   989  		}
   990  	}
   991  	p.pkg.MarkComplete()
   992  	return p.pkg
   993  }