]> granicus.if.org Git - clang/commitdiff
Add some more cast kinds.
authorAnders Carlsson <andersca@mac.com>
Sun, 18 Oct 2009 18:12:03 +0000 (18:12 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 18 Oct 2009 18:12:03 +0000 (18:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84423 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
lib/AST/Expr.cpp
lib/CodeGen/CGExprScalar.cpp
lib/Sema/SemaExpr.cpp

index a560ac404805ca663388993f88054efe5df8c976..fa27c9c463135f5be42dbcdcb9a5024ae1f6cddf 100644 (file)
@@ -1407,7 +1407,19 @@ public:
     /// CK_VectorSplat - Casting from an integer/floating type to an extended
     /// vector type with the same element type as the src type. Splats the 
     /// src expression into the destionation expression.
-    CK_VectorSplat
+    CK_VectorSplat,
+    
+    /// CK_IntegralCast - Casting between integral types of different size.
+    CK_IntegralCast,
+
+    /// CK_IntegralToFloating - Integral to floating point.
+    CK_IntegralToFloating,
+    
+    /// CK_FloatingToIntegral - Floating point to integral.
+    CK_FloatingToIntegral,
+    
+    /// CK_FloatingCast - Casting between floating types of different size.
+    CK_FloatingCast
   };
 
 private:
index 83120d2c1c2ef4da5b4d230cb74c2736a3f86977..c0e0369787de52c36fb29d5991d8d4233a000243 100644 (file)
@@ -430,6 +430,12 @@ const char *CastExpr::getCastKindName() const {
     return "ToVoid";
   case CastExpr::CK_VectorSplat:
     return "VectorSplat";
+  case CastExpr::CK_IntegralCast:
+    return "IntegralCast";
+  case CastExpr::CK_IntegralToFloating:
+    return "IntegralToFloating";
+  case CastExpr::CK_FloatingToIntegral:
+    return "FloatingToIntegral";
   }
 
   assert(0 && "Unhandled cast kind!");
index 422e2b65bca9dc6d24866343998d7bb859a27a30..d986549555ceed8e2dcd83d5911d4e81ec8347e9 100644 (file)
@@ -700,7 +700,16 @@ Value *ScalarExprEmitter::EmitCastExpr(const CastExpr *CE) {
 
   case CastExpr::CK_IntegralToPointer: {
     Value *Src = Visit(const_cast<Expr*>(E));
-    return Builder.CreateIntToPtr(Src, ConvertType(DestTy));
+    
+    // First, convert to the correct width so that we control the kind of
+    // extension.
+    const llvm::Type *MiddleTy =
+      llvm::IntegerType::get(VMContext, CGF.LLVMPointerWidth);
+    bool InputSigned = E->getType()->isSignedIntegerType();
+    llvm::Value* IntResult =
+      Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
+    
+    return Builder.CreateIntToPtr(IntResult, ConvertType(DestTy));
   }
 
   case CastExpr::CK_PointerToIntegral: {
index b98b67fd741bc40c84b86925a0924f40b1c441e4..ad62ae7d84b5e31b0d9b212ced2dbaadf0f9da2d 100644 (file)
@@ -3153,6 +3153,40 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
   return Owned(E);
 }
 
+static CastExpr::CastKind getScalarCastKind(ASTContext &Context,
+                                            QualType SrcTy, QualType DestTy) {
+  if (Context.getCanonicalType(SrcTy).getUnqualifiedType() ==
+      Context.getCanonicalType(DestTy).getUnqualifiedType())
+    return CastExpr::CK_NoOp;
+
+  if (SrcTy->hasPointerRepresentation()) {
+    if (DestTy->hasPointerRepresentation())
+      return CastExpr::CK_BitCast;
+    if (DestTy->isIntegerType())
+      return CastExpr::CK_PointerToIntegral;
+  }
+  
+  if (SrcTy->isIntegerType()) {
+    if (DestTy->isIntegerType())
+      return CastExpr::CK_IntegralCast;
+    if (DestTy->hasPointerRepresentation())
+      return CastExpr::CK_IntegralToPointer;
+    if (DestTy->isRealFloatingType())
+      return CastExpr::CK_IntegralToFloating;
+  }
+  
+  if (SrcTy->isRealFloatingType()) {
+    if (DestTy->isRealFloatingType())
+      return CastExpr::CK_FloatingCast;
+    if (DestTy->isIntegerType())
+      return CastExpr::CK_FloatingToIntegral;
+  }
+  
+  // FIXME: Assert here.
+  // assert(false && "Unhandled cast combination!");
+  return CastExpr::CK_Unknown;
+}
+
 /// CheckCastTypes - Check type constraints for casting between types.
 bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
                           CastExpr::CastKind& Kind,
@@ -3242,7 +3276,8 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
                   diag::err_cast_pointer_to_non_pointer_int)
         << castType << castExpr->getSourceRange();
   }
-  
+
+  Kind = getScalarCastKind(Context, castExpr->getType(), castType);
   return false;
 }