]> granicus.if.org Git - clang/commitdiff
Introduce five new cast kinds for various conversions into and
authorJohn McCall <rjmccall@apple.com>
Sat, 13 Nov 2010 09:02:35 +0000 (09:02 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 13 Nov 2010 09:02:35 +0000 (09:02 +0000)
between complex types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118994 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
include/clang/AST/OperationKinds.h
include/clang/AST/Stmt.h
lib/AST/Expr.cpp
lib/AST/ExprConstant.cpp
lib/Checker/GRExprEngine.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprScalar.cpp
lib/Sema/SemaExpr.cpp

index be6e1bca5838284c85b964d785199e3d22b5b0de..eda2368344453eaf5b688be3755f0319d5a7fe60 100644 (file)
@@ -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;
     }
index 4e57df1af6ef0c1e7b43403dba6723ac213c5c52..7cfeed2ab5094e1f0acfc91a7115de45832ee21e 100644 (file)
@@ -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
 };
 
 
index ca42b3ea7e0fa135b813301a8d6195418b90abc9..3c5d306af89159a37110966c0c56a1ea1a0e8e25 100644 (file)
@@ -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 {
index 2edf62ab3978eaee0e9a74890a58a6bb8372c3f5..cc209a458a121daa6c0817b1b1ced1474d160b48 100644 (file)
@@ -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;
 }
 
index dfeb32df3d331db5bd01a527331c1e17b875a5ad..172a811bee1c55c9ca932f22542c1548eac20288 100644 (file)
@@ -2165,6 +2165,8 @@ bool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) {
   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))
index 73b5bf8967efbe6038d35cb4a0aa59233b991e42..19238bf2afb5118d21e4a32d8bbdb15d8df27843 100644 (file)
@@ -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:
index bb2eb3c7982c8b02128f5023e2900cf78d5180a5..6739fd679cfd1e0097a419c733dc3fde8d0dfc8f 100644 (file)
@@ -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:
index 517a8da34d38c89f5f6addc88d91a79263705628..637441f4e199df9f472221ccadd001a15fd7d11b 100644 (file)
@@ -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);
index d07d20395d549ef72677f7fbdc9da1c2e7f763f2..5b419c02f8bdbb0f31cc0cae64932b6b0e9c5156 100644 (file)
@@ -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;
index 590685d6ccc62ca7d45739b3ff5220c289c70ae5..b9d3d8756598f5d3050c1b62bfffe21650cab2d8 100644 (file)
@@ -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<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 @@ 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<ComplexType>(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;
   }