Mercurial > projects > ddmd
annotate dmd/CondExp.d @ 191:52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
Also changed Array allocation policy:
Now doesn't reallocate but malloc's, followed by a memcpy (no free).
(this fixes a crash while compiling druntime. Same bug in dmd)
author | korDen@korDen-pc |
---|---|
date | Sun, 25 Mar 2012 03:11:12 +0400 |
parents | b0d41ff5e0df |
children |
rev | line source |
---|---|
0 | 1 module dmd.CondExp; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.BinExp; |
5 import dmd.Loc; | |
123 | 6 import dmd.PtrExp; |
0 | 7 import dmd.MATCH; |
8 import dmd.Expression; | |
129 | 9 import dmd.GlobalExpressions; |
0 | 10 import dmd.Scope; |
11 import dmd.InterState; | |
12 import dmd.OutBuffer; | |
13 import dmd.HdrGenState; | |
14 import dmd.Type; | |
15 import dmd.InlineCostState; | |
16 import dmd.InlineDoState; | |
17 import dmd.InlineScanState; | |
18 import dmd.IRState; | |
19 import dmd.TOK; | |
20 import dmd.TY; | |
21 import dmd.WANT; | |
50 | 22 import dmd.PREC; |
0 | 23 import dmd.Global; |
24 | |
25 import dmd.backend.elem; | |
26 import dmd.backend.Util; | |
27 import dmd.backend.OPER; | |
28 import dmd.backend.mTY; | |
29 import dmd.backend.TYM; | |
30 import dmd.codegen.Util; | |
31 | |
50 | 32 import dmd.expression.Util; |
33 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
34 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
35 |
0 | 36 class CondExp : BinExp |
37 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
38 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
39 |
0 | 40 Expression econd; |
41 | |
42 this(Loc loc, Expression econd, Expression e1, Expression e2) | |
43 { | |
178 | 44 register(); |
0 | 45 super(loc, TOK.TOKquestion, CondExp.sizeof, e1, e2); |
46 this.econd = econd; | |
47 } | |
48 | |
72 | 49 override Expression syntaxCopy() |
0 | 50 { |
43 | 51 return new CondExp(loc, econd.syntaxCopy(), e1.syntaxCopy(), e2.syntaxCopy()); |
0 | 52 } |
53 | |
72 | 54 override Expression semantic(Scope sc) |
0 | 55 { |
56 Type t1; | |
57 Type t2; | |
58 uint cs0; | |
59 uint cs1; | |
60 | |
61 version (LOGSEMANTIC) { | |
62 printf("CondExp.semantic('%s')\n", toChars()); | |
63 } | |
64 if (type) | |
65 return this; | |
66 | |
67 econd = econd.semantic(sc); | |
68 econd = resolveProperties(sc, econd); | |
69 econd = econd.checkToPointer(); | |
70 econd = econd.checkToBoolean(); | |
71 | |
72 static if (false) { | |
73 /* this cannot work right because the types of e1 and e2 | |
74 * both contribute to the type of the result. | |
75 */ | |
76 if (sc.flags & SCOPEstaticif) | |
77 { | |
78 /* If in static if, don't evaluate what we don't have to. | |
79 */ | |
80 econd = econd.optimize(WANTflags); | |
81 if (econd.isBool(TRUE)) | |
82 { | |
83 e1 = e1.semantic(sc); | |
84 e1 = resolveProperties(sc, e1); | |
85 return e1; | |
86 } | |
87 else if (econd.isBool(FALSE)) | |
88 { | |
89 e2 = e2.semantic(sc); | |
90 e2 = resolveProperties(sc, e2); | |
91 return e2; | |
92 } | |
93 } | |
94 } | |
95 | |
96 cs0 = sc.callSuper; | |
97 e1 = e1.semantic(sc); | |
98 e1 = resolveProperties(sc, e1); | |
99 cs1 = sc.callSuper; | |
100 sc.callSuper = cs0; | |
101 e2 = e2.semantic(sc); | |
102 e2 = resolveProperties(sc, e2); | |
103 sc.mergeCallSuper(loc, cs1); | |
104 | |
105 // If either operand is void, the result is void | |
106 t1 = e1.type; | |
107 t2 = e2.type; | |
108 if (t1.ty == Tvoid || t2.ty == Tvoid) | |
109 type = Type.tvoid; | |
110 else if (t1 == t2) | |
111 type = t1; | |
112 else | |
113 { | |
114 typeCombine(sc); | |
115 switch (e1.type.toBasetype().ty) | |
116 { | |
117 case Tcomplex32: | |
118 case Tcomplex64: | |
119 case Tcomplex80: | |
120 e2 = e2.castTo(sc, e1.type); | |
121 break; | |
122 default: | |
123 break; | |
124 } | |
125 switch (e2.type.toBasetype().ty) | |
126 { | |
127 case Tcomplex32: | |
128 case Tcomplex64: | |
129 case Tcomplex80: | |
130 e1 = e1.castTo(sc, e2.type); | |
131 break; | |
132 default: | |
133 break; | |
134 } | |
135 if (type.toBasetype().ty == Tarray) | |
136 { | |
137 e1 = e1.castTo(sc, type); | |
138 e2 = e2.castTo(sc, type); | |
139 } | |
140 } | |
141 static if (false) { | |
142 printf("res: %s\n", type.toChars()); | |
143 printf("e1 : %s\n", e1.type.toChars()); | |
144 printf("e2 : %s\n", e2.type.toChars()); | |
145 } | |
146 return this; | |
147 } | |
148 | |
72 | 149 override Expression optimize(int result) |
0 | 150 { |
151 Expression e; | |
152 | |
153 econd = econd.optimize(WANTflags | (result & WANTinterpret)); | |
154 if (econd.isBool(true)) | |
155 e = e1.optimize(result); | |
156 else if (econd.isBool(false)) | |
157 e = e2.optimize(result); | |
158 else | |
159 { | |
160 e1 = e1.optimize(result); | |
161 e2 = e2.optimize(result); | |
162 e = this; | |
163 } | |
164 | |
165 return e; | |
166 } | |
167 | |
72 | 168 override Expression interpret(InterState istate) |
0 | 169 { |
129 | 170 version (LOG) { |
171 printf("CondExp.interpret() %.*s\n", toChars()); | |
172 } | |
173 Expression e = econd.interpret(istate); | |
174 if (e !is EXP_CANT_INTERPRET) | |
175 { | |
176 if (e.isBool(true)) | |
177 e = e1.interpret(istate); | |
178 else if (e.isBool(false)) | |
179 e = e2.interpret(istate); | |
180 else | |
181 e = EXP_CANT_INTERPRET; | |
182 } | |
183 return e; | |
0 | 184 } |
185 | |
72 | 186 override void checkEscape() |
0 | 187 { |
188 e1.checkEscape(); | |
189 e2.checkEscape(); | |
190 } | |
191 | |
135 | 192 override void checkEscapeRef() |
193 { | |
194 e1.checkEscapeRef(); | |
195 e2.checkEscapeRef(); | |
196 } | |
197 | |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
198 override bool isLvalue() |
0 | 199 { |
123 | 200 return e1.isLvalue() && e2.isLvalue(); |
0 | 201 } |
202 | |
123 | 203 override Expression toLvalue(Scope sc, Expression ex) |
0 | 204 { |
123 | 205 PtrExp e; |
206 | |
207 // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2) | |
208 e = new PtrExp(loc, this, type); | |
209 | |
210 e1 = e1.addressOf(sc); | |
211 //e1 = e1.toLvalue(sc, null); | |
212 | |
213 e2 = e2.addressOf(sc); | |
214 //e2 = e2.toLvalue(sc, null); | |
215 | |
216 typeCombine(sc); | |
217 | |
218 type = e2.type; | |
219 return e; | |
0 | 220 } |
221 | |
72 | 222 override Expression modifiableLvalue(Scope sc, Expression e) |
0 | 223 { |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
224 //error("conditional expression %s is not a modifiable lvalue", toChars()); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
225 e1 = e1.modifiableLvalue(sc, e1); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
226 e2 = e2.modifiableLvalue(sc, e1); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
227 return toLvalue(sc, this); |
0 | 228 } |
229 | |
72 | 230 override Expression checkToBoolean() |
0 | 231 { |
123 | 232 e1 = e1.checkToBoolean(); |
233 e2 = e2.checkToBoolean(); | |
234 return this; | |
0 | 235 } |
236 | |
72 | 237 override bool checkSideEffect(int flag) |
0 | 238 { |
64 | 239 if (flag == 2) |
240 { | |
241 return econd.checkSideEffect(2) || e1.checkSideEffect(2) || e2.checkSideEffect(2); | |
242 } | |
243 else | |
244 { | |
245 econd.checkSideEffect(1); | |
246 e1.checkSideEffect(flag); | |
247 return e2.checkSideEffect(flag); | |
248 } | |
0 | 249 } |
250 | |
72 | 251 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 252 { |
50 | 253 expToCBuffer(buf, hgs, econd, PREC_oror); |
254 buf.writestring(" ? "); | |
255 expToCBuffer(buf, hgs, e1, PREC_expr); | |
256 buf.writestring(" : "); | |
257 expToCBuffer(buf, hgs, e2, PREC_cond); | |
0 | 258 } |
259 | |
72 | 260 override MATCH implicitConvTo(Type t) |
0 | 261 { |
262 MATCH m1 = e1.implicitConvTo(t); | |
263 MATCH m2 = e2.implicitConvTo(t); | |
264 //printf("CondExp: m1 %d m2 %d\n", m1, m2); | |
265 | |
266 // Pick the worst match | |
267 return (m1 < m2) ? m1 : m2; | |
268 } | |
269 | |
72 | 270 override Expression castTo(Scope sc, Type t) |
0 | 271 { |
272 Expression e = this; | |
273 | |
274 if (type !is t) | |
275 { | |
276 if (1 || e1.op == TOKstring || e2.op == TOKstring) | |
277 { | |
278 e = new CondExp(loc, econd, e1.castTo(sc, t), e2.castTo(sc, t)); | |
279 e.type = t; | |
280 } | |
281 else | |
282 e = Expression.castTo(sc, t); | |
283 } | |
284 return e; | |
285 } | |
286 | |
72 | 287 override void scanForNestedRef(Scope sc) |
0 | 288 { |
289 assert(false); | |
290 } | |
291 | |
72 | 292 override bool canThrow() |
0 | 293 { |
294 return econd.canThrow() || e1.canThrow() || e2.canThrow(); | |
295 } | |
296 | |
72 | 297 override int inlineCost(InlineCostState* ics) |
0 | 298 { |
299 return 1 + e1.inlineCost(ics) + e2.inlineCost(ics) + econd.inlineCost(ics); | |
300 } | |
301 | |
72 | 302 override Expression doInline(InlineDoState ids) |
0 | 303 { |
304 CondExp ce = cast(CondExp)copy(); | |
305 | |
306 ce.econd = econd.doInline(ids); | |
307 ce.e1 = e1.doInline(ids); | |
308 ce.e2 = e2.doInline(ids); | |
309 return ce; | |
310 } | |
311 | |
72 | 312 override Expression inlineScan(InlineScanState* iss) |
0 | 313 { |
314 econd = econd.inlineScan(iss); | |
315 e1 = e1.inlineScan(iss); | |
316 e2 = e2.inlineScan(iss); | |
317 return this; | |
318 } | |
319 | |
72 | 320 override elem* toElem(IRState* irs) |
0 | 321 { |
322 elem* eleft; | |
323 elem* eright; | |
324 | |
325 elem* ec = econd.toElem(irs); | |
326 | |
327 eleft = e1.toElem(irs); | |
328 tym_t ty = eleft.Ety; | |
329 if (global.params.cov && e1.loc.linnum) | |
330 eleft = el_combine(incUsageElem(irs, e1.loc), eleft); | |
331 | |
332 eright = e2.toElem(irs); | |
333 if (global.params.cov && e2.loc.linnum) | |
334 eright = el_combine(incUsageElem(irs, e2.loc), eright); | |
335 | |
336 elem* e = el_bin(OPcond, ty, ec, el_bin(OPcolon, ty, eleft, eright)); | |
337 if (tybasic(ty) == TYstruct) | |
338 e.Enumbytes = cast(uint)e1.type.size(); | |
339 | |
340 el_setLoc(e, loc); | |
341 return e; | |
342 } | |
72 | 343 } |