github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/src/go/internal/gcimporter/bimport.go (about)

     1  // Copyright 2015 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
     6  
     7  import (
     8  	"encoding/binary"
     9  	"fmt"
    10  	"go/constant"
    11  	"go/token"
    12  	"go/types"
    13  	"sort"
    14  	"strings"
    15  	"unicode"
    16  	"unicode/utf8"
    17  )
    18  
    19  type importer struct {
    20  	imports map[string]*types.Package
    21  	data    []byte
    22  	path    string
    23  	buf     []byte // for reading strings
    24  
    25  	// object lists
    26  	strList       []string         // in order of appearance
    27  	pkgList       []*types.Package // in order of appearance
    28  	typList       []types.Type     // in order of appearance
    29  	trackAllTypes bool
    30  
    31  	// position encoding
    32  	posInfoFormat bool
    33  	prevFile      string
    34  	prevLine      int
    35  
    36  	// debugging support
    37  	debugFormat bool
    38  	read        int // bytes read
    39  }
    40  
    41  // BImportData imports a package from the serialized package data
    42  // and returns the number of bytes consumed and a reference to the package.
    43  // If data is obviously malformed, an error is returned but in
    44  // general it is not recommended to call BImportData on untrusted data.
    45  func BImportData(imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
    46  	p := importer{
    47  		imports: imports,
    48  		data:    data,
    49  		path:    path,
    50  		strList: []string{""}, // empty string is mapped to 0
    51  	}
    52  
    53  	// read low-level encoding format
    54  	switch format := p.rawByte(); format {
    55  	case 'c':
    56  		// compact format - nothing to do
    57  	case 'd':
    58  		p.debugFormat = true
    59  	default:
    60  		return p.read, nil, fmt.Errorf("invalid encoding format in export data: got %q; want 'c' or 'd'", format)
    61  	}
    62  
    63  	p.trackAllTypes = p.rawByte() == 'a'
    64  
    65  	p.posInfoFormat = p.int() != 0
    66  
    67  	// --- generic export data ---
    68  
    69  	if v := p.string(); v != "v0" {
    70  		return p.read, nil, fmt.Errorf("unknown export data version: %s", v)
    71  	}
    72  
    73  	// populate typList with predeclared "known" types
    74  	p.typList = append(p.typList, predeclared...)
    75  
    76  	// read package data
    77  	pkg := p.pkg()
    78  
    79  	// read objects of phase 1 only (see cmd/compiler/internal/gc/bexport.go)
    80  	objcount := 0
    81  	for {
    82  		tag := p.tagOrIndex()
    83  		if tag == endTag {
    84  			break
    85  		}
    86  		p.obj(tag)
    87  		objcount++
    88  	}
    89  
    90  	// self-verification
    91  	if count := p.int(); count != objcount {
    92  		panic(fmt.Sprintf("got %d objects; want %d", objcount, count))
    93  	}
    94  
    95  	// ignore compiler-specific import data
    96  
    97  	// complete interfaces
    98  	for _, typ := range p.typList {
    99  		// If we only record named types (!p.trackAllTypes),
   100  		// we must check the underlying types here. If we
   101  		// track all types, the Underlying() method call is
   102  		// not needed.
   103  		// TODO(gri) Remove if p.trackAllTypes is gone.
   104  		if it, ok := typ.Underlying().(*types.Interface); ok {
   105  			it.Complete()
   106  		}
   107  	}
   108  
   109  	// record all referenced packages as imports
   110  	list := append(([]*types.Package)(nil), p.pkgList[1:]...)
   111  	sort.Sort(byPath(list))
   112  	pkg.SetImports(list)
   113  
   114  	// package was imported completely and without errors
   115  	pkg.MarkComplete()
   116  
   117  	return p.read, pkg, nil
   118  }
   119  
   120  func (p *importer) pkg() *types.Package {
   121  	// if the package was seen before, i is its index (>= 0)
   122  	i := p.tagOrIndex()
   123  	if i >= 0 {
   124  		return p.pkgList[i]
   125  	}
   126  
   127  	// otherwise, i is the package tag (< 0)
   128  	if i != packageTag {
   129  		panic(fmt.Sprintf("unexpected package tag %d", i))
   130  	}
   131  
   132  	// read package data
   133  	name := p.string()
   134  	path := p.string()
   135  
   136  	// we should never see an empty package name
   137  	if name == "" {
   138  		panic("empty package name in import")
   139  	}
   140  
   141  	// an empty path denotes the package we are currently importing;
   142  	// it must be the first package we see
   143  	if (path == "") != (len(p.pkgList) == 0) {
   144  		panic(fmt.Sprintf("package path %q for pkg index %d", path, len(p.pkgList)))
   145  	}
   146  
   147  	// if the package was imported before, use that one; otherwise create a new one
   148  	if path == "" {
   149  		path = p.path
   150  	}
   151  	pkg := p.imports[path]
   152  	if pkg == nil {
   153  		pkg = types.NewPackage(path, name)
   154  		p.imports[path] = pkg
   155  	} else if pkg.Name() != name {
   156  		panic(fmt.Sprintf("conflicting names %s and %s for package %q", pkg.Name(), name, path))
   157  	}
   158  	p.pkgList = append(p.pkgList, pkg)
   159  
   160  	return pkg
   161  }
   162  
   163  func (p *importer) declare(obj types.Object) {
   164  	pkg := obj.Pkg()
   165  	if alt := pkg.Scope().Insert(obj); alt != nil {
   166  		// This could only trigger if we import a (non-type) object a second time.
   167  		// This should never happen because 1) we only import a package once; and
   168  		// b) we ignore compiler-specific export data which may contain functions
   169  		// whose inlined function bodies refer to other functions that were already
   170  		// imported.
   171  		// (See also the comment in cmd/compile/internal/gc/bimport.go importer.obj,
   172  		// switch case importing functions).
   173  		panic(fmt.Sprintf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", alt, obj))
   174  	}
   175  }
   176  
   177  func (p *importer) obj(tag int) {
   178  	switch tag {
   179  	case constTag:
   180  		p.pos()
   181  		pkg, name := p.qualifiedName()
   182  		typ := p.typ(nil)
   183  		val := p.value()
   184  		p.declare(types.NewConst(token.NoPos, pkg, name, typ, val))
   185  
   186  	case typeTag:
   187  		_ = p.typ(nil)
   188  
   189  	case varTag:
   190  		p.pos()
   191  		pkg, name := p.qualifiedName()
   192  		typ := p.typ(nil)
   193  		p.declare(types.NewVar(token.NoPos, pkg, name, typ))
   194  
   195  	case funcTag:
   196  		p.pos()
   197  		pkg, name := p.qualifiedName()
   198  		params, isddd := p.paramList()
   199  		result, _ := p.paramList()
   200  		sig := types.NewSignature(nil, params, result, isddd)
   201  		p.declare(types.NewFunc(token.NoPos, pkg, name, sig))
   202  
   203  	default:
   204  		panic(fmt.Sprintf("unexpected object tag %d", tag))
   205  	}
   206  }
   207  
   208  func (p *importer) pos() {
   209  	if !p.posInfoFormat {
   210  		return
   211  	}
   212  
   213  	file := p.prevFile
   214  	line := p.prevLine
   215  	if delta := p.int(); delta != 0 {
   216  		// line changed
   217  		line += delta
   218  	} else if n := p.int(); n >= 0 {
   219  		// file changed
   220  		file = p.prevFile[:n] + p.string()
   221  		p.prevFile = file
   222  		line = p.int()
   223  	}
   224  	p.prevLine = line
   225  
   226  	// TODO(gri) register new position
   227  }
   228  
   229  func (p *importer) qualifiedName() (pkg *types.Package, name string) {
   230  	name = p.string()
   231  	pkg = p.pkg()
   232  	return
   233  }
   234  
   235  func (p *importer) record(t types.Type) {
   236  	p.typList = append(p.typList, t)
   237  }
   238  
   239  // A dddSlice is a types.Type representing ...T parameters.
   240  // It only appears for parameter types and does not escape
   241  // the importer.
   242  type dddSlice struct {
   243  	elem types.Type
   244  }
   245  
   246  func (t *dddSlice) Underlying() types.Type { return t }
   247  func (t *dddSlice) String() string         { return "..." + t.elem.String() }
   248  
   249  // parent is the package which declared the type; parent == nil means
   250  // the package currently imported. The parent package is needed for
   251  // exported struct fields and interface methods which don't contain
   252  // explicit package information in the export data.
   253  func (p *importer) typ(parent *types.Package) types.Type {
   254  	// if the type was seen before, i is its index (>= 0)
   255  	i := p.tagOrIndex()
   256  	if i >= 0 {
   257  		return p.typList[i]
   258  	}
   259  
   260  	// otherwise, i is the type tag (< 0)
   261  	switch i {
   262  	case namedTag:
   263  		// read type object
   264  		p.pos()
   265  		parent, name := p.qualifiedName()
   266  		scope := parent.Scope()
   267  		obj := scope.Lookup(name)
   268  
   269  		// if the object doesn't exist yet, create and insert it
   270  		if obj == nil {
   271  			obj = types.NewTypeName(token.NoPos, parent, name, nil)
   272  			scope.Insert(obj)
   273  		}
   274  
   275  		if _, ok := obj.(*types.TypeName); !ok {
   276  			panic(fmt.Sprintf("pkg = %s, name = %s => %s", parent, name, obj))
   277  		}
   278  
   279  		// associate new named type with obj if it doesn't exist yet
   280  		t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)
   281  
   282  		// but record the existing type, if any
   283  		t := obj.Type().(*types.Named)
   284  		p.record(t)
   285  
   286  		// read underlying type
   287  		t0.SetUnderlying(p.typ(parent))
   288  
   289  		// interfaces don't have associated methods
   290  		if types.IsInterface(t0) {
   291  			return t
   292  		}
   293  
   294  		// read associated methods
   295  		for i := p.int(); i > 0; i-- {
   296  			// TODO(gri) replace this with something closer to fieldName
   297  			p.pos()
   298  			name := p.string()
   299  			if !exported(name) {
   300  				p.pkg()
   301  			}
   302  
   303  			recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
   304  			params, isddd := p.paramList()
   305  			result, _ := p.paramList()
   306  
   307  			sig := types.NewSignature(recv.At(0), params, result, isddd)
   308  			t0.AddMethod(types.NewFunc(token.NoPos, parent, name, sig))
   309  		}
   310  
   311  		return t
   312  
   313  	case arrayTag:
   314  		t := new(types.Array)
   315  		if p.trackAllTypes {
   316  			p.record(t)
   317  		}
   318  
   319  		n := p.int64()
   320  		*t = *types.NewArray(p.typ(parent), n)
   321  		return t
   322  
   323  	case sliceTag:
   324  		t := new(types.Slice)
   325  		if p.trackAllTypes {
   326  			p.record(t)
   327  		}
   328  
   329  		*t = *types.NewSlice(p.typ(parent))
   330  		return t
   331  
   332  	case dddTag:
   333  		t := new(dddSlice)
   334  		if p.trackAllTypes {
   335  			p.record(t)
   336  		}
   337  
   338  		t.elem = p.typ(parent)
   339  		return t
   340  
   341  	case structTag:
   342  		t := new(types.Struct)
   343  		if p.trackAllTypes {
   344  			p.record(t)
   345  		}
   346  
   347  		*t = *types.NewStruct(p.fieldList(parent))
   348  		return t
   349  
   350  	case pointerTag:
   351  		t := new(types.Pointer)
   352  		if p.trackAllTypes {
   353  			p.record(t)
   354  		}
   355  
   356  		*t = *types.NewPointer(p.typ(parent))
   357  		return t
   358  
   359  	case signatureTag:
   360  		t := new(types.Signature)
   361  		if p.trackAllTypes {
   362  			p.record(t)
   363  		}
   364  
   365  		params, isddd := p.paramList()
   366  		result, _ := p.paramList()
   367  		*t = *types.NewSignature(nil, params, result, isddd)
   368  		return t
   369  
   370  	case interfaceTag:
   371  		// Create a dummy entry in the type list. This is safe because we
   372  		// cannot expect the interface type to appear in a cycle, as any
   373  		// such cycle must contain a named type which would have been
   374  		// first defined earlier.
   375  		n := len(p.typList)
   376  		if p.trackAllTypes {
   377  			p.record(nil)
   378  		}
   379  
   380  		// no embedded interfaces with gc compiler
   381  		if p.int() != 0 {
   382  			panic("unexpected embedded interface")
   383  		}
   384  
   385  		t := types.NewInterface(p.methodList(parent), nil)
   386  		if p.trackAllTypes {
   387  			p.typList[n] = t
   388  		}
   389  		return t
   390  
   391  	case mapTag:
   392  		t := new(types.Map)
   393  		if p.trackAllTypes {
   394  			p.record(t)
   395  		}
   396  
   397  		key := p.typ(parent)
   398  		val := p.typ(parent)
   399  		*t = *types.NewMap(key, val)
   400  		return t
   401  
   402  	case chanTag:
   403  		t := new(types.Chan)
   404  		if p.trackAllTypes {
   405  			p.record(t)
   406  		}
   407  
   408  		var dir types.ChanDir
   409  		// tag values must match the constants in cmd/compile/internal/gc/go.go
   410  		switch d := p.int(); d {
   411  		case 1 /* Crecv */ :
   412  			dir = types.RecvOnly
   413  		case 2 /* Csend */ :
   414  			dir = types.SendOnly
   415  		case 3 /* Cboth */ :
   416  			dir = types.SendRecv
   417  		default:
   418  			panic(fmt.Sprintf("unexpected channel dir %d", d))
   419  		}
   420  		val := p.typ(parent)
   421  		*t = *types.NewChan(dir, val)
   422  		return t
   423  
   424  	default:
   425  		panic(fmt.Sprintf("unexpected type tag %d", i))
   426  	}
   427  }
   428  
   429  func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) {
   430  	if n := p.int(); n > 0 {
   431  		fields = make([]*types.Var, n)
   432  		tags = make([]string, n)
   433  		for i := range fields {
   434  			fields[i] = p.field(parent)
   435  			tags[i] = p.string()
   436  		}
   437  	}
   438  	return
   439  }
   440  
   441  func (p *importer) field(parent *types.Package) *types.Var {
   442  	p.pos()
   443  	pkg, name := p.fieldName(parent)
   444  	typ := p.typ(parent)
   445  
   446  	anonymous := false
   447  	if name == "" {
   448  		// anonymous field - typ must be T or *T and T must be a type name
   449  		switch typ := deref(typ).(type) {
   450  		case *types.Basic: // basic types are named types
   451  			pkg = nil // // objects defined in Universe scope have no package
   452  			name = typ.Name()
   453  		case *types.Named:
   454  			name = typ.Obj().Name()
   455  		default:
   456  			panic("anonymous field expected")
   457  		}
   458  		anonymous = true
   459  	}
   460  
   461  	return types.NewField(token.NoPos, pkg, name, typ, anonymous)
   462  }
   463  
   464  func (p *importer) methodList(parent *types.Package) (methods []*types.Func) {
   465  	if n := p.int(); n > 0 {
   466  		methods = make([]*types.Func, n)
   467  		for i := range methods {
   468  			methods[i] = p.method(parent)
   469  		}
   470  	}
   471  	return
   472  }
   473  
   474  func (p *importer) method(parent *types.Package) *types.Func {
   475  	p.pos()
   476  	pkg, name := p.fieldName(parent)
   477  	params, isddd := p.paramList()
   478  	result, _ := p.paramList()
   479  	sig := types.NewSignature(nil, params, result, isddd)
   480  	return types.NewFunc(token.NoPos, pkg, name, sig)
   481  }
   482  
   483  func (p *importer) fieldName(parent *types.Package) (*types.Package, string) {
   484  	pkg := parent
   485  	if pkg == nil {
   486  		// use the imported package instead
   487  		pkg = p.pkgList[0]
   488  	}
   489  	name := p.string()
   490  	if name == "" {
   491  		return pkg, "" // anonymous
   492  	}
   493  	if name == "?" || name != "_" && !exported(name) {
   494  		// explicitly qualified field
   495  		if name == "?" {
   496  			name = "" // anonymous
   497  		}
   498  		pkg = p.pkg()
   499  	}
   500  	return pkg, name
   501  }
   502  
   503  func (p *importer) paramList() (*types.Tuple, bool) {
   504  	n := p.int()
   505  	if n == 0 {
   506  		return nil, false
   507  	}
   508  	// negative length indicates unnamed parameters
   509  	named := true
   510  	if n < 0 {
   511  		n = -n
   512  		named = false
   513  	}
   514  	// n > 0
   515  	params := make([]*types.Var, n)
   516  	isddd := false
   517  	for i := range params {
   518  		params[i], isddd = p.param(named)
   519  	}
   520  	return types.NewTuple(params...), isddd
   521  }
   522  
   523  func (p *importer) param(named bool) (*types.Var, bool) {
   524  	t := p.typ(nil)
   525  	td, isddd := t.(*dddSlice)
   526  	if isddd {
   527  		t = types.NewSlice(td.elem)
   528  	}
   529  
   530  	var pkg *types.Package
   531  	var name string
   532  	if named {
   533  		name = p.string()
   534  		if name == "" {
   535  			panic("expected named parameter")
   536  		}
   537  		if name != "_" {
   538  			pkg = p.pkg()
   539  		}
   540  		if i := strings.Index(name, "ยท"); i > 0 {
   541  			name = name[:i] // cut off gc-specific parameter numbering
   542  		}
   543  	}
   544  
   545  	// read and discard compiler-specific info
   546  	p.string()
   547  
   548  	return types.NewVar(token.NoPos, pkg, name, t), isddd
   549  }
   550  
   551  func exported(name string) bool {
   552  	ch, _ := utf8.DecodeRuneInString(name)
   553  	return unicode.IsUpper(ch)
   554  }
   555  
   556  func (p *importer) value() constant.Value {
   557  	switch tag := p.tagOrIndex(); tag {
   558  	case falseTag:
   559  		return constant.MakeBool(false)
   560  	case trueTag:
   561  		return constant.MakeBool(true)
   562  	case int64Tag:
   563  		return constant.MakeInt64(p.int64())
   564  	case floatTag:
   565  		return p.float()
   566  	case complexTag:
   567  		re := p.float()
   568  		im := p.float()
   569  		return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
   570  	case stringTag:
   571  		return constant.MakeString(p.string())
   572  	default:
   573  		panic(fmt.Sprintf("unexpected value tag %d", tag))
   574  	}
   575  }
   576  
   577  func (p *importer) float() constant.Value {
   578  	sign := p.int()
   579  	if sign == 0 {
   580  		return constant.MakeInt64(0)
   581  	}
   582  
   583  	exp := p.int()
   584  	mant := []byte(p.string()) // big endian
   585  
   586  	// remove leading 0's if any
   587  	for len(mant) > 0 && mant[0] == 0 {
   588  		mant = mant[1:]
   589  	}
   590  
   591  	// convert to little endian
   592  	// TODO(gri) go/constant should have a more direct conversion function
   593  	//           (e.g., once it supports a big.Float based implementation)
   594  	for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 {
   595  		mant[i], mant[j] = mant[j], mant[i]
   596  	}
   597  
   598  	// adjust exponent (constant.MakeFromBytes creates an integer value,
   599  	// but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
   600  	exp -= len(mant) << 3
   601  	if len(mant) > 0 {
   602  		for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 {
   603  			exp++
   604  		}
   605  	}
   606  
   607  	x := constant.MakeFromBytes(mant)
   608  	switch {
   609  	case exp < 0:
   610  		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
   611  		x = constant.BinaryOp(x, token.QUO, d)
   612  	case exp > 0:
   613  		x = constant.Shift(x, token.SHL, uint(exp))
   614  	}
   615  
   616  	if sign < 0 {
   617  		x = constant.UnaryOp(token.SUB, x, 0)
   618  	}
   619  	return x
   620  }
   621  
   622  // ----------------------------------------------------------------------------
   623  // Low-level decoders
   624  
   625  func (p *importer) tagOrIndex() int {
   626  	if p.debugFormat {
   627  		p.marker('t')
   628  	}
   629  
   630  	return int(p.rawInt64())
   631  }
   632  
   633  func (p *importer) int() int {
   634  	x := p.int64()
   635  	if int64(int(x)) != x {
   636  		panic("exported integer too large")
   637  	}
   638  	return int(x)
   639  }
   640  
   641  func (p *importer) int64() int64 {
   642  	if p.debugFormat {
   643  		p.marker('i')
   644  	}
   645  
   646  	return p.rawInt64()
   647  }
   648  
   649  func (p *importer) string() string {
   650  	if p.debugFormat {
   651  		p.marker('s')
   652  	}
   653  	// if the string was seen before, i is its index (>= 0)
   654  	// (the empty string is at index 0)
   655  	i := p.rawInt64()
   656  	if i >= 0 {
   657  		return p.strList[i]
   658  	}
   659  	// otherwise, i is the negative string length (< 0)
   660  	if n := int(-i); n <= cap(p.buf) {
   661  		p.buf = p.buf[:n]
   662  	} else {
   663  		p.buf = make([]byte, n)
   664  	}
   665  	for i := range p.buf {
   666  		p.buf[i] = p.rawByte()
   667  	}
   668  	s := string(p.buf)
   669  	p.strList = append(p.strList, s)
   670  	return s
   671  }
   672  
   673  func (p *importer) marker(want byte) {
   674  	if got := p.rawByte(); got != want {
   675  		panic(fmt.Sprintf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read))
   676  	}
   677  
   678  	pos := p.read
   679  	if n := int(p.rawInt64()); n != pos {
   680  		panic(fmt.Sprintf("incorrect position: got %d; want %d", n, pos))
   681  	}
   682  }
   683  
   684  // rawInt64 should only be used by low-level decoders
   685  func (p *importer) rawInt64() int64 {
   686  	i, err := binary.ReadVarint(p)
   687  	if err != nil {
   688  		panic(fmt.Sprintf("read error: %v", err))
   689  	}
   690  	return i
   691  }
   692  
   693  // needed for binary.ReadVarint in rawInt64
   694  func (p *importer) ReadByte() (byte, error) {
   695  	return p.rawByte(), nil
   696  }
   697  
   698  // byte is the bottleneck interface for reading p.data.
   699  // It unescapes '|' 'S' to '$' and '|' '|' to '|'.
   700  // rawByte should only be used by low-level decoders.
   701  func (p *importer) rawByte() byte {
   702  	b := p.data[0]
   703  	r := 1
   704  	if b == '|' {
   705  		b = p.data[1]
   706  		r = 2
   707  		switch b {
   708  		case 'S':
   709  			b = '$'
   710  		case '|':
   711  			// nothing to do
   712  		default:
   713  			panic("unexpected escape sequence in export data")
   714  		}
   715  	}
   716  	p.data = p.data[r:]
   717  	p.read += r
   718  	return b
   719  
   720  }
   721  
   722  // ----------------------------------------------------------------------------
   723  // Export format
   724  
   725  // Tags. Must be < 0.
   726  const (
   727  	// Objects
   728  	packageTag = -(iota + 1)
   729  	constTag
   730  	typeTag
   731  	varTag
   732  	funcTag
   733  	endTag
   734  
   735  	// Types
   736  	namedTag
   737  	arrayTag
   738  	sliceTag
   739  	dddTag
   740  	structTag
   741  	pointerTag
   742  	signatureTag
   743  	interfaceTag
   744  	mapTag
   745  	chanTag
   746  
   747  	// Values
   748  	falseTag
   749  	trueTag
   750  	int64Tag
   751  	floatTag
   752  	fractionTag // not used by gc
   753  	complexTag
   754  	stringTag
   755  	unknownTag // not used by gc (only appears in packages with errors)
   756  )
   757  
   758  var predeclared = []types.Type{
   759  	// basic types
   760  	types.Typ[types.Bool],
   761  	types.Typ[types.Int],
   762  	types.Typ[types.Int8],
   763  	types.Typ[types.Int16],
   764  	types.Typ[types.Int32],
   765  	types.Typ[types.Int64],
   766  	types.Typ[types.Uint],
   767  	types.Typ[types.Uint8],
   768  	types.Typ[types.Uint16],
   769  	types.Typ[types.Uint32],
   770  	types.Typ[types.Uint64],
   771  	types.Typ[types.Uintptr],
   772  	types.Typ[types.Float32],
   773  	types.Typ[types.Float64],
   774  	types.Typ[types.Complex64],
   775  	types.Typ[types.Complex128],
   776  	types.Typ[types.String],
   777  
   778  	// aliases
   779  	types.Universe.Lookup("byte").Type(),
   780  	types.Universe.Lookup("rune").Type(),
   781  
   782  	// error
   783  	types.Universe.Lookup("error").Type(),
   784  
   785  	// untyped types
   786  	types.Typ[types.UntypedBool],
   787  	types.Typ[types.UntypedInt],
   788  	types.Typ[types.UntypedRune],
   789  	types.Typ[types.UntypedFloat],
   790  	types.Typ[types.UntypedComplex],
   791  	types.Typ[types.UntypedString],
   792  	types.Typ[types.UntypedNil],
   793  
   794  	// package unsafe
   795  	types.Typ[types.UnsafePointer],
   796  
   797  	// invalid type
   798  	types.Typ[types.Invalid], // only appears in packages with errors
   799  
   800  	// used internally by gc; never used by this package or in .a files
   801  	anyType{},
   802  }
   803  
   804  type anyType struct{}
   805  
   806  func (t anyType) Underlying() types.Type { return t }
   807  func (t anyType) String() string         { return "any" }