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

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

View as plain text