// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Except for this comment, this file is a verbatim copy of the file
// with the same name in $GOROOT/src/go/internal/gccgoimporter, with
// a small modification in parseInterface to support older Go versions.

package gccgoimporter

import (
	"bytes"
	"errors"
	"fmt"
	"go/constant"
	"go/token"
	"go/types"
	"io"
	"strconv"
	"strings"
	"text/scanner"
	"unicode/utf8"
)

type parser struct {
	scanner  *scanner.Scanner
	version  string                    // format version
	tok      rune                      // current token
	lit      string                    // literal string; only valid for Ident, Int, String tokens
	pkgpath  string                    // package path of imported package
	pkgname  string                    // name of imported package
	pkg      *types.Package            // reference to imported package
	imports  map[string]*types.Package // package path -> package object
	typeList []types.Type              // type number -> type
	typeData []string                  // unparsed type data (v3 and later)
	fixups   []fixupRecord             // fixups to apply at end of parsing
	initdata InitData                  // package init priority data
	aliases  map[int]string            // maps saved type number to alias name
}

// When reading export data it's possible to encounter a defined type
// N1 with an underlying defined type N2 while we are still reading in
// that defined type N2; see issues #29006 and #29198 for instances
// of this. Example:
//
//   type N1 N2
//   type N2 struct {
//      ...
//      p *N1
//   }
//
// To handle such cases, the parser generates a fixup record (below) and
// delays setting of N1's underlying type until parsing is complete, at
// which point fixups are applied.

type fixupRecord struct {
	toUpdate *types.Named // type to modify when fixup is processed
	target   types.Type   // type that was incomplete when fixup was created
}

func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
	p.scanner = new(scanner.Scanner)
	p.initScanner(filename, src)
	p.imports = imports
	p.aliases = make(map[int]string)
	p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16)
}

func (p *parser) initScanner(filename string, src io.Reader) {
	p.scanner.Init(src)
	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings
	p.scanner.Whitespace = 1<<'\t' | 1<<' '
	p.scanner.Filename = filename // for good error messages
	p.next()
}

type importError struct {
	pos scanner.Position
	err error
}

func (e importError) Error() string {
	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
}

func (p *parser) error(err interface{}) {
	if s, ok := err.(string); ok {
		err = errors.New(s)
	}
	// panic with a runtime.Error if err is not an error
	panic(importError{p.scanner.Pos(), err.(error)})
}

func (p *parser) errorf(format string, args ...interface{}) {
	p.error(fmt.Errorf(format, args...))
}

func (p *parser) expect(tok rune) string {
	lit := p.lit
	if p.tok != tok {
		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
	}
	p.next()
	return lit
}

func (p *parser) expectEOL() {
	if p.version == "v1" || p.version == "v2" {
		p.expect(';')
	}
	p.expect('\n')
}

func (p *parser) expectKeyword(keyword string) {
	lit := p.expect(scanner.Ident)
	if lit != keyword {
		p.errorf("expected keyword %s, got %q", keyword, lit)
	}
}

func (p *parser) parseString() string {
	str, err := strconv.Unquote(p.expect(scanner.String))
	if err != nil {
		p.error(err)
	}
	return str
}

// unquotedString     = { unquotedStringChar } .
// unquotedStringChar = <neither a whitespace nor a ';' char> .
func (p *parser) parseUnquotedString() string {
	if p.tok == scanner.EOF {
		p.error("unexpected EOF")
	}
	var buf bytes.Buffer
	buf.WriteString(p.scanner.TokenText())
	// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
	// we need to let it be consumed by p.next().
	for ch := p.scanner.Peek(); ch != '\n' && ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
		buf.WriteRune(ch)
		p.scanner.Next()
	}
	p.next()
	return buf.String()
}

func (p *parser) next() {
	p.tok = p.scanner.Scan()
	switch p.tok {
	case scanner.Ident, scanner.Int, scanner.Float, scanner.String, '·':
		p.lit = p.scanner.TokenText()
	default:
		p.lit = ""
	}
}

func (p *parser) parseQualifiedName() (path, name string) {
	return p.parseQualifiedNameStr(p.parseString())
}

func (p *parser) parseUnquotedQualifiedName() (path, name string) {
	return p.parseQualifiedNameStr(p.parseUnquotedString())
}

