github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/go/internal/gcimporter/gcimporter.go (about)

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