@@ -393,12 +393,16 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
393
393
if (BO->isLogicalOp ())
394
394
return this ->VisitLogicalBinOp (BO);
395
395
396
- if (BO->getType ()->isAnyComplexType ())
397
- return this ->VisitComplexBinOp (BO);
398
-
399
396
const Expr *LHS = BO->getLHS ();
400
397
const Expr *RHS = BO->getRHS ();
401
398
399
+ if (BO->getType ()->isAnyComplexType ())
400
+ return this ->VisitComplexBinOp (BO);
401
+ if ((LHS->getType ()->isAnyComplexType () ||
402
+ RHS->getType ()->isAnyComplexType ()) &&
403
+ BO->isComparisonOp ())
404
+ return this ->emitComplexComparison (LHS, RHS, BO);
405
+
402
406
if (BO->isPtrMemOp ())
403
407
return this ->visit (RHS);
404
408
@@ -3410,6 +3414,102 @@ bool ByteCodeExprGen<Emitter>::emitComplexBoolCast(const Expr *E) {
3410
3414
return true ;
3411
3415
}
3412
3416
3417
+ template <class Emitter >
3418
+ bool ByteCodeExprGen<Emitter>::emitComplexComparison(const Expr *LHS,
3419
+ const Expr *RHS,
3420
+ const BinaryOperator *E) {
3421
+ assert (E->isComparisonOp ());
3422
+ assert (!Initializing);
3423
+ assert (!DiscardResult);
3424
+
3425
+ PrimType ElemT;
3426
+ bool LHSIsComplex;
3427
+ unsigned LHSOffset;
3428
+ if (LHS->getType ()->isAnyComplexType ()) {
3429
+ LHSIsComplex = true ;
3430
+ ElemT = classifyComplexElementType (LHS->getType ());
3431
+ LHSOffset = allocateLocalPrimitive (LHS, PT_Ptr, /* IsConst=*/ true ,
3432
+ /* IsExtended=*/ false );
3433
+ if (!this ->visit (LHS))
3434
+ return false ;
3435
+ if (!this ->emitSetLocal (PT_Ptr, LHSOffset, E))
3436
+ return false ;
3437
+ } else {
3438
+ LHSIsComplex = false ;
3439
+ PrimType LHST = classifyPrim (LHS->getType ());
3440
+ LHSOffset = this ->allocateLocalPrimitive (LHS, LHST, true , false );
3441
+ if (!this ->visit (LHS))
3442
+ return false ;
3443
+ if (!this ->emitSetLocal (LHST, LHSOffset, E))
3444
+ return false ;
3445
+ }
3446
+
3447
+ bool RHSIsComplex;
3448
+ unsigned RHSOffset;
3449
+ if (RHS->getType ()->isAnyComplexType ()) {
3450
+ RHSIsComplex = true ;
3451
+ ElemT = classifyComplexElementType (RHS->getType ());
3452
+ RHSOffset = allocateLocalPrimitive (RHS, PT_Ptr, /* IsConst=*/ true ,
3453
+ /* IsExtended=*/ false );
3454
+ if (!this ->visit (RHS))
3455
+ return false ;
3456
+ if (!this ->emitSetLocal (PT_Ptr, RHSOffset, E))
3457
+ return false ;
3458
+ } else {
3459
+ RHSIsComplex = false ;
3460
+ PrimType RHST = classifyPrim (RHS->getType ());
3461
+ RHSOffset = this ->allocateLocalPrimitive (RHS, RHST, true , false );
3462
+ if (!this ->visit (RHS))
3463
+ return false ;
3464
+ if (!this ->emitSetLocal (RHST, RHSOffset, E))
3465
+ return false ;
3466
+ }
3467
+
3468
+ auto getElem = [&](unsigned LocalOffset, unsigned Index,
3469
+ bool IsComplex) -> bool {
3470
+ if (IsComplex) {
3471
+ if (!this ->emitGetLocal (PT_Ptr, LocalOffset, E))
3472
+ return false ;
3473
+ return this ->emitArrayElemPop (ElemT, Index, E);
3474
+ }
3475
+ return this ->emitGetLocal (ElemT, LocalOffset, E);
3476
+ };
3477
+
3478
+ for (unsigned I = 0 ; I != 2 ; ++I) {
3479
+ // Get both values.
3480
+ if (!getElem (LHSOffset, I, LHSIsComplex))
3481
+ return false ;
3482
+ if (!getElem (RHSOffset, I, RHSIsComplex))
3483
+ return false ;
3484
+ // And compare them.
3485
+ if (!this ->emitEQ (ElemT, E))
3486
+ return false ;
3487
+
3488
+ if (!this ->emitCastBoolUint8 (E))
3489
+ return false ;
3490
+ }
3491
+
3492
+ // We now have two bool values on the stack. Compare those.
3493
+ if (!this ->emitAddUint8 (E))
3494
+ return false ;
3495
+ if (!this ->emitConstUint8 (2 , E))
3496
+ return false ;
3497
+
3498
+ if (E->getOpcode () == BO_EQ) {
3499
+ if (!this ->emitEQUint8 (E))
3500
+ return false ;
3501
+ } else if (E->getOpcode () == BO_NE) {
3502
+ if (!this ->emitNEUint8 (E))
3503
+ return false ;
3504
+ } else
3505
+ return false ;
3506
+
3507
+ // In C, this returns an int.
3508
+ if (PrimType ResT = classifyPrim (E->getType ()); ResT != PT_Bool)
3509
+ return this ->emitCast (PT_Bool, ResT, E);
3510
+ return true ;
3511
+ }
3512
+
3413
3513
// / When calling this, we have a pointer of the local-to-destroy
3414
3514
// / on the stack.
3415
3515
// / Emit destruction of record types (or arrays of record types).
0 commit comments