parser.mx raw

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