aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-10-18 18:12:03 +0000
committerAnders Carlsson <andersca@mac.com>2009-10-18 18:12:03 +0000
commit82debc7d282e723e58d183bfa89ddc2500a8daaf (patch)
treecdab83016d60bd68811bfbc05411a4d41ed456bb
parentb14346b95e728f3f9425f9c2dc7973875874eb38 (diff)
Add some more cast kinds.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84423 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Expr.h14
-rw-r--r--lib/AST/Expr.cpp6
-rw-r--r--lib/CodeGen/CGExprScalar.cpp11
-rw-r--r--lib/Sema/SemaExpr.cpp37
4 files changed, 65 insertions, 3 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index a560ac4048..fa27c9c463 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -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:
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 83120d2c1c..c0e0369787 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -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!");
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 422e2b65bc..d986549555 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -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: {
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index b98b67fd74..ad62ae7d84 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -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;
}