@@ -241,57 +241,11 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
241
241
242
242
case CK_IntegralComplexToBoolean:
243
243
case CK_FloatingComplexToBoolean: {
244
- PrimType ElemT = classifyComplexElementType (SubExpr->getType ());
245
- // We emit the expression (__real(E) != 0 || __imag(E) != 0)
246
- // for us, that means (bool)E[0] || (bool)E[1]
244
+ if (DiscardResult)
245
+ return this ->discard (SubExpr);
247
246
if (!this ->visit (SubExpr))
248
247
return false ;
249
- if (!this ->emitConstUint8 (0 , CE))
250
- return false ;
251
- if (!this ->emitArrayElemPtrUint8 (CE))
252
- return false ;
253
- if (!this ->emitLoadPop (ElemT, CE))
254
- return false ;
255
- if (ElemT == PT_Float) {
256
- if (!this ->emitCastFloatingIntegral (PT_Bool, CE))
257
- return false ;
258
- } else {
259
- if (!this ->emitCast (ElemT, PT_Bool, CE))
260
- return false ;
261
- }
262
-
263
- // We now have the bool value of E[0] on the stack.
264
- LabelTy LabelTrue = this ->getLabel ();
265
- if (!this ->jumpTrue (LabelTrue))
266
- return false ;
267
-
268
- if (!this ->emitConstUint8 (1 , CE))
269
- return false ;
270
- if (!this ->emitArrayElemPtrPopUint8 (CE))
271
- return false ;
272
- if (!this ->emitLoadPop (ElemT, CE))
273
- return false ;
274
- if (ElemT == PT_Float) {
275
- if (!this ->emitCastFloatingIntegral (PT_Bool, CE))
276
- return false ;
277
- } else {
278
- if (!this ->emitCast (ElemT, PT_Bool, CE))
279
- return false ;
280
- }
281
- // Leave the boolean value of E[1] on the stack.
282
- LabelTy EndLabel = this ->getLabel ();
283
- this ->jump (EndLabel);
284
-
285
- this ->emitLabel (LabelTrue);
286
- if (!this ->emitPopPtr (CE))
287
- return false ;
288
- if (!this ->emitConstBool (true , CE))
289
- return false ;
290
-
291
- this ->fallthrough (EndLabel);
292
- this ->emitLabel (EndLabel);
293
-
294
- return true ;
248
+ return this ->emitComplexBoolCast (SubExpr);
295
249
}
296
250
297
251
case CK_IntegralComplexToReal:
@@ -2223,8 +2177,15 @@ bool ByteCodeExprGen<Emitter>::visitInitializer(const Expr *E) {
2223
2177
template <class Emitter >
2224
2178
bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) {
2225
2179
std::optional<PrimType> T = classify (E->getType ());
2226
- if (!T)
2180
+ if (!T) {
2181
+ // Convert complex values to bool.
2182
+ if (E->getType ()->isAnyComplexType ()) {
2183
+ if (!this ->visit (E))
2184
+ return false ;
2185
+ return this ->emitComplexBoolCast (E);
2186
+ }
2227
2187
return false ;
2188
+ }
2228
2189
2229
2190
if (!this ->visit (E))
2230
2191
return false ;
@@ -3383,6 +3344,63 @@ bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
3383
3344
return true ;
3384
3345
}
3385
3346
3347
+ template <class Emitter >
3348
+ bool ByteCodeExprGen<Emitter>::emitComplexBoolCast(const Expr *E) {
3349
+ assert (!DiscardResult);
3350
+ PrimType ElemT = classifyComplexElementType (E->getType ());
3351
+ // We emit the expression (__real(E) != 0 || __imag(E) != 0)
3352
+ // for us, that means (bool)E[0] || (bool)E[1]
3353
+ if (!this ->emitConstUint8 (0 , E))
3354
+ return false ;
3355
+ if (!this ->emitArrayElemPtrUint8 (E))
3356
+ return false ;
3357
+ if (!this ->emitLoadPop (ElemT, E))
3358
+ return false ;
3359
+ if (ElemT == PT_Float) {
3360
+ if (!this ->emitCastFloatingIntegral (PT_Bool, E))
3361
+ return false ;
3362
+ } else {
3363
+ if (!this ->emitCast (ElemT, PT_Bool, E))
3364
+ return false ;
3365
+ }
3366
+
3367
+ // We now have the bool value of E[0] on the stack.
3368
+ LabelTy LabelTrue = this ->getLabel ();
3369
+ if (!this ->jumpTrue (LabelTrue))
3370
+ return false ;
3371
+
3372
+ if (!this ->emitConstUint8 (1 , E))
3373
+ return false ;
3374
+ if (!this ->emitArrayElemPtrPopUint8 (E))
3375
+ return false ;
3376
+ if (!this ->emitLoadPop (ElemT, E))
3377
+ return false ;
3378
+ if (ElemT == PT_Float) {
3379
+ if (!this ->emitCastFloatingIntegral (PT_Bool, E))
3380
+ return false ;
3381
+ } else {
3382
+ if (!this ->emitCast (ElemT, PT_Bool, E))
3383
+ return false ;
3384
+ }
3385
+ // Leave the boolean value of E[1] on the stack.
3386
+ LabelTy EndLabel = this ->getLabel ();
3387
+ this ->jump (EndLabel);
3388
+
3389
+ this ->emitLabel (LabelTrue);
3390
+ if (!this ->emitPopPtr (E))
3391
+ return false ;
3392
+ if (!this ->emitConstBool (true , E))
3393
+ return false ;
3394
+
3395
+ this ->fallthrough (EndLabel);
3396
+ this ->emitLabel (EndLabel);
3397
+
3398
+ return true ;
3399
+ }
3400
+
3401
+ // / When calling this, we have a pointer of the local-to-destroy
3402
+ // / on the stack.
3403
+ // / Emit destruction of record types (or arrays of record types).
3386
3404
template <class Emitter >
3387
3405
bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Record *R) {
3388
3406
assert (R);
0 commit comments