]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/noder/irgen.go
[dev.unified] all: merge master (993c387) into dev.unified
[gostls13.git] / src / cmd / compile / internal / noder / irgen.go
1 // Copyright 2021 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 package noder
6
7 import (
8         "fmt"
9
10         "cmd/compile/internal/base"
11         "cmd/compile/internal/dwarfgen"
12         "cmd/compile/internal/ir"
13         "cmd/compile/internal/syntax"
14         "cmd/compile/internal/typecheck"
15         "cmd/compile/internal/types"
16         "cmd/compile/internal/types2"
17         "cmd/internal/src"
18 )
19
20 // checkFiles configures and runs the types2 checker on the given
21 // parsed source files and then returns the result.
22 func checkFiles(noders []*noder) (posMap, *types2.Package, *types2.Info) {
23         if base.SyntaxErrors() != 0 {
24                 base.ErrorExit()
25         }
26
27         // setup and syntax error reporting
28         var m posMap
29         files := make([]*syntax.File, len(noders))
30         for i, p := range noders {
31                 m.join(&p.posMap)
32                 files[i] = p.file
33         }
34
35         // typechecking
36         ctxt := types2.NewContext()
37         importer := gcimports{
38                 ctxt:     ctxt,
39                 packages: make(map[string]*types2.Package),
40         }
41         conf := types2.Config{
42                 Context:               ctxt,
43                 GoVersion:             base.Flag.Lang,
44                 IgnoreBranchErrors:    true, // parser already checked via syntax.CheckBranches mode
45                 CompilerErrorMessages: true, // use error strings matching existing compiler errors
46                 Error: func(err error) {
47                         terr := err.(types2.Error)
48                         base.ErrorfAt(m.makeXPos(terr.Pos), "%s", terr.Msg)
49                 },
50                 Importer: &importer,
51                 Sizes:    &gcSizes{},
52         }
53         info := &types2.Info{
54                 Types:      make(map[syntax.Expr]types2.TypeAndValue),
55                 Defs:       make(map[*syntax.Name]types2.Object),
56                 Uses:       make(map[*syntax.Name]types2.Object),
57                 Selections: make(map[*syntax.SelectorExpr]*types2.Selection),
58                 Implicits:  make(map[syntax.Node]types2.Object),
59                 Scopes:     make(map[syntax.Node]*types2.Scope),
60                 Instances:  make(map[*syntax.Name]types2.Instance),
61                 // expand as needed
62         }
63
64         pkg, err := conf.Check(base.Ctxt.Pkgpath, files, info)
65
66         base.ExitIfErrors()
67         if err != nil {
68                 base.FatalfAt(src.NoXPos, "conf.Check error: %v", err)
69         }
70
71         return m, pkg, info
72 }
73
74 // check2 type checks a Go package using types2, and then generates IR
75 // using the results.
76 func check2(noders []*noder) {
77         m, pkg, info := checkFiles(noders)
78
79         g := irgen{
80                 target: typecheck.Target,
81                 self:   pkg,
82                 info:   info,
83                 posMap: m,
84                 objs:   make(map[types2.Object]*ir.Name),
85                 typs:   make(map[types2.Type]*types.Type),
86         }
87         g.generate(noders)
88 }
89
90 // Information about sub-dictionary entries in a dictionary
91 type subDictInfo struct {
92         // Call or XDOT node that requires a dictionary.
93         callNode ir.Node
94         // Saved CallExpr.X node (*ir.SelectorExpr or *InstExpr node) for a generic
95         // method or function call, since this node will get dropped when the generic
96         // method/function call is transformed to a call on the instantiated shape
97         // function. Nil for other kinds of calls or XDOTs.
98         savedXNode ir.Node
99 }
100
101 // dictInfo is the dictionary format for an instantiation of a generic function with
102 // particular shapes. shapeParams, derivedTypes, subDictCalls, itabConvs, and methodExprClosures
103 // describe the actual dictionary entries in order, and the remaining fields are other info
104 // needed in doing dictionary processing during compilation.
105 type dictInfo struct {
106         // Types substituted for the type parameters, which are shape types.
107         shapeParams []*types.Type
108         // All types derived from those typeparams used in the instantiation.
109         derivedTypes []*types.Type
110         // Nodes in the instantiation that requires a subdictionary. Includes
111         // method and function calls (OCALL), function values (OFUNCINST), method
112         // values/expressions (OXDOT).
113         subDictCalls []subDictInfo
114         // Nodes in the instantiation that are a conversion from a typeparam/derived
115         // type to a specific interface.
116         itabConvs []ir.Node
117         // Method expression closures. For a generic type T with method M(arg1, arg2) res,
118         // these closures are func(rcvr T, arg1, arg2) res.
119         // These closures capture no variables, they are just the generic version of ·f symbols
120         // that live in the dictionary instead of in the readonly globals section.
121         methodExprClosures []methodExprClosure
122
123         // Mapping from each shape type that substitutes a type param, to its
124         // type bound (which is also substituted with shapes if it is parameterized)
125         shapeToBound map[*types.Type]*types.Type
126
127         // For type switches on nonempty interfaces, a map from OTYPE entries of
128         // HasShape type, to the interface type we're switching from.
129         type2switchType map[ir.Node]*types.Type
130
131         startSubDict            int // Start of dict entries for subdictionaries
132         startItabConv           int // Start of dict entries for itab conversions
133         startMethodExprClosures int // Start of dict entries for closures for method expressions
134         dictLen                 int // Total number of entries in dictionary
135 }
136
137 type methodExprClosure struct {
138         idx  int    // index in list of shape parameters
139         name string // method name
140 }
141
142 // instInfo is information gathered on an shape instantiation of a function.
143 type instInfo struct {
144         fun       *ir.Func // The instantiated function (with body)
145         dictParam *ir.Name // The node inside fun that refers to the dictionary param
146
147         dictInfo *dictInfo
148 }
149
150 type irgen struct {
151         target *ir.Package
152         self   *types2.Package
153         info   *types2.Info
154
155         posMap
156         objs   map[types2.Object]*ir.Name
157         typs   map[types2.Type]*types.Type
158         marker dwarfgen.ScopeMarker
159
160         // laterFuncs records tasks that need to run after all declarations
161         // are processed.
162         laterFuncs []func()
163         // haveEmbed indicates whether the current node belongs to file that
164         // imports "embed" package.
165         haveEmbed bool
166
167         // exprStmtOK indicates whether it's safe to generate expressions or
168         // statements yet.
169         exprStmtOK bool
170
171         // types which we need to finish, by doing g.fillinMethods.
172         typesToFinalize []*typeDelayInfo
173
174         // True when we are compiling a top-level generic function or method. Use to
175         // avoid adding closures of generic functions/methods to the target.Decls
176         // list.
177         topFuncIsGeneric bool
178
179         // The context during type/function/method declarations that is used to
180         // uniquely name type parameters. We need unique names for type params so we
181         // can be sure they match up correctly between types2-to-types1 translation
182         // and types1 importing.
183         curDecl string
184 }
185
186 // genInst has the information for creating needed instantiations and modifying
187 // functions to use instantiations.
188 type genInst struct {
189         dnum int // for generating unique dictionary variables
190
191         // Map from the names of all instantiations to information about the
192         // instantiations.
193         instInfoMap map[*types.Sym]*instInfo
194
195         // Dictionary syms which we need to finish, by writing out any itabconv
196         // or method expression closure entries.
197         dictSymsToFinalize []*delayInfo
198
199         // New instantiations created during this round of buildInstantiations().
200         newInsts []ir.Node
201 }
202
203 func (g *irgen) later(fn func()) {
204         g.laterFuncs = append(g.laterFuncs, fn)
205 }
206
207 type delayInfo struct {
208         gf     *ir.Name
209         targs  []*types.Type
210         sym    *types.Sym
211         off    int
212         isMeth bool
213 }
214
215 type typeDelayInfo struct {
216         typ  *types2.Named
217         ntyp *types.Type
218 }
219
220 func (g *irgen) generate(noders []*noder) {
221         types.LocalPkg.Name = g.self.Name()
222         typecheck.TypecheckAllowed = true
223
224         // Prevent size calculations until we set the underlying type
225         // for all package-block defined types.
226         types.DeferCheckSize()
227
228         // At this point, types2 has already handled name resolution and
229         // type checking. We just need to map from its object and type
230         // representations to those currently used by the rest of the
231         // compiler. This happens in a few passes.
232
233         // 1. Process all import declarations. We use the compiler's own
234         // importer for this, rather than types2's gcimporter-derived one,
235         // to handle extensions and inline function bodies correctly.
236         //
237         // Also, we need to do this in a separate pass, because mappings are
238         // instantiated on demand. If we interleaved processing import
239         // declarations with other declarations, it's likely we'd end up
240         // wanting to map an object/type from another source file, but not
241         // yet have the import data it relies on.
242         declLists := make([][]syntax.Decl, len(noders))
243 Outer:
244         for i, p := range noders {
245                 g.pragmaFlags(p.file.Pragma, ir.GoBuildPragma)
246                 for j, decl := range p.file.DeclList {
247                         switch decl := decl.(type) {
248                         case *syntax.ImportDecl:
249                                 g.importDecl(p, decl)
250                         default:
251                                 declLists[i] = p.file.DeclList[j:]
252                                 continue Outer // no more ImportDecls
253                         }
254                 }
255         }
256
257         // 2. Process all package-block type declarations. As with imports,
258         // we need to make sure all types are properly instantiated before
259         // trying to map any expressions that utilize them. In particular,
260         // we need to make sure type pragmas are already known (see comment
261         // in irgen.typeDecl).
262         //
263         // We could perhaps instead defer processing of package-block
264         // variable initializers and function bodies, like noder does, but
265         // special-casing just package-block type declarations minimizes the
266         // differences between processing package-block and function-scoped
267         // declarations.
268         for _, declList := range declLists {
269                 for _, decl := range declList {
270                         switch decl := decl.(type) {
271                         case *syntax.TypeDecl:
272                                 g.typeDecl((*ir.Nodes)(&g.target.Decls), decl)
273                         }
274                 }
275         }
276         types.ResumeCheckSize()
277
278         // 3. Process all remaining declarations.
279         for i, declList := range declLists {
280                 old := g.haveEmbed
281                 g.haveEmbed = noders[i].importedEmbed
282                 g.decls((*ir.Nodes)(&g.target.Decls), declList)
283                 g.haveEmbed = old
284         }
285         g.exprStmtOK = true
286
287         // 4. Run any "later" tasks. Avoid using 'range' so that tasks can
288         // recursively queue further tasks. (Not currently utilized though.)
289         for len(g.laterFuncs) > 0 {
290                 fn := g.laterFuncs[0]
291                 g.laterFuncs = g.laterFuncs[1:]
292                 fn()
293         }
294
295         if base.Flag.W > 1 {
296                 for _, n := range g.target.Decls {
297                         s := fmt.Sprintf("\nafter noder2 %v", n)
298                         ir.Dump(s, n)
299                 }
300         }
301
302         for _, p := range noders {
303                 // Process linkname and cgo pragmas.
304                 p.processPragmas()
305
306                 // Double check for any type-checking inconsistencies. This can be
307                 // removed once we're confident in IR generation results.
308                 syntax.Crawl(p.file, func(n syntax.Node) bool {
309                         g.validate(n)
310                         return false
311                 })
312         }
313
314         if base.Flag.Complete {
315                 for _, n := range g.target.Decls {
316                         if fn, ok := n.(*ir.Func); ok {
317                                 if fn.Body == nil && fn.Nname.Sym().Linkname == "" {
318                                         base.ErrorfAt(fn.Pos(), "missing function body")
319                                 }
320                         }
321                 }
322         }
323
324         // Check for unusual case where noder2 encounters a type error that types2
325         // doesn't check for (e.g. notinheap incompatibility).
326         base.ExitIfErrors()
327
328         typecheck.DeclareUniverse()
329
330         // Create any needed instantiations of generic functions and transform
331         // existing and new functions to use those instantiations.
332         BuildInstantiations()
333
334         // Remove all generic functions from g.target.Decl, since they have been
335         // used for stenciling, but don't compile. Generic functions will already
336         // have been marked for export as appropriate.
337         j := 0
338         for i, decl := range g.target.Decls {
339                 if decl.Op() != ir.ODCLFUNC || !decl.Type().HasTParam() {
340                         g.target.Decls[j] = g.target.Decls[i]
341                         j++
342                 }
343         }
344         g.target.Decls = g.target.Decls[:j]
345
346         base.Assertf(len(g.laterFuncs) == 0, "still have %d later funcs", len(g.laterFuncs))
347 }
348
349 func (g *irgen) unhandled(what string, p poser) {
350         base.FatalfAt(g.pos(p), "unhandled %s: %T", what, p)
351         panic("unreachable")
352 }
353
354 // delayTransform returns true if we should delay all transforms, because we are
355 // creating the nodes for a generic function/method.
356 func (g *irgen) delayTransform() bool {
357         return g.topFuncIsGeneric
358 }