github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/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  // Except for this comment, this file is a verbatim copy of the file
     6  // with the same name in $GOROOT/src/go/internal/gccgoimporter, with
     7  // a small modification in parseInterface to support older Go versions.
     8  
     9  package gccgoimporter
    10  
    11  import (
    12  	"bytes"
    13  	"errors"
    14  	"fmt"
    15  	"go/constant"
    16  	"go/token"
    17  	"go/types"
    18  	"io"
    19  	"strconv"
    20  	"strings"
    21  	"text/scanner"
    22  	"unicode/utf8"
    23  )
    24  
    25  type parser struct {
    26  	scanner  *scanner.Scanner
    27  	version  string                    // format version
    28  	tok      rune                      // current token
    29  	lit      string                    // literal string; only valid for Ident, Int, String tokens
    30  	pkgpath  string                    // package path of imported package
    31  	pkgname  string                    // name of imported package
    32  	pkg      *types.Package            // reference to imported package
    33  	imports  map[string]*types.Package // package path -> package object
    34  	typeList []types.Type              // type number -> type
    35  	typeData []string                  // unparsed type data (v3 and later)
    36  	fixups   []fixupRecord             // fixups to apply at end of parsing
    37  	initdata InitData                  // package init priority data
    38  	aliases  map[int]string            // maps saved type number to alias name
    39  }
    40  
    41  // When reading export data it's possible to encounter a defined type
    42  // N1 with an underlying defined type N2 while we are still reading in
    43  // that defined type N2; see issues #29006 and #29198 for instances
    44  // of this. Example:
    45  //
    46  //   type N1 N2
    47  //   type N2 struct {
    48  //      ...
    49  //      p *N1
    50  //   }
    51  //
    52  // To handle such cases, the parser generates a fixup record (below) and
    53  // delays setting of N1's underlying type until parsing is complete, at
    54  // which point fixups are applied.
    55  
    56  type fixupRecord struct {
    57  	toUpdate *types.Named // type to modify when fixup is processed
    58  	target   types.Type   // type that was incomplete when fixup was created
    59  }
    60  
    61  func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
    62  	p.scanner = new(scanner.Scanner)
    63  	p.initScanner(filename, src)
    64  	p.imports = imports
    65  	p.aliases = make(map[int]string)
    66  	p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
    67  }
    68  
    69  func (p *parser) initScanner(filename string, src io.Reader) {
    70  	p.scanner.Init(src)
    71  	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
    72  	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings
    73  	p.scanner.Whitespace = 1<<'\t' | 1<<' '
    74  	p.scanner.Filename = filename // for good error messages
    75  	p.next()
    76  }
    77  
    78  type importError struct {
    79  	pos scanner.Position
    80  	err error
    81  }
    82  
    83  func (e importError) Error() string {
    84  	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
    85  }
    86  
    87  func (p *parser) error(err interface{}) {
    88  	if s, ok := err.(string); ok {
    89  		err = errors.New(s)
    90  	}
    91  	// panic with a runtime.Error if err is not an error
    92  	panic(importError{p.scanner.Pos(), err.(error)})
    93  }
    94  
    95  func (p *parser) errorf(format string, args ...interface{}) {
    96  	p.error(fmt.Errorf(format, args...))
    97  }
    98  
    99  func (p *parser) expect(tok rune) string {
   100  	lit := p.lit
   101  	if p.tok != tok {
   102  		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
   103  	}
   104  	p.next()
   105  	return lit
   106  }
   107  
   108  func (p *parser) expectEOL() {
   109  	if p.version == "v1" || p.version == "v2" {
   110  		p.expect(';')
   111  	}
   112  	p.expect('\n')
   113  }
   114  
   115  func (p *parser) expectKeyword(keyword string) {
   116  	lit := p.expect(scanner.Ident)
   117  	if lit != keyword {
   118  		p.errorf("expected keyword %s, got %q", keyword, lit)
   119  	}
   120  }
   121  
   122  func (p *parser) parseString() string {
   123  	str, err := strconv.Unquote(p.expect(scanner.String))
   124  	if err != nil {
   125  		p.error(err)
   126  	}
   127  	return str
   128  }
   129  
   130  // parseUnquotedString parses an UnquotedString:
   131  //
   132  //	unquotedString     = { unquotedStringChar } .
   133  //	unquotedStringChar = <neither a whitespace nor a ';' char> .
   134  func (p *parser) parseUnquotedString() string {
   135  	if p.tok == scanner.EOF {
   136  		p.error("unexpected EOF")
   137  	}
   138  	var buf bytes.Buffer
   139  	buf.WriteString(p.scanner.TokenText())
   140  	// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
   141  	// we need to let it be consumed by p.next().
   142  	for ch := p.scanner.Peek(); ch != '\n' && ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
   143  		buf.WriteRune(ch)
   144  		p.scanner.Next()
   145  	}
   146  	p.next()
   147  	return buf.String()
   148  }
   149  
   150  func (p *parser) next() {
   151  	p.tok = p.scanner.Scan()
   152  	switch p.tok {
   153  	case scanner.Ident, scanner.Int, scanner.Float, scanner.String, 'ยท':
   154  		p.lit = p.scanner.TokenText()
   155  	default:
   156  		p.lit = ""
   157  	}
   158  }
   159  
   160  func (p *parser) parseQualifiedName() (path, name string) {
   161  	return p.parseQualifiedNameStr(p.parseString())
   162  }
   163  
   164  func (p *parser) parseUnquotedQualifiedName() (path, name string) {
   165  	return p.parseQualifiedNameStr(p.parseUnquotedString())
   166  }
   167  
   168  // parseQualifiedNameStr is given the leading name (unquoted by the caller if necessary)
   169  // and then parses the remainder of a qualified name:
   170  //
   171  //	qualifiedName = [ ["."] unquotedString "." ] unquotedString .
   172  //
   173  // The above production uses greedy matching.
   174  func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
   175  	parts := strings.Split(unquotedName, ".")
   176  	if parts[0] == "" {
   177  		parts = parts[1:]
   178  	}
   179  
   180  	switch len(parts) {
   181  	case 0:
   182  		p.errorf("malformed qualified name: %q", unquotedName)
   183  	case 1:
   184  		// unqualified name
   185  		pkgpath = p.pkgpath
   186  		name = parts[0]
   187  	default:
   188  		// qualified name, which may contain periods
   189  		pkgpath = strings.Join(parts[0:len(parts)-1], ".")
   190  		name = parts[len(parts)-1]
   191  	}
   192  
   193  	return
   194  }
   195  
   196  // getPkg returns the package for a given path. If the package is
   197  // not found but we have a package name, create the package and
   198  // add it to the p.imports map.
   199  func (p *parser) getPkg(pkgpath, name string) *types.Package {
   200  	// package unsafe is not in the imports map - handle explicitly
   201  	if pkgpath == "unsafe" {
   202  		return types.Unsafe
   203  	}
   204  	pkg := p.imports[pkgpath]
   205  	if pkg == nil && name != "" {
   206  		pkg = types.NewPackage(pkgpath, name)
   207  		p.imports[pkgpath] = pkg
   208  	}
   209  	return pkg
   210  }
   211  
   212  // parseExportedName is like parseQualifiedName, but
   213  // the package path is resolved to an imported *types.Package.
   214  //
   215  //	ExportedName = string [string] .
   216  func (p *parser) parseExportedName() (pkg *types.Package, name string) {
   217  	path, name := p.parseQualifiedName()
   218  	var pkgname string
   219  	if p.tok == scanner.String {
   220  		pkgname = p.parseString()
   221  	}
   222  	pkg = p.getPkg(path, pkgname)
   223  	if pkg == nil {
   224  		p.errorf("package %s (path = %q) not found", name, path)
   225  	}
   226  	return
   227  }
   228  
   229  // parseName parses a Name:
   230  //
   231  //	Name = QualifiedName | "?" .
   232  func (p *parser) parseName() string {
   233  	if p.tok == '?' {
   234  		// Anonymous.
   235  		p.next()
   236  		return ""
   237  	}
   238  	// The package path is redundant for us. Don't try to parse it.
   239  	_, name := p.parseUnquotedQualifiedName()
   240  	return name
   241  }
   242  
   243  func deref(typ types.Type) types.Type {
   244  	if p, _ := typ.(*types.Pointer); p != nil {
   245  		typ = p.Elem()
   246  	}
   247  	return typ
   248  }
   249  
   250  // parseField parses a Field:
   251  //
   252  //	Field = Name Type [string] .
   253  func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
   254  	name := p.parseName()
   255  	typ, n := p.parseTypeExtended(pkg)
   256  	anon := false
   257  	if name == "" {
   258  		anon = true
   259  		// Alias?
   260  		if aname, ok := p.aliases[n]; ok {
   261  			name = aname
   262  		} else {
   263  			switch typ := deref(typ).(type) {
   264  			case *types.Basic:
   265  				name = typ.Name()
   266  			case *types.Named:
   267  				name = typ.Obj().Name()
   268  			default:
   269  				p.error("embedded field expected")
   270  			}
   271  		}
   272  	}
   273  	field = types.NewField(token.NoPos, pkg, name, typ, anon)
   274  	if p.tok == scanner.String {
   275  		tag = p.parseString()
   276  	}
   277  	return
   278  }
   279  
   280  // parseParam parses a Param:
   281  //
   282  //	Param = Name ["..."] Type .
   283  func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
   284  	name := p.parseName()
   285  	// Ignore names invented for inlinable functions.
   286  	if strings.HasPrefix(name, "p.") || strings.HasPrefix(name, "r.") || strings.HasPrefix(name, "$ret") {
   287  		name = ""
   288  	}
   289  	if p.tok == '<' && p.scanner.Peek() == 'e' {
   290  		// EscInfo = "<esc:" int ">" . (optional and ignored)
   291  		p.next()
   292  		p.expectKeyword("esc")
   293  		p.expect(':')
   294  		p.expect(scanner.Int)
   295  		p.expect('>')
   296  	}
   297  	if p.tok == '.' {
   298  		p.next()
   299  		p.expect('.')
   300  		p.expect('.')
   301  		isVariadic = true
   302  	}
   303  	typ := p.parseType(pkg)
   304  	if isVariadic {
   305  		typ = types.NewSlice(typ)
   306  	}
   307  	param = types.NewParam(token.NoPos, pkg, name, typ)
   308  	return
   309  }
   310  
   311  // parseVar parses a Var:
   312  //
   313  //	Var = Name Type .
   314  func (p *parser) parseVar(pkg *types.Package) *types.Var {
   315  	name := p.parseName()
   316  	v := types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
   317  	if name[0] == '.' || name[0] == '<' {
   318  		// This is an unexported variable,
   319  		// or a variable defined in a different package.
   320  		// We only want to record exported variables.
   321  		return nil
   322  	}
   323  	return v
   324  }
   325  
   326  // parseConversion parses a Conversion:
   327  //
   328  //	Conversion = "convert" "(" Type "," ConstValue ")" .
   329  func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
   330  	p.expectKeyword("convert")
   331  	p.expect('(')
   332  	typ = p.parseType(pkg)
   333  	p.expect(',')
   334  	val, _ = p.parseConstValue(pkg)
   335  	p.expect(')')
   336  	return
   337  }
   338  
   339  // parseConstValue parses a ConstValue:
   340  //
   341  //	ConstValue     = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
   342  //	FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
   343  func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
   344  	// v3 changed to $false, $true, $convert, to avoid confusion
   345  	// with variable names in inline function bodies.
   346  	if p.tok == '$' {
   347  		p.next()
   348  		if p.tok != scanner.Ident {
   349  			p.errorf("expected identifier after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit)
   350  		}
   351  	}
   352  
   353  	switch p.tok {
   354  	case scanner.String:
   355  		str := p.parseString()
   356  		val = constant.MakeString(str)
   357  		typ = types.Typ[types.UntypedString]
   358  		return
   359  
   360  	case scanner.Ident:
   361  		b := false
   362  		switch p.lit {
   363  		case "false":
   364  		case "true":
   365  			b = true
   366  
   367  		case "convert":
   368  			return p.parseConversion(pkg)
   369  
   370  		default:
   371  			p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   372  		}
   373  
   374  		p.next()
   375  		val = constant.MakeBool(b)
   376  		typ = types.Typ[types.UntypedBool]
   377  		return
   378  	}
   379  
   380  	sign := ""
   381  	if p.tok == '-' {
   382  		p.next()
   383  		sign = "-"
   384  	}
   385  
   386  	switch p.tok {
   387  	case scanner.Int:
   388  		val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
   389  		if val == nil {
   390  			p.error("could not parse integer literal")
   391  		}
   392  
   393  		p.next()
   394  		if p.tok == '\'' {
   395  			p.next()
   396  			typ = types.Typ[types.UntypedRune]
   397  		} else {
   398  			typ = types.Typ[types.UntypedInt]
   399  		}
   400  
   401  	case scanner.Float:
   402  		re := sign + p.lit
   403  		p.next()
   404  
   405  		var im string
   406  		switch p.tok {
   407  		case '+':
   408  			p.next()
   409  			im = p.expect(scanner.Float)
   410  
   411  		case '-':
   412  			p.next()
   413  			im = "-" + p.expect(scanner.Float)
   414  
   415  		case scanner.Ident:
   416  			// re is in fact the imaginary component. Expect "i" below.
   417  			im = re
   418  			re = "0"
   419  
   420  		default:
   421  			val = constant.MakeFromLiteral(re, token.FLOAT, 0)
   422  			if val == nil {
   423  				p.error("could not parse float literal")
   424  			}
   425  			typ = types.Typ[types.UntypedFloat]
   426  			return
   427  		}
   428  
   429  		p.expectKeyword("i")
   430  		reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
   431  		if reval == nil {
   432  			p.error("could not parse real component of complex literal")
   433  		}
   434  		imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
   435  		if imval == nil {
   436  			p.error("could not parse imag component of complex literal")
   437  		}
   438  		val = constant.BinaryOp(reval, token.ADD, imval)
   439  		typ = types.Typ[types.UntypedComplex]
   440  
   441  	default:
   442  		p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   443  	}
   444  
   445  	return
   446  }
   447  
   448  // parseConst parses a Const:
   449  //
   450  //	Const = Name [Type] "=" ConstValue .
   451  func (p *parser) parseConst(pkg *types.Package) *types.Const {
   452  	name := p.parseName()
   453  	var typ types.Type
   454  	if p.tok == '<' {
   455  		typ = p.parseType(pkg)
   456  	}
   457  	p.expect('=')
   458  	val, vtyp := p.parseConstValue(pkg)
   459  	if typ == nil {
   460  		typ = vtyp
   461  	}
   462  	return types.NewConst(token.NoPos, pkg, name, typ, val)
   463  }
   464  
   465  // reserved is a singleton type used to fill type map slots that have
   466  // been reserved (i.e., for which a type number has been parsed) but
   467  // which don't have their actual type yet. When the type map is updated,
   468  // the actual type must replace a reserved entry (or we have an internal
   469  // error). Used for self-verification only - not required for correctness.
   470  var reserved = new(struct{ types.Type })
   471  
   472  // reserve reserves the type map entry n for future use.
   473  func (p *parser) reserve(n int) {
   474  	// Notes:
   475  	// - for pre-V3 export data, the type numbers we see are
   476  	//   guaranteed to be in increasing order, so we append a
   477  	//   reserved entry onto the list.
   478  	// - for V3+ export data, type numbers can appear in
   479  	//   any order, however the 'types' section tells us the
   480  	//   total number of types, hence typeList is pre-allocated.
   481  	if len(p.typeData) == 0 {
   482  		if n != len(p.typeList) {
   483  			p.errorf("invalid type number %d (out of sync)", n)
   484  		}
   485  		p.typeList = append(p.typeList, reserved)
   486  	} else {
   487  		if p.typeList[n] != nil {
   488  			p.errorf("previously visited type number %d", n)
   489  		}
   490  		p.typeList[n] = reserved
   491  	}
   492  }
   493  
   494  // update sets the type map entries for the entries in nlist to t.
   495  // An entry in nlist can be a type number in p.typeList,
   496  // used to resolve named types, or it can be a *types.Pointer,
   497  // used to resolve pointers to named types in case they are referenced
   498  // by embedded fields.
   499  func (p *parser) update(t types.Type, nlist []interface{}) {
   500  	if t == reserved {
   501  		p.errorf("internal error: update(%v) invoked on reserved", nlist)
   502  	}
   503  	if t == nil {
   504  		p.errorf("internal error: update(%v) invoked on nil", nlist)
   505  	}
   506  	for _, n := range nlist {
   507  		switch n := n.(type) {
   508  		case int:
   509  			if p.typeList[n] == t {
   510  				continue
   511  			}
   512  			if p.typeList[n] != reserved {
   513  				p.errorf("internal error: update(%v): %d not reserved", nlist, n)
   514  			}
   515  			p.typeList[n] = t
   516  		case *types.Pointer:
   517  			if *n != (types.Pointer{}) {
   518  				elem := n.Elem()
   519  				if elem == t {
   520  					continue
   521  				}
   522  				p.errorf("internal error: update: pointer already set to %v, expected %v", elem, t)
   523  			}
   524  			*n = *types.NewPointer(t)
   525  		default:
   526  			p.errorf("internal error: %T on nlist", n)
   527  		}
   528  	}
   529  }
   530  
   531  // parseNamedType parses a NamedType:
   532  //
   533  //	NamedType = TypeName [ "=" ] Type { Method } .
   534  //	TypeName  = ExportedName .
   535  //	Method    = "func" "(" Param ")" Name ParamList ResultList [InlineBody] ";" .
   536  func (p *parser) parseNamedType(nlist []interface{}) types.Type {
   537  	pkg, name := p.parseExportedName()
   538  	scope := pkg.Scope()
   539  	obj := scope.Lookup(name)
   540  	if obj != nil && obj.Type() == nil {
   541  		p.errorf("%v has nil type", obj)
   542  	}
   543  
   544  	if p.tok == scanner.Ident && p.lit == "notinheap" {
   545  		p.next()
   546  		// The go/types package has no way of recording that
   547  		// this type is marked notinheap. Presumably no user
   548  		// of this package actually cares.
   549  	}
   550  
   551  	// type alias
   552  	if p.tok == '=' {
   553  		p.next()
   554  		p.aliases[nlist[len(nlist)-1].(int)] = name
   555  		if obj != nil {
   556  			// use the previously imported (canonical) type
   557  			t := obj.Type()
   558  			p.update(t, nlist)
   559  			p.parseType(pkg) // discard
   560  			return t
   561  		}
   562  		t := p.parseType(pkg, nlist...)
   563  		obj = types.NewTypeName(token.NoPos, pkg, name, t)
   564  		scope.Insert(obj)
   565  		return t
   566  	}
   567  
   568  	// defined type
   569  	if obj == nil {
   570  		// A named type may be referred to before the underlying type
   571  		// is known - set it up.
   572  		tname := types.NewTypeName(token.NoPos, pkg, name, nil)
   573  		types.NewNamed(tname, nil, nil)
   574  		scope.Insert(tname)
   575  		obj = tname
   576  	}
   577  
   578  	// use the previously imported (canonical), or newly created type
   579  	t := obj.Type()
   580  	p.update(t, nlist)
   581  
   582  	nt, ok := t.(*types.Named)
   583  	if !ok {
   584  		// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
   585  		pt := p.parseType(pkg)
   586  		if pt != t {
   587  			p.error("unexpected underlying type for non-named TypeName")
   588  		}
   589  		return t
   590  	}
   591  
   592  	underlying := p.parseType(pkg)
   593  	if nt.Underlying() == nil {
   594  		if underlying.Underlying() == nil {
   595  			fix := fixupRecord{toUpdate: nt, target: underlying}
   596  			p.fixups = append(p.fixups, fix)
   597  		} else {
   598  			nt.SetUnderlying(underlying.Underlying())
   599  		}
   600  	}
   601  
   602  	if p.tok == '\n' {
   603  		p.next()
   604  		// collect associated methods
   605  		for p.tok == scanner.Ident {
   606  			p.expectKeyword("func")
   607  			if p.tok == '/' {
   608  				// Skip a /*nointerface*/ or /*asm ID */ comment.
   609  				p.expect('/')
   610  				p.expect('*')
   611  				if p.expect(scanner.Ident) == "asm" {
   612  					p.parseUnquotedString()
   613  				}
   614  				p.expect('*')
   615  				p.expect('/')
   616  			}
   617  			p.expect('(')
   618  			receiver, _ := p.parseParam(pkg)
   619  			p.expect(')')
   620  			name := p.parseName()
   621  			params, isVariadic := p.parseParamList(pkg)
   622  			results := p.parseResultList(pkg)
   623  			p.skipInlineBody()
   624  			p.expectEOL()
   625  
   626  			sig := types.NewSignature(receiver, params, results, isVariadic)
   627  			nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
   628  		}
   629  	}
   630  
   631  	return nt
   632  }
   633  
   634  func (p *parser) parseInt64() int64 {
   635  	lit := p.expect(scanner.Int)
   636  	n, err := strconv.ParseInt(lit, 10, 64)
   637  	if err != nil {
   638  		p.error(err)
   639  	}
   640  	return n
   641  }
   642  
   643  func (p *parser) parseInt() int {
   644  	lit := p.expect(scanner.Int)
   645  	n, err := strconv.ParseInt(lit, 10, 0 /* int */)
   646  	if err != nil {
   647  		p.error(err)
   648  	}
   649  	return int(n)
   650  }
   651  
   652  // parseArrayOrSliceType parses an ArrayOrSliceType:
   653  //
   654  //	ArrayOrSliceType = "[" [ int ] "]" Type .
   655  func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []interface{}) types.Type {
   656  	p.expect('[')
   657  	if p.tok == ']' {
   658  		p.next()
   659  
   660  		t := new(types.Slice)
   661  		p.update(t, nlist)
   662  
   663  		*t = *types.NewSlice(p.parseType(pkg))
   664  		return t
   665  	}
   666  
   667  	t := new(types.Array)
   668  	p.update(t, nlist)
   669  
   670  	len := p.parseInt64()
   671  	p.expect(']')
   672  
   673  	*t = *types.NewArray(p.parseType(pkg), len)
   674  	return t
   675  }
   676  
   677  // parseMapType parses a MapType:
   678  //
   679  //	MapType = "map" "[" Type "]" Type .
   680  func (p *parser) parseMapType(pkg *types.Package, nlist []interface{}) types.Type {
   681  	p.expectKeyword("map")
   682  
   683  	t := new(types.Map)
   684  	p.update(t, nlist)
   685  
   686  	p.expect('[')
   687  	key := p.parseType(pkg)
   688  	p.expect(']')
   689  	elem := p.parseType(pkg)
   690  
   691  	*t = *types.NewMap(key, elem)
   692  	return t
   693  }
   694  
   695  // parseChanType parses a ChanType:
   696  //
   697  //	ChanType = "chan" ["<-" | "-<"] Type .
   698  func (p *parser) parseChanType(pkg *types.Package, nlist []interface{}) types.Type {
   699  	p.expectKeyword("chan")
   700  
   701  	t := new(types.Chan)
   702  	p.update(t, nlist)
   703  
   704  	dir := types.SendRecv
   705  	switch p.tok {
   706  	case '-':
   707  		p.next()
   708  		p.expect('<')
   709  		dir = types.SendOnly
   710  
   711  	case '<':
   712  		// don't consume '<' if it belongs to Type
   713  		if p.scanner.Peek() == '-' {
   714  			p.next()
   715  			p.expect('-')
   716  			dir = types.RecvOnly
   717  		}
   718  	}
   719  
   720  	*t = *types.NewChan(dir, p.parseType(pkg))
   721  	return t
   722  }
   723  
   724  // parseStructType parses a StructType:
   725  //
   726  //	StructType = "struct" "{" { Field } "}" .
   727  func (p *parser) parseStructType(pkg *types.Package, nlist []interface{}) types.Type {
   728  	p.expectKeyword("struct")
   729  
   730  	t := new(types.Struct)
   731  	p.update(t, nlist)
   732  
   733  	var fields []*types.Var
   734  	var tags []string
   735  
   736  	p.expect('{')
   737  	for p.tok != '}' && p.tok != scanner.EOF {
   738  		field, tag := p.parseField(pkg)
   739  		p.expect(';')
   740  		fields = append(fields, field)
   741  		tags = append(tags, tag)
   742  	}
   743  	p.expect('}')
   744  
   745  	*t = *types.NewStruct(fields, tags)
   746  	return t
   747  }
   748  
   749  // parseParamList parses a ParamList:
   750  //
   751  //	ParamList = "(" [ { Parameter "," } Parameter ] ")" .
   752  func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
   753  	var list []*types.Var
   754  	isVariadic := false
   755  
   756  	p.expect('(')
   757  	for p.tok != ')' && p.tok != scanner.EOF {
   758  		if len(list) > 0 {
   759  			p.expect(',')
   760  		}
   761  		par, variadic := p.parseParam(pkg)
   762  		list = append(list, par)
   763  		if variadic {
   764  			if isVariadic {
   765  				p.error("... not on final argument")
   766  			}
   767  			isVariadic = true
   768  		}
   769  	}
   770  	p.expect(')')
   771  
   772  	return types.NewTuple(list...), isVariadic
   773  }
   774  
   775  // parseResultList parses a ResultList:
   776  //
   777  //	ResultList = Type | ParamList .
   778  func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
   779  	switch p.tok {
   780  	case '<':
   781  		p.next()
   782  		if p.tok == scanner.Ident && p.lit == "inl" {
   783  			return nil
   784  		}
   785  		taa, _ := p.parseTypeAfterAngle(pkg)
   786  		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", taa))
   787  
   788  	case '(':
   789  		params, _ := p.parseParamList(pkg)
   790  		return params
   791  
   792  	default:
   793  		return nil
   794  	}
   795  }
   796  
   797  // parseFunctionType parses a FunctionType:
   798  //
   799  //	FunctionType = ParamList ResultList .
   800  func (p *parser) parseFunctionType(pkg *types.Package, nlist []interface{}) *types.Signature {
   801  	t := new(types.Signature)
   802  	p.update(t, nlist)
   803  
   804  	params, isVariadic := p.parseParamList(pkg)
   805  	results := p.parseResultList(pkg)
   806  
   807  	*t = *types.NewSignature(nil, params, results, isVariadic)
   808  	return t
   809  }
   810  
   811  // parseFunc parses a Func:
   812  //
   813  //	Func = Name FunctionType [InlineBody] .
   814  func (p *parser) parseFunc(pkg *types.Package) *types.Func {
   815  	if p.tok == '/' {
   816  		// Skip an /*asm ID */ comment.
   817  		p.expect('/')
   818  		p.expect('*')
   819  		if p.expect(scanner.Ident) == "asm" {
   820  			p.parseUnquotedString()
   821  		}
   822  		p.expect('*')
   823  		p.expect('/')
   824  	}
   825  
   826  	name := p.parseName()
   827  	f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
   828  	p.skipInlineBody()
   829  
   830  	if name[0] == '.' || name[0] == '<' || strings.ContainsRune(name, '$') {
   831  		// This is an unexported function,
   832  		// or a function defined in a different package,
   833  		// or a type$equal or type$hash function.
   834  		// We only want to record exported functions.
   835  		return nil
   836  	}
   837  
   838  	return f
   839  }
   840  
   841  // parseInterfaceType parses an InterfaceType:
   842  //
   843  //	InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
   844  func (p *parser) parseInterfaceType(pkg *types.Package, nlist []interface{}) types.Type {
   845  	p.expectKeyword("interface")
   846  
   847  	t := new(types.Interface)
   848  	p.update(t, nlist)
   849  
   850  	var methods []*types.Func
   851  	var embeddeds []types.Type
   852  
   853  	p.expect('{')
   854  	for p.tok != '}' && p.tok != scanner.EOF {
   855  		if p.tok == '?' {
   856  			p.next()
   857  			embeddeds = append(embeddeds, p.parseType(pkg))
   858  		} else {
   859  			method := p.parseFunc(pkg)
   860  			if method != nil {
   861  				methods = append(methods, method)
   862  			}
   863  		}
   864  		p.expect(';')
   865  	}
   866  	p.expect('}')
   867  
   868  	*t = *newInterface(methods, embeddeds)
   869  	return t
   870  }
   871  
   872  // parsePointerType parses a PointerType:
   873  //
   874  //	PointerType = "*" ("any" | Type) .
   875  func (p *parser) parsePointerType(pkg *types.Package, nlist []interface{}) types.Type {
   876  	p.expect('*')
   877  	if p.tok == scanner.Ident {
   878  		p.expectKeyword("any")
   879  		t := types.Typ[types.UnsafePointer]
   880  		p.update(t, nlist)
   881  		return t
   882  	}
   883  
   884  	t := new(types.Pointer)
   885  	p.update(t, nlist)
   886  
   887  	*t = *types.NewPointer(p.parseType(pkg, t))
   888  
   889  	return t
   890  }
   891  
   892  // parseTypeSpec parses a TypeSpec:
   893  //
   894  //	TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
   895  func (p *parser) parseTypeSpec(pkg *types.Package, nlist []interface{}) types.Type {
   896  	switch p.tok {
   897  	case scanner.String:
   898  		return p.parseNamedType(nlist)
   899  
   900  	case scanner.Ident:
   901  		switch p.lit {
   902  		case "map":
   903  			return p.parseMapType(pkg, nlist)
   904  
   905  		case "chan":
   906  			return p.parseChanType(pkg, nlist)
   907  
   908  		case "struct":
   909  			return p.parseStructType(pkg, nlist)
   910  
   911  		case "interface":
   912  			return p.parseInterfaceType(pkg, nlist)
   913  		}
   914  
   915  	case '*':
   916  		return p.parsePointerType(pkg, nlist)
   917  
   918  	case '[':
   919  		return p.parseArrayOrSliceType(pkg, nlist)
   920  
   921  	case '(':
   922  		return p.parseFunctionType(pkg, nlist)
   923  	}
   924  
   925  	p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
   926  	return nil
   927  }
   928  
   929  const (
   930  	// From gofrontend/go/export.h
   931  	// Note that these values are negative in the gofrontend and have been made positive
   932  	// in the gccgoimporter.
   933  	gccgoBuiltinINT8       = 1
   934  	gccgoBuiltinINT16      = 2
   935  	gccgoBuiltinINT32      = 3
   936  	gccgoBuiltinINT64      = 4
   937  	gccgoBuiltinUINT8      = 5
   938  	gccgoBuiltinUINT16     = 6
   939  	gccgoBuiltinUINT32     = 7
   940  	gccgoBuiltinUINT64     = 8
   941  	gccgoBuiltinFLOAT32    = 9
   942  	gccgoBuiltinFLOAT64    = 10
   943  	gccgoBuiltinINT        = 11
   944  	gccgoBuiltinUINT       = 12
   945  	gccgoBuiltinUINTPTR    = 13
   946  	gccgoBuiltinBOOL       = 15
   947  	gccgoBuiltinSTRING     = 16
   948  	gccgoBuiltinCOMPLEX64  = 17
   949  	gccgoBuiltinCOMPLEX128 = 18
   950  	gccgoBuiltinERROR      = 19
   951  	gccgoBuiltinBYTE       = 20
   952  	gccgoBuiltinRUNE       = 21
   953  )
   954  
   955  func lookupBuiltinType(typ int) types.Type {
   956  	return [...]types.Type{
   957  		gccgoBuiltinINT8:       types.Typ[types.Int8],
   958  		gccgoBuiltinINT16:      types.Typ[types.Int16],
   959  		gccgoBuiltinINT32:      types.Typ[types.Int32],
   960  		gccgoBuiltinINT64:      types.Typ[types.Int64],
   961  		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
   962  		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
   963  		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
   964  		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
   965  		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
   966  		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
   967  		gccgoBuiltinINT:        types.Typ[types.Int],
   968  		gccgoBuiltinUINT:       types.Typ[types.Uint],
   969  		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
   970  		gccgoBuiltinBOOL:       types.Typ[types.Bool],
   971  		gccgoBuiltinSTRING:     types.Typ[types.String],
   972  		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
   973  		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
   974  		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
   975  		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
   976  		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
   977  	}[typ]
   978  }
   979  
   980  // parseType parses a Type:
   981  //
   982  //	Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
   983  //
   984  // parseType updates the type map to t for all type numbers n.
   985  func (p *parser) parseType(pkg *types.Package, n ...interface{}) types.Type {
   986  	p.expect('<')
   987  	t, _ := p.parseTypeAfterAngle(pkg, n...)
   988  	return t
   989  }
   990  
   991  // (*parser).Type after reading the "<".
   992  func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
   993  	p.expectKeyword("type")
   994  
   995  	n1 = 0
   996  	switch p.tok {
   997  	case scanner.Int:
   998  		n1 = p.parseInt()
   999  		if p.tok == '>' {
  1000  			if len(p.typeData) > 0 && p.typeList[n1] == nil {
  1001  				p.parseSavedType(pkg, n1, n)
  1002  			}
  1003  			t = p.typeList[n1]
  1004  			if len(p.typeData) == 0 && t == reserved {
  1005  				p.errorf("invalid type cycle, type %d not yet defined (nlist=%v)", n1, n)
  1006  			}
  1007  			p.update(t, n)
  1008  		} else {
  1009  			p.reserve(n1)
  1010  			t = p.parseTypeSpec(pkg, append(n, n1))
  1011  		}
  1012  
  1013  	case '-':
  1014  		p.next()
  1015  		n1 := p.parseInt()
  1016  		t = lookupBuiltinType(n1)
  1017  		p.update(t, n)
  1018  
  1019  	default:
  1020  		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
  1021  		return nil, 0
  1022  	}
  1023  
  1024  	if t == nil || t == reserved {
  1025  		p.errorf("internal error: bad return from parseType(%v)", n)
  1026  	}
  1027  
  1028  	p.expect('>')
  1029  	return
  1030  }
  1031  
  1032  // parseTypeExtended is identical to parseType, but if the type in
  1033  // question is a saved type, returns the index as well as the type
  1034  // pointer (index returned is zero if we parsed a builtin).
  1035  func (p *parser) parseTypeExtended(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
  1036  	p.expect('<')
  1037  	t, n1 = p.parseTypeAfterAngle(pkg, n...)
  1038  	return
  1039  }
  1040  
  1041  // InlineBody = "<inl:NN>" .{NN}
  1042  // Reports whether a body was skipped.
  1043  func (p *parser) skipInlineBody() {
  1044  	// We may or may not have seen the '<' already, depending on
  1045  	// whether the function had a result type or not.
  1046  	if p.tok == '<' {
  1047  		p.next()
  1048  		p.expectKeyword("inl")
  1049  	} else if p.tok != scanner.Ident || p.lit != "inl" {
  1050  		return
  1051  	} else {
  1052  		p.next()
  1053  	}
  1054  
  1055  	p.expect(':')
  1056  	want := p.parseInt()
  1057  	p.expect('>')
  1058  
  1059  	defer func(w uint64) {
  1060  		p.scanner.Whitespace = w
  1061  	}(p.scanner.Whitespace)
  1062  	p.scanner.Whitespace = 0
  1063  
  1064  	got := 0
  1065  	for got < want {
  1066  		r := p.scanner.Next()
  1067  		if r == scanner.EOF {
  1068  			p.error("unexpected EOF")
  1069  		}
  1070  		got += utf8.RuneLen(r)
  1071  	}
  1072  }
  1073  
  1074  // parseTypes parses a Types:
  1075  //
  1076  //	Types = "types" maxp1 exportedp1 (offset length)* .
  1077  func (p *parser) parseTypes(pkg *types.Package) {
  1078  	maxp1 := p.parseInt()
  1079  	exportedp1 := p.parseInt()
  1080  	p.typeList = make([]types.Type, maxp1)
  1081  
  1082  	type typeOffset struct {
  1083  		offset int
  1084  		length int
  1085  	}
  1086  	var typeOffsets []typeOffset
  1087  
  1088  	total := 0
  1089  	for i := 1; i < maxp1; i++ {
  1090  		len := p.parseInt()
  1091  		typeOffsets = append(typeOffsets, typeOffset{total, len})
  1092  		total += len
  1093  	}
  1094  
  1095  	defer func(w uint64) {
  1096  		p.scanner.Whitespace = w
  1097  	}(p.scanner.Whitespace)
  1098  	p.scanner.Whitespace = 0
  1099  
  1100  	// We should now have p.tok pointing to the final newline.
  1101  	// The next runes from the scanner should be the type data.
  1102  
  1103  	var sb strings.Builder
  1104  	for sb.Len() < total {
  1105  		r := p.scanner.Next()
  1106  		if r == scanner.EOF {
  1107  			p.error("unexpected EOF")
  1108  		}
  1109  		sb.WriteRune(r)
  1110  	}
  1111  	allTypeData := sb.String()
  1112  
  1113  	p.typeData = []string{""} // type 0, unused
  1114  	for _, to := range typeOffsets {
  1115  		p.typeData = append(p.typeData, allTypeData[to.offset:to.offset+to.length])
  1116  	}
  1117  
  1118  	for i := 1; i < int(exportedp1); i++ {
  1119  		p.parseSavedType(pkg, i, nil)
  1120  	}
  1121  }
  1122  
  1123  // parseSavedType parses one saved type definition.
  1124  func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []interface{}) {
  1125  	defer func(s *scanner.Scanner, tok rune, lit string) {
  1126  		p.scanner = s
  1127  		p.tok = tok
  1128  		p.lit = lit
  1129  	}(p.scanner, p.tok, p.lit)
  1130  
  1131  	p.scanner = new(scanner.Scanner)
  1132  	p.initScanner(p.scanner.Filename, strings.NewReader(p.typeData[i]))
  1133  	p.expectKeyword("type")
  1134  	id := p.parseInt()
  1135  	if id != i {
  1136  		p.errorf("type ID mismatch: got %d, want %d", id, i)
  1137  	}
  1138  	if p.typeList[i] == reserved {
  1139  		p.errorf("internal error: %d already reserved in parseSavedType", i)
  1140  	}
  1141  	if p.typeList[i] == nil {
  1142  		p.reserve(i)
  1143  		p.parseTypeSpec(pkg, append(nlist, i))
  1144  	}
  1145  	if p.typeList[i] == nil || p.typeList[i] == reserved {
  1146  		p.errorf("internal error: parseSavedType(%d,%v) reserved/nil", i, nlist)
  1147  	}
  1148  }
  1149  
  1150  // parsePackageInit parses a PackageInit:
  1151  //
  1152  //	PackageInit = unquotedString unquotedString int .
  1153  func (p *parser) parsePackageInit() PackageInit {
  1154  	name := p.parseUnquotedString()
  1155  	initfunc := p.parseUnquotedString()
  1156  	priority := -1
  1157  	if p.version == "v1" {
  1158  		priority = p.parseInt()
  1159  	}
  1160  	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
  1161  }
  1162  
  1163  // Create the package if we have parsed both the package path and package name.
  1164  func (p *parser) maybeCreatePackage() {
  1165  	if p.pkgname != "" && p.pkgpath != "" {
  1166  		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
  1167  	}
  1168  }
  1169  
  1170  // parseInitDataDirective parses an InitDataDirective:
  1171  //
  1172  //	InitDataDirective = ( "v1" | "v2" | "v3" ) ";" |
  1173  //		"priority" int ";" |
  1174  //		"init" { PackageInit } ";" |
  1175  //		"checksum" unquotedString ";" .
  1176  func (p *parser) parseInitDataDirective() {
  1177  	if p.tok != scanner.Ident {
  1178  		// unexpected token kind; panic
  1179  		p.expect(scanner.Ident)
  1180  	}
  1181  
  1182  	switch p.lit {
  1183  	case "v1", "v2", "v3":
  1184  		p.version = p.lit
  1185  		p.next()
  1186  		p.expect(';')
  1187  		p.expect('\n')
  1188  
  1189  	case "priority":
  1190  		p.next()
  1191  		p.initdata.Priority = p.parseInt()
  1192  		p.expectEOL()
  1193  
  1194  	case "init":
  1195  		p.next()
  1196  		for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
  1197  			p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
  1198  		}
  1199  		p.expectEOL()
  1200  
  1201  	case "init_graph":
  1202  		p.next()
  1203  		// The graph data is thrown away for now.
  1204  		for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
  1205  			p.parseInt64()
  1206  			p.parseInt64()
  1207  		}
  1208  		p.expectEOL()
  1209  
  1210  	case "checksum":
  1211  		// Don't let the scanner try to parse the checksum as a number.
  1212  		defer func(mode uint) {
  1213  			p.scanner.Mode = mode
  1214  		}(p.scanner.Mode)
  1215  		p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
  1216  		p.next()
  1217  		p.parseUnquotedString()
  1218  		p.expectEOL()
  1219  
  1220  	default:
  1221  		p.errorf("unexpected identifier: %q", p.lit)
  1222  	}
  1223  }
  1224  
  1225  // parseDirective parses a Directive:
  1226  //
  1227  //	Directive = InitDataDirective |
  1228  //		"package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
  1229  //		"pkgpath" unquotedString ";" |
  1230  //		"prefix" unquotedString ";" |
  1231  //		"import" unquotedString unquotedString string ";" |
  1232  //		"indirectimport" unquotedString unquotedstring ";" |
  1233  //		"func" Func ";" |
  1234  //		"type" Type ";" |
  1235  //		"var" Var ";" |
  1236  //		"const" Const ";" .
  1237  func (p *parser) parseDirective() {
  1238  	if p.tok != scanner.Ident {
  1239  		// unexpected token kind; panic
  1240  		p.expect(scanner.Ident)
  1241  	}
  1242  
  1243  	switch p.lit {
  1244  	case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum":
  1245  		p.parseInitDataDirective()
  1246  
  1247  	case "package":
  1248  		p.next()
  1249  		p.pkgname = p.parseUnquotedString()
  1250  		p.maybeCreatePackage()
  1251  		if p.version != "v1" && p.tok != '\n' && p.tok != ';' {
  1252  			p.parseUnquotedString()
  1253  			p.parseUnquotedString()
  1254  		}
  1255  		p.expectEOL()
  1256  
  1257  	case "pkgpath":
  1258  		p.next()
  1259  		p.pkgpath = p.parseUnquotedString()
  1260  		p.maybeCreatePackage()
  1261  		p.expectEOL()
  1262  
  1263  	case "prefix":
  1264  		p.next()
  1265  		p.pkgpath = p.parseUnquotedString()
  1266  		p.expectEOL()
  1267  
  1268  	case "import":
  1269  		p.next()
  1270  		pkgname := p.parseUnquotedString()
  1271  		pkgpath := p.parseUnquotedString()
  1272  		p.getPkg(pkgpath, pkgname)
  1273  		p.parseString()
  1274  		p.expectEOL()
  1275  
  1276  	case "indirectimport":
  1277  		p.next()
  1278  		pkgname := p.parseUnquotedString()
  1279  		pkgpath := p.parseUnquotedString()
  1280  		p.getPkg(pkgpath, pkgname)
  1281  		p.expectEOL()
  1282  
  1283  	case "types":
  1284  		p.next()
  1285  		p.parseTypes(p.pkg)
  1286  		p.expectEOL()
  1287  
  1288  	case "func":
  1289  		p.next()
  1290  		fun := p.parseFunc(p.pkg)
  1291  		if fun != nil {
  1292  			p.pkg.Scope().Insert(fun)
  1293  		}
  1294  		p.expectEOL()
  1295  
  1296  	case "type":
  1297  		p.next()
  1298  		p.parseType(p.pkg)
  1299  		p.expectEOL()
  1300  
  1301  	case "var":
  1302  		p.next()
  1303  		v := p.parseVar(p.pkg)
  1304  		if v != nil {
  1305  			p.pkg.Scope().Insert(v)
  1306  		}
  1307  		p.expectEOL()
  1308  
  1309  	case "const":
  1310  		p.next()
  1311  		c := p.parseConst(p.pkg)
  1312  		p.pkg.Scope().Insert(c)
  1313  		p.expectEOL()
  1314  
  1315  	default:
  1316  		p.errorf("unexpected identifier: %q", p.lit)
  1317  	}
  1318  }
  1319  
  1320  // parsePackage parses a Package:
  1321  //
  1322  //	Package = { Directive } .
  1323  func (p *parser) parsePackage() *types.Package {
  1324  	for p.tok != scanner.EOF {
  1325  		p.parseDirective()
  1326  	}
  1327  	for _, f := range p.fixups {
  1328  		if f.target.Underlying() == nil {
  1329  			p.errorf("internal error: fixup can't be applied, loop required")
  1330  		}
  1331  		f.toUpdate.SetUnderlying(f.target.Underlying())
  1332  	}
  1333  	p.fixups = nil
  1334  	for _, typ := range p.typeList {
  1335  		if it, ok := typ.(*types.Interface); ok {
  1336  			it.Complete()
  1337  		}
  1338  	}
  1339  	p.pkg.MarkComplete()
  1340  	return p.pkg
  1341  }