summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2009-06-28 02:36:38 +0000
committerNate Begeman <natebegeman@mac.com>2009-06-28 02:36:38 +0000
commitbd956c429040a41c7e9e4fdd3063ec0ab98457cb (patch)
treeada8f3690cc2719f70171e9775cedcdc4959d5d5 /clang/lib
parent9d09e20142f6767eadcfb27318f6850c1d371c3e (diff)
downloadbcm5719-llvm-bd956c429040a41c7e9e4fdd3063ec0ab98457cb.tar.gz
bcm5719-llvm-bd956c429040a41c7e9e4fdd3063ec0ab98457cb.zip
OpenCL 1.0 support:
Handle rules for ExtVector + ExtVector and ExtVector + Scalar operations. Fix problem Eli noticed where we were allowing pointer types to be splatted to vector elements. llvm-svn: 74404
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp75
1 files changed, 46 insertions, 29 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 464ee939ffe..6e111651066 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2940,9 +2940,13 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) {
return false;
}
- // All scalar -> ext vector "c-style" casts are legal; the appropriate
+ // All non-pointer scalars can be cast to ExtVector type. The appropriate
// conversion will take place first from scalar to elt type, and then
// splat from elt type to vector.
+ if (SrcTy->isPointerType())
+ return Diag(R.getBegin(),
+ diag::err_invalid_conversion_between_vector_and_scalar)
+ << DestTy << SrcTy << R;
return false;
}
@@ -3374,12 +3378,16 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
return IncompatibleObjCQualifiedId;
}
+ // Allow scalar to ExtVector assignments, and assignments of an ExtVector type
+ // to the same ExtVector type.
+ if (lhsType->isExtVectorType()) {
+ if (rhsType->isExtVectorType())
+ return lhsType == rhsType ? Compatible : Incompatible;
+ if (!rhsType->isVectorType() && rhsType->isArithmeticType())
+ return Compatible;
+ }
+
if (lhsType->isVectorType() || rhsType->isVectorType()) {
- // For ExtVector, allow vector splats; float -> <n x float>
- if (const ExtVectorType *LV = lhsType->getAsExtVectorType())
- if (LV->getElementType() == rhsType)
- return Compatible;
-
// If we are allowing lax vector conversions, and LHS and RHS are both
// vectors, the total size only needs to be the same. This is a bitcast;
// no bits are changed but the result type is different.
@@ -3606,32 +3614,41 @@ inline QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex,
}
}
- // If the lhs is an extended vector and the rhs is a scalar of the same type
- // or a literal, promote the rhs to the vector type.
- if (const ExtVectorType *V = lhsType->getAsExtVectorType()) {
- QualType eltType = V->getElementType();
-
- if ((eltType->getAsBuiltinType() == rhsType->getAsBuiltinType()) ||
- (eltType->isIntegerType() && isa<IntegerLiteral>(rex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(rex))) {
- ImpCastExprToType(rex, lhsType);
- return lhsType;
- }
+ // Canonicalize the ExtVector to the LHS, remember if we swapped so we can
+ // swap back (so that we don't reverse the inputs to a subtract, for instance.
+ bool swapped = false;
+ if (rhsType->isExtVectorType()) {
+ swapped = true;
+ std::swap(rex, lex);
+ std::swap(rhsType, lhsType);
}
-
- // If the rhs is an extended vector and the lhs is a scalar of the same type,
- // promote the lhs to the vector type.
- if (const ExtVectorType *V = rhsType->getAsExtVectorType()) {
- QualType eltType = V->getElementType();
-
- if ((eltType->getAsBuiltinType() == lhsType->getAsBuiltinType()) ||
- (eltType->isIntegerType() && isa<IntegerLiteral>(lex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(lex))) {
- ImpCastExprToType(lex, rhsType);
- return rhsType;
+
+ // Handle the case of an ext vector and scalar
+ if (const ExtVectorType *LV = lhsType->getAsExtVectorType()) {
+ QualType EltTy = LV->getElementType();
+ if (EltTy->isIntegralType() && rhsType->isIntegralType()) {
+ if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) {
+ ImpCastExprToType(rex, EltTy);
+ rex = new (Context) CStyleCastExpr(lhsType, rex, lhsType,
+ rex->getSourceRange().getBegin(),
+ rex->getSourceRange().getEnd());
+ if (swapped) std::swap(rex, lex);
+ return lhsType;
+ }
+ }
+ if (EltTy->isRealFloatingType() && rhsType->isScalarType() &&
+ rhsType->isRealFloatingType()) {
+ if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) {
+ ImpCastExprToType(rex, EltTy);
+ rex = new (Context) CStyleCastExpr(lhsType, rex, lhsType,
+ rex->getSourceRange().getBegin(),
+ rex->getSourceRange().getEnd());
+ if (swapped) std::swap(rex, lex);
+ return lhsType;
+ }
}
}
-
+
// You cannot convert between vector values of different size.
Diag(Loc, diag::err_typecheck_vector_not_convertable)
<< lex->getType() << rex->getType()
OpenPOWER on IntegriCloud