1
2
3
4
5 package noder
6
7 import (
8 "go/constant"
9
10 "cmd/compile/internal/base"
11 "cmd/compile/internal/ir"
12 "cmd/compile/internal/syntax"
13 "cmd/compile/internal/typecheck"
14 "cmd/compile/internal/types"
15 "cmd/compile/internal/types2"
16 )
17
18
19
20
21 func (g *irgen) decls(decls []syntax.Decl) []ir.Node {
22 var res ir.Nodes
23 for _, decl := range decls {
24 switch decl := decl.(type) {
25 case *syntax.ConstDecl:
26 g.constDecl(&res, decl)
27 case *syntax.FuncDecl:
28 g.funcDecl(&res, decl)
29 case *syntax.TypeDecl:
30 if ir.CurFunc == nil {
31 continue
32 }
33 g.typeDecl(&res, decl)
34 case *syntax.VarDecl:
35 g.varDecl(&res, decl)
36 default:
37 g.unhandled("declaration", decl)
38 }
39 }
40 return res
41 }
42
43 func (g *irgen) importDecl(p *noder, decl *syntax.ImportDecl) {
44
45
46
47 g.pragmaFlags(decl.Pragma, 0)
48
49 ipkg := importfile(decl)
50 if ipkg == ir.Pkgs.Unsafe {
51 p.importedUnsafe = true
52 }
53 if ipkg.Path == "embed" {
54 p.importedEmbed = true
55 }
56 }
57
58 func (g *irgen) constDecl(out *ir.Nodes, decl *syntax.ConstDecl) {
59 g.pragmaFlags(decl.Pragma, 0)
60
61 for _, name := range decl.NameList {
62 name, obj := g.def(name)
63
64
65
66
67
68 val := obj.(*types2.Const).Val()
69 switch name.Type() {
70 case types.UntypedInt, types.UntypedRune:
71 val = constant.ToInt(val)
72 case types.UntypedFloat:
73 val = constant.ToFloat(val)
74 case types.UntypedComplex:
75 val = constant.ToComplex(val)
76 }
77 name.SetVal(val)
78
79 out.Append(ir.NewDecl(g.pos(decl), ir.ODCLCONST, name))
80 }
81 }
82
83 func (g *irgen) funcDecl(out *ir.Nodes, decl *syntax.FuncDecl) {
84 fn := ir.NewFunc(g.pos(decl))
85 fn.Nname, _ = g.def(decl.Name)
86 fn.Nname.Func = fn
87 fn.Nname.Defn = fn
88
89 fn.Pragma = g.pragmaFlags(decl.Pragma, funcPragmas)
90 if fn.Pragma&ir.Systemstack != 0 && fn.Pragma&ir.Nosplit != 0 {
91 base.ErrorfAt(fn.Pos(), "go:nosplit and go:systemstack cannot be combined")
92 }
93
94 if decl.Name.Value == "init" && decl.Recv == nil {
95 g.target.Inits = append(g.target.Inits, fn)
96 }
97
98 g.funcBody(fn, decl.Recv, decl.Type, decl.Body)
99
100 out.Append(fn)
101 }
102
103 func (g *irgen) typeDecl(out *ir.Nodes, decl *syntax.TypeDecl) {
104 if decl.Alias {
105 name, _ := g.def(decl.Name)
106 g.pragmaFlags(decl.Pragma, 0)
107
108
109
110
111 if ir.CurFunc == nil {
112 name.Sym().Def = ir.TypeNode(name.Type())
113 }
114
115 out.Append(ir.NewDecl(g.pos(decl), ir.ODCLTYPE, name))
116 return
117 }
118
119
120 types.DeferCheckSize()
121
122 name, obj := g.def(decl.Name)
123 ntyp, otyp := name.Type(), obj.Type()
124 if ir.CurFunc != nil {
125 typecheck.TypeGen++
126 ntyp.Vargen = typecheck.TypeGen
127 }
128
129 pragmas := g.pragmaFlags(decl.Pragma, typePragmas)
130 name.SetPragma(pragmas)
131
132 if pragmas&ir.NotInHeap != 0 {
133 ntyp.SetNotInHeap(true)
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156 ntyp.SetUnderlying(g.typeExpr(decl.Type))
157 if len(decl.TParamList) > 0 {
158
159
160
161 ntyp.SetHasTParam(true)
162 }
163 types.ResumeCheckSize()
164
165 if otyp, ok := otyp.(*types2.Named); ok && otyp.NumMethods() != 0 {
166 methods := make([]*types.Field, otyp.NumMethods())
167 for i := range methods {
168 m := otyp.Method(i)
169 meth := g.obj(m)
170 methods[i] = types.NewField(meth.Pos(), g.selector(m), meth.Type())
171 methods[i].Nname = meth
172 }
173 ntyp.Methods().Set(methods)
174 }
175
176 out.Append(ir.NewDecl(g.pos(decl), ir.ODCLTYPE, name))
177 }
178
179 func (g *irgen) varDecl(out *ir.Nodes, decl *syntax.VarDecl) {
180 pos := g.pos(decl)
181 names := make([]*ir.Name, len(decl.NameList))
182 for i, name := range decl.NameList {
183 names[i], _ = g.def(name)
184 }
185 values := g.exprList(decl.Values)
186
187 if decl.Pragma != nil {
188 pragma := decl.Pragma.(*pragmas)
189
190 varEmbed(g.makeXPos, names[0], decl, pragma, true)
191 g.reportUnused(pragma)
192 }
193
194 var as2 *ir.AssignListStmt
195 if len(values) != 0 && len(names) != len(values) {
196 as2 = ir.NewAssignListStmt(pos, ir.OAS2, make([]ir.Node, len(names)), values)
197 }
198
199 for i, name := range names {
200 if ir.CurFunc != nil {
201 out.Append(ir.NewDecl(pos, ir.ODCL, name))
202 }
203 if as2 != nil {
204 as2.Lhs[i] = name
205 name.Defn = as2
206 } else {
207 as := ir.NewAssignStmt(pos, name, nil)
208 if len(values) != 0 {
209 as.Y = values[i]
210 name.Defn = as
211 } else if ir.CurFunc == nil {
212 name.Defn = as
213 }
214 lhs := []ir.Node{as.X}
215 rhs := []ir.Node{}
216 if as.Y != nil {
217 rhs = []ir.Node{as.Y}
218 }
219 transformAssign(as, lhs, rhs)
220 as.X = lhs[0]
221 if as.Y != nil {
222 as.Y = rhs[0]
223 }
224 as.SetTypecheck(1)
225 out.Append(as)
226 }
227 }
228 if as2 != nil {
229 transformAssign(as2, as2.Lhs, as2.Rhs)
230 as2.SetTypecheck(1)
231 out.Append(as2)
232 }
233 }
234
235
236
237 func (g *irgen) pragmaFlags(pragma syntax.Pragma, allowed ir.PragmaFlag) ir.PragmaFlag {
238 if pragma == nil {
239 return 0
240 }
241 p := pragma.(*pragmas)
242 present := p.Flag & allowed
243 p.Flag &^= allowed
244 g.reportUnused(p)
245 return present
246 }
247
248
249 func (g *irgen) reportUnused(pragma *pragmas) {
250 for _, pos := range pragma.Pos {
251 if pos.Flag&pragma.Flag != 0 {
252 base.ErrorfAt(g.makeXPos(pos.Pos), "misplaced compiler directive")
253 }
254 }
255 if len(pragma.Embeds) > 0 {
256 for _, e := range pragma.Embeds {
257 base.ErrorfAt(g.makeXPos(e.Pos), "misplaced go:embed directive")
258 }
259 }
260 }
261
View as plain text