// qualifiedName = [ ["."] unquotedString "." ] unquotedString .
//
// The above production uses greedy matching.
func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
	parts := strings.Split(unquotedName, ".")
	if parts[0] == "" {
		parts = parts[1:]
	}

	switch len(parts) {
	case 0:
		p.errorf("malformed qualified name: %q", unquotedName)
	case 1:
		// unqualified name
		pkgpath = p.pkgpath
		name = parts[0]
	default:
		// qualified name, which may contain periods
		pkgpath = strings.Join(parts[0:len(parts)-1], ".")
		name = parts[len(parts)-1]
	}

	return
}

// getPkg returns the package for a given path. If the package is
// not found but we have a package name, create the package and
// add it to the p.imports map.
//
func (p *parser) getPkg(pkgpath, name string) *types.Package {
	// package unsafe is not in the imports map - handle explicitly
	if pkgpath == "unsafe" {
		return types.Unsafe
	}
	pkg := p.imports[pkgpath]
	if pkg == nil && name != "" {
		pkg = types.NewPackage(pkgpath, name)
		p.imports[pkgpath] = pkg
	}
	return pkg
}

// parseExportedName is like parseQualifiedName, but
// the package path is resolved to an imported *types.Package.
//
// ExportedName = string [string] .
func (p *parser) parseExportedName() (pkg *types.Package, name string) {
	path, name := p.parseQualifiedName()
	var pkgname string
	if p.tok == scanner.String {
		pkgname = p.parseString()
	}
	pkg = p.getPkg(path, pkgname)
	if pkg == nil {
		p.errorf("package %s (path = %q) not found", name, path)
	}
	return
}

// Name = QualifiedName | "?" .
func (p *parser) parseName() string {
	if p.tok == '?' {
		// Anonymous.
		p.next()
		return ""
	}
	// The package path is redundant for us. Don't try to parse it.
	_, name := p.parseUnquotedQualifiedName()
	return name
}

func deref(typ types.Type) types.Type {
	if p, _ := typ.(*types.Pointer); p != nil {
		typ = p.Elem()
	}
	return typ
}

// Field = Name Type [string] .
func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
	name := p.parseName()
	typ, n := p.parseTypeExtended(pkg)
	anon := false
	if name == "" {
		anon = true
		// Alias?
		if aname, ok := p.aliases[n]; ok {
			name = aname
		} else {
			switch typ := deref(typ).(type) {
			case *types.Basic:
				name = typ.Name()
			case *types.Named:
				name = typ.Obj().Name()
			default:
				p.error("embedded field expected")
			}
		}
	}
	field = types.NewField(token.NoPos, pkg, name, typ, anon)
	if p.tok == scanner.String {
		tag = p.parseString()
	}
	return
}

// Param = Name ["..."] Type .
func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
	name := p.parseName()
	// Ignore names invented for inlinable functions.
	if strings.HasPrefix(name, "p.") || strings.HasPrefix(name, "r.") || strings.HasPrefix(name, "$ret") {
		name = ""
	}
	if p.tok == '<' && p.scanner.Peek() == 'e' {
		// EscInfo = "<esc:" int ">" . (optional and ignored)
		p.next()
		p.expectKeyword("esc")
		p.expect(':')
		p.expect(scanner.Int)
		p.expect('>')
	}
	if p.tok == '.' {
		p.next()
		p.expect('.')
		p.expect('.')
		isVariadic = true
	}
	typ := p.parseType(pkg)
	if isVariadic {
		typ = types.NewSlice(typ)
	}
	param = types.NewParam(token.NoPos, pkg, name, typ)
	return
}

// Var = Name Type .
func (p *parser) parseVar(pkg *types.Package) *types.Var {
	name := p.parseName()
	v := types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
	if name[0] == '.' || name[0] == '<' {
		// This is an unexported variable,
		// or a variable defined in a different package.
		// We only want to record exported variables.
		return nil
	}
	return v
}

// Conversion = "convert" "(" Type "," ConstValue ")" .
func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
	p.expectKeyword("convert")
	p.expect('(')
	typ = p.parseType(pkg)
	p.expect(',')
	val, _ = p.parseConstValue(pkg)
	p.expect(')')
	return
}

