Assorted work leading towards the elimination of CK_Unknown.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119138 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index b6a0251..70e9a97 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -604,7 +604,7 @@
// corresponding cast expression.
//
if (NumExprs == 1) {
- CastKind Kind = CK_Unknown;
+ CastKind Kind = CK_Invalid;
CXXCastPath BasePath;
if (CheckCastTypes(TInfo->getTypeLoc().getSourceRange(), Ty, Exprs[0],
Kind, BasePath,
@@ -1708,7 +1708,7 @@
case ImplicitConversionSequence::UserDefinedConversion: {
FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
- CastKind CastKind = CK_Unknown;
+ CastKind CastKind;
QualType BeforeToType;
if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
CastKind = CK_UserDefinedConversion;
@@ -1893,9 +1893,23 @@
break;
case ICK_Complex_Promotion:
- case ICK_Complex_Conversion:
- ImpCastExprToType(From, ToType, CK_Unknown);
+ case ICK_Complex_Conversion: {
+ QualType FromEl = From->getType()->getAs<ComplexType>()->getElementType();
+ QualType ToEl = ToType->getAs<ComplexType>()->getElementType();
+ CastKind CK;
+ if (FromEl->isRealFloatingType()) {
+ if (ToEl->isRealFloatingType())
+ CK = CK_FloatingComplexCast;
+ else
+ CK = CK_FloatingComplexToIntegralComplex;
+ } else if (ToEl->isRealFloatingType()) {
+ CK = CK_IntegralComplexToFloatingComplex;
+ } else {
+ CK = CK_IntegralComplexCast;
+ }
+ ImpCastExprToType(From, ToType, CK);
break;
+ }
case ICK_Floating_Integral:
if (ToType->isRealFloatingType())
@@ -1916,9 +1930,8 @@
<< From->getType() << ToType << Action
<< From->getSourceRange();
}
-
- CastKind Kind = CK_Unknown;
+ CastKind Kind = CK_Invalid;
CXXCastPath BasePath;
if (CheckPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess))
return true;
@@ -1927,7 +1940,7 @@
}
case ICK_Pointer_Member: {
- CastKind Kind = CK_Unknown;
+ CastKind Kind = CK_Invalid;
CXXCastPath BasePath;
if (CheckMemberPointerConversion(From, ToType, Kind, BasePath,
IgnoreBaseAccess))
@@ -1938,9 +1951,16 @@
break;
}
case ICK_Boolean_Conversion: {
- CastKind Kind = CK_Unknown;
- if (FromType->isMemberPointerType())
- Kind = CK_MemberPointerToBoolean;
+ CastKind Kind = CK_Invalid;
+ switch (FromType->getScalarTypeKind()) {
+ case Type::STK_Pointer: Kind = CK_PointerToBoolean; break;
+ case Type::STK_MemberPointer: Kind = CK_MemberPointerToBoolean; break;
+ case Type::STK_Bool: llvm_unreachable("bool -> bool conversion?");
+ case Type::STK_Integral: Kind = CK_IntegralToBoolean; break;
+ case Type::STK_Floating: Kind = CK_FloatingToBoolean; break;
+ case Type::STK_IntegralComplex: Kind = CK_IntegralComplexToBoolean; break;
+ case Type::STK_FloatingComplex: Kind = CK_FloatingComplexToBoolean; break;
+ }
ImpCastExprToType(From, Context.BoolTy, Kind);
break;
@@ -1971,7 +1991,52 @@
break;
case ICK_Complex_Real:
- ImpCastExprToType(From, ToType, CK_Unknown);
+ // Case 1. x -> _Complex y
+ if (const ComplexType *ToComplex = ToType->getAs<ComplexType>()) {
+ QualType ElType = ToComplex->getElementType();
+ bool isFloatingComplex = ElType->isRealFloatingType();
+
+ // x -> y
+ if (Context.hasSameUnqualifiedType(ElType, From->getType())) {
+ // do nothing
+ } else if (From->getType()->isRealFloatingType()) {
+ ImpCastExprToType(From, ElType,
+ isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral);
+ } else {
+ assert(From->getType()->isIntegerType());
+ ImpCastExprToType(From, ElType,
+ isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast);
+ }
+ // y -> _Complex y
+ ImpCastExprToType(From, ToType,
+ isFloatingComplex ? CK_FloatingRealToComplex
+ : CK_IntegralRealToComplex);
+
+ // Case 2. _Complex x -> y
+ } else {
+ const ComplexType *FromComplex = From->getType()->getAs<ComplexType>();
+ assert(FromComplex);
+
+ QualType ElType = FromComplex->getElementType();
+ bool isFloatingComplex = ElType->isRealFloatingType();
+
+ // _Complex x -> x
+ ImpCastExprToType(From, ElType,
+ isFloatingComplex ? CK_FloatingComplexToReal
+ : CK_IntegralComplexToReal);
+
+ // x -> y
+ if (Context.hasSameUnqualifiedType(ElType, ToType)) {
+ // do nothing
+ } else if (ToType->isRealFloatingType()) {
+ ImpCastExprToType(From, ToType,
+ isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating);
+ } else {
+ assert(ToType->isIntegerType());
+ ImpCastExprToType(From, ToType,
+ isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast);
+ }
+ }
break;
case ICK_Lvalue_To_Rvalue: