Black Lives Matter. Support the Equal Justice Initiative.

Source file src/go/internal/gccgoimporter/parser.go

Documentation: go/internal/gccgoimporter

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

View as plain text