// ConstValue     = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion .
// FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
	// v3 changed to $false, $true, $convert, to avoid confusion
	// with variable names in inline function bodies.
	if p.tok == '$' {
		p.next()
		if p.tok != scanner.Ident {
			p.errorf("expected identifer after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit)
		}
	}

	switch p.tok {
	case scanner.String:
		str := p.parseString()
		val = constant.MakeString(str)
		typ = types.Typ[types.UntypedString]
		return

	case scanner.Ident:
		b := false
		switch p.lit {
		case "false":
		case "true":
			b = true

		case "convert":
			return p.parseConversion(pkg)

		default:
			p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
		}

		p.next()
		val = constant.MakeBool(b)
		typ = types.Typ[types.UntypedBool]
		return
	}

	sign := ""
	if p.tok == '-' {
		p.next()
		sign = "-"
	}

	switch p.tok {
	case scanner.Int:
		val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
		if val == nil {
			p.error("could not parse integer literal")
		}

		p.next()
		if p.tok == '\'' {
			p.next()
			typ = types.Typ[types.UntypedRune]
		} else {
			typ = types.Typ[types.UntypedInt]
		}

	case scanner.Float:
		re := sign + p.lit
		p.next()

		var im string
		switch p.tok {
		case '+':
			p.next()
			im = p.expect(scanner.Float)

		case '-':
			p.next()
			im = "-" + p.expect(scanner.Float)

		case scanner.Ident:
			// re is in fact the imaginary component. Expect "i" below.
			im = re
			re = "0"

		default:
			val = constant.MakeFromLiteral(re, token.FLOAT, 0)
			if val == nil {
				p.error("could not parse float literal")
			}
			typ = types.Typ[types.UntypedFloat]
			return
		}

		p.expectKeyword("i")
		reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
		if reval == nil {
			p.error("could not parse real component of complex literal")
		}
		imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
		if imval == nil {
			p.error("could not parse imag component of complex literal")
		}
		val = constant.BinaryOp(reval, token.ADD, imval)
		typ = types.Typ[types.UntypedComplex]

	default:
		p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
	}

	return
}

// Const = Name [Type] "=" ConstValue .
func (p *parser) parseConst(pkg *types.Package) *types.Const {
	name := p.parseName()
	var typ types.Type
	if p.tok == '<' {
		typ = p.parseType(pkg)
	}
	p.expect('=')
	val, vtyp := p.parseConstValue(pkg)
	if typ == nil {
		typ = vtyp
	}
	return types.NewConst(token.NoPos, pkg, name, typ, val)
}

// reserved is a singleton type used to fill type map slots that have
// been reserved (i.e., for which a type number has been parsed) but
// which don't have their actual type yet. When the type map is updated,
// the actual type must replace a reserved entry (or we have an internal
// error). Used for self-verification only - not required for correctness.
var reserved = new(struct{ types.Type })

// reserve reserves the type map entry n for future use.
func (p *parser) reserve(n int) {
	// Notes:
	// - for pre-V3 export data, the type numbers we see are
	//   guaranteed to be in increasing order, so we append a
	//   reserved entry onto the list.
	// - for V3+ export data, type numbers can appear in
	//   any order, however the 'types' section tells us the
	//   total number of types, hence typeList is pre-allocated.
	if len(p.typeData) == 0 {
		if n != len(p.typeList) {
			p.errorf("invalid type number %d (out of sync)", n)
		}
		p.typeList = append(p.typeList, reserved)
	} else {
		if p.typeList[n] != nil {
			p.errorf("previously visited type number %d", n)
		}
		p.typeList[n] = reserved
	}
}

// update sets the type map entries for the entries in nlist to t.
// An entry in nlist can be a type number in p.typeList,
// used to resolve named types, or it can be a *types.Pointer,
// used to resolve pointers to named types in case they are referenced
// by embedded fields.
func (p *parser) update(t types.Type, nlist []interface{}) {
	if t == reserved {
		p.errorf("internal error: update(%v) invoked on reserved", nlist)
	}
	if t == nil {
		p.errorf("internal error: update(%v) invoked on nil", nlist)
	}
	for _, n := range nlist {
		switch n := n.(type) {
		case int:
			if p.typeList[n] == t {
				continue
			}
			if p.typeList[n] != reserved {
				p.errorf("internal error: update(%v): %d not reserved", nlist, n)
			}
			p.typeList[n] = t
		case *types.Pointer:
			if *n != (types.Pointer{}) {
				elem := n.Elem()
				if elem == t {
					continue
				}
				p.errorf("internal error: update: pointer already set to %v, expected %v", elem, t)
			}
			*n = *types.NewPointer(t)
		default:
			p.errorf("internal error: %T on nlist", n)
		}
	}
}

