@@ -3475,17 +3475,36 @@ class BinaryOperator : public Expr {
3475
3475
public:
3476
3476
typedef BinaryOperatorKind Opcode;
3477
3477
3478
- BinaryOperator (Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
3479
- ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
3480
- FPOptions FPFeatures)
3478
+ protected:
3479
+ size_t offsetOfTrailingStorage () const ;
3480
+
3481
+ // / Return a pointer to the trailing FPOptions
3482
+ FPOptions *getTrailingFPFeatures () {
3483
+ assert (BinaryOperatorBits.HasFPFeatures );
3484
+ return reinterpret_cast <FPOptions *>(reinterpret_cast <char *>(this ) +
3485
+ offsetOfTrailingStorage ());
3486
+ }
3487
+ const FPOptions *getTrailingFPFeatures () const {
3488
+ assert (BinaryOperatorBits.HasFPFeatures );
3489
+ return reinterpret_cast <const FPOptions *>(
3490
+ reinterpret_cast <const char *>(this ) + offsetOfTrailingStorage ());
3491
+ }
3492
+
3493
+ // / Build a binary operator, assuming that appropriate storage has been
3494
+ // / allocated for the trailing objects when needed.
3495
+ BinaryOperator (const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
3496
+ QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
3497
+ SourceLocation opLoc, FPOptions FPFeatures)
3481
3498
: Expr(BinaryOperatorClass, ResTy, VK, OK) {
3482
3499
BinaryOperatorBits.Opc = opc;
3483
- BinaryOperatorBits.FPFeatures = FPFeatures.getInt ();
3500
+ assert (!isCompoundAssignmentOp () &&
3501
+ " Use CompoundAssignOperator for compound assignments" );
3484
3502
BinaryOperatorBits.OpLoc = opLoc;
3485
3503
SubExprs[LHS] = lhs;
3486
3504
SubExprs[RHS] = rhs;
3487
- assert (!isCompoundAssignmentOp () &&
3488
- " Use CompoundAssignOperator for compound assignments" );
3505
+ BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage (Ctx);
3506
+ if (BinaryOperatorBits.HasFPFeatures )
3507
+ *getTrailingFPFeatures () = FPFeatures;
3489
3508
setDependence (computeDependence (this ));
3490
3509
}
3491
3510
@@ -3494,6 +3513,13 @@ class BinaryOperator : public Expr {
3494
3513
BinaryOperatorBits.Opc = BO_Comma;
3495
3514
}
3496
3515
3516
+ public:
3517
+ static BinaryOperator *CreateEmpty (const ASTContext &C, bool hasFPFeatures);
3518
+
3519
+ static BinaryOperator *Create (const ASTContext &C, Expr *lhs, Expr *rhs,
3520
+ Opcode opc, QualType ResTy, ExprValueKind VK,
3521
+ ExprObjectKind OK, SourceLocation opLoc,
3522
+ FPOptions FPFeatures);
3497
3523
SourceLocation getExprLoc () const { return getOperatorLoc (); }
3498
3524
SourceLocation getOperatorLoc () const { return BinaryOperatorBits.OpLoc ; }
3499
3525
void setOperatorLoc (SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
@@ -3634,42 +3660,69 @@ class BinaryOperator : public Expr {
3634
3660
return const_child_range (&SubExprs[0 ], &SubExprs[0 ] + END_EXPR);
3635
3661
}
3636
3662
3637
- // Set the FP contractability status of this operator. Only meaningful for
3638
- // operations on floating point types.
3639
- void setFPFeatures (FPOptions F) {
3640
- BinaryOperatorBits.FPFeatures = F.getInt ();
3663
+ // / Set and fetch the bit that shows whether FPFeatures needs to be
3664
+ // / allocated in Trailing Storage
3665
+ void setHasStoredFPFeatures (bool B) { BinaryOperatorBits.HasFPFeatures = B; }
3666
+ bool hasStoredFPFeatures () const { return BinaryOperatorBits.HasFPFeatures ; }
3667
+
3668
+ // / Get FPFeatures from trailing storage
3669
+ FPOptions getStoredFPFeatures () const {
3670
+ assert (hasStoredFPFeatures ());
3671
+ return *getTrailingFPFeatures ();
3672
+ }
3673
+ // / Set FPFeatures in trailing storage, used only by Serialization
3674
+ void setStoredFPFeatures (FPOptions F) {
3675
+ assert (BinaryOperatorBits.HasFPFeatures );
3676
+ *getTrailingFPFeatures () = F;
3641
3677
}
3642
3678
3643
- FPOptions getFPFeatures () const {
3644
- return FPOptions (BinaryOperatorBits.FPFeatures );
3679
+ // Get the FP features status of this operator. Only meaningful for
3680
+ // operations on floating point types.
3681
+ FPOptions getFPFeatures (const ASTContext &C) const {
3682
+ if (BinaryOperatorBits.HasFPFeatures )
3683
+ return getStoredFPFeatures ();
3684
+ return FPOptions::defaultWithoutTrailingStorage (C);
3645
3685
}
3646
3686
3647
3687
// Get the FP contractability status of this operator. Only meaningful for
3648
3688
// operations on floating point types.
3649
- bool isFPContractableWithinStatement () const {
3650
- return getFPFeatures ().allowFPContractWithinStatement ();
3689
+ bool isFPContractableWithinStatement (const ASTContext &C ) const {
3690
+ return getFPFeatures (C ).allowFPContractWithinStatement ();
3651
3691
}
3652
3692
3653
3693
// Get the FENV_ACCESS status of this operator. Only meaningful for
3654
3694
// operations on floating point types.
3655
- bool isFEnvAccessOn () const { return getFPFeatures ().allowFEnvAccess (); }
3695
+ bool isFEnvAccessOn (const ASTContext &C) const {
3696
+ return getFPFeatures (C).allowFEnvAccess ();
3697
+ }
3656
3698
3657
3699
protected:
3658
- BinaryOperator (Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy ,
3659
- ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc ,
3660
- FPOptions FPFeatures, bool dead2)
3700
+ BinaryOperator (const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
3701
+ QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
3702
+ SourceLocation opLoc, FPOptions FPFeatures, bool dead2)
3661
3703
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK) {
3662
3704
BinaryOperatorBits.Opc = opc;
3663
- BinaryOperatorBits.FPFeatures = FPFeatures.getInt ();
3705
+ assert (isCompoundAssignmentOp () &&
3706
+ " Use CompoundAssignOperator for compound assignments" );
3664
3707
BinaryOperatorBits.OpLoc = opLoc;
3665
3708
SubExprs[LHS] = lhs;
3666
3709
SubExprs[RHS] = rhs;
3710
+ BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage (Ctx);
3711
+ if (BinaryOperatorBits.HasFPFeatures )
3712
+ *getTrailingFPFeatures () = FPFeatures;
3667
3713
setDependence (computeDependence (this ));
3668
3714
}
3669
3715
3716
+ // / Construct an empty BinaryOperator, SC is CompoundAssignOperator.
3670
3717
BinaryOperator (StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
3671
3718
BinaryOperatorBits.Opc = BO_MulAssign;
3672
3719
}
3720
+
3721
+ // / Return the size in bytes needed for the trailing objects.
3722
+ // / Used to allocate the right amount of storage.
3723
+ static unsigned sizeOfTrailingObjects (bool HasFPFeatures) {
3724
+ return HasFPFeatures * sizeof (FPOptions);
3725
+ }
3673
3726
};
3674
3727
3675
3728
// / CompoundAssignOperator - For compound assignments (e.g. +=), we keep
@@ -3681,22 +3734,33 @@ class BinaryOperator : public Expr {
3681
3734
class CompoundAssignOperator : public BinaryOperator {
3682
3735
QualType ComputationLHSType;
3683
3736
QualType ComputationResultType;
3684
- public:
3685
- CompoundAssignOperator (Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
3686
- ExprValueKind VK, ExprObjectKind OK,
3687
- QualType CompLHSType, QualType CompResultType,
3688
- SourceLocation OpLoc, FPOptions FPFeatures)
3689
- : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
3690
- true ),
3691
- ComputationLHSType (CompLHSType),
3692
- ComputationResultType(CompResultType) {
3737
+
3738
+ // / Construct an empty CompoundAssignOperator.
3739
+ explicit CompoundAssignOperator (const ASTContext &C, EmptyShell Empty,
3740
+ bool hasFPFeatures)
3741
+ : BinaryOperator(CompoundAssignOperatorClass, Empty) {}
3742
+
3743
+ protected:
3744
+ CompoundAssignOperator (const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc,
3745
+ QualType ResType, ExprValueKind VK, ExprObjectKind OK,
3746
+ SourceLocation OpLoc, FPOptions FPFeatures,
3747
+ QualType CompLHSType, QualType CompResultType)
3748
+ : BinaryOperator(C, lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
3749
+ true ),
3750
+ ComputationLHSType (CompLHSType), ComputationResultType(CompResultType) {
3693
3751
assert (isCompoundAssignmentOp () &&
3694
3752
" Only should be used for compound assignments" );
3695
3753
}
3696
3754
3697
- // / Build an empty compound assignment operator expression.
3698
- explicit CompoundAssignOperator (EmptyShell Empty)
3699
- : BinaryOperator(CompoundAssignOperatorClass, Empty) { }
3755
+ public:
3756
+ static CompoundAssignOperator *CreateEmpty (const ASTContext &C,
3757
+ bool hasFPFeatures);
3758
+
3759
+ static CompoundAssignOperator *
3760
+ Create (const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
3761
+ ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
3762
+ FPOptions FPFeatures, QualType CompLHSType = QualType(),
3763
+ QualType CompResultType = QualType());
3700
3764
3701
3765
// The two computation types are the type the LHS is converted
3702
3766
// to for the computation and the type of the result; the two are
@@ -3712,6 +3776,12 @@ class CompoundAssignOperator : public BinaryOperator {
3712
3776
}
3713
3777
};
3714
3778
3779
+ inline size_t BinaryOperator::offsetOfTrailingStorage () const {
3780
+ assert (BinaryOperatorBits.HasFPFeatures );
3781
+ return isa<CompoundAssignOperator>(this ) ? sizeof (CompoundAssignOperator)
3782
+ : sizeof (BinaryOperator);
3783
+ }
3784
+
3715
3785
// / AbstractConditionalOperator - An abstract base class for
3716
3786
// / ConditionalOperator and BinaryConditionalOperator.
3717
3787
class AbstractConditionalOperator : public Expr {
0 commit comments