supported: AltiVec vector initialization with a single literal according to PIM section 2.5.1 - after initialization all elements have the value specified by the literal
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128375 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index dd81b38..b5c67b8 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5105,8 +5105,16 @@
if (castType->isExtVectorType())
return CheckExtVectorCast(TyR, castType, castExpr, Kind);
- if (castType->isVectorType())
- return CheckVectorCast(TyR, castType, castExpr->getType(), Kind);
+ if (castType->isVectorType()) {
+ if (castType->getAs<VectorType>()->getVectorKind() ==
+ VectorType::AltiVecVector &&
+ (castExpr->getType()->isIntegerType() ||
+ castExpr->getType()->isFloatingType())) {
+ Kind = CK_VectorSplat;
+ return false;
+ } else
+ return CheckVectorCast(TyR, castType, castExpr->getType(), Kind);
+ }
if (castExpr->getType()->isVectorType())
return CheckVectorCast(TyR, castExpr->getType(), castType, Kind);
@@ -5254,9 +5262,9 @@
TypeSourceInfo *TInfo) {
ParenListExpr *PE = cast<ParenListExpr>(Op);
QualType Ty = TInfo->getType();
- bool isAltiVecLiteral = false;
+ bool isVectorLiteral = false;
- // Check for an altivec literal,
+ // Check for an altivec or OpenCL literal,
// i.e. all the elements are integer constants.
if (getLangOptions().AltiVec && Ty->isVectorType()) {
if (PE->getNumExprs() == 0) {
@@ -5265,18 +5273,45 @@
}
if (PE->getNumExprs() == 1) {
if (!PE->getExpr(0)->getType()->isVectorType())
- isAltiVecLiteral = true;
+ isVectorLiteral = true;
}
else
- isAltiVecLiteral = true;
+ isVectorLiteral = true;
}
- // If this is an altivec initializer, '(' type ')' '(' init, ..., init ')'
+ // If this is a vector initializer, '(' type ')' '(' init, ..., init ')'
// then handle it as such.
- if (isAltiVecLiteral) {
+ if (isVectorLiteral) {
llvm::SmallVector<Expr *, 8> initExprs;
- for (unsigned i = 0, e = PE->getNumExprs(); i != e; ++i)
- initExprs.push_back(PE->getExpr(i));
+ // '(...)' form of vector initialization in AltiVec: the number of
+ // initializers must be one or must match the size of the vector.
+ // If a single value is specified in the initializer then it will be
+ // replicated to all the components of the vector
+ if (Ty->getAs<VectorType>()->getVectorKind() ==
+ VectorType::AltiVecVector) {
+ unsigned numElems = Ty->getAs<VectorType>()->getNumElements();
+ // The number of initializers must be one or must match the size of the
+ // vector. If a single value is specified in the initializer then it will
+ // be replicated to all the components of the vector
+ if (PE->getNumExprs() == 1) {
+ QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
+ Expr *Literal = PE->getExpr(0);
+ ImpCastExprToType(Literal, ElemTy,
+ PrepareScalarCast(*this, Literal, ElemTy));
+ return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal);
+ }
+ else if (PE->getNumExprs() < numElems) {
+ Diag(PE->getExprLoc(),
+ diag::err_incorrect_number_of_vector_initializers);
+ return ExprError();
+ }
+ else
+ for (unsigned i = 0, e = PE->getNumExprs(); i != e; ++i)
+ initExprs.push_back(PE->getExpr(i));
+ }
+ else
+ for (unsigned i = 0, e = PE->getNumExprs(); i != e; ++i)
+ initExprs.push_back(PE->getExpr(i));
// FIXME: This means that pretty-printing the final AST will produce curly
// braces instead of the original commas.