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