1package main
2
3import (
4	"encoding/binary"
5	"fmt"
6	"go/ast"
7	"go/token"
8	"strconv"
9	"strings"
10	"unicode"
11	"unicode/utf8"
12)
13
14//-------------------------------------------------------------------------
15// gc_bin_parser
16//
17// The following part of the code may contain portions of the code from the Go
18// standard library, which tells me to retain their copyright notice:
19//
20// Copyright (c) 2012 The Go Authors. All rights reserved.
21//
22// Redistribution and use in source and binary forms, with or without
23// modification, are permitted provided that the following conditions are
24// met:
25//
26//    * Redistributions of source code must retain the above copyright
27// notice, this list of conditions and the following disclaimer.
28//    * Redistributions in binary form must reproduce the above
29// copyright notice, this list of conditions and the following disclaimer
30// in the documentation and/or other materials provided with the
31// distribution.
32//    * Neither the name of Google Inc. nor the names of its
33// contributors may be used to endorse or promote products derived from
34// this software without specific prior written permission.
35//
36// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
39// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
40// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47//-------------------------------------------------------------------------
48
49type gc_bin_parser struct {
50	data    []byte
51	buf     []byte // for reading strings
52	version int    // export format version
53
54	// object lists
55	strList       []string   // in order of appearance
56	pathList      []string   // in order of appearance
57	pkgList       []string   // in order of appearance
58	typList       []ast.Expr // in order of appearance
59	callback      func(pkg string, decl ast.Decl)
60	pfc           *package_file_cache
61	trackAllTypes bool
62
63	// position encoding
64	posInfoFormat bool
65	prevFile      string
66	prevLine      int
67
68	// debugging support
69	debugFormat bool
70	read        int // bytes read
71
72}
73
74func (p *gc_bin_parser) init(data []byte, pfc *package_file_cache) {
75	p.data = data
76	p.version = -1            // unknown version
77	p.strList = []string{""}  // empty string is mapped to 0
78	p.pathList = []string{""} // empty string is mapped to 0
79	p.pfc = pfc
80}
81
82func (p *gc_bin_parser) parse_export(callback func(string, ast.Decl)) {
83	p.callback = callback
84
85	// read version info
86	var versionstr string
87	if b := p.rawByte(); b == 'c' || b == 'd' {
88		// Go1.7 encoding; first byte encodes low-level
89		// encoding format (compact vs debug).
90		// For backward-compatibility only (avoid problems with
91		// old installed packages). Newly compiled packages use
92		// the extensible format string.
93		// TODO(gri) Remove this support eventually; after Go1.8.
94		if b == 'd' {
95			p.debugFormat = true
96		}
97		p.trackAllTypes = p.rawByte() == 'a'
98		p.posInfoFormat = p.int() != 0
99		versionstr = p.string()
100		if versionstr == "v1" {
101			p.version = 0
102		}
103	} else {
104		// Go1.8 extensible encoding
105		// read version string and extract version number (ignore anything after the version number)
106		versionstr = p.rawStringln(b)
107		if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
108			if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
109				p.version = v
110			}
111		}
112	}
113
114	// read version specific flags - extend as necessary
115	switch p.version {
116	// case 7:
117	// 	...
118	//	fallthrough
119	case 6, 5, 4, 3, 2, 1:
120		p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
121		p.trackAllTypes = p.int() != 0
122		p.posInfoFormat = p.int() != 0
123	case 0:
124		// Go1.7 encoding format - nothing to do here
125	default:
126		panic(fmt.Errorf("unknown export format version %d (%q)", p.version, versionstr))
127	}
128
129	// --- generic export data ---
130
131	// populate typList with predeclared "known" types
132	p.typList = append(p.typList, predeclared...)
133
134	// read package data
135	pkgName := p.pkg()
136	p.pfc.defalias = pkgName[strings.LastIndex(pkgName, "!")+1:]
137
138	// read objects of phase 1 only (see cmd/compiler/internal/gc/bexport.go)
139	objcount := 0
140	for {
141		tag := p.tagOrIndex()
142		if tag == endTag {
143			break
144		}
145		p.obj(tag)
146		objcount++
147	}
148
149	// self-verification
150	if count := p.int(); count != objcount {
151		panic(fmt.Sprintf("got %d objects; want %d", objcount, count))
152	}
153}
154
155// MaxPkgHeight is a height greater than any likely package height.
156const MaxPkgHeight = 1e9
157
158func (p *gc_bin_parser) pkg() string {
159	// if the package was seen before, i is its index (>= 0)
160	i := p.tagOrIndex()
161	if i >= 0 {
162		return p.pkgList[i]
163	}
164
165	// otherwise, i is the package tag (< 0)
166	if i != packageTag {
167		panic(fmt.Sprintf("unexpected package tag %d version %d", i, p.version))
168	}
169
170	// read package data
171	name := p.string()
172	var path string
173	if p.version >= 5 {
174		path = p.path()
175	} else {
176		path = p.string()
177	}
178	var height int
179	if p.version >= 6 {
180		height = p.int()
181	}
182
183	// we should never see an empty package name
184	if name == "" {
185		panic("empty package name in import")
186	}
187
188	// an empty path denotes the package we are currently importing;
189	// it must be the first package we see
190	if (path == "") != (len(p.pkgList) == 0) {
191		panic(fmt.Sprintf("package path %q for pkg index %d", path, len(p.pkgList)))
192	}
193
194	if p.version >= 6 {
195		if height < 0 || height >= MaxPkgHeight {
196			panic(fmt.Sprintf("bad package height %v for package %s", height, name))
197		}
198
199		// reexported packages should always have a lower height than
200		// the main package
201		// if len(p.pkgList) != 0 && height >= p.imp.Height {
202		// 	p.formatErrorf("package %q (height %d) reexports package %q (height %d)", p.imp.Path, p.imp.Height, path, height)
203		// }
204	}
205
206	var fullName string
207	if path != "" {
208		fullName = "!" + path + "!" + name
209		p.pfc.add_package_to_scope(fullName, path)
210	} else {
211		fullName = "!" + p.pfc.name + "!" + name
212	}
213
214	// if the package was imported before, use that one; otherwise create a new one
215	// pkg.Height = height
216	p.pkgList = append(p.pkgList, fullName)
217	return p.pkgList[len(p.pkgList)-1]
218}
219
220func (p *gc_bin_parser) obj(tag int) {
221	switch tag {
222	case constTag:
223		p.pos()
224		pkg, name := p.qualifiedName()
225		typ := p.typ("")
226		p.skipValue() // ignore const value, gocode's not interested
227		p.callback(pkg, &ast.GenDecl{
228			Tok: token.CONST,
229			Specs: []ast.Spec{
230				&ast.ValueSpec{
231					Names:  []*ast.Ident{ast.NewIdent(name)},
232					Type:   typ,
233					Values: []ast.Expr{&ast.BasicLit{Kind: token.INT, Value: "0"}},
234				},
235			},
236		})
237
238	case aliasTag:
239		// TODO(gri) verify type alias hookup is correct
240		p.pos()
241		pkg, name := p.qualifiedName()
242		typ := p.typ("")
243		p.callback(pkg, &ast.GenDecl{
244			Tok:   token.TYPE,
245			Specs: []ast.Spec{typeAliasSpec(name, typ)},
246		})
247
248	case typeTag:
249		_ = p.typ("")
250
251	case varTag:
252		p.pos()
253		pkg, name := p.qualifiedName()
254		typ := p.typ("")
255		p.callback(pkg, &ast.GenDecl{
256			Tok: token.VAR,
257			Specs: []ast.Spec{
258				&ast.ValueSpec{
259					Names: []*ast.Ident{ast.NewIdent(name)},
260					Type:  typ,
261				},
262			},
263		})
264
265	case funcTag:
266		p.pos()
267		pkg, name := p.qualifiedName()
268		params := p.paramList()
269		results := p.paramList()
270		p.callback(pkg, &ast.FuncDecl{
271			Name: ast.NewIdent(name),
272			Type: &ast.FuncType{Params: params, Results: results},
273		})
274
275	default:
276		panic(fmt.Sprintf("unexpected object tag %d", tag))
277	}
278}
279
280const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
281
282func (p *gc_bin_parser) pos() {
283	if !p.posInfoFormat {
284		return
285	}
286
287	file := p.prevFile
288	line := p.prevLine
289	delta := p.int()
290	line += delta
291	if p.version >= 5 {
292		if delta == deltaNewFile {
293			if n := p.int(); n >= 0 {
294				// file changed
295				file = p.path()
296				line = n
297			}
298		}
299	} else {
300		if delta == 0 {
301			if n := p.int(); n >= 0 {
302				// file changed
303				file = p.prevFile[:n] + p.string()
304				line = p.int()
305			}
306		}
307	}
308	p.prevFile = file
309	p.prevLine = line
310
311	// TODO(gri) register new position
312}
313
314func (p *gc_bin_parser) qualifiedName() (pkg string, name string) {
315	name = p.string()
316	pkg = p.pkg()
317	return pkg, name
318}
319
320func (p *gc_bin_parser) reserveMaybe() int {
321	if p.trackAllTypes {
322		p.typList = append(p.typList, nil)
323		return len(p.typList) - 1
324	} else {
325		return -1
326	}
327}
328
329func (p *gc_bin_parser) recordMaybe(idx int, t ast.Expr) ast.Expr {
330	if idx == -1 {
331		return t
332	}
333	p.typList[idx] = t
334	return t
335}
336
337func (p *gc_bin_parser) record(t ast.Expr) {
338	p.typList = append(p.typList, t)
339}
340
341// parent is the package which declared the type; parent == nil means
342// the package currently imported. The parent package is needed for
343// exported struct fields and interface methods which don't contain
344// explicit package information in the export data.
345func (p *gc_bin_parser) typ(parent string) ast.Expr {
346	// if the type was seen before, i is its index (>= 0)
347	i := p.tagOrIndex()
348	if i >= 0 {
349		return p.typList[i]
350	}
351
352	// otherwise, i is the type tag (< 0)
353	switch i {
354	case namedTag:
355		// read type object
356		p.pos()
357		parent, name := p.qualifiedName()
358		tdecl := &ast.GenDecl{
359			Tok: token.TYPE,
360			Specs: []ast.Spec{
361				&ast.TypeSpec{
362					Name: ast.NewIdent(name),
363				},
364			},
365		}
366
367		// record it right away (underlying type can contain refs to t)
368		t := &ast.SelectorExpr{X: ast.NewIdent(parent), Sel: ast.NewIdent(name)}
369		p.record(t)
370
371		// parse underlying type
372		t0 := p.typ(parent)
373		tdecl.Specs[0].(*ast.TypeSpec).Type = t0
374
375		p.callback(parent, tdecl)
376
377		// interfaces have no methods
378		if _, ok := t0.(*ast.InterfaceType); ok {
379			return t
380		}
381
382		// read associated methods
383		for i := p.int(); i > 0; i-- {
384			// TODO(gri) replace this with something closer to fieldName
385			p.pos()
386			name := p.string()
387			if !exported(name) {
388				p.pkg()
389			}
390
391			recv := p.paramList()
392			params := p.paramList()
393			results := p.paramList()
394			p.int() // go:nointerface pragma - discarded
395
396			strip_method_receiver(recv)
397			p.callback(parent, &ast.FuncDecl{
398				Recv: recv,
399				Name: ast.NewIdent(name),
400				Type: &ast.FuncType{Params: params, Results: results},
401			})
402		}
403		return t
404	case arrayTag:
405		i := p.reserveMaybe()
406		n := p.int64()
407		elt := p.typ(parent)
408		return p.recordMaybe(i, &ast.ArrayType{
409			Len: &ast.BasicLit{Kind: token.INT, Value: fmt.Sprint(n)},
410			Elt: elt,
411		})
412
413	case sliceTag:
414		i := p.reserveMaybe()
415		elt := p.typ(parent)
416		return p.recordMaybe(i, &ast.ArrayType{Len: nil, Elt: elt})
417
418	case dddTag:
419		i := p.reserveMaybe()
420		elt := p.typ(parent)
421		return p.recordMaybe(i, &ast.Ellipsis{Elt: elt})
422
423	case structTag:
424		i := p.reserveMaybe()
425		return p.recordMaybe(i, p.structType(parent))
426
427	case pointerTag:
428		i := p.reserveMaybe()
429		elt := p.typ(parent)
430		return p.recordMaybe(i, &ast.StarExpr{X: elt})
431
432	case signatureTag:
433		i := p.reserveMaybe()
434		params := p.paramList()
435		results := p.paramList()
436		return p.recordMaybe(i, &ast.FuncType{Params: params, Results: results})
437
438	case interfaceTag:
439		i := p.reserveMaybe()
440		var embeddeds []*ast.SelectorExpr
441		for n := p.int(); n > 0; n-- {
442			p.pos()
443			if named, ok := p.typ(parent).(*ast.SelectorExpr); ok {
444				embeddeds = append(embeddeds, named)
445			}
446		}
447		methods := p.methodList(parent)
448		for _, field := range embeddeds {
449			methods = append(methods, &ast.Field{Type: field})
450		}
451		return p.recordMaybe(i, &ast.InterfaceType{Methods: &ast.FieldList{List: methods}})
452
453	case mapTag:
454		i := p.reserveMaybe()
455		key := p.typ(parent)
456		val := p.typ(parent)
457		return p.recordMaybe(i, &ast.MapType{Key: key, Value: val})
458
459	case chanTag:
460		i := p.reserveMaybe()
461		dir := ast.SEND | ast.RECV
462		switch d := p.int(); d {
463		case 1:
464			dir = ast.RECV
465		case 2:
466			dir = ast.SEND
467		case 3:
468			// already set
469		default:
470			panic(fmt.Sprintf("unexpected channel dir %d", d))
471		}
472		elt := p.typ(parent)
473		return p.recordMaybe(i, &ast.ChanType{Dir: dir, Value: elt})
474
475	default:
476		panic(fmt.Sprintf("unexpected type tag %d", i))
477	}
478}
479
480func (p *gc_bin_parser) structType(parent string) *ast.StructType {
481	var fields []*ast.Field
482	if n := p.int(); n > 0 {
483		fields = make([]*ast.Field, n)
484		for i := range fields {
485			fields[i], _ = p.field(parent) // (*ast.Field, tag), not interested in tags
486		}
487	}
488	return &ast.StructType{Fields: &ast.FieldList{List: fields}}
489}
490
491func (p *gc_bin_parser) field(parent string) (*ast.Field, string) {
492	p.pos()
493	_, name, _ := p.fieldName(parent)
494	typ := p.typ(parent)
495	tag := p.string()
496
497	var names []*ast.Ident
498	if name != "" {
499		names = []*ast.Ident{ast.NewIdent(name)}
500	}
501	return &ast.Field{
502		Names: names,
503		Type:  typ,
504	}, tag
505}
506
507func (p *gc_bin_parser) methodList(parent string) (methods []*ast.Field) {
508	if n := p.int(); n > 0 {
509		methods = make([]*ast.Field, n)
510		for i := range methods {
511			methods[i] = p.method(parent)
512		}
513	}
514	return
515}
516
517func (p *gc_bin_parser) method(parent string) *ast.Field {
518	p.pos()
519	_, name, _ := p.fieldName(parent)
520	params := p.paramList()
521	results := p.paramList()
522	return &ast.Field{
523		Names: []*ast.Ident{ast.NewIdent(name)},
524		Type:  &ast.FuncType{Params: params, Results: results},
525	}
526}
527
528func (p *gc_bin_parser) fieldName(parent string) (string, string, bool) {
529	name := p.string()
530	pkg := parent
531	if p.version == 0 && name == "_" {
532		// version 0 didn't export a package for _ fields
533		return pkg, name, false
534	}
535	var alias bool
536	switch name {
537	case "":
538		// 1) field name matches base type name and is exported: nothing to do
539	case "?":
540		// 2) field name matches base type name and is not exported: need package
541		name = ""
542		pkg = p.pkg()
543	case "@":
544		// 3) field name doesn't match type name (alias)
545		name = p.string()
546		alias = true
547		fallthrough
548	default:
549		if !exported(name) {
550			pkg = p.pkg()
551		}
552	}
553	return pkg, name, alias
554}
555
556func (p *gc_bin_parser) paramList() *ast.FieldList {
557	n := p.int()
558	if n == 0 {
559		return nil
560	}
561	// negative length indicates unnamed parameters
562	named := true
563	if n < 0 {
564		n = -n
565		named = false
566	}
567	// n > 0
568	flds := make([]*ast.Field, n)
569	for i := range flds {
570		flds[i] = p.param(named)
571	}
572	return &ast.FieldList{List: flds}
573}
574
575func (p *gc_bin_parser) param(named bool) *ast.Field {
576	t := p.typ("")
577
578	name := "?"
579	if named {
580		name = p.string()
581		if name == "" {
582			panic("expected named parameter")
583		}
584		if name != "_" {
585			p.pkg()
586		}
587		if i := strings.Index(name, "·"); i > 0 {
588			name = name[:i] // cut off gc-specific parameter numbering
589		}
590	}
591
592	// read and discard compiler-specific info
593	p.string()
594
595	return &ast.Field{
596		Names: []*ast.Ident{ast.NewIdent(name)},
597		Type:  t,
598	}
599}
600
601func exported(name string) bool {
602	ch, _ := utf8.DecodeRuneInString(name)
603	return unicode.IsUpper(ch)
604}
605
606func (p *gc_bin_parser) skipValue() {
607	switch tag := p.tagOrIndex(); tag {
608	case falseTag, trueTag:
609	case int64Tag:
610		p.int64()
611	case floatTag:
612		p.float()
613	case complexTag:
614		p.float()
615		p.float()
616	case stringTag:
617		p.string()
618	case unknownTag:
619		break
620	default:
621		panic(fmt.Sprintf("unexpected value tag %d", tag))
622	}
623}
624
625func (p *gc_bin_parser) float() {
626	sign := p.int()
627	if sign == 0 {
628		return
629	}
630
631	p.int()    // exp
632	p.string() // mant
633}
634
635// ----------------------------------------------------------------------------
636// Low-level decoders
637
638func (p *gc_bin_parser) tagOrIndex() int {
639	if p.debugFormat {
640		p.marker('t')
641	}
642
643	return int(p.rawInt64())
644}
645
646func (p *gc_bin_parser) int() int {
647	x := p.int64()
648	if int64(int(x)) != x {
649		panic("exported integer too large")
650	}
651	return int(x)
652}
653
654func (p *gc_bin_parser) int64() int64 {
655	if p.debugFormat {
656		p.marker('i')
657	}
658
659	return p.rawInt64()
660}
661
662func (p *gc_bin_parser) path() string {
663	if p.debugFormat {
664		p.marker('p')
665	}
666	// if the path was seen before, i is its index (>= 0)
667	// (the empty string is at index 0)
668	i := p.rawInt64()
669	if i >= 0 {
670		return p.pathList[i]
671	}
672	// otherwise, i is the negative path length (< 0)
673	a := make([]string, -i)
674	for n := range a {
675		a[n] = p.string()
676	}
677	s := strings.Join(a, "/")
678	p.pathList = append(p.pathList, s)
679	return s
680}
681
682func (p *gc_bin_parser) string() string {
683	if p.debugFormat {
684		p.marker('s')
685	}
686	// if the string was seen before, i is its index (>= 0)
687	// (the empty string is at index 0)
688	i := p.rawInt64()
689	if i >= 0 {
690		return p.strList[i]
691	}
692	// otherwise, i is the negative string length (< 0)
693	if n := int(-i); n <= cap(p.buf) {
694		p.buf = p.buf[:n]
695	} else {
696		p.buf = make([]byte, n)
697	}
698	for i := range p.buf {
699		p.buf[i] = p.rawByte()
700	}
701	s := string(p.buf)
702	p.strList = append(p.strList, s)
703	return s
704}
705
706func (p *gc_bin_parser) marker(want byte) {
707	if got := p.rawByte(); got != want {
708		panic(fmt.Sprintf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read))
709	}
710
711	pos := p.read
712	if n := int(p.rawInt64()); n != pos {
713		panic(fmt.Sprintf("incorrect position: got %d; want %d", n, pos))
714	}
715}
716
717// rawInt64 should only be used by low-level decoders.
718func (p *gc_bin_parser) rawInt64() int64 {
719	i, err := binary.ReadVarint(p)
720	if err != nil {
721		panic(fmt.Sprintf("read error: %v", err))
722	}
723	return i
724}
725
726// rawStringln should only be used to read the initial version string.
727func (p *gc_bin_parser) rawStringln(b byte) string {
728	p.buf = p.buf[:0]
729	for b != '\n' {
730		p.buf = append(p.buf, b)
731		b = p.rawByte()
732	}
733	return string(p.buf)
734}
735
736// needed for binary.ReadVarint in rawInt64
737func (p *gc_bin_parser) ReadByte() (byte, error) {
738	return p.rawByte(), nil
739}
740
741// byte is the bottleneck interface for reading p.data.
742// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
743// rawByte should only be used by low-level decoders.
744func (p *gc_bin_parser) rawByte() byte {
745	b := p.data[0]
746	r := 1
747	if b == '|' {
748		b = p.data[1]
749		r = 2
750		switch b {
751		case 'S':
752			b = '$'
753		case '|':
754			// nothing to do
755		default:
756			panic("unexpected escape sequence in export data")
757		}
758	}
759	p.data = p.data[r:]
760	p.read += r
761	return b
762
763}
764
765// ----------------------------------------------------------------------------
766// Export format
767
768// Tags. Must be < 0.
769const (
770	// Objects
771	packageTag = -(iota + 1)
772	constTag
773	typeTag
774	varTag
775	funcTag
776	endTag
777
778	// Types
779	namedTag
780	arrayTag
781	sliceTag
782	dddTag
783	structTag
784	pointerTag
785	signatureTag
786	interfaceTag
787	mapTag
788	chanTag
789
790	// Values
791	falseTag
792	trueTag
793	int64Tag
794	floatTag
795	fractionTag // not used by gc
796	complexTag
797	stringTag
798	nilTag     // only used by gc (appears in exported inlined function bodies)
799	unknownTag // not used by gc (only appears in packages with errors)
800
801	// Type aliases
802	aliasTag
803)
804
805var predeclared = []ast.Expr{
806	// basic types
807	ast.NewIdent("bool"),
808	ast.NewIdent("int"),
809	ast.NewIdent("int8"),
810	ast.NewIdent("int16"),
811	ast.NewIdent("int32"),
812	ast.NewIdent("int64"),
813	ast.NewIdent("uint"),
814	ast.NewIdent("uint8"),
815	ast.NewIdent("uint16"),
816	ast.NewIdent("uint32"),
817	ast.NewIdent("uint64"),
818	ast.NewIdent("uintptr"),
819	ast.NewIdent("float32"),
820	ast.NewIdent("float64"),
821	ast.NewIdent("complex64"),
822	ast.NewIdent("complex128"),
823	ast.NewIdent("string"),
824
825	// basic type aliases
826	ast.NewIdent("byte"),
827	ast.NewIdent("rune"),
828
829	// error
830	ast.NewIdent("error"),
831
832	// TODO(nsf): don't think those are used in just package type info,
833	// maybe for consts, but we are not interested in that
834	// untyped types
835	ast.NewIdent(">_<"), // TODO: types.Typ[types.UntypedBool],
836	ast.NewIdent(">_<"), // TODO: types.Typ[types.UntypedInt],
837	ast.NewIdent(">_<"), // TODO: types.Typ[types.UntypedRune],
838	ast.NewIdent(">_<"), // TODO: types.Typ[types.UntypedFloat],
839	ast.NewIdent(">_<"), // TODO: types.Typ[types.UntypedComplex],
840	ast.NewIdent(">_<"), // TODO: types.Typ[types.UntypedString],
841	ast.NewIdent(">_<"), // TODO: types.Typ[types.UntypedNil],
842
843	// package unsafe
844	&ast.SelectorExpr{X: ast.NewIdent("unsafe"), Sel: ast.NewIdent("Pointer")},
845
846	// invalid type
847	ast.NewIdent(">_<"), // TODO: types.Typ[types.Invalid], // only appears in packages with errors
848
849	// used internally by gc; never used by this package or in .a files
850	ast.NewIdent("any"),
851}
852