From: John McCall Date: Tue, 14 Dec 2010 17:51:41 +0000 (+0000) Subject: Rewrite ComplexExprEvaluator::VisitCastExpr to use cast kinds, and fix X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8786da77984e81d48e0e1b2bd339809b1efc19f3;p=clang Rewrite ComplexExprEvaluator::VisitCastExpr to use cast kinds, and fix the basic casting logic to insert intermediate casts and preserve the exact complex-cast design. Fixes a crash in the test suite. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121776 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 1e356f13d1..7c350d417b 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2133,97 +2133,128 @@ bool ComplexExprEvaluator::VisitImaginaryLiteral(ImaginaryLiteral *E) { } bool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) { - Expr* SubExpr = E->getSubExpr(); - QualType EltType = E->getType()->getAs()->getElementType(); - QualType SubType = SubExpr->getType(); - // TODO: just trust CastKind + switch (E->getCastKind()) { + case CK_BitCast: + case CK_LValueBitCast: + case CK_BaseToDerived: + case CK_DerivedToBase: + case CK_UncheckedDerivedToBase: + case CK_Dynamic: + case CK_ToUnion: + case CK_ArrayToPointerDecay: + case CK_FunctionToPointerDecay: + case CK_NullToPointer: + case CK_NullToMemberPointer: + case CK_BaseToDerivedMemberPointer: + case CK_DerivedToBaseMemberPointer: + case CK_MemberPointerToBoolean: + case CK_ConstructorConversion: + case CK_IntegralToPointer: + case CK_PointerToIntegral: + case CK_PointerToBoolean: + case CK_ToVoid: + case CK_VectorSplat: + case CK_IntegralCast: + case CK_IntegralToBoolean: + case CK_IntegralToFloating: + case CK_FloatingToIntegral: + case CK_FloatingToBoolean: + case CK_FloatingCast: + case CK_AnyPointerToObjCPointerCast: + case CK_AnyPointerToBlockPointerCast: + case CK_ObjCObjectLValueCast: + case CK_FloatingComplexToReal: + case CK_FloatingComplexToBoolean: + case CK_IntegralComplexToReal: + case CK_IntegralComplexToBoolean: + llvm_unreachable("invalid cast kind for complex value"); + + case CK_LValueToRValue: + case CK_NoOp: + return Visit(E->getSubExpr()); - if (SubType->isRealFloatingType()) { + case CK_Dependent: + case CK_GetObjCProperty: + case CK_UserDefinedConversion: + return false; + + case CK_FloatingRealToComplex: { APFloat &Real = Result.FloatReal; - if (!EvaluateFloat(SubExpr, Real, Info)) + if (!EvaluateFloat(E->getSubExpr(), Real, Info)) return false; - if (EltType->isRealFloatingType()) { - Result.makeComplexFloat(); - Real = HandleFloatToFloatCast(EltType, SubType, Real, Info.Ctx); - Result.FloatImag = APFloat(Real.getSemantics()); - return true; - } else { - Result.makeComplexInt(); - Result.IntReal = HandleFloatToIntCast(EltType, SubType, Real, Info.Ctx); - Result.IntImag = APSInt(Result.IntReal.getBitWidth(), - !Result.IntReal.isSigned()); - return true; - } - } else if (SubType->isIntegerType()) { + Result.makeComplexFloat(); + Result.FloatImag = APFloat(Real.getSemantics()); + return true; + } + + case CK_FloatingComplexCast: { + if (!Visit(E->getSubExpr())) + return false; + + QualType To = E->getType()->getAs()->getElementType(); + QualType From + = E->getSubExpr()->getType()->getAs()->getElementType(); + + Result.FloatReal + = HandleFloatToFloatCast(To, From, Result.FloatReal, Info.Ctx); + Result.FloatImag + = HandleFloatToFloatCast(To, From, Result.FloatImag, Info.Ctx); + return true; + } + + case CK_FloatingComplexToIntegralComplex: { + if (!Visit(E->getSubExpr())) + return false; + + QualType To = E->getType()->getAs()->getElementType(); + QualType From + = E->getSubExpr()->getType()->getAs()->getElementType(); + Result.makeComplexInt(); + Result.IntReal = HandleFloatToIntCast(To, From, Result.FloatReal, Info.Ctx); + Result.IntImag = HandleFloatToIntCast(To, From, Result.FloatImag, Info.Ctx); + return true; + } + + case CK_IntegralRealToComplex: { APSInt &Real = Result.IntReal; - if (!EvaluateInteger(SubExpr, Real, Info)) + if (!EvaluateInteger(E->getSubExpr(), Real, Info)) return false; - if (EltType->isRealFloatingType()) { - Result.makeComplexFloat(); - Result.FloatReal - = HandleIntToFloatCast(EltType, SubType, Real, Info.Ctx); - Result.FloatImag = APFloat(Result.FloatReal.getSemantics()); - return true; - } else { - Result.makeComplexInt(); - Real = HandleIntToIntCast(EltType, SubType, Real, Info.Ctx); - Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned()); - return true; - } - } else if (const ComplexType *CT = SubType->getAs()) { - if (!Visit(SubExpr)) + Result.makeComplexInt(); + Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned()); + return true; + } + + case CK_IntegralComplexCast: { + if (!Visit(E->getSubExpr())) return false; - QualType SrcType = CT->getElementType(); + QualType To = E->getType()->getAs()->getElementType(); + QualType From + = E->getSubExpr()->getType()->getAs()->getElementType(); - if (Result.isComplexFloat()) { - if (EltType->isRealFloatingType()) { - Result.makeComplexFloat(); - Result.FloatReal = HandleFloatToFloatCast(EltType, SrcType, - Result.FloatReal, - Info.Ctx); - Result.FloatImag = HandleFloatToFloatCast(EltType, SrcType, - Result.FloatImag, - Info.Ctx); - return true; - } else { - Result.makeComplexInt(); - Result.IntReal = HandleFloatToIntCast(EltType, SrcType, - Result.FloatReal, - Info.Ctx); - Result.IntImag = HandleFloatToIntCast(EltType, SrcType, - Result.FloatImag, - Info.Ctx); - return true; - } - } else { - assert(Result.isComplexInt() && "Invalid evaluate result."); - if (EltType->isRealFloatingType()) { - Result.makeComplexFloat(); - Result.FloatReal = HandleIntToFloatCast(EltType, SrcType, - Result.IntReal, - Info.Ctx); - Result.FloatImag = HandleIntToFloatCast(EltType, SrcType, - Result.IntImag, - Info.Ctx); - return true; - } else { - Result.makeComplexInt(); - Result.IntReal = HandleIntToIntCast(EltType, SrcType, - Result.IntReal, - Info.Ctx); - Result.IntImag = HandleIntToIntCast(EltType, SrcType, - Result.IntImag, - Info.Ctx); - return true; - } - } + Result.IntReal = HandleIntToIntCast(To, From, Result.IntReal, Info.Ctx); + Result.IntImag = HandleIntToIntCast(To, From, Result.IntImag, Info.Ctx); + return true; + } + + case CK_IntegralComplexToFloatingComplex: { + if (!Visit(E->getSubExpr())) + return false; + + QualType To = E->getType()->getAs()->getElementType(); + QualType From + = E->getSubExpr()->getType()->getAs()->getElementType(); + Result.makeComplexFloat(); + Result.FloatReal = HandleIntToFloatCast(To, From, Result.IntReal, Info.Ctx); + Result.FloatImag = HandleIntToFloatCast(To, From, Result.IntImag, Info.Ctx); + return true; + } } - // FIXME: Handle more casts. + llvm_unreachable("unknown cast resulting in complex value"); return false; } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3f114dd629..862a242d51 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4487,6 +4487,8 @@ static CastKind PrepareScalarCast(Sema &S, Expr *&Src, QualType DestTy) { case Type::STK_Floating: return CK_IntegralToFloating; case Type::STK_IntegralComplex: + S.ImpCastExprToType(Src, cast(DestTy)->getElementType(), + CK_IntegralCast); return CK_IntegralRealToComplex; case Type::STK_FloatingComplex: S.ImpCastExprToType(Src, cast(DestTy)->getElementType(), @@ -4506,6 +4508,8 @@ static CastKind PrepareScalarCast(Sema &S, Expr *&Src, QualType DestTy) { case Type::STK_Integral: return CK_FloatingToIntegral; case Type::STK_FloatingComplex: + S.ImpCastExprToType(Src, cast(DestTy)->getElementType(), + CK_FloatingCast); return CK_FloatingRealToComplex; case Type::STK_IntegralComplex: S.ImpCastExprToType(Src, cast(DestTy)->getElementType(), @@ -4524,8 +4528,13 @@ static CastKind PrepareScalarCast(Sema &S, Expr *&Src, QualType DestTy) { return CK_FloatingComplexCast; case Type::STK_IntegralComplex: return CK_FloatingComplexToIntegralComplex; - case Type::STK_Floating: - return CK_FloatingComplexToReal; + case Type::STK_Floating: { + QualType ET = cast(SrcTy)->getElementType(); + if (S.Context.hasSameType(ET, DestTy)) + return CK_FloatingComplexToReal; + S.ImpCastExprToType(Src, ET, CK_FloatingComplexToReal); + return CK_FloatingCast; + } case Type::STK_Bool: return CK_FloatingComplexToBoolean; case Type::STK_Integral: @@ -4545,8 +4554,13 @@ static CastKind PrepareScalarCast(Sema &S, Expr *&Src, QualType DestTy) { return CK_IntegralComplexToFloatingComplex; case Type::STK_IntegralComplex: return CK_IntegralComplexCast; - case Type::STK_Integral: - return CK_IntegralComplexToReal; + case Type::STK_Integral: { + QualType ET = cast(SrcTy)->getElementType(); + if (S.Context.hasSameType(ET, DestTy)) + return CK_IntegralComplexToReal; + S.ImpCastExprToType(Src, ET, CK_IntegralComplexToReal); + return CK_IntegralCast; + } case Type::STK_Bool: return CK_IntegralComplexToBoolean; case Type::STK_Floating: