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/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 2edf62a..cc209a4 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -798,9 +798,19 @@
return "AnyPointerToBlockPointerCast";
case CK_ObjCObjectLValueCast:
return "ObjCObjectLValueCast";
+ 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";
}
- assert(0 && "Unhandled cast kind!");
+ llvm_unreachable("Unhandled cast kind!");
return 0;
}
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index dfeb32d..172a811 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -2165,6 +2165,8 @@
QualType EltType = E->getType()->getAs<ComplexType>()->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 73b5bf8..19238bf 100644
--- a/lib/Checker/GRExprEngine.cpp
+++ b/lib/Checker/GRExprEngine.cpp
@@ -2524,6 +2524,11 @@
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 bb2eb3c..6739fd6 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1814,6 +1814,11 @@
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 517a8da..637441f 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -350,6 +350,8 @@
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 d07d203..5b419c0 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1079,7 +1079,11 @@
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 590685d..b9d3d87 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -399,18 +399,30 @@
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<ComplexType>(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<ComplexType>(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 @@
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 @@
if (LHSComplexFloat) {
if (order > 0) { // LHS is wider
// float -> _Complex double
- ImpCastExprToType(rhsExpr, lhs, CK_Unknown);
+ QualType fp = cast<ComplexType>(lhs)->getElementType();
+ ImpCastExprToType(rhsExpr, fp, CK_FloatingCast);
+ ImpCastExprToType(rhsExpr, lhs, CK_FloatingRealToComplex);
return lhs;
}
@@ -455,11 +469,11 @@
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 @@
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 @@
// 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 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 @@
// _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 @@
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;
}