1
2
3
4
5 package reflectdata
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/compile/internal/types"
11 "cmd/internal/src"
12 )
13
14 func hasRType(n, rtype ir.Node, fieldName string) bool {
15 if rtype != nil {
16 return true
17 }
18
19 return false
20 }
21
22
23 func assertOp(n ir.Node, op ir.Op) {
24 base.AssertfAt(n.Op() == op, n.Pos(), "want %v, have %v", op, n)
25 }
26
27
28 func assertOp2(n ir.Node, op1, op2 ir.Op) {
29 base.AssertfAt(n.Op() == op1 || n.Op() == op2, n.Pos(), "want %v or %v, have %v", op1, op2, n)
30 }
31
32
33
34 func kindRType(pos src.XPos, typ *types.Type, k types.Kind) ir.Node {
35 base.AssertfAt(typ.Kind() == k, pos, "want %v type, have %v", k, typ)
36 return TypePtrAt(pos, typ)
37 }
38
39
40
41 func mapRType(pos src.XPos, typ *types.Type) ir.Node {
42 return kindRType(pos, typ, types.TMAP)
43 }
44
45
46
47 func chanRType(pos src.XPos, typ *types.Type) ir.Node {
48 return kindRType(pos, typ, types.TCHAN)
49 }
50
51
52
53
54 func sliceElemRType(pos src.XPos, typ *types.Type) ir.Node {
55 base.AssertfAt(typ.IsSlice(), pos, "want slice type, have %v", typ)
56 return TypePtrAt(pos, typ.Elem())
57 }
58
59
60
61
62 func concreteRType(pos src.XPos, typ *types.Type) ir.Node {
63 base.AssertfAt(!typ.IsInterface(), pos, "want non-interface type, have %v", typ)
64 return TypePtrAt(pos, typ)
65 }
66
67
68
69
70 func AppendElemRType(pos src.XPos, n *ir.CallExpr) ir.Node {
71 assertOp(n, ir.OAPPEND)
72 if hasRType(n, n.RType, "RType") {
73 return n.RType
74 }
75 return sliceElemRType(pos, n.Type())
76 }
77
78
79
80
81
82 func CompareRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
83 assertOp2(n, ir.OEQ, ir.ONE)
84 base.AssertfAt(n.X.Type().IsInterface() != n.Y.Type().IsInterface(), n.Pos(), "expect mixed interface and non-interface, have %L and %L", n.X, n.Y)
85 if hasRType(n, n.RType, "RType") {
86 return n.RType
87 }
88 typ := n.X.Type()
89 if typ.IsInterface() {
90 typ = n.Y.Type()
91 }
92 return concreteRType(pos, typ)
93 }
94
95
96
97
98
99
100
101
102 func ConvIfaceTypeWord(pos src.XPos, n *ir.ConvExpr) ir.Node {
103 assertOp(n, ir.OCONVIFACE)
104 src, dst := n.X.Type(), n.Type()
105 base.AssertfAt(dst.IsInterface(), n.Pos(), "want interface type, have %L", n)
106 if hasRType(n, n.TypeWord, "TypeWord") {
107 return n.TypeWord
108 }
109 if dst.IsEmptyInterface() {
110 return concreteRType(pos, src)
111 }
112 if !src.IsInterface() {
113 return ITabAddrAt(pos, src, dst)
114 }
115 return TypePtrAt(pos, dst)
116 }
117
118
119
120
121
122 func ConvIfaceSrcRType(pos src.XPos, n *ir.ConvExpr) ir.Node {
123 assertOp(n, ir.OCONVIFACE)
124 if hasRType(n, n.SrcRType, "SrcRType") {
125 return n.SrcRType
126 }
127 return concreteRType(pos, n.X.Type())
128 }
129
130
131
132
133 func CopyElemRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
134 assertOp(n, ir.OCOPY)
135 if hasRType(n, n.RType, "RType") {
136 return n.RType
137 }
138 return sliceElemRType(pos, n.X.Type())
139 }
140
141
142
143
144 func DeleteMapRType(pos src.XPos, n *ir.CallExpr) ir.Node {
145 assertOp(n, ir.ODELETE)
146 if hasRType(n, n.RType, "RType") {
147 return n.RType
148 }
149 return mapRType(pos, n.Args[0].Type())
150 }
151
152
153
154
155 func IndexMapRType(pos src.XPos, n *ir.IndexExpr) ir.Node {
156 assertOp(n, ir.OINDEXMAP)
157 if hasRType(n, n.RType, "RType") {
158 return n.RType
159 }
160 return mapRType(pos, n.X.Type())
161 }
162
163
164
165
166 func MakeChanRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
167 assertOp(n, ir.OMAKECHAN)
168 if hasRType(n, n.RType, "RType") {
169 return n.RType
170 }
171 return chanRType(pos, n.Type())
172 }
173
174
175
176
177 func MakeMapRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
178 assertOp(n, ir.OMAKEMAP)
179 if hasRType(n, n.RType, "RType") {
180 return n.RType
181 }
182 return mapRType(pos, n.Type())
183 }
184
185
186
187
188 func MakeSliceElemRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
189 assertOp2(n, ir.OMAKESLICE, ir.OMAKESLICECOPY)
190 if hasRType(n, n.RType, "RType") {
191 return n.RType
192 }
193 return sliceElemRType(pos, n.Type())
194 }
195
196
197
198
199 func RangeMapRType(pos src.XPos, n *ir.RangeStmt) ir.Node {
200 assertOp(n, ir.ORANGE)
201 if hasRType(n, n.RType, "RType") {
202 return n.RType
203 }
204 return mapRType(pos, n.X.Type())
205 }
206
207
208
209
210 func UnsafeSliceElemRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
211 assertOp(n, ir.OUNSAFESLICE)
212 if hasRType(n, n.RType, "RType") {
213 return n.RType
214 }
215 return sliceElemRType(pos, n.Type())
216 }
217
View as plain text