// NamedType = TypeName [ "=" ] Type { Method } .
// TypeName  = ExportedName .
// Method    = "func" "(" Param ")" Name ParamList ResultList [InlineBody] ";" .
func (p *parser) parseNamedType(nlist []interface{}) types.Type {
	pkg, name := p.parseExportedName()
	scope := pkg.Scope()
	obj := scope.Lookup(name)
	if obj != nil && obj.Type() == nil {
		p.errorf("%v has nil type", obj)
	}

	// type alias
	if p.tok == '=' {
		p.next()
		p.aliases[nlist[len(nlist)-1].(int)] = name
		if obj != nil {
			// use the previously imported (canonical) type
			t := obj.Type()
			p.update(t, nlist)
			p.parseType(pkg) // discard
			return t
		}
		t := p.parseType(pkg, nlist...)
		obj = types.NewTypeName(token.NoPos, pkg, name, t)
		scope.Insert(obj)
		return t
	}

	// defined type
	if obj == nil {
		// A named type may be referred to before the underlying type
		// is known - set it up.
		tname := types.NewTypeName(token.NoPos, pkg, name, nil)
		types.NewNamed(tname, nil, nil)
		scope.Insert(tname)
		obj = tname
	}

	// use the previously imported (canonical), or newly created type
	t := obj.Type()
	p.update(t, nlist)

	nt, ok := t.(*types.Named)
	if !ok {
		// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
		pt := p.parseType(pkg)
		if pt != t {
			p.error("unexpected underlying type for non-named TypeName")
		}
		return t
	}

	underlying := p.parseType(pkg)
	if nt.Underlying() == nil {
		if underlying.Underlying() == nil {
			fix := fixupRecord{toUpdate: nt, target: underlying}
			p.fixups = append(p.fixups, fix)
		} else {
			nt.SetUnderlying(underlying.Underlying())
		}
	}

	if p.tok == '\n' {
		p.next()
		// collect associated methods
		for p.tok == scanner.Ident {
			p.expectKeyword("func")
			if p.tok == '/' {
				// Skip a /*nointerface*/ or /*asm ID */ comment.
				p.expect('/')
				p.expect('*')
				if p.expect(scanner.Ident) == "asm" {
					p.parseUnquotedString()
				}
				p.expect('*')
				p.expect('/')
			}
			p.expect('(')
			receiver, _ := p.parseParam(pkg)
			p.expect(')')
			name := p.parseName()
			params, isVariadic := p.parseParamList(pkg)
			results := p.parseResultList(pkg)
			p.skipInlineBody()
			p.expectEOL()

			sig := types.NewSignature(receiver, params, results, isVariadic)
			nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
		}
	}

	return nt
}

func (p *parser) parseInt64() int64 {
	lit := p.expect(scanner.Int)
	n, err := strconv.ParseInt(lit, 10, 64)
	if err != nil {
		p.error(err)
	}
	return n
}

func (p *parser) parseInt() int {
	lit := p.expect(scanner.Int)
	n, err := strconv.ParseInt(lit, 10, 0 /* int */)
	if err != nil {
		p.error(err)
	}
	return int(n)
}

// ArrayOrSliceType = "[" [ int ] "]" Type .
func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []interface{}) types.Type {
	p.expect('[')
	if p.tok == ']' {
		p.next()

		t := new(types.Slice)
		p.update(t, nlist)

		*t = *types.NewSlice(p.parseType(pkg))
		return t
	}

	t := new(types.Array)
	p.update(t, nlist)

	len := p.parseInt64()
	p.expect(']')

	*t = *types.NewArray(p.parseType(pkg), len)
	return t
}

