1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Except for this comment, this file is a verbatim copy of the file
6// with the same name in $GOROOT/src/go/internal/gccgoimporter, with
7// a small modification in parseInterface to support older Go versions.
8
9package gccgoimporter
10
11import (
12	"bytes"
13	"errors"
14	"fmt"
15	"go/constant"
16	"go/token"
17	"go/types"
18	"io"
19	"strconv"
20	"strings"
21	"text/scanner"
22)
23
24type parser struct {
25	scanner  scanner.Scanner
26	version  string                    // format version
27	tok      rune                      // current token
28	lit      string                    // literal string; only valid for Ident, Int, String tokens
29	pkgpath  string                    // package path of imported package
30	pkgname  string                    // name of imported package
31	pkg      *types.Package            // reference to imported package
32	imports  map[string]*types.Package // package path -> package object
33	typeList []types.Type              // type number -> type
34	initdata InitData                  // package init priority data
35}
36
37func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
38	p.scanner.Init(src)
39	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
40	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
41	p.scanner.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' '
42	p.scanner.Filename = filename // for good error messages
43	p.next()
44	p.imports = imports
45	p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
46}
47
48type importError struct {
49	pos scanner.Position
50	err error
51}
52
53func (e importError) Error() string {
54	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
55}
56
57func (p *parser) error(err interface{}) {
58	if s, ok := err.(string); ok {
59		err = errors.New(s)
60	}
61	// panic with a runtime.Error if err is not an error
62	panic(importError{p.scanner.Pos(), err.(error)})
63}
64
65func (p *parser) errorf(format string, args ...interface{}) {
66	p.error(fmt.Errorf(format, args...))
67}
68
69func (p *parser) expect(tok rune) string {
70	lit := p.lit
71	if p.tok != tok {
72		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
73	}
74	p.next()
75	return lit
76}
77
78func (p *parser) expectKeyword(keyword string) {
79	lit := p.expect(scanner.Ident)
80	if lit != keyword {
81		p.errorf("expected keyword %s, got %q", keyword, lit)
82	}
83}
84
85func (p *parser) parseString() string {
86	str, err := strconv.Unquote(p.expect(scanner.String))
87	if err != nil {
88		p.error(err)
89	}
90	return str
91}
92
93// unquotedString     = { unquotedStringChar } .
94// unquotedStringChar = <neither a whitespace nor a ';' char> .
95func (p *parser) parseUnquotedString() string {
96	if p.tok == scanner.EOF {
97		p.error("unexpected EOF")
98	}
99	var buf bytes.Buffer
100	buf.WriteString(p.scanner.TokenText())
101	// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
102	// we need to let it be consumed by p.next().
103	for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
104		buf.WriteRune(ch)
105		p.scanner.Next()
106	}
107	p.next()
108	return buf.String()
109}
110
111func (p *parser) next() {
112	p.tok = p.scanner.Scan()
113	switch p.tok {
114	case scanner.Ident, scanner.Int, scanner.Float, scanner.String, '·':
115		p.lit = p.scanner.TokenText()
116	default:
117		p.lit = ""
118	}
119}
120
121func (p *parser) parseQualifiedName() (path, name string) {
122	return p.parseQualifiedNameStr(p.parseString())
123}
124
125func (p *parser) parseUnquotedQualifiedName() (path, name string) {
126	return p.parseQualifiedNameStr(p.parseUnquotedString())
127}
128
129// qualifiedName = [ ["."] unquotedString "." ] unquotedString .
130//
131// The above production uses greedy matching.
132func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
133	parts := strings.Split(unquotedName, ".")
134	if parts[0] == "" {
135		parts = parts[1:]
136	}
137
138	switch len(parts) {
139	case 0:
140		p.errorf("malformed qualified name: %q", unquotedName)
141	case 1:
142		// unqualified name
143		pkgpath = p.pkgpath
144		name = parts[0]
145	default:
146		// qualified name, which may contain periods
147		pkgpath = strings.Join(parts[0:len(parts)-1], ".")
148		name = parts[len(parts)-1]
149	}
150
151	return
152}
153
154// getPkg returns the package for a given path. If the package is
155// not found but we have a package name, create the package and
156// add it to the p.imports map.
157//
158func (p *parser) getPkg(pkgpath, name string) *types.Package {
159	// package unsafe is not in the imports map - handle explicitly
160	if pkgpath == "unsafe" {
161		return types.Unsafe
162	}
163	pkg := p.imports[pkgpath]
164	if pkg == nil && name != "" {
165		pkg = types.NewPackage(pkgpath, name)
166		p.imports[pkgpath] = pkg
167	}
168	return pkg
169}
170
171// parseExportedName is like parseQualifiedName, but
172// the package path is resolved to an imported *types.Package.
173//
174// ExportedName = string [string] .
175func (p *parser) parseExportedName() (pkg *types.Package, name string) {
176	path, name := p.parseQualifiedName()
177	var pkgname string
178	if p.tok == scanner.String {
179		pkgname = p.parseString()
180	}
181	pkg = p.getPkg(path, pkgname)
182	if pkg == nil {
183		p.errorf("package %s (path = %q) not found", name, path)
184	}
185	return
186}
187
188// Name = QualifiedName | "?" .
189func (p *parser) parseName() string {
190	if p.tok == '?' {
191		// Anonymous.
192		p.next()
193		return ""
194	}
195	// The package path is redundant for us. Don't try to parse it.
196	_, name := p.parseUnquotedQualifiedName()
197	return name
198}
199
200func deref(typ types.Type) types.Type {
201	if p, _ := typ.(*types.Pointer); p != nil {
202		typ = p.Elem()
203	}
204	return typ
205}
206
207// Field = Name Type [string] .
208func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
209	name := p.parseName()
210	typ := p.parseType(pkg)
211	anon := false
212	if name == "" {
213		anon = true
214		switch typ := deref(typ).(type) {
215		case *types.Basic:
216			name = typ.Name()
217		case *types.Named:
218			name = typ.Obj().Name()
219		default:
220			p.error("anonymous field expected")
221		}
222	}
223	field = types.NewField(token.NoPos, pkg, name, typ, anon)
224	if p.tok == scanner.String {
225		tag = p.parseString()
226	}
227	return
228}
229
230// Param = Name ["..."] Type .
231func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
232	name := p.parseName()
233	if p.tok == '<' && p.scanner.Peek() == 'e' {
234		// EscInfo = "<esc:" int ">" . (optional and ignored)
235		p.next()
236		p.expectKeyword("esc")
237		p.expect(':')
238		p.expect(scanner.Int)
239		p.expect('>')
240	}
241	if p.tok == '.' {
242		p.next()
243		p.expect('.')
244		p.expect('.')
245		isVariadic = true
246	}
247	typ := p.parseType(pkg)
248	if isVariadic {
249		typ = types.NewSlice(typ)
250	}
251	param = types.NewParam(token.NoPos, pkg, name, typ)
252	return
253}
254
255// Var = Name Type .
256func (p *parser) parseVar(pkg *types.Package) *types.Var {
257	name := p.parseName()
258	return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
259}
260
261// Conversion = "convert" "(" Type "," ConstValue ")" .
262func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
263	p.expectKeyword("convert")
264	p.expect('(')
265	typ = p.parseType(pkg)
266	p.expect(',')
267	val, _ = p.parseConstValue(pkg)
268	p.expect(')')
269	return
270}
271
272// ConstValue     = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
273// FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
274func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
275	switch p.tok {
276	case scanner.String:
277		str := p.parseString()
278		val = constant.MakeString(str)
279		typ = types.Typ[types.UntypedString]
280		return
281
282	case scanner.Ident:
283		b := false
284		switch p.lit {
285		case "false":
286		case "true":
287			b = true
288
289		case "convert":
290			return p.parseConversion(pkg)
291
292		default:
293			p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
294		}
295
296		p.next()
297		val = constant.MakeBool(b)
298		typ = types.Typ[types.UntypedBool]
299		return
300	}
301
302	sign := ""
303	if p.tok == '-' {
304		p.next()
305		sign = "-"
306	}
307
308	switch p.tok {
309	case scanner.Int:
310		val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
311		if val == nil {
312			p.error("could not parse integer literal")
313		}
314
315		p.next()
316		if p.tok == '\'' {
317			p.next()
318			typ = types.Typ[types.UntypedRune]
319		} else {
320			typ = types.Typ[types.UntypedInt]
321		}
322
323	case scanner.Float:
324		re := sign + p.lit
325		p.next()
326
327		var im string
328		switch p.tok {
329		case '+':
330			p.next()
331			im = p.expect(scanner.Float)
332
333		case '-':
334			p.next()
335			im = "-" + p.expect(scanner.Float)
336
337		case scanner.Ident:
338			// re is in fact the imaginary component. Expect "i" below.
339			im = re
340			re = "0"
341
342		default:
343			val = constant.MakeFromLiteral(re, token.FLOAT, 0)
344			if val == nil {
345				p.error("could not parse float literal")
346			}
347			typ = types.Typ[types.UntypedFloat]
348			return
349		}
350
351		p.expectKeyword("i")
352		reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
353		if reval == nil {
354			p.error("could not parse real component of complex literal")
355		}
356		imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
357		if imval == nil {
358			p.error("could not parse imag component of complex literal")
359		}
360		val = constant.BinaryOp(reval, token.ADD, imval)
361		typ = types.Typ[types.UntypedComplex]
362
363	default:
364		p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
365	}
366
367	return
368}
369
370// Const = Name [Type] "=" ConstValue .
371func (p *parser) parseConst(pkg *types.Package) *types.Const {
372	name := p.parseName()
373	var typ types.Type
374	if p.tok == '<' {
375		typ = p.parseType(pkg)
376	}
377	p.expect('=')
378	val, vtyp := p.parseConstValue(pkg)
379	if typ == nil {
380		typ = vtyp
381	}
382	return types.NewConst(token.NoPos, pkg, name, typ, val)
383}
384
385// reserved is a singleton type used to fill type map slots that have
386// been reserved (i.e., for which a type number has been parsed) but
387// which don't have their actual type yet. When the type map is updated,
388// the actual type must replace a reserved entry (or we have an internal
389// error). Used for self-verification only - not required for correctness.
390var reserved = new(struct{ types.Type })
391
392// reserve reserves the type map entry n for future use.
393func (p *parser) reserve(n int) {
394	if n != len(p.typeList) {
395		p.errorf("invalid type number %d (out of sync)", n)
396	}
397	p.typeList = append(p.typeList, reserved)
398}
399
400// update sets the type map entries for the given type numbers nlist to t.
401func (p *parser) update(t types.Type, nlist []int) {
402	for _, n := range nlist {
403		if p.typeList[n] != reserved {
404			p.errorf("typeMap[%d] not reserved", n)
405		}
406		p.typeList[n] = t
407	}
408}
409
410// NamedType = TypeName [ "=" ] Type { Method } .
411// TypeName  = ExportedName .
412// Method    = "func" "(" Param ")" Name ParamList ResultList ";" .
413func (p *parser) parseNamedType(nlist []int) types.Type {
414	pkg, name := p.parseExportedName()
415	scope := pkg.Scope()
416	obj := scope.Lookup(name)
417	if obj != nil && obj.Type() == nil {
418		p.errorf("%v has nil type", obj)
419	}
420
421	// type alias
422	if p.tok == '=' {
423		p.next()
424		if obj != nil {
425			// use the previously imported (canonical) type
426			t := obj.Type()
427			p.update(t, nlist)
428			p.parseType(pkg) // discard
429			return t
430		}
431		t := p.parseType(pkg, nlist...)
432		obj = types.NewTypeName(token.NoPos, pkg, name, t)
433		scope.Insert(obj)
434		return t
435	}
436
437	// defined type
438	if obj == nil {
439		// A named type may be referred to before the underlying type
440		// is known - set it up.
441		tname := types.NewTypeName(token.NoPos, pkg, name, nil)
442		types.NewNamed(tname, nil, nil)
443		scope.Insert(tname)
444		obj = tname
445	}
446
447	// use the previously imported (canonical), or newly created type
448	t := obj.Type()
449	p.update(t, nlist)
450
451	nt, ok := t.(*types.Named)
452	if !ok {
453		// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
454		pt := p.parseType(pkg)
455		if pt != t {
456			p.error("unexpected underlying type for non-named TypeName")
457		}
458		return t
459	}
460
461	underlying := p.parseType(pkg)
462	if nt.Underlying() == nil {
463		nt.SetUnderlying(underlying.Underlying())
464	}
465
466	// collect associated methods
467	for p.tok == scanner.Ident {
468		p.expectKeyword("func")
469		p.expect('(')
470		receiver, _ := p.parseParam(pkg)
471		p.expect(')')
472		name := p.parseName()
473		params, isVariadic := p.parseParamList(pkg)
474		results := p.parseResultList(pkg)
475		p.expect(';')
476
477		sig := types.NewSignature(receiver, params, results, isVariadic)
478		nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
479	}
480
481	return nt
482}
483
484func (p *parser) parseInt64() int64 {
485	lit := p.expect(scanner.Int)
486	n, err := strconv.ParseInt(lit, 10, 64)
487	if err != nil {
488		p.error(err)
489	}
490	return n
491}
492
493func (p *parser) parseInt() int {
494	lit := p.expect(scanner.Int)
495	n, err := strconv.ParseInt(lit, 10, 0 /* int */)
496	if err != nil {
497		p.error(err)
498	}
499	return int(n)
500}
501
502// ArrayOrSliceType = "[" [ int ] "]" Type .
503func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []int) types.Type {
504	p.expect('[')
505	if p.tok == ']' {
506		p.next()
507
508		t := new(types.Slice)
509		p.update(t, nlist)
510
511		*t = *types.NewSlice(p.parseType(pkg))
512		return t
513	}
514
515	t := new(types.Array)
516	p.update(t, nlist)
517
518	len := p.parseInt64()
519	p.expect(']')
520
521	*t = *types.NewArray(p.parseType(pkg), len)
522	return t
523}
524
525// MapType = "map" "[" Type "]" Type .
526func (p *parser) parseMapType(pkg *types.Package, nlist []int) types.Type {
527	p.expectKeyword("map")
528
529	t := new(types.Map)
530	p.update(t, nlist)
531
532	p.expect('[')
533	key := p.parseType(pkg)
534	p.expect(']')
535	elem := p.parseType(pkg)
536
537	*t = *types.NewMap(key, elem)
538	return t
539}
540
541// ChanType = "chan" ["<-" | "-<"] Type .
542func (p *parser) parseChanType(pkg *types.Package, nlist []int) types.Type {
543	p.expectKeyword("chan")
544
545	t := new(types.Chan)
546	p.update(t, nlist)
547
548	dir := types.SendRecv
549	switch p.tok {
550	case '-':
551		p.next()
552		p.expect('<')
553		dir = types.SendOnly
554
555	case '<':
556		// don't consume '<' if it belongs to Type
557		if p.scanner.Peek() == '-' {
558			p.next()
559			p.expect('-')
560			dir = types.RecvOnly
561		}
562	}
563
564	*t = *types.NewChan(dir, p.parseType(pkg))
565	return t
566}
567
568// StructType = "struct" "{" { Field } "}" .
569func (p *parser) parseStructType(pkg *types.Package, nlist []int) types.Type {
570	p.expectKeyword("struct")
571
572	t := new(types.Struct)
573	p.update(t, nlist)
574
575	var fields []*types.Var
576	var tags []string
577
578	p.expect('{')
579	for p.tok != '}' && p.tok != scanner.EOF {
580		field, tag := p.parseField(pkg)
581		p.expect(';')
582		fields = append(fields, field)
583		tags = append(tags, tag)
584	}
585	p.expect('}')
586
587	*t = *types.NewStruct(fields, tags)
588	return t
589}
590
591// ParamList = "(" [ { Parameter "," } Parameter ] ")" .
592func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
593	var list []*types.Var
594	isVariadic := false
595
596	p.expect('(')
597	for p.tok != ')' && p.tok != scanner.EOF {
598		if len(list) > 0 {
599			p.expect(',')
600		}
601		par, variadic := p.parseParam(pkg)
602		list = append(list, par)
603		if variadic {
604			if isVariadic {
605				p.error("... not on final argument")
606			}
607			isVariadic = true
608		}
609	}
610	p.expect(')')
611
612	return types.NewTuple(list...), isVariadic
613}
614
615// ResultList = Type | ParamList .
616func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
617	switch p.tok {
618	case '<':
619		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg)))
620
621	case '(':
622		params, _ := p.parseParamList(pkg)
623		return params
624
625	default:
626		return nil
627	}
628}
629
630// FunctionType = ParamList ResultList .
631func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signature {
632	t := new(types.Signature)
633	p.update(t, nlist)
634
635	params, isVariadic := p.parseParamList(pkg)
636	results := p.parseResultList(pkg)
637
638	*t = *types.NewSignature(nil, params, results, isVariadic)
639	return t
640}
641
642// Func = Name FunctionType .
643func (p *parser) parseFunc(pkg *types.Package) *types.Func {
644	name := p.parseName()
645	if strings.ContainsRune(name, '$') {
646		// This is a Type$equal or Type$hash function, which we don't want to parse,
647		// except for the types.
648		p.discardDirectiveWhileParsingTypes(pkg)
649		return nil
650	}
651	return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
652}
653
654// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
655func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type {
656	p.expectKeyword("interface")
657
658	t := new(types.Interface)
659	p.update(t, nlist)
660
661	var methods []*types.Func
662	var embeddeds []types.Type
663
664	p.expect('{')
665	for p.tok != '}' && p.tok != scanner.EOF {
666		if p.tok == '?' {
667			p.next()
668			embeddeds = append(embeddeds, p.parseType(pkg))
669		} else {
670			method := p.parseFunc(pkg)
671			methods = append(methods, method)
672		}
673		p.expect(';')
674	}
675	p.expect('}')
676
677	*t = *newInterface(methods, embeddeds)
678	return t
679}
680
681// PointerType = "*" ("any" | Type) .
682func (p *parser) parsePointerType(pkg *types.Package, nlist []int) types.Type {
683	p.expect('*')
684	if p.tok == scanner.Ident {
685		p.expectKeyword("any")
686		t := types.Typ[types.UnsafePointer]
687		p.update(t, nlist)
688		return t
689	}
690
691	t := new(types.Pointer)
692	p.update(t, nlist)
693
694	*t = *types.NewPointer(p.parseType(pkg))
695
696	return t
697}
698
699// TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
700func (p *parser) parseTypeSpec(pkg *types.Package, nlist []int) types.Type {
701	switch p.tok {
702	case scanner.String:
703		return p.parseNamedType(nlist)
704
705	case scanner.Ident:
706		switch p.lit {
707		case "map":
708			return p.parseMapType(pkg, nlist)
709
710		case "chan":
711			return p.parseChanType(pkg, nlist)
712
713		case "struct":
714			return p.parseStructType(pkg, nlist)
715
716		case "interface":
717			return p.parseInterfaceType(pkg, nlist)
718		}
719
720	case '*':
721		return p.parsePointerType(pkg, nlist)
722
723	case '[':
724		return p.parseArrayOrSliceType(pkg, nlist)
725
726	case '(':
727		return p.parseFunctionType(pkg, nlist)
728	}
729
730	p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
731	return nil
732}
733
734const (
735	// From gofrontend/go/export.h
736	// Note that these values are negative in the gofrontend and have been made positive
737	// in the gccgoimporter.
738	gccgoBuiltinINT8       = 1
739	gccgoBuiltinINT16      = 2
740	gccgoBuiltinINT32      = 3
741	gccgoBuiltinINT64      = 4
742	gccgoBuiltinUINT8      = 5
743	gccgoBuiltinUINT16     = 6
744	gccgoBuiltinUINT32     = 7
745	gccgoBuiltinUINT64     = 8
746	gccgoBuiltinFLOAT32    = 9
747	gccgoBuiltinFLOAT64    = 10
748	gccgoBuiltinINT        = 11
749	gccgoBuiltinUINT       = 12
750	gccgoBuiltinUINTPTR    = 13
751	gccgoBuiltinBOOL       = 15
752	gccgoBuiltinSTRING     = 16
753	gccgoBuiltinCOMPLEX64  = 17
754	gccgoBuiltinCOMPLEX128 = 18
755	gccgoBuiltinERROR      = 19
756	gccgoBuiltinBYTE       = 20
757	gccgoBuiltinRUNE       = 21
758)
759
760func lookupBuiltinType(typ int) types.Type {
761	return [...]types.Type{
762		gccgoBuiltinINT8:       types.Typ[types.Int8],
763		gccgoBuiltinINT16:      types.Typ[types.Int16],
764		gccgoBuiltinINT32:      types.Typ[types.Int32],
765		gccgoBuiltinINT64:      types.Typ[types.Int64],
766		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
767		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
768		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
769		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
770		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
771		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
772		gccgoBuiltinINT:        types.Typ[types.Int],
773		gccgoBuiltinUINT:       types.Typ[types.Uint],
774		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
775		gccgoBuiltinBOOL:       types.Typ[types.Bool],
776		gccgoBuiltinSTRING:     types.Typ[types.String],
777		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
778		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
779		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
780		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
781		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
782	}[typ]
783}
784
785// Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
786//
787// parseType updates the type map to t for all type numbers n.
788//
789func (p *parser) parseType(pkg *types.Package, n ...int) (t types.Type) {
790	p.expect('<')
791	p.expectKeyword("type")
792
793	switch p.tok {
794	case scanner.Int:
795		n1 := p.parseInt()
796		if p.tok == '>' {
797			t = p.typeList[n1]
798			if t == reserved {
799				p.errorf("invalid type cycle, type %d not yet defined", n1)
800			}
801			p.update(t, n)
802		} else {
803			p.reserve(n1)
804			t = p.parseTypeSpec(pkg, append(n, n1))
805		}
806
807	case '-':
808		p.next()
809		n1 := p.parseInt()
810		t = lookupBuiltinType(n1)
811		p.update(t, n)
812
813	default:
814		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
815	}
816
817	p.expect('>')
818	return
819}
820
821// PackageInit = unquotedString unquotedString int .
822func (p *parser) parsePackageInit() PackageInit {
823	name := p.parseUnquotedString()
824	initfunc := p.parseUnquotedString()
825	priority := -1
826	if p.version == "v1" {
827		priority = p.parseInt()
828	}
829	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
830}
831
832// Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type.
833func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) {
834	for {
835		switch p.tok {
836		case ';':
837			return
838		case '<':
839			p.parseType(pkg)
840		case scanner.EOF:
841			p.error("unexpected EOF")
842		default:
843			p.next()
844		}
845	}
846}
847
848// Create the package if we have parsed both the package path and package name.
849func (p *parser) maybeCreatePackage() {
850	if p.pkgname != "" && p.pkgpath != "" {
851		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
852	}
853}
854
855// InitDataDirective = ( "v1" | "v2" ) ";" |
856//                     "priority" int ";" |
857//                     "init" { PackageInit } ";" |
858//                     "checksum" unquotedString ";" .
859func (p *parser) parseInitDataDirective() {
860	if p.tok != scanner.Ident {
861		// unexpected token kind; panic
862		p.expect(scanner.Ident)
863	}
864
865	switch p.lit {
866	case "v1", "v2":
867		p.version = p.lit
868		p.next()
869		p.expect(';')
870
871	case "priority":
872		p.next()
873		p.initdata.Priority = p.parseInt()
874		p.expect(';')
875
876	case "init":
877		p.next()
878		for p.tok != ';' && p.tok != scanner.EOF {
879			p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
880		}
881		p.expect(';')
882
883	case "init_graph":
884		p.next()
885		// The graph data is thrown away for now.
886		for p.tok != ';' && p.tok != scanner.EOF {
887			p.parseInt64()
888			p.parseInt64()
889		}
890		p.expect(';')
891
892	case "checksum":
893		// Don't let the scanner try to parse the checksum as a number.
894		defer func(mode uint) {
895			p.scanner.Mode = mode
896		}(p.scanner.Mode)
897		p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
898		p.next()
899		p.parseUnquotedString()
900		p.expect(';')
901
902	default:
903		p.errorf("unexpected identifier: %q", p.lit)
904	}
905}
906
907// Directive = InitDataDirective |
908//             "package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
909//             "pkgpath" unquotedString ";" |
910//             "prefix" unquotedString ";" |
911//             "import" unquotedString unquotedString string ";" |
912//             "func" Func ";" |
913//             "type" Type ";" |
914//             "var" Var ";" |
915//             "const" Const ";" .
916func (p *parser) parseDirective() {
917	if p.tok != scanner.Ident {
918		// unexpected token kind; panic
919		p.expect(scanner.Ident)
920	}
921
922	switch p.lit {
923	case "v1", "v2", "priority", "init", "init_graph", "checksum":
924		p.parseInitDataDirective()
925
926	case "package":
927		p.next()
928		p.pkgname = p.parseUnquotedString()
929		p.maybeCreatePackage()
930		if p.version == "v2" && p.tok != ';' {
931			p.parseUnquotedString()
932			p.parseUnquotedString()
933		}
934		p.expect(';')
935
936	case "pkgpath":
937		p.next()
938		p.pkgpath = p.parseUnquotedString()
939		p.maybeCreatePackage()
940		p.expect(';')
941
942	case "prefix":
943		p.next()
944		p.pkgpath = p.parseUnquotedString()
945		p.expect(';')
946
947	case "import":
948		p.next()
949		pkgname := p.parseUnquotedString()
950		pkgpath := p.parseUnquotedString()
951		p.getPkg(pkgpath, pkgname)
952		p.parseString()
953		p.expect(';')
954
955	case "func":
956		p.next()
957		fun := p.parseFunc(p.pkg)
958		if fun != nil {
959			p.pkg.Scope().Insert(fun)
960		}
961		p.expect(';')
962
963	case "type":
964		p.next()
965		p.parseType(p.pkg)
966		p.expect(';')
967
968	case "var":
969		p.next()
970		v := p.parseVar(p.pkg)
971		p.pkg.Scope().Insert(v)
972		p.expect(';')
973
974	case "const":
975		p.next()
976		c := p.parseConst(p.pkg)
977		p.pkg.Scope().Insert(c)
978		p.expect(';')
979
980	default:
981		p.errorf("unexpected identifier: %q", p.lit)
982	}
983}
984
985// Package = { Directive } .
986func (p *parser) parsePackage() *types.Package {
987	for p.tok != scanner.EOF {
988		p.parseDirective()
989	}
990	for _, typ := range p.typeList {
991		if it, ok := typ.(*types.Interface); ok {
992			it.Complete()
993		}
994	}
995	p.pkg.MarkComplete()
996	return p.pkg
997}
998