1
2
3
4
5 package noder
6
7 import (
8 "fmt"
9 "os"
10
11 "cmd/compile/internal/base"
12 "cmd/compile/internal/dwarfgen"
13 "cmd/compile/internal/ir"
14 "cmd/compile/internal/syntax"
15 "cmd/compile/internal/typecheck"
16 "cmd/compile/internal/types"
17 "cmd/compile/internal/types2"
18 "cmd/internal/src"
19 )
20
21
22
23 func checkFiles(noders []*noder) (posMap, *types2.Package, *types2.Info) {
24 if base.SyntaxErrors() != 0 {
25 base.ErrorExit()
26 }
27
28
29 var m posMap
30 files := make([]*syntax.File, len(noders))
31 for i, p := range noders {
32 m.join(&p.posMap)
33 files[i] = p.file
34 }
35
36
37 ctxt := types2.NewContext()
38 importer := gcimports{
39 ctxt: ctxt,
40 packages: map[string]*types2.Package{"unsafe": types2.Unsafe},
41 }
42 conf := types2.Config{
43 Context: ctxt,
44 GoVersion: base.Flag.Lang,
45 IgnoreLabels: true,
46 CompilerErrorMessages: true,
47 Error: func(err error) {
48 terr := err.(types2.Error)
49 base.ErrorfAt(m.makeXPos(terr.Pos), "%s", terr.Msg)
50 },
51 Importer: &importer,
52 Sizes: &gcSizes{},
53 }
54 info := &types2.Info{
55 Types: make(map[syntax.Expr]types2.TypeAndValue),
56 Defs: make(map[*syntax.Name]types2.Object),
57 Uses: make(map[*syntax.Name]types2.Object),
58 Selections: make(map[*syntax.SelectorExpr]*types2.Selection),
59 Implicits: make(map[syntax.Node]types2.Object),
60 Scopes: make(map[syntax.Node]*types2.Scope),
61 Instances: make(map[*syntax.Name]types2.Instance),
62
63 }
64
65 pkg, err := conf.Check(base.Ctxt.Pkgpath, files, info)
66
67 base.ExitIfErrors()
68 if err != nil {
69 base.FatalfAt(src.NoXPos, "conf.Check error: %v", err)
70 }
71
72 return m, pkg, info
73 }
74
75
76
77 func check2(noders []*noder) {
78 m, pkg, info := checkFiles(noders)
79
80 if base.Flag.G < 2 {
81 os.Exit(0)
82 }
83
84 g := irgen{
85 target: typecheck.Target,
86 self: pkg,
87 info: info,
88 posMap: m,
89 objs: make(map[types2.Object]*ir.Name),
90 typs: make(map[types2.Type]*types.Type),
91 }
92 g.generate(noders)
93
94 if base.Flag.G < 3 {
95 os.Exit(0)
96 }
97 }
98
99
100 type subDictInfo struct {
101
102 callNode ir.Node
103
104
105
106
107 savedXNode ir.Node
108 }
109
110
111
112
113
114 type dictInfo struct {
115
116 shapeParams []*types.Type
117
118 derivedTypes []*types.Type
119
120
121
122 subDictCalls []subDictInfo
123
124
125 itabConvs []ir.Node
126
127
128
129 shapeToBound map[*types.Type]*types.Type
130
131
132
133 type2switchType map[ir.Node]*types.Type
134
135 startSubDict int
136 startItabConv int
137 dictLen int
138 }
139
140
141 type instInfo struct {
142 fun *ir.Func
143 dictParam *ir.Name
144
145 dictInfo *dictInfo
146 }
147
148 type irgen struct {
149 target *ir.Package
150 self *types2.Package
151 info *types2.Info
152
153 posMap
154 objs map[types2.Object]*ir.Name
155 typs map[types2.Type]*types.Type
156 marker dwarfgen.ScopeMarker
157
158
159
160 laterFuncs []func()
161
162
163 haveEmbed bool
164
165
166
167 exprStmtOK bool
168
169
170 typesToFinalize []*typeDelayInfo
171
172
173
174
175 topFuncIsGeneric bool
176
177
178
179
180
181 curDecl string
182 }
183
184
185
186 type genInst struct {
187 dnum int
188
189
190
191 instInfoMap map[*types.Sym]*instInfo
192
193
194
195 dictSymsToFinalize []*delayInfo
196
197
198 newInsts []ir.Node
199 }
200
201 func (g *irgen) later(fn func()) {
202 g.laterFuncs = append(g.laterFuncs, fn)
203 }
204
205 type delayInfo struct {
206 gf *ir.Name
207 targs []*types.Type
208 sym *types.Sym
209 off int
210 isMeth bool
211 }
212
213 type typeDelayInfo struct {
214 typ *types2.Named
215 ntyp *types.Type
216 }
217
218 func (g *irgen) generate(noders []*noder) {
219 types.LocalPkg.Name = g.self.Name()
220 types.LocalPkg.Height = g.self.Height()
221 typecheck.TypecheckAllowed = true
222
223
224
225 types.DeferCheckSize()
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 declLists := make([][]syntax.Decl, len(noders))
242 Outer:
243 for i, p := range noders {
244 g.pragmaFlags(p.file.Pragma, ir.GoBuildPragma)
245 for j, decl := range p.file.DeclList {
246 switch decl := decl.(type) {
247 case *syntax.ImportDecl:
248 g.importDecl(p, decl)
249 default:
250 declLists[i] = p.file.DeclList[j:]
251 continue Outer
252 }
253 }
254 }
255
256
257
258
259
260
261
262
263
264
265
266
267 for _, declList := range declLists {
268 for _, decl := range declList {
269 switch decl := decl.(type) {
270 case *syntax.TypeDecl:
271 g.typeDecl((*ir.Nodes)(&g.target.Decls), decl)
272 }
273 }
274 }
275 types.ResumeCheckSize()
276
277
278 for i, declList := range declLists {
279 old := g.haveEmbed
280 g.haveEmbed = noders[i].importedEmbed
281 g.decls((*ir.Nodes)(&g.target.Decls), declList)
282 g.haveEmbed = old
283 }
284 g.exprStmtOK = true
285
286
287
288 for len(g.laterFuncs) > 0 {
289 fn := g.laterFuncs[0]
290 g.laterFuncs = g.laterFuncs[1:]
291 fn()
292 }
293
294 if base.Flag.W > 1 {
295 for _, n := range g.target.Decls {
296 s := fmt.Sprintf("\nafter noder2 %v", n)
297 ir.Dump(s, n)
298 }
299 }
300
301 for _, p := range noders {
302
303 p.processPragmas()
304
305
306
307 syntax.Crawl(p.file, func(n syntax.Node) bool {
308 g.validate(n)
309 return false
310 })
311 }
312
313 if base.Flag.Complete {
314 for _, n := range g.target.Decls {
315 if fn, ok := n.(*ir.Func); ok {
316 if fn.Body == nil && fn.Nname.Sym().Linkname == "" {
317 base.ErrorfAt(fn.Pos(), "missing function body")
318 }
319 }
320 }
321 }
322
323
324
325 base.ExitIfErrors()
326
327 typecheck.DeclareUniverse()
328
329
330
331 BuildInstantiations()
332
333
334
335
336 j := 0
337 for i, decl := range g.target.Decls {
338 if decl.Op() != ir.ODCLFUNC || !decl.Type().HasTParam() {
339 g.target.Decls[j] = g.target.Decls[i]
340 j++
341 }
342 }
343 g.target.Decls = g.target.Decls[:j]
344
345 base.Assertf(len(g.laterFuncs) == 0, "still have %d later funcs", len(g.laterFuncs))
346 }
347
348 func (g *irgen) unhandled(what string, p poser) {
349 base.FatalfAt(g.pos(p), "unhandled %s: %T", what, p)
350 panic("unreachable")
351 }
352
353
354
355 func (g *irgen) delayTransform() bool {
356 return g.topFuncIsGeneric
357 }
358
View as plain text