diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 111 |
1 files changed, 29 insertions, 82 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 40909534629..c0c074d316a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -938,68 +938,6 @@ static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr, return false; } -/// \brief Takes two complex float types and converts them to the same type. -/// Helper function of UsualArithmeticConversions() -static QualType -handleComplexFloatToComplexFloatConverstion(Sema &S, ExprResult &LHS, - ExprResult &RHS, QualType LHSType, - QualType RHSType, - bool IsCompAssign) { - int order = S.Context.getFloatingTypeOrder(LHSType, RHSType); - - if (order < 0) { - // _Complex float -> _Complex double - if (!IsCompAssign) - LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingComplexCast); - return RHSType; - } - if (order > 0) - // _Complex float -> _Complex double - RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingComplexCast); - return LHSType; -} - -/// \brief Converts otherExpr to complex float and promotes complexExpr if -/// necessary. Helper function of UsualArithmeticConversions() -static QualType handleOtherComplexFloatConversion(Sema &S, - ExprResult &ComplexExpr, - ExprResult &OtherExpr, - QualType ComplexTy, - QualType OtherTy, - bool ConvertComplexExpr, - bool ConvertOtherExpr) { - int order = S.Context.getFloatingTypeOrder(ComplexTy, OtherTy); - - // If just the complexExpr is complex, the otherExpr needs to be converted, - // and the complexExpr might need to be promoted. - if (order > 0) { // complexExpr is wider - // float -> _Complex double - if (ConvertOtherExpr) { - QualType fp = cast<ComplexType>(ComplexTy)->getElementType(); - OtherExpr = S.ImpCastExprToType(OtherExpr.get(), fp, CK_FloatingCast); - OtherExpr = S.ImpCastExprToType(OtherExpr.get(), ComplexTy, - CK_FloatingRealToComplex); - } - return ComplexTy; - } - - // otherTy is at least as wide. Find its corresponding complex type. - QualType result = (order == 0 ? ComplexTy : - S.Context.getComplexType(OtherTy)); - - // double -> _Complex double - if (ConvertOtherExpr) - OtherExpr = S.ImpCastExprToType(OtherExpr.get(), result, - CK_FloatingRealToComplex); - - // _Complex float -> _Complex double - if (ConvertComplexExpr && order < 0) - ComplexExpr = S.ImpCastExprToType(ComplexExpr.get(), result, - CK_FloatingComplexCast); - - return result; -} - /// \brief Handle arithmetic conversion with complex types. Helper function of /// UsualArithmeticConversions() static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS, @@ -1025,26 +963,35 @@ static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS, // when combining a "long double" with a "double _Complex", the // "double _Complex" is promoted to "long double _Complex". - bool LHSComplexFloat = LHSType->isComplexType(); - bool RHSComplexFloat = RHSType->isComplexType(); - - // If both are complex, just cast to the more precise type. - if (LHSComplexFloat && RHSComplexFloat) - return handleComplexFloatToComplexFloatConverstion(S, LHS, RHS, - LHSType, RHSType, - IsCompAssign); - - // If only one operand is complex, promote it if necessary and convert the - // other operand to complex. - if (LHSComplexFloat) - return handleOtherComplexFloatConversion( - S, LHS, RHS, LHSType, RHSType, /*convertComplexExpr*/!IsCompAssign, - /*convertOtherExpr*/ true); - - assert(RHSComplexFloat); - return handleOtherComplexFloatConversion( - S, RHS, LHS, RHSType, LHSType, /*convertComplexExpr*/true, - /*convertOtherExpr*/ !IsCompAssign); + // Compute the rank of the two types, regardless of whether they are complex. + int Order = S.Context.getFloatingTypeOrder(LHSType, RHSType); + + auto *LHSComplexType = dyn_cast<ComplexType>(LHSType); + auto *RHSComplexType = dyn_cast<ComplexType>(RHSType); + QualType LHSElementType = + LHSComplexType ? LHSComplexType->getElementType() : LHSType; + QualType RHSElementType = + RHSComplexType ? RHSComplexType->getElementType() : RHSType; + + QualType ResultType = S.Context.getComplexType(LHSElementType); + if (Order < 0) { + // Promote the precision of the LHS if not an assignment. + ResultType = S.Context.getComplexType(RHSElementType); + if (!IsCompAssign) { + if (LHSComplexType) + LHS = + S.ImpCastExprToType(LHS.get(), ResultType, CK_FloatingComplexCast); + else + LHS = S.ImpCastExprToType(LHS.get(), RHSElementType, CK_FloatingCast); + } + } else if (Order > 0) { + // Promote the precision of the RHS. + if (RHSComplexType) + RHS = S.ImpCastExprToType(RHS.get(), ResultType, CK_FloatingComplexCast); + else + RHS = S.ImpCastExprToType(RHS.get(), LHSElementType, CK_FloatingCast); + } + return ResultType; } /// \brief Hande arithmetic conversion from integer to float. Helper function |