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