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
5package gccgoimporter
6
7import (
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
20type 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
51type 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
56func (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
64func (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
73type importError struct {
74	pos scanner.Position
75	err error
76}
77
78func (e importError) Error() string {
79	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
80}
81
82func (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
90func (p *parser) errorf(format string, args ...any) {
91	p.error(fmt.Errorf(format, args...))
92}
93
94func (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
103func (p *parser) expectEOL() {
104	if p.version == "v1" || p.version == "v2" {
105		p.expect(';')
106	}
107	p.expect('\n')
108}
109
110func (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
117func (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> .
127func (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
143func (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
153func (p *parser) parseQualifiedName() (path, name string) {
154	return p.parseQualifiedNameStr(p.parseString())
155}
156
157func (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.
164func (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.
189func (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] .
206func (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 | "?" .
220func (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
231func 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] .
239func (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 .
267func (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 .
296func (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 ")" .
309func (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"] .
321func (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 .
427func (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.
446var reserved = new(struct{ types.Type })
447
448// reserve reserves the type map entry n for future use.
449func (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.
475func (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] ";" .
510func (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
608func (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
617func (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 .
627func (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 .
650func (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 .
666func (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 } "}" .
693func (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 ] ")" .
716func (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 .
740func (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 .
760func (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] .
772func (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) ";" } "}" .
800func (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) .
829func (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 .
847func (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
881const (
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	gccgoBuiltinANY        = 22
906)
907
908func lookupBuiltinType(typ int) types.Type {
909	return [...]types.Type{
910		gccgoBuiltinINT8:       types.Typ[types.Int8],
911		gccgoBuiltinINT16:      types.Typ[types.Int16],
912		gccgoBuiltinINT32:      types.Typ[types.Int32],
913		gccgoBuiltinINT64:      types.Typ[types.Int64],
914		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
915		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
916		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
917		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
918		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
919		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
920		gccgoBuiltinINT:        types.Typ[types.Int],
921		gccgoBuiltinUINT:       types.Typ[types.Uint],
922		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
923		gccgoBuiltinBOOL:       types.Typ[types.Bool],
924		gccgoBuiltinSTRING:     types.Typ[types.String],
925		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
926		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
927		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
928		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
929		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
930		gccgoBuiltinANY:        types.Universe.Lookup("any").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.
937func (p *parser) parseType(pkg *types.Package, n ...any) types.Type {
938	p.expect('<')
939	t, _ := p.parseTypeAfterAngle(pkg, n...)
940	return t
941}
942
943// (*parser).Type after reading the "<".
944func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...any) (t types.Type, n1 int) {
945	p.expectKeyword("type")
946
947	n1 = 0
948	switch p.tok {
949	case scanner.Int:
950		n1 = p.parseInt()
951		if p.tok == '>' {
952			if len(p.typeData) > 0 && p.typeList[n1] == nil {
953				p.parseSavedType(pkg, n1, n)
954			}
955			t = p.typeList[n1]
956			if len(p.typeData) == 0 && t == reserved {
957				p.errorf("invalid type cycle, type %d not yet defined (nlist=%v)", n1, n)
958			}
959			p.update(t, n)
960		} else {
961			p.reserve(n1)
962			t = p.parseTypeSpec(pkg, append(n, n1))
963		}
964
965	case '-':
966		p.next()
967		n1 := p.parseInt()
968		t = lookupBuiltinType(n1)
969		p.update(t, n)
970
971	default:
972		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
973		return nil, 0
974	}
975
976	if t == nil || t == reserved {
977		p.errorf("internal error: bad return from parseType(%v)", n)
978	}
979
980	p.expect('>')
981	return
982}
983
984// parseTypeExtended is identical to parseType, but if the type in
985// question is a saved type, returns the index as well as the type
986// pointer (index returned is zero if we parsed a builtin).
987func (p *parser) parseTypeExtended(pkg *types.Package, n ...any) (t types.Type, n1 int) {
988	p.expect('<')
989	t, n1 = p.parseTypeAfterAngle(pkg, n...)
990	return
991}
992
993// InlineBody = "<inl:NN>" .{NN}
994// Reports whether a body was skipped.
995func (p *parser) skipInlineBody() {
996	// We may or may not have seen the '<' already, depending on
997	// whether the function had a result type or not.
998	if p.tok == '<' {
999		p.next()
1000		p.expectKeyword("inl")
1001	} else if p.tok != scanner.Ident || p.lit != "inl" {
1002		return
1003	} else {
1004		p.next()
1005	}
1006
1007	p.expect(':')
1008	want := p.parseInt()
1009	p.expect('>')
1010
1011	defer func(w uint64) {
1012		p.scanner.Whitespace = w
1013	}(p.scanner.Whitespace)
1014	p.scanner.Whitespace = 0
1015
1016	got := 0
1017	for got < want {
1018		r := p.scanner.Next()
1019		if r == scanner.EOF {
1020			p.error("unexpected EOF")
1021		}
1022		got += utf8.RuneLen(r)
1023	}
1024}
1025
1026// Types = "types" maxp1 exportedp1 (offset length)* .
1027func (p *parser) parseTypes(pkg *types.Package) {
1028	maxp1 := p.parseInt()
1029	exportedp1 := p.parseInt()
1030	p.typeList = make([]types.Type, maxp1, maxp1)
1031
1032	type typeOffset struct {
1033		offset int
1034		length int
1035	}
1036	var typeOffsets []typeOffset
1037
1038	total := 0
1039	for i := 1; i < maxp1; i++ {
1040		len := p.parseInt()
1041		typeOffsets = append(typeOffsets, typeOffset{total, len})
1042		total += len
1043	}
1044
1045	defer func(w uint64) {
1046		p.scanner.Whitespace = w
1047	}(p.scanner.Whitespace)
1048	p.scanner.Whitespace = 0
1049
1050	// We should now have p.tok pointing to the final newline.
1051	// The next runes from the scanner should be the type data.
1052
1053	var sb strings.Builder
1054	for sb.Len() < total {
1055		r := p.scanner.Next()
1056		if r == scanner.EOF {
1057			p.error("unexpected EOF")
1058		}
1059		sb.WriteRune(r)
1060	}
1061	allTypeData := sb.String()
1062
1063	p.typeData = []string{""} // type 0, unused
1064	for _, to := range typeOffsets {
1065		p.typeData = append(p.typeData, allTypeData[to.offset:to.offset+to.length])
1066	}
1067
1068	for i := 1; i < exportedp1; i++ {
1069		p.parseSavedType(pkg, i, nil)
1070	}
1071}
1072
1073// parseSavedType parses one saved type definition.
1074func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []any) {
1075	defer func(s *scanner.Scanner, tok rune, lit string) {
1076		p.scanner = s
1077		p.tok = tok
1078		p.lit = lit
1079	}(p.scanner, p.tok, p.lit)
1080
1081	p.scanner = new(scanner.Scanner)
1082	p.initScanner(p.scanner.Filename, strings.NewReader(p.typeData[i]))
1083	p.expectKeyword("type")
1084	id := p.parseInt()
1085	if id != i {
1086		p.errorf("type ID mismatch: got %d, want %d", id, i)
1087	}
1088	if p.typeList[i] == reserved {
1089		p.errorf("internal error: %d already reserved in parseSavedType", i)
1090	}
1091	if p.typeList[i] == nil {
1092		p.reserve(i)
1093		p.parseTypeSpec(pkg, append(nlist, i))
1094	}
1095	if p.typeList[i] == nil || p.typeList[i] == reserved {
1096		p.errorf("internal error: parseSavedType(%d,%v) reserved/nil", i, nlist)
1097	}
1098}
1099
1100// PackageInit = unquotedString unquotedString int .
1101func (p *parser) parsePackageInit() PackageInit {
1102	name := p.parseUnquotedString()
1103	initfunc := p.parseUnquotedString()
1104	priority := -1
1105	if p.version == "v1" {
1106		priority = p.parseInt()
1107	}
1108	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
1109}
1110
1111// Create the package if we have parsed both the package path and package name.
1112func (p *parser) maybeCreatePackage() {
1113	if p.pkgname != "" && p.pkgpath != "" {
1114		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
1115	}
1116}
1117
1118// InitDataDirective = ( "v1" | "v2" | "v3" ) ";" |
1119//
1120//	"priority" int ";" |
1121//	"init" { PackageInit } ";" |
1122//	"checksum" unquotedString ";" .
1123func (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//
1174//	"package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
1175//	"pkgpath" unquotedString ";" |
1176//	"prefix" unquotedString ";" |
1177//	"import" unquotedString unquotedString string ";" |
1178//	"indirectimport" unquotedString unquotedstring ";" |
1179//	"func" Func ";" |
1180//	"type" Type ";" |
1181//	"var" Var ";" |
1182//	"const" Const ";" .
1183func (p *parser) parseDirective() {
1184	if p.tok != scanner.Ident {
1185		// unexpected token kind; panic
1186		p.expect(scanner.Ident)
1187	}
1188
1189	switch p.lit {
1190	case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum":
1191		p.parseInitDataDirective()
1192
1193	case "package":
1194		p.next()
1195		p.pkgname = p.parseUnquotedString()
1196		p.maybeCreatePackage()
1197		if p.version != "v1" && p.tok != '\n' && p.tok != ';' {
1198			p.parseUnquotedString()
1199			p.parseUnquotedString()
1200		}
1201		p.expectEOL()
1202
1203	case "pkgpath":
1204		p.next()
1205		p.pkgpath = p.parseUnquotedString()
1206		p.maybeCreatePackage()
1207		p.expectEOL()
1208
1209	case "prefix":
1210		p.next()
1211		p.pkgpath = p.parseUnquotedString()
1212		p.expectEOL()
1213
1214	case "import":
1215		p.next()
1216		pkgname := p.parseUnquotedString()
1217		pkgpath := p.parseUnquotedString()
1218		p.getPkg(pkgpath, pkgname)
1219		p.parseString()
1220		p.expectEOL()
1221
1222	case "indirectimport":
1223		p.next()
1224		pkgname := p.parseUnquotedString()
1225		pkgpath := p.parseUnquotedString()
1226		p.getPkg(pkgpath, pkgname)
1227		p.expectEOL()
1228
1229	case "types":
1230		p.next()
1231		p.parseTypes(p.pkg)
1232		p.expectEOL()
1233
1234	case "func":
1235		p.next()
1236		fun := p.parseFunc(p.pkg)
1237		if fun != nil {
1238			p.pkg.Scope().Insert(fun)
1239		}
1240		p.expectEOL()
1241
1242	case "type":
1243		p.next()
1244		p.parseType(p.pkg)
1245		p.expectEOL()
1246
1247	case "var":
1248		p.next()
1249		v := p.parseVar(p.pkg)
1250		if v != nil {
1251			p.pkg.Scope().Insert(v)
1252		}
1253		p.expectEOL()
1254
1255	case "const":
1256		p.next()
1257		c := p.parseConst(p.pkg)
1258		p.pkg.Scope().Insert(c)
1259		p.expectEOL()
1260
1261	default:
1262		p.errorf("unexpected identifier: %q", p.lit)
1263	}
1264}
1265
1266// Package = { Directive } .
1267func (p *parser) parsePackage() *types.Package {
1268	for p.tok != scanner.EOF {
1269		p.parseDirective()
1270	}
1271	for _, f := range p.fixups {
1272		if f.target.Underlying() == nil {
1273			p.errorf("internal error: fixup can't be applied, loop required")
1274		}
1275		f.toUpdate.SetUnderlying(f.target.Underlying())
1276	}
1277	p.fixups = nil
1278	for _, typ := range p.typeList {
1279		if it, ok := typ.(*types.Interface); ok {
1280			it.Complete()
1281		}
1282	}
1283	p.pkg.MarkComplete()
1284	return p.pkg
1285}
1286