// MapType = "map" "[" Type "]" Type .
func (p *parser) parseMapType(pkg *types.Package, nlist []interface{}) types.Type {
	p.expectKeyword("map")

	t := new(types.Map)
	p.update(t, nlist)

	p.expect('[')
	key := p.parseType(pkg)
	p.expect(']')
	elem := p.parseType(pkg)

	*t = *types.NewMap(key, elem)
	return t
}

// ChanType = "chan" ["<-" | "-<"] Type .
func (p *parser) parseChanType(pkg *types.Package, nlist []interface{}) types.Type {
	p.expectKeyword("chan")

	t := new(types.Chan)
	p.update(t, nlist)

	dir := types.SendRecv
	switch p.tok {
	case '-':
		p.next()
		p.expect('<')
		dir = types.SendOnly

	case '<':
		// don't consume '<' if it belongs to Type
		if p.scanner.Peek() == '-' {
			p.next()
			p.expect('-')
			dir = types.RecvOnly
		}
	}

	*t = *types.NewChan(dir, p.parseType(pkg))
	return t
}

// StructType = "struct" "{" { Field } "}" .
func (p *parser) parseStructType(pkg *types.Package, nlist []interface{}) types.Type {
	p.expectKeyword("struct")

	t := new(types.Struct)
	p.update(t, nlist)

	var fields []*types.Var
	var tags []string

	p.expect('{')
	for p.tok != '}' && p.tok != scanner.EOF {
		field, tag := p.parseField(pkg)
		p.expect(';')
		fields = append(fields, field)
		tags = append(tags, tag)
	}
	p.expect('}')

	*t = *types.NewStruct(fields, tags)
	return t
}

// ParamList = "(" [ { Parameter "," } Parameter ] ")" .
func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
	var list []*types.Var
	isVariadic := false

	p.expect('(')
	for p.tok != ')' && p.tok != scanner.EOF {
		if len(list) > 0 {
			p.expect(',')
		}
		par, variadic := p.parseParam(pkg)
		list = append(list, par)
		if variadic {
			if isVariadic {
				p.error("... not on final argument")
			}
			isVariadic = true
		}
	}
	p.expect(')')

	return types.NewTuple(list...), isVariadic
}

// ResultList = Type | ParamList .
func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
	switch p.tok {
	case '<':
		p.next()
		if p.tok == scanner.Ident && p.lit == "inl" {
			return nil
		}
		taa, _ := p.parseTypeAfterAngle(pkg)
		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", taa))

	case '(':
		params, _ := p.parseParamList(pkg)
		return params

	default:
		return nil
	}
}

// FunctionType = ParamList ResultList .
func (p *parser) parseFunctionType(pkg *types.Package, nlist []interface{}) *types.Signature {
	t := new(types.Signature)
	p.update(t, nlist)

	params, isVariadic := p.parseParamList(pkg)
	results := p.parseResultList(pkg)

	*t = *types.NewSignature(nil, params, results, isVariadic)
	return t
}

// Func = Name FunctionType [InlineBody] .
func (p *parser) parseFunc(pkg *types.Package) *types.Func {
	if p.tok == '/' {
		// Skip an /*asm ID */ comment.
		p.expect('/')
		p.expect('*')
		if p.expect(scanner.Ident) == "asm" {
			p.parseUnquotedString()
		}
		p.expect('*')
		p.expect('/')
	}

	name := p.parseName()
	f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
	p.skipInlineBody()

	if name[0] == '.' || name[0] == '<' || strings.ContainsRune(name, '$') {
		// This is an unexported function,
		// or a function defined in a different package,
		// or a type$equal or type$hash function.
		// We only want to record exported functions.
		return nil
	}

	return f
}

// InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
func (p *parser) parseInterfaceType(pkg *types.Package, nlist []interface{}) types.Type {
	p.expectKeyword("interface")

	t := new(types.Interface)
	p.update(t, nlist)

	var methods []*types.Func
	var embeddeds []types.Type

	p.expect('{')
	for p.tok != '}' && p.tok != scanner.EOF {
		if p.tok == '?' {
			p.next()
			embeddeds = append(embeddeds, p.parseType(pkg))
		} else {
			method := p.parseFunc(pkg)
			if method != nil {
				methods = append(methods, method)
			}
		}
		p.expect(';')
	}
	p.expect('}')

	*t = *newInterface(methods, embeddeds)
	return t
}

