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(castExpr)) return Diag(castExpr->getLocStart(), diag::err_illegal_super_cast) << TyR; + if (isa(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(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()->getElementType()); + + Kind = CastExpr::CK_VectorSplat; return false; }