From: John McCall Date: Sat, 13 Nov 2010 09:02:35 +0000 (+0000) Subject: Introduce five new cast kinds for various conversions into and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2bb5d00fcf71a7b4d478d478be778fff0494aff6;p=clang Introduce five new cast kinds for various conversions into and between complex types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118994 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index be6e1bca58..eda2368344 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1997,6 +1997,11 @@ private: case CK_AnyPointerToObjCPointerCast: case CK_AnyPointerToBlockPointerCast: case CK_ObjCObjectLValueCast: + case CK_FloatingRealToComplex: + case CK_FloatingComplexCast: + case CK_IntegralRealToComplex: + case CK_IntegralComplexCast: + case CK_IntegralToFloatingComplex: assert(path_empty() && "Cast kind should not have a base path!"); break; } diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h index 4e57df1af6..7cfeed2ab5 100644 --- a/include/clang/AST/OperationKinds.h +++ b/include/clang/AST/OperationKinds.h @@ -118,7 +118,22 @@ enum CastKind { /// \brief Converting between two Objective-C object types, which /// can occur when performing reference binding to an Objective-C /// object. - CK_ObjCObjectLValueCast + CK_ObjCObjectLValueCast, + + /// \brief Floating point real to floating point complex + CK_FloatingRealToComplex, + + /// \brief Casting between floating point complex types of different size + CK_FloatingComplexCast, + + /// \brief Integral real to integral complex + CK_IntegralRealToComplex, + + /// \brief Casting between integral complex types of different size + CK_IntegralComplexCast, + + /// \brief Casting from an integral complex to a floating complex. + CK_IntegralToFloatingComplex }; diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index ca42b3ea7e..3c5d306af8 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -156,8 +156,8 @@ protected: friend class CastExpr; unsigned : NumExprBits; - unsigned Kind : 5; - unsigned BasePathSize : 32 - NumExprBits - 5; + unsigned Kind : 6; + unsigned BasePathSize : 32 - 6 - NumExprBits; }; union { diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 2edf62ab39..cc209a458a 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -798,9 +798,19 @@ const char *CastExpr::getCastKindName() const { return "AnyPointerToBlockPointerCast"; case CK_ObjCObjectLValueCast: return "ObjCObjectLValueCast"; - } - - assert(0 && "Unhandled cast kind!"); + case CK_FloatingRealToComplex: + return "FloatingRealToComplex"; + case CK_FloatingComplexCast: + return "FloatingComplexCast"; + case CK_IntegralRealToComplex: + return "IntegralRealToComplex"; + case CK_IntegralComplexCast: + return "IntegralComplexCast"; + case CK_IntegralToFloatingComplex: + return "IntegralToFloatingComplex"; + } + + llvm_unreachable("Unhandled cast kind!"); return 0; } diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index dfeb32df3d..172a811bee 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2165,6 +2165,8 @@ bool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) { QualType EltType = E->getType()->getAs()->getElementType(); QualType SubType = SubExpr->getType(); + // TODO: just trust CastKind + if (SubType->isRealFloatingType()) { APFloat &Real = Result.FloatReal; if (!EvaluateFloat(SubExpr, Real, Info)) diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 73b5bf8967..19238bf2af 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -2524,6 +2524,11 @@ void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, case CK_IntegralToFloating: case CK_FloatingToIntegral: case CK_FloatingCast: + case CK_FloatingRealToComplex: + case CK_FloatingComplexCast: + case CK_IntegralRealToComplex: + case CK_IntegralComplexCast: + case CK_IntegralToFloatingComplex: case CK_AnyPointerToObjCPointerCast: case CK_AnyPointerToBlockPointerCast: case CK_DerivedToBase: diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index bb2eb3c798..6739fd679c 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1814,6 +1814,11 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { case CK_IntegralToFloating: case CK_FloatingToIntegral: case CK_FloatingCast: + case CK_FloatingRealToComplex: + case CK_FloatingComplexCast: + case CK_IntegralRealToComplex: + case CK_IntegralComplexCast: + case CK_IntegralToFloatingComplex: case CK_DerivedToBaseMemberPointer: case CK_BaseToDerivedMemberPointer: case CK_MemberPointerToBoolean: diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 517a8da34d..637441f4e1 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -350,6 +350,8 @@ ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op, QualType DestTy) { + // FIXME: this should be based off of the CastKind. + // Two cases here: cast from (complex to complex) and (scalar to complex). if (Op->getType()->isAnyComplexType()) return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index d07d20395d..5b419c02f8 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1079,7 +1079,11 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src); } - + case CK_FloatingRealToComplex: + case CK_FloatingComplexCast: + case CK_IntegralRealToComplex: + case CK_IntegralComplexCast: + case CK_IntegralToFloatingComplex: case CK_ConstructorConversion: assert(0 && "Should be unreachable!"); break; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 590685d6cc..b9d3d87565 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -399,18 +399,30 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (LHSComplexFloat || RHSComplexFloat) { // if we have an integer operand, the result is the complex type. - if (LHSComplexFloat && - (rhs->isIntegerType() || rhs->isComplexIntegerType())) { - // convert the rhs to the lhs complex type. - ImpCastExprToType(rhsExpr, lhs, CK_Unknown); + if (!RHSComplexFloat && !rhs->isRealFloatingType()) { + if (rhs->isIntegerType()) { + QualType fp = cast(lhs)->getElementType(); + ImpCastExprToType(rhsExpr, fp, CK_IntegralToFloating); + ImpCastExprToType(rhsExpr, lhs, CK_FloatingRealToComplex); + } else { + assert(rhs->isComplexIntegerType()); + ImpCastExprToType(rhsExpr, lhs, CK_IntegralToFloatingComplex); + } return lhs; } - if (!LHSComplexFloat && RHSComplexFloat && - (lhs->isIntegerType() || lhs->isComplexIntegerType())) { - // convert the lhs to the rhs complex type. - if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_Unknown); + if (!LHSComplexFloat && !lhs->isRealFloatingType()) { + if (!isCompAssign) { + // int -> float -> _Complex float + if (lhs->isIntegerType()) { + QualType fp = cast(rhs)->getElementType(); + ImpCastExprToType(lhsExpr, fp, CK_IntegralToFloating); + ImpCastExprToType(lhsExpr, rhs, CK_FloatingRealToComplex); + } else { + assert(lhs->isComplexIntegerType()); + ImpCastExprToType(lhsExpr, rhs, CK_IntegralToFloatingComplex); + } + } return rhs; } @@ -430,13 +442,13 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (LHSComplexFloat && RHSComplexFloat) { if (order > 0) { // _Complex float -> _Complex double - ImpCastExprToType(rhsExpr, lhs, CK_Unknown); + ImpCastExprToType(rhsExpr, lhs, CK_FloatingComplexCast); return lhs; } else if (order < 0) { // _Complex float -> _Complex double if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_Unknown); + ImpCastExprToType(lhsExpr, rhs, CK_FloatingComplexCast); return rhs; } return lhs; @@ -447,7 +459,9 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (LHSComplexFloat) { if (order > 0) { // LHS is wider // float -> _Complex double - ImpCastExprToType(rhsExpr, lhs, CK_Unknown); + QualType fp = cast(lhs)->getElementType(); + ImpCastExprToType(rhsExpr, fp, CK_FloatingCast); + ImpCastExprToType(rhsExpr, lhs, CK_FloatingRealToComplex); return lhs; } @@ -455,11 +469,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, QualType result = (order == 0 ? lhs : Context.getComplexType(rhs)); // double -> _Complex double - ImpCastExprToType(rhsExpr, result, CK_Unknown); + ImpCastExprToType(rhsExpr, result, CK_FloatingRealToComplex); // _Complex float -> _Complex double if (!isCompAssign && order < 0) - ImpCastExprToType(lhsExpr, result, CK_Unknown); + ImpCastExprToType(lhsExpr, result, CK_FloatingComplexCast); return result; } @@ -470,8 +484,10 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (order < 0) { // RHS is wider // float -> _Complex double - if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_Unknown); + if (!isCompAssign) { + ImpCastExprToType(lhsExpr, rhs, CK_FloatingCast); + ImpCastExprToType(lhsExpr, rhs, CK_FloatingRealToComplex); + } return rhs; } @@ -480,11 +496,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, // double -> _Complex double if (!isCompAssign) - ImpCastExprToType(lhsExpr, result, CK_Unknown); + ImpCastExprToType(lhsExpr, result, CK_FloatingRealToComplex); // _Complex float -> _Complex double if (order > 0) - ImpCastExprToType(rhsExpr, result, CK_Unknown); + ImpCastExprToType(rhsExpr, result, CK_FloatingComplexCast); return result; } @@ -521,11 +537,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, QualType result = Context.getComplexType(lhs); // _Complex int -> _Complex float - ImpCastExprToType(rhsExpr, result, CK_Unknown); + ImpCastExprToType(rhsExpr, result, CK_IntegralToFloatingComplex); // float -> _Complex float if (!isCompAssign) - ImpCastExprToType(lhsExpr, result, CK_Unknown); + ImpCastExprToType(lhsExpr, result, CK_FloatingRealToComplex); return result; } @@ -544,10 +560,10 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, // _Complex int -> _Complex float if (!isCompAssign) - ImpCastExprToType(lhsExpr, result, CK_Unknown); + ImpCastExprToType(lhsExpr, result, CK_IntegralToFloatingComplex); // float -> _Complex float - ImpCastExprToType(rhsExpr, result, CK_Unknown); + ImpCastExprToType(rhsExpr, result, CK_FloatingRealToComplex); return result; } @@ -563,21 +579,21 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, assert(order && "inequal types with equal element ordering"); if (order > 0) { // _Complex int -> _Complex long - ImpCastExprToType(rhsExpr, lhs, CK_Unknown); + ImpCastExprToType(rhsExpr, lhs, CK_IntegralComplexCast); return lhs; } if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_Unknown); + ImpCastExprToType(lhsExpr, rhs, CK_IntegralComplexCast); return rhs; } else if (lhsComplexInt) { // int -> _Complex int - ImpCastExprToType(rhsExpr, lhs, CK_Unknown); + ImpCastExprToType(rhsExpr, lhs, CK_IntegralRealToComplex); return lhs; } else if (rhsComplexInt) { // int -> _Complex int if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_Unknown); + ImpCastExprToType(lhsExpr, rhs, CK_IntegralRealToComplex); return rhs; }