// PointerType = "*" ("any" | Type) .
func (p *parser) parsePointerType(pkg *types.Package, nlist []interface{}) types.Type {
	p.expect('*')
	if p.tok == scanner.Ident {
		p.expectKeyword("any")
		t := types.Typ[types.UnsafePointer]
		p.update(t, nlist)
		return t
	}

	t := new(types.Pointer)
	p.update(t, nlist)

	*t = *types.NewPointer(p.parseType(pkg, t))

	return t
}

// TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
func (p *parser) parseTypeSpec(pkg *types.Package, nlist []interface{}) types.Type {
	switch p.tok {
	case scanner.String:
		return p.parseNamedType(nlist)

	case scanner.Ident:
		switch p.lit {
		case "map":
			return p.parseMapType(pkg, nlist)

		case "chan":
			return p.parseChanType(pkg, nlist)

		case "struct":
			return p.parseStructType(pkg, nlist)

		case "interface":
			return p.parseInterfaceType(pkg, nlist)
		}

	case '*':
		return p.parsePointerType(pkg, nlist)

	case '[':
		return p.parseArrayOrSliceType(pkg, nlist)

	case '(':
		return p.parseFunctionType(pkg, nlist)
	}

	p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
	return nil
}

const (
	// From gofrontend/go/export.h
	// Note that these values are negative in the gofrontend and have been made positive
	// in the gccgoimporter.
	gccgoBuiltinINT8       = 1
	gccgoBuiltinINT16      = 2
	gccgoBuiltinINT32      = 3
	gccgoBuiltinINT64      = 4
	gccgoBuiltinUINT8      = 5
	gccgoBuiltinUINT16     = 6
	gccgoBuiltinUINT32     = 7
	gccgoBuiltinUINT64     = 8
	gccgoBuiltinFLOAT32    = 9
	gccgoBuiltinFLOAT64    = 10
	gccgoBuiltinINT        = 11
	gccgoBuiltinUINT       = 12
	gccgoBuiltinUINTPTR    = 13
	gccgoBuiltinBOOL       = 15
	gccgoBuiltinSTRING     = 16
	gccgoBuiltinCOMPLEX64  = 17
	gccgoBuiltinCOMPLEX128 = 18
	gccgoBuiltinERROR      = 19
	gccgoBuiltinBYTE       = 20
	gccgoBuiltinRUNE       = 21
)

func lookupBuiltinType(typ int) types.Type {
	return [...]types.Type{
		gccgoBuiltinINT8:       types.Typ[types.Int8],
		gccgoBuiltinINT16:      types.Typ[types.Int16],
		gccgoBuiltinINT32:      types.Typ[types.Int32],
		gccgoBuiltinINT64:      types.Typ[types.Int64],
		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
		gccgoBuiltinINT:        types.Typ[types.Int],
		gccgoBuiltinUINT:       types.Typ[types.Uint],
		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
		gccgoBuiltinBOOL:       types.Typ[types.Bool],
		gccgoBuiltinSTRING:     types.Typ[types.String],
		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
	}[typ]
}

// Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
//
// parseType updates the type map to t for all type numbers n.
//
func (p *parser) parseType(pkg *types.Package, n ...interface{}) types.Type {
	p.expect('<')
	t, _ := p.parseTypeAfterAngle(pkg, n...)
	return t
}

// (*parser).Type after reading the "<".
func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
	p.expectKeyword("type")

	n1 = 0
	switch p.tok {
	case scanner.Int:
		n1 = p.parseInt()
		if p.tok == '>' {
			if len(p.typeData) > 0 && p.typeList[n1] == nil {
				p.parseSavedType(pkg, n1, n)
			}
			t = p.typeList[n1]
			if len(p.typeData) == 0 && t == reserved {
				p.errorf("invalid type cycle, type %d not yet defined (nlist=%v)", n1, n)
			}
			p.update(t, n)
		} else {
			p.reserve(n1)
			t = p.parseTypeSpec(pkg, append(n, n1))
		}

	case '-':
		p.next()
		n1 := p.parseInt()
		t = lookupBuiltinType(n1)
		p.update(t, n)

	default:
		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
		return nil, 0
	}

	if t == nil || t == reserved {
		p.errorf("internal error: bad return from parseType(%v)", n)
	}

	p.expect('>')
	return
}

