github.com/bir3/gocompiler@v0.9.2202/src/go/internal/gcimporter/support.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 // This file implements support functionality for iimport.go. 6 7 package gcimporter 8 9 import ( 10 "fmt" 11 "github.com/bir3/gocompiler/src/go/token" 12 "github.com/bir3/gocompiler/src/go/types" 13 "github.com/bir3/gocompiler/src/internal/pkgbits" 14 "sync" 15 ) 16 17 func assert(b bool) { 18 if !b { 19 panic("assertion failed") 20 } 21 } 22 23 func errorf(format string, args ...any) { 24 panic(fmt.Sprintf(format, args...)) 25 } 26 27 // deltaNewFile is a magic line delta offset indicating a new file. 28 // We use -64 because it is rare; see issue 20080 and CL 41619. 29 // -64 is the smallest int that fits in a single byte as a varint. 30 const deltaNewFile = -64 31 32 // Synthesize a token.Pos 33 type fakeFileSet struct { 34 fset *token.FileSet 35 files map[string]*fileInfo 36 } 37 38 type fileInfo struct { 39 file *token.File 40 lastline int 41 } 42 43 const maxlines = 64 * 1024 44 45 func (s *fakeFileSet) pos(file string, line, column int) token.Pos { 46 // TODO(mdempsky): Make use of column. 47 48 // Since we don't know the set of needed file positions, we reserve 49 // maxlines positions per file. We delay calling token.File.SetLines until 50 // all positions have been calculated (by way of fakeFileSet.setLines), so 51 // that we can avoid setting unnecessary lines. See also golang/go#46586. 52 f := s.files[file] 53 if f == nil { 54 f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)} 55 s.files[file] = f 56 } 57 58 if line > maxlines { 59 line = 1 60 } 61 if line > f.lastline { 62 f.lastline = line 63 } 64 65 // Return a fake position assuming that f.file consists only of newlines. 66 return token.Pos(f.file.Base() + line - 1) 67 } 68 69 func (s *fakeFileSet) setLines() { 70 fakeLinesOnce.Do(func() { 71 fakeLines = make([]int, maxlines) 72 for i := range fakeLines { 73 fakeLines[i] = i 74 } 75 }) 76 for _, f := range s.files { 77 f.file.SetLines(fakeLines[:f.lastline]) 78 } 79 } 80 81 var ( 82 fakeLines []int 83 fakeLinesOnce sync.Once 84 ) 85 86 func chanDir(d int) types.ChanDir { 87 // tag values must match the constants in cmd/compile/internal/gc/go.go 88 switch d { 89 case 1 /* Crecv */ : 90 return types.RecvOnly 91 case 2 /* Csend */ : 92 return types.SendOnly 93 case 3 /* Cboth */ : 94 return types.SendRecv 95 default: 96 errorf("unexpected channel dir %d", d) 97 return 0 98 } 99 } 100 101 var predeclared = []types.Type{ 102 // basic types 103 types.Typ[types.Bool], 104 types.Typ[types.Int], 105 types.Typ[types.Int8], 106 types.Typ[types.Int16], 107 types.Typ[types.Int32], 108 types.Typ[types.Int64], 109 types.Typ[types.Uint], 110 types.Typ[types.Uint8], 111 types.Typ[types.Uint16], 112 types.Typ[types.Uint32], 113 types.Typ[types.Uint64], 114 types.Typ[types.Uintptr], 115 types.Typ[types.Float32], 116 types.Typ[types.Float64], 117 types.Typ[types.Complex64], 118 types.Typ[types.Complex128], 119 types.Typ[types.String], 120 121 // basic type aliases 122 types.Universe.Lookup("byte").Type(), 123 types.Universe.Lookup("rune").Type(), 124 125 // error 126 types.Universe.Lookup("error").Type(), 127 128 // untyped types 129 types.Typ[types.UntypedBool], 130 types.Typ[types.UntypedInt], 131 types.Typ[types.UntypedRune], 132 types.Typ[types.UntypedFloat], 133 types.Typ[types.UntypedComplex], 134 types.Typ[types.UntypedString], 135 types.Typ[types.UntypedNil], 136 137 // package unsafe 138 types.Typ[types.UnsafePointer], 139 140 // invalid type 141 types.Typ[types.Invalid], // only appears in packages with errors 142 143 // used internally by gc; never used by this package or in .a files 144 // not to be confused with the universe any 145 anyType{}, 146 147 // comparable 148 types.Universe.Lookup("comparable").Type(), 149 150 // any 151 types.Universe.Lookup("any").Type(), 152 } 153 154 type anyType struct{} 155 156 func (t anyType) Underlying() types.Type { return t } 157 func (t anyType) String() string { return "any" } 158 159 // See cmd/compile/internal/noder.derivedInfo. 160 type derivedInfo struct { 161 idx pkgbits.Index 162 needed bool 163 } 164 165 // See cmd/compile/internal/noder.typeInfo. 166 type typeInfo struct { 167 idx pkgbits.Index 168 derived bool 169 } 170 171 // See cmd/compile/internal/types.SplitVargenSuffix. 172 func splitVargenSuffix(name string) (base, suffix string) { 173 i := len(name) 174 for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' { 175 i-- 176 } 177 const dot = "ยท" 178 if i >= len(dot) && name[i-len(dot):i] == dot { 179 i -= len(dot) 180 return name[:i], name[i:] 181 } 182 return name, "" 183 }