1
2
3
4
5 package ir
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/types"
10 "cmd/internal/src"
11 "fmt"
12 )
13
14
15
16
17
18
19
20
21
22
23
24 type Ntype interface {
25 Node
26 CanBeNtype()
27 }
28
29
30
31 type miniType struct {
32 miniNode
33 typ *types.Type
34 }
35
36 func (*miniType) CanBeNtype() {}
37
38 func (n *miniType) Type() *types.Type { return n.typ }
39
40
41
42
43
44
45
46
47
48
49 func (n *miniType) setOTYPE(t *types.Type, self Ntype) {
50 if n.typ != nil {
51 panic(n.op.String() + " SetType: type already set")
52 }
53 n.op = OTYPE
54 n.typ = t
55 t.SetNod(self)
56 }
57
58 func (n *miniType) Sym() *types.Sym { return nil }
59 func (n *miniType) Implicit() bool { return false }
60
61
62 type ChanType struct {
63 miniType
64 Elem Ntype
65 Dir types.ChanDir
66 }
67
68 func NewChanType(pos src.XPos, elem Ntype, dir types.ChanDir) *ChanType {
69 n := &ChanType{Elem: elem, Dir: dir}
70 n.op = OTCHAN
71 n.pos = pos
72 return n
73 }
74
75 func (n *ChanType) SetOTYPE(t *types.Type) {
76 n.setOTYPE(t, n)
77 n.Elem = nil
78 }
79
80
81 type MapType struct {
82 miniType
83 Key Ntype
84 Elem Ntype
85 }
86
87 func NewMapType(pos src.XPos, key, elem Ntype) *MapType {
88 n := &MapType{Key: key, Elem: elem}
89 n.op = OTMAP
90 n.pos = pos
91 return n
92 }
93
94 func (n *MapType) SetOTYPE(t *types.Type) {
95 n.setOTYPE(t, n)
96 n.Key = nil
97 n.Elem = nil
98 }
99
100
101 type StructType struct {
102 miniType
103 Fields []*Field
104 }
105
106 func NewStructType(pos src.XPos, fields []*Field) *StructType {
107 n := &StructType{Fields: fields}
108 n.op = OTSTRUCT
109 n.pos = pos
110 return n
111 }
112
113 func (n *StructType) SetOTYPE(t *types.Type) {
114 n.setOTYPE(t, n)
115 n.Fields = nil
116 }
117
118
119 type InterfaceType struct {
120 miniType
121 Methods []*Field
122 }
123
124 func NewInterfaceType(pos src.XPos, methods []*Field) *InterfaceType {
125 n := &InterfaceType{Methods: methods}
126 n.op = OTINTER
127 n.pos = pos
128 return n
129 }
130
131 func (n *InterfaceType) SetOTYPE(t *types.Type) {
132 n.setOTYPE(t, n)
133 n.Methods = nil
134 }
135
136
137 type FuncType struct {
138 miniType
139 Recv *Field
140 Params []*Field
141 Results []*Field
142 }
143
144 func NewFuncType(pos src.XPos, rcvr *Field, args, results []*Field) *FuncType {
145 n := &FuncType{Recv: rcvr, Params: args, Results: results}
146 n.op = OTFUNC
147 n.pos = pos
148 return n
149 }
150
151 func (n *FuncType) SetOTYPE(t *types.Type) {
152 n.setOTYPE(t, n)
153 n.Recv = nil
154 n.Params = nil
155 n.Results = nil
156 }
157
158
159
160 type Field struct {
161 Pos src.XPos
162 Sym *types.Sym
163 Ntype Ntype
164 Type *types.Type
165 Embedded bool
166 IsDDD bool
167 Note string
168 Decl *Name
169 }
170
171 func NewField(pos src.XPos, sym *types.Sym, ntyp Ntype, typ *types.Type) *Field {
172 return &Field{Pos: pos, Sym: sym, Ntype: ntyp, Type: typ}
173 }
174
175 func (f *Field) String() string {
176 var typ string
177 if f.Type != nil {
178 typ = fmt.Sprint(f.Type)
179 } else {
180 typ = fmt.Sprint(f.Ntype)
181 }
182 if f.Sym != nil {
183 return fmt.Sprintf("%v %v", f.Sym, typ)
184 }
185 return typ
186 }
187
188
189
190
191 func copyField(f *Field) *Field {
192 if f == nil {
193 return nil
194 }
195 c := *f
196 return &c
197 }
198 func doField(f *Field, do func(Node) bool) bool {
199 if f == nil {
200 return false
201 }
202 if f.Decl != nil && do(f.Decl) {
203 return true
204 }
205 if f.Ntype != nil && do(f.Ntype) {
206 return true
207 }
208 return false
209 }
210 func editField(f *Field, edit func(Node) Node) {
211 if f == nil {
212 return
213 }
214 if f.Decl != nil {
215 f.Decl = edit(f.Decl).(*Name)
216 }
217 if f.Ntype != nil {
218 f.Ntype = edit(f.Ntype).(Ntype)
219 }
220 }
221
222 func copyFields(list []*Field) []*Field {
223 out := make([]*Field, len(list))
224 for i, f := range list {
225 out[i] = copyField(f)
226 }
227 return out
228 }
229 func doFields(list []*Field, do func(Node) bool) bool {
230 for _, x := range list {
231 if doField(x, do) {
232 return true
233 }
234 }
235 return false
236 }
237 func editFields(list []*Field, edit func(Node) Node) {
238 for _, f := range list {
239 editField(f, edit)
240 }
241 }
242
243
244
245 type SliceType struct {
246 miniType
247 Elem Ntype
248 DDD bool
249 }
250
251 func NewSliceType(pos src.XPos, elem Ntype) *SliceType {
252 n := &SliceType{Elem: elem}
253 n.op = OTSLICE
254 n.pos = pos
255 return n
256 }
257
258 func (n *SliceType) SetOTYPE(t *types.Type) {
259 n.setOTYPE(t, n)
260 n.Elem = nil
261 }
262
263
264
265 type ArrayType struct {
266 miniType
267 Len Node
268 Elem Ntype
269 }
270
271 func NewArrayType(pos src.XPos, len Node, elem Ntype) *ArrayType {
272 n := &ArrayType{Len: len, Elem: elem}
273 n.op = OTARRAY
274 n.pos = pos
275 return n
276 }
277
278 func (n *ArrayType) SetOTYPE(t *types.Type) {
279 n.setOTYPE(t, n)
280 n.Len = nil
281 n.Elem = nil
282 }
283
284
285 type typeNode struct {
286 miniNode
287 typ *types.Type
288 }
289
290 func newTypeNode(pos src.XPos, typ *types.Type) *typeNode {
291 n := &typeNode{typ: typ}
292 n.pos = pos
293 n.op = OTYPE
294 return n
295 }
296
297 func (n *typeNode) Type() *types.Type { return n.typ }
298 func (n *typeNode) Sym() *types.Sym { return n.typ.Sym() }
299 func (n *typeNode) CanBeNtype() {}
300
301
302 func TypeNode(t *types.Type) Ntype {
303 return TypeNodeAt(src.NoXPos, t)
304 }
305
306
307
308
309
310
311
312
313 func TypeNodeAt(pos src.XPos, t *types.Type) Ntype {
314 if n := t.Obj(); n != nil {
315 if n.Type() != t {
316 base.Fatalf("type skew: %v has type %v, but expected %v", n, n.Type(), t)
317 }
318 return n.(Ntype)
319 }
320 return newTypeNode(pos, t)
321 }
322
323
324 type DynamicType struct {
325 miniExpr
326 X Node
327 ITab Node
328 }
329
330 func NewDynamicType(pos src.XPos, x Node) *DynamicType {
331 n := &DynamicType{X: x}
332 n.pos = pos
333 n.op = ODYNAMICTYPE
334 return n
335 }
336
View as plain text