1// Copyright 2011 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// This file is a modified copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go,
6// but it also contains the original source-based importer code for Go1.6.
7// Once we stop supporting 1.6, we can remove that code.
8
9// Package gcimporter provides various functions for reading
10// gc-generated object files that can be used to implement the
11// Importer interface defined by the Go 1.5 standard library package.
12package gcimporter // import "golang.org/x/tools/go/internal/gcimporter"
13
14import (
15	"bufio"
16	"errors"
17	"fmt"
18	"go/build"
19	"go/constant"
20	"go/token"
21	"go/types"
22	"io"
23	"io/ioutil"
24	"os"
25	"path/filepath"
26	"sort"
27	"strconv"
28	"strings"
29	"text/scanner"
30)
31
32// debugging/development support
33const debug = false
34
35var pkgExts = [...]string{".a", ".o"}
36
37// FindPkg returns the filename and unique package id for an import
38// path based on package information provided by build.Import (using
39// the build.Default build.Context). A relative srcDir is interpreted
40// relative to the current working directory.
41// If no file was found, an empty filename is returned.
42//
43func FindPkg(path, srcDir string) (filename, id string) {
44	if path == "" {
45		return
46	}
47
48	var noext string
49	switch {
50	default:
51		// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
52		// Don't require the source files to be present.
53		if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
54			srcDir = abs
55		}
56		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
57		if bp.PkgObj == "" {
58			id = path // make sure we have an id to print in error message
59			return
60		}
61		noext = strings.TrimSuffix(bp.PkgObj, ".a")
62		id = bp.ImportPath
63
64	case build.IsLocalImport(path):
65		// "./x" -> "/this/directory/x.ext", "/this/directory/x"
66		noext = filepath.Join(srcDir, path)
67		id = noext
68
69	case filepath.IsAbs(path):
70		// for completeness only - go/build.Import
71		// does not support absolute imports
72		// "/x" -> "/x.ext", "/x"
73		noext = path
74		id = path
75	}
76
77	if false { // for debugging
78		if path != id {
79			fmt.Printf("%s -> %s\n", path, id)
80		}
81	}
82
83	// try extensions
84	for _, ext := range pkgExts {
85		filename = noext + ext
86		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
87			return
88		}
89	}
90
91	filename = "" // not found
92	return
93}
94
95// ImportData imports a package by reading the gc-generated export data,
96// adds the corresponding package object to the packages map indexed by id,
97// and returns the object.
98//
99// The packages map must contains all packages already imported. The data
100// reader position must be the beginning of the export data section. The
101// filename is only used in error messages.
102//
103// If packages[id] contains the completely imported package, that package
104// can be used directly, and there is no need to call this function (but
105// there is also no harm but for extra time used).
106//
107func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) {
108	// support for parser error handling
109	defer func() {
110		switch r := recover().(type) {
111		case nil:
112			// nothing to do
113		case importError:
114			err = r
115		default:
116			panic(r) // internal error
117		}
118	}()
119
120	var p parser
121	p.init(filename, id, data, packages)
122	pkg = p.parseExport()
123
124	return
125}
126
127// Import imports a gc-generated package given its import path and srcDir, adds
128// the corresponding package object to the packages map, and returns the object.
129// The packages map must contain all packages already imported.
130//
131func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
132	var rc io.ReadCloser
133	var filename, id string
134	if lookup != nil {
135		// With custom lookup specified, assume that caller has
136		// converted path to a canonical import path for use in the map.
137		if path == "unsafe" {
138			return types.Unsafe, nil
139		}
140		id = path
141
142		// No need to re-import if the package was imported completely before.
143		if pkg = packages[id]; pkg != nil && pkg.Complete() {
144			return
145		}
146		f, err := lookup(path)
147		if err != nil {
148			return nil, err
149		}
150		rc = f
151	} else {
152		filename, id = FindPkg(path, srcDir)
153		if filename == "" {
154			if path == "unsafe" {
155				return types.Unsafe, nil
156			}
157			return nil, fmt.Errorf("can't find import: %q", id)
158		}
159
160		// no need to re-import if the package was imported completely before
161		if pkg = packages[id]; pkg != nil && pkg.Complete() {
162			return
163		}
164
165		// open file
166		f, err := os.Open(filename)
167		if err != nil {
168			return nil, err
169		}
170		defer func() {
171			if err != nil {
172				// add file name to error
173				err = fmt.Errorf("%s: %v", filename, err)
174			}
175		}()
176		rc = f
177	}
178	defer rc.Close()
179
180	var hdr string
181	buf := bufio.NewReader(rc)
182	if hdr, err = FindExportData(buf); err != nil {
183		return
184	}
185
186	switch hdr {
187	case "$$\n":
188		// Work-around if we don't have a filename; happens only if lookup != nil.
189		// Either way, the filename is only needed for importer error messages, so
190		// this is fine.
191		if filename == "" {
192			filename = path
193		}
194		return ImportData(packages, filename, id, buf)
195
196	case "$$B\n":
197		var data []byte
198		data, err = ioutil.ReadAll(buf)
199		if err != nil {
200			break
201		}
202
203		// TODO(gri): allow clients of go/importer to provide a FileSet.
204		// Or, define a new standard go/types/gcexportdata package.
205		fset := token.NewFileSet()
206
207		// The indexed export format starts with an 'i'; the older
208		// binary export format starts with a 'c', 'd', or 'v'
209		// (from "version"). Select appropriate importer.
210		if len(data) > 0 && data[0] == 'i' {
211			_, pkg, err = IImportData(fset, packages, data[1:], id)
212		} else {
213			_, pkg, err = BImportData(fset, packages, data, id)
214		}
215
216	default:
217		err = fmt.Errorf("unknown export data header: %q", hdr)
218	}
219
220	return
221}
222
223// ----------------------------------------------------------------------------
224// Parser
225
226// TODO(gri) Imported objects don't have position information.
227//           Ideally use the debug table line info; alternatively
228//           create some fake position (or the position of the
229//           import). That way error messages referring to imported
230//           objects can print meaningful information.
231
232// parser parses the exports inside a gc compiler-produced
233// object/archive file and populates its scope with the results.
234type parser struct {
235	scanner    scanner.Scanner
236	tok        rune                      // current token
237	lit        string                    // literal string; only valid for Ident, Int, String tokens
238	id         string                    // package id of imported package
239	sharedPkgs map[string]*types.Package // package id -> package object (across importer)
240	localPkgs  map[string]*types.Package // package id -> package object (just this package)
241}
242
243func (p *parser) init(filename, id string, src io.Reader, packages map[string]*types.Package) {
244	p.scanner.Init(src)
245	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
246	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
247	p.scanner.Whitespace = 1<<'\t' | 1<<' '
248	p.scanner.Filename = filename // for good error messages
249	p.next()
250	p.id = id
251	p.sharedPkgs = packages
252	if debug {
253		// check consistency of packages map
254		for _, pkg := range packages {
255			if pkg.Name() == "" {
256				fmt.Printf("no package name for %s\n", pkg.Path())
257			}
258		}
259	}
260}
261
262func (p *parser) next() {
263	p.tok = p.scanner.Scan()
264	switch p.tok {
265	case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·':
266		p.lit = p.scanner.TokenText()
267	default:
268		p.lit = ""
269	}
270	if debug {
271		fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit)
272	}
273}
274
275func declTypeName(pkg *types.Package, name string) *types.TypeName {
276	scope := pkg.Scope()
277	if obj := scope.Lookup(name); obj != nil {
278		return obj.(*types.TypeName)
279	}
280	obj := types.NewTypeName(token.NoPos, pkg, name, nil)
281	// a named type may be referred to before the underlying type
282	// is known - set it up
283	types.NewNamed(obj, nil, nil)
284	scope.Insert(obj)
285	return obj
286}
287
288// ----------------------------------------------------------------------------
289// Error handling
290
291// Internal errors are boxed as importErrors.
292type importError struct {
293	pos scanner.Position
294	err error
295}
296
297func (e importError) Error() string {
298	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
299}
300
301func (p *parser) error(err interface{}) {
302	if s, ok := err.(string); ok {
303		err = errors.New(s)
304	}
305	// panic with a runtime.Error if err is not an error
306	panic(importError{p.scanner.Pos(), err.(error)})
307}
308
309func (p *parser) errorf(format string, args ...interface{}) {
310	p.error(fmt.Sprintf(format, args...))
311}
312
313func (p *parser) expect(tok rune) string {
314	lit := p.lit
315	if p.tok != tok {
316		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
317	}
318	p.next()
319	return lit
320}
321
322func (p *parser) expectSpecial(tok string) {
323	sep := 'x' // not white space
324	i := 0
325	for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
326		sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
327		p.next()
328		i++
329	}
330	if i < len(tok) {
331		p.errorf("expected %q, got %q", tok, tok[0:i])
332	}
333}
334
335func (p *parser) expectKeyword(keyword string) {
336	lit := p.expect(scanner.Ident)
337	if lit != keyword {
338		p.errorf("expected keyword %s, got %q", keyword, lit)
339	}
340}
341
342// ----------------------------------------------------------------------------
343// Qualified and unqualified names
344
345// PackageId = string_lit .
346//
347func (p *parser) parsePackageID() string {
348	id, err := strconv.Unquote(p.expect(scanner.String))
349	if err != nil {
350		p.error(err)
351	}
352	// id == "" stands for the imported package id
353	// (only known at time of package installation)
354	if id == "" {
355		id = p.id
356	}
357	return id
358}
359
360// PackageName = ident .
361//
362func (p *parser) parsePackageName() string {
363	return p.expect(scanner.Ident)
364}
365
366// dotIdentifier = ( ident | '·' ) { ident | int | '·' } .
367func (p *parser) parseDotIdent() string {
368	ident := ""
369	if p.tok != scanner.Int {
370		sep := 'x' // not white space
371		for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
372			ident += p.lit
373			sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
374			p.next()
375		}
376	}
377	if ident == "" {
378		p.expect(scanner.Ident) // use expect() for error handling
379	}
380	return ident
381}
382
383// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) .
384//
385func (p *parser) parseQualifiedName() (id, name string) {
386	p.expect('@')
387	id = p.parsePackageID()
388	p.expect('.')
389	// Per rev f280b8a485fd (10/2/2013), qualified names may be used for anonymous fields.
390	if p.tok == '?' {
391		p.next()
392	} else {
393		name = p.parseDotIdent()
394	}
395	return
396}
397
398// getPkg returns the package for a given id. If the package is
399// not found, create the package and add it to the p.localPkgs
400// and p.sharedPkgs maps. name is the (expected) name of the
401// package. If name == "", the package name is expected to be
402// set later via an import clause in the export data.
403//
404// id identifies a package, usually by a canonical package path like
405// "encoding/json" but possibly by a non-canonical import path like
406// "./json".
407//
408func (p *parser) getPkg(id, name string) *types.Package {
409	// package unsafe is not in the packages maps - handle explicitly
410	if id == "unsafe" {
411		return types.Unsafe
412	}
413
414	pkg := p.localPkgs[id]
415	if pkg == nil {
416		// first import of id from this package
417		pkg = p.sharedPkgs[id]
418		if pkg == nil {
419			// first import of id by this importer;
420			// add (possibly unnamed) pkg to shared packages
421			pkg = types.NewPackage(id, name)
422			p.sharedPkgs[id] = pkg
423		}
424		// add (possibly unnamed) pkg to local packages
425		if p.localPkgs == nil {
426			p.localPkgs = make(map[string]*types.Package)
427		}
428		p.localPkgs[id] = pkg
429	} else if name != "" {
430		// package exists already and we have an expected package name;
431		// make sure names match or set package name if necessary
432		if pname := pkg.Name(); pname == "" {
433			pkg.SetName(name)
434		} else if pname != name {
435			p.errorf("%s package name mismatch: %s (given) vs %s (expected)", id, pname, name)
436		}
437	}
438	return pkg
439}
440
441// parseExportedName is like parseQualifiedName, but
442// the package id is resolved to an imported *types.Package.
443//
444func (p *parser) parseExportedName() (pkg *types.Package, name string) {
445	id, name := p.parseQualifiedName()
446	pkg = p.getPkg(id, "")
447	return
448}
449
450// ----------------------------------------------------------------------------
451// Types
452
453// BasicType = identifier .
454//
455func (p *parser) parseBasicType() types.Type {
456	id := p.expect(scanner.Ident)
457	obj := types.Universe.Lookup(id)
458	if obj, ok := obj.(*types.TypeName); ok {
459		return obj.Type()
460	}
461	p.errorf("not a basic type: %s", id)
462	return nil
463}
464
465// ArrayType = "[" int_lit "]" Type .
466//
467func (p *parser) parseArrayType(parent *types.Package) types.Type {
468	// "[" already consumed and lookahead known not to be "]"
469	lit := p.expect(scanner.Int)
470	p.expect(']')
471	elem := p.parseType(parent)
472	n, err := strconv.ParseInt(lit, 10, 64)
473	if err != nil {
474		p.error(err)
475	}
476	return types.NewArray(elem, n)
477}
478
479// MapType = "map" "[" Type "]" Type .
480//
481func (p *parser) parseMapType(parent *types.Package) types.Type {
482	p.expectKeyword("map")
483	p.expect('[')
484	key := p.parseType(parent)
485	p.expect(']')
486	elem := p.parseType(parent)
487	return types.NewMap(key, elem)
488}
489
490// Name = identifier | "?" | QualifiedName .
491//
492// For unqualified and anonymous names, the returned package is the parent
493// package unless parent == nil, in which case the returned package is the
494// package being imported. (The parent package is not nil if the the name
495// is an unqualified struct field or interface method name belonging to a
496// type declared in another package.)
497//
498// For qualified names, the returned package is nil (and not created if
499// it doesn't exist yet) unless materializePkg is set (which creates an
500// unnamed package with valid package path). In the latter case, a
501// subsequent import clause is expected to provide a name for the package.
502//
503func (p *parser) parseName(parent *types.Package, materializePkg bool) (pkg *types.Package, name string) {
504	pkg = parent
505	if pkg == nil {
506		pkg = p.sharedPkgs[p.id]
507	}
508	switch p.tok {
509	case scanner.Ident:
510		name = p.lit
511		p.next()
512	case '?':
513		// anonymous
514		p.next()
515	case '@':
516		// exported name prefixed with package path
517		pkg = nil
518		var id string
519		id, name = p.parseQualifiedName()
520		if materializePkg {
521			pkg = p.getPkg(id, "")
522		}
523	default:
524		p.error("name expected")
525	}
526	return
527}
528
529func deref(typ types.Type) types.Type {
530	if p, _ := typ.(*types.Pointer); p != nil {
531		return p.Elem()
532	}
533	return typ
534}
535
536// Field = Name Type [ string_lit ] .
537//
538func (p *parser) parseField(parent *types.Package) (*types.Var, string) {
539	pkg, name := p.parseName(parent, true)
540
541	if name == "_" {
542		// Blank fields should be package-qualified because they
543		// are unexported identifiers, but gc does not qualify them.
544		// Assuming that the ident belongs to the current package
545		// causes types to change during re-exporting, leading
546		// to spurious "can't assign A to B" errors from go/types.
547		// As a workaround, pretend all blank fields belong
548		// to the same unique dummy package.
549		const blankpkg = "<_>"
550		pkg = p.getPkg(blankpkg, blankpkg)
551	}
552
553	typ := p.parseType(parent)
554	anonymous := false
555	if name == "" {
556		// anonymous field - typ must be T or *T and T must be a type name
557		switch typ := deref(typ).(type) {
558		case *types.Basic: // basic types are named types
559			pkg = nil // objects defined in Universe scope have no package
560			name = typ.Name()
561		case *types.Named:
562			name = typ.Obj().Name()
563		default:
564			p.errorf("anonymous field expected")
565		}
566		anonymous = true
567	}
568	tag := ""
569	if p.tok == scanner.String {
570		s := p.expect(scanner.String)
571		var err error
572		tag, err = strconv.Unquote(s)
573		if err != nil {
574			p.errorf("invalid struct tag %s: %s", s, err)
575		}
576	}
577	return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag
578}
579
580// StructType = "struct" "{" [ FieldList ] "}" .
581// FieldList  = Field { ";" Field } .
582//
583func (p *parser) parseStructType(parent *types.Package) types.Type {
584	var fields []*types.Var
585	var tags []string
586
587	p.expectKeyword("struct")
588	p.expect('{')
589	for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
590		if i > 0 {
591			p.expect(';')
592		}
593		fld, tag := p.parseField(parent)
594		if tag != "" && tags == nil {
595			tags = make([]string, i)
596		}
597		if tags != nil {
598			tags = append(tags, tag)
599		}
600		fields = append(fields, fld)
601	}
602	p.expect('}')
603
604	return types.NewStruct(fields, tags)
605}
606
607// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] .
608//
609func (p *parser) parseParameter() (par *types.Var, isVariadic bool) {
610	_, name := p.parseName(nil, false)
611	// remove gc-specific parameter numbering
612	if i := strings.Index(name, "·"); i >= 0 {
613		name = name[:i]
614	}
615	if p.tok == '.' {
616		p.expectSpecial("...")
617		isVariadic = true
618	}
619	typ := p.parseType(nil)
620	if isVariadic {
621		typ = types.NewSlice(typ)
622	}
623	// ignore argument tag (e.g. "noescape")
624	if p.tok == scanner.String {
625		p.next()
626	}
627	// TODO(gri) should we provide a package?
628	par = types.NewVar(token.NoPos, nil, name, typ)
629	return
630}
631
632// Parameters    = "(" [ ParameterList ] ")" .
633// ParameterList = { Parameter "," } Parameter .
634//
635func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) {
636	p.expect('(')
637	for p.tok != ')' && p.tok != scanner.EOF {
638		if len(list) > 0 {
639			p.expect(',')
640		}
641		par, variadic := p.parseParameter()
642		list = append(list, par)
643		if variadic {
644			if isVariadic {
645				p.error("... not on final argument")
646			}
647			isVariadic = true
648		}
649	}
650	p.expect(')')
651
652	return
653}
654
655// Signature = Parameters [ Result ] .
656// Result    = Type | Parameters .
657//
658func (p *parser) parseSignature(recv *types.Var) *types.Signature {
659	params, isVariadic := p.parseParameters()
660
661	// optional result type
662	var results []*types.Var
663	if p.tok == '(' {
664		var variadic bool
665		results, variadic = p.parseParameters()
666		if variadic {
667			p.error("... not permitted on result type")
668		}
669	}
670
671	return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic)
672}
673
674// InterfaceType = "interface" "{" [ MethodList ] "}" .
675// MethodList    = Method { ";" Method } .
676// Method        = Name Signature .
677//
678// The methods of embedded interfaces are always "inlined"
679// by the compiler and thus embedded interfaces are never
680// visible in the export data.
681//
682func (p *parser) parseInterfaceType(parent *types.Package) types.Type {
683	var methods []*types.Func
684
685	p.expectKeyword("interface")
686	p.expect('{')
687	for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
688		if i > 0 {
689			p.expect(';')
690		}
691		pkg, name := p.parseName(parent, true)
692		sig := p.parseSignature(nil)
693		methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig))
694	}
695	p.expect('}')
696
697	// Complete requires the type's embedded interfaces to be fully defined,
698	// but we do not define any
699	return newInterface(methods, nil).Complete()
700}
701
702// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type .
703//
704func (p *parser) parseChanType(parent *types.Package) types.Type {
705	dir := types.SendRecv
706	if p.tok == scanner.Ident {
707		p.expectKeyword("chan")
708		if p.tok == '<' {
709			p.expectSpecial("<-")
710			dir = types.SendOnly
711		}
712	} else {
713		p.expectSpecial("<-")
714		p.expectKeyword("chan")
715		dir = types.RecvOnly
716	}
717	elem := p.parseType(parent)
718	return types.NewChan(dir, elem)
719}
720
721// Type =
722//	BasicType | TypeName | ArrayType | SliceType | StructType |
723//      PointerType | FuncType | InterfaceType | MapType | ChanType |
724//      "(" Type ")" .
725//
726// BasicType   = ident .
727// TypeName    = ExportedName .
728// SliceType   = "[" "]" Type .
729// PointerType = "*" Type .
730// FuncType    = "func" Signature .
731//
732func (p *parser) parseType(parent *types.Package) types.Type {
733	switch p.tok {
734	case scanner.Ident:
735		switch p.lit {
736		default:
737			return p.parseBasicType()
738		case "struct":
739			return p.parseStructType(parent)
740		case "func":
741			// FuncType
742			p.next()
743			return p.parseSignature(nil)
744		case "interface":
745			return p.parseInterfaceType(parent)
746		case "map":
747			return p.parseMapType(parent)
748		case "chan":
749			return p.parseChanType(parent)
750		}
751	case '@':
752		// TypeName
753		pkg, name := p.parseExportedName()
754		return declTypeName(pkg, name).Type()
755	case '[':
756		p.next() // look ahead
757		if p.tok == ']' {
758			// SliceType
759			p.next()
760			return types.NewSlice(p.parseType(parent))
761		}
762		return p.parseArrayType(parent)
763	case '*':
764		// PointerType
765		p.next()
766		return types.NewPointer(p.parseType(parent))
767	case '<':
768		return p.parseChanType(parent)
769	case '(':
770		// "(" Type ")"
771		p.next()
772		typ := p.parseType(parent)
773		p.expect(')')
774		return typ
775	}
776	p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit)
777	return nil
778}
779
780// ----------------------------------------------------------------------------
781// Declarations
782
783// ImportDecl = "import" PackageName PackageId .
784//
785func (p *parser) parseImportDecl() {
786	p.expectKeyword("import")
787	name := p.parsePackageName()
788	p.getPkg(p.parsePackageID(), name)
789}
790
791// int_lit = [ "+" | "-" ] { "0" ... "9" } .
792//
793func (p *parser) parseInt() string {
794	s := ""
795	switch p.tok {
796	case '-':
797		s = "-"
798		p.next()
799	case '+':
800		p.next()
801	}
802	return s + p.expect(scanner.Int)
803}
804
805// number = int_lit [ "p" int_lit ] .
806//
807func (p *parser) parseNumber() (typ *types.Basic, val constant.Value) {
808	// mantissa
809	mant := constant.MakeFromLiteral(p.parseInt(), token.INT, 0)
810	if mant == nil {
811		panic("invalid mantissa")
812	}
813
814	if p.lit == "p" {
815		// exponent (base 2)
816		p.next()
817		exp, err := strconv.ParseInt(p.parseInt(), 10, 0)
818		if err != nil {
819			p.error(err)
820		}
821		if exp < 0 {
822			denom := constant.MakeInt64(1)
823			denom = constant.Shift(denom, token.SHL, uint(-exp))
824			typ = types.Typ[types.UntypedFloat]
825			val = constant.BinaryOp(mant, token.QUO, denom)
826			return
827		}
828		if exp > 0 {
829			mant = constant.Shift(mant, token.SHL, uint(exp))
830		}
831		typ = types.Typ[types.UntypedFloat]
832		val = mant
833		return
834	}
835
836	typ = types.Typ[types.UntypedInt]
837	val = mant
838	return
839}
840
841// ConstDecl   = "const" ExportedName [ Type ] "=" Literal .
842// Literal     = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit .
843// bool_lit    = "true" | "false" .
844// complex_lit = "(" float_lit "+" float_lit "i" ")" .
845// rune_lit    = "(" int_lit "+" int_lit ")" .
846// string_lit  = `"` { unicode_char } `"` .
847//
848func (p *parser) parseConstDecl() {
849	p.expectKeyword("const")
850	pkg, name := p.parseExportedName()
851
852	var typ0 types.Type
853	if p.tok != '=' {
854		// constant types are never structured - no need for parent type
855		typ0 = p.parseType(nil)
856	}
857
858	p.expect('=')
859	var typ types.Type
860	var val constant.Value
861	switch p.tok {
862	case scanner.Ident:
863		// bool_lit
864		if p.lit != "true" && p.lit != "false" {
865			p.error("expected true or false")
866		}
867		typ = types.Typ[types.UntypedBool]
868		val = constant.MakeBool(p.lit == "true")
869		p.next()
870
871	case '-', scanner.Int:
872		// int_lit
873		typ, val = p.parseNumber()
874
875	case '(':
876		// complex_lit or rune_lit
877		p.next()
878		if p.tok == scanner.Char {
879			p.next()
880			p.expect('+')
881			typ = types.Typ[types.UntypedRune]
882			_, val = p.parseNumber()
883			p.expect(')')
884			break
885		}
886		_, re := p.parseNumber()
887		p.expect('+')
888		_, im := p.parseNumber()
889		p.expectKeyword("i")
890		p.expect(')')
891		typ = types.Typ[types.UntypedComplex]
892		val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
893
894	case scanner.Char:
895		// rune_lit
896		typ = types.Typ[types.UntypedRune]
897		val = constant.MakeFromLiteral(p.lit, token.CHAR, 0)
898		p.next()
899
900	case scanner.String:
901		// string_lit
902		typ = types.Typ[types.UntypedString]
903		val = constant.MakeFromLiteral(p.lit, token.STRING, 0)
904		p.next()
905
906	default:
907		p.errorf("expected literal got %s", scanner.TokenString(p.tok))
908	}
909
910	if typ0 == nil {
911		typ0 = typ
912	}
913
914	pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val))
915}
916
917// TypeDecl = "type" ExportedName Type .
918//
919func (p *parser) parseTypeDecl() {
920	p.expectKeyword("type")
921	pkg, name := p.parseExportedName()
922	obj := declTypeName(pkg, name)
923
924	// The type object may have been imported before and thus already
925	// have a type associated with it. We still need to parse the type
926	// structure, but throw it away if the object already has a type.
927	// This ensures that all imports refer to the same type object for
928	// a given type declaration.
929	typ := p.parseType(pkg)
930
931	if name := obj.Type().(*types.Named); name.Underlying() == nil {
932		name.SetUnderlying(typ)
933	}
934}
935
936// VarDecl = "var" ExportedName Type .
937//
938func (p *parser) parseVarDecl() {
939	p.expectKeyword("var")
940	pkg, name := p.parseExportedName()
941	typ := p.parseType(pkg)
942	pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ))
943}
944
945// Func = Signature [ Body ] .
946// Body = "{" ... "}" .
947//
948func (p *parser) parseFunc(recv *types.Var) *types.Signature {
949	sig := p.parseSignature(recv)
950	if p.tok == '{' {
951		p.next()
952		for i := 1; i > 0; p.next() {
953			switch p.tok {
954			case '{':
955				i++
956			case '}':
957				i--
958			}
959		}
960	}
961	return sig
962}
963
964// MethodDecl = "func" Receiver Name Func .
965// Receiver   = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" .
966//
967func (p *parser) parseMethodDecl() {
968	// "func" already consumed
969	p.expect('(')
970	recv, _ := p.parseParameter() // receiver
971	p.expect(')')
972
973	// determine receiver base type object
974	base := deref(recv.Type()).(*types.Named)
975
976	// parse method name, signature, and possibly inlined body
977	_, name := p.parseName(nil, false)
978	sig := p.parseFunc(recv)
979
980	// methods always belong to the same package as the base type object
981	pkg := base.Obj().Pkg()
982
983	// add method to type unless type was imported before
984	// and method exists already
985	// TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small.
986	base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
987}
988
989// FuncDecl = "func" ExportedName Func .
990//
991func (p *parser) parseFuncDecl() {
992	// "func" already consumed
993	pkg, name := p.parseExportedName()
994	typ := p.parseFunc(nil)
995	pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ))
996}
997
998// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" .
999//
1000func (p *parser) parseDecl() {
1001	if p.tok == scanner.Ident {
1002		switch p.lit {
1003		case "import":
1004			p.parseImportDecl()
1005		case "const":
1006			p.parseConstDecl()
1007		case "type":
1008			p.parseTypeDecl()
1009		case "var":
1010			p.parseVarDecl()
1011		case "func":
1012			p.next() // look ahead
1013			if p.tok == '(' {
1014				p.parseMethodDecl()
1015			} else {
1016				p.parseFuncDecl()
1017			}
1018		}
1019	}
1020	p.expect('\n')
1021}
1022
1023// ----------------------------------------------------------------------------
1024// Export
1025
1026// Export        = "PackageClause { Decl } "$$" .
1027// PackageClause = "package" PackageName [ "safe" ] "\n" .
1028//
1029func (p *parser) parseExport() *types.Package {
1030	p.expectKeyword("package")
1031	name := p.parsePackageName()
1032	if p.tok == scanner.Ident && p.lit == "safe" {
1033		// package was compiled with -u option - ignore
1034		p.next()
1035	}
1036	p.expect('\n')
1037
1038	pkg := p.getPkg(p.id, name)
1039
1040	for p.tok != '$' && p.tok != scanner.EOF {
1041		p.parseDecl()
1042	}
1043
1044	if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' {
1045		// don't call next()/expect() since reading past the
1046		// export data may cause scanner errors (e.g. NUL chars)
1047		p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch)
1048	}
1049
1050	if n := p.scanner.ErrorCount; n != 0 {
1051		p.errorf("expected no scanner errors, got %d", n)
1052	}
1053
1054	// Record all locally referenced packages as imports.
1055	var imports []*types.Package
1056	for id, pkg2 := range p.localPkgs {
1057		if pkg2.Name() == "" {
1058			p.errorf("%s package has no name", id)
1059		}
1060		if id == p.id {
1061			continue // avoid self-edge
1062		}
1063		imports = append(imports, pkg2)
1064	}
1065	sort.Sort(byPath(imports))
1066	pkg.SetImports(imports)
1067
1068	// package was imported completely and without errors
1069	pkg.MarkComplete()
1070
1071	return pkg
1072}
1073
1074type byPath []*types.Package
1075
1076func (a byPath) Len() int           { return len(a) }
1077func (a byPath) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
1078func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
1079