aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Expr.h7
-rw-r--r--lib/AST/Expr.cpp2
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaExpr.cpp27
4 files changed, 28 insertions, 11 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 67f493c47c..fb87ed631a 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -1402,7 +1402,12 @@ public:
CK_PointerToIntegral,
/// CK_ToVoid - Cast to void.
- CK_ToVoid
+ CK_ToVoid,
+
+ /// 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
};
private:
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index fa999ffe35..547854bb61 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -428,6 +428,8 @@ const char *CastExpr::getCastKindName() const {
return "PointerToIntegral";
case CastExpr::CK_ToVoid:
return "ToVoid";
+ case CastExpr::CK_VectorSplat:
+ return "VectorSplat";
}
assert(0 && "Unhandled cast kind!");
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 8de4bec6bd..398b413e26 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -3669,7 +3669,8 @@ public:
// We allow casting between vectors and integer datatypes of the same size,
// or vectors and the element type of that vector.
// returns true if the cast is invalid
- bool CheckExtVectorCast(SourceRange R, QualType VectorTy, QualType Ty);
+ bool CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *&CastExpr,
+ CastExpr::CastKind &Kind);
/// CXXCheckCStyleCast - Check constraints of a C-style or function-style
/// cast under C++ semantics.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index b998385398..67058860d6 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3205,11 +3205,9 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
<< castExpr->getType() << castExpr->getSourceRange();
}
- if (castType->isExtVectorType()) {
- // FIXME: Set the cast kind.
- return CheckExtVectorCast(TyR, castType, castExpr->getType());
- }
-
+ if (castType->isExtVectorType())
+ return CheckExtVectorCast(TyR, castType, castExpr, Kind);
+
if (castType->isVectorType())
return CheckVectorCast(TyR, castType, castExpr->getType(), Kind);
if (castExpr->getType()->isVectorType())
@@ -3218,6 +3216,9 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
if (getLangOptions().ObjC1 && isa<ObjCSuperExpr>(castExpr))
return Diag(castExpr->getLocStart(), diag::err_illegal_super_cast) << TyR;
+ if (isa<ObjCSelectorExpr>(castExpr))
+ return Diag(castExpr->getLocStart(), diag::err_cast_selector_expr);
+
if (!castType->isArithmeticType()) {
QualType castExprType = castExpr->getType();
if (!castExprType->isIntegralType() && castExprType->isArithmeticType())
@@ -3230,8 +3231,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
diag::err_cast_pointer_to_non_pointer_int)
<< castType << castExpr->getSourceRange();
}
- if (isa<ObjCSelectorExpr>(castExpr))
- return Diag(castExpr->getLocStart(), diag::err_cast_selector_expr);
+
return false;
}
@@ -3255,15 +3255,19 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
return false;
}
-bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) {
+bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
+ CastExpr::CastKind &Kind) {
assert(DestTy->isExtVectorType() && "Not an extended vector type!");
-
+
+ QualType SrcTy = CastExpr->getType();
+
// If SrcTy is a VectorType, the total size must match to explicitly cast to
// an ExtVectorType.
if (SrcTy->isVectorType()) {
if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy))
return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
<< DestTy << SrcTy << R;
+ Kind = CastExpr::CK_BitCast;
return false;
}
@@ -3274,6 +3278,11 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) {
return Diag(R.getBegin(),
diag::err_invalid_conversion_between_vector_and_scalar)
<< DestTy << SrcTy << R;
+
+ // FIXME: Pass a cast kind to the implicit cast expr.
+ ImpCastExprToType(CastExpr, DestTy->getAs<ExtVectorType>()->getElementType());
+
+ Kind = CastExpr::CK_VectorSplat;
return false;
}