// parseTypeExtended is identical to parseType, but if the type in
// question is a saved type, returns the index as well as the type
// pointer (index returned is zero if we parsed a builtin).
func (p *parser) parseTypeExtended(pkg *types.Package, n ...interface{}) (t types.Type, n1 int) {
	p.expect('<')
	t, n1 = p.parseTypeAfterAngle(pkg, n...)
	return
}

// InlineBody = "<inl:NN>" .{NN}
// Reports whether a body was skipped.
func (p *parser) skipInlineBody() {
	// We may or may not have seen the '<' already, depending on
	// whether the function had a result type or not.
	if p.tok == '<' {
		p.next()
		p.expectKeyword("inl")
	} else if p.tok != scanner.Ident || p.lit != "inl" {
		return
	} else {
		p.next()
	}

	p.expect(':')
	want := p.parseInt()
	p.expect('>')

	defer func(w uint64) {
		p.scanner.Whitespace = w
	}(p.scanner.Whitespace)
	p.scanner.Whitespace = 0

	got := 0
	for got < want {
		r := p.scanner.Next()
		if r == scanner.EOF {
			p.error("unexpected EOF")
		}
		got += utf8.RuneLen(r)
	}
}

// Types = "types" maxp1 exportedp1 (offset length)* .
func (p *parser) parseTypes(pkg *types.Package) {
	maxp1 := p.parseInt()
	exportedp1 := p.parseInt()
	p.typeList = make([]types.Type, maxp1, maxp1)

	type typeOffset struct {
		offset int
		length int
	}
	var typeOffsets []typeOffset

	total := 0
	for i := 1; i < maxp1; i++ {
		len := p.parseInt()
		typeOffsets = append(typeOffsets, typeOffset{total, len})
		total += len
	}

	defer func(w uint64) {
		p.scanner.Whitespace = w
	}(p.scanner.Whitespace)
	p.scanner.Whitespace = 0

	// We should now have p.tok pointing to the final newline.
	// The next runes from the scanner should be the type data.

	var sb strings.Builder
	for sb.Len() < total {
		r := p.scanner.Next()
		if r == scanner.EOF {
			p.error("unexpected EOF")
		}
		sb.WriteRune(r)
	}
	allTypeData := sb.String()

	p.typeData = []string{""} // type 0, unused
	for _, to := range typeOffsets {
		p.typeData = append(p.typeData, allTypeData[to.offset:to.offset+to.length])
	}

	for i := 1; i < int(exportedp1); i++ {
		p.parseSavedType(pkg, i, nil)
	}
}

// parseSavedType parses one saved type definition.
func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []interface{}) {
	defer func(s *scanner.Scanner, tok rune, lit string) {
		p.scanner = s
		p.tok = tok
		p.lit = lit
	}(p.scanner, p.tok, p.lit)

	p.scanner = new(scanner.Scanner)
	p.initScanner(p.scanner.Filename, strings.NewReader(p.typeData[i]))
	p.expectKeyword("type")
	id := p.parseInt()
	if id != i {
		p.errorf("type ID mismatch: got %d, want %d", id, i)
	}
	if p.typeList[i] == reserved {
		p.errorf("internal error: %d already reserved in parseSavedType", i)
	}
	if p.typeList[i] == nil {
		p.reserve(i)
		p.parseTypeSpec(pkg, append(nlist, i))
	}
	if p.typeList[i] == nil || p.typeList[i] == reserved {
		p.errorf("internal error: parseSavedType(%d,%v) reserved/nil", i, nlist)
	}
}

// PackageInit = unquotedString unquotedString int .
func (p *parser) parsePackageInit() PackageInit {
	name := p.parseUnquotedString()
	initfunc := p.parseUnquotedString()
	priority := -1
	if p.version == "v1" {
		priority = p.parseInt()
	}
	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
}

// Create the package if we have parsed both the package path and package name.
func (p *parser) maybeCreatePackage() {
	if p.pkgname != "" && p.pkgpath != "" {
		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
	}
}

