• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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// This file implements support functionality for iimport.go.
6
7package importer
8
9import (
10	"cmd/compile/internal/base"
11	"cmd/compile/internal/types2"
12	"fmt"
13	"go/token"
14	"internal/pkgbits"
15	"sync"
16)
17
18func assert(p bool) {
19	base.Assert(p)
20}
21
22func errorf(format string, args ...interface{}) {
23	panic(fmt.Sprintf(format, args...))
24}
25
26const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
27
28// Synthesize a token.Pos
29type fakeFileSet struct {
30	fset  *token.FileSet
31	files map[string]*token.File
32}
33
34func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
35	// TODO(mdempsky): Make use of column.
36
37	// Since we don't know the set of needed file positions, we
38	// reserve maxlines positions per file.
39	const maxlines = 64 * 1024
40	f := s.files[file]
41	if f == nil {
42		f = s.fset.AddFile(file, -1, maxlines)
43		s.files[file] = f
44		// Allocate the fake linebreak indices on first use.
45		// TODO(adonovan): opt: save ~512KB using a more complex scheme?
46		fakeLinesOnce.Do(func() {
47			fakeLines = make([]int, maxlines)
48			for i := range fakeLines {
49				fakeLines[i] = i
50			}
51		})
52		f.SetLines(fakeLines)
53	}
54
55	if line > maxlines {
56		line = 1
57	}
58
59	// Treat the file as if it contained only newlines
60	// and column=1: use the line number as the offset.
61	return f.Pos(line - 1)
62}
63
64var (
65	fakeLines     []int
66	fakeLinesOnce sync.Once
67)
68
69func chanDir(d int) types2.ChanDir {
70	// tag values must match the constants in cmd/compile/internal/gc/go.go
71	switch d {
72	case 1 /* Crecv */ :
73		return types2.RecvOnly
74	case 2 /* Csend */ :
75		return types2.SendOnly
76	case 3 /* Cboth */ :
77		return types2.SendRecv
78	default:
79		errorf("unexpected channel dir %d", d)
80		return 0
81	}
82}
83
84var predeclared = []types2.Type{
85	// basic types
86	types2.Typ[types2.Bool],
87	types2.Typ[types2.Int],
88	types2.Typ[types2.Int8],
89	types2.Typ[types2.Int16],
90	types2.Typ[types2.Int32],
91	types2.Typ[types2.Int64],
92	types2.Typ[types2.Uint],
93	types2.Typ[types2.Uint8],
94	types2.Typ[types2.Uint16],
95	types2.Typ[types2.Uint32],
96	types2.Typ[types2.Uint64],
97	types2.Typ[types2.Uintptr],
98	types2.Typ[types2.Float32],
99	types2.Typ[types2.Float64],
100	types2.Typ[types2.Complex64],
101	types2.Typ[types2.Complex128],
102	types2.Typ[types2.String],
103
104	// basic type aliases
105	types2.Universe.Lookup("byte").Type(),
106	types2.Universe.Lookup("rune").Type(),
107
108	// error
109	types2.Universe.Lookup("error").Type(),
110
111	// untyped types
112	types2.Typ[types2.UntypedBool],
113	types2.Typ[types2.UntypedInt],
114	types2.Typ[types2.UntypedRune],
115	types2.Typ[types2.UntypedFloat],
116	types2.Typ[types2.UntypedComplex],
117	types2.Typ[types2.UntypedString],
118	types2.Typ[types2.UntypedNil],
119
120	// package unsafe
121	types2.Typ[types2.UnsafePointer],
122
123	// invalid type
124	types2.Typ[types2.Invalid], // only appears in packages with errors
125
126	// used internally by gc; never used by this package or in .a files
127	// not to be confused with the universe any
128	anyType{},
129
130	// comparable
131	types2.Universe.Lookup("comparable").Type(),
132
133	// "any" has special handling: see usage of predeclared.
134}
135
136type anyType struct{}
137
138func (t anyType) Underlying() types2.Type { return t }
139func (t anyType) String() string          { return "any" }
140
141// See cmd/compile/internal/noder.derivedInfo.
142type derivedInfo struct {
143	idx    pkgbits.Index
144	needed bool
145}
146
147// See cmd/compile/internal/noder.typeInfo.
148type typeInfo struct {
149	idx     pkgbits.Index
150	derived bool
151}
152