Skip to content

Commit da97613

Browse files
committed
cmd/compile: remove GOEXPERIMENT=nounified frontend
This CL removes most of the code specific to the nounified frontend. To simplify review, it's a strict remove-only CL. Updates #57410. Change-Id: Ic3196570aa4286618c1d5e7fd0d0e6601a18195b Reviewed-on: https://go-review.googlesource.com/c/go/+/458620 Run-TryBot: Matthew Dempsky <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Matthew Dempsky <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent a7de684 commit da97613

23 files changed

+0
-11575
lines changed

src/cmd/compile/internal/inline/inl.go

Lines changed: 0 additions & 589 deletions
Large diffs are not rendered by default.

src/cmd/compile/internal/noder/decl.go

Lines changed: 0 additions & 334 deletions
Original file line numberDiff line numberDiff line change
@@ -5,348 +5,14 @@
55
package noder
66

77
import (
8-
"go/constant"
9-
10-
"cmd/compile/internal/base"
11-
"cmd/compile/internal/ir"
128
"cmd/compile/internal/syntax"
13-
"cmd/compile/internal/typecheck"
14-
"cmd/compile/internal/types"
159
"cmd/compile/internal/types2"
1610
)
1711

18-
// TODO(mdempsky): Skip blank declarations? Probably only safe
19-
// for declarations without pragmas.
20-
21-
func (g *irgen) decls(res *ir.Nodes, decls []syntax.Decl) {
22-
for _, decl := range decls {
23-
switch decl := decl.(type) {
24-
case *syntax.ConstDecl:
25-
g.constDecl(res, decl)
26-
case *syntax.FuncDecl:
27-
g.funcDecl(res, decl)
28-
case *syntax.TypeDecl:
29-
if ir.CurFunc == nil {
30-
continue // already handled in irgen.generate
31-
}
32-
g.typeDecl(res, decl)
33-
case *syntax.VarDecl:
34-
g.varDecl(res, decl)
35-
default:
36-
g.unhandled("declaration", decl)
37-
}
38-
}
39-
}
40-
41-
func (g *irgen) importDecl(p *noder, decl *syntax.ImportDecl) {
42-
g.pragmaFlags(decl.Pragma, 0)
43-
44-
// Get the imported package's path, as resolved already by types2
45-
// and gcimporter. This is the same path as would be computed by
46-
// parseImportPath.
47-
switch pkgNameOf(g.info, decl).Imported().Path() {
48-
case "unsafe":
49-
p.importedUnsafe = true
50-
case "embed":
51-
p.importedEmbed = true
52-
}
53-
}
54-
5512
// pkgNameOf returns the PkgName associated with the given ImportDecl.
5613
func pkgNameOf(info *types2.Info, decl *syntax.ImportDecl) *types2.PkgName {
5714
if name := decl.LocalPkgName; name != nil {
5815
return info.Defs[name].(*types2.PkgName)
5916
}
6017
return info.Implicits[decl].(*types2.PkgName)
6118
}
62-
63-
func (g *irgen) constDecl(out *ir.Nodes, decl *syntax.ConstDecl) {
64-
g.pragmaFlags(decl.Pragma, 0)
65-
66-
for _, name := range decl.NameList {
67-
name, obj := g.def(name)
68-
69-
// For untyped numeric constants, make sure the value
70-
// representation matches what the rest of the
71-
// compiler (really just iexport) expects.
72-
// TODO(mdempsky): Revisit after #43891 is resolved.
73-
val := obj.(*types2.Const).Val()
74-
switch name.Type() {
75-
case types.UntypedInt, types.UntypedRune:
76-
val = constant.ToInt(val)
77-
case types.UntypedFloat:
78-
val = constant.ToFloat(val)
79-
case types.UntypedComplex:
80-
val = constant.ToComplex(val)
81-
}
82-
name.SetVal(val)
83-
84-
out.Append(ir.NewDecl(g.pos(decl), ir.ODCLCONST, name))
85-
}
86-
}
87-
88-
func (g *irgen) funcDecl(out *ir.Nodes, decl *syntax.FuncDecl) {
89-
assert(g.curDecl == "")
90-
// Set g.curDecl to the function name, as context for the type params declared
91-
// during types2-to-types1 translation if this is a generic function.
92-
g.curDecl = decl.Name.Value
93-
obj2 := g.info.Defs[decl.Name]
94-
recv := types2.AsSignature(obj2.Type()).Recv()
95-
if recv != nil {
96-
t2 := deref2(recv.Type())
97-
// This is a method, so set g.curDecl to recvTypeName.methName instead.
98-
g.curDecl = t2.(*types2.Named).Obj().Name() + "." + g.curDecl
99-
}
100-
101-
fn := ir.NewFunc(g.pos(decl))
102-
fn.Nname, _ = g.def(decl.Name)
103-
fn.Nname.Func = fn
104-
fn.Nname.Defn = fn
105-
106-
fn.Pragma = g.pragmaFlags(decl.Pragma, funcPragmas)
107-
if fn.Pragma&ir.Systemstack != 0 && fn.Pragma&ir.Nosplit != 0 {
108-
base.ErrorfAt(fn.Pos(), "go:nosplit and go:systemstack cannot be combined")
109-
}
110-
if fn.Pragma&ir.Nointerface != 0 {
111-
// Propagate //go:nointerface from Func.Pragma to Field.Nointerface.
112-
// This is a bit roundabout, but this is the earliest point where we've
113-
// processed the function's pragma flags, and we've also already created
114-
// the Fields to represent the receiver's method set.
115-
if recv := fn.Type().Recv(); recv != nil {
116-
typ := types.ReceiverBaseType(recv.Type)
117-
if orig := typ.OrigType(); orig != nil {
118-
// For a generic method, we mark the methods on the
119-
// base generic type, since those are the methods
120-
// that will be stenciled.
121-
typ = orig
122-
}
123-
meth := typecheck.Lookdot1(fn, typecheck.Lookup(decl.Name.Value), typ, typ.Methods(), 0)
124-
meth.SetNointerface(true)
125-
}
126-
}
127-
128-
if decl.Body != nil {
129-
if fn.Pragma&ir.Noescape != 0 {
130-
base.ErrorfAt(fn.Pos(), "can only use //go:noescape with external func implementations")
131-
}
132-
if (fn.Pragma&ir.UintptrKeepAlive != 0 && fn.Pragma&ir.UintptrEscapes == 0) && fn.Pragma&ir.Nosplit == 0 {
133-
// Stack growth can't handle uintptr arguments that may
134-
// be pointers (as we don't know which are pointers
135-
// when creating the stack map). Thus uintptrkeepalive
136-
// functions (and all transitive callees) must be
137-
// nosplit.
138-
//
139-
// N.B. uintptrescapes implies uintptrkeepalive but it
140-
// is OK since the arguments must escape to the heap.
141-
//
142-
// TODO(prattmic): Add recursive nosplit check of callees.
143-
// TODO(prattmic): Functions with no body (i.e.,
144-
// assembly) must also be nosplit, but we can't check
145-
// that here.
146-
base.ErrorfAt(fn.Pos(), "go:uintptrkeepalive requires go:nosplit")
147-
}
148-
}
149-
150-
if decl.Name.Value == "init" && decl.Recv == nil {
151-
g.target.Inits = append(g.target.Inits, fn)
152-
}
153-
154-
saveHaveEmbed := g.haveEmbed
155-
saveCurDecl := g.curDecl
156-
g.curDecl = ""
157-
g.later(func() {
158-
defer func(b bool, s string) {
159-
// Revert haveEmbed and curDecl back to what they were before
160-
// the "later" function.
161-
g.haveEmbed = b
162-
g.curDecl = s
163-
}(g.haveEmbed, g.curDecl)
164-
165-
// Set haveEmbed and curDecl to what they were for this funcDecl.
166-
g.haveEmbed = saveHaveEmbed
167-
g.curDecl = saveCurDecl
168-
if fn.Type().HasTParam() {
169-
g.topFuncIsGeneric = true
170-
}
171-
g.funcBody(fn, decl.Recv, decl.Type, decl.Body)
172-
g.topFuncIsGeneric = false
173-
if fn.Type().HasTParam() && fn.Body != nil {
174-
// Set pointers to the dcls/body of a generic function/method in
175-
// the Inl struct, so it is marked for export, is available for
176-
// stenciling, and works with Inline_Flood().
177-
fn.Inl = &ir.Inline{
178-
Cost: 1,
179-
Dcl: fn.Dcl,
180-
Body: fn.Body,
181-
}
182-
}
183-
184-
out.Append(fn)
185-
})
186-
}
187-
188-
func (g *irgen) typeDecl(out *ir.Nodes, decl *syntax.TypeDecl) {
189-
// Set the position for any error messages we might print (e.g. too large types).
190-
base.Pos = g.pos(decl)
191-
assert(ir.CurFunc != nil || g.curDecl == "")
192-
// Set g.curDecl to the type name, as context for the type params declared
193-
// during types2-to-types1 translation if this is a generic type.
194-
saveCurDecl := g.curDecl
195-
g.curDecl = decl.Name.Value
196-
if decl.Alias {
197-
name, _ := g.def(decl.Name)
198-
g.pragmaFlags(decl.Pragma, 0)
199-
assert(name.Alias()) // should be set by irgen.obj
200-
201-
out.Append(ir.NewDecl(g.pos(decl), ir.ODCLTYPE, name))
202-
g.curDecl = ""
203-
return
204-
}
205-
206-
// Prevent size calculations until we set the underlying type.
207-
types.DeferCheckSize()
208-
209-
name, obj := g.def(decl.Name)
210-
ntyp, otyp := name.Type(), obj.Type()
211-
if ir.CurFunc != nil {
212-
ntyp.SetVargen()
213-
}
214-
215-
pragmas := g.pragmaFlags(decl.Pragma, 0)
216-
name.SetPragma(pragmas) // TODO(mdempsky): Is this still needed?
217-
218-
ntyp.SetUnderlying(g.typeExpr(decl.Type))
219-
220-
tparams := otyp.(*types2.Named).TypeParams()
221-
if n := tparams.Len(); n > 0 {
222-
rparams := make([]*types.Type, n)
223-
for i := range rparams {
224-
rparams[i] = g.typ(tparams.At(i))
225-
}
226-
// This will set hasTParam flag if any rparams are not concrete types.
227-
ntyp.SetRParams(rparams)
228-
}
229-
types.ResumeCheckSize()
230-
231-
g.curDecl = saveCurDecl
232-
if otyp, ok := otyp.(*types2.Named); ok && otyp.NumMethods() != 0 {
233-
methods := make([]*types.Field, otyp.NumMethods())
234-
for i := range methods {
235-
m := otyp.Method(i)
236-
// Set g.curDecl to recvTypeName.methName, as context for the
237-
// method-specific type params in the receiver.
238-
g.curDecl = decl.Name.Value + "." + m.Name()
239-
meth := g.obj(m)
240-
methods[i] = types.NewField(meth.Pos(), g.selector(m), meth.Type())
241-
methods[i].Nname = meth
242-
g.curDecl = ""
243-
}
244-
ntyp.Methods().Set(methods)
245-
}
246-
247-
out.Append(ir.NewDecl(g.pos(decl), ir.ODCLTYPE, name))
248-
}
249-
250-
func (g *irgen) varDecl(out *ir.Nodes, decl *syntax.VarDecl) {
251-
pos := g.pos(decl)
252-
// Set the position for any error messages we might print (e.g. too large types).
253-
base.Pos = pos
254-
names := make([]*ir.Name, len(decl.NameList))
255-
for i, name := range decl.NameList {
256-
names[i], _ = g.def(name)
257-
}
258-
259-
if decl.Pragma != nil {
260-
pragma := decl.Pragma.(*pragmas)
261-
varEmbed(g.makeXPos, names[0], decl, pragma, g.haveEmbed)
262-
g.reportUnused(pragma)
263-
}
264-
265-
haveEmbed := g.haveEmbed
266-
do := func() {
267-
defer func(b bool) { g.haveEmbed = b }(g.haveEmbed)
268-
269-
g.haveEmbed = haveEmbed
270-
values := g.exprList(decl.Values)
271-
272-
var as2 *ir.AssignListStmt
273-
if len(values) != 0 && len(names) != len(values) {
274-
as2 = ir.NewAssignListStmt(pos, ir.OAS2, make([]ir.Node, len(names)), values)
275-
}
276-
277-
for i, name := range names {
278-
if ir.CurFunc != nil {
279-
out.Append(ir.NewDecl(pos, ir.ODCL, name))
280-
}
281-
if as2 != nil {
282-
as2.Lhs[i] = name
283-
name.Defn = as2
284-
} else {
285-
as := ir.NewAssignStmt(pos, name, nil)
286-
if len(values) != 0 {
287-
as.Y = values[i]
288-
name.Defn = as
289-
} else if ir.CurFunc == nil {
290-
name.Defn = as
291-
}
292-
if !g.delayTransform() {
293-
lhs := []ir.Node{as.X}
294-
rhs := []ir.Node{}
295-
if as.Y != nil {
296-
rhs = []ir.Node{as.Y}
297-
}
298-
transformAssign(as, lhs, rhs)
299-
as.X = lhs[0]
300-
if as.Y != nil {
301-
as.Y = rhs[0]
302-
}
303-
}
304-
as.SetTypecheck(1)
305-
out.Append(as)
306-
}
307-
}
308-
if as2 != nil {
309-
if !g.delayTransform() {
310-
transformAssign(as2, as2.Lhs, as2.Rhs)
311-
}
312-
as2.SetTypecheck(1)
313-
out.Append(as2)
314-
}
315-
}
316-
317-
// If we're within a function, we need to process the assignment
318-
// part of the variable declaration right away. Otherwise, we leave
319-
// it to be handled after all top-level declarations are processed.
320-
if ir.CurFunc != nil {
321-
do()
322-
} else {
323-
g.later(do)
324-
}
325-
}
326-
327-
// pragmaFlags returns any specified pragma flags included in allowed,
328-
// and reports errors about any other, unexpected pragmas.
329-
func (g *irgen) pragmaFlags(pragma syntax.Pragma, allowed ir.PragmaFlag) ir.PragmaFlag {
330-
if pragma == nil {
331-
return 0
332-
}
333-
p := pragma.(*pragmas)
334-
present := p.Flag & allowed
335-
p.Flag &^= allowed
336-
g.reportUnused(p)
337-
return present
338-
}
339-
340-
// reportUnused reports errors about any unused pragmas.
341-
func (g *irgen) reportUnused(pragma *pragmas) {
342-
for _, pos := range pragma.Pos {
343-
if pos.Flag&pragma.Flag != 0 {
344-
base.ErrorfAt(g.makeXPos(pos.Pos), "misplaced compiler directive")
345-
}
346-
}
347-
if len(pragma.Embeds) > 0 {
348-
for _, e := range pragma.Embeds {
349-
base.ErrorfAt(g.makeXPos(e.Pos), "misplaced go:embed directive")
350-
}
351-
}
352-
}

0 commit comments

Comments
 (0)