// InitDataDirective = ( "v1" | "v2" | "v3" ) ";" |
//                     "priority" int ";" |
//                     "init" { PackageInit } ";" |
//                     "checksum" unquotedString ";" .
func (p *parser) parseInitDataDirective() {
	if p.tok != scanner.Ident {
		// unexpected token kind; panic
		p.expect(scanner.Ident)
	}

	switch p.lit {
	case "v1", "v2", "v3":
		p.version = p.lit
		p.next()
		p.expect(';')
		p.expect('\n')

	case "priority":
		p.next()
		p.initdata.Priority = p.parseInt()
		p.expectEOL()

	case "init":
		p.next()
		for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
			p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
		}
		p.expectEOL()

	case "init_graph":
		p.next()
		// The graph data is thrown away for now.
		for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
			p.parseInt64()
			p.parseInt64()
		}
		p.expectEOL()

	case "checksum":
		// Don't let the scanner try to parse the checksum as a number.
		defer func(mode uint) {
			p.scanner.Mode = mode
		}(p.scanner.Mode)
		p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
		p.next()
		p.parseUnquotedString()
		p.expectEOL()

	default:
		p.errorf("unexpected identifier: %q", p.lit)
	}
}

// Directive = InitDataDirective |
//             "package" unquotedString [ unquotedString ] [ unquotedString ] ";" |
//             "pkgpath" unquotedString ";" |
//             "prefix" unquotedString ";" |
//             "import" unquotedString unquotedString string ";" |
//             "indirectimport" unquotedString unquotedstring ";" |
//             "func" Func ";" |
//             "type" Type ";" |
//             "var" Var ";" |
//             "const" Const ";" .
func (p *parser) parseDirective() {
	if p.tok != scanner.Ident {
		// unexpected token kind; panic
		p.expect(scanner.Ident)
	}

	switch p.lit {
	case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum":
		p.parseInitDataDirective()

	case "package":
		p.next()
		p.pkgname = p.parseUnquotedString()
		p.maybeCreatePackage()
		if p.version != "v1" && p.tok != '\n' && p.tok != ';' {
			p.parseUnquotedString()
			p.parseUnquotedString()
		}
		p.expectEOL()

	case "pkgpath":
		p.next()
		p.pkgpath = p.parseUnquotedString()
		p.maybeCreatePackage()
		p.expectEOL()

	case "prefix":
		p.next()
		p.pkgpath = p.parseUnquotedString()
		p.expectEOL()

	case "import":
		p.next()
		pkgname := p.parseUnquotedString()
		pkgpath := p.parseUnquotedString()
		p.getPkg(pkgpath, pkgname)
		p.parseString()
		p.expectEOL()

	case "indirectimport":
		p.next()
		pkgname := p.parseUnquotedString()
		pkgpath := p.parseUnquotedString()
		p.getPkg(pkgpath, pkgname)
		p.expectEOL()

	case "types":
		p.next()
		p.parseTypes(p.pkg)
		p.expectEOL()

	case "func":
		p.next()
		fun := p.parseFunc(p.pkg)
		if fun != nil {
			p.pkg.Scope().Insert(fun)
		}
		p.expectEOL()

	case "type":
		p.next()
		p.parseType(p.pkg)
		p.expectEOL()

	case "var":
		p.next()
		v := p.parseVar(p.pkg)
		if v != nil {
			p.pkg.Scope().Insert(v)
		}
		p.expectEOL()

	case "const":
		p.next()
		c := p.parseConst(p.pkg)
		p.pkg.Scope().Insert(c)
		p.expectEOL()

	default:
		p.errorf("unexpected identifier: %q", p.lit)
	}
}

// Package = { Directive } .
func (p *parser) parsePackage() *types.Package {
	for p.tok != scanner.EOF {
		p.parseDirective()
	}
	for _, f := range p.fixups {
		if f.target.Underlying() == nil {
			p.errorf("internal error: fixup can't be applied, loop required")
		}
		f.toUpdate.SetUnderlying(f.target.Underlying())
	}
	p.fixups = nil
	for _, typ := range p.typeList {
		if it, ok := typ.(*types.Interface); ok {
			it.Complete()
		}
	}
	p.pkg.MarkComplete()
	return p